Allow override_find_program to use an executable.
With this it is now possible to do foobar = executable('foobar', ...) meson.override_find_program('foobar', foobar) Which is convenient for a project like protobuf which produces both a dependency and a tool. If protobuf is updated to use override_find_program, it can be used as protobuf_dep = dependency('protobuf', version : '>=3.3.1', fallback : ['protobuf', 'protobuf_dep']) protoc_prog = find_program('protoc')
This commit is contained in:
parent
862019e6de
commit
07d2d88fa9
|
@ -1529,7 +1529,9 @@ the following methods.
|
|||
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`.
|
||||
`find_program`, `configure_file` or `executable`.
|
||||
|
||||
If `program` is an `executable`, it cannot be used during configure.
|
||||
|
||||
- `project_version()` returns the version string specified in
|
||||
`project` function call.
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
## More flexible `override_find_program()`.
|
||||
|
||||
It is now possible to pass an `executable` to
|
||||
`override_find_program()` if the overridden program is not used during
|
||||
configure.
|
||||
|
||||
This is particularly useful for fallback dependencies like Protobuf
|
||||
that also provide a tool like protoc.
|
|
@ -1314,6 +1314,10 @@ class Executable(BuildTarget):
|
|||
# Only linkwithable if using export_dynamic
|
||||
self.is_linkwithable = self.export_dynamic
|
||||
|
||||
def description(self):
|
||||
'''Human friendly description of the executable'''
|
||||
return self.name
|
||||
|
||||
def type_suffix(self):
|
||||
return "@exe"
|
||||
|
||||
|
|
|
@ -1057,6 +1057,10 @@ class ExternalProgram:
|
|||
r = '<{} {!r} -> {!r}>'
|
||||
return r.format(self.__class__.__name__, self.name, self.command)
|
||||
|
||||
def description(self):
|
||||
'''Human friendly description of the command'''
|
||||
return ' '.join(self.command)
|
||||
|
||||
@staticmethod
|
||||
def from_cross_info(cross_info, name):
|
||||
if name not in cross_info.config['binaries']:
|
||||
|
|
|
@ -480,7 +480,7 @@ class ExternalProgramHolder(InterpreterObject, ObjectHolder):
|
|||
return self.held_object.get_path()
|
||||
|
||||
def found(self):
|
||||
return self.held_object.found()
|
||||
return isinstance(self.held_object, build.Executable) or self.held_object.found()
|
||||
|
||||
def get_command(self):
|
||||
return self.held_object.get_command()
|
||||
|
@ -1780,9 +1780,8 @@ class MesonMain(InterpreterObject):
|
|||
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.')
|
||||
if not isinstance(exe, (dependencies.ExternalProgram, build.Executable)):
|
||||
raise InterpreterException('Second argument must be an external program or executable.')
|
||||
self.interpreter.add_find_program_override(name, exe)
|
||||
|
||||
@noPosargs
|
||||
|
@ -2184,6 +2183,11 @@ external dependencies (including libraries) must go to "dependencies".''')
|
|||
'or configure_file(), or a compiler object; not {!r}'
|
||||
if isinstance(cmd, ExternalProgramHolder):
|
||||
cmd = cmd.held_object
|
||||
if isinstance(cmd, build.Executable):
|
||||
progname = node.args.arguments[0].value
|
||||
msg = 'Program {!r} was overridden with the compiled executable {!r}'\
|
||||
' and therefore cannot be used during configuration'
|
||||
raise InterpreterException(msg.format(progname, cmd.description()))
|
||||
elif isinstance(cmd, CompilerHolder):
|
||||
cmd = cmd.compiler.get_exelist()[0]
|
||||
prog = ExternalProgram(cmd, silent=True)
|
||||
|
@ -2758,7 +2762,7 @@ external dependencies (including libraries) must go to "dependencies".''')
|
|||
exe = self.build.find_overrides[name]
|
||||
if not silent:
|
||||
mlog.log('Program', mlog.bold(name), 'found:', mlog.green('YES'),
|
||||
'(overridden: %s)' % ' '.join(exe.command))
|
||||
'(overridden: %s)' % exe.description())
|
||||
return ExternalProgramHolder(exe)
|
||||
return None
|
||||
|
||||
|
|
|
@ -3881,6 +3881,17 @@ endian = 'little'
|
|||
return
|
||||
raise RuntimeError('Could not find the rpath')
|
||||
|
||||
def test_override_with_exe_dep(self):
|
||||
'''
|
||||
Test that we produce the correct dependencies when a program is overridden with an executable.
|
||||
'''
|
||||
testdir = os.path.join(self.common_test_dir, '206 override with exe')
|
||||
self.init(testdir)
|
||||
with open(os.path.join(self.builddir, 'build.ninja')) as bfile:
|
||||
for line in bfile:
|
||||
if 'main1.c:' in line or 'main2.c:' in line:
|
||||
self.assertIn('| subprojects/sub/foobar', line)
|
||||
|
||||
@skipIfNoPkgconfig
|
||||
def test_usage_external_library(self):
|
||||
'''
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
project('myexe', 'c')
|
||||
sub = subproject('sub')
|
||||
prog = find_program('foobar')
|
||||
custom1 = custom_target('custom1',
|
||||
build_by_default : true,
|
||||
input : [],
|
||||
output : 'main1.c',
|
||||
command : [prog, '@OUTPUT@'])
|
||||
gen = generator(prog,
|
||||
output : '@BASENAME@.c',
|
||||
arguments : ['@OUTPUT@'])
|
||||
custom2 = gen.process('main2.input')
|
||||
|
||||
executable('e1', custom1)
|
||||
executable('e2', custom2)
|
|
@ -0,0 +1,12 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
FILE *f = fopen(argv[1], "w");
|
||||
const char msg[] = "int main(void) {return 0;}\n";
|
||||
size_t w = fwrite(msg, 1, sizeof(msg) - 1, f);
|
||||
assert(w == sizeof(msg) - 1);
|
||||
int r = fclose(f);
|
||||
assert(r == 0);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
project('sub', 'c')
|
||||
foobar = executable('foobar', 'foobar.c', native : true)
|
||||
meson.override_find_program('foobar', foobar)
|
|
@ -0,0 +1,3 @@
|
|||
int main(void) {
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
project('myexe', 'c')
|
||||
|
||||
foo = executable('foo', 'foo.c')
|
||||
meson.override_find_program('bar', foo)
|
||||
bar = find_program('bar')
|
||||
run_command(bar)
|
Loading…
Reference in New Issue