OSDN Git Service

mesa: Reduce clip.h header file inclusion.
[android-x86/external-mesa.git] / scons / gallium.py
1 """gallium
2
3 Frontend-tool for Gallium3D architecture.
4
5 """
6
7 #
8 # Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
9 # All Rights Reserved.
10 #
11 # Permission is hereby granted, free of charge, to any person obtaining a
12 # copy of this software and associated documentation files (the
13 # "Software"), to deal in the Software without restriction, including
14 # without limitation the rights to use, copy, modify, merge, publish,
15 # distribute, sub license, and/or sell copies of the Software, and to
16 # permit persons to whom the Software is furnished to do so, subject to
17 # the following conditions:
18 #
19 # The above copyright notice and this permission notice (including the
20 # next paragraph) shall be included in all copies or substantial portions
21 # of the Software.
22 #
23 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
26 # IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
27 # ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 #
31
32
33 import distutils.version
34 import os
35 import os.path
36 import re
37 import subprocess
38
39 import SCons.Action
40 import SCons.Builder
41 import SCons.Scanner
42
43
44 def symlink(target, source, env):
45     target = str(target[0])
46     source = str(source[0])
47     if os.path.islink(target) or os.path.exists(target):
48         os.remove(target)
49     os.symlink(os.path.basename(source), target)
50
51 def install(env, source, subdir):
52     target_dir = os.path.join(env.Dir('#.').srcnode().abspath, env['build'], subdir)
53     env.Install(target_dir, source)
54
55 def install_program(env, source):
56     install(env, source, 'bin')
57
58 def install_shared_library(env, sources, version = ()):
59     install_dir = os.path.join(env.Dir('#.').srcnode().abspath, env['build'])
60     version = tuple(map(str, version))
61     if env['SHLIBSUFFIX'] == '.dll':
62         dlls = env.FindIxes(sources, 'SHLIBPREFIX', 'SHLIBSUFFIX')
63         install(env, dlls, 'bin')
64         libs = env.FindIxes(sources, 'LIBPREFIX', 'LIBSUFFIX')
65         install(env, libs, 'lib')
66     else:
67         for source in sources:
68             target_dir =  os.path.join(install_dir, 'lib')
69             target_name = '.'.join((str(source),) + version)
70             last = env.InstallAs(os.path.join(target_dir, target_name), source)
71             while len(version):
72                 version = version[:-1]
73                 target_name = '.'.join((str(source),) + version)
74                 action = SCons.Action.Action(symlink, "$TARGET -> $SOURCE")
75                 last = env.Command(os.path.join(target_dir, target_name), last, action) 
76
77 def createInstallMethods(env):
78     env.AddMethod(install_program, 'InstallProgram')
79     env.AddMethod(install_shared_library, 'InstallSharedLibrary')
80
81
82 def num_jobs():
83     try:
84         return int(os.environ['NUMBER_OF_PROCESSORS'])
85     except (ValueError, KeyError):
86         pass
87
88     try:
89         return os.sysconf('SC_NPROCESSORS_ONLN')
90     except (ValueError, OSError, AttributeError):
91         pass
92
93     try:
94         return int(os.popen2("sysctl -n hw.ncpu")[1].read())
95     except ValueError:
96         pass
97
98     return 1
99
100
101 def generate(env):
102     """Common environment generation code"""
103
104     # Toolchain
105     platform = env['platform']
106     if env['toolchain'] == 'default':
107         if platform == 'winddk':
108             env['toolchain'] = 'winddk'
109         elif platform == 'wince':
110             env['toolchain'] = 'wcesdk'
111     env.Tool(env['toolchain'])
112
113     if env['platform'] == 'embedded':
114         # Allow overriding compiler from environment
115         if os.environ.has_key('CC'):
116             env['CC'] = os.environ['CC']
117             # Update CCVERSION to match
118             pipe = SCons.Action._subproc(env, [env['CC'], '--version'],
119                                          stdin = 'devnull',
120                                          stderr = 'devnull',
121                                          stdout = subprocess.PIPE)
122             if pipe.wait() == 0:
123                 line = pipe.stdout.readline()
124                 match = re.search(r'[0-9]+(\.[0-9]+)+', line)
125                 if match:
126                     env['CCVERSION'] = match.group(0)
127             
128
129     env['gcc'] = 'gcc' in os.path.basename(env['CC']).split('-')
130     env['msvc'] = env['CC'] == 'cl'
131
132     # shortcuts
133     debug = env['debug']
134     machine = env['machine']
135     platform = env['platform']
136     x86 = env['machine'] == 'x86'
137     ppc = env['machine'] == 'ppc'
138     gcc = env['gcc']
139     msvc = env['msvc']
140
141     # Put build output in a separate dir, which depends on the current
142     # configuration. See also http://www.scons.org/wiki/AdvancedBuildExample
143     build_topdir = 'build'
144     build_subdir = env['platform']
145     if env['machine'] != 'generic':
146         build_subdir += '-' + env['machine']
147     if env['debug']:
148         build_subdir += "-debug"
149     if env['profile']:
150         build_subdir += "-profile"
151     build_dir = os.path.join(build_topdir, build_subdir)
152     # Place the .sconsign file in the build dir too, to avoid issues with
153     # different scons versions building the same source file
154     env['build'] = build_dir
155     env.SConsignFile(os.path.join(build_dir, '.sconsign'))
156     if 'SCONS_CACHE_DIR' in os.environ:
157         print 'scons: Using build cache in %s.' % (os.environ['SCONS_CACHE_DIR'],)
158         env.CacheDir(os.environ['SCONS_CACHE_DIR'])
159     env['CONFIGUREDIR'] = os.path.join(build_dir, 'conf')
160     env['CONFIGURELOG'] = os.path.join(os.path.abspath(build_dir), 'config.log')
161
162     # Parallel build
163     if env.GetOption('num_jobs') <= 1:
164         env.SetOption('num_jobs', num_jobs())
165
166     # C preprocessor options
167     cppdefines = []
168     if debug:
169         cppdefines += ['DEBUG']
170     else:
171         cppdefines += ['NDEBUG']
172     if env['profile']:
173         cppdefines += ['PROFILE']
174     if platform == 'windows':
175         cppdefines += [
176             'WIN32',
177             '_WINDOWS',
178             #'_UNICODE',
179             #'UNICODE',
180             # http://msdn.microsoft.com/en-us/library/aa383745.aspx
181             ('_WIN32_WINNT', '0x0601'),
182             ('WINVER', '0x0601'),
183         ]
184         if msvc and env['toolchain'] != 'winddk':
185             cppdefines += [
186                 'VC_EXTRALEAN',
187                 '_USE_MATH_DEFINES',
188                 '_CRT_SECURE_NO_WARNINGS',
189                 '_CRT_SECURE_NO_DEPRECATE',
190                 '_SCL_SECURE_NO_WARNINGS',
191                 '_SCL_SECURE_NO_DEPRECATE',
192             ]
193         if debug:
194             cppdefines += ['_DEBUG']
195     if env['toolchain'] == 'winddk':
196         # Mimic WINDDK's builtin flags. See also:
197         # - WINDDK's bin/makefile.new i386mk.inc for more info.
198         # - buildchk_wxp_x86.log files, generated by the WINDDK's build
199         # - http://alter.org.ua/docs/nt_kernel/vc8_proj/
200         if machine == 'x86':
201             cppdefines += ['_X86_', 'i386']
202         if machine == 'x86_64':
203             cppdefines += ['_AMD64_', 'AMD64']
204     if platform == 'winddk':
205         cppdefines += [
206             'STD_CALL',
207             ('CONDITION_HANDLING', '1'),
208             ('NT_INST', '0'),
209             ('WIN32', '100'),
210             ('_NT1X_', '100'),
211             ('WINNT', '1'),
212             ('_WIN32_WINNT', '0x0501'), # minimum required OS version
213             ('WINVER', '0x0501'),
214             ('_WIN32_IE', '0x0603'),
215             ('WIN32_LEAN_AND_MEAN', '1'),
216             ('DEVL', '1'),
217             ('__BUILDMACHINE__', 'WinDDK'),
218             ('FPO', '0'),
219         ]
220         if debug:
221             cppdefines += [('DBG', 1)]
222     if platform == 'wince':
223         cppdefines += [
224             '_CRT_SECURE_NO_DEPRECATE',
225             '_USE_32BIT_TIME_T',
226             'UNICODE',
227             '_UNICODE',
228             ('UNDER_CE', '600'),
229             ('_WIN32_WCE', '0x600'),
230             'WINCEOEM',
231             'WINCEINTERNAL',
232             'WIN32',
233             'STRICT',
234             'x86',
235             '_X86_',
236             'INTERNATIONAL',
237             ('INTLMSG_CODEPAGE', '1252'),
238         ]
239     if platform == 'windows':
240         cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_USER']
241     if platform == 'winddk':
242         cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_DISPLAY']
243     if platform == 'wince':
244         cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_CE']
245         cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_CE_OGL']
246     if platform == 'embedded':
247         cppdefines += ['PIPE_OS_EMBEDDED']
248     env.Append(CPPDEFINES = cppdefines)
249
250     # C compiler options
251     cflags = [] # C
252     cxxflags = [] # C++
253     ccflags = [] # C & C++
254     if gcc:
255         ccversion = env['CCVERSION']
256         if debug:
257             ccflags += ['-O0', '-g3']
258         elif ccversion.startswith('4.2.'):
259             # gcc 4.2.x optimizer is broken
260             print "warning: gcc 4.2.x optimizer is broken -- disabling optimizations"
261             ccflags += ['-O0', '-g3']
262         else:
263             ccflags += ['-O3', '-g3']
264         if env['profile']:
265             # See http://code.google.com/p/jrfonseca/wiki/Gprof2Dot#Which_options_should_I_pass_to_gcc_when_compiling_for_profiling?
266             ccflags += [
267                 '-fno-omit-frame-pointer',
268                 '-fno-optimize-sibling-calls',
269             ]
270         if env['machine'] == 'x86':
271             ccflags += [
272                 '-m32',
273                 #'-march=pentium4',
274                 #'-mfpmath=sse',
275             ]
276             if platform != 'windows':
277                 # XXX: -mstackrealign causes stack corruption on MinGW. Ditto
278                 # for -mincoming-stack-boundary=2.  Still enable it on other
279                 # platforms for now, but we can't rely on it for cross platform
280                 # code. We have to use __attribute__((force_align_arg_pointer))
281                 # instead.
282                 ccflags += [
283                     '-mmmx', '-msse', '-msse2', # enable SIMD intrinsics
284                 ]
285             if platform in ['windows', 'darwin']:
286                 # Workaround http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37216
287                 ccflags += ['-fno-common']
288             if distutils.version.LooseVersion(ccversion) >= distutils.version.LooseVersion('4.2'):
289                 ccflags += [
290                     '-mstackrealign', # ensure stack is aligned
291                 ]
292         if env['machine'] == 'x86_64':
293             ccflags += ['-m64']
294         # See also:
295         # - http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
296         ccflags += [
297             '-Wall',
298             '-Wno-long-long',
299             '-ffast-math',
300             '-fmessage-length=0', # be nice to Eclipse
301         ]
302         cflags += [
303             '-Wmissing-prototypes',
304             '-std=gnu99',
305         ]
306         if distutils.version.LooseVersion(ccversion) >= distutils.version.LooseVersion('4.0'):
307             ccflags += [
308                 '-Wmissing-field-initializers',
309             ]
310         if distutils.version.LooseVersion(ccversion) >= distutils.version.LooseVersion('4.2'):
311             ccflags += [
312                 '-Werror=pointer-arith',
313             ]
314             cflags += [
315                 '-Werror=declaration-after-statement',
316             ]
317     if msvc:
318         # See also:
319         # - http://msdn.microsoft.com/en-us/library/19z1t1wy.aspx
320         # - cl /?
321         if debug:
322             ccflags += [
323               '/Od', # disable optimizations
324               '/Oi', # enable intrinsic functions
325               '/Oy-', # disable frame pointer omission
326               '/GL-', # disable whole program optimization
327             ]
328         else:
329             ccflags += [
330                 '/O2', # optimize for speed
331                 '/GL', # enable whole program optimization
332             ]
333         ccflags += [
334             '/fp:fast', # fast floating point 
335             '/W3', # warning level
336             #'/Wp64', # enable 64 bit porting warnings
337         ]
338         if env['machine'] == 'x86':
339             ccflags += [
340                 #'/arch:SSE2', # use the SSE2 instructions
341             ]
342         if platform == 'windows':
343             ccflags += [
344                 # TODO
345             ]
346         if platform == 'winddk':
347             ccflags += [
348                 '/Zl', # omit default library name in .OBJ
349                 '/Zp8', # 8bytes struct member alignment
350                 '/Gy', # separate functions for linker
351                 '/Gm-', # disable minimal rebuild
352                 '/WX', # treat warnings as errors
353                 '/Gz', # __stdcall Calling convention
354                 '/GX-', # disable C++ EH
355                 '/GR-', # disable C++ RTTI
356                 '/GF', # enable read-only string pooling
357                 '/G6', # optimize for PPro, P-II, P-III
358                 '/Ze', # enable extensions
359                 '/Gi-', # disable incremental compilation
360                 '/QIfdiv-', # disable Pentium FDIV fix
361                 '/hotpatch', # prepares an image for hotpatching.
362                 #'/Z7', #enable old-style debug info
363             ]
364         if platform == 'wince':
365             # See also C:\WINCE600\public\common\oak\misc\makefile.def
366             ccflags += [
367                 '/Zl', # omit default library name in .OBJ
368                 '/GF', # enable read-only string pooling
369                 '/GR-', # disable C++ RTTI
370                 '/GS', # enable security checks
371                 # Allow disabling language conformance to maintain backward compat
372                 #'/Zc:wchar_t-', # don't force wchar_t as native type, instead of typedef
373                 #'/Zc:forScope-', # don't enforce Standard C++ for scoping rules
374                 #'/wd4867',
375                 #'/wd4430',
376                 #'/MT',
377                 #'/U_MT',
378             ]
379         # Automatic pdb generation
380         # See http://scons.tigris.org/issues/show_bug.cgi?id=1656
381         env.EnsureSConsVersion(0, 98, 0)
382         env['PDB'] = '${TARGET.base}.pdb'
383     env.Append(CCFLAGS = ccflags)
384     env.Append(CFLAGS = cflags)
385     env.Append(CXXFLAGS = cxxflags)
386
387     if env['platform'] == 'windows' and msvc:
388         # Choose the appropriate MSVC CRT
389         # http://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx
390         if env['debug']:
391             env.Append(CCFLAGS = ['/MTd'])
392             env.Append(SHCCFLAGS = ['/LDd'])
393         else:
394             env.Append(CCFLAGS = ['/MT'])
395             env.Append(SHCCFLAGS = ['/LD'])
396     
397     # Assembler options
398     if gcc:
399         if env['machine'] == 'x86':
400             env.Append(ASFLAGS = ['-m32'])
401         if env['machine'] == 'x86_64':
402             env.Append(ASFLAGS = ['-m64'])
403
404     # Linker options
405     linkflags = []
406     shlinkflags = []
407     if gcc:
408         if env['machine'] == 'x86':
409             linkflags += ['-m32']
410         if env['machine'] == 'x86_64':
411             linkflags += ['-m64']
412         if env['platform'] not in ('darwin'):
413             shlinkflags += [
414                 '-Wl,-Bsymbolic',
415             ]
416         # Handle circular dependencies in the libraries
417         if env['platform'] in ('darwin'):
418             pass
419         else:
420             env['_LIBFLAGS'] = '-Wl,--start-group ' + env['_LIBFLAGS'] + ' -Wl,--end-group'
421     if msvc:
422         if not env['debug']:
423             # enable Link-time Code Generation
424             linkflags += ['/LTCG']
425             env.Append(ARFLAGS = ['/LTCG'])
426     if platform == 'windows' and msvc:
427         # See also:
428         # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx
429         linkflags += [
430             '/fixed:no',
431             '/incremental:no',
432         ]
433     if platform == 'winddk':
434         linkflags += [
435             '/merge:_PAGE=PAGE',
436             '/merge:_TEXT=.text',
437             '/section:INIT,d',
438             '/opt:ref',
439             '/opt:icf',
440             '/ignore:4198,4010,4037,4039,4065,4070,4078,4087,4089,4221',
441             '/incremental:no',
442             '/fullbuild',
443             '/release',
444             '/nodefaultlib',
445             '/wx',
446             '/debug',
447             '/debugtype:cv',
448             '/version:5.1',
449             '/osversion:5.1',
450             '/functionpadmin:5',
451             '/safeseh',
452             '/pdbcompress',
453             '/stack:0x40000,0x1000',
454             '/driver',
455             '/align:0x80',
456             '/subsystem:native,5.01',
457             '/base:0x10000',
458
459             '/entry:DrvEnableDriver',
460         ]
461         if env['debug'] or env['profile']:
462             linkflags += [
463                 '/MAP', # http://msdn.microsoft.com/en-us/library/k7xkk3e2.aspx
464             ]
465     if platform == 'wince':
466         linkflags += [
467             '/nodefaultlib',
468             #'/incremental:no',
469             #'/fullbuild',
470             '/entry:_DllMainCRTStartup',
471         ]
472     env.Append(LINKFLAGS = linkflags)
473     env.Append(SHLINKFLAGS = shlinkflags)
474
475     # Default libs
476     env.Append(LIBS = [])
477
478     # Load LLVM
479     if env['llvm']:
480         env.Tool('llvm')
481
482     # Custom builders and methods
483     env.Tool('custom')
484     createInstallMethods(env)
485
486     # for debugging
487     #print env.Dump()
488
489
490 def exists(env):
491     return 1