Merge pull request #6532 from jon-turney/languages-native-kwarg

Add add_languages(native:)
pull/6760/head
Jussi Pakkanen 5 years ago committed by GitHub
commit 5c51d4521a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 28
      docs/markdown/Reference-manual.md
  2. 20
      docs/markdown/snippets/native_compiler_not_required.md
  3. 16
      mesonbuild/build.py
  4. 2
      mesonbuild/compilers/__init__.py
  5. 9
      mesonbuild/compilers/compilers.py
  6. 21
      mesonbuild/interpreter.py
  7. 3
      test cases/common/85 add language/meson.build
  8. 3
      test cases/failing/100 no native compiler/main.c
  9. 12
      test cases/failing/100 no native compiler/meson.build
  10. 3
      test cases/failing/101 no lang/main.c
  11. 2
      test cases/failing/101 no lang/meson.build
  12. 2
      test cases/warning/2 languages missing native/meson.build

@ -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()

@ -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)
```

@ -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])))

@ -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,

@ -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': [],

@ -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

@ -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)

@ -0,0 +1,3 @@
int main(void) {
return 0;
}

@ -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)

@ -0,0 +1,3 @@
int main(void) {
return 0;
}

@ -0,0 +1,2 @@
project('target without lang')
executable('main', 'main.c')

@ -0,0 +1,2 @@
project('languages missing native')
add_languages('c')
Loading…
Cancel
Save