OSDN Git Service

Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
[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 os
34 import os.path
35 import re
36
37 import SCons.Action
38 import SCons.Builder
39 import SCons.Scanner
40
41
42 def quietCommandLines(env):
43     # Quiet command lines
44     # See also http://www.scons.org/wiki/HidingCommandLinesInOutput
45     env['CCCOMSTR'] = "Compiling $SOURCE ..."
46     env['CXXCOMSTR'] = "Compiling $SOURCE ..."
47     env['ARCOMSTR'] = "Archiving $TARGET ..."
48     env['RANLIBCOMSTR'] = ""
49     env['LINKCOMSTR'] = "Linking $TARGET ..."
50
51
52 def createConvenienceLibBuilder(env):
53     """This is a utility function that creates the ConvenienceLibrary
54     Builder in an Environment if it is not there already.
55
56     If it is already there, we return the existing one.
57
58     Based on the stock StaticLibrary and SharedLibrary builders.
59     """
60
61     try:
62         convenience_lib = env['BUILDERS']['ConvenienceLibrary']
63     except KeyError:
64         action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ]
65         if env.Detect('ranlib'):
66             ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR")
67             action_list.append(ranlib_action)
68
69         convenience_lib = SCons.Builder.Builder(action = action_list,
70                                   emitter = '$LIBEMITTER',
71                                   prefix = '$LIBPREFIX',
72                                   suffix = '$LIBSUFFIX',
73                                   src_suffix = '$SHOBJSUFFIX',
74                                   src_builder = 'SharedObject')
75         env['BUILDERS']['ConvenienceLibrary'] = convenience_lib
76
77     return convenience_lib
78
79
80 # TODO: handle import statements with multiple modules
81 # TODO: handle from import statements
82 import_re = re.compile(r'^import\s+(\S+)$', re.M)
83
84 def python_scan(node, env, path):
85     # http://www.scons.org/doc/0.98.5/HTML/scons-user/c2781.html#AEN2789
86     contents = node.get_contents()
87     source_dir = node.get_dir()
88     imports = import_re.findall(contents)
89     results = []
90     for imp in imports:
91         for dir in path:
92             file = os.path.join(str(dir), imp.replace('.', os.sep) + '.py')
93             if os.path.exists(file):
94                 results.append(env.File(file))
95                 break
96             file = os.path.join(str(dir), imp.replace('.', os.sep), '__init__.py')
97             if os.path.exists(file):
98                 results.append(env.File(file))
99                 break
100     return results
101
102 python_scanner = SCons.Scanner.Scanner(function = python_scan, skeys = ['.py'])
103
104
105 def code_generate(env, script, target, source, command):
106     """Method to simplify code generation via python scripts.
107
108     http://www.scons.org/wiki/UsingCodeGenerators
109     http://www.scons.org/doc/0.98.5/HTML/scons-user/c2768.html
110     """
111
112     # We're generating code using Python scripts, so we have to be
113     # careful with our scons elements.  This entry represents
114     # the generator file *in the source directory*.
115     script_src = env.File(script).srcnode()
116
117     # This command creates generated code *in the build directory*.
118     command = command.replace('$SCRIPT', script_src.path)
119     code = env.Command(target, source, command)
120
121     # Explicitly mark that the generated code depends on the generator,
122     # and on implicitly imported python modules
123     path = (script_src.get_dir(),)
124     deps = [script_src]
125     deps += script_src.get_implicit_deps(env, python_scanner, path)
126     env.Depends(code, deps)
127
128     # Running the Python script causes .pyc files to be generated in the
129     # source directory.  When we clean up, they should go too. So add side
130     # effects for .pyc files
131     for dep in deps:
132         pyc = env.File(str(dep) + 'c')
133         env.SideEffect(pyc, code)
134
135     return code
136
137
138 def createCodeGenerateMethod(env):
139     env.Append(SCANNERS = python_scanner)
140     env.AddMethod(code_generate, 'CodeGenerate')
141
142
143 def generate(env):
144     """Common environment generation code"""
145
146     # FIXME: this is already too late
147     #if env.get('quiet', False):
148     #    quietCommandLines(env)
149
150     # shortcuts
151     debug = env['debug']
152     machine = env['machine']
153     platform = env['platform']
154     x86 = env['machine'] == 'x86'
155     gcc = env['platform'] in ('linux', 'freebsd', 'darwin')
156     msvc = env['platform'] in ('windows', 'winddk', 'wince')
157
158     # Tool
159     if platform == 'winddk':
160         env.Tool('winddk')
161     elif platform == 'wince':
162         env.Tool('wcesdk')
163     else:
164         env.Tool('default')
165
166     # Put build output in a separate dir, which depends on the current
167     # configuration. See also http://www.scons.org/wiki/AdvancedBuildExample
168     build_topdir = 'build'
169     build_subdir = env['platform']
170     if env['dri']:
171         build_subdir += "-dri"
172     if env['llvm']:
173         build_subdir += "-llvm"
174     if env['machine'] != 'generic':
175         build_subdir += '-' + env['machine']
176     if env['debug']:
177         build_subdir += "-debug"
178     if env['profile']:
179         build_subdir += "-profile"
180     build_dir = os.path.join(build_topdir, build_subdir)
181     # Place the .sconsign file in the build dir too, to avoid issues with
182     # different scons versions building the same source file
183     env['build'] = build_dir
184     env.SConsignFile(os.path.join(build_dir, '.sconsign'))
185
186     # C preprocessor options
187     cppdefines = []
188     if debug:
189         cppdefines += ['DEBUG']
190     else:
191         cppdefines += ['NDEBUG']
192     if env['profile']:
193         cppdefines += ['PROFILE']
194     if platform == 'windows':
195         cppdefines += [
196             'WIN32',
197             '_WINDOWS',
198             '_UNICODE',
199             'UNICODE',
200             # http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx,
201             'WIN32_LEAN_AND_MEAN',
202             'VC_EXTRALEAN',
203             '_CRT_SECURE_NO_DEPRECATE',
204         ]
205         if debug:
206             cppdefines += ['_DEBUG']
207     if platform == 'winddk':
208         # Mimic WINDDK's builtin flags. See also:
209         # - WINDDK's bin/makefile.new i386mk.inc for more info.
210         # - buildchk_wxp_x86.log files, generated by the WINDDK's build
211         # - http://alter.org.ua/docs/nt_kernel/vc8_proj/
212         cppdefines += [
213             ('_X86_', '1'),
214             ('i386', '1'),
215             'STD_CALL',
216             ('CONDITION_HANDLING', '1'),
217             ('NT_INST', '0'),
218             ('WIN32', '100'),
219             ('_NT1X_', '100'),
220             ('WINNT', '1'),
221             ('_WIN32_WINNT', '0x0501'), # minimum required OS version
222             ('WINVER', '0x0501'),
223             ('_WIN32_IE', '0x0603'),
224             ('WIN32_LEAN_AND_MEAN', '1'),
225             ('DEVL', '1'),
226             ('__BUILDMACHINE__', 'WinDDK'),
227             ('FPO', '0'),
228         ]
229         if debug:
230             cppdefines += [('DBG', 1)]
231     if platform == 'wince':
232         cppdefines += [
233             '_CRT_SECURE_NO_DEPRECATE',
234             '_USE_32BIT_TIME_T',
235             'UNICODE',
236             '_UNICODE',
237             ('UNDER_CE', '600'),
238             ('_WIN32_WCE', '0x600'),
239             'WINCEOEM',
240             'WINCEINTERNAL',
241             'WIN32',
242             'STRICT',
243             'x86',
244             '_X86_',
245             'INTERNATIONAL',
246             ('INTLMSG_CODEPAGE', '1252'),
247         ]
248     if platform == 'windows':
249         cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_USER']
250     if platform == 'winddk':
251         cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_DISPLAY']
252     if platform == 'wince':
253         cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_CE']
254     env.Append(CPPDEFINES = cppdefines)
255
256     # C preprocessor includes
257     if platform == 'winddk':
258         env.Append(CPPPATH = [
259             env['SDK_INC_PATH'],
260             env['DDK_INC_PATH'],
261             env['WDM_INC_PATH'],
262             env['CRT_INC_PATH'],
263         ])
264
265     # C compiler options
266     cflags = []
267     if gcc:
268         if debug:
269             cflags += ['-O0', '-g3']
270         else:
271             cflags += ['-O3', '-g3']
272         if env['profile']:
273             cflags += ['-pg']
274         if env['machine'] == 'x86':
275             cflags += [
276                 '-m32',
277                 #'-march=pentium4',
278                 '-mmmx', '-msse', '-msse2', # enable SIMD intrinsics
279                 #'-mfpmath=sse',
280             ]
281         if env['machine'] == 'x86_64':
282             cflags += ['-m64']
283         cflags += [
284             '-Wall',
285             '-Wmissing-prototypes',
286             '-Wno-long-long',
287             '-ffast-math',
288             '-pedantic',
289             '-fmessage-length=0', # be nice to Eclipse
290         ]
291     if msvc:
292         # See also:
293         # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx
294         # - cl /?
295         if debug:
296             cflags += [
297               '/Od', # disable optimizations
298               '/Oi', # enable intrinsic functions
299               '/Oy-', # disable frame pointer omission
300             ]
301         else:
302             cflags += [
303               '/Ox', # maximum optimizations
304               '/Oi', # enable intrinsic functions
305               '/Os', # favor code space
306             ]
307         if env['profile']:
308             cflags += [
309                 '/Gh', # enable _penter hook function
310                 '/GH', # enable _pexit hook function
311             ]
312         cflags += [
313             '/W3', # warning level
314             #'/Wp64', # enable 64 bit porting warnings
315         ]
316         if platform == 'windows':
317             cflags += [
318                 # TODO
319             ]
320         if platform == 'winddk':
321             cflags += [
322                 '/Zl', # omit default library name in .OBJ
323                 '/Zp8', # 8bytes struct member alignment
324                 '/Gy', # separate functions for linker
325                 '/Gm-', # disable minimal rebuild
326                 '/WX', # treat warnings as errors
327                 '/Gz', # __stdcall Calling convention
328                 '/GX-', # disable C++ EH
329                 '/GR-', # disable C++ RTTI
330                 '/GF', # enable read-only string pooling
331                 '/G6', # optimize for PPro, P-II, P-III
332                 '/Ze', # enable extensions
333                 '/Gi-', # disable incremental compilation
334                 '/QIfdiv-', # disable Pentium FDIV fix
335                 '/hotpatch', # prepares an image for hotpatching.
336                 #'/Z7', #enable old-style debug info
337             ]
338         if platform == 'wince':
339             # See also C:\WINCE600\public\common\oak\misc\makefile.def
340             cflags += [
341                 '/Zl', # omit default library name in .OBJ
342                 '/GF', # enable read-only string pooling
343                 '/GR-', # disable C++ RTTI
344                 '/GS', # enable security checks
345                 # Allow disabling language conformance to maintain backward compat
346                 #'/Zc:wchar_t-', # don't force wchar_t as native type, instead of typedef
347                 #'/Zc:forScope-', # don't enforce Standard C++ for scoping rules
348                 #'/wd4867',
349                 #'/wd4430',
350                 #'/MT',
351                 #'/U_MT',
352             ]
353         # Automatic pdb generation
354         # See http://scons.tigris.org/issues/show_bug.cgi?id=1656
355         env.EnsureSConsVersion(0, 98, 0)
356         env['PDB'] = '${TARGET.base}.pdb'
357     env.Append(CFLAGS = cflags)
358     env.Append(CXXFLAGS = cflags)
359
360     # Assembler options
361     if gcc:
362         if env['machine'] == 'x86':
363             env.Append(ASFLAGS = ['-m32'])
364         if env['machine'] == 'x86_64':
365             env.Append(ASFLAGS = ['-m64'])
366
367     # Linker options
368     linkflags = []
369     if gcc:
370         if env['machine'] == 'x86':
371             linkflags += ['-m32']
372         if env['machine'] == 'x86_64':
373             linkflags += ['-m64']
374     if platform == 'winddk':
375         # See also:
376         # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx
377         linkflags += [
378             '/merge:_PAGE=PAGE',
379             '/merge:_TEXT=.text',
380             '/section:INIT,d',
381             '/opt:ref',
382             '/opt:icf',
383             '/ignore:4198,4010,4037,4039,4065,4070,4078,4087,4089,4221',
384             '/incremental:no',
385             '/fullbuild',
386             '/release',
387             '/nodefaultlib',
388             '/wx',
389             '/debug',
390             '/debugtype:cv',
391             '/version:5.1',
392             '/osversion:5.1',
393             '/functionpadmin:5',
394             '/safeseh',
395             '/pdbcompress',
396             '/stack:0x40000,0x1000',
397             '/driver',
398             '/align:0x80',
399             '/subsystem:native,5.01',
400             '/base:0x10000',
401
402             '/entry:DrvEnableDriver',
403         ]
404         if env['profile']:
405             linkflags += [
406                 '/MAP', # http://msdn.microsoft.com/en-us/library/k7xkk3e2.aspx
407             ]
408     if platform == 'wince':
409         linkflags += [
410             '/nodefaultlib',
411             #'/incremental:no',
412             #'/fullbuild',
413             '/entry:_DllMainCRTStartup',
414         ]
415     env.Append(LINKFLAGS = linkflags)
416
417     # Default libs
418     env.Append(LIBS = [])
419
420     # Custom builders and methods
421     createConvenienceLibBuilder(env)
422     createCodeGenerateMethod(env)
423
424     # for debugging
425     #print env.Dump()
426
427
428 def exists(env):
429     return 1