aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/interpreter.py
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild/interpreter.py')
-rw-r--r--mesonbuild/interpreter.py83
1 files changed, 58 insertions, 25 deletions
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 89c9daa..e616d85 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -3251,7 +3251,7 @@ external dependencies (including libraries) must go to "dependencies".''')
return success
- def program_from_file_for(self, for_machine, prognames, silent):
+ def program_from_file_for(self, for_machine, prognames):
for p in unholder(prognames):
if isinstance(p, mesonlib.File):
continue # Always points to a local (i.e. self generated) file.
@@ -3290,15 +3290,13 @@ external dependencies (including libraries) must go to "dependencies".''')
if progobj.found():
return progobj
- def program_from_overrides(self, command_names, silent=False):
+ def program_from_overrides(self, command_names, extra_info):
for name in command_names:
if not isinstance(name, str):
continue
if name in self.build.find_overrides:
exe = self.build.find_overrides[name]
- if not silent:
- mlog.log('Program', mlog.bold(name), 'found:', mlog.green('YES'),
- '(overridden: %s)' % exe.description())
+ extra_info.append(mlog.blue('(overriden)'))
return ExternalProgramHolder(exe, self.subproject, self.backend)
return None
@@ -3316,40 +3314,75 @@ external dependencies (including libraries) must go to "dependencies".''')
% name)
self.build.find_overrides[name] = exe
+ def notfound_program(self, args):
+ return ExternalProgramHolder(dependencies.NonExistingExternalProgram(' '.join(args)), self.subproject)
+
# TODO update modules to always pass `for_machine`. It is bad-form to assume
# the host machine.
def find_program_impl(self, args, for_machine: MachineChoice = MachineChoice.HOST,
required=True, silent=True, wanted='', search_dirs=None):
- if not isinstance(args, list):
- args = [args]
+ args = mesonlib.listify(args)
- progobj = self.program_from_overrides(args, silent=silent)
- if progobj is None:
- progobj = self.program_from_file_for(for_machine, args, silent=silent)
- if progobj is None:
- progobj = self.program_from_system(args, search_dirs, silent=silent)
- if progobj is None and args[0].endswith('python3'):
- prog = dependencies.ExternalProgram('python3', mesonlib.python_command, silent=True)
- progobj = ExternalProgramHolder(prog, self.subproject)
- if required and (progobj is None or not progobj.found()):
- raise InvalidArguments('Program(s) {!r} not found or not executable'.format(args))
+ extra_info = []
+ progobj = self.program_lookup(args, for_machine, required, search_dirs, extra_info)
if progobj is None:
- return ExternalProgramHolder(dependencies.NonExistingExternalProgram(' '.join(args)), self.subproject)
- # Only store successful lookups
- self.store_name_lookups(args)
+ progobj = self.notfound_program(args)
+
+ if not progobj.found():
+ mlog.log('Program', mlog.bold(progobj.get_name()), 'found:', mlog.red('NO'))
+ if required:
+ m = 'Program {!r} not found'
+ raise InterpreterException(m.format(progobj.get_name()))
+ return progobj
+
if wanted:
version = progobj.get_version(self)
is_found, not_found, found = mesonlib.version_compare_many(version, wanted)
if not is_found:
mlog.log('Program', mlog.bold(progobj.get_name()), 'found:', mlog.red('NO'),
- 'found {!r} but need:'.format(version),
- ', '.join(["'{}'".format(e) for e in not_found]))
+ 'found', mlog.normal_cyan(version), 'but need:',
+ mlog.bold(', '.join(["'{}'".format(e) for e in not_found])))
if required:
m = 'Invalid version of program, need {!r} {!r} found {!r}.'
- raise InvalidArguments(m.format(progobj.get_name(), not_found, version))
- return ExternalProgramHolder(dependencies.NonExistingExternalProgram(' '.join(args)), self.subproject)
+ raise InterpreterException(m.format(progobj.get_name(), not_found, version))
+ return self.notfound_program(args)
+ extra_info.insert(0, mlog.normal_cyan(version))
+
+ # Only store successful lookups
+ self.store_name_lookups(args)
+ mlog.log('Program', mlog.bold(progobj.get_name()), 'found:', mlog.green('YES'), *extra_info)
return progobj
+ def program_lookup(self, args, for_machine, required, search_dirs, extra_info):
+ progobj = self.program_from_overrides(args, extra_info)
+ if progobj:
+ return progobj
+
+ fallback = None
+ wrap_mode = self.coredata.get_builtin_option('wrap_mode')
+ if wrap_mode != WrapMode.nofallback:
+ fallback = self.environment.wrap_resolver.find_program_provider(args)
+ if fallback and wrap_mode == WrapMode.forcefallback:
+ return self.find_program_fallback(fallback, args, required, extra_info)
+
+ progobj = self.program_from_file_for(for_machine, args)
+ if progobj is None:
+ progobj = self.program_from_system(args, search_dirs, silent=True)
+ if progobj is None and args[0].endswith('python3'):
+ prog = dependencies.ExternalProgram('python3', mesonlib.python_command, silent=True)
+ progobj = ExternalProgramHolder(prog, self.subproject) if prog.found() else None
+ if progobj is None and fallback and required:
+ progobj = self.find_program_fallback(fallback, args, required, extra_info)
+
+ return progobj
+
+ def find_program_fallback(self, fallback, args, required, extra_info):
+ mlog.log('Fallback to subproject', mlog.bold(fallback), 'which provides program',
+ mlog.bold(' '.join(args)))
+ sp_kwargs = { 'required': required }
+ self.do_subproject(fallback, 'meson', sp_kwargs)
+ return self.program_from_overrides(args, extra_info)
+
@FeatureNewKwargs('find_program', '0.53.0', ['dirs'])
@FeatureNewKwargs('find_program', '0.52.0', ['version'])
@FeatureNewKwargs('find_program', '0.49.0', ['disabler'])
@@ -3362,7 +3395,7 @@ external dependencies (including libraries) must go to "dependencies".''')
disabled, required, feature = extract_required_kwarg(kwargs, self.subproject)
if disabled:
mlog.log('Program', mlog.bold(' '.join(args)), 'skipped: feature', mlog.bold(feature), 'disabled')
- return ExternalProgramHolder(dependencies.NonExistingExternalProgram(' '.join(args)), self.subproject)
+ return self.notfound_program(args)
search_dirs = extract_search_dirs(kwargs)
wanted = mesonlib.stringlistify(kwargs.get('version', []))