diff options
author | Nathan Binkert <nate@binkert.org> | 2010-09-09 14:15:42 -0700 |
---|---|---|
committer | Nathan Binkert <nate@binkert.org> | 2010-09-09 14:15:42 -0700 |
commit | e6ee56c6571999631ce31b05d0e563d66a7bbdd8 (patch) | |
tree | 174a7431f8a5b5e80c90b8a9887c90b245af07d8 /src/SConscript | |
parent | 710ed8f492aa783933df6551ff98c9a6750fd9f7 (diff) | |
download | gem5-e6ee56c6571999631ce31b05d0e563d66a7bbdd8.tar.xz |
init: don't build files that centralize python and swig code
Instead of putting all object files into m5/object/__init__.py, interrogate
the importer to find out what should be imported.
Instead of creating a single file that lists all of the embedded python
modules, use static object construction to put those objects onto a list.
Do something similar for embedded swig (C++) code.
Diffstat (limited to 'src/SConscript')
-rw-r--r-- | src/SConscript | 177 |
1 files changed, 54 insertions, 123 deletions
diff --git a/src/SConscript b/src/SConscript index 67d285016..f7794658b 100644 --- a/src/SConscript +++ b/src/SConscript @@ -51,6 +51,8 @@ Export('env') build_env = [(opt, env[opt]) for opt in export_vars] +from m5.util import code_formatter + ######################################################################## # Code for adding source files of various types # @@ -142,8 +144,8 @@ class PySource(SourceFile): self.arcname = joinpath(*arcpath) self.abspath = abspath self.compiled = File(self.filename + 'c') - self.assembly = File(self.filename + '.s') - self.symname = "PyEMB_" + PySource.invalid_sym_char.sub('_', modpath) + self.cpp = File(self.filename + '.cc') + self.symname = PySource.invalid_sym_char.sub('_', modpath) PySource.modules[modpath] = self PySource.tnodes[self.tnode] = self @@ -446,24 +448,6 @@ env.Command('python/m5/info.py', makeInfoPyFile) PySource('m5', 'python/m5/info.py') -# Generate the __init__.py file for m5.objects -def makeObjectsInitFile(target, source, env): - code = code_formatter() - code('''\ -from params import * -from m5.SimObject import * -''') - - for module in source: - code('from $0 import *', module.get_contents()) - code.write(str(target[0])) - -# Generate an __init__.py file for the objects package -env.Command('python/m5/objects/__init__.py', - map(Value, SimObject.modnames), - makeObjectsInitFile) -PySource('m5.objects', 'python/m5/objects/__init__.py') - ######################################################################## # # Create all of the SimObject param headers and enum headers @@ -632,39 +616,32 @@ env.Command(params_file, map(Value, names), buildParams) env.Depends(params_file, params_hh_files + params_i_files + depends) SwigSource('m5.objects', params_file) +# Generate the main swig init file +def makeEmbeddedSwigInit(target, source, env): + code = code_formatter() + module = source[0].get_contents() + code('''\ +#include "sim/init.hh" + +extern "C" { + void init_${module}(); +} + +EmbeddedSwig embed_swig_${module}(init_${module}); +''') + code.write(str(target[0])) + # Build all swig modules for swig in SwigSource.all: env.Command([swig.cc_source.tnode, swig.py_source.tnode], swig.tnode, '$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} ' '-o ${TARGETS[0]} $SOURCES') + init_file = 'python/swig/init_%s.cc' % swig.module + env.Command(init_file, Value(swig.module), makeEmbeddedSwigInit) + Source(init_file) env.Depends(swig.py_source.tnode, swig.tnode) env.Depends(swig.cc_source.tnode, swig.tnode) -# Generate the main swig init file -def makeSwigInit(target, source, env): - code = code_formatter() - - code('extern "C" {') - code.indent() - for module in source: - code('void init_$0();', module.get_contents()) - code.dedent() - code('}') - - code('void initSwig() {') - code.indent() - for module in source: - code('init_$0();', module.get_contents()) - code.dedent() - code('}') - - code.write(str(target[0])) - -env.Command('python/swig/init.cc', - map(Value, sorted(s.module for s in SwigSource.all)), - makeSwigInit) -Source('python/swig/init.cc') - def getFlags(source_flags): flagsMap = {} flagsList = [] @@ -892,13 +869,17 @@ env.Command('base/traceflags.hh', flags, traceFlagsHH) env.Command('base/traceflags.cc', flags, traceFlagsCC) Source('base/traceflags.cc') -# embed python files. All .py files that have been indicated by a +# Embed python files. All .py files that have been indicated by a # PySource() call in a SConscript need to be embedded into the M5 # library. To do that, we compile the file to byte code, marshal the -# byte code, compress it, and then generate an assembly file that -# inserts the result into the data section with symbols indicating the -# beginning, and end (and with the size at the end) -def objectifyPyFile(target, source, env): +# byte code, compress it, and then generate a c++ file that +# inserts the result into an array. +def embedPyFile(target, source, env): + def c_str(string): + if string is None: + return "0" + return '"%s"' % string + '''Action function to compile a .py into a code object, marshal it, compress it, and stick it into an asm file so the code appears as just bytes with a label in the data section''' @@ -910,90 +891,40 @@ def objectifyPyFile(target, source, env): marshalled = marshal.dumps(compiled) compressed = zlib.compress(marshalled) data = compressed + sym = pysource.symname - # Some C/C++ compilers prepend an underscore to global symbol - # names, so if they're going to do that, we need to prepend that - # leading underscore to globals in the assembly file. - if env['LEADING_UNDERSCORE']: - sym = '_' + pysource.symname - else: - sym = pysource.symname - - step = 16 code = code_formatter() code('''\ -.data -.globl ${sym}_beg -.globl ${sym}_end -${sym}_beg:''') +#include "sim/init.hh" +namespace { + +const char data_${sym}[] = { +''') + code.indent() + step = 16 for i in xrange(0, len(data), step): x = array.array('B', data[i:i+step]) - bytes = ','.join([str(d) for d in x]) - code('.byte $bytes') - code('${sym}_end:') - code('.long $0', len(marshalled)) - - code.write(str(target[0])) - -for source in PySource.all: - env.Command(source.assembly, source.tnode, objectifyPyFile) - Source(source.assembly) - -# Generate init_python.cc which creates a bunch of EmbeddedPyModule -# structs that describe the embedded python code. One such struct -# contains information about the importer that python uses to get at -# the embedded files, and then there's a list of all of the rest that -# the importer uses to load the rest on demand. -def pythonInit(target, source, env): - code = code_formatter() + code(''.join('%d,' % d for d in x)) + code.dedent() + + code('''}; - def dump_mod(sym, endchar=','): - def c_str(string): - if string is None: - return "0" - return '"%s"' % string +EmbeddedPython embedded_${sym}( + ${{c_str(pysource.arcname)}}, + ${{c_str(pysource.abspath)}}, + ${{c_str(pysource.modpath)}}, + data_${sym}, + ${{len(data)}}, + ${{len(marshalled)}}); - pysource = PySource.symnames[sym] - arcname = c_str(pysource.arcname) - abspath = c_str(pysource.abspath) - modpath = c_str(pysource.modpath) - code.indent() - code('''\ -{ $arcname, - $abspath, - $modpath, - ${sym}_beg, ${sym}_end, - ${sym}_end - ${sym}_beg, - *(int *)${sym}_end }$endchar +/* namespace */ } ''') - code.dedent() - - code('#include "sim/init.hh"') - for sym in source: - sym = sym.get_contents() - code('extern const char ${sym}_beg[], ${sym}_end[];') - - code('const EmbeddedPyModule embeddedPyImporter = ') - dump_mod("PyEMB_importer", endchar=';') - code() - - code('const EmbeddedPyModule embeddedPyModules[] = {') - for i,sym in enumerate(source): - sym = sym.get_contents() - if sym == "PyEMB_importer": - # Skip the importer since we've already exported it - continue - dump_mod(sym) - code(' { 0, 0, 0, 0, 0, 0, 0 }') - code('};') - code.write(str(target[0])) -env.Command('sim/init_python.cc', - map(Value, (s.symname for s in PySource.all)), - pythonInit) -Source('sim/init_python.cc') +for source in PySource.all: + env.Command(source.cpp, source.tnode, embedPyFile) + Source(source.cpp) ######################################################################## # |