custom.py revision c7bd0fa4851187c3102948f5f4d70c26d1b55a5e
197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca"""custom 297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé FonsecaCustom builders and methods. 497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca""" 697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# 897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# All Rights Reserved. 1097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# 1197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# Permission is hereby granted, free of charge, to any person obtaining a 1297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# copy of this software and associated documentation files (the 1397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# "Software"), to deal in the Software without restriction, including 1497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# without limitation the rights to use, copy, modify, merge, publish, 1597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# distribute, sub license, and/or sell copies of the Software, and to 1697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# permit persons to whom the Software is furnished to do so, subject to 1797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# the following conditions: 1897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# 1997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# The above copyright notice and this permission notice (including the 2097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# next paragraph) shall be included in all copies or substantial portions 2197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# of the Software. 2297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# 2397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 2497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 2697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 2797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 3097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# 3197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 3297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 3397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecaimport os 3497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecaimport os.path 3597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecaimport re 3697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 3797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecaimport SCons.Action 3897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecaimport SCons.Builder 3997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecaimport SCons.Scanner 4097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 4197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecaimport fixes 4297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 4397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 4497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef quietCommandLines(env): 4597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca # Quiet command lines 4697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca # See also http://www.scons.org/wiki/HidingCommandLinesInOutput 4797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca env['ASCOMSTR'] = " Assembling $SOURCE ..." 4897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca env['ASPPCOMSTR'] = " Assembling $SOURCE ..." 4997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca env['CCCOMSTR'] = " Compiling $SOURCE ..." 5097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca env['SHCCCOMSTR'] = " Compiling $SOURCE ..." 5197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca env['CXXCOMSTR'] = " Compiling $SOURCE ..." 5297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca env['SHCXXCOMSTR'] = " Compiling $SOURCE ..." 5397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca env['ARCOMSTR'] = " Archiving $TARGET ..." 5497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca env['RANLIBCOMSTR'] = " Indexing $TARGET ..." 5597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca env['LINKCOMSTR'] = " Linking $TARGET ..." 5697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca env['SHLINKCOMSTR'] = " Linking $TARGET ..." 5797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca env['LDMODULECOMSTR'] = " Linking $TARGET ..." 5897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca env['SWIGCOMSTR'] = " Generating $TARGET ..." 5954d8c5e3c2fc7db643a2bae61be203ab9cbb1efaJosé Fonseca env['LEXCOMSTR'] = " Generating $TARGET ..." 6054d8c5e3c2fc7db643a2bae61be203ab9cbb1efaJosé Fonseca env['YACCCOMSTR'] = " Generating $TARGET ..." 612311e2adf0db3c46a1054d94cdfcd2ec0badbfd3José Fonseca env['CODEGENCOMSTR'] = " Generating $TARGET ..." 6237058c3497850f452bdaf70a5dda07ee4840b6b9José Fonseca env['INSTALLSTR'] = " Installing $TARGET ..." 6397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 6497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 6597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef createConvenienceLibBuilder(env): 6697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca """This is a utility function that creates the ConvenienceLibrary 6797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca Builder in an Environment if it is not there already. 6897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 6997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca If it is already there, we return the existing one. 7097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 7197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca Based on the stock StaticLibrary and SharedLibrary builders. 7297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca """ 7397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 7497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca try: 7597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca convenience_lib = env['BUILDERS']['ConvenienceLibrary'] 7697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca except KeyError: 7797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ] 7897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca if env.Detect('ranlib'): 7997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR") 8097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca action_list.append(ranlib_action) 8197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 8297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca convenience_lib = SCons.Builder.Builder(action = action_list, 8397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca emitter = '$LIBEMITTER', 8497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca prefix = '$LIBPREFIX', 8597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca suffix = '$LIBSUFFIX', 8697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca src_suffix = '$SHOBJSUFFIX', 8797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca src_builder = 'SharedObject') 8897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca env['BUILDERS']['ConvenienceLibrary'] = convenience_lib 8997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 9097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca return convenience_lib 9197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 9297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 9397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# TODO: handle import statements with multiple modules 9497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca# TODO: handle from import statements 9597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecaimport_re = re.compile(r'^import\s+(\S+)$', re.M) 9697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 9797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef python_scan(node, env, path): 9897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca # http://www.scons.org/doc/0.98.5/HTML/scons-user/c2781.html#AEN2789 9997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca contents = node.get_contents() 10097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca source_dir = node.get_dir() 10197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca imports = import_re.findall(contents) 10297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca results = [] 10397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca for imp in imports: 10497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca for dir in path: 10597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca file = os.path.join(str(dir), imp.replace('.', os.sep) + '.py') 10697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca if os.path.exists(file): 10797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca results.append(env.File(file)) 10897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca break 10997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca file = os.path.join(str(dir), imp.replace('.', os.sep), '__init__.py') 11097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca if os.path.exists(file): 11197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca results.append(env.File(file)) 11297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca break 11397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca return results 11497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 11597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecapython_scanner = SCons.Scanner.Scanner(function = python_scan, skeys = ['.py']) 11697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 11797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 11897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef code_generate(env, script, target, source, command): 11997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca """Method to simplify code generation via python scripts. 12097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 12197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca http://www.scons.org/wiki/UsingCodeGenerators 12297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca http://www.scons.org/doc/0.98.5/HTML/scons-user/c2768.html 12397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca """ 12497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 12597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca # We're generating code using Python scripts, so we have to be 12697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca # careful with our scons elements. This entry represents 12797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca # the generator file *in the source directory*. 12897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca script_src = env.File(script).srcnode() 12997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 13097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca # This command creates generated code *in the build directory*. 13197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca command = command.replace('$SCRIPT', script_src.path) 1322311e2adf0db3c46a1054d94cdfcd2ec0badbfd3José Fonseca action = SCons.Action.Action(command, "$CODEGENCOMSTR") 1332311e2adf0db3c46a1054d94cdfcd2ec0badbfd3José Fonseca code = env.Command(target, source, action) 13497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 13597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca # Explicitly mark that the generated code depends on the generator, 13697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca # and on implicitly imported python modules 13797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca path = (script_src.get_dir(),) 13897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca deps = [script_src] 13997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca deps += script_src.get_implicit_deps(env, python_scanner, path) 14097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca env.Depends(code, deps) 14197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 14297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca # Running the Python script causes .pyc files to be generated in the 14397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca # source directory. When we clean up, they should go too. So add side 14497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca # effects for .pyc files 14597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca for dep in deps: 14697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca pyc = env.File(str(dep) + 'c') 14797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca env.SideEffect(pyc, code) 14897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 14997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca return code 15097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 15197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 15297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef createCodeGenerateMethod(env): 15397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca env.Append(SCANNERS = python_scanner) 15497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca env.AddMethod(code_generate, 'CodeGenerate') 15597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 15697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 15797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef generate(env): 15897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca """Common environment generation code""" 15997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 160c7bd0fa4851187c3102948f5f4d70c26d1b55a5eJosé Fonseca verbose = env.get('verbose', False) or not env.get('quiet', True) 161c7bd0fa4851187c3102948f5f4d70c26d1b55a5eJosé Fonseca if not verbose: 16297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca quietCommandLines(env) 16397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 16497e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca # Custom builders and methods 16597e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca createConvenienceLibBuilder(env) 16697e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca createCodeGenerateMethod(env) 16797e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 16897e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca # for debugging 16997e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca #print env.Dump() 17097e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 17197e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca 17297e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonsecadef exists(env): 17397e2c5ac0bba7298c9a32703fe3d19de1f7b815aJosé Fonseca return 1 174