From de65adb8b100731ff31eee92da44b4cc10ac5aa3 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Sun, 11 Mar 2018 14:58:23 +0200 Subject: Made it possible to override find_program to return a different program. Closes https://github.com/mesonbuild/meson/issues/2005 --- mesonbuild/build.py | 2 ++ mesonbuild/interpreter.py | 45 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 2 deletions(-) (limited to 'mesonbuild') diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 8d16c95..97c3df8 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -121,6 +121,8 @@ class Build: self.dep_manifest = {} self.cross_stdlibs = {} self.test_setups = {} + self.find_overrides = {} + self.searched_programs = set() # The list of all programs that have been searched for. def add_compiler(self, compiler): if self.static_linker is None and compiler.needs_static_linker(): diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index b99a413..6d7f2a9 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -1304,6 +1304,7 @@ class MesonMain(InterpreterObject): 'add_install_script': self.add_install_script_method, 'add_postconf_script': self.add_postconf_script_method, 'install_dependency_manifest': self.install_dependency_manifest_method, + 'override_find_program': self.override_find_program_method, 'project_version': self.project_version_method, 'project_license': self.project_license_method, 'version': self.version_method, @@ -1416,6 +1417,20 @@ class MesonMain(InterpreterObject): raise InterpreterException('Argument must be a string.') self.build.dep_manifest_name = args[0] + def override_find_program_method(self, args, kwargs): + if len(args) != 2: + raise InterpreterException('Override needs two arguments') + name = args[0] + exe = args[1] + if not isinstance(name, str): + raise InterpreterException('First argument must be a string') + if hasattr(exe, 'held_object'): + exe = exe.held_object + if not isinstance(exe, dependencies.ExternalProgram): + # FIXME, make this work if the exe is an Executable target. + raise InterpreterException('Second argument must be an external program.') + self.interpreter.add_find_program_override(name, exe) + def project_version_method(self, args, kwargs): return self.build.dep_manifest[self.interpreter.active_projectname]['version'] @@ -2264,6 +2279,31 @@ to directly access options of other subprojects.''') if progobj.found(): return progobj + def program_from_overrides(self, command_names): + for name in command_names: + if not isinstance(name, str): + continue + if name in self.build.find_overrides: + exe = self.build.find_overrides[name] + mlog.log('Program', mlog.bold(name), 'found:', mlog.green('YES'), + '(overridden: %s)' % ' '.join(exe.command)) + return ExternalProgramHolder(exe) + return None + + def store_name_lookups(self, command_names): + for name in command_names: + if isinstance(name, str): + self.build.searched_programs.add(name) + + def add_find_program_override(self, name, exe): + if name in self.build.searched_programs: + raise InterpreterException('Tried to override finding of executable "%s" which has already been found.' + % name) + if name in self.build.find_overrides: + raise InterpreterException('Tried to override executable "%s" which has already been overridden.' + % name) + self.build.find_overrides[name] = exe + @permittedKwargs(permitted_kwargs['find_program']) def func_find_program(self, node, args, kwargs): if not args: @@ -2271,8 +2311,9 @@ to directly access options of other subprojects.''') required = kwargs.get('required', True) if not isinstance(required, bool): raise InvalidArguments('"required" argument must be a boolean.') - progobj = None - if self.build.environment.is_cross_build(): + self.store_name_lookups(args) + progobj = self.program_from_overrides(args) + if progobj is None and self.build.environment.is_cross_build(): use_native = kwargs.get('native', False) if not isinstance(use_native, bool): raise InvalidArguments('Argument to "native" must be a boolean.') -- cgit v1.1