aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2019-07-12 17:33:50 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2019-07-19 00:17:29 +0200
commit8239d71025ad59e44e7ac7b43849554990efe9f9 (patch)
treec8f9be13f1a6d1f739c1f831d0459baecb88d933
parent2912f44e9c21aa7578bdceb0d78ba53a555c6397 (diff)
downloadmeson-8239d71025ad59e44e7ac7b43849554990efe9f9.zip
meson-8239d71025ad59e44e7ac7b43849554990efe9f9.tar.gz
meson-8239d71025ad59e44e7ac7b43849554990efe9f9.tar.bz2
backends: create ExecutableSerialisation in meson_exe if possible
If meson_exe is only being used to capture the output of the command, we can skip going through a pickled ExecutableSerialization object. This makes "ninja -v" output more useful.
-rw-r--r--mesonbuild/backend/backends.py16
-rw-r--r--mesonbuild/scripts/meson_exe.py33
2 files changed, 34 insertions, 15 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 4e6c259..8328c57 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -69,12 +69,12 @@ class TargetInstallData:
self.optional = optional
class ExecutableSerialisation:
- def __init__(self, name, fname, cmd_args, env, is_cross, exe_wrapper,
- workdir, extra_paths, capture, needs_exe_wrapper: bool):
+ def __init__(self, name, fname, cmd_args, env=None, is_cross=False, exe_wrapper=None,
+ workdir=None, extra_paths=None, capture=None, needs_exe_wrapper: bool = False):
self.name = name
self.fname = fname
self.cmd_args = cmd_args
- self.env = env
+ self.env = env or {}
self.is_cross = is_cross
if exe_wrapper is not None:
assert(isinstance(exe_wrapper, dependencies.ExternalProgram))
@@ -345,6 +345,7 @@ class Backend:
else:
exe_cmd = [exe]
exe_for_machine = MachineChoice.BUILD
+
is_cross_built = not self.environment.machines.matches_build_machine(exe_for_machine)
if is_cross_built and self.environment.need_exe_wrapper():
exe_wrapper = self.environment.get_exe_wrapper()
@@ -356,10 +357,13 @@ class Backend:
else:
exe_wrapper = None
- force_serialize = force_serialize or extra_paths or capture or workdir or \
+ force_serialize = force_serialize or extra_paths or workdir or \
exe_wrapper or any('\n' in c for c in cmd_args)
if not force_serialize:
- return None
+ if not capture:
+ return None
+ return (self.environment.get_build_command() +
+ ['--internal', 'exe', '--capture', capture, '--'] + exe_cmd + cmd_args)
workdir = workdir or self.environment.get_build_dir()
env = {}
@@ -384,7 +388,7 @@ class Backend:
extra_paths, capture,
self.environment.need_exe_wrapper())
pickle.dump(es, f)
- return self.environment.get_build_command() + ['--internal', 'exe', exe_data]
+ return self.environment.get_build_command() + ['--internal', 'exe', '--unpickle', exe_data]
def serialize_tests(self):
test_data = os.path.join(self.environment.get_scratch_dir(), 'meson_test_setup.dat')
diff --git a/mesonbuild/scripts/meson_exe.py b/mesonbuild/scripts/meson_exe.py
index c1d0d64..e5bc9dc 100644
--- a/mesonbuild/scripts/meson_exe.py
+++ b/mesonbuild/scripts/meson_exe.py
@@ -20,12 +20,14 @@ import platform
import subprocess
from .. import mesonlib
+from ..backend.backends import ExecutableSerialisation
options = None
def buildparser():
- parser = argparse.ArgumentParser()
- parser.add_argument('args', nargs='+')
+ parser = argparse.ArgumentParser(description='Custom executable wrapper for Meson. Do not run on your own, mmm\'kay?')
+ parser.add_argument('--unpickle')
+ parser.add_argument('--capture')
return parser
def is_windows():
@@ -101,13 +103,26 @@ def run_exe(exe):
def run(args):
global options
- options = buildparser().parse_args(args)
- if len(options.args) != 1:
- print('Test runner for Meson. Do not run on your own, mmm\'kay?')
- print(sys.argv[0] + ' [data file]')
- exe_data_file = options.args[0]
- with open(exe_data_file, 'rb') as f:
- exe = pickle.load(f)
+ parser = buildparser()
+ options, cmd_args = parser.parse_known_args(args)
+ # argparse supports double dash to separate options and positional arguments,
+ # but the user has to remove it manually.
+ if cmd_args and cmd_args[0] == '--':
+ cmd_args = cmd_args[1:]
+ if not options.unpickle and not cmd_args:
+ parser.error('either --unpickle or executable and arguments are required')
+ if options.unpickle:
+ if cmd_args or options.capture:
+ parser.error('no other arguments can be used with --unpickle')
+ with open(options.unpickle, 'rb') as f:
+ exe = pickle.load(f)
+ else:
+ exe_cmd = cmd_args[0]
+ cmd_args = cmd_args[1:]
+ basename = os.path.basename(exe_cmd)
+ exe = ExecutableSerialisation(basename, [exe_cmd], cmd_args,
+ capture=options.capture)
+
return run_exe(exe)
if __name__ == '__main__':