aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2018-03-11 14:58:23 +0200
committerNirbheek Chauhan <nirbheek@centricular.com>2018-04-15 13:32:38 +0530
commitde65adb8b100731ff31eee92da44b4cc10ac5aa3 (patch)
tree023b6dec62c5b45b8ce127fa03e53a19d133b9e1
parent3f7c6cf3d6a204e9665faad3c05bb5049f08ac74 (diff)
downloadmeson-de65adb8b100731ff31eee92da44b4cc10ac5aa3.zip
meson-de65adb8b100731ff31eee92da44b4cc10ac5aa3.tar.gz
meson-de65adb8b100731ff31eee92da44b4cc10ac5aa3.tar.bz2
Made it possible to override find_program to return a different program.
Closes https://github.com/mesonbuild/meson/issues/2005
-rw-r--r--mesonbuild/build.py2
-rw-r--r--mesonbuild/interpreter.py45
-rw-r--r--test cases/common/182 find override/meson.build4
-rw-r--r--test cases/common/182 find override/otherdir/main.c5
-rw-r--r--test cases/common/182 find override/otherdir/meson.build11
-rw-r--r--test cases/common/182 find override/otherdir/source.desc1
-rwxr-xr-xtest cases/common/182 find override/subdir/converter.py15
-rw-r--r--test cases/common/182 find override/subdir/meson.build3
-rw-r--r--test cases/failing/70 override used/meson.build5
-rwxr-xr-xtest cases/failing/70 override used/other.py3
-rwxr-xr-xtest cases/failing/70 override used/something.py3
-rw-r--r--test cases/failing/71 dual override/meson.build5
-rw-r--r--test cases/failing/71 dual override/overrides.py4
13 files changed, 104 insertions, 2 deletions
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.')
diff --git a/test cases/common/182 find override/meson.build b/test cases/common/182 find override/meson.build
new file mode 100644
index 0000000..ebf3a05
--- /dev/null
+++ b/test cases/common/182 find override/meson.build
@@ -0,0 +1,4 @@
+project('find program override', 'c')
+
+subdir('subdir')
+subdir('otherdir')
diff --git a/test cases/common/182 find override/otherdir/main.c b/test cases/common/182 find override/otherdir/main.c
new file mode 100644
index 0000000..2cef67c
--- /dev/null
+++ b/test cases/common/182 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/182 find override/otherdir/meson.build b/test cases/common/182 find override/otherdir/meson.build
new file mode 100644
index 0000000..84e7e84
--- /dev/null
+++ b/test cases/common/182 find override/otherdir/meson.build
@@ -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)
diff --git a/test cases/common/182 find override/otherdir/source.desc b/test cases/common/182 find override/otherdir/source.desc
new file mode 100644
index 0000000..8b19c9c
--- /dev/null
+++ b/test cases/common/182 find override/otherdir/source.desc
@@ -0,0 +1 @@
+be_seeing_you
diff --git a/test cases/common/182 find override/subdir/converter.py b/test cases/common/182 find override/subdir/converter.py
new file mode 100755
index 0000000..55b2a70
--- /dev/null
+++ b/test cases/common/182 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) \ No newline at end of file
diff --git a/test cases/common/182 find override/subdir/meson.build b/test cases/common/182 find override/subdir/meson.build
new file mode 100644
index 0000000..0d1f9d0
--- /dev/null
+++ b/test cases/common/182 find override/subdir/meson.build
@@ -0,0 +1,3 @@
+x = find_program('converter.py')
+
+meson.override_find_program('codegen', x)
diff --git a/test cases/failing/70 override used/meson.build b/test cases/failing/70 override used/meson.build
new file mode 100644
index 0000000..61885bb
--- /dev/null
+++ b/test cases/failing/70 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/70 override used/other.py b/test cases/failing/70 override used/other.py
new file mode 100755
index 0000000..f62ba96
--- /dev/null
+++ b/test cases/failing/70 override used/other.py
@@ -0,0 +1,3 @@
+#!/usr/bin/env python3
+
+print('Doing something else.')
diff --git a/test cases/failing/70 override used/something.py b/test cases/failing/70 override used/something.py
new file mode 100755
index 0000000..64c9454
--- /dev/null
+++ b/test cases/failing/70 override used/something.py
@@ -0,0 +1,3 @@
+#!/usr/bin/env python3
+
+print('Doing something.')
diff --git a/test cases/failing/71 dual override/meson.build b/test cases/failing/71 dual override/meson.build
new file mode 100644
index 0000000..e5f86ba
--- /dev/null
+++ b/test cases/failing/71 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/71 dual override/overrides.py b/test cases/failing/71 dual override/overrides.py
new file mode 100644
index 0000000..49e9b7a
--- /dev/null
+++ b/test cases/failing/71 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.')