diff --git a/src/python/importer.cc b/src/python/importer.cc index c7beb6243e..7d1f7dcf4c 100644 --- a/src/python/importer.cc +++ b/src/python/importer.cc @@ -29,10 +29,13 @@ #include "pybind11/pybind11.h" #include "python/m5ImporterCode.hh" +#include "sim/init.hh" + namespace py = pybind11; PYBIND11_EMBEDDED_MODULE(importer, m) { + m.def("_init_all_embedded", gem5::EmbeddedPython::initAll); py::str importer_code( reinterpret_cast(gem5::Blobs::m5ImporterCode), gem5::Blobs::m5ImporterCode_len); diff --git a/src/python/importer.py b/src/python/importer.py index 94edb91936..f75f95b675 100644 --- a/src/python/importer.py +++ b/src/python/importer.py @@ -74,7 +74,12 @@ class CodeImporter(object): # Create an importer and add it to the meta_path so future imports can # use it. There's currently nothing in the importer, but calls to # add_module can be used to add code. -import sys -importer = CodeImporter() -add_module = importer.add_module -sys.meta_path.insert(0, importer) +def install(): + importer = CodeImporter() + global add_module + add_module = importer.add_module + import sys + sys.meta_path.insert(0, importer) + + # Injected into this module's namespace by the c++ code that loads it. + _init_all_embedded() diff --git a/src/sim/init.cc b/src/sim/init.cc index 5067604d3e..d612b0bf3d 100644 --- a/src/sim/init.cc +++ b/src/sim/init.cc @@ -202,7 +202,7 @@ PYBIND11_EMBEDDED_MODULE(_m5, _m5) * main function. */ int -m5Main(int argc, char **argv) +gem5Main(int argc, char **argv) { #if HAVE_PROTOBUF // Verify that the version of the protobuf library that we linked diff --git a/src/sim/init.hh b/src/sim/init.hh index 6613a20ce1..b4c248d4ef 100644 --- a/src/sim/init.hh +++ b/src/sim/init.hh @@ -98,7 +98,7 @@ class EmbeddedPyBind static std::map &getMap(); }; -int m5Main(int argc, char **argv); +int gem5Main(int argc, char **argv); } // namespace gem5 diff --git a/src/sim/main.cc b/src/sim/main.cc index 5e31933d20..c89e67ff39 100644 --- a/src/sim/main.cc +++ b/src/sim/main.cc @@ -28,45 +28,40 @@ #include +#include "pybind11/embed.h" +#include "pybind11/pybind11.h" + #include "sim/init.hh" #include "sim/init_signals.hh" using namespace gem5; +namespace py = pybind11; + // main() is now pretty stripped down and just sets up python and then -// calls initM5Python which loads the various embedded python modules -// into the python environment and then starts things running by -// calling m5Main. +// calls EmbeddedPython::initAll which loads the various embedded python +// modules into the python environment and then starts things running by +// calling gem5Main. int main(int argc, char **argv) { - int ret; - - // Initialize m5 special signal handling. + // Initialize gem5 special signal handling. initSignals(); -#if PY_MAJOR_VERSION >= 3 + // Convert argv[0] to a wchar_t string, using python's locale and cleanup + // functions. std::unique_ptr program( - Py_DecodeLocale(argv[0], NULL), + Py_DecodeLocale(argv[0], nullptr), &PyMem_RawFree); + + // This can help python find libraries at run time relative to this binary. + // It's probably not necessary, but is mostly harmless and might be useful. Py_SetProgramName(program.get()); -#else - Py_SetProgramName(argv[0]); -#endif - // initialize embedded Python interpreter - Py_Initialize(); + py::scoped_interpreter guard; - // Initialize the embedded m5 python library - ret = EmbeddedPython::initAll(); + auto importer = py::module_::import("importer"); + importer.attr("install")(); - if (ret == 0) { - // start m5 - ret = m5Main(argc, argv); - } - - // clean up Python intepreter. - Py_Finalize(); - - return ret; + return gem5Main(argc, argv); }