diff options
Diffstat (limited to 'mesonbuild/interpreter.py')
-rw-r--r-- | mesonbuild/interpreter.py | 63 |
1 files changed, 29 insertions, 34 deletions
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index 2c6806a..5b9bb41 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -23,7 +23,7 @@ from . import compilers from .wrap import wrap, WrapMode from . import mesonlib from .mesonlib import FileMode, Popen_safe, get_meson_script -from .dependencies import InternalDependency, Dependency +from .dependencies import InternalDependency, Dependency, ExternalProgram from .interpreterbase import InterpreterBase from .interpreterbase import check_stringlist, noPosargs, noKwargs, stringArgs from .interpreterbase import InterpreterException, InvalidArguments, InvalidCode @@ -72,17 +72,19 @@ class TryRunResultHolder(InterpreterObject): class RunProcess(InterpreterObject): - def __init__(self, command_array, source_dir, build_dir, subdir, mesonintrospect, in_builddir=False): + def __init__(self, cmd, args, 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, mesonintrospect, in_builddir) + if not isinstance(cmd, ExternalProgram): + raise AssertionError('BUG: RunProcess must be passed an ExternalProgram') + pc, self.stdout, self.stderr = self.run_command(cmd, args, 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, mesonintrospect, in_builddir): - cmd_name = command_array[0] + def run_command(self, cmd, args, source_dir, build_dir, subdir, mesonintrospect, in_builddir): + command_array = cmd.get_command() + args env = {'MESON_SOURCE_ROOT': source_dir, 'MESON_BUILD_ROOT': build_dir, 'MESON_SUBDIR': subdir, @@ -97,18 +99,6 @@ class RunProcess(InterpreterObject): try: return Popen_safe(command_array, env=child_env, cwd=cwd) except FileNotFoundError: - pass - # Was not a command, is a program in path? - exe = shutil.which(cmd_name) - if exe is not None: - command_array = [exe] + command_array[1:] - return Popen_safe(command_array, env=child_env, cwd=cwd) - # No? Maybe it is a script in the source tree. - fullpath = os.path.join(source_dir, subdir, cmd_name) - command_array = [fullpath] + command_array[1:] - try: - return Popen_safe(command_array, env=child_env, cwd=cwd) - except FileNotFoundError: raise InterpreterException('Could not execute command "%s".' % cmd_name) def returncode_method(self, args, kwargs): @@ -250,7 +240,6 @@ class DependencyHolder(InterpreterObject): def found_method(self, args, kwargs): if self.held_object.type_name == 'internal': return True - return self.held_object.found() def version_method(self, args, kwargs): @@ -1105,7 +1094,8 @@ class MesonMain(InterpreterObject): if found.found(): self._found_source_scripts[key] = found else: - raise InterpreterException('Script {!r} not found'.format(name)) + m = 'Script or command {!r} not found or not executable' + raise InterpreterException(m.format(name)) return build.RunScript(found.get_command(), args) def add_install_script_method(self, args, kwargs): @@ -1471,31 +1461,36 @@ class Interpreter(InterpreterBase): cargs = args[1:] srcdir = self.environment.get_source_dir() builddir = self.environment.get_build_dir() + m = 'must be a string, or the output of find_program(), files(), or ' \ + 'configure_file(); not {!r}' if isinstance(cmd, ExternalProgramHolder): - cmd = cmd.get_command() - elif isinstance(cmd, str): - cmd = [cmd] - elif isinstance(cmd, mesonlib.File): - cmd = [cmd.absolute_path(srcdir, builddir)] + cmd = cmd.held_object else: - m = 'First argument must be a string, or the output of ' \ - 'find_program(), files(), or configure_file(); not {!r}' - raise InterpreterException(m.format(cmd)) + if isinstance(cmd, mesonlib.File): + cmd = cmd.absolute_path(srcdir, builddir) + elif not isinstance(cmd, str): + raise InterpreterException('First argument ' + m.format(cmd)) + # Prefer scripts in the current source directory + search_dir = os.path.join(srcdir, self.subdir) + prog = ExternalProgram(cmd, silent=True, search_dir=search_dir) + if not prog.found(): + raise InterpreterException('Program or command {!r} not found' + 'or not executable'.format(cmd)) + cmd = prog expanded_args = [] for a in mesonlib.flatten(cargs): if isinstance(a, str): expanded_args.append(a) elif isinstance(a, mesonlib.File): expanded_args.append(a.absolute_path(srcdir, builddir)) + elif isinstance(a, ExternalProgramHolder): + expanded_args.append(a.held_object.get_path()) else: - m = 'run_command() arguments must be strings, the output of ' \ - 'files(), or configure_file(); not {!r}' - raise InterpreterException(m.format(a)) - args = cmd + expanded_args + raise InterpreterException('Arguments ' + m.format(a)) in_builddir = kwargs.get('in_builddir', False) if not isinstance(in_builddir, bool): raise InterpreterException('in_builddir must be boolean.') - return RunProcess(args, srcdir, builddir, self.subdir, + return RunProcess(cmd, expanded_args, srcdir, builddir, self.subdir, get_meson_script(self.environment, 'mesonintrospect'), in_builddir) @stringArgs @@ -1851,7 +1846,7 @@ class Interpreter(InterpreterBase): if progobj.found(): return progobj if required and not progobj.found(): - raise InvalidArguments('Program "%s" not found.' % exename) + raise InvalidArguments('Program "%s" not found or not executable' % exename) return progobj def func_find_library(self, node, args, kwargs): @@ -2427,7 +2422,7 @@ different subdirectory. exe_wrapper.append(i) elif isinstance(i, dependencies.ExternalProgram): if not i.found(): - raise InterpreterException('Tried to use non-found external executable.') + raise InterpreterException('Tried to use non-found executable.') exe_wrapper += i.get_command() else: raise InterpreterException('Exe wrapper can only contain strings or external binaries.') |