diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 85d5eb6c8..156f3bdd1 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -395,13 +395,30 @@ class Backend: exe_cmd = ['mono'] + exe_cmd exe_wrapper = None - force_serialize = force_serialize or extra_paths or workdir or \ - exe_wrapper or any('\n' in c for c in cmd_args) + reasons = [] + if extra_paths: + reasons.append('to set PATH') + + if exe_wrapper: + reasons.append('to use exe_wrapper') + + if workdir: + reasons.append('to set workdir') + + if any('\n' in c for c in cmd_args): + reasons.append('because command contains newlines') + + force_serialize = force_serialize or bool(reasons) + + if capture: + reasons.append('to capture output') + if not force_serialize: if not capture: - return None - return (self.environment.get_build_command() + - ['--internal', 'exe', '--capture', capture, '--'] + exe_cmd + cmd_args) + return None, '' + return ((self.environment.get_build_command() + + ['--internal', 'exe', '--capture', capture, '--'] + exe_cmd + cmd_args), + ', '.join(reasons)) workdir = workdir or self.environment.get_build_dir() env = {} @@ -425,7 +442,8 @@ class Backend: exe_wrapper, workdir, extra_paths, capture) pickle.dump(es, f) - return self.environment.get_build_command() + ['--internal', 'exe', '--unpickle', exe_data] + return (self.environment.get_build_command() + ['--internal', 'exe', '--unpickle', exe_data], + ', '.join(reasons)) def serialize_tests(self): test_data = os.path.join(self.environment.get_scratch_dir(), 'meson_test_setup.dat') diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 66fc46489..d25360141 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -870,7 +870,7 @@ int dummy; (srcs, ofilenames, cmd) = self.eval_custom_target_command(target) deps = self.unwrap_dep_list(target) deps += self.get_custom_target_depend_files(target) - desc = 'Generating {0} with a {1} command' + desc = 'Generating {0} with a custom command{1}' if target.build_always_stale: deps.append('PHONY') if target.depfile is None: @@ -884,14 +884,14 @@ int dummy; for output in d.get_outputs(): elem.add_dep(os.path.join(self.get_target_dir(d), output)) - meson_exe_cmd = self.as_meson_exe_cmdline(target.name, target.command[0], cmd[1:], - extra_bdeps=target.get_transitive_build_target_deps(), - capture=ofilenames[0] if target.capture else None) + meson_exe_cmd, reason = self.as_meson_exe_cmdline(target.name, target.command[0], cmd[1:], + extra_bdeps=target.get_transitive_build_target_deps(), + capture=ofilenames[0] if target.capture else None) if meson_exe_cmd: cmd = meson_exe_cmd - cmd_type = 'meson_exe.py custom' + cmd_type = ' (wrapped by meson {})'.format(reason) else: - cmd_type = 'custom' + cmd_type = '' if target.depfile is not None: depfile = target.get_dep_outname(elem.infilenames) rel_dfile = os.path.join(self.get_target_dir(target), depfile) @@ -2012,9 +2012,9 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485''')) outfilelist = outfilelist[len(generator.outputs):] args = self.replace_paths(target, args, override_subdir=subdir) cmdlist = exe_arr + self.replace_extra_args(args, genlist) - meson_exe_cmd = self.as_meson_exe_cmdline('generator ' + cmdlist[0], - cmdlist[0], cmdlist[1:], - capture=outfiles[0] if generator.capture else None) + meson_exe_cmd, reason = self.as_meson_exe_cmdline('generator ' + cmdlist[0], + cmdlist[0], cmdlist[1:], + capture=outfiles[0] if generator.capture else None) if meson_exe_cmd: cmdlist = meson_exe_cmd abs_pdir = os.path.join(self.environment.get_build_dir(), self.get_target_dir(target)) @@ -2026,11 +2026,16 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485''')) elem.add_item('DEPFILE', depfile) if len(extra_dependencies) > 0: elem.add_dep(extra_dependencies) + if len(generator.outputs) == 1: - elem.add_item('DESC', 'Generating {!r}.'.format(sole_output)) + what = '{!r}'.format(sole_output) else: # since there are multiple outputs, we log the source that caused the rebuild - elem.add_item('DESC', 'Generating source from {!r}.'.format(sole_output)) + what = 'from {!r}.'.format(sole_output) + if reason: + reason = ' (wrapped by meson {})'.format(reason) + elem.add_item('DESC', 'Generating {}{}.'.format(what, reason)) + if isinstance(exe, build.BuildTarget): elem.add_dep(self.get_target_filename(exe)) elem.add_item('COMMAND', cmdlist) diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index 3b0f84246..c2969edf9 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -150,7 +150,7 @@ class Vs2010Backend(backends.Backend): # Always use a wrapper because MSBuild eats random characters when # there are many arguments. tdir_abs = os.path.join(self.environment.get_build_dir(), self.get_target_dir(target)) - cmd = self.as_meson_exe_cmdline( + cmd, _ = self.as_meson_exe_cmdline( 'generator ' + cmd[0], cmd[0], cmd[1:], @@ -565,12 +565,12 @@ class Vs2010Backend(backends.Backend): # there are many arguments. tdir_abs = os.path.join(self.environment.get_build_dir(), self.get_target_dir(target)) extra_bdeps = target.get_transitive_build_target_deps() - wrapper_cmd = self.as_meson_exe_cmdline(target.name, target.command[0], cmd[1:], - # All targets run from the target dir - workdir=tdir_abs, - extra_bdeps=extra_bdeps, - capture=ofilenames[0] if target.capture else None, - force_serialize=True) + wrapper_cmd, _ = self.as_meson_exe_cmdline(target.name, target.command[0], cmd[1:], + # All targets run from the target dir + workdir=tdir_abs, + extra_bdeps=extra_bdeps, + capture=ofilenames[0] if target.capture else None, + force_serialize=True) if target.build_always_stale: # Use a nonexistent file to always consider the target out-of-date. ofilenames += [self.nonexistent_file(os.path.join(self.environment.get_scratch_dir(),