custom.py revision 54d8c5e3c2fc7db643a2bae61be203ab9cbb1efa
1"""custom 2 3Custom builders and methods. 4 5""" 6 7# 8# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 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 TUNGSTEN GRAPHICS 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 33import os 34import os.path 35import re 36 37import SCons.Action 38import SCons.Builder 39import SCons.Scanner 40 41import fixes 42 43 44def quietCommandLines(env): 45 # Quiet command lines 46 # See also http://www.scons.org/wiki/HidingCommandLinesInOutput 47 env['ASCOMSTR'] = " Assembling $SOURCE ..." 48 env['ASPPCOMSTR'] = " Assembling $SOURCE ..." 49 env['CCCOMSTR'] = " Compiling $SOURCE ..." 50 env['SHCCCOMSTR'] = " Compiling $SOURCE ..." 51 env['CXXCOMSTR'] = " Compiling $SOURCE ..." 52 env['SHCXXCOMSTR'] = " Compiling $SOURCE ..." 53 env['ARCOMSTR'] = " Archiving $TARGET ..." 54 env['RANLIBCOMSTR'] = " Indexing $TARGET ..." 55 env['LINKCOMSTR'] = " Linking $TARGET ..." 56 env['SHLINKCOMSTR'] = " Linking $TARGET ..." 57 env['LDMODULECOMSTR'] = " Linking $TARGET ..." 58 env['SWIGCOMSTR'] = " Generating $TARGET ..." 59 env['LEXCOMSTR'] = " Generating $TARGET ..." 60 env['YACCCOMSTR'] = " Generating $TARGET ..." 61 env['CODEGENCOMSTR'] = " Generating $TARGET ..." 62 63 64def createConvenienceLibBuilder(env): 65 """This is a utility function that creates the ConvenienceLibrary 66 Builder in an Environment if it is not there already. 67 68 If it is already there, we return the existing one. 69 70 Based on the stock StaticLibrary and SharedLibrary builders. 71 """ 72 73 try: 74 convenience_lib = env['BUILDERS']['ConvenienceLibrary'] 75 except KeyError: 76 action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ] 77 if env.Detect('ranlib'): 78 ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR") 79 action_list.append(ranlib_action) 80 81 convenience_lib = SCons.Builder.Builder(action = action_list, 82 emitter = '$LIBEMITTER', 83 prefix = '$LIBPREFIX', 84 suffix = '$LIBSUFFIX', 85 src_suffix = '$SHOBJSUFFIX', 86 src_builder = 'SharedObject') 87 env['BUILDERS']['ConvenienceLibrary'] = convenience_lib 88 89 return convenience_lib 90 91 92# TODO: handle import statements with multiple modules 93# TODO: handle from import statements 94import_re = re.compile(r'^import\s+(\S+)$', re.M) 95 96def python_scan(node, env, path): 97 # http://www.scons.org/doc/0.98.5/HTML/scons-user/c2781.html#AEN2789 98 contents = node.get_contents() 99 source_dir = node.get_dir() 100 imports = import_re.findall(contents) 101 results = [] 102 for imp in imports: 103 for dir in path: 104 file = os.path.join(str(dir), imp.replace('.', os.sep) + '.py') 105 if os.path.exists(file): 106 results.append(env.File(file)) 107 break 108 file = os.path.join(str(dir), imp.replace('.', os.sep), '__init__.py') 109 if os.path.exists(file): 110 results.append(env.File(file)) 111 break 112 return results 113 114python_scanner = SCons.Scanner.Scanner(function = python_scan, skeys = ['.py']) 115 116 117def code_generate(env, script, target, source, command): 118 """Method to simplify code generation via python scripts. 119 120 http://www.scons.org/wiki/UsingCodeGenerators 121 http://www.scons.org/doc/0.98.5/HTML/scons-user/c2768.html 122 """ 123 124 # We're generating code using Python scripts, so we have to be 125 # careful with our scons elements. This entry represents 126 # the generator file *in the source directory*. 127 script_src = env.File(script).srcnode() 128 129 # This command creates generated code *in the build directory*. 130 command = command.replace('$SCRIPT', script_src.path) 131 action = SCons.Action.Action(command, "$CODEGENCOMSTR") 132 code = env.Command(target, source, action) 133 134 # Explicitly mark that the generated code depends on the generator, 135 # and on implicitly imported python modules 136 path = (script_src.get_dir(),) 137 deps = [script_src] 138 deps += script_src.get_implicit_deps(env, python_scanner, path) 139 env.Depends(code, deps) 140 141 # Running the Python script causes .pyc files to be generated in the 142 # source directory. When we clean up, they should go too. So add side 143 # effects for .pyc files 144 for dep in deps: 145 pyc = env.File(str(dep) + 'c') 146 env.SideEffect(pyc, code) 147 148 return code 149 150 151def createCodeGenerateMethod(env): 152 env.Append(SCANNERS = python_scanner) 153 env.AddMethod(code_generate, 'CodeGenerate') 154 155 156def generate(env): 157 """Common environment generation code""" 158 159 if env.get('quiet', True): 160 quietCommandLines(env) 161 162 # Custom builders and methods 163 createConvenienceLibBuilder(env) 164 createCodeGenerateMethod(env) 165 166 # for debugging 167 #print env.Dump() 168 169 170def exists(env): 171 return 1 172