Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/49392 )

Change subject: scons,python: Split the marshal binary into a c++ wrapper and script.
......................................................................

scons,python: Split the marshal binary into a c++ wrapper and script.

The new c++ wrapper is called gem5py, and will run any python script
using gem5's embedded python interpreter. The "marshal" functionality is
split out into a separate python script gem5py can run.

The command line for gem5py should look like this:

gem5py ${SCRIPT TO RUN} ${ARGS TO THE SCRIPT}

So, for instance, to marshal a file called foo.py, the command line
might look like this:

gem5py python/marshal.py foo.py

Also, this change reorders the sources for the python embedding action
and limits the max_sources for Transform() to 1, so that it just shows
the python file being embedded and not gem5py or the marshal.py script.
Those are still sources so dependency tracking works correctly, but they
are also implied and just add visual noise to the build output.

Change-Id: I7ae6bd114973ae44c3b634884b6dafc6577e0788
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49392
Tested-by: kokoro <[email protected]>
Reviewed-by: Gabe Black <[email protected]>
Maintainer: Gabe Black <[email protected]>
---
M SConstruct
M src/SConscript
R src/python/gem5py.cc
A src/python/marshal.py
4 files changed, 91 insertions(+), 29 deletions(-)

Approvals:
  Gabe Black: Looks good to me, approved; Looks good to me, approved
  kokoro: Regressions pass




diff --git a/SConstruct b/SConstruct
index de7cdef..283ebab 100755
--- a/SConstruct
+++ b/SConstruct
@@ -244,9 +244,9 @@
     ('CC', 'C compiler', environ.get('CC', main['CC'])),
     ('CXX', 'C++ compiler', environ.get('CXX', main['CXX'])),
     ('CCFLAGS_EXTRA', 'Extra C and C++ compiler flags', ''),
+    ('GEM5PY_CCFLAGS_EXTRA', 'Extra C and C++ gem5py compiler flags', ''),
+    ('GEM5PY_LDFLAGS_EXTRA', 'Extra marshal gem5py flags', ''),
     ('LDFLAGS_EXTRA', 'Extra linker flags', ''),
- ('MARSHAL_CCFLAGS_EXTRA', 'Extra C and C++ marshal compiler flags', ''),
-    ('MARSHAL_LDFLAGS_EXTRA', 'Extra marshal linker flags', ''),
     ('PYTHON_CONFIG', 'Python config binary to use',
      [ 'python3-config', 'python-config']
     ),
@@ -530,11 +530,11 @@
         warning('Embedded python library too new. '
                 'Python 3 expected, found %s.' % ver_string)

-marshal_env = main.Clone()
+gem5py_env = main.Clone()

 # Bare minimum environment that only includes python
-marshal_env.Append(CCFLAGS='$MARSHAL_CCFLAGS_EXTRA')
-marshal_env.Append(LINKFLAGS='$MARSHAL_LDFLAGS_EXTRA')
+gem5py_env.Append(CCFLAGS=['${GEM5PY_CCFLAGS_EXTRA}'])
+gem5py_env.Append(LINKFLAGS=['${GEM5PY_LDFLAGS_EXTRA}'])

 main['HAVE_PKG_CONFIG'] = main.Detect('pkg-config')

@@ -708,7 +708,7 @@
     env.Append(CCFLAGS='$CCFLAGS_EXTRA')
     env.Append(LINKFLAGS='$LDFLAGS_EXTRA')

-    exports=['env', 'marshal_env']
+    exports=['env', 'gem5py_env']

     # The src/SConscript file sets up the build rules in 'env' according
     # to the configured variables.  It returns a list of environments,
diff --git a/src/SConscript b/src/SConscript
index fdd5830..e1ee8a4 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -80,7 +80,8 @@
 # Build a small helper that marshals the Python code using the same version
 # of Python as gem5. This is in an unorthodox location to avoid building it
 # for every variant.
-py_marshal = marshal_env.Program('marshal', 'python/marshal.cc')[0]
+gem5py = gem5py_env.Program('gem5py', 'python/gem5py.cc')[0]
+marshal_py = Dir('python').File('marshal.py')

 # Embed python files.  All .py files that have been indicated by a
 # PySource() call in a SConscript need to be embedded into the M5
@@ -99,11 +100,11 @@

     import subprocess

-    marshal_bin, pysource = source
+    pysource, gem5py, marshal_py = source
     modpath = env['PYSOURCE_MODPATH']
     abspath = env['PYSOURCE_ABSPATH']
     marshalled = subprocess.check_output(
-            [marshal_bin.abspath, str(pysource)], env=env['ENV'])
+ [gem5py.abspath, str(marshal_py), str(pysource)], env=env['ENV'])

     compressed = zlib.compress(marshalled)
     data = compressed
@@ -172,8 +173,8 @@
                 'PYSOURCE_MODPATH': modpath,
                 'PYSOURCE_ABSPATH': abspath,
         }
-        marshal_env.Command(cpp, [ py_marshal, File(source) ],
-                MakeAction(embedPyFile, Transform("EMBED PY"),
+        gem5py_env.Command(cpp, [ File(source), gem5py, marshal_py ],
+ MakeAction(embedPyFile, Transform("EMBED PY", max_sources=1),
                     varlist=overrides.keys()),
                 **overrides)
         Source(cpp, tags=self.tags, add_tags='python')
diff --git a/src/python/marshal.cc b/src/python/gem5py.cc
similarity index 85%
rename from src/python/marshal.cc
rename to src/python/gem5py.cc
index 99305b2..f2d8759 100644
--- a/src/python/marshal.cc
+++ b/src/python/gem5py.cc
@@ -37,24 +37,16 @@

 #include <pybind11/embed.h>

+#include <cstdlib>
+#include <iostream>
+
 namespace py = pybind11;

-constexpr auto MarshalScript = R"(
-import marshal
-import sys
-
-if len(sys.argv) < 2:
-    print(f"Usage: {sys.argv[0]} PYSOURCE", file=sys.stderr)
-    sys.exit(1)
-
-source = sys.argv[1]
-with open(source, 'r') as f:
-    src = f.read()
-
-compiled = compile(src, source, 'exec')
-marshalled = marshal.dumps(compiled)
-sys.stdout.buffer.write(marshalled)
-)";
+/*
+ * This wrapper program runs python scripts using the python interpretter which + * will be built into gem5. Its first argument is the script to run, and then
+ * all subsequent arguments are passed to the python script as its argv.
+ */

 int
 main(int argc, const char **argv)
@@ -74,12 +66,17 @@
     // Clear out argv just in case it has something in it.
     py_argv.attr("clear")();

+    if (argc < 2) {
+        std::cerr << "Usage: gem5py SCRIPT [arg] ..." << std::endl;
+        std::exit(1);
+    }
+
     // Fill it with our argvs.
-    for (int i = 0; i < argc; i++)
+    for (int i = 1; i < argc; i++)
         py_argv.append(argv[i]);

     // Actually call the script.
-    py::exec(MarshalScript, py::globals());
+    py::eval_file(argv[1]);

     return 0;
 }
diff --git a/src/python/marshal.py b/src/python/marshal.py
new file mode 100644
index 0000000..bb5169f
--- /dev/null
+++ b/src/python/marshal.py
@@ -0,0 +1,64 @@
+# Copyright (c) 2019 ARM Limited
+# All rights reserved
+#
+# The license below extends only to copyright in the software and shall
+# not be construed as granting a license to any other intellectual
+# property including but not limited to intellectual property relating
+# to a hardware implementation of the functionality of the software
+# licensed hereunder.  You may use the software subject to the license
+# terms below provided that you ensure that this notice is replicated
+# unmodified and in its entirety in all distributions of the software,
+# modified or unmodified, in source code or in binary form.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Marshal another python script.
+
+This script compiles another script, marshals the resulting code object, and +writes it to stdout. Marshalling an object in this sense is essentially what
+would happen to write it out in a pyc file.
+
+This code object can then be read back in by another python script later and
+executed, without having to have access to the original file. This is how
+python code is embedded into the gem5 binary.
+
+The output of the marshal module is *not* generally compatible accross python +interpretters, and so the exact same interpretter should be used both to run
+this script, and to read in and execute the marshalled code later.
+"""
+
+import marshal
+import sys
+
+if len(sys.argv) < 2:
+    print(f"Usage: {sys.argv[0]} PYSOURCE", file=sys.stderr)
+    sys.exit(1)
+
+source = sys.argv[1]
+with open(source, 'r') as f:
+    src = f.read()
+
+compiled = compile(src, source, 'exec')
+marshalled = marshal.dumps(compiled)
+sys.stdout.buffer.write(marshalled)

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/49392
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I7ae6bd114973ae44c3b634884b6dafc6577e0788
Gerrit-Change-Number: 49392
Gerrit-PatchSet: 17
Gerrit-Owner: Gabe Black <[email protected]>
Gerrit-Reviewer: Andreas Sandberg <[email protected]>
Gerrit-Reviewer: Gabe Black <[email protected]>
Gerrit-Reviewer: Jason Lowe-Power <[email protected]>
Gerrit-Reviewer: Jason Lowe-Power <[email protected]>
Gerrit-Reviewer: kokoro <[email protected]>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to