From 66e5c4b7dc7bfd052b2cd9da112d5f24b868175d Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Tue, 11 Jul 2023 10:53:51 -0700 Subject: [PATCH] interpreter: extend add_*_arguments to support `native : 'both'` This allows for arguments that are needed for both machines to be passed to both at the same time. This can be helpful if when cross compiling, when something like a `-D` option needs to be the same for the host and the build targets. --- docs/markdown/snippets/add_native_both.md | 4 ++ docs/yaml/functions/add_global_arguments.yaml | 14 +++--- mesonbuild/interpreter/interpreter.py | 39 ++++++++++++---- mesonbuild/interpreter/kwargs.py | 6 +++ .../meson.build | 46 +++++++++++++++---- .../meson.options | 1 + .../test.json | 11 +++++ .../2 languages missing native/meson.build | 3 -- .../2 languages missing native/test.json | 7 --- unittests/allplatformstests.py | 9 ++++ 10 files changed, 106 insertions(+), 34 deletions(-) create mode 100644 test cases/common/115 subproject project arguments/meson.options create mode 100644 test cases/common/115 subproject project arguments/test.json delete mode 100644 test cases/warning/2 languages missing native/meson.build delete mode 100644 test cases/warning/2 languages missing native/test.json diff --git a/docs/markdown/snippets/add_native_both.md b/docs/markdown/snippets/add_native_both.md index 4b87a871cc28..b15d439219b1 100644 --- a/docs/markdown/snippets/add_native_both.md +++ b/docs/markdown/snippets/add_native_both.md @@ -4,3 +4,7 @@ This has been added to the `add_language()` function. This allows explicitly setting the default behavior of getting a language for both the host and build machines. The default has been changed to `'both'`, and Meson will no longer warn about getting no value for `native` in this function as a result. + +This as also been added to `add_global_args()`, `add_global_link_args()`, +`add_project_args()`, and `add_project_link_args()`. The default for these +remains the same, but `'both'` is now allowed diff --git a/docs/yaml/functions/add_global_arguments.yaml b/docs/yaml/functions/add_global_arguments.yaml index 3b26d10c8d07..3d739bab2483 100644 --- a/docs/yaml/functions/add_global_arguments.yaml +++ b/docs/yaml/functions/add_global_arguments.yaml @@ -26,13 +26,13 @@ kwargs: it in per-target flags. native: - type: bool + type: bool | str default: false since: 0.48.0 description: | - A boolean specifying whether the arguments should be - applied to the native or cross compilation. If `true` the arguments - will only be used for native compilations. If `false` the arguments - will only be used in cross compilations. If omitted, the flags are - added to native compilations if compiling natively and cross - compilations (only) when cross compiling. + A boolean or `'both'` specifying whether the arguments should be + applied to targets for the host machine, the build machine, or both. If + `true` the arguments will only be used for build targets. If `false` + the arguments will only be used for host targets. *(since 1.4.0)* If + `'both'` then arguments will be used for both host and build targets. + When host == build, all options are equivalent. diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index cfafdc00bf8a..0851b30445f1 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -1,5 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright 2012-2021 The Meson development team +# Copyright © 2023 Intel Corporation from __future__ import annotations @@ -2858,29 +2859,49 @@ def func_add_test_setup(self, node: mparser.BaseNode, args: T.Tuple[str], kwargs kwargs['exclude_suites']) @typed_pos_args('add_global_arguments', varargs=str) - @typed_kwargs('add_global_arguments', NATIVE_KW, LANGUAGE_KW) + @typed_kwargs('add_global_arguments', NATIVE_BOTH_KW, LANGUAGE_KW) def func_add_global_arguments(self, node: mparser.FunctionNode, args: T.Tuple[T.List[str]], kwargs: 'kwtypes.FuncAddProjectArgs') -> None: - self._add_global_arguments(node, self.build.global_args[kwargs['native']], args[0], kwargs) + native = kwargs['native'] + if native is InterpreterMachineChoice.BOTH: + self._add_global_arguments(node, self.build.global_args[MachineChoice.HOST], args[0], kwargs) + self._add_global_arguments(node, self.build.global_args[MachineChoice.BUILD], args[0], kwargs) + else: + self._add_global_arguments(node, self.build.global_args[native.as_machinechoice()], args[0], kwargs) @typed_pos_args('add_global_link_arguments', varargs=str) - @typed_kwargs('add_global_arguments', NATIVE_KW, LANGUAGE_KW) + @typed_kwargs('add_global_arguments', NATIVE_BOTH_KW, LANGUAGE_KW) def func_add_global_link_arguments(self, node: mparser.FunctionNode, args: T.Tuple[T.List[str]], kwargs: 'kwtypes.FuncAddProjectArgs') -> None: - self._add_global_arguments(node, self.build.global_link_args[kwargs['native']], args[0], kwargs) + native = kwargs['native'] + if native is InterpreterMachineChoice.BOTH: + self._add_global_arguments(node, self.build.global_link_args[MachineChoice.HOST], args[0], kwargs) + self._add_global_arguments(node, self.build.global_link_args[MachineChoice.BUILD], args[0], kwargs) + else: + self._add_global_arguments(node, self.build.global_link_args[native.as_machinechoice()], args[0], kwargs) @typed_pos_args('add_project_arguments', varargs=str) - @typed_kwargs('add_project_arguments', NATIVE_KW, LANGUAGE_KW) + @typed_kwargs('add_project_arguments', NATIVE_BOTH_KW, LANGUAGE_KW) def func_add_project_arguments(self, node: mparser.FunctionNode, args: T.Tuple[T.List[str]], kwargs: 'kwtypes.FuncAddProjectArgs') -> None: - self._add_project_arguments(node, self.build.projects_args[kwargs['native']], args[0], kwargs) + native = kwargs['native'] + if native is InterpreterMachineChoice.BOTH: + self._add_project_arguments(node, self.build.projects_args[MachineChoice.BUILD], args[0], kwargs) + self._add_project_arguments(node, self.build.projects_args[MachineChoice.HOST], args[0], kwargs) + else: + self._add_project_arguments(node, self.build.projects_args[native.as_machinechoice()], args[0], kwargs) @typed_pos_args('add_project_link_arguments', varargs=str) - @typed_kwargs('add_global_arguments', NATIVE_KW, LANGUAGE_KW) + @typed_kwargs('add_global_arguments', NATIVE_BOTH_KW, LANGUAGE_KW) def func_add_project_link_arguments(self, node: mparser.FunctionNode, args: T.Tuple[T.List[str]], kwargs: 'kwtypes.FuncAddProjectArgs') -> None: - self._add_project_arguments(node, self.build.projects_link_args[kwargs['native']], args[0], kwargs) + native = kwargs['native'] + if native is InterpreterMachineChoice.BOTH: + self._add_project_arguments(node, self.build.projects_link_args[MachineChoice.BUILD], args[0], kwargs) + self._add_project_arguments(node, self.build.projects_link_args[MachineChoice.HOST], args[0], kwargs) + else: + self._add_project_arguments(node, self.build.projects_link_args[native.as_machinechoice()], args[0], kwargs) @FeatureNew('add_project_dependencies', '0.63.0') @typed_pos_args('add_project_dependencies', varargs=dependencies.Dependency) @typed_kwargs('add_project_dependencies', NATIVE_KW, LANGUAGE_KW) - def func_add_project_dependencies(self, node: mparser.FunctionNode, args: T.Tuple[T.List[dependencies.Dependency]], kwargs: 'kwtypes.FuncAddProjectArgs') -> None: + def func_add_project_dependencies(self, node: mparser.FunctionNode, args: T.Tuple[T.List[dependencies.Dependency]], kwargs: kwtypes.FuncAddProjectDeps) -> None: for_machine = kwargs['native'] for lang in kwargs['language']: if lang not in self.compilers[for_machine]: diff --git a/mesonbuild/interpreter/kwargs.py b/mesonbuild/interpreter/kwargs.py index 8443166fef47..dde27c6a9d14 100644 --- a/mesonbuild/interpreter/kwargs.py +++ b/mesonbuild/interpreter/kwargs.py @@ -29,6 +29,12 @@ class FuncAddProjectArgs(TypedDict): a MachineChoice instance already. """ + native: InterpreterMachineChoice + language: T.List[str] + + +class FuncAddProjectDeps(TypedDict): + native: MachineChoice language: T.List[str] diff --git a/test cases/common/115 subproject project arguments/meson.build b/test cases/common/115 subproject project arguments/meson.build index 90d4c05f33a4..ae62a4e6a550 100644 --- a/test cases/common/115 subproject project arguments/meson.build +++ b/test cases/common/115 subproject project arguments/meson.build @@ -2,16 +2,46 @@ project('project options tester', 'c', 'cpp', version : '2.3.4', license : 'mylicense') -add_global_arguments('-DGLOBAL_ARGUMENT', language: 'c') -add_project_arguments('-DPROJECT_OPTION', language: 'c') -add_project_arguments('-DPROJECT_OPTION_CPP', language: 'cpp') -add_project_arguments('-DPROJECT_OPTION_C_CPP', language: ['c', 'cpp']) +machine = get_option('machine') +assert(machine in ['host', 'build', 'both']) +if machine == 'host' + native = false +elif machine == 'build' + native = true +else + native = 'both' +endif -sub = subproject('subexe', version : '1.0.0') +if not add_languages('c', 'cpp', native : native, required : false) + error(f'MESON_SKIP_TEST this test requires compilers for @machine@ machine(s)') +endif -add_project_arguments('-DPROJECT_OPTION_1', language: 'c') +add_global_arguments('-DGLOBAL_ARGUMENT', language: 'c', native : native) +add_project_arguments('-DPROJECT_OPTION', language: 'c', native : native) +add_project_arguments('-DPROJECT_OPTION_CPP', language: 'cpp', native : native) +add_project_arguments('-DPROJECT_OPTION_C_CPP', language: ['c', 'cpp'], native : native) -e = executable('exe', 'exe.c') -e = executable('execpp', 'exe.cpp') +# XXX: when subprojects allow host/build +if machine != 'build' + sub = subproject('subexe', version : '1.0.0') +endif + +add_project_arguments('-DPROJECT_OPTION_1', language: 'c', native : native) + +if machine == 'both' + native = false +endif + +e = executable('exe', 'exe.c', native : native) +e = executable('execpp', 'exe.cpp', native : native) test('exetest', e) test('execpptest', e) + +if machine == 'both' + e = executable('exe_build', 'exe.c', native : true) + e = executable('execpp_build', 'exe.cpp', native : true) + if meson.can_run_host_binaries() + test('exetest_build', e) + test('execpptest_build', e) + endif +endif diff --git a/test cases/common/115 subproject project arguments/meson.options b/test cases/common/115 subproject project arguments/meson.options new file mode 100644 index 000000000000..399ee9e08e46 --- /dev/null +++ b/test cases/common/115 subproject project arguments/meson.options @@ -0,0 +1 @@ +option('machine', type : 'string', value : 'host') diff --git a/test cases/common/115 subproject project arguments/test.json b/test cases/common/115 subproject project arguments/test.json new file mode 100644 index 000000000000..ae17f6957500 --- /dev/null +++ b/test cases/common/115 subproject project arguments/test.json @@ -0,0 +1,11 @@ +{ + "matrix": { + "options": { + "machine": [ + { "val": "host" }, + { "val": "build" }, + { "val": "both" } + ] + } + } +} diff --git a/test cases/warning/2 languages missing native/meson.build b/test cases/warning/2 languages missing native/meson.build deleted file mode 100644 index e2047152b85e..000000000000 --- a/test cases/warning/2 languages missing native/meson.build +++ /dev/null @@ -1,3 +0,0 @@ -project('languages missing native', - meson_version : '>= 0.54') -add_languages('c') diff --git a/test cases/warning/2 languages missing native/test.json b/test cases/warning/2 languages missing native/test.json deleted file mode 100644 index f929654d82b6..000000000000 --- a/test cases/warning/2 languages missing native/test.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "stdout": [ - { - "line": "test cases/warning/2 languages missing native/meson.build:3: WARNING: add_languages is missing native:, assuming languages are wanted for both host and build." - } - ] -} diff --git a/unittests/allplatformstests.py b/unittests/allplatformstests.py index c15519874113..d95ca9a212d4 100644 --- a/unittests/allplatformstests.py +++ b/unittests/allplatformstests.py @@ -1,5 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright 2016-2021 The Meson development team +# Copyright © 2023 Intel Corporation import subprocess import re @@ -4920,3 +4921,11 @@ def test_c_cpp_stds(self): # The first supported std should be selected self.setconf('-Dcpp_std=c++11,gnu++11,vc++11') self.assertEqual(self.getconf('cpp_std'), 'c++11') + + def test_add_arguments_both_no_dups(self) -> None: + testdir = os.path.join(self.common_test_dir, '115 subproject project arguments') + self.init(testdir, extra_args=['-Dmachine=both']) + compdb = self.get_compdb() + # It really doesn't matter what target we look at + self.assertEqual(compdb[0]['command'].count('-DGLOBAL_ARGUMENT'), 1, + msg="`native : both` inserted arguments twice in the same target")