aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2018-04-16 22:22:02 +0300
committerGitHub <noreply@github.com>2018-04-16 22:22:02 +0300
commit0e00470d8c9711e62848a1d697d156cbab66e0bc (patch)
tree192047ead98b0c212f5b6b5b730f3f7d9ed87157
parent5e45f4c621f14176478e3160e2bb3c6c77796b41 (diff)
parent6cdd14fc4eca8bddd4716ab5a9ebf09476846e6b (diff)
downloadmeson-0e00470d8c9711e62848a1d697d156cbab66e0bc.zip
meson-0e00470d8c9711e62848a1d697d156cbab66e0bc.tar.gz
meson-0e00470d8c9711e62848a1d697d156cbab66e0bc.tar.bz2
Merge pull request #3218 from mesonbuild/findoverrider
Make it possible to override find_program [skip ci]
-rw-r--r--docs/markdown/Reference-manual.md7
-rw-r--r--docs/markdown/snippets/find-override.md37
-rw-r--r--mesonbuild/build.py2
-rw-r--r--mesonbuild/coredata.py1
-rw-r--r--mesonbuild/interpreter.py110
-rw-r--r--mesonbuild/mesonmain.py3
-rw-r--r--mesonbuild/modules/__init__.py15
-rw-r--r--mesonbuild/modules/gnome.py30
-rw-r--r--mesonbuild/modules/i18n.py4
-rw-r--r--mesonbuild/modules/modtest.py4
-rw-r--r--mesonbuild/modules/pkgconfig.py4
-rw-r--r--mesonbuild/modules/python3.py8
-rw-r--r--mesonbuild/modules/qt4.py8
-rw-r--r--mesonbuild/modules/qt5.py8
-rw-r--r--mesonbuild/modules/rpm.py4
-rw-r--r--mesonbuild/modules/unstable_icestorm.py18
-rw-r--r--mesonbuild/modules/unstable_simd.py8
-rw-r--r--mesonbuild/modules/windows.py4
-rw-r--r--test cases/common/190 find override/meson.build12
-rw-r--r--test cases/common/190 find override/otherdir/main.c5
-rw-r--r--test cases/common/190 find override/otherdir/main2.c5
-rw-r--r--test cases/common/190 find override/otherdir/meson.build26
-rw-r--r--test cases/common/190 find override/otherdir/source.desc1
-rw-r--r--test cases/common/190 find override/otherdir/source2.desc1
-rwxr-xr-xtest cases/common/190 find override/subdir/converter.py15
-rwxr-xr-xtest cases/common/190 find override/subdir/gencodegen.py.in15
-rw-r--r--test cases/common/190 find override/subdir/meson.build14
-rw-r--r--test cases/failing/72 override used/meson.build5
-rwxr-xr-xtest cases/failing/72 override used/other.py3
-rwxr-xr-xtest cases/failing/72 override used/something.py3
-rw-r--r--test cases/failing/73 dual override/meson.build5
-rw-r--r--test cases/failing/73 dual override/overrides.py4
32 files changed, 299 insertions, 90 deletions
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index da4c92b..fad6a3c 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -1396,6 +1396,13 @@ the following methods.
/path/to/meson.py introspect`. The user is responsible for splitting
the string to an array if needed.
+- `override_find_program(progname, program)` [*(Added
+ 0.46.0)*](Release-notes-for-0-46-0.html#Can-override-find_program)
+ specifies that whenever `find_program` is used to find a program
+ named `progname`, Meson should not not look it up on the system but
+ instead return `program`, which may either be the result of
+ `find_program` or `configure_file`.
+
- `project_version()` returns the version string specified in `project` function call.
- `project_license()` returns the array of licenses specified in `project` function call.
diff --git a/docs/markdown/snippets/find-override.md b/docs/markdown/snippets/find-override.md
new file mode 100644
index 0000000..ef3a4a2
--- /dev/null
+++ b/docs/markdown/snippets/find-override.md
@@ -0,0 +1,37 @@
+## Can override find_program
+
+It is now possible to override the result of `find_program` to point
+to a custom program you want. The overriding is global and applies to
+every subproject from there on. Here is how you would use it.
+
+In master project
+
+```meson
+subproject('mydep')
+```
+
+In the called subproject:
+
+```meson
+prog = find_program('my_custom_script')
+meson.override_find_program('mycodegen', prog)
+```
+
+In master project (or, in fact, any subproject):
+
+```meson
+genprog = find_program('mycodegen')
+```
+
+Now `genprog` points to the custom script. If the dependency had come
+from the system, then it would point to the system version.
+
+You can also use the return value of `configure_file()` to override
+a program in the same way as above:
+
+```meson
+prog_script = configure_file(input : 'script.sh.in',
+ output : 'script.sh',
+ configuration : cdata)
+meson.override_find_program('mycodegen', prog_script)
+```
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/coredata.py b/mesonbuild/coredata.py
index a696cca..918671a 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -185,7 +185,6 @@ class CoreData:
self.compilers = OrderedDict()
self.cross_compilers = OrderedDict()
self.deps = OrderedDict()
- self.modules = {}
# Only to print a warning if it changes between Meson invocations.
self.pkgconf_envvar = os.environ.get('PKG_CONFIG_PATH', '')
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index b99a413..a130312 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,26 @@ 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 isinstance(exe, mesonlib.File):
+ abspath = exe.absolute_path(self.interpreter.environment.source_dir,
+ self.interpreter.environment.build_dir)
+ if not os.path.exists(abspath):
+ raise InterpreterException('Tried to override %s with a file that does not exist.' % name)
+ exe = dependencies.ExternalProgram(abspath)
+ 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']
@@ -1493,7 +1514,7 @@ permitted_kwargs = {'add_global_arguments': {'language'},
class Interpreter(InterpreterBase):
def __init__(self, build, backend, subproject='', subdir='', subproject_dir='subprojects',
- default_project_options=[]):
+ modules = None, default_project_options=[]):
super().__init__(build.environment.get_source_dir(), subdir)
self.an_unpicklable_object = mesonlib.an_unpicklable_object
self.build = build
@@ -1501,6 +1522,10 @@ class Interpreter(InterpreterBase):
self.coredata = self.environment.get_coredata()
self.backend = backend
self.subproject = subproject
+ if modules is None:
+ self.modules = {}
+ else:
+ self.modules = modules
# Subproject directory is usually the name of the subproject, but can
# be different for dependencies provided by wrap files.
self.subproject_directory_name = subdir.split(os.path.sep)[-1]
@@ -1681,13 +1706,13 @@ class Interpreter(InterpreterBase):
plainname = modname.split('-', 1)[1]
mlog.warning('Module %s has no backwards or forwards compatibility and might not exist in future releases.' % modname, location=node)
modname = 'unstable_' + plainname
- if modname not in self.environment.coredata.modules:
+ if modname not in self.modules:
try:
module = importlib.import_module('mesonbuild.modules.' + modname)
except ImportError:
raise InvalidArguments('Module "%s" does not exist' % (modname, ))
- self.environment.coredata.modules[modname] = module.initialize()
- return ModuleHolder(modname, self.environment.coredata.modules[modname], self)
+ self.modules[modname] = module.initialize(self)
+ return ModuleHolder(modname, self.modules[modname], self)
@stringArgs
@noKwargs
@@ -1864,15 +1889,16 @@ external dependencies (including libraries) must go to "dependencies".''')
self.global_args_frozen = True
mlog.log()
with mlog.nested():
- mlog.log('Executing subproject ', mlog.bold(dirname), '.\n', sep='')
+ mlog.log('\nExecuting subproject ', mlog.bold(dirname), '.\n', sep='')
subi = Interpreter(self.build, self.backend, dirname, subdir, self.subproject_dir,
- mesonlib.stringlistify(kwargs.get('default_options', [])))
+ self.modules, mesonlib.stringlistify(kwargs.get('default_options', [])))
subi.subprojects = self.subprojects
subi.subproject_stack = self.subproject_stack + [dirname]
current_active = self.active_projectname
subi.run()
mlog.log('\nSubproject', mlog.bold(dirname), 'finished.')
+
if 'version' in kwargs:
pv = subi.project_version
wanted = kwargs['version']
@@ -2225,7 +2251,7 @@ to directly access options of other subprojects.''')
break
self.coredata.base_options[optname] = oobj
- def program_from_cross_file(self, prognames):
+ def program_from_cross_file(self, prognames, silent=False):
bins = self.environment.cross_info.config['binaries']
for p in prognames:
if hasattr(p, 'held_object'):
@@ -2236,11 +2262,11 @@ to directly access options of other subprojects.''')
raise InterpreterException('Executable name must be a string.')
if p in bins:
exename = bins[p]
- extprog = dependencies.ExternalProgram(exename)
+ extprog = dependencies.ExternalProgram(exename, silent=silent)
progobj = ExternalProgramHolder(extprog)
return progobj
- def program_from_system(self, args):
+ def program_from_system(self, args, silent=False):
# Search for scripts relative to current subdir.
# Do not cache found programs because find_program('foobar')
# might give different results when run from different source dirs.
@@ -2259,11 +2285,55 @@ to directly access options of other subprojects.''')
else:
raise InvalidArguments('find_program only accepts strings and '
'files, not {!r}'.format(exename))
- extprog = dependencies.ExternalProgram(exename, search_dir=search_dir)
+ extprog = dependencies.ExternalProgram(exename, search_dir=search_dir,
+ silent=silent)
progobj = ExternalProgramHolder(extprog)
if progobj.found():
return progobj
+ def program_from_overrides(self, command_names, silent=False):
+ 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)' % ' '.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
+
+ def find_program_impl(self, args, native=False, required=True, silent=True):
+ if not isinstance(args, list):
+ args = [args]
+ progobj = self.program_from_overrides(args, silent=silent)
+ if progobj is None and self.build.environment.is_cross_build():
+ if not native:
+ progobj = self.program_from_cross_file(args, silent=silent)
+ if progobj is None:
+ progobj = self.program_from_system(args, silent=silent)
+ if required and (progobj is None or not progobj.found()):
+ raise InvalidArguments('Program(s) {!r} not found or not executable'.format(args))
+ if progobj is None:
+ return ExternalProgramHolder(dependencies.NonExistingExternalProgram())
+ # Only store successful lookups
+ self.store_name_lookups(args)
+ return progobj
+
@permittedKwargs(permitted_kwargs['find_program'])
def func_find_program(self, node, args, kwargs):
if not args:
@@ -2271,20 +2341,10 @@ 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():
- use_native = kwargs.get('native', False)
- if not isinstance(use_native, bool):
- raise InvalidArguments('Argument to "native" must be a boolean.')
- if not use_native:
- progobj = self.program_from_cross_file(args)
- if progobj is None:
- progobj = self.program_from_system(args)
- if required and (progobj is None or not progobj.found()):
- raise InvalidArguments('Program(s) {!r} not found or not executable'.format(args))
- if progobj is None:
- return ExternalProgramHolder(dependencies.NonExistingExternalProgram())
- return progobj
+ use_native = kwargs.get('native', False)
+ if not isinstance(use_native, bool):
+ raise InvalidArguments('Argument to "native" must be a boolean.')
+ return self.find_program_impl(args, native=use_native, required=required, silent=False)
def func_find_library(self, node, args, kwargs):
raise InvalidCode('find_library() is removed, use meson.get_compiler(\'name\').find_library() instead.\n'
@@ -2691,7 +2751,7 @@ root and issuing %s.
exe = args[1]
if not isinstance(exe, (ExecutableHolder, JarHolder, ExternalProgramHolder)):
if isinstance(exe, mesonlib.File):
- exe = self.func_find_program(node, (args[1], ), {})
+ exe = self.func_find_program(node, args[1], {})
else:
raise InterpreterException('Second argument must be executable.')
par = kwargs.get('is_parallel', True)
diff --git a/mesonbuild/mesonmain.py b/mesonbuild/mesonmain.py
index 651224e..daf5907 100644
--- a/mesonbuild/mesonmain.py
+++ b/mesonbuild/mesonmain.py
@@ -210,7 +210,8 @@ class MesonApp:
# Post-conf scripts must be run after writing coredata or else introspection fails.
g.run_postconf_scripts()
except:
- os.unlink(cdf)
+ if 'cdf' in locals():
+ os.unlink(cdf)
raise
def run_script_command(args):
diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py
index bf513fd..55bbbd3 100644
--- a/mesonbuild/modules/__init__.py
+++ b/mesonbuild/modules/__init__.py
@@ -18,26 +18,15 @@ class permittedSnippetKwargs:
return f(s, interpreter, state, args, kwargs)
return wrapped
-_found_programs = {}
-
class ExtensionModule:
- def __init__(self):
+ def __init__(self, interpreter):
+ self.interpreter = interpreter
self.snippets = set() # List of methods that operate only on the interpreter.
def is_snippet(self, funcname):
return funcname in self.snippets
-def find_program(program_name, target_name):
- if program_name in _found_programs:
- return _found_programs[program_name]
- program = dependencies.ExternalProgram(program_name)
- if not program.found():
- m = "Target {!r} can't be generated as {!r} could not be found"
- raise MesonException(m.format(target_name, program_name))
- _found_programs[program_name] = program
- return program
-
def get_include_args(include_dirs, prefix='-I'):
'''
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py
index 4dc29c3..5455118 100644
--- a/mesonbuild/modules/gnome.py
+++ b/mesonbuild/modules/gnome.py
@@ -25,7 +25,7 @@ from .. import mesonlib
from .. import compilers
from .. import interpreter
from . import GResourceTarget, GResourceHeaderTarget, GirTarget, TypelibTarget, VapiTarget
-from . import find_program, get_include_args
+from . import get_include_args
from . import ExtensionModule
from . import ModuleReturnValue
from ..mesonlib import MesonException, OrderedSet, Popen_safe, extract_as_list
@@ -45,14 +45,14 @@ gdbuswarning_printed = False
gresource_warning_printed = False
_gir_has_extra_lib_arg = None
-def gir_has_extra_lib_arg():
+def gir_has_extra_lib_arg(intr_obj):
global _gir_has_extra_lib_arg
if _gir_has_extra_lib_arg is not None:
return _gir_has_extra_lib_arg
_gir_has_extra_lib_arg = False
try:
- g_ir_scanner = find_program('g-ir-scanner', '').get_command()
+ g_ir_scanner = intr_obj.find_program_impl('g-ir-scanner').get_command()
opts = Popen_safe(g_ir_scanner + ['--help'], stderr=subprocess.STDOUT)[1]
_gir_has_extra_lib_arg = '--extra-library' in opts
except (MesonException, FileNotFoundError, subprocess.CalledProcessError):
@@ -302,7 +302,7 @@ class GnomeModule(ExtensionModule):
link_command.append('-Wl,-rpath,' + libdir)
if depends:
depends.append(lib)
- if gir_has_extra_lib_arg() and use_gir_args:
+ if gir_has_extra_lib_arg(self.interpreter) and use_gir_args:
link_command.append('--extra-library=' + lib.name)
else:
link_command.append('-l' + lib.name)
@@ -369,7 +369,7 @@ class GnomeModule(ExtensionModule):
mlog.log('dependency {!r} not handled to build gir files'.format(dep))
continue
- if gir_has_extra_lib_arg() and use_gir_args:
+ if gir_has_extra_lib_arg(self.interpreter) and use_gir_args:
fixed_ldflags = OrderedSet()
for ldflag in ldflags:
if ldflag.startswith("-l"):
@@ -388,8 +388,8 @@ class GnomeModule(ExtensionModule):
raise MesonException('Gir takes one argument')
if kwargs.get('install_dir'):
raise MesonException('install_dir is not supported with generate_gir(), see "install_dir_gir" and "install_dir_typelib"')
- giscanner = find_program('g-ir-scanner', 'Gir')
- gicompiler = find_program('g-ir-compiler', 'Gir')
+ giscanner = self.interpreter.find_program_impl('g-ir-scanner')
+ gicompiler = self.interpreter.find_program_impl('g-ir-compiler')
girtarget = args[0]
while hasattr(girtarget, 'held_object'):
girtarget = girtarget.held_object
@@ -637,7 +637,7 @@ class GnomeModule(ExtensionModule):
srcdir = os.path.join(state.build_to_src, state.subdir)
outdir = state.subdir
- cmd = [find_program('glib-compile-schemas', 'gsettings-compile')]
+ cmd = [self.interpreter.find_program_impl('glib-compile-schemas')]
cmd += ['--targetdir', outdir, srcdir]
kwargs['command'] = cmd
kwargs['input'] = []
@@ -876,7 +876,7 @@ This will become a hard error in the future.''')
namebase = args[0]
xml_file = args[1]
target_name = namebase + '-gdbus'
- cmd = [find_program('gdbus-codegen', target_name)]
+ cmd = [self.interpreter.find_program_impl('gdbus-codegen')]
if 'interface_prefix' in kwargs:
cmd += ['--interface-prefix', kwargs.pop('interface_prefix')]
if 'namespace' in kwargs:
@@ -1013,7 +1013,7 @@ This will become a hard error in the future.''')
elif arg not in known_custom_target_kwargs:
raise MesonException(
'Mkenums does not take a %s keyword argument.' % (arg, ))
- cmd = [find_program('glib-mkenums', 'mkenums')] + cmd
+ cmd = [self.interpreter.find_program_impl(['glib-mkenums', 'mkenums'])] + cmd
custom_kwargs = {}
for arg in known_custom_target_kwargs:
if arg in kwargs:
@@ -1209,7 +1209,7 @@ G_END_DECLS'''
new_genmarshal = mesonlib.version_compare(self._get_native_glib_version(state), '>= 2.53.3')
- cmd = [find_program('glib-genmarshal', output + '_genmarshal')]
+ cmd = [self.interpreter.find_program_impl('glib-genmarshal')]
known_kwargs = ['internal', 'nostdinc', 'skip_source', 'stdinc',
'valist_marshallers', 'extra_args']
known_custom_target_kwargs = ['build_always', 'depends',
@@ -1355,9 +1355,9 @@ G_END_DECLS'''
pkg_cmd, vapi_depends, vapi_packages, vapi_includes = self._extract_vapi_packages(state, kwargs)
target_name = 'generate_vapi({})'.format(library)
if 'VAPIGEN' in os.environ:
- cmd = [find_program(os.environ['VAPIGEN'], target_name)]
+ cmd = [self.interpreter.find_program_impl(os.environ['VAPIGEN'])]
else:
- cmd = [find_program('vapigen', target_name)]
+ cmd = [self.interpreter.find_program_impl('vapigen')]
cmd += ['--quiet', '--library=' + library, '--directory=' + build_dir]
cmd += self._vapi_args_to_command('--vapidir=', 'vapi_dirs', kwargs)
cmd += self._vapi_args_to_command('--metadatadir=', 'metadata_dirs', kwargs)
@@ -1412,5 +1412,5 @@ G_END_DECLS'''
created_values.append(rv)
return ModuleReturnValue(rv, created_values)
-def initialize():
- return GnomeModule()
+def initialize(*args, **kwargs):
+ return GnomeModule(*args, **kwargs)
diff --git a/mesonbuild/modules/i18n.py b/mesonbuild/modules/i18n.py
index 6c02fbb..4281200 100644
--- a/mesonbuild/modules/i18n.py
+++ b/mesonbuild/modules/i18n.py
@@ -143,5 +143,5 @@ class I18nModule(ExtensionModule):
return ModuleReturnValue(None, targets)
-def initialize():
- return I18nModule()
+def initialize(*args, **kwargs):
+ return I18nModule(*args, **kwargs)
diff --git a/mesonbuild/modules/modtest.py b/mesonbuild/modules/modtest.py
index 758eeae..533989f 100644
--- a/mesonbuild/modules/modtest.py
+++ b/mesonbuild/modules/modtest.py
@@ -24,5 +24,5 @@ class TestModule(ExtensionModule):
rv = ModuleReturnValue(None, [])
return rv
-def initialize():
- return TestModule()
+def initialize(*args, **kwargs):
+ return TestModule(*args, **kwargs)
diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py
index 6f0e717..934e2f4 100644
--- a/mesonbuild/modules/pkgconfig.py
+++ b/mesonbuild/modules/pkgconfig.py
@@ -393,5 +393,5 @@ class PkgConfigModule(ExtensionModule):
res = build.Data(mesonlib.File(True, state.environment.get_scratch_dir(), pcfile), pkgroot)
return ModuleReturnValue(res, [res])
-def initialize():
- return PkgConfigModule()
+def initialize(*args, **kwargs):
+ return PkgConfigModule(*args, **kwargs)
diff --git a/mesonbuild/modules/python3.py b/mesonbuild/modules/python3.py
index d2bf1dc..79da29a 100644
--- a/mesonbuild/modules/python3.py
+++ b/mesonbuild/modules/python3.py
@@ -23,8 +23,8 @@ from ..build import known_shmod_kwargs
class Python3Module(ExtensionModule):
- def __init__(self):
- super().__init__()
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
self.snippets.add('extension_module')
@permittedSnippetKwargs(known_shmod_kwargs)
@@ -69,5 +69,5 @@ class Python3Module(ExtensionModule):
return ModuleReturnValue(path, [])
-def initialize():
- return Python3Module()
+def initialize(*args, **kwargs):
+ return Python3Module(*args, **kwargs)
diff --git a/mesonbuild/modules/qt4.py b/mesonbuild/modules/qt4.py
index 3011de7..29992d5 100644
--- a/mesonbuild/modules/qt4.py
+++ b/mesonbuild/modules/qt4.py
@@ -19,11 +19,11 @@ from . import ExtensionModule
class Qt4Module(ExtensionModule, QtBaseModule):
- def __init__(self):
+ def __init__(self, interpreter):
QtBaseModule.__init__(self, qt_version=4)
- ExtensionModule.__init__(self)
+ ExtensionModule.__init__(self, interpreter)
-def initialize():
+def initialize(*args, **kwargs):
mlog.warning('rcc dependencies will not work properly until this upstream issue is fixed:',
mlog.bold('https://bugreports.qt.io/browse/QTBUG-45460'))
- return Qt4Module()
+ return Qt4Module(*args, **kwargs)
diff --git a/mesonbuild/modules/qt5.py b/mesonbuild/modules/qt5.py
index 7b7acbb..19623ac 100644
--- a/mesonbuild/modules/qt5.py
+++ b/mesonbuild/modules/qt5.py
@@ -19,11 +19,11 @@ from . import ExtensionModule
class Qt5Module(ExtensionModule, QtBaseModule):
- def __init__(self):
+ def __init__(self, interpreter):
QtBaseModule.__init__(self, qt_version=5)
- ExtensionModule.__init__(self)
+ ExtensionModule.__init__(self, interpreter)
-def initialize():
+def initialize(*args, **kwargs):
mlog.warning('rcc dependencies will not work reliably until this upstream issue is fixed:',
mlog.bold('https://bugreports.qt.io/browse/QTBUG-45460'))
- return Qt5Module()
+ return Qt5Module(*args, **kwargs)
diff --git a/mesonbuild/modules/rpm.py b/mesonbuild/modules/rpm.py
index 5c9ed14..ba5bcaa 100644
--- a/mesonbuild/modules/rpm.py
+++ b/mesonbuild/modules/rpm.py
@@ -167,5 +167,5 @@ class RPMModule(ExtensionModule):
mlog.log('RPM spec template written to %s.spec.\n' % proj)
return ModuleReturnValue(None, [])
-def initialize():
- return RPMModule()
+def initialize(*args, **kwargs):
+ return RPMModule(*args, **kwargs)
diff --git a/mesonbuild/modules/unstable_icestorm.py b/mesonbuild/modules/unstable_icestorm.py
index 1f548b6..55c647f 100644
--- a/mesonbuild/modules/unstable_icestorm.py
+++ b/mesonbuild/modules/unstable_icestorm.py
@@ -18,17 +18,17 @@ from . import ExtensionModule
class IceStormModule(ExtensionModule):
- def __init__(self):
- super().__init__()
+ def __init__(self, interpreter):
+ super().__init__(interpreter)
self.snippets.add('project')
self.yosys_bin = None
def detect_binaries(self, interpreter):
- self.yosys_bin = interpreter.func_find_program(None, ['yosys'], {})
- self.arachne_bin = interpreter.func_find_program(None, ['arachne-pnr'], {})
- self.icepack_bin = interpreter.func_find_program(None, ['icepack'], {})
- self.iceprog_bin = interpreter.func_find_program(None, ['iceprog'], {})
- self.icetime_bin = interpreter.func_find_program(None, ['icetime'], {})
+ self.yosys_bin = interpreter.find_program_impl(['yosys'])
+ self.arachne_bin = interpreter.find_program_impl(['arachne-pnr'])
+ self.icepack_bin = interpreter.find_program_impl(['icepack'])
+ self.iceprog_bin = interpreter.find_program_impl(['iceprog'])
+ self.icetime_bin = interpreter.find_program_impl(['icetime'])
def project(self, interpreter, state, args, kwargs):
if not self.yosys_bin:
@@ -80,5 +80,5 @@ class IceStormModule(ExtensionModule):
interpreter.func_run_target(None, [time_name], {
'command': [self.icetime_bin, bin_target]})
-def initialize():
- return IceStormModule()
+def initialize(*args, **kwargs):
+ return IceStormModule(*args, **kwargs)
diff --git a/mesonbuild/modules/unstable_simd.py b/mesonbuild/modules/unstable_simd.py
index b774cff..c41e96c 100644
--- a/mesonbuild/modules/unstable_simd.py
+++ b/mesonbuild/modules/unstable_simd.py
@@ -18,8 +18,8 @@ from . import ExtensionModule
class SimdModule(ExtensionModule):
- def __init__(self):
- super().__init__()
+ def __init__(self, interpreter):
+ super().__init__(interpreter)
self.snippets.add('check')
# FIXME add Altivec and AVX512.
self.isets = ('mmx',
@@ -79,5 +79,5 @@ class SimdModule(ExtensionModule):
result.append(interpreter.func_static_lib(None, [libname], lib_kwargs))
return [result, cdata]
-def initialize():
- return SimdModule()
+def initialize(*args, **kwargs):
+ return SimdModule(*args, **kwargs)
diff --git a/mesonbuild/modules/windows.py b/mesonbuild/modules/windows.py
index dc6e9d8..62cb9d1 100644
--- a/mesonbuild/modules/windows.py
+++ b/mesonbuild/modules/windows.py
@@ -104,5 +104,5 @@ class WindowsModule(ExtensionModule):
return ModuleReturnValue(res_targets, [res_targets])
-def initialize():
- return WindowsModule()
+def initialize(*args, **kwargs):
+ return WindowsModule(*args, **kwargs)
diff --git a/test cases/common/190 find override/meson.build b/test cases/common/190 find override/meson.build
new file mode 100644
index 0000000..3b8af80
--- /dev/null
+++ b/test cases/common/190 find override/meson.build
@@ -0,0 +1,12 @@
+project('find program override', 'c')
+
+gencodegen = find_program('gencodegen', required : false)
+
+assert(not gencodegen.found(), 'gencodegen is an internal program, should not be found')
+
+# Test the check-if-found-else-override workflow
+if not gencodegen.found()
+ subdir('subdir')
+endif
+
+subdir('otherdir')
diff --git a/test cases/common/190 find override/otherdir/main.c b/test cases/common/190 find override/otherdir/main.c
new file mode 100644
index 0000000..2cef67c
--- /dev/null
+++ b/test cases/common/190 find override/otherdir/main.c
@@ -0,0 +1,5 @@
+int be_seeing_you();
+
+int main(int argc, char **argv) {
+ return be_seeing_you() == 6 ? 0 : 1;
+}
diff --git a/test cases/common/190 find override/otherdir/main2.c b/test cases/common/190 find override/otherdir/main2.c
new file mode 100644
index 0000000..6d71688
--- /dev/null
+++ b/test cases/common/190 find override/otherdir/main2.c
@@ -0,0 +1,5 @@
+int number_returner();
+
+int main(int argc, char **argv) {
+ return number_returner() == 100 ? 0 : 1;
+}
diff --git a/test cases/common/190 find override/otherdir/meson.build b/test cases/common/190 find override/otherdir/meson.build
new file mode 100644
index 0000000..dc41f5b
--- /dev/null
+++ b/test cases/common/190 find override/otherdir/meson.build
@@ -0,0 +1,26 @@
+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)
+
+# The same again, but this time with a program that was genererated
+# with configure_file.
+
+gen = find_program('gencodegen')
+
+src = custom_target('hundred',
+ input : 'source2.desc',
+ output : 'file2.c',
+ command : [gen, '@INPUT@', '@OUTPUT@']
+ )
+
+e = executable('hundred', 'main2.c', src)
+
+test('hundred', e)
diff --git a/test cases/common/190 find override/otherdir/source.desc b/test cases/common/190 find override/otherdir/source.desc
new file mode 100644
index 0000000..8b19c9c
--- /dev/null
+++ b/test cases/common/190 find override/otherdir/source.desc
@@ -0,0 +1 @@
+be_seeing_you
diff --git a/test cases/common/190 find override/otherdir/source2.desc b/test cases/common/190 find override/otherdir/source2.desc
new file mode 100644
index 0000000..965f868
--- /dev/null
+++ b/test cases/common/190 find override/otherdir/source2.desc
@@ -0,0 +1 @@
+number_returner
diff --git a/test cases/common/190 find override/subdir/converter.py b/test cases/common/190 find override/subdir/converter.py
new file mode 100755
index 0000000..ee2ff85
--- /dev/null
+++ b/test cases/common/190 find override/subdir/converter.py
@@ -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)
diff --git a/test cases/common/190 find override/subdir/gencodegen.py.in b/test cases/common/190 find override/subdir/gencodegen.py.in
new file mode 100755
index 0000000..57d9c40
--- /dev/null
+++ b/test cases/common/190 find override/subdir/gencodegen.py.in
@@ -0,0 +1,15 @@
+#!/usr/bin/env python3
+
+import sys
+import pathlib
+
+[ifilename, ofilename] = sys.argv[1:3]
+
+ftempl = '''int %s() {
+ return @NUMBER@;
+}
+'''
+
+d = pathlib.Path(ifilename).read_text().split('\n')[0].strip()
+
+pathlib.Path(ofilename).write_text(ftempl % d)
diff --git a/test cases/common/190 find override/subdir/meson.build b/test cases/common/190 find override/subdir/meson.build
new file mode 100644
index 0000000..e5de34d
--- /dev/null
+++ b/test cases/common/190 find override/subdir/meson.build
@@ -0,0 +1,14 @@
+x = find_program('converter.py')
+
+meson.override_find_program('codegen', x)
+
+# Override a command with a generated script
+
+cdata = configuration_data()
+
+cdata.set('NUMBER', 100)
+numprog = configure_file(input : 'gencodegen.py.in',
+ output : 'gencodegen.py',
+ configuration : cdata)
+
+meson.override_find_program('gencodegen', numprog)
diff --git a/test cases/failing/72 override used/meson.build b/test cases/failing/72 override used/meson.build
new file mode 100644
index 0000000..61885bb
--- /dev/null
+++ b/test cases/failing/72 override used/meson.build
@@ -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)
diff --git a/test cases/failing/72 override used/other.py b/test cases/failing/72 override used/other.py
new file mode 100755
index 0000000..f62ba96
--- /dev/null
+++ b/test cases/failing/72 override used/other.py
@@ -0,0 +1,3 @@
+#!/usr/bin/env python3
+
+print('Doing something else.')
diff --git a/test cases/failing/72 override used/something.py b/test cases/failing/72 override used/something.py
new file mode 100755
index 0000000..64c9454
--- /dev/null
+++ b/test cases/failing/72 override used/something.py
@@ -0,0 +1,3 @@
+#!/usr/bin/env python3
+
+print('Doing something.')
diff --git a/test cases/failing/73 dual override/meson.build b/test cases/failing/73 dual override/meson.build
new file mode 100644
index 0000000..e5f86ba
--- /dev/null
+++ b/test cases/failing/73 dual override/meson.build
@@ -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)
diff --git a/test cases/failing/73 dual override/overrides.py b/test cases/failing/73 dual override/overrides.py
new file mode 100644
index 0000000..49e9b7a
--- /dev/null
+++ b/test cases/failing/73 dual override/overrides.py
@@ -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.')