diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2020-03-09 01:20:57 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-09 01:20:57 +0200 |
commit | 5c51d4521ab37edce88c61fd5067c93a44078854 (patch) | |
tree | 51910cba73b3017087fc13b6bdb64afd3bd4e09e | |
parent | 3a57e5177ba949cff5f971f7338a1c75a2724ac2 (diff) | |
parent | 48e5c1234ad4dd0438324ab8164f94d12a8c2218 (diff) | |
download | meson-5c51d4521ab37edce88c61fd5067c93a44078854.tar.gz |
Merge pull request #6532 from jon-turney/languages-native-kwarg
Add add_languages(native:)
-rw-r--r-- | docs/markdown/Reference-manual.md | 28 | ||||
-rw-r--r-- | docs/markdown/snippets/native_compiler_not_required.md | 20 | ||||
-rw-r--r-- | mesonbuild/build.py | 16 | ||||
-rw-r--r-- | mesonbuild/compilers/__init__.py | 2 | ||||
-rw-r--r-- | mesonbuild/compilers/compilers.py | 9 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 21 | ||||
-rw-r--r-- | test cases/common/85 add language/meson.build | 3 | ||||
-rw-r--r-- | test cases/failing/100 no native compiler/main.c | 3 | ||||
-rw-r--r-- | test cases/failing/100 no native compiler/meson.build | 12 | ||||
-rw-r--r-- | test cases/failing/101 no lang/main.c | 3 | ||||
-rw-r--r-- | test cases/failing/101 no lang/meson.build | 2 | ||||
-rw-r--r-- | test cases/warning/2 languages missing native/meson.build | 2 |
12 files changed, 103 insertions, 18 deletions
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md index 9bb791117..ea02cd40b 100644 --- a/docs/markdown/Reference-manual.md +++ b/docs/markdown/Reference-manual.md @@ -54,9 +54,9 @@ Like `add_global_arguments` but the arguments are passed to the linker. bool add_languages(*langs*) ``` -Add support for new programming languages. Equivalent to having them -in the `project` declaration. This function is usually used to add -languages that are only used on some platforms like this: +Add programming languages used by the project. Equivalent to having them in the +`project` declaration. This function is usually used to add languages that are +only used under some conditions, like this: ```meson project('foobar', 'c') @@ -68,12 +68,22 @@ if add_languages('cpp', required : false) endif ``` -Takes one keyword argument, `required`. It defaults to `true`, which -means that if any of the languages specified is not found, Meson will -halt. Returns true if all languages specified were found and false -otherwise. Since *0.47.0* the value of a -[`feature`](Build-options.md#features) option can also be passed to -the `required` keyword argument. +Takes the following keyword arguments: + +- `required` defaults to `true`, which means that if any of the languages +specified is not found, Meson will halt. Since *0.47.0* the value of a +[`feature`](Build-options.md#features) option can also be passed. + +- `native` if set to `true`, the language will be used to compile for the build + machine, if `false`, for the host machine. Since *0.54.0*. + +Returns `true` if all languages specified were found and `false` otherwise. + +If `native` is omitted, the languages may be used for either build or host +machine, but are never required for the build machine. (i.e. it is equivalent +to `add_languages(*langs*, native: false, required: *required*) and +add_languages(*langs*, native: true, required: false)`. This default behaviour +may change to `native: false` in a future meson version. ### add_project_arguments() diff --git a/docs/markdown/snippets/native_compiler_not_required.md b/docs/markdown/snippets/native_compiler_not_required.md new file mode 100644 index 000000000..331b3c759 --- /dev/null +++ b/docs/markdown/snippets/native_compiler_not_required.md @@ -0,0 +1,20 @@ +## Native (build machine) compilers not always required + +`add_languages()` gained a `native:` keyword, indicating if a native or cross +compiler is to be used. + +For the benefit of existing simple build definitions which don't contain any +`native: true` targets, without breaking backwards compatibility for build +definitions which assume that the native compiler is available after +`add_languages()`, if the `native:` keyword is absent the languages may be used +for either the build or host machine, but are never required for the build +machine. + +This changes the behaviour of the following meson fragment (when cross-compiling +but a native compiler is not available) from reporting an error at +`add_language` to reporting an error at `executable`. + +``` +add_language('c') +executable('main', 'main.c', native: true) +``` diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 6755dca79..61894fe8a 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -28,7 +28,7 @@ from .mesonlib import ( extract_as_list, typeslistify, stringlistify, classify_unity_sources, get_filenames_templates_dict, substitute_values, has_path_sep, unholder ) -from .compilers import Compiler, is_object, clink_langs, sort_clink, lang_suffixes +from .compilers import Compiler, is_object, clink_langs, sort_clink, lang_suffixes, is_known_suffix from .linkers import StaticLinker from .interpreterbase import FeatureNew @@ -651,14 +651,24 @@ class BuildTarget(Target): sources.append(s) if sources: # For each source, try to add one compiler that can compile it. - # It's ok if no compilers can do so, because users are expected to - # be able to add arbitrary non-source files to the sources list. + # + # If it has a suffix that belongs to a known language, we must have + # a compiler for that language. + # + # Otherwise, it's ok if no compilers can compile it, because users + # are expected to be able to add arbitrary non-source files to the + # sources list for s in sources: for lang, compiler in compilers.items(): if compiler.can_compile(s): if lang not in self.compilers: self.compilers[lang] = compiler break + else: + if is_known_suffix(s): + raise MesonException('No {} machine compiler for "{}"'. + format(self.for_machine.get_lower_case_name(), s)) + # Re-sort according to clink_langs self.compilers = OrderedDict(sorted(self.compilers.items(), key=lambda t: sort_clink(t[0]))) diff --git a/mesonbuild/compilers/__init__.py b/mesonbuild/compilers/__init__.py index b378a63e7..a4e39432a 100644 --- a/mesonbuild/compilers/__init__.py +++ b/mesonbuild/compilers/__init__.py @@ -30,6 +30,7 @@ __all__ = [ 'is_llvm_ir', 'is_object', 'is_source', + 'is_known_suffix', 'lang_suffixes', 'sort_clink', @@ -115,6 +116,7 @@ from .compilers import ( is_llvm_ir, is_object, is_library, + is_known_suffix, lang_suffixes, sort_clink, CompilerArgs, diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index caa860032..366bb50fa 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -14,6 +14,7 @@ import contextlib, os.path, re, tempfile import collections.abc +import itertools import typing as T from functools import lru_cache @@ -75,6 +76,7 @@ clink_suffixes = () for _l in clink_langs + ('vala',): clink_suffixes += lang_suffixes[_l] clink_suffixes += ('h', 'll', 's') +all_suffixes = set(itertools.chain(*lang_suffixes.values(), clink_suffixes)) # Languages that should use LDFLAGS arguments when linking. languages_using_ldflags = ('objcpp', 'cpp', 'objc', 'c', 'fortran', 'd', 'cuda') @@ -147,6 +149,13 @@ def is_library(fname): suffix = fname.split('.')[-1] return suffix in lib_suffixes +def is_known_suffix(fname): + if hasattr(fname, 'fname'): + fname = fname.fname + suffix = fname.split('.')[-1] + + return suffix in all_suffixes + cuda_buildtype_args = {'plain': [], 'debug': [], 'debugoptimized': [], diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index e8284bbc1..af6eda321 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -2119,7 +2119,7 @@ _base_test_args = {'args', 'depends', 'env', 'should_fail', 'timeout', 'workdir' permitted_kwargs = {'add_global_arguments': {'language', 'native'}, 'add_global_link_arguments': {'language', 'native'}, - 'add_languages': {'required'}, + 'add_languages': {'required', 'native'}, 'add_project_link_arguments': {'language', 'native'}, 'add_project_arguments': {'language', 'native'}, 'add_test_setup': {'exe_wrapper', 'gdb', 'timeout_multiplier', 'env', 'is_default'}, @@ -2951,11 +2951,13 @@ external dependencies (including libraries) must go to "dependencies".''') self.build.projects[self.subproject] = proj_name mlog.log('Project name:', mlog.bold(proj_name)) mlog.log('Project version:', mlog.bold(self.project_version)) - self.add_languages(proj_langs, True) + self.add_languages(proj_langs, True, MachineChoice.BUILD) + self.add_languages(proj_langs, True, MachineChoice.HOST) self.set_backend() if not self.is_subproject(): self.check_stdlibs() + @FeatureNewKwargs('add_languages', '0.54.0', ['native']) @permittedKwargs(permitted_kwargs['add_languages']) @stringArgs def func_add_languages(self, node, args, kwargs): @@ -2964,7 +2966,15 @@ external dependencies (including libraries) must go to "dependencies".''') for lang in sorted(args, key=compilers.sort_clink): mlog.log('Compiler for language', mlog.bold(lang), 'skipped: feature', mlog.bold(feature), 'disabled') return False - return self.add_languages(args, required) + if 'native' in kwargs: + return self.add_languages(args, required, self.machine_from_native_kwarg(kwargs)) + else: + # absent 'native' means 'both' for backwards compatibility + mlog.warning('add_languages is missing native:, assuming languages are wanted for both host and build.', + location=self.current_node) + success = self.add_languages(args, False, MachineChoice.BUILD) + success &= self.add_languages(args, required, MachineChoice.HOST) + return success def get_message_string_arg(self, arg): if isinstance(arg, list): @@ -3060,9 +3070,8 @@ external dependencies (including libraries) must go to "dependencies".''') self.validate_arguments(args, 0, []) raise Exception() - def add_languages(self, args: T.Sequence[str], required: bool) -> bool: - success = self.add_languages_for(args, required, MachineChoice.BUILD) - success &= self.add_languages_for(args, required, MachineChoice.HOST) + def add_languages(self, args: T.Sequence[str], required: bool, for_machine: MachineChoice) -> bool: + success = self.add_languages_for(args, required, for_machine) if not self.coredata.is_cross_build(): self.coredata.copy_build_options_from_regular_ones() return success diff --git a/test cases/common/85 add language/meson.build b/test cases/common/85 add language/meson.build index d9bc0fa2b..aa4972abd 100644 --- a/test cases/common/85 add language/meson.build +++ b/test cases/common/85 add language/meson.build @@ -6,3 +6,6 @@ assert(add_languages('cpp'), 'Add_languages returned false on success') assert(not add_languages('klingon', required : false), 'Add_languages returned true on failure.') test('C++', executable('cppprog', 'prog.cc')) + +add_languages('c', native: true) +add_languages('c', native: false) diff --git a/test cases/failing/100 no native compiler/main.c b/test cases/failing/100 no native compiler/main.c new file mode 100644 index 000000000..9b6bdc2ec --- /dev/null +++ b/test cases/failing/100 no native compiler/main.c @@ -0,0 +1,3 @@ +int main(void) { + return 0; +} diff --git a/test cases/failing/100 no native compiler/meson.build b/test cases/failing/100 no native compiler/meson.build new file mode 100644 index 000000000..f0126ac15 --- /dev/null +++ b/test cases/failing/100 no native compiler/meson.build @@ -0,0 +1,12 @@ +project('no native compiler') + +if not meson.is_cross_build() + error('MESON_SKIP_TEST test only applicable when cross building.') +endif + +if add_languages('c', required: false, native: true) + error('MESON_SKIP_TEST test only applicable when native compiler not available.') +endif + +add_languages('c') +executable('main', 'main.c', native: true) diff --git a/test cases/failing/101 no lang/main.c b/test cases/failing/101 no lang/main.c new file mode 100644 index 000000000..9b6bdc2ec --- /dev/null +++ b/test cases/failing/101 no lang/main.c @@ -0,0 +1,3 @@ +int main(void) { + return 0; +} diff --git a/test cases/failing/101 no lang/meson.build b/test cases/failing/101 no lang/meson.build new file mode 100644 index 000000000..85c5db8e5 --- /dev/null +++ b/test cases/failing/101 no lang/meson.build @@ -0,0 +1,2 @@ +project('target without lang') +executable('main', 'main.c') diff --git a/test cases/warning/2 languages missing native/meson.build b/test cases/warning/2 languages missing native/meson.build new file mode 100644 index 000000000..f4aa9567a --- /dev/null +++ b/test cases/warning/2 languages missing native/meson.build @@ -0,0 +1,2 @@ +project('languages missing native') +add_languages('c') |