Made it possible to override find_program to return a different program.

Closes https://github.com/mesonbuild/meson/issues/2005
pull/3218/head
Jussi Pakkanen 7 years ago committed by Nirbheek Chauhan
parent 3f7c6cf3d6
commit de65adb8b1
  1. 2
      mesonbuild/build.py
  2. 45
      mesonbuild/interpreter.py
  3. 4
      test cases/common/182 find override/meson.build
  4. 5
      test cases/common/182 find override/otherdir/main.c
  5. 11
      test cases/common/182 find override/otherdir/meson.build
  6. 1
      test cases/common/182 find override/otherdir/source.desc
  7. 15
      test cases/common/182 find override/subdir/converter.py
  8. 3
      test cases/common/182 find override/subdir/meson.build
  9. 5
      test cases/failing/70 override used/meson.build
  10. 3
      test cases/failing/70 override used/other.py
  11. 3
      test cases/failing/70 override used/something.py
  12. 5
      test cases/failing/71 dual override/meson.build
  13. 4
      test cases/failing/71 dual override/overrides.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():

@ -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.')

@ -0,0 +1,4 @@
project('find program override', 'c')
subdir('subdir')
subdir('otherdir')

@ -0,0 +1,5 @@
int be_seeing_you();
int main(int argc, char **argv) {
return be_seeing_you() == 6 ? 0 : 1;
}

@ -0,0 +1,11 @@
gen = find_program('codegen') # Should use overridden value set in "subdir".
src = custom_target('arrival',
input : 'source.desc',
output : 'file.c',
command : [gen, '@INPUT@', '@OUTPUT@']
)
e = executable('six', 'main.c', src)
test('six', e)

@ -0,0 +1,15 @@
#!/usr/bin/env python3
import sys
import pathlib
[ifilename, ofilename] = sys.argv[1:3]
ftempl = '''int %s() {
return 6;
}
'''
d = pathlib.Path(ifilename).read_text().split('\n')[0].strip()
pathlib.Path(ofilename).write_text(ftempl % d)

@ -0,0 +1,3 @@
x = find_program('converter.py')
meson.override_find_program('codegen', x)

@ -0,0 +1,5 @@
project('overridde an already found exe', 'c')
old = find_program('something.py')
replacement = find_program('other.py')
meson.override_find_program('something.py', replacement)

@ -0,0 +1,3 @@
#!/usr/bin/env python3
print('Doing something else.')

@ -0,0 +1,3 @@
#!/usr/bin/env python3
print('Doing something.')

@ -0,0 +1,5 @@
project('yo dawg', 'c')
p = find_program('overrides.py')
meson.override_find_program('override', p)
meson.override_find_program('override', p)

@ -0,0 +1,4 @@
#!/usr/bin/env python3
print('Yo dawg, we put overrides in your overrides,')
print('so now you can override when you override.')
Loading…
Cancel
Save