"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/scons/gallium.py" (16 Sep 2020, 26541 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "gallium.py" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 20.1.6_vs_20.1.7.

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