Permit overriding find_program from the cross file.
This commit is contained in:
parent
e94a9c8fcf
commit
72a6683c6f
|
@ -466,6 +466,12 @@ Keyword arguments are the following:
|
|||
then use the `.found()` method on the returned object to check
|
||||
whether it was found or not.
|
||||
|
||||
- `native` defines how this executable should be searched. By default
|
||||
it is set to `false`, which causes Meson to first look for the
|
||||
executable in the cross file (when cross building) and if it is not
|
||||
defined there, then from the system. If set to `true`, the cross
|
||||
file is ignored and the program is only searched from the system.
|
||||
|
||||
Meson will also autodetect scripts with a shebang line and run them
|
||||
with the executable/interpreter specified in it both on Windows
|
||||
(because the command invocator will reject the command otherwise) and
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
# Can override executables in the cross file
|
||||
|
||||
The cross file can now be used for overriding the result of
|
||||
`find_program`. As an example if you want to find the `objdump`
|
||||
command and have the following definition in your cross file:
|
||||
|
||||
[binaries]
|
||||
...
|
||||
objdump = '/usr/bin/arm-linux-gnueabihf-objdump-6'
|
||||
|
||||
Then issuing the command `find_program('objdump')` will return the
|
||||
version specified in the cross file. If you need the build machine's
|
||||
objdump, you can specify the `native` keyword like this:
|
||||
|
||||
native_objdump = find_program('objdump', native : true)
|
|
@ -1317,7 +1317,7 @@ permitted_kwargs = {'add_global_arguments': {'language'},
|
|||
'custom_target': {'input', 'output', 'command', 'install', 'install_dir', 'build_always', 'capture', 'depends', 'depend_files', 'depfile', 'build_by_default'},
|
||||
'declare_dependency': {'include_directories', 'link_with', 'sources', 'dependencies', 'compile_args', 'link_args', 'version'},
|
||||
'executable': exe_kwargs,
|
||||
'find_program': {'required'},
|
||||
'find_program': {'required', 'native'},
|
||||
'generator': {'arguments', 'output', 'depfile'},
|
||||
'include_directories': {'is_system'},
|
||||
'install_data': {'install_dir', 'install_mode', 'sources'},
|
||||
|
@ -1963,13 +1963,22 @@ class Interpreter(InterpreterBase):
|
|||
break
|
||||
self.coredata.base_options[optname] = oobj
|
||||
|
||||
@permittedKwargs(permitted_kwargs['find_program'])
|
||||
def func_find_program(self, node, args, kwargs):
|
||||
if not args:
|
||||
raise InterpreterException('No program name specified.')
|
||||
required = kwargs.get('required', True)
|
||||
if not isinstance(required, bool):
|
||||
raise InvalidArguments('"required" argument must be a boolean.')
|
||||
def program_from_cross_file(self, prognames):
|
||||
bins = self.environment.cross_info.config['binaries']
|
||||
for p in prognames:
|
||||
if hasattr(p, 'held_object'):
|
||||
p = p.held_object
|
||||
if isinstance(p, mesonlib.File):
|
||||
continue # Always points to a local (i.e. self generated) file.
|
||||
if not isinstance(p, str):
|
||||
raise InterpreterException('Executable name must be a string.')
|
||||
if p in bins:
|
||||
exename = bins[p]
|
||||
extprog = dependencies.ExternalProgram(exename)
|
||||
progobj = ExternalProgramHolder(extprog)
|
||||
return progobj
|
||||
|
||||
def program_from_system(self, args):
|
||||
# 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.
|
||||
|
@ -1992,8 +2001,27 @@ class Interpreter(InterpreterBase):
|
|||
progobj = ExternalProgramHolder(extprog)
|
||||
if progobj.found():
|
||||
return progobj
|
||||
if required and not progobj.found():
|
||||
|
||||
@permittedKwargs(permitted_kwargs['find_program'])
|
||||
def func_find_program(self, node, args, kwargs):
|
||||
if not args:
|
||||
raise InterpreterException('No program name specified.')
|
||||
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" not found or not executable' % exename)
|
||||
if progobj is None:
|
||||
return ExternalProgramHolder(dependencies.ExternalProgram('nonexistingprogram'))
|
||||
return progobj
|
||||
|
||||
def func_find_library(self, node, args, kwargs):
|
||||
|
|
|
@ -1923,6 +1923,28 @@ class LinuxlikeTests(BasePlatformTests):
|
|||
self.run_tests()
|
||||
self.run_target('coverage-html')
|
||||
|
||||
def test_cross_find_program(self):
|
||||
testdir = os.path.join(self.unit_test_dir, '12 cross prog')
|
||||
crossfile = tempfile.NamedTemporaryFile(mode='w')
|
||||
print(os.path.join(testdir, 'some_cross_tool.py'))
|
||||
crossfile.write('''[binaries]
|
||||
c = '/usr/bin/cc'
|
||||
ar = '/usr/bin/ar'
|
||||
strip = '/usr/bin/ar'
|
||||
sometool.py = '%s'
|
||||
|
||||
[properties]
|
||||
|
||||
[host_machine]
|
||||
system = 'linux'
|
||||
cpu_family = 'arm'
|
||||
cpu = 'armv7' # Not sure if correct.
|
||||
endian = 'little'
|
||||
''' % os.path.join(testdir, 'some_cross_tool.py'))
|
||||
crossfile.flush()
|
||||
self.init(testdir, ['--cross-file='+crossfile.name])
|
||||
|
||||
|
||||
class LinuxArmCrossCompileTests(BasePlatformTests):
|
||||
'''
|
||||
Tests that verify cross-compilation to Linux/ARM
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
project('cross find program', 'c')
|
||||
|
||||
native_exe = find_program('sometool.py', native : true)
|
||||
cross_exe = find_program('sometool.py')
|
||||
|
||||
native_out = run_command(native_exe).stdout().strip()
|
||||
cross_out = run_command(cross_exe).stdout().strip()
|
||||
|
||||
assert(native_out == 'native',
|
||||
'Native output incorrect:' + native_out)
|
||||
assert(cross_out == 'cross',
|
||||
'Cross output incorrect:' + cross_out)
|
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
print('cross')
|
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
print('native')
|
Loading…
Reference in New Issue