1 | """gallium
|
---|
2 |
|
---|
3 | Frontend-tool for Gallium3D architecture.
|
---|
4 |
|
---|
5 | """
|
---|
6 |
|
---|
7 | #
|
---|
8 | # Copyright 2008 VMware, Inc.
|
---|
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 VMWARE 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 | import platform as host_platform
|
---|
39 | import sys
|
---|
40 | import tempfile
|
---|
41 |
|
---|
42 | import SCons.Action
|
---|
43 | import SCons.Builder
|
---|
44 | import SCons.Scanner
|
---|
45 |
|
---|
46 |
|
---|
47 | def symlink(target, source, env):
|
---|
48 | target = str(target[0])
|
---|
49 | source = str(source[0])
|
---|
50 | if os.path.islink(target) or os.path.exists(target):
|
---|
51 | os.remove(target)
|
---|
52 | os.symlink(os.path.basename(source), target)
|
---|
53 |
|
---|
54 | def install(env, source, subdir):
|
---|
55 | target_dir = os.path.join(env.Dir('#.').srcnode().abspath, env['build_dir'], subdir)
|
---|
56 | return env.Install(target_dir, source)
|
---|
57 |
|
---|
58 | def install_program(env, source):
|
---|
59 | return install(env, source, 'bin')
|
---|
60 |
|
---|
61 | def install_shared_library(env, sources, version = ()):
|
---|
62 | targets = []
|
---|
63 | install_dir = os.path.join(env.Dir('#.').srcnode().abspath, env['build_dir'])
|
---|
64 | version = tuple(map(str, version))
|
---|
65 | if env['SHLIBSUFFIX'] == '.dll':
|
---|
66 | dlls = env.FindIxes(sources, 'SHLIBPREFIX', 'SHLIBSUFFIX')
|
---|
67 | targets += install(env, dlls, 'bin')
|
---|
68 | libs = env.FindIxes(sources, 'LIBPREFIX', 'LIBSUFFIX')
|
---|
69 | targets += install(env, libs, 'lib')
|
---|
70 | else:
|
---|
71 | for source in sources:
|
---|
72 | target_dir = os.path.join(install_dir, 'lib')
|
---|
73 | target_name = '.'.join((str(source),) + version)
|
---|
74 | last = env.InstallAs(os.path.join(target_dir, target_name), source)
|
---|
75 | targets += last
|
---|
76 | while len(version):
|
---|
77 | version = version[:-1]
|
---|
78 | target_name = '.'.join((str(source),) + version)
|
---|
79 | action = SCons.Action.Action(symlink, " Symlinking $TARGET ...")
|
---|
80 | last = env.Command(os.path.join(target_dir, target_name), last, action)
|
---|
81 | targets += last
|
---|
82 | return targets
|
---|
83 |
|
---|
84 |
|
---|
85 | def msvc2013_compat(env):
|
---|
86 | if env['gcc']:
|
---|
87 | env.Append(CCFLAGS = [
|
---|
88 | '-Werror=vla',
|
---|
89 | '-Werror=pointer-arith',
|
---|
90 | ])
|
---|
91 |
|
---|
92 |
|
---|
93 | def unit_test(env, test_name, program_target, args=None):
|
---|
94 | env.InstallProgram(program_target)
|
---|
95 |
|
---|
96 | cmd = [program_target[0].abspath]
|
---|
97 | if args is not None:
|
---|
98 | cmd += args
|
---|
99 | cmd = ' '.join(cmd)
|
---|
100 |
|
---|
101 | # http://www.scons.org/wiki/UnitTests
|
---|
102 | action = SCons.Action.Action(cmd, " Running $SOURCE ...")
|
---|
103 | alias = env.Alias(test_name, program_target, action)
|
---|
104 | env.AlwaysBuild(alias)
|
---|
105 | env.Depends('check', alias)
|
---|
106 |
|
---|
107 |
|
---|
108 | def num_jobs():
|
---|
109 | try:
|
---|
110 | return int(os.environ['NUMBER_OF_PROCESSORS'])
|
---|
111 | except (ValueError, KeyError):
|
---|
112 | pass
|
---|
113 |
|
---|
114 | try:
|
---|
115 | return os.sysconf('SC_NPROCESSORS_ONLN')
|
---|
116 | except (ValueError, OSError, AttributeError):
|
---|
117 | pass
|
---|
118 |
|
---|
119 | try:
|
---|
120 | return int(os.popen2("sysctl -n hw.ncpu")[1].read())
|
---|
121 | except ValueError:
|
---|
122 | pass
|
---|
123 |
|
---|
124 | return 1
|
---|
125 |
|
---|
126 |
|
---|
127 | def check_cc(env, cc, expr, cpp_opt = '-E'):
|
---|
128 | # Invoke C-preprocessor to determine whether the specified expression is
|
---|
129 | # true or not.
|
---|
130 |
|
---|
131 | sys.stdout.write('Checking for %s ... ' % cc)
|
---|
132 |
|
---|
133 | source = tempfile.NamedTemporaryFile(suffix='.c', delete=False)
|
---|
134 | source.write('#if !(%s)\n#error\n#endif\n' % expr)
|
---|
135 | source.close()
|
---|
136 |
|
---|
137 | pipe = SCons.Action._subproc(env, [env['CC'], cpp_opt, source.name],
|
---|
138 | stdin = 'devnull',
|
---|
139 | stderr = 'devnull',
|
---|
140 | stdout = 'devnull')
|
---|
141 | result = pipe.wait() == 0
|
---|
142 |
|
---|
143 | os.unlink(source.name)
|
---|
144 |
|
---|
145 | sys.stdout.write(' %s\n' % ['no', 'yes'][int(bool(result))])
|
---|
146 | return result
|
---|
147 |
|
---|
148 | def check_header(env, header):
|
---|
149 | '''Check if the header exist'''
|
---|
150 |
|
---|
151 | conf = SCons.Script.Configure(env)
|
---|
152 | have_header = False
|
---|
153 |
|
---|
154 | if conf.CheckHeader(header):
|
---|
155 | have_header = True
|
---|
156 |
|
---|
157 | env = conf.Finish()
|
---|
158 | return have_header
|
---|
159 |
|
---|
160 | def check_functions(env, functions):
|
---|
161 | '''Check if all of the functions exist'''
|
---|
162 |
|
---|
163 | conf = SCons.Script.Configure(env)
|
---|
164 | have_functions = True
|
---|
165 |
|
---|
166 | for function in functions:
|
---|
167 | if not conf.CheckFunc(function):
|
---|
168 | have_functions = False
|
---|
169 |
|
---|
170 | env = conf.Finish()
|
---|
171 | return have_functions
|
---|
172 |
|
---|
173 | def check_prog(env, prog):
|
---|
174 | """Check whether this program exists."""
|
---|
175 |
|
---|
176 | sys.stdout.write('Checking for %s ... ' % prog)
|
---|
177 |
|
---|
178 | result = env.Detect(prog)
|
---|
179 |
|
---|
180 | sys.stdout.write(' %s\n' % ['no', 'yes'][int(bool(result))])
|
---|
181 | return result
|
---|
182 |
|
---|
183 |
|
---|
184 | def generate(env):
|
---|
185 | """Common environment generation code"""
|
---|
186 |
|
---|
187 | # Tell tools which machine to compile for
|
---|
188 | env['TARGET_ARCH'] = env['machine']
|
---|
189 | env['MSVS_ARCH'] = env['machine']
|
---|
190 |
|
---|
191 | # Toolchain
|
---|
192 | platform = env['platform']
|
---|
193 | env.Tool(env['toolchain'])
|
---|
194 |
|
---|
195 | # Allow override compiler and specify additional flags from environment
|
---|
196 | if 'CC' in os.environ:
|
---|
197 | env['CC'] = os.environ['CC']
|
---|
198 | if 'CFLAGS' in os.environ:
|
---|
199 | env['CCFLAGS'] += SCons.Util.CLVar(os.environ['CFLAGS'])
|
---|
200 | if 'CXX' in os.environ:
|
---|
201 | env['CXX'] = os.environ['CXX']
|
---|
202 | if 'CXXFLAGS' in os.environ:
|
---|
203 | env['CXXFLAGS'] += SCons.Util.CLVar(os.environ['CXXFLAGS'])
|
---|
204 | if 'LDFLAGS' in os.environ:
|
---|
205 | env['LINKFLAGS'] += SCons.Util.CLVar(os.environ['LDFLAGS'])
|
---|
206 |
|
---|
207 | # Detect gcc/clang not by executable name, but through pre-defined macros
|
---|
208 | # as autoconf does, to avoid drawing wrong conclusions when using tools
|
---|
209 | # that overrice CC/CXX like scan-build.
|
---|
210 | env['gcc_compat'] = 0
|
---|
211 | env['clang'] = 0
|
---|
212 | env['msvc'] = 0
|
---|
213 | if host_platform.system() == 'Windows':
|
---|
214 | env['msvc'] = check_cc(env, 'MSVC', 'defined(_MSC_VER)', '/E')
|
---|
215 | if not env['msvc']:
|
---|
216 | env['gcc_compat'] = check_cc(env, 'GCC', 'defined(__GNUC__)')
|
---|
217 | env['clang'] = check_cc(env, 'Clang', '__clang__')
|
---|
218 | env['gcc'] = env['gcc_compat'] and not env['clang']
|
---|
219 | env['suncc'] = env['platform'] == 'sunos' and os.path.basename(env['CC']) == 'cc'
|
---|
220 | env['icc'] = 'icc' == os.path.basename(env['CC'])
|
---|
221 |
|
---|
222 | if env['msvc'] and env['toolchain'] == 'default' and env['machine'] == 'x86_64':
|
---|
223 | # MSVC x64 support is broken in earlier versions of scons
|
---|
224 | env.EnsurePythonVersion(2, 0)
|
---|
225 |
|
---|
226 | # shortcuts
|
---|
227 | machine = env['machine']
|
---|
228 | platform = env['platform']
|
---|
229 | x86 = env['machine'] == 'x86'
|
---|
230 | ppc = env['machine'] == 'ppc'
|
---|
231 | gcc_compat = env['gcc_compat']
|
---|
232 | msvc = env['msvc']
|
---|
233 | suncc = env['suncc']
|
---|
234 | icc = env['icc']
|
---|
235 |
|
---|
236 | # Determine whether we are cross compiling; in particular, whether we need
|
---|
237 | # to compile code generators with a different compiler as the target code.
|
---|
238 | hosthost_platform = host_platform.system().lower()
|
---|
239 | if hosthost_platform.startswith('cygwin'):
|
---|
240 | hosthost_platform = 'cygwin'
|
---|
241 | host_machine = os.environ.get('PROCESSOR_ARCHITEW6432', os.environ.get('PROCESSOR_ARCHITECTURE', host_platform.machine()))
|
---|
242 | host_machine = {
|
---|
243 | 'x86': 'x86',
|
---|
244 | 'i386': 'x86',
|
---|
245 | 'i486': 'x86',
|
---|
246 | 'i586': 'x86',
|
---|
247 | 'i686': 'x86',
|
---|
248 | 'ppc' : 'ppc',
|
---|
249 | 'AMD64': 'x86_64',
|
---|
250 | 'x86_64': 'x86_64',
|
---|
251 | }.get(host_machine, 'generic')
|
---|
252 | env['crosscompile'] = platform != hosthost_platform
|
---|
253 | if machine == 'x86_64' and host_machine != 'x86_64':
|
---|
254 | env['crosscompile'] = True
|
---|
255 | env['hostonly'] = False
|
---|
256 |
|
---|
257 | # Backwards compatability with the debug= profile= options
|
---|
258 | if env['build'] == 'debug':
|
---|
259 | if not env['debug']:
|
---|
260 | print('scons: warning: debug option is deprecated and will be removed eventually; use instead')
|
---|
261 | print('')
|
---|
262 | print(' scons build=release')
|
---|
263 | print('')
|
---|
264 | env['build'] = 'release'
|
---|
265 | if env['profile']:
|
---|
266 | print('scons: warning: profile option is deprecated and will be removed eventually; use instead')
|
---|
267 | print('')
|
---|
268 | print(' scons build=profile')
|
---|
269 | print('')
|
---|
270 | env['build'] = 'profile'
|
---|
271 | if False:
|
---|
272 | # Enforce SConscripts to use the new build variable
|
---|
273 | env.popitem('debug')
|
---|
274 | env.popitem('profile')
|
---|
275 | else:
|
---|
276 | # Backwards portability with older sconscripts
|
---|
277 | if env['build'] in ('debug', 'checked'):
|
---|
278 | env['debug'] = True
|
---|
279 | env['profile'] = False
|
---|
280 | if env['build'] == 'profile':
|
---|
281 | env['debug'] = False
|
---|
282 | env['profile'] = True
|
---|
283 | if env['build'] in ('release', 'opt'):
|
---|
284 | env['debug'] = False
|
---|
285 | env['profile'] = False
|
---|
286 |
|
---|
287 | # Put build output in a separate dir, which depends on the current
|
---|
288 | # configuration. See also http://www.scons.org/wiki/AdvancedBuildExample
|
---|
289 | build_topdir = 'build'
|
---|
290 | build_subdir = env['platform']
|
---|
291 | if env['embedded']:
|
---|
292 | build_subdir = 'embedded-' + build_subdir
|
---|
293 | if env['machine'] != 'generic':
|
---|
294 | build_subdir += '-' + env['machine']
|
---|
295 | if env['build'] != 'release':
|
---|
296 | build_subdir += '-' + env['build']
|
---|
297 | build_dir = os.path.join(build_topdir, build_subdir)
|
---|
298 | # Place the .sconsign file in the build dir too, to avoid issues with
|
---|
299 | # different scons versions building the same source file
|
---|
300 | env['build_dir'] = build_dir
|
---|
301 | env.SConsignFile(os.path.join(build_dir, '.sconsign'))
|
---|
302 | if 'SCONS_CACHE_DIR' in os.environ:
|
---|
303 | print('scons: Using build cache in %s.' % (os.environ['SCONS_CACHE_DIR'],))
|
---|
304 | env.CacheDir(os.environ['SCONS_CACHE_DIR'])
|
---|
305 | env['CONFIGUREDIR'] = os.path.join(build_dir, 'conf')
|
---|
306 | env['CONFIGURELOG'] = os.path.join(os.path.abspath(build_dir), 'config.log')
|
---|
307 |
|
---|
308 | # Parallel build
|
---|
309 | if env.GetOption('num_jobs') <= 1:
|
---|
310 | env.SetOption('num_jobs', num_jobs())
|
---|
311 |
|
---|
312 | env.Decider('MD5-timestamp')
|
---|
313 | env.SetOption('max_drift', 60)
|
---|
314 |
|
---|
315 | # C preprocessor options
|
---|
316 | cppdefines = []
|
---|
317 | cppdefines += [
|
---|
318 | '__STDC_CONSTANT_MACROS',
|
---|
319 | '__STDC_FORMAT_MACROS',
|
---|
320 | '__STDC_LIMIT_MACROS',
|
---|
321 | 'HAVE_NO_AUTOCONF',
|
---|
322 | ]
|
---|
323 | if env['build'] in ('debug', 'checked'):
|
---|
324 | cppdefines += ['DEBUG']
|
---|
325 | else:
|
---|
326 | cppdefines += ['NDEBUG']
|
---|
327 | if env['build'] == 'profile':
|
---|
328 | cppdefines += ['PROFILE']
|
---|
329 | if env['build'] in ('opt', 'profile'):
|
---|
330 | cppdefines += ['VMX86_STATS']
|
---|
331 | if env['platform'] in ('posix', 'linux', 'freebsd', 'darwin'):
|
---|
332 | cppdefines += [
|
---|
333 | '_POSIX_SOURCE',
|
---|
334 | ('_POSIX_C_SOURCE', '199309L'),
|
---|
335 | '_SVID_SOURCE',
|
---|
336 | '_BSD_SOURCE',
|
---|
337 | '_GNU_SOURCE',
|
---|
338 | '_DEFAULT_SOURCE',
|
---|
339 | ]
|
---|
340 | if env['platform'] == 'darwin':
|
---|
341 | cppdefines += [
|
---|
342 | '_DARWIN_C_SOURCE',
|
---|
343 | 'GLX_USE_APPLEGL',
|
---|
344 | 'GLX_DIRECT_RENDERING',
|
---|
345 | ]
|
---|
346 | else:
|
---|
347 | cppdefines += [
|
---|
348 | 'GLX_DIRECT_RENDERING',
|
---|
349 | 'GLX_INDIRECT_RENDERING',
|
---|
350 | ]
|
---|
351 |
|
---|
352 | if check_header(env, 'xlocale.h'):
|
---|
353 | cppdefines += ['HAVE_XLOCALE_H']
|
---|
354 |
|
---|
355 | if check_header(env, 'endian.h'):
|
---|
356 | cppdefines += ['HAVE_ENDIAN_H']
|
---|
357 |
|
---|
358 | if check_functions(env, ['strtod_l', 'strtof_l']):
|
---|
359 | cppdefines += ['HAVE_STRTOD_L']
|
---|
360 |
|
---|
361 | if platform == 'windows':
|
---|
362 | cppdefines += [
|
---|
363 | 'WIN32',
|
---|
364 | '_WINDOWS',
|
---|
365 | #'_UNICODE',
|
---|
366 | #'UNICODE',
|
---|
367 | # http://msdn.microsoft.com/en-us/library/aa383745.aspx
|
---|
368 | ('_WIN32_WINNT', '0x0601'),
|
---|
369 | ('WINVER', '0x0601'),
|
---|
370 | ]
|
---|
371 | if gcc_compat:
|
---|
372 | cppdefines += [('__MSVCRT_VERSION__', '0x0700')]
|
---|
373 | if msvc:
|
---|
374 | cppdefines += [
|
---|
375 | 'VC_EXTRALEAN',
|
---|
376 | '_USE_MATH_DEFINES',
|
---|
377 | '_CRT_SECURE_NO_WARNINGS',
|
---|
378 | '_CRT_SECURE_NO_DEPRECATE',
|
---|
379 | '_SCL_SECURE_NO_WARNINGS',
|
---|
380 | '_SCL_SECURE_NO_DEPRECATE',
|
---|
381 | '_ALLOW_KEYWORD_MACROS',
|
---|
382 | '_HAS_EXCEPTIONS=0', # Tell C++ STL to not use exceptions
|
---|
383 | ]
|
---|
384 | if env['build'] in ('debug', 'checked'):
|
---|
385 | cppdefines += ['_DEBUG']
|
---|
386 | if platform == 'windows':
|
---|
387 | cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_USER']
|
---|
388 | if env['embedded']:
|
---|
389 | cppdefines += ['PIPE_SUBSYSTEM_EMBEDDED']
|
---|
390 | if env['texture_float']:
|
---|
391 | print('warning: Floating-point textures enabled.')
|
---|
392 | print('warning: Please consult docs/patents.txt with your lawyer before building Mesa.')
|
---|
393 | cppdefines += ['TEXTURE_FLOAT_ENABLED']
|
---|
394 | env.Append(CPPDEFINES = cppdefines)
|
---|
395 |
|
---|
396 | # C compiler options
|
---|
397 | cflags = [] # C
|
---|
398 | cxxflags = [] # C++
|
---|
399 | ccflags = [] # C & C++
|
---|
400 | if gcc_compat:
|
---|
401 | if env['build'] == 'debug':
|
---|
402 | ccflags += ['-O0']
|
---|
403 | else:
|
---|
404 | ccflags += ['-O3']
|
---|
405 | if env['gcc']:
|
---|
406 | # gcc's builtin memcmp is slower than glibc's
|
---|
407 | # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43052
|
---|
408 | ccflags += ['-fno-builtin-memcmp']
|
---|
409 | # Work around aliasing bugs - developers should comment this out
|
---|
410 | ccflags += ['-fno-strict-aliasing']
|
---|
411 | ccflags += ['-g']
|
---|
412 | if env['build'] in ('checked', 'profile') or env['asan']:
|
---|
413 | # See http://code.google.com/p/jrfonseca/wiki/Gprof2Dot#Which_options_should_I_pass_to_gcc_when_compiling_for_profiling?
|
---|
414 | ccflags += [
|
---|
415 | '-fno-omit-frame-pointer',
|
---|
416 | ]
|
---|
417 | if env['gcc']:
|
---|
418 | ccflags += ['-fno-optimize-sibling-calls']
|
---|
419 | if env['machine'] == 'x86':
|
---|
420 | ccflags += [
|
---|
421 | '-m32',
|
---|
422 | #'-march=pentium4',
|
---|
423 | ]
|
---|
424 | if platform != 'haiku':
|
---|
425 | # NOTE: We need to ensure stack is realigned given that we
|
---|
426 | # produce shared objects, and have no control over the stack
|
---|
427 | # alignment policy of the application. Therefore we need
|
---|
428 | # -mstackrealign ore -mincoming-stack-boundary=2.
|
---|
429 | #
|
---|
430 | # XXX: We could have SSE without -mstackrealign if we always used
|
---|
431 | # __attribute__((force_align_arg_pointer)), but that's not
|
---|
432 | # always the case.
|
---|
433 | ccflags += [
|
---|
434 | '-mstackrealign', # ensure stack is aligned
|
---|
435 | '-msse', '-msse2', # enable SIMD intrinsics
|
---|
436 | '-mfpmath=sse', # generate SSE floating-point arithmetic
|
---|
437 | ]
|
---|
438 | if platform in ['windows', 'darwin']:
|
---|
439 | # Workaround http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37216
|
---|
440 | ccflags += ['-fno-common']
|
---|
441 | if platform in ['haiku']:
|
---|
442 | # Make optimizations compatible with Pentium or higher on Haiku
|
---|
443 | ccflags += [
|
---|
444 | '-mstackrealign', # ensure stack is aligned
|
---|
445 | '-march=i586', # Haiku target is Pentium
|
---|
446 | '-mtune=i686' # use i686 where we can
|
---|
447 | ]
|
---|
448 | if env['machine'] == 'x86_64':
|
---|
449 | ccflags += ['-m64']
|
---|
450 | if platform == 'darwin':
|
---|
451 | ccflags += ['-fno-common']
|
---|
452 | if env['platform'] not in ('cygwin', 'haiku', 'windows'):
|
---|
453 | ccflags += ['-fvisibility=hidden']
|
---|
454 | # See also:
|
---|
455 | # - http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
|
---|
456 | ccflags += [
|
---|
457 | '-Wall',
|
---|
458 | '-Wno-long-long',
|
---|
459 | '-fmessage-length=0', # be nice to Eclipse
|
---|
460 | ]
|
---|
461 | cflags += [
|
---|
462 | '-Wmissing-prototypes',
|
---|
463 | '-std=gnu99',
|
---|
464 | ]
|
---|
465 | if icc:
|
---|
466 | cflags += [
|
---|
467 | '-std=gnu99',
|
---|
468 | ]
|
---|
469 | if msvc:
|
---|
470 | # See also:
|
---|
471 | # - http://msdn.microsoft.com/en-us/library/19z1t1wy.aspx
|
---|
472 | # - cl /?
|
---|
473 | if env['build'] == 'debug':
|
---|
474 | ccflags += [
|
---|
475 | '/Od', # disable optimizations
|
---|
476 | '/Oi', # enable intrinsic functions
|
---|
477 | ]
|
---|
478 | else:
|
---|
479 | ccflags += [
|
---|
480 | '/O2', # optimize for speed
|
---|
481 | ]
|
---|
482 | if env['build'] in ('release', 'opt'):
|
---|
483 | if not env['clang']:
|
---|
484 | ccflags += [
|
---|
485 | '/GL', # enable whole program optimization
|
---|
486 | ]
|
---|
487 | else:
|
---|
488 | ccflags += [
|
---|
489 | '/Oy-', # disable frame pointer omission
|
---|
490 | ]
|
---|
491 | ccflags += [
|
---|
492 | '/W3', # warning level
|
---|
493 | '/wd4018', # signed/unsigned mismatch
|
---|
494 | '/wd4056', # overflow in floating-point constant arithmetic
|
---|
495 | '/wd4244', # conversion from 'type1' to 'type2', possible loss of data
|
---|
496 | '/wd4267', # 'var' : conversion from 'size_t' to 'type', possible loss of data
|
---|
497 | '/wd4305', # truncation from 'type1' to 'type2'
|
---|
498 | '/wd4351', # new behavior: elements of array 'array' will be default initialized
|
---|
499 | '/wd4756', # overflow in constant arithmetic
|
---|
500 | '/wd4800', # forcing value to bool 'true' or 'false' (performance warning)
|
---|
501 | '/wd4996', # disable deprecated POSIX name warnings
|
---|
502 | ]
|
---|
503 | if env['clang']:
|
---|
504 | ccflags += [
|
---|
505 | '-Wno-microsoft-enum-value', # enumerator value is not representable in underlying type 'int'
|
---|
506 | ]
|
---|
507 | if env['machine'] == 'x86':
|
---|
508 | ccflags += [
|
---|
509 | '/arch:SSE2', # use the SSE2 instructions (default since MSVC 2012)
|
---|
510 | ]
|
---|
511 | if platform == 'windows':
|
---|
512 | ccflags += [
|
---|
513 | # TODO
|
---|
514 | ]
|
---|
515 | # Automatic pdb generation
|
---|
516 | # See http://scons.tigris.org/issues/show_bug.cgi?id=1656
|
---|
517 | env.EnsureSConsVersion(0, 98, 0)
|
---|
518 | env['PDB'] = '${TARGET.base}.pdb'
|
---|
519 | env.Append(CCFLAGS = ccflags)
|
---|
520 | env.Append(CFLAGS = cflags)
|
---|
521 | env.Append(CXXFLAGS = cxxflags)
|
---|
522 |
|
---|
523 | if env['platform'] == 'windows' and msvc:
|
---|
524 | # Choose the appropriate MSVC CRT
|
---|
525 | # http://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx
|
---|
526 | if env['build'] in ('debug', 'checked'):
|
---|
527 | env.Append(CCFLAGS = ['/MTd'])
|
---|
528 | env.Append(SHCCFLAGS = ['/LDd'])
|
---|
529 | else:
|
---|
530 | env.Append(CCFLAGS = ['/MT'])
|
---|
531 | env.Append(SHCCFLAGS = ['/LD'])
|
---|
532 |
|
---|
533 | # Static code analysis
|
---|
534 | if env['analyze']:
|
---|
535 | if env['msvc']:
|
---|
536 | # http://msdn.microsoft.com/en-us/library/ms173498.aspx
|
---|
537 | env.Append(CCFLAGS = [
|
---|
538 | '/analyze',
|
---|
539 | #'/analyze:log', '${TARGET.base}.xml',
|
---|
540 | '/wd28251', # Inconsistent annotation for function
|
---|
541 | ])
|
---|
542 | if env['clang']:
|
---|
543 | # scan-build will produce more comprehensive output
|
---|
544 | env.Append(CCFLAGS = ['--analyze'])
|
---|
545 |
|
---|
546 | # https://github.com/google/sanitizers/wiki/AddressSanitizer
|
---|
547 | if env['asan']:
|
---|
548 | if gcc_compat:
|
---|
549 | env.Append(CCFLAGS = [
|
---|
550 | '-fsanitize=address',
|
---|
551 | ])
|
---|
552 | env.Append(LINKFLAGS = [
|
---|
553 | '-fsanitize=address',
|
---|
554 | ])
|
---|
555 |
|
---|
556 | # Assembler options
|
---|
557 | if gcc_compat:
|
---|
558 | if env['machine'] == 'x86':
|
---|
559 | env.Append(ASFLAGS = ['-m32'])
|
---|
560 | if env['machine'] == 'x86_64':
|
---|
561 | env.Append(ASFLAGS = ['-m64'])
|
---|
562 |
|
---|
563 | # Linker options
|
---|
564 | linkflags = []
|
---|
565 | shlinkflags = []
|
---|
566 | if gcc_compat:
|
---|
567 | if env['machine'] == 'x86':
|
---|
568 | linkflags += ['-m32']
|
---|
569 | if env['machine'] == 'x86_64':
|
---|
570 | linkflags += ['-m64']
|
---|
571 | if env['platform'] not in ('darwin'):
|
---|
572 | shlinkflags += [
|
---|
573 | '-Wl,-Bsymbolic',
|
---|
574 | ]
|
---|
575 | # Handle circular dependencies in the libraries
|
---|
576 | if env['platform'] in ('darwin'):
|
---|
577 | pass
|
---|
578 | else:
|
---|
579 | env['_LIBFLAGS'] = '-Wl,--start-group ' + env['_LIBFLAGS'] + ' -Wl,--end-group'
|
---|
580 | if env['platform'] == 'windows':
|
---|
581 | linkflags += [
|
---|
582 | '-Wl,--nxcompat', # DEP
|
---|
583 | '-Wl,--dynamicbase', # ASLR
|
---|
584 | ]
|
---|
585 | # Avoid depending on gcc runtime DLLs
|
---|
586 | linkflags += ['-static-libgcc']
|
---|
587 | if 'w64' in env['CC'].split('-'):
|
---|
588 | linkflags += ['-static-libstdc++']
|
---|
589 | # Handle the @xx symbol munging of DLL exports
|
---|
590 | shlinkflags += ['-Wl,--enable-stdcall-fixup']
|
---|
591 | #shlinkflags += ['-Wl,--kill-at']
|
---|
592 | if msvc:
|
---|
593 | if env['build'] in ('release', 'opt') and not env['clang']:
|
---|
594 | # enable Link-time Code Generation
|
---|
595 | linkflags += ['/LTCG']
|
---|
596 | env.Append(ARFLAGS = ['/LTCG'])
|
---|
597 | if platform == 'windows' and msvc:
|
---|
598 | # See also:
|
---|
599 | # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx
|
---|
600 | linkflags += [
|
---|
601 | '/fixed:no',
|
---|
602 | '/incremental:no',
|
---|
603 | '/dynamicbase', # ASLR
|
---|
604 | '/nxcompat', # DEP
|
---|
605 | ]
|
---|
606 | env.Append(LINKFLAGS = linkflags)
|
---|
607 | env.Append(SHLINKFLAGS = shlinkflags)
|
---|
608 |
|
---|
609 | # We have C++ in several libraries, so always link with the C++ compiler
|
---|
610 | if gcc_compat:
|
---|
611 | env['LINK'] = env['CXX']
|
---|
612 |
|
---|
613 | # Default libs
|
---|
614 | libs = []
|
---|
615 | if env['platform'] in ('darwin', 'freebsd', 'linux', 'posix', 'sunos'):
|
---|
616 | libs += ['m', 'pthread', 'dl']
|
---|
617 | if env['platform'] in ('linux',):
|
---|
618 | libs += ['rt']
|
---|
619 | if env['platform'] in ('haiku'):
|
---|
620 | libs += ['root', 'be', 'network', 'translation']
|
---|
621 | env.Append(LIBS = libs)
|
---|
622 |
|
---|
623 | # OpenMP
|
---|
624 | if env['openmp']:
|
---|
625 | if env['msvc']:
|
---|
626 | env.Append(CCFLAGS = ['/openmp'])
|
---|
627 | # When building openmp release VS2008 link.exe crashes with LNK1103 error.
|
---|
628 | # Workaround: overwrite PDB flags with empty value as it isn't required anyways
|
---|
629 | if env['build'] == 'release':
|
---|
630 | env['PDB'] = ''
|
---|
631 | if env['gcc']:
|
---|
632 | env.Append(CCFLAGS = ['-fopenmp'])
|
---|
633 | env.Append(LIBS = ['gomp'])
|
---|
634 |
|
---|
635 | # Load tools
|
---|
636 | env.Tool('lex')
|
---|
637 | if env['msvc']:
|
---|
638 | env.Append(LEXFLAGS = [
|
---|
639 | # Force flex to use const keyword in prototypes, as relies on
|
---|
640 | # __cplusplus or __STDC__ macro to determine whether it's safe to
|
---|
641 | # use const keyword, but MSVC never defines __STDC__ unless we
|
---|
642 | # disable all MSVC extensions.
|
---|
643 | '-DYY_USE_CONST=',
|
---|
644 | ])
|
---|
645 | # Flex relies on __STDC_VERSION__>=199901L to decide when to include
|
---|
646 | # C99 inttypes.h. We always have inttypes.h available with MSVC
|
---|
647 | # (either the one bundled with MSVC 2013, or the one we bundle
|
---|
648 | # ourselves), but we can't just define __STDC_VERSION__ without
|
---|
649 | # breaking stuff, as MSVC doesn't fully support C99. There's also no
|
---|
650 | # way to premptively include stdint.
|
---|
651 | env.Append(CCFLAGS = ['-FIinttypes.h'])
|
---|
652 | if host_platform.system() == 'Windows':
|
---|
653 | # Prefer winflexbison binaries, as not only they are easier to install
|
---|
654 | # (no additional dependencies), but also better Windows support.
|
---|
655 | if check_prog(env, 'win_flex'):
|
---|
656 | env["LEX"] = 'win_flex'
|
---|
657 | env.Append(LEXFLAGS = [
|
---|
658 | # windows compatibility (uses <io.h> instead of <unistd.h> and
|
---|
659 | # _isatty, _fileno functions)
|
---|
660 | '--wincompat'
|
---|
661 | ])
|
---|
662 |
|
---|
663 | env.Tool('yacc')
|
---|
664 | if host_platform.system() == 'Windows':
|
---|
665 | if check_prog(env, 'win_bison'):
|
---|
666 | env["YACC"] = 'win_bison'
|
---|
667 |
|
---|
668 | if env['llvm']:
|
---|
669 | env.Tool('llvm')
|
---|
670 |
|
---|
671 | # Custom builders and methods
|
---|
672 | env.Tool('custom')
|
---|
673 | env.AddMethod(install_program, 'InstallProgram')
|
---|
674 | env.AddMethod(install_shared_library, 'InstallSharedLibrary')
|
---|
675 | env.AddMethod(msvc2013_compat, 'MSVC2013Compat')
|
---|
676 | env.AddMethod(unit_test, 'UnitTest')
|
---|
677 |
|
---|
678 | env.PkgCheckModules('X11', ['x11', 'xext', 'xdamage >= 1.1', 'xfixes', 'glproto >= 1.4.13', 'dri2proto >= 2.8'])
|
---|
679 | env.PkgCheckModules('XCB', ['x11-xcb', 'xcb-glx >= 1.8.1', 'xcb-dri2 >= 1.8'])
|
---|
680 | env.PkgCheckModules('XF86VIDMODE', ['xxf86vm'])
|
---|
681 | env.PkgCheckModules('DRM', ['libdrm >= 2.4.75'])
|
---|
682 |
|
---|
683 | if env['x11']:
|
---|
684 | env.Append(CPPPATH = env['X11_CPPPATH'])
|
---|
685 |
|
---|
686 | env['dri'] = env['x11'] and env['drm']
|
---|
687 |
|
---|
688 | # for debugging
|
---|
689 | #print env.Dump()
|
---|
690 |
|
---|
691 |
|
---|
692 | def exists(env):
|
---|
693 | return 1
|
---|