scons: Use '-Werror=' option on GCC 4.2.x and greater.
[mesa.git] / scons / gallium.py
index 38782ac7266f5535d3f006de9e8a2757a945fbb6..c88af96898ba96dd2570bc99cc12228c31a3ccd8 100644 (file)
@@ -30,6 +30,7 @@ Frontend-tool for Gallium3D architecture.
 #
 
 
+import distutils.version
 import os
 import os.path
 import re
@@ -38,116 +39,6 @@ import SCons.Action
 import SCons.Builder
 import SCons.Scanner
 
-import fixes
-
-
-def quietCommandLines(env):
-    # Quiet command lines
-    # See also http://www.scons.org/wiki/HidingCommandLinesInOutput
-    env['ASCOMSTR'] = "  Assembling $SOURCE ..."
-    env['ASPPCOMSTR'] = "  Assembling $SOURCE ..."
-    env['CCCOMSTR'] = "  Compiling $SOURCE ..."
-    env['SHCCCOMSTR'] = "  Compiling $SOURCE ..."
-    env['CXXCOMSTR'] = "  Compiling $SOURCE ..."
-    env['SHCXXCOMSTR'] = "  Compiling $SOURCE ..."
-    env['ARCOMSTR'] = "  Archiving $TARGET ..."
-    env['RANLIBCOMSTR'] = "  Indexing $TARGET ..."
-    env['LINKCOMSTR'] = "  Linking $TARGET ..."
-    env['SHLINKCOMSTR'] = "  Linking $TARGET ..."
-    env['LDMODULECOMSTR'] = "  Linking $TARGET ..."
-    env['SWIGCOMSTR'] = "  Generating $TARGET ..."
-
-
-def createConvenienceLibBuilder(env):
-    """This is a utility function that creates the ConvenienceLibrary
-    Builder in an Environment if it is not there already.
-
-    If it is already there, we return the existing one.
-
-    Based on the stock StaticLibrary and SharedLibrary builders.
-    """
-
-    try:
-        convenience_lib = env['BUILDERS']['ConvenienceLibrary']
-    except KeyError:
-        action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ]
-        if env.Detect('ranlib'):
-            ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR")
-            action_list.append(ranlib_action)
-
-        convenience_lib = SCons.Builder.Builder(action = action_list,
-                                  emitter = '$LIBEMITTER',
-                                  prefix = '$LIBPREFIX',
-                                  suffix = '$LIBSUFFIX',
-                                  src_suffix = '$SHOBJSUFFIX',
-                                  src_builder = 'SharedObject')
-        env['BUILDERS']['ConvenienceLibrary'] = convenience_lib
-
-    return convenience_lib
-
-
-# TODO: handle import statements with multiple modules
-# TODO: handle from import statements
-import_re = re.compile(r'^import\s+(\S+)$', re.M)
-
-def python_scan(node, env, path):
-    # http://www.scons.org/doc/0.98.5/HTML/scons-user/c2781.html#AEN2789
-    contents = node.get_contents()
-    source_dir = node.get_dir()
-    imports = import_re.findall(contents)
-    results = []
-    for imp in imports:
-        for dir in path:
-            file = os.path.join(str(dir), imp.replace('.', os.sep) + '.py')
-            if os.path.exists(file):
-                results.append(env.File(file))
-                break
-            file = os.path.join(str(dir), imp.replace('.', os.sep), '__init__.py')
-            if os.path.exists(file):
-                results.append(env.File(file))
-                break
-    return results
-
-python_scanner = SCons.Scanner.Scanner(function = python_scan, skeys = ['.py'])
-
-
-def code_generate(env, script, target, source, command):
-    """Method to simplify code generation via python scripts.
-
-    http://www.scons.org/wiki/UsingCodeGenerators
-    http://www.scons.org/doc/0.98.5/HTML/scons-user/c2768.html
-    """
-
-    # We're generating code using Python scripts, so we have to be
-    # careful with our scons elements.  This entry represents
-    # the generator file *in the source directory*.
-    script_src = env.File(script).srcnode()
-
-    # This command creates generated code *in the build directory*.
-    command = command.replace('$SCRIPT', script_src.path)
-    code = env.Command(target, source, command)
-
-    # Explicitly mark that the generated code depends on the generator,
-    # and on implicitly imported python modules
-    path = (script_src.get_dir(),)
-    deps = [script_src]
-    deps += script_src.get_implicit_deps(env, python_scanner, path)
-    env.Depends(code, deps)
-
-    # Running the Python script causes .pyc files to be generated in the
-    # source directory.  When we clean up, they should go too. So add side
-    # effects for .pyc files
-    for dep in deps:
-        pyc = env.File(str(dep) + 'c')
-        env.SideEffect(pyc, code)
-
-    return code
-
-
-def createCodeGenerateMethod(env):
-    env.Append(SCANNERS = python_scanner)
-    env.AddMethod(code_generate, 'CodeGenerate')
-
 
 def symlink(target, source, env):
     target = str(target[0])
@@ -156,19 +47,34 @@ def symlink(target, source, env):
         os.remove(target)
     os.symlink(os.path.basename(source), target)
 
-def install_shared_library(env, source, version = ()):
-    source = str(source[0])
+def install(env, source, subdir):
+    target_dir = os.path.join(env.Dir('#.').srcnode().abspath, env['build'], subdir)
+    env.Install(target_dir, source)
+
+def install_program(env, source):
+    install(env, source, 'bin')
+
+def install_shared_library(env, sources, version = ()):
+    install_dir = os.path.join(env.Dir('#.').srcnode().abspath, env['build'])
     version = tuple(map(str, version))
-    target_dir =  os.path.join(env.Dir('#.').srcnode().abspath, env['build'], 'lib')
-    target_name = '.'.join((str(source),) + version)
-    last = env.InstallAs(os.path.join(target_dir, target_name), source)
-    while len(version):
-        version = version[:-1]
-        target_name = '.'.join((str(source),) + version)
-        action = SCons.Action.Action(symlink, "$TARGET -> $SOURCE")
-        last = env.Command(os.path.join(target_dir, target_name), last, action) 
+    if env['SHLIBSUFFIX'] == '.dll':
+        dlls = env.FindIxes(sources, 'SHLIBPREFIX', 'SHLIBSUFFIX')
+        install(env, dlls, 'bin')
+        libs = env.FindIxes(sources, 'LIBPREFIX', 'LIBSUFFIX')
+        install(env, libs, 'lib')
+    else:
+        for source in sources:
+            target_dir =  os.path.join(install_dir, 'lib')
+            target_name = '.'.join((str(source),) + version)
+            last = env.InstallAs(os.path.join(target_dir, target_name), source)
+            while len(version):
+                version = version[:-1]
+                target_name = '.'.join((str(source),) + version)
+                action = SCons.Action.Action(symlink, "$TARGET -> $SOURCE")
+                last = env.Command(os.path.join(target_dir, target_name), last, action) 
 
 def createInstallMethods(env):
+    env.AddMethod(install_program, 'InstallProgram')
     env.AddMethod(install_shared_library, 'InstallSharedLibrary')
 
 
@@ -194,9 +100,6 @@ def num_jobs():
 def generate(env):
     """Common environment generation code"""
 
-    if env.get('quiet', True):
-        quietCommandLines(env)
-
     # Toolchain
     platform = env['platform']
     if env['toolchain'] == 'default':
@@ -236,6 +139,8 @@ def generate(env):
     env['build'] = build_dir
     env.SConsignFile(os.path.join(build_dir, '.sconsign'))
     env.CacheDir('build/cache')
+    env['CONFIGUREDIR'] = os.path.join(build_dir, 'conf')
+    env['CONFIGURELOG'] = os.path.join(os.path.abspath(build_dir), 'config.log')
 
     # Parallel build
     if env.GetOption('num_jobs') <= 1:
@@ -257,13 +162,15 @@ def generate(env):
             #'UNICODE',
             ('_WIN32_WINNT', '0x0501'), # minimum required OS version
             ('WINVER', '0x0501'),
-            # http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx,
-            'WIN32_LEAN_AND_MEAN',
         ]
         if msvc and env['toolchain'] != 'winddk':
             cppdefines += [
                 'VC_EXTRALEAN',
+                '_USE_MATH_DEFINES',
+                '_CRT_SECURE_NO_WARNINGS',
                 '_CRT_SECURE_NO_DEPRECATE',
+                '_SCL_SECURE_NO_WARNINGS',
+                '_SCL_SECURE_NO_DEPRECATE',
             ]
         if debug:
             cppdefines += ['_DEBUG']
@@ -343,10 +250,18 @@ def generate(env):
             ccflags += [
                 '-m32',
                 #'-march=pentium4',
-                '-mmmx', '-msse', '-msse2', # enable SIMD intrinsics
-                '-mstackrealign', # ensure stack is aligned -- do not enabled -msse without it!
                 #'-mfpmath=sse',
             ]
+            if platform != 'windows':
+                # XXX: -mstackrealign causes stack corruption on MinGW. Ditto
+                # for -mincoming-stack-boundary=2.  Still enable it on other
+                # platforms for now, but we can't rely on it for cross platform
+                # code. We have to use __attribute__((force_align_arg_pointer))
+                # instead.
+                ccflags += [
+                    '-mmmx', '-msse', '-msse2', # enable SIMD intrinsics
+                    '-mstackrealign', # ensure stack is aligned
+                ]
         if env['machine'] == 'x86_64':
             ccflags += ['-m64']
         # See also:
@@ -354,16 +269,21 @@ def generate(env):
         ccflags += [
             '-Wall',
             '-Wmissing-field-initializers',
-            '-Wpointer-arith',
             '-Wno-long-long',
             '-ffast-math',
             '-fmessage-length=0', # be nice to Eclipse
         ]
         cflags += [
-            '-Werror=declaration-after-statement',
             '-Wmissing-prototypes',
             '-std=gnu99',
         ]
+        if distutils.version.LooseVersion(env['CCVERSION']) >= distutils.version.LooseVersion('4.2'):
+           ccflags += [
+               '-Werror=pointer-arith',
+           ]
+           cflags += [
+               '-Werror=declaration-after-statement',
+           ]
     if msvc:
         # See also:
         # - http://msdn.microsoft.com/en-us/library/19z1t1wy.aspx
@@ -378,20 +298,15 @@ def generate(env):
         else:
             ccflags += [
                 '/O2', # optimize for speed
-                #'/fp:fast', # fast floating point 
-            ]
-        if env['profile']:
-            ccflags += [
-                '/Gh', # enable _penter hook function
-                '/GH', # enable _pexit hook function
+                '/GL', # enable whole program optimization
             ]
         ccflags += [
+            '/fp:fast', # fast floating point 
             '/W3', # warning level
             #'/Wp64', # enable 64 bit porting warnings
         ]
         if env['machine'] == 'x86':
             ccflags += [
-                #'/QIfist', # Suppress _ftol
                 #'/arch:SSE2', # use the SSE2 instructions
             ]
         if platform == 'windows':
@@ -468,7 +383,15 @@ def generate(env):
             '-Wl,-Bsymbolic',
         ]
         # Handle circular dependencies in the libraries
-        env['_LIBFLAGS'] = '-Wl,--start-group ' + env['_LIBFLAGS'] + ' -Wl,--end-group'
+        if env['platform'] in ('darwin'):
+            pass
+        else:
+            env['_LIBFLAGS'] = '-Wl,--start-group ' + env['_LIBFLAGS'] + ' -Wl,--end-group'
+    if msvc:
+        if not env['debug']:
+            # enable Link-time Code Generation
+            linkflags += ['/LTCG']
+            env.Append(ARFLAGS = ['/LTCG'])
     if platform == 'windows' and msvc:
         # See also:
         # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx
@@ -522,8 +445,7 @@ def generate(env):
     env.Append(LIBS = [])
 
     # Custom builders and methods
-    createConvenienceLibBuilder(env)
-    createCodeGenerateMethod(env)
+    env.Tool('custom')
     createInstallMethods(env)
 
     # for debugging