modname,ext = self.extname
assert ext == 'i'
+ self.package = package
self.module = modname
cc_file = joinpath(self.dirname, modname + '_wrap.cc')
py_file = joinpath(self.dirname, modname + '.py')
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}();
-}
+def makeEmbeddedSwigInit(package):
+ def body(target, source, env):
+ assert len(target) == 1 and len(source) == 1
-EmbeddedSwig embed_swig_${module}(init_${module});
-''')
- code.write(str(target[0]))
+ code = code_formatter()
+ module = source[0].get_contents()
+ # Provide the full context so that the swig-generated call to
+ # Py_InitModule ends up placing the embedded module in the
+ # right package.
+ context = str(package) + "._" + str(module)
+ code('''\
+ #include "sim/init.hh"
+
+ extern "C" {
+ void init_${module}();
+ }
+
+ EmbeddedSwig embed_swig_${module}(init_${module}, "${context}");
+ ''')
+ code.write(str(target[0]))
+ return body
# Build all swig modules
for swig in SwigSource.all:
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")))
+ MakeAction(makeEmbeddedSwigInit(swig.package),
+ Transform("EMBED SW")))
env.Depends(SWIG, init_file)
Source(init_file, **swig.guards)
return 0;
}
-EmbeddedSwig::EmbeddedSwig(void (*init_func)())
- : initFunc(init_func)
+EmbeddedSwig::EmbeddedSwig(void (*init_func)(), const string& _context)
+ : initFunc(init_func), context(_context)
{
getList().push_back(this);
}
void
EmbeddedSwig::initAll()
{
- // initialize SWIG modules. initSwig() is autogenerated and calls
+ char* old_context = _Py_PackageContext;
+ // initialize SWIG modules. initFunc() is autogenerated and calls
// all of the individual swig initialization functions.
- list<EmbeddedSwig *>::iterator i = getList().begin();
- list<EmbeddedSwig *>::iterator end = getList().end();
- for (; i != end; ++i)
- (*i)->initFunc();
+ for (auto i : getList()) {
+ // to ensure that the loaded modules are placed in the right
+ // package we have to be a bit unorthodox and directly
+ // manipulate the package context since swig simply calls
+ // Py_InitModule with nothing but the module name of the
+ // wrapper
+ char* cstr = new char[i->context.size() + 1];
+ strcpy(cstr, i->context.c_str());
+ _Py_PackageContext = cstr;
+ i->initFunc();
+ delete[] cstr;
+ }
+ _Py_PackageContext = old_context;
}
int
#include <Python.h>
-/*
- * Data structure describing an embedded python file.
- */
#include <list>
+#include <string>
#include <inttypes.h>
typedef _object PyObject;
#endif
+/*
+ * Data structure describing an embedded python file.
+ */
struct EmbeddedPython
{
const char *filename;
{
void (*initFunc)();
- EmbeddedSwig(void (*init_func)());
+ std::string context;
+
+ EmbeddedSwig(void (*init_func)(), const std::string& _context);
static std::list<EmbeddedSwig *> &getList();
static void initAll();