diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2017-08-19 19:47:51 +0300 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2017-09-04 22:47:12 +0300 |
commit | 72a6683c6f564afa8f8d7e96b0238961aa867f00 (patch) | |
tree | b6c7828fcaaf52472626bb55efb1cad4ba7bad40 | |
parent | e94a9c8fcfa4776e09c9cabfe01de705ce34b735 (diff) | |
download | meson-72a6683c6f564afa8f8d7e96b0238961aa867f00.zip meson-72a6683c6f564afa8f8d7e96b0238961aa867f00.tar.gz meson-72a6683c6f564afa8f8d7e96b0238961aa867f00.tar.bz2 |
Permit overriding find_program from the cross file.
-rw-r--r-- | docs/markdown/Reference-manual.md | 6 | ||||
-rw-r--r-- | docs/markdown/snippets/cross_find.md | 15 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 46 | ||||
-rwxr-xr-x | run_unittests.py | 22 | ||||
-rw-r--r-- | test cases/unit/12 cross prog/meson.build | 12 | ||||
-rwxr-xr-x | test cases/unit/12 cross prog/some_cross_tool.py | 5 | ||||
-rwxr-xr-x | test cases/unit/12 cross prog/sometool.py | 5 |
7 files changed, 102 insertions, 9 deletions
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md index 3f25e80..34b473d 100644 --- a/docs/markdown/Reference-manual.md +++ b/docs/markdown/Reference-manual.md @@ -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 diff --git a/docs/markdown/snippets/cross_find.md b/docs/markdown/snippets/cross_find.md new file mode 100644 index 0000000..b16d64d --- /dev/null +++ b/docs/markdown/snippets/cross_find.md @@ -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) diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index 72df3c7..d71ce1f 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -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): diff --git a/run_unittests.py b/run_unittests.py index 1fb1b4b..c065790 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -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 diff --git a/test cases/unit/12 cross prog/meson.build b/test cases/unit/12 cross prog/meson.build new file mode 100644 index 0000000..e628701 --- /dev/null +++ b/test cases/unit/12 cross prog/meson.build @@ -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) diff --git a/test cases/unit/12 cross prog/some_cross_tool.py b/test cases/unit/12 cross prog/some_cross_tool.py new file mode 100755 index 0000000..1edd10f --- /dev/null +++ b/test cases/unit/12 cross prog/some_cross_tool.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +from __future__ import print_function + +print('cross') diff --git a/test cases/unit/12 cross prog/sometool.py b/test cases/unit/12 cross prog/sometool.py new file mode 100755 index 0000000..4c0e3b1 --- /dev/null +++ b/test cases/unit/12 cross prog/sometool.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +from __future__ import print_function + +print('native') |