scons: Properly generate PDB files on MSVC.
[profile/ivi/mesa.git] / SConstruct
1 #######################################################################
2 # Top-level SConstruct
3
4 import os
5 import os.path
6 import sys
7
8
9 #######################################################################
10 # Configuration options
11 #
12 # For example, invoke scons as 
13 #
14 #   scons debug=1 dri=0 machine=x86
15 #
16 # to set configuration variables. Or you can write those options to a file
17 # named config.py:
18 #
19 #   # config.py
20 #   debug=1
21 #   dri=0
22 #   machine='x86'
23
24 # Invoke
25 #
26 #   scons -h
27 #
28 # to get the full list of options. See scons manpage for more info.
29 #  
30
31 platform_map = {
32         'linux2': 'linux',
33         'win32': 'winddk',
34 }
35
36 default_platform = platform_map.get(sys.platform, sys.platform)
37
38 if default_platform in ('linux', 'freebsd', 'darwin'):
39         default_statetrackers = 'mesa'
40         default_drivers = 'softpipe,failover,i915simple,i965simple'
41         default_winsys = 'xlib'
42         default_dri = 'yes'
43 elif default_platform in ('winddk',):
44         default_statetrackers = 'none'
45         default_drivers = 'softpipe,i915simple'
46         default_winsys = 'none'
47         default_dri = 'no'
48 else:
49         default_drivers = 'all'
50         default_winsys = 'all'
51         default_dri = 'no'
52
53
54 # TODO: auto-detect defaults
55 opts = Options('config.py')
56 opts.Add(BoolOption('debug', 'build debug version', False))
57 opts.Add(EnumOption('machine', 'use machine-specific assembly code', 'x86',
58                      allowed_values=('generic', 'x86', 'x86-64')))
59 opts.Add(EnumOption('platform', 'target platform', default_platform,
60                      allowed_values=('linux', 'cell', 'winddk')))
61 opts.Add(ListOption('statetrackers', 'state_trackers to build', default_statetrackers,
62                      [
63                         'mesa', 
64                      ],
65                      ))
66 opts.Add(ListOption('drivers', 'pipe drivers to build', default_drivers,
67                      [
68                         'softpipe', 
69                         'failover', 
70                         'i915simple', 
71                         'i965simple', 
72                         'cell',
73                      ],
74                      ))
75 opts.Add(ListOption('winsys', 'winsys drivers to build', default_winsys,
76                      [
77                         'xlib', 
78                         'intel',
79                      ],
80                      ))
81 opts.Add(BoolOption('llvm', 'use LLVM', 'no'))
82 opts.Add(BoolOption('dri', 'build DRI drivers', default_dri))
83
84 env = Environment(
85         options = opts, 
86         ENV = os.environ)
87 Help(opts.GenerateHelpText(env))
88
89 # for debugging
90 #print env.Dump()
91
92 # replicate options values in local variables
93 debug = env['debug']
94 dri = env['dri']
95 llvm = env['llvm']
96 machine = env['machine']
97 platform = env['platform']
98
99 # derived options
100 x86 = machine == 'x86'
101 gcc = platform in ('linux', 'freebsd', 'darwin')
102 msvc = platform in ('win32', 'winddk')
103
104 Export([
105         'debug', 
106         'x86', 
107         'dri', 
108         'llvm',
109         'platform',
110         'gcc',
111         'msvc',
112 ])
113
114
115 #######################################################################
116 # Environment setup
117 #
118 # TODO: put the compiler specific settings in separate files
119 # TODO: auto-detect as much as possible
120
121
122 if platform == 'winddk':
123         env.Tool('winddk', ['.'])
124         
125         env.Append(CPPPATH = [
126                 env['SDK_INC_PATH'],
127                 env['DDK_INC_PATH'],
128                 env['WDM_INC_PATH'],
129                 env['CRT_INC_PATH'],
130         ])
131
132 # Optimization flags
133 if gcc:
134         if debug:
135                 env.Append(CFLAGS = '-O0 -g3')
136                 env.Append(CXXFLAGS = '-O0 -g3')
137         else:
138                 env.Append(CFLAGS = '-O3 -g3')
139                 env.Append(CXXFLAGS = '-O3 -g3')
140
141         env.Append(CFLAGS = '-Wall -Wmissing-prototypes -Wno-long-long -ffast-math -pedantic')
142         env.Append(CXXFLAGS = '-Wall -pedantic')
143         
144         # Be nice to Eclipse
145         env.Append(CFLAGS = '-fmessage-length=0')
146         env.Append(CXXFLAGS = '-fmessage-length=0')
147
148 if msvc:
149         env.Append(CFLAGS = '/W3')
150         if debug:
151                 cflags = [
152                         '/Od', # disable optimizations
153                         '/Oy-', # disable frame pointer omission
154                 ]
155         else:
156                 cflags = [
157                         '/Ox', # maximum optimizations
158                         '/Os', # favor code space
159                 ]
160         env.Append(CFLAGS = cflags)
161         env.Append(CXXFLAGS = cflags)
162         # Put debugging information in a separate .pdb file for each object file as
163         # descrived in the scons manpage
164         env['CCPDBFLAGS'] = '/Zi /Fd${TARGET}.pdb'
165
166 # Defines
167 if debug:
168         if gcc:
169                 env.Append(CPPDEFINES = ['DEBUG'])
170         if msvc:
171                 env.Append(CPPDEFINES = [
172                         ('DBG', '1'),
173                         ('DEBUG', '1'),
174                         ('_DEBUG', '1'),
175                 ])
176 else:
177         env.Append(CPPDEFINES = ['NDEBUG'])
178
179
180 # Includes
181 env.Append(CPPPATH = [
182         '#/include',
183         '#/src/gallium/include',
184         '#/src/gallium/auxiliary',
185         '#/src/gallium/drivers',
186 ])
187
188
189 # x86 assembly
190 if x86:
191         env.Append(CPPDEFINES = [
192                 'USE_X86_ASM', 
193                 'USE_MMX_ASM',
194                 'USE_3DNOW_ASM',
195                 'USE_SSE_ASM',
196         ])
197         if gcc: 
198                 env.Append(CFLAGS = '-m32')
199                 env.Append(CXXFLAGS = '-m32')
200
201
202 # Posix
203 if platform in ('posix', 'linux', 'freebsd', 'darwin'):
204         env.Append(CPPDEFINES = [
205                 '_POSIX_SOURCE',
206                 ('_POSIX_C_SOURCE', '199309L'), 
207                 '_SVID_SOURCE',
208                 '_BSD_SOURCE', 
209                 '_GNU_SOURCE',
210                 
211                 'PTHREADS',
212                 'HAVE_POSIX_MEMALIGN',
213         ])
214         env.Append(CPPPATH = ['/usr/X11R6/include'])
215         env.Append(LIBPATH = ['/usr/X11R6/lib'])
216         env.Append(LIBS = [
217                 'm',
218                 'pthread',
219                 'expat',
220                 'dl',
221         ])
222
223
224 # DRI
225 if dri:
226         env.ParseConfig('pkg-config --cflags --libs libdrm')
227         env.Append(CPPDEFINES = [
228                 ('USE_EXTERNAL_DXTN_LIB', '1'), 
229                 'IN_DRI_DRIVER',
230                 'GLX_DIRECT_RENDERING',
231                 'GLX_INDIRECT_RENDERING',
232         ])
233
234 # LLVM
235 if llvm:
236         # See also http://www.scons.org/wiki/UsingPkgConfig
237         env.ParseConfig('llvm-config --cflags --ldflags --libs')
238         env.Append(CPPDEFINES = ['MESA_LLVM'])
239         env.Append(CXXFLAGS = ['-Wno-long-long'])
240         
241
242 # libGL
243 if platform not in ('winddk',):
244         env.Append(LIBS = [
245                 'X11',
246                 'Xext',
247                 'Xxf86vm',
248                 'Xdamage',
249                 'Xfixes',
250         ])
251
252 Export('env')
253
254
255 #######################################################################
256 # Convenience Library Builder
257 # based on the stock StaticLibrary and SharedLibrary builders
258
259 def createConvenienceLibBuilder(env):
260     """This is a utility function that creates the ConvenienceLibrary
261     Builder in an Environment if it is not there already.
262
263     If it is already there, we return the existing one.
264     """
265
266     try:
267         convenience_lib = env['BUILDERS']['ConvenienceLibrary']
268     except KeyError:
269         action_list = [ Action("$ARCOM", "$ARCOMSTR") ]
270         if env.Detect('ranlib'):
271             ranlib_action = Action("$RANLIBCOM", "$RANLIBCOMSTR")
272             action_list.append(ranlib_action)
273
274         convenience_lib = Builder(action = action_list,
275                                   emitter = '$LIBEMITTER',
276                                   prefix = '$LIBPREFIX',
277                                   suffix = '$LIBSUFFIX',
278                                   src_suffix = '$SHOBJSUFFIX',
279                                   src_builder = 'SharedObject')
280         env['BUILDERS']['ConvenienceLibrary'] = convenience_lib
281         env['BUILDERS']['Library'] = convenience_lib
282
283     return convenience_lib
284
285 createConvenienceLibBuilder(env)
286
287
288 #######################################################################
289 # Invoke SConscripts
290
291 # Put build output in a separate dir, which depends on the current configuration
292 # See also http://www.scons.org/wiki/AdvancedBuildExample
293 build_topdir = 'build'
294 build_subdir = platform
295 if dri:
296         build_subdir += "-dri"
297 if llvm:
298         build_subdir += "-llvm"
299 if x86:
300         build_subdir += "-x86"
301 if debug:
302         build_subdir += "-debug"
303 build_dir = os.path.join(build_topdir, build_subdir)
304
305 # TODO: Build several variants at the same time?
306 # http://www.scons.org/wiki/SimultaneousVariantBuilds
307
308 SConscript(
309         'src/SConscript',
310         build_dir = build_dir,
311         duplicate = 0 # http://www.scons.org/doc/0.97/HTML/scons-user/x2261.html
312 )