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
|
then use the `.found()` method on the returned object to check
|
||||||
whether it was found or not.
|
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
|
Meson will also autodetect scripts with a shebang line and run them
|
||||||
with the executable/interpreter specified in it both on Windows
|
with the executable/interpreter specified in it both on Windows
|
||||||
(because the command invocator will reject the command otherwise) and
|
(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'},
|
'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'},
|
'declare_dependency': {'include_directories', 'link_with', 'sources', 'dependencies', 'compile_args', 'link_args', 'version'},
|
||||||
'executable': exe_kwargs,
|
'executable': exe_kwargs,
|
||||||
'find_program': {'required'},
|
'find_program': {'required', 'native'},
|
||||||
'generator': {'arguments', 'output', 'depfile'},
|
'generator': {'arguments', 'output', 'depfile'},
|
||||||
'include_directories': {'is_system'},
|
'include_directories': {'is_system'},
|
||||||
'install_data': {'install_dir', 'install_mode', 'sources'},
|
'install_data': {'install_dir', 'install_mode', 'sources'},
|
||||||
|
@ -1963,13 +1963,22 @@ class Interpreter(InterpreterBase):
|
||||||
break
|
break
|
||||||
self.coredata.base_options[optname] = oobj
|
self.coredata.base_options[optname] = oobj
|
||||||
|
|
||||||
@permittedKwargs(permitted_kwargs['find_program'])
|
def program_from_cross_file(self, prognames):
|
||||||
def func_find_program(self, node, args, kwargs):
|
bins = self.environment.cross_info.config['binaries']
|
||||||
if not args:
|
for p in prognames:
|
||||||
raise InterpreterException('No program name specified.')
|
if hasattr(p, 'held_object'):
|
||||||
required = kwargs.get('required', True)
|
p = p.held_object
|
||||||
if not isinstance(required, bool):
|
if isinstance(p, mesonlib.File):
|
||||||
raise InvalidArguments('"required" argument must be a boolean.')
|
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.
|
# Search for scripts relative to current subdir.
|
||||||
# Do not cache found programs because find_program('foobar')
|
# Do not cache found programs because find_program('foobar')
|
||||||
# might give different results when run from different source dirs.
|
# might give different results when run from different source dirs.
|
||||||
|
@ -1992,8 +2001,27 @@ class Interpreter(InterpreterBase):
|
||||||
progobj = ExternalProgramHolder(extprog)
|
progobj = ExternalProgramHolder(extprog)
|
||||||
if progobj.found():
|
if progobj.found():
|
||||||
return progobj
|
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)
|
raise InvalidArguments('Program "%s" not found or not executable' % exename)
|
||||||
|
if progobj is None:
|
||||||
|
return ExternalProgramHolder(dependencies.ExternalProgram('nonexistingprogram'))
|
||||||
return progobj
|
return progobj
|
||||||
|
|
||||||
def func_find_library(self, node, args, kwargs):
|
def func_find_library(self, node, args, kwargs):
|
||||||
|
|
|
@ -1923,6 +1923,28 @@ class LinuxlikeTests(BasePlatformTests):
|
||||||
self.run_tests()
|
self.run_tests()
|
||||||
self.run_target('coverage-html')
|
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):
|
class LinuxArmCrossCompileTests(BasePlatformTests):
|
||||||
'''
|
'''
|
||||||
Tests that verify cross-compilation to Linux/ARM
|
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