radeonsi: add a common function for getting the size of gs_ngg_scratch
[mesa.git] / scons / custom.py
index 39a5333fd014ec4b6e89dc301fb08dbd89bbf05d..2fad8f5b6d4398dfb0fe18c771579b8194f71192 100644 (file)
@@ -5,7 +5,7 @@ Custom builders and methods.
 """
 
 #
-# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+# Copyright 2008 VMware, Inc.
 # All Rights Reserved.
 #
 # Permission is hereby granted, free of charge, to any person obtaining a
@@ -23,18 +23,17 @@ Custom builders and methods.
 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-# IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+# IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
 # ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
 
 
-import os
 import os.path
-import re
 import sys
 import subprocess
+import modulefinder
 
 import SCons.Action
 import SCons.Builder
@@ -44,6 +43,18 @@ import fixes
 
 import source_list
 
+# the get_implicit_deps() method changed between 2.4 and 2.5: now it expects
+# a callable that takes a scanner as argument and returns a path, rather than
+# a path directly. We want to support both, so we need to detect the SCons version,
+# for which no API is provided by SCons 8-P
+
+# Scons version string has consistently been in this format:
+# MajorVersion.MinorVersion.Patch[.alpha/beta.yyyymmdd]
+# so this formula should cover all versions regardless of type
+# stable, alpha or beta.
+# For simplicity alpha and beta flags are removed.
+scons_version = tuple(map(int, SCons.__version__.split('.')[:3]))
+
 def quietCommandLines(env):
     # Quiet command lines
     # See also http://www.scons.org/wiki/HidingCommandLinesInOutput
@@ -93,27 +104,25 @@ def createConvenienceLibBuilder(env):
     return convenience_lib
 
 
-# TODO: handle import statements with multiple modules
-# TODO: handle from import statements
-import_re = re.compile(r'^\s*import\s+(\S+)\s*$', re.M)
-
 def python_scan(node, env, path):
     # http://www.scons.org/doc/0.98.5/HTML/scons-user/c2781.html#AEN2789
+    # https://docs.python.org/2/library/modulefinder.html
     contents = node.get_contents()
-    source_dir = node.get_dir()
-    imports = import_re.findall(contents)
+
+    # Tell ModuleFinder to search dependencies in the script dir, and the glapi
+    # dirs
+    source_dir = node.get_dir().abspath
+    GLAPI = env.Dir('#src/mapi/glapi/gen').abspath
+    path = [source_dir, GLAPI] + sys.path
+
+    finder = modulefinder.ModuleFinder(path=path)
+    finder.run_script(node.abspath)
     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
-    #print node, map(str, results)
+    for name, mod in finder.modules.items():
+        if mod.__file__ is None:
+            continue
+        assert os.path.exists(mod.__file__)
+        results.append(env.File(mod.__file__))
     return results
 
 python_scanner = SCons.Scanner.Scanner(function = python_scan, skeys = ['.py'])
@@ -138,7 +147,7 @@ def code_generate(env, script, target, source, command):
 
     # Explicitly mark that the generated code depends on the generator,
     # and on implicitly imported python modules
-    path = (script_src.get_dir(),)
+    path = (script_src.get_dir(),) if scons_version < (2, 5, 0) else lambda x: script_src
     deps = [script_src]
     deps += script_src.get_implicit_deps(env, python_scanner, path)
     env.Depends(code, deps)
@@ -185,7 +194,7 @@ def _pkg_check_modules(env, name, modules):
     except OSError:
         return
     prefix = name + '_'
-    for flag_name, flag_value in flags.iteritems():
+    for flag_name, flag_value in flags.items():
         assert '_' not in flag_name
         env[prefix + flag_name] = flag_value
 
@@ -218,7 +227,7 @@ def pkg_use_modules(env, names):
             raise Exception('Attempt to use unavailable module %s' % name)
 
         flags = {}
-        for flag_name, flag_value in env.Dictionary().iteritems():
+        for flag_name, flag_value in env.Dictionary().items():
             if flag_name.startswith(prefix):
                 flag_name = flag_name[len(prefix):]
                 if '_' not in flag_name:
@@ -253,12 +262,16 @@ def parse_source_list(env, filename, names=None):
     sym_table = parser.parse(src.abspath)
 
     if names:
-        if isinstance(names, basestring):
-            names = [names]
+        if sys.version_info[0] >= 3:
+            if isinstance(names, str):
+                names = [names]
+        else:
+            if isinstance(names, basestring):
+                names = [names]
 
         symbols = names
     else:
-        symbols = sym_table.keys()
+        symbols = list(sym_table.keys())
 
     # convert the symbol table to source lists
     src_lists = {}
@@ -276,6 +289,9 @@ def parse_source_list(env, filename, names=None):
                     # Prefer relative source paths, as absolute files tend to
                     # cause duplicate actions.
                     f = f[len(cur_srcdir + '/'):]
+                # do not include any headers
+                if f.endswith(tuple(['.h','.hpp','.inl'])):
+                    continue
                 srcs.append(f)
 
         src_lists[sym] = srcs