diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 80cf0ee63..efc5bffa5 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -20,7 +20,8 @@ from .. import mlog from .. import compilers import json import subprocess -from ..mesonlib import MesonException, get_compiler_for_source, classify_unity_sources +from ..mesonlib import MesonException, get_meson_script +from ..mesonlib import get_compiler_for_source, classify_unity_sources from ..compilers import CompilerArgs class CleanTrees: @@ -33,7 +34,7 @@ class CleanTrees: self.trees = trees class InstallData: - def __init__(self, source_dir, build_dir, prefix, strip_bin): + def __init__(self, source_dir, build_dir, prefix, strip_bin, mesonintrospect): self.source_dir = source_dir self.build_dir = build_dir self.prefix = prefix @@ -46,6 +47,7 @@ class InstallData: self.po = [] self.install_scripts = [] self.install_subdirs = [] + self.mesonintrospect = mesonintrospect class ExecutableSerialisation: def __init__(self, name, fname, cmd_args, env, is_cross, exe_wrapper, @@ -714,7 +716,7 @@ class Backend: def run_postconf_scripts(self): env = {'MESON_SOURCE_ROOT': self.environment.get_source_dir(), 'MESON_BUILD_ROOT': self.environment.get_build_dir(), - } + 'MESONINTROSPECT': get_meson_script(self.environment, 'mesonintrospect')} child_env = os.environ.copy() child_env.update(env) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 31439707c..5a9462fa0 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -20,7 +20,8 @@ from .. import mlog from .. import dependencies from .. import compilers from ..compilers import CompilerArgs -from ..mesonlib import File, MesonException, get_compiler_for_source, Popen_safe +from ..mesonlib import File, MesonException +from ..mesonlib import get_meson_script, get_compiler_for_source, Popen_safe from .backends import CleanTrees, InstallData from ..build import InvalidArguments import os, sys, pickle, re @@ -515,7 +516,7 @@ int dummy; self.processed_targets[target.name + target.type_suffix()] = True def generate_run_target(self, target, outfile): - runnerscript = [sys.executable, self.environment.get_build_command(), '--internal', 'commandrunner'] + cmd = [sys.executable, self.environment.get_build_command(), '--internal', 'commandrunner'] deps = self.unwrap_dep_list(target) arg_strings = [] for i in target.args: @@ -531,7 +532,10 @@ int dummy; else: raise AssertionError('Unreachable code in generate_run_target: ' + str(i)) elem = NinjaBuildElement(self.all_outputs, target.name, 'CUSTOM_COMMAND', []) - cmd = runnerscript + [self.environment.get_source_dir(), self.environment.get_build_dir(), target.subdir] + cmd += [self.environment.get_source_dir(), + self.environment.get_build_dir(), + target.subdir, + get_meson_script(self.environment, 'mesonintrospect')] texe = target.command try: texe = texe.held_object @@ -608,7 +612,8 @@ int dummy; d = InstallData(self.environment.get_source_dir(), self.environment.get_build_dir(), self.environment.get_prefix(), - strip_bin) + strip_bin, + get_meson_script(self.environment, 'mesonintrospect')) elem = NinjaBuildElement(self.all_outputs, 'install', 'CUSTOM_COMMAND', 'PHONY') elem.add_dep('all') elem.add_item('DESC', 'Installing files.') @@ -729,9 +734,7 @@ int dummy; def generate_tests(self, outfile): self.serialise_tests() - meson_exe = self.environment.get_build_command() - (base, ext) = os.path.splitext(meson_exe) - test_exe = base + 'test' + ext + test_exe = get_meson_script(self.environment, 'mesontest') cmd = [sys.executable, test_exe, '--no-rebuild'] if not self.environment.coredata.get_builtin_option('stdsplit'): cmd += ['--no-stdsplit'] diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index 7afbc0d17..139360c57 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -24,7 +24,7 @@ from .. import mlog from .. import compilers from ..build import BuildTarget from ..compilers import CompilerArgs -from ..mesonlib import MesonException, File +from ..mesonlib import MesonException, File, get_meson_script from ..environment import Environment def autodetect_vs_version(build): @@ -409,8 +409,10 @@ class Vs2010Backend(backends.Backend): customstep = ET.SubElement(action, 'PostBuildEvent') cmd_raw = [target.command] + target.args cmd = [sys.executable, os.path.join(self.environment.get_script_dir(), 'commandrunner.py'), - self.environment.get_build_dir(), self.environment.get_source_dir(), - self.get_target_dir(target)] + self.environment.get_build_dir(), + self.environment.get_source_dir(), + self.get_target_dir(target), + get_meson_script(self.environment, 'mesonintrospect')] for i in cmd_raw: if isinstance(i, build.BuildTarget): cmd.append(os.path.join(self.environment.get_build_dir(), self.get_target_filename(i))) @@ -1164,11 +1166,8 @@ if %%errorlevel%% neq 0 goto :VCEnd''' postbuild = ET.SubElement(action, 'PostBuildEvent') ET.SubElement(postbuild, 'Message') # FIXME: No benchmarks? - meson_py = self.environment.get_build_command() - (base, ext) = os.path.splitext(meson_py) - mesontest_py = base + 'test' + ext test_command = [sys.executable, - mesontest_py, + get_meson_script(self.environment, 'mesontest'), '--no-rebuild'] if not self.environment.coredata.get_builtin_option('stdsplit'): test_command += ['--no-stdsplit'] diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index d1ac56994..8c8000cc5 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -22,7 +22,7 @@ from . import optinterpreter from . import compilers from .wrap import wrap, WrapMode from . import mesonlib -from .mesonlib import FileMode, Popen_safe +from .mesonlib import FileMode, Popen_safe, get_meson_script from .dependencies import InternalDependency, Dependency from .interpreterbase import InterpreterBase from .interpreterbase import check_stringlist, noPosargs, noKwargs, stringArgs @@ -72,20 +72,21 @@ class TryRunResultHolder(InterpreterObject): class RunProcess(InterpreterObject): - def __init__(self, command_array, source_dir, build_dir, subdir, in_builddir=False): + def __init__(self, command_array, source_dir, build_dir, subdir, mesonintrospect, in_builddir=False): super().__init__() - pc, self.stdout, self.stderr = self.run_command(command_array, source_dir, build_dir, subdir, in_builddir) + pc, self.stdout, self.stderr = self.run_command(command_array, source_dir, build_dir, subdir, mesonintrospect, in_builddir) self.returncode = pc.returncode self.methods.update({'returncode': self.returncode_method, 'stdout': self.stdout_method, 'stderr': self.stderr_method, }) - def run_command(self, command_array, source_dir, build_dir, subdir, in_builddir): + def run_command(self, command_array, source_dir, build_dir, subdir, mesonintrospect, in_builddir): cmd_name = command_array[0] env = {'MESON_SOURCE_ROOT': source_dir, 'MESON_BUILD_ROOT': build_dir, - 'MESON_SUBDIR': subdir} + 'MESON_SUBDIR': subdir, + 'MESONINTROSPECT': mesonintrospect} if in_builddir: cwd = os.path.join(build_dir, subdir) else: @@ -1490,8 +1491,8 @@ class Interpreter(InterpreterBase): in_builddir = kwargs.get('in_builddir', False) if not isinstance(in_builddir, bool): raise InterpreterException('in_builddir must be boolean.') - return RunProcess(args, self.environment.source_dir, self.environment.build_dir, - self.subdir, in_builddir) + return RunProcess(args, self.environment.source_dir, self.environment.build_dir, self.subdir, + get_meson_script(self.environment, 'mesonintrospect'), in_builddir) @stringArgs def func_gettext(self, nodes, args, kwargs): diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py index 291eb68fc..a2ab4843a 100644 --- a/mesonbuild/mesonlib.py +++ b/mesonbuild/mesonlib.py @@ -175,6 +175,15 @@ class File: def relative_name(self): return os.path.join(self.subdir, self.fname) +def get_meson_script(env, script): + ''' + Given the path of `meson.py`/`meson`, get the path of a meson script such + as `mesonintrospect` or `mesontest`. + ''' + meson_py = env.get_build_command() + (base, ext) = os.path.splitext(meson_py) + return os.path.join(os.path.dirname(base), script + ext) + def get_compiler_for_source(compilers, src): for comp in compilers: if comp.can_compile(src): diff --git a/mesonbuild/scripts/commandrunner.py b/mesonbuild/scripts/commandrunner.py index cf2770dc5..87e3b8bf3 100644 --- a/mesonbuild/scripts/commandrunner.py +++ b/mesonbuild/scripts/commandrunner.py @@ -17,11 +17,11 @@ what to run, sets up the environment and executes the command.""" import sys, os, subprocess, shutil -def run_command(source_dir, build_dir, subdir, command, arguments): +def run_command(source_dir, build_dir, subdir, mesonintrospect, command, arguments): env = {'MESON_SOURCE_ROOT': source_dir, 'MESON_BUILD_ROOT': build_dir, 'MESON_SUBDIR': subdir, - } + 'MESONINTROSPECT': mesonintrospect} cwd = os.path.join(source_dir, subdir) child_env = os.environ.copy() child_env.update(env) @@ -47,9 +47,10 @@ def run(args): src_dir = args[0] build_dir = args[1] subdir = args[2] - command = args[3] - arguments = args[4:] - pc = run_command(src_dir, build_dir, subdir, command, arguments) + mesonintrospect = args[3] + command = args[4] + arguments = args[5:] + pc = run_command(src_dir, build_dir, subdir, mesonintrospect, command, arguments) pc.wait() return pc.returncode diff --git a/mesonbuild/scripts/meson_install.py b/mesonbuild/scripts/meson_install.py index e1720322f..2205f1ae0 100644 --- a/mesonbuild/scripts/meson_install.py +++ b/mesonbuild/scripts/meson_install.py @@ -183,7 +183,7 @@ def run_install_script(d): 'MESON_BUILD_ROOT': d.build_dir, 'MESON_INSTALL_PREFIX': d.prefix, 'MESON_INSTALL_DESTDIR_PREFIX': d.fullprefix, - } + 'MESONINTROSPECT': d.mesonintrospect} child_env = os.environ.copy() child_env.update(env) diff --git a/test cases/common/141 mesonintrospect from scripts/check_env.py b/test cases/common/141 mesonintrospect from scripts/check_env.py new file mode 100644 index 000000000..dc8ad638c --- /dev/null +++ b/test cases/common/141 mesonintrospect from scripts/check_env.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 + +import os +import sys + +do_print = False + +if len(sys.argv) > 1: + do_print = bool(sys.argv[1]) + +if 'MESONINTROSPECT' not in os.environ: + raise RuntimeError('MESONINTROSPECT not found') + +mesonintrospect = os.environ['MESONINTROSPECT'] + +if not os.path.isfile(mesonintrospect): + raise RuntimeError('{!r} does not exist'.format(mesonintrospect)) + +if do_print: + print(mesonintrospect, end='') diff --git a/test cases/common/141 mesonintrospect from scripts/meson.build b/test cases/common/141 mesonintrospect from scripts/meson.build new file mode 100644 index 000000000..f78710b47 --- /dev/null +++ b/test cases/common/141 mesonintrospect from scripts/meson.build @@ -0,0 +1,14 @@ +project('mesonintrospect from scripts', 'c') + +python = import('python3').find_python() + +ret = run_command(python, ['check_env.py', '1']) +if ret.returncode() == 0 + find_program(ret.stdout()) +else + message(ret.stdout()) + message(ret.stderr()) +endif + +meson.add_postconf_script('check_env.py') +meson.add_install_script('check_env.py')