diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md index e3830cc51..f4fa89eb8 100644 --- a/docs/markdown/Reference-manual.md +++ b/docs/markdown/Reference-manual.md @@ -1773,10 +1773,6 @@ the following methods. refer to files in the current or any other source directory instead of constructing paths manually with `meson.current_source_dir()`. -- `get_cross_property(propname, fallback_value)` returns the given - property from a cross file, the optional second argument is returned - if not cross compiling or the given property is not found. - - `get_compiler(language)` returns [an object describing a compiler](#compiler-object), takes one positional argument which is the language to use. It also accepts one keyword argument, `native` @@ -1786,6 +1782,19 @@ the following methods. returns the "cross" compiler if we're currently cross-compiling and the "native" compiler if we're not. +- `get_cross_property(propname, fallback_value)` + *Consider get_external_property() instead*. Returns the given + property from a cross file, the optional fallback_value is returned + if not cross compiling or the given property is not found. + +- `get_external_property(propname, fallback_value, native: true/false)` + *(added 0.54.0)* returns the given property from a native or cross file. + The optional fallback_value is returned if the given property is not found. + The optional `native: true` forces retrieving a variable from the + native file, even when cross-compiling. + If `native: false` or not specified, variable is retrieved from the + cross-file if cross-compiling, and from the native-file when not cross-compiling. + - `has_exe_wrapper()` returns true when doing a cross build if there is a wrapper command that can be used to execute cross built binaries (for example when cross compiling from Linux to Windows, diff --git a/docs/markdown/snippets/native_property.md b/docs/markdown/snippets/native_property.md new file mode 100644 index 000000000..d3808d895 --- /dev/null +++ b/docs/markdown/snippets/native_property.md @@ -0,0 +1,18 @@ +## Native file properties + +As of Meson 0.54.0, the `--native-file nativefile.ini` can contain: + +* binaries +* paths +* properties + +which are defined and used the same way as in cross files. +The `properties` are new for Meson 0.54.0, and are read like: + +```meson +x = meson.get_external_property('foobar', 'foo') +``` + +where `foobar` is the property name, and the optional `foo` is the fallback string value. + +For cross-compiled projects, `get_external_property()` reads the cross-file unless `native: true` is specified. \ No newline at end of file diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index beaff767c..554d79b4f 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -538,6 +538,7 @@ class Environment: coredata.load_configs(self.coredata.config_files)) binaries.build = BinaryTable(config.get('binaries', {})) paths.build = Directories(**config.get('paths', {})) + properties.build = Properties(config.get('properties', {})) ## Read in cross file(s) to override host machine configuration diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index e32e0a1d9..74882b223 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -35,8 +35,11 @@ from .modules import ModuleReturnValue from .cmake import CMakeInterpreter from pathlib import Path, PurePath -import os, shutil, uuid -import re, shlex +import os +import shutil +import uuid +import re +import shlex import subprocess import collections from itertools import chain @@ -1845,6 +1848,7 @@ class MesonMain(InterpreterObject): 'version': self.version_method, 'project_name': self.project_name_method, 'get_cross_property': self.get_cross_property_method, + 'get_external_property': self.get_external_property_method, 'backend': self.backend_method, }) @@ -2017,7 +2021,7 @@ class MesonMain(InterpreterObject): @noArgsFlattening @permittedKwargs({}) - def get_cross_property_method(self, args, kwargs): + def get_cross_property_method(self, args, kwargs) -> str: if len(args) < 1 or len(args) > 2: raise InterpreterException('Must have one or two arguments.') propname = args[0] @@ -2031,6 +2035,34 @@ class MesonMain(InterpreterObject): return args[1] raise InterpreterException('Unknown cross property: %s.' % propname) + @noArgsFlattening + @permittedKwargs({'native'}) + @FeatureNew('meson.get_external_property', '0.54.0') + def get_external_property_method(self, args: T.Sequence[str], kwargs: dict) -> str: + if len(args) < 1 or len(args) > 2: + raise InterpreterException('Must have one or two positional arguments.') + propname = args[0] + if not isinstance(propname, str): + raise InterpreterException('Property name must be string.') + + def _get_native() -> str: + try: + props = self.interpreter.environment.properties.build + return props[propname] + except Exception: + if len(args) == 2: + return args[1] + raise InterpreterException('Unknown native property: %s.' % propname) + if 'native' in kwargs: + if kwargs['native']: + return _get_native() + else: + return self.get_cross_property_method(args, {}) + else: # native: not specified + if self.build.environment.is_cross_build(): + return self.get_cross_property_method(args, kwargs) + else: + return _get_native() known_library_kwargs = ( build.known_shlib_kwargs | diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py index 85d883bef..891e7a12e 100644 --- a/mesonbuild/mesonlib.py +++ b/mesonbuild/mesonlib.py @@ -1,4 +1,4 @@ -# Copyright 2012-2015 The Meson development team +# Copyright 2012-2019 The Meson development team # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/test cases/common/192 args flattening/meson.build b/test cases/common/192 args flattening/meson.build index 6da2e8f25..1dac2f912 100644 --- a/test cases/common/192 args flattening/meson.build +++ b/test cases/common/192 args flattening/meson.build @@ -1,29 +1,31 @@ project('args flattening') arr = get_variable('does-not-exist', ['bar', 'baz']) - assert(arr == ['bar', 'baz'], 'get_variable with array fallback is broken') set_variable('arr', ['bar', 'baz']) - assert(arr == ['bar', 'baz'], 'set_variable(array) is broken') conf = configuration_data() - conf.set('foo', ['bar', 'baz']) - assert(conf.get('foo') == ['bar', 'baz'], 'configuration_data.set(array) is broken') arr = conf.get('does-not-exist', ['bar', 'baz']) - assert(arr == ['bar', 'baz'], 'configuration_data.get with array fallback is broken') arr = meson.get_cross_property('does-not-exist', ['bar', 'baz']) - assert(arr == ['bar', 'baz'], 'meson.get_cross_property with array fallback is broken') +arr = meson.get_external_property('does-not-exist', ['bar', 'baz']) +assert(arr == ['bar', 'baz'], 'meson.get_external_property with array fallback is broken') + +arr = meson.get_external_property('does-not-exist', ['bar', 'baz'], native: true) +assert(arr == ['bar', 'baz'], 'meson.get_external_property native:true with array fallback is broken') + +arr = meson.get_external_property('does-not-exist', ['bar', 'baz'], native: false) +assert(arr == ['bar', 'baz'], 'meson.get_external_property native:false with array fallback is broken') + # Test deprecated behaviour conf.set(['foo', 'bar']) - message(conf.get('foo')) diff --git a/test cases/common/229 native prop/crossfile.ini b/test cases/common/229 native prop/crossfile.ini new file mode 100644 index 000000000..62d63ed63 --- /dev/null +++ b/test cases/common/229 native prop/crossfile.ini @@ -0,0 +1,3 @@ +[properties] +astring = 'cross' +anarray = ['one', 'two'] \ No newline at end of file diff --git a/test cases/common/229 native prop/meson.build b/test cases/common/229 native prop/meson.build new file mode 100644 index 000000000..64da41018 --- /dev/null +++ b/test cases/common/229 native prop/meson.build @@ -0,0 +1,25 @@ +project('get prop') + +x = meson.get_external_property('astring') +ref = meson.is_cross_build() ? 'cross' : 'mystring' +assert(x==ref, 'did not get native property string. did you use "meson setup --native-file native.txt"') + +x = meson.get_external_property('astring', native: true) +assert(x=='mystring', 'did not get native property with native:true and non-cross build.') + +x = meson.get_external_property('astring', 'fallback', native: false) +assert(x==ref, 'did not get get native property with native:false and non-cross build.') + + +x = meson.get_external_property('notexist', 'fallback') +assert(x=='fallback', 'fallback did not work') + +x = meson.get_external_property('notexist', 'fallback', native: true) +assert(x=='fallback', 'fallback native:true did not work') + +x = meson.get_external_property('notexist', 'fallback', native: false) +assert(x=='fallback', 'fallback native:false did not work') + + +x = meson.get_external_property('anarray') +assert(x==['one', 'two'], 'array did not work') \ No newline at end of file diff --git a/test cases/common/229 native prop/nativefile.ini b/test cases/common/229 native prop/nativefile.ini new file mode 100644 index 000000000..03c1e0397 --- /dev/null +++ b/test cases/common/229 native prop/nativefile.ini @@ -0,0 +1,3 @@ +[properties] +astring = 'mystring' +anarray = ['one', 'two'] \ No newline at end of file diff --git a/test cases/failing/99 no native prop/meson.build b/test cases/failing/99 no native prop/meson.build new file mode 100644 index 000000000..c9567549f --- /dev/null +++ b/test cases/failing/99 no native prop/meson.build @@ -0,0 +1,3 @@ +project('missing property') + +message(meson.get_external_property('nonexisting'))