summaryrefslogtreecommitdiff
path: root/scons
diff options
context:
space:
mode:
authorJosé Fonseca <jrfonseca@tungstengraphics.com>2008-07-03 12:42:23 +0900
committerJosé Fonseca <jrfonseca@tungstengraphics.com>2008-07-03 15:06:24 +0900
commit27d8d6f44faa61a61c330d032111eee64dd8b8c7 (patch)
treedaa0db92b6ce952196acfc84a7a4e78277a33d65 /scons
parent1ca23061478868d61b9b2e6a30367e8e1de4a456 (diff)
scons: Add a env.CodeGenerate method to simplify code generation via python scripts.
env.CodeGenerate( target = 'my_source.c', script = 'my_generator.py', source = ['input.txt', 'another.txt'], command = 'python $SCRIPT $SOURCE > $TARGET' ) It will take care generating all appropriate dependencies, including any module imported by the generator script, and the respective .pyc file side effects.
Diffstat (limited to 'scons')
-rw-r--r--scons/gallium.py72
1 files changed, 69 insertions, 3 deletions
diff --git a/scons/gallium.py b/scons/gallium.py
index 59ba34844b..bfdd2de8db 100644
--- a/scons/gallium.py
+++ b/scons/gallium.py
@@ -30,10 +30,13 @@ Frontend-tool for Gallium3D architecture.
#
+import os
import os.path
+import re
import SCons.Action
import SCons.Builder
+import SCons.Scanner
def quietCommandLines(env):
@@ -70,11 +73,73 @@ def createConvenienceLibBuilder(env):
src_suffix = '$SHOBJSUFFIX',
src_builder = 'SharedObject')
env['BUILDERS']['ConvenienceLibrary'] = convenience_lib
- env['BUILDERS']['Library'] = 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 generate(env):
"""Common environment generation code"""
@@ -336,9 +401,10 @@ def generate(env):
]
env.Append(LINKFLAGS = linkflags)
- # Convenience Library Builder
+ # Custom builders and methods
createConvenienceLibBuilder(env)
-
+ createCodeGenerateMethod(env)
+
# for debugging
#print env.Dump()