- PySource(package, py_file)
-
-def MakeSwigInit(target, source, env):
- f = file(str(target[0]), 'w')
- print >>f, 'extern "C" {'
- for module in source:
- print >>f, ' void init_%s();' % module.get_contents()
- print >>f, '}'
- print >>f, 'void init_swig() {'
- for module in source:
- print >>f, ' init_%s();' % module.get_contents()
- print >>f, '}'
- f.close()
-env.Command('python/swig/init.cc', swig_modules, MakeSwigInit)
-
-def CompilePyFile(target, source, env):
- import py_compile
- py_compile.compile(str(source[0]), str(target[0]))
-
-py_compiled = []
-py_arcname = {}
-py_zip_depends = []
-for source in py_sources:
- filename = str(source)
- package = py_source_packages[source]
- arc_path = package.split('.') + [ basename(filename) + 'c' ]
- zip_path = [ 'zip' ] + arc_path
- arcname = joinpath(*arc_path)
- zipname = joinpath(*zip_path)
- f = File(zipname)
-
- env.Command(f, source, CompilePyFile)
- py_compiled.append(f)
- py_arcname[f] = arcname
-
- # make the zipfile depend on the archive name so that the archive
- # is rebuilt if the name changes
- py_zip_depends.append(Value(arcname))
-
-# Action function to build the zip archive. Uses the PyZipFile module
-# included in the standard Python library.
-def buildPyZip(target, source, env):
- zf = zipfile.ZipFile(str(target[0]), 'w')
- for s in source:
- arcname = py_arcname[s]
- zipname = str(s)
- zf.write(zipname, arcname)
- zf.close()
-
-# Add the zip file target to the environment.
-env.Command('m5py.zip', py_compiled, buildPyZip)
-env.Depends('m5py.zip', py_zip_depends)
+
+ hh_file = File('enums/%s.hh' % name)
+ env.Command(hh_file, Value(name),
+ MakeAction(createEnumDecls, Transform("ENUMDECL")))
+ env.Depends(hh_file, depends + extra_deps)
+
+ i_file = File('python/m5/internal/enum_%s.i' % name)
+ env.Command(i_file, Value(name),
+ MakeAction(createEnumSwigWrapper, Transform("ENUMSWIG")))
+ env.Depends(i_file, depends + extra_deps)
+ SwigSource('m5.internal', i_file)
+
+# Generate SimObject SWIG wrapper files
+for name,simobj in sim_objects.iteritems():
+ py_source = PySource.modules[simobj.__module__]
+ extra_deps = [ py_source.tnode ]
+
+ i_file = File('python/m5/internal/param_%s.i' % name)
+ env.Command(i_file, Value(name),
+ MakeAction(createSimObjectSwigWrapper, Transform("SO SWIG")))
+ env.Depends(i_file, depends + extra_deps)
+ SwigSource('m5.internal', i_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,
+ MakeAction('$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} '
+ '-o ${TARGETS[0]} $SOURCES', Transform("SWIG")))
+ cc_file = str(swig.tnode)
+ init_file = '%s/%s_init.cc' % (dirname(cc_file), basename(cc_file))
+ env.Command(init_file, Value(swig.module),
+ MakeAction(makeEmbeddedSwigInit, Transform("EMBED SW")))
+ Source(init_file, **swig.guards)
+
+# Build all protocol buffers if we have got protoc and protobuf available
+if env['HAVE_PROTOBUF']:
+ for proto in ProtoBuf.all:
+ # Use both the source and header as the target, and the .proto
+ # file as the source. When executing the protoc compiler, also
+ # specify the proto_path to avoid having the generated files
+ # include the path.
+ env.Command([proto.cc_file, proto.hh_file], proto.tnode,
+ MakeAction('$PROTOC --cpp_out ${TARGET.dir} '
+ '--proto_path ${SOURCE.dir} $SOURCE',
+ Transform("PROTOC")))
+
+ # Add the C++ source file
+ Source(proto.cc_file, **proto.guards)
+elif ProtoBuf.all:
+ print 'Got protobuf to build, but lacks support!'
+ Exit(1)
+
+#
+# Handle debug flags
+#
+def makeDebugFlagCC(target, source, env):
+ assert(len(target) == 1 and len(source) == 1)
+
+ val = eval(source[0].get_contents())
+ name, compound, desc = val
+ compound = list(sorted(compound))
+
+ code = code_formatter()
+
+ # file header
+ code('''
+/*
+ * DO NOT EDIT THIS FILE! Automatically generated
+ */
+
+#include "base/debug.hh"
+''')
+
+ for flag in compound:
+ code('#include "debug/$flag.hh"')
+ code()
+ code('namespace Debug {')
+ code()
+
+ if not compound:
+ code('SimpleFlag $name("$name", "$desc");')
+ else:
+ code('CompoundFlag $name("$name", "$desc",')
+ code.indent()
+ last = len(compound) - 1
+ for i,flag in enumerate(compound):
+ if i != last:
+ code('$flag,')
+ else:
+ code('$flag);')
+ code.dedent()
+
+ code()
+ code('} // namespace Debug')
+
+ code.write(str(target[0]))
+
+def makeDebugFlagHH(target, source, env):
+ assert(len(target) == 1 and len(source) == 1)
+
+ val = eval(source[0].get_contents())
+ name, compound, desc = val
+
+ code = code_formatter()
+
+ # file header boilerplate
+ code('''\
+/*
+ * DO NOT EDIT THIS FILE!
+ *
+ * Automatically generated by SCons
+ */
+
+#ifndef __DEBUG_${name}_HH__
+#define __DEBUG_${name}_HH__
+
+namespace Debug {
+''')
+
+ if compound:
+ code('class CompoundFlag;')
+ code('class SimpleFlag;')
+
+ if compound:
+ code('extern CompoundFlag $name;')
+ for flag in compound:
+ code('extern SimpleFlag $flag;')
+ else:
+ code('extern SimpleFlag $name;')
+
+ code('''
+}
+
+#endif // __DEBUG_${name}_HH__
+''')
+
+ code.write(str(target[0]))
+
+for name,flag in sorted(debug_flags.iteritems()):
+ n, compound, desc = flag
+ assert n == name
+
+ env.Command('debug/%s.hh' % name, Value(flag),
+ MakeAction(makeDebugFlagHH, Transform("TRACING", 0)))
+ env.Command('debug/%s.cc' % name, Value(flag),
+ MakeAction(makeDebugFlagCC, Transform("TRACING", 0)))
+ Source('debug/%s.cc' % name)
+
+# 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 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'''
+
+ src = file(str(source[0]), 'r').read()
+
+ pysource = PySource.tnodes[source[0]]
+ compiled = compile(src, pysource.abspath, 'exec')
+ marshalled = marshal.dumps(compiled)
+ compressed = zlib.compress(marshalled)
+ data = compressed
+ sym = pysource.symname
+
+ code = code_formatter()
+ code('''\
+#include "sim/init.hh"
+
+namespace {
+
+const uint8_t data_${sym}[] = {
+''')
+ code.indent()
+ step = 16
+ for i in xrange(0, len(data), step):
+ x = array.array('B', data[i:i+step])
+ code(''.join('%d,' % d for d in x))
+ code.dedent()
+
+ code('''};
+
+EmbeddedPython embedded_${sym}(
+ ${{c_str(pysource.arcname)}},
+ ${{c_str(pysource.abspath)}},
+ ${{c_str(pysource.modpath)}},
+ data_${sym},
+ ${{len(data)}},
+ ${{len(marshalled)}});
+
+} // anonymous namespace
+''')
+ code.write(str(target[0]))
+
+for source in PySource.all:
+ env.Command(source.cpp, source.tnode,
+ MakeAction(embedPyFile, Transform("EMBED PY")))
+ Source(source.cpp)