diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2017-05-08 20:08:28 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-08 20:08:28 +0200 |
commit | e0cf45edf099240cce38661904d3169c7fd9bb76 (patch) | |
tree | 8ac7592c352c08db9e13244f1744cc9d407b54e1 /mesonbuild/interpreter.py | |
parent | 8b0d575823ca6a0a36c20952220b9beec6664b20 (diff) | |
parent | 333085160d6cbff2b4a47fac76cb507cd1f6d1c7 (diff) | |
download | meson-e0cf45edf099240cce38661904d3169c7fd9bb76.zip meson-e0cf45edf099240cce38661904d3169c7fd9bb76.tar.gz meson-e0cf45edf099240cce38661904d3169c7fd9bb76.tar.bz2 |
Merge pull request #1747 from centricular/run-command-configure-file
Some fixes to run_command()
Diffstat (limited to 'mesonbuild/interpreter.py')
-rw-r--r-- | mesonbuild/interpreter.py | 64 |
1 files changed, 32 insertions, 32 deletions
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index 7eb1f26..80d482e 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): @@ -1469,28 +1459,38 @@ class Interpreter(InterpreterBase): raise InterpreterException('Not enough arguments') cmd = args[0] 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] + cmd = cmd.held_object else: - raise InterpreterException('First argument should be find_program() ' - 'or string, not {!r}'.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): - if a.is_built: - raise InterpreterException('Can not use generated files in run_command.') - expanded_args.append(os.path.join(self.environment.get_source_dir(), str(a))) + expanded_args.append(a.absolute_path(srcdir, builddir)) + elif isinstance(a, ExternalProgramHolder): + expanded_args.append(a.held_object.get_path()) else: - raise InterpreterException('Run_command arguments must be strings or the output of files().') - 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, self.environment.source_dir, self.environment.build_dir, self.subdir, + return RunProcess(cmd, expanded_args, srcdir, builddir, self.subdir, get_meson_script(self.environment, 'mesonintrospect'), in_builddir) @stringArgs @@ -1846,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): @@ -2426,7 +2426,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.') |