From a6164ca5a81224b7ed672401a47260f498f06e44 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Thu, 6 Feb 2020 09:10:01 -0800 Subject: Allow setting project options from cross or native files This allows adding a `[project options]` section to a cross or native file that contains the options defined for a project in it's meson_option.txt file. --- docs/markdown/Machine-files.md | 20 ++++++ .../snippets/project_options_in_machine_files.md | 37 ++++++++++ mesonbuild/coredata.py | 10 ++- mesonbuild/environment.py | 19 +++++ run_unittests.py | 83 +++++++++++++++++++++- .../unit/75 user options for subproject/.gitignore | 1 + .../75 user options for subproject/meson.build | 3 + 7 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 docs/markdown/snippets/project_options_in_machine_files.md create mode 100644 test cases/unit/75 user options for subproject/.gitignore create mode 100644 test cases/unit/75 user options for subproject/meson.build diff --git a/docs/markdown/Machine-files.md b/docs/markdown/Machine-files.md index 9011f79..26af44a 100644 --- a/docs/markdown/Machine-files.md +++ b/docs/markdown/Machine-files.md @@ -12,6 +12,7 @@ The following sections are allowed: - binaries - paths - properties +- project options ### constants @@ -166,6 +167,25 @@ section may contain random key value pairs accessed using the The properties section can contain any variable you like, and is accessed via `meson.get_external_property`, or `meson.get_cross_property`. +### Project specific options + +*New in 0.54.0* + +Being able to set project specific options in a native or cross files can be +done using the `[project options]` section of the specific file (if doing a +cross build the options from the native file will be ignored) + +For setting options in supbprojects use the `:project options` +section instead. + +```ini +[project options] +build-tests = true + +[zlib:project options] +build-tests = false +``` + ## Loading multiple machine files Native files allow layering (cross files can be layered since meson 0.52.0). diff --git a/docs/markdown/snippets/project_options_in_machine_files.md b/docs/markdown/snippets/project_options_in_machine_files.md new file mode 100644 index 0000000..78b129a --- /dev/null +++ b/docs/markdown/snippets/project_options_in_machine_files.md @@ -0,0 +1,37 @@ +## Project options can be set in native or cross files + +A new set of sections has been added to the cross and native files, `[project +options]` and `[:project options]`, where `subproject_name` +is the name of a subproject. Any options that are allowed in the project can +be set from this section. They have the lowest precedent, and will be +overwritten by command line arguments. + + +```meson +option('foo', type : 'string', value : 'foo') +``` + +```ini +[project options] +foo = 'other val' +``` + +```console +meson build --native-file my.ini +``` + +Will result in the option foo having the value `other val`, + +```console +meson build --native-file my.ini -Dfoo='different val' +``` + +Will result in the option foo having the value `different val`, + + +Subproject options are assigned like this: + +```ini +[zlib:project options] +foo = 'some val' +``` diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index e2a6954..49104a7 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -377,6 +377,7 @@ class CoreData: host_cache = DependencyCache(self.builtins_per_machine, MachineChoice.BUILD) self.deps = PerMachine(build_cache, host_cache) # type: PerMachine[DependencyCache] self.compiler_check_cache = OrderedDict() + # Only to print a warning if it changes between Meson invocations. self.config_files = self.__load_config_files(options, scratch_dir, 'native') self.builtin_options_libdir_cross_fixup() @@ -734,7 +735,7 @@ class CoreData: if not self.is_cross_build(): self.copy_build_options_from_regular_ones() - def set_default_options(self, default_options, subproject, env): + def set_default_options(self, default_options: T.Mapping[str, str], subproject: str, env: 'Environment') -> None: # Warn if the user is using two different ways of setting build-type # options that override each other if 'buildtype' in env.cmd_line_options and \ @@ -755,6 +756,13 @@ class CoreData: k = subproject + ':' + k cmd_line_options[k] = v + # load the values for user options out of the appropriate machine file, + # then overload the command line + for k, v in env.user_options.get(subproject, {}).items(): + if subproject: + k = '{}:{}'.format(subproject, k) + cmd_line_options[k] = v + # Override project default_options using conf files (cross or native) for k, v in env.paths.host: if v is not None: diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index a82c8f8..c872aee 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -553,6 +553,9 @@ class Environment: # architecture, just the build and host architectures paths = PerMachineDefaultable() + # We only need one of these as project options are not per machine + user_options = {} + ## Setup build machine defaults # Will be fully initialized later using compilers later. @@ -565,12 +568,26 @@ class Environment: ## Read in native file(s) to override build machine configuration + def load_user_options(): + for section in config.keys(): + if section.endswith('project options'): + if ':' in section: + project = section.split(':')[0] + else: + project = '' + user_options[project] = config.get(section, {}) + if self.coredata.config_files is not None: config = coredata.parse_machine_files(self.coredata.config_files) binaries.build = BinaryTable(config.get('binaries', {})) paths.build = Directories(**config.get('paths', {})) properties.build = Properties(config.get('properties', {})) + # Don't run this if there are any cross files, we don't want to use + # the native values if we're doing a cross build + if not self.coredata.cross_files: + load_user_options() + ## Read in cross file(s) to override host machine configuration if self.coredata.cross_files: @@ -582,6 +599,7 @@ class Environment: if 'target_machine' in config: machines.target = MachineInfo.from_literal(config['target_machine']) paths.host = Directories(**config.get('paths', {})) + load_user_options() ## "freeze" now initialized configuration, and "save" to the class. @@ -589,6 +607,7 @@ class Environment: self.binaries = binaries.default_missing() self.properties = properties.default_missing() self.paths = paths.default_missing() + self.user_options = user_options exe_wrapper = self.lookup_binary_entry(MachineChoice.HOST, 'exe_wrapper') if exe_wrapper is not None: diff --git a/run_unittests.py b/run_unittests.py index 2b0e4e1..9d96ce0 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -7672,7 +7672,10 @@ class NativeFileTests(BasePlatformTests): for section, entries in values.items(): f.write('[{}]\n'.format(section)) for k, v in entries.items(): - f.write("{}='{}'\n".format(k, v)) + if isinstance(v, bool): + f.write("{}={}\n".format(k, v)) + else: + f.write("{}='{}'\n".format(k, v)) return filename def helper_create_binary_wrapper(self, binary, dir_=None, extra_args=None, **kwargs): @@ -7996,6 +7999,54 @@ class NativeFileTests(BasePlatformTests): self.init(testcase, extra_args=['--native-file', config]) self.build() + def test_user_options(self): + testcase = os.path.join(self.common_test_dir, '43 options') + for opt, value in [('testoption', 'some other val'), ('other_one', True), + ('combo_opt', 'one'), ('array_opt', ['two']), + ('integer_opt', 0)]: + config = self.helper_create_native_file({'project options': {opt: value}}) + with self.assertRaises(subprocess.CalledProcessError) as cm: + self.init(testcase, extra_args=['--native-file', config]) + self.assertRegex(cm.exception.stdout, r'Incorrect value to [a-z]+ option') + + def test_user_options_command_line_overrides(self): + testcase = os.path.join(self.common_test_dir, '43 options') + config = self.helper_create_native_file({'project options': {'other_one': True}}) + self.init(testcase, extra_args=['--native-file', config, '-Dother_one=false']) + + def test_user_options_subproject(self): + testcase = os.path.join(self.unit_test_dir, '75 user options for subproject') + + s = os.path.join(testcase, 'subprojects') + if not os.path.exists(s): + os.mkdir(s) + s = os.path.join(s, 'sub') + if not os.path.exists(s): + sub = os.path.join(self.common_test_dir, '43 options') + shutil.copytree(sub, s) + + for opt, value in [('testoption', 'some other val'), ('other_one', True), + ('combo_opt', 'one'), ('array_opt', ['two']), + ('integer_opt', 0)]: + config = self.helper_create_native_file({'project options': {'sub:{}'.format(opt): value}}) + with self.assertRaises(subprocess.CalledProcessError) as cm: + self.init(testcase, extra_args=['--native-file', config]) + self.assertRegex(cm.exception.stdout, r'Incorrect value to [a-z]+ option') + + def test_option_bool(self): + # Bools are allowed to be unquoted + testcase = os.path.join(self.common_test_dir, '1 trivial') + config = self.helper_create_native_file({'built-in options': {'werror': True}}) + self.init(testcase, extra_args=['--native-file', config]) + configuration = self.introspect('--buildoptions') + for each in configuration: + # Test that no-per subproject options are inherited from the parent + if 'werror' in each['name']: + self.assertEqual(each['value'], True) + break + else: + self.fail('Did not find werror in build options?') + class CrossFileTests(BasePlatformTests): @@ -8005,6 +8056,11 @@ class CrossFileTests(BasePlatformTests): This is mainly aimed to testing overrides from cross files. """ + def setUp(self): + super().setUp() + self.current_config = 0 + self.current_wrapper = 0 + def _cross_file_generator(self, *, needs_exe_wrapper: bool = False, exe_wrapper: T.Optional[T.List[str]] = None) -> str: if is_windows(): @@ -8133,6 +8189,21 @@ class CrossFileTests(BasePlatformTests): self.init(testdir, extra_args=['--cross-file=' + name], inprocess=True) self.wipe() + def helper_create_cross_file(self, values): + """Create a config file as a temporary file. + + values should be a nested dictionary structure of {section: {key: + value}} + """ + filename = os.path.join(self.builddir, 'generated{}.config'.format(self.current_config)) + self.current_config += 1 + with open(filename, 'wt') as f: + for section, entries in values.items(): + f.write('[{}]\n'.format(section)) + for k, v in entries.items(): + f.write("{}='{}'\n".format(k, v)) + return filename + def test_cross_file_dirs(self): testcase = os.path.join(self.unit_test_dir, '60 native file override') self.init(testcase, default_args=False, @@ -8189,6 +8260,16 @@ class CrossFileTests(BasePlatformTests): '-Ddef_sharedstatedir=sharedstatebar', '-Ddef_sysconfdir=sysconfbar']) + def test_user_options(self): + # This is just a touch test for cross file, since the implementation + # shares code after loading from the files + testcase = os.path.join(self.common_test_dir, '43 options') + config = self.helper_create_cross_file({'project options': {'testoption': 'some other value'}}) + with self.assertRaises(subprocess.CalledProcessError) as cm: + self.init(testcase, extra_args=['--native-file', config]) + self.assertRegex(cm.exception.stdout, r'Incorrect value to [a-z]+ option') + + class TAPParserTests(unittest.TestCase): def assert_test(self, events, **kwargs): if 'explanation' not in kwargs: diff --git a/test cases/unit/75 user options for subproject/.gitignore b/test cases/unit/75 user options for subproject/.gitignore new file mode 100644 index 0000000..4976afc --- /dev/null +++ b/test cases/unit/75 user options for subproject/.gitignore @@ -0,0 +1 @@ +subprojects/* diff --git a/test cases/unit/75 user options for subproject/meson.build b/test cases/unit/75 user options for subproject/meson.build new file mode 100644 index 0000000..0bc395b --- /dev/null +++ b/test cases/unit/75 user options for subproject/meson.build @@ -0,0 +1,3 @@ +project('user option for subproject') + +p = subproject('sub') -- cgit v1.1 From 54fb61627851a0fe765d31955629ff5d7be2d064 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Wed, 3 Jun 2020 11:19:36 -0700 Subject: docs/Machine-files: remove duplicate Properties section --- docs/markdown/Machine-files.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/docs/markdown/Machine-files.md b/docs/markdown/Machine-files.md index 26af44a..ae0219b 100644 --- a/docs/markdown/Machine-files.md +++ b/docs/markdown/Machine-files.md @@ -158,13 +158,6 @@ command line will override any options in the native file. For example, passing In addition to special data that may be specified in cross files, this section may contain random key value pairs accessed using the -`meson.get_external_property()` - -## Properties - -*New for native files in 0.54.0* - -The properties section can contain any variable you like, and is accessed via `meson.get_external_property`, or `meson.get_cross_property`. ### Project specific options -- cgit v1.1 From af763e093a8172536d96e24901b82edd2e5b2dc9 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Wed, 10 Jun 2020 10:28:21 -0700 Subject: mconf/mintro: use authoritative list of options from coredata This splits the directory options and non-directory options into two dicts, and then merges them later to maintain API. --- mesonbuild/coredata.py | 29 +++++++++++++++++------------ mesonbuild/mconf.py | 14 +------------- mesonbuild/mintro.py | 14 +------------- 3 files changed, 19 insertions(+), 38 deletions(-) diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 49104a7..3330ae5 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -1158,23 +1158,25 @@ class BuiltinOption(T.Generic[_T, _U]): cmdline_name = self.argparse_name_to_arg(prefix + name) parser.add_argument(cmdline_name, help=h + help_suffix, **kwargs) + # Update `docs/markdown/Builtin-options.md` after changing the options below -builtin_options = OrderedDict([ - # Directories - ('prefix', BuiltinOption(UserStringOption, 'Installation prefix', default_prefix())), - ('bindir', BuiltinOption(UserStringOption, 'Executable directory', 'bin')), - ('datadir', BuiltinOption(UserStringOption, 'Data file directory', 'share')), - ('includedir', BuiltinOption(UserStringOption, 'Header file directory', 'include')), - ('infodir', BuiltinOption(UserStringOption, 'Info page directory', 'share/info')), - ('libdir', BuiltinOption(UserStringOption, 'Library directory', default_libdir())), - ('libexecdir', BuiltinOption(UserStringOption, 'Library executable directory', default_libexecdir())), - ('localedir', BuiltinOption(UserStringOption, 'Locale data directory', 'share/locale')), +BUILTIN_DIR_OPTIONS = OrderedDict([ + ('prefix', BuiltinOption(UserStringOption, 'Installation prefix', default_prefix())), + ('bindir', BuiltinOption(UserStringOption, 'Executable directory', 'bin')), + ('datadir', BuiltinOption(UserStringOption, 'Data file directory', 'share')), + ('includedir', BuiltinOption(UserStringOption, 'Header file directory', 'include')), + ('infodir', BuiltinOption(UserStringOption, 'Info page directory', 'share/info')), + ('libdir', BuiltinOption(UserStringOption, 'Library directory', default_libdir())), + ('libexecdir', BuiltinOption(UserStringOption, 'Library executable directory', default_libexecdir())), + ('localedir', BuiltinOption(UserStringOption, 'Locale data directory', 'share/locale')), ('localstatedir', BuiltinOption(UserStringOption, 'Localstate data directory', 'var')), ('mandir', BuiltinOption(UserStringOption, 'Manual page directory', 'share/man')), ('sbindir', BuiltinOption(UserStringOption, 'System executable directory', 'sbin')), ('sharedstatedir', BuiltinOption(UserStringOption, 'Architecture-independent data directory', 'com')), ('sysconfdir', BuiltinOption(UserStringOption, 'Sysconf data directory', 'etc')), - # Core options +]) # type: OptionDictType + +BUILTIN_CORE_OPTIONS = OrderedDict([ ('auto_features', BuiltinOption(UserFeatureOption, "Override value of all 'auto' features", 'auto')), ('backend', BuiltinOption(UserComboOption, 'Backend to use', 'ninja', choices=backendlist)), ('buildtype', BuiltinOption(UserComboOption, 'Build type to use', 'debug', @@ -1194,7 +1196,9 @@ builtin_options = OrderedDict([ ('werror', BuiltinOption(UserBooleanOption, 'Treat warnings as errors', False, yielding=False)), ('wrap_mode', BuiltinOption(UserComboOption, 'Wrap mode', 'default', choices=['default', 'nofallback', 'nodownload', 'forcefallback'])), ('force_fallback_for', BuiltinOption(UserArrayOption, 'Force fallback for those subprojects', [])), -]) +]) # type: OptionDictType + +builtin_options = OrderedDict(chain(BUILTIN_DIR_OPTIONS.items(), BUILTIN_CORE_OPTIONS.items())) builtin_options_per_machine = OrderedDict([ ('pkg_config_path', BuiltinOption(UserArrayOption, 'List of additional paths for pkg-config to search', [])), @@ -1230,3 +1234,4 @@ forbidden_target_names = {'clean': None, 'dist': None, 'distcheck': None, } + diff --git a/mesonbuild/mconf.py b/mesonbuild/mconf.py index 2e03cab..f070355 100644 --- a/mesonbuild/mconf.py +++ b/mesonbuild/mconf.py @@ -184,19 +184,7 @@ class Conf: if not self.default_values_only: print(' Build dir ', self.build_dir) - dir_option_names = ['bindir', - 'datadir', - 'includedir', - 'infodir', - 'libdir', - 'libexecdir', - 'localedir', - 'localstatedir', - 'mandir', - 'prefix', - 'sbindir', - 'sharedstatedir', - 'sysconfdir'] + dir_option_names = list(coredata.BUILTIN_DIR_OPTIONS) test_option_names = ['errorlogs', 'stdsplit'] core_option_names = [k for k in self.coredata.builtins if k not in dir_option_names + test_option_names] diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index cccedaa..0049bbd 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -200,19 +200,7 @@ def list_buildoptions_from_source(intr: IntrospectionInterpreter) -> T.List[T.Di def list_buildoptions(coredata: cdata.CoreData, subprojects: T.Optional[T.List[str]] = None) -> T.List[T.Dict[str, T.Union[str, bool, int, T.List[str]]]]: optlist = [] # type: T.List[T.Dict[str, T.Union[str, bool, int, T.List[str]]]] - dir_option_names = ['bindir', - 'datadir', - 'includedir', - 'infodir', - 'libdir', - 'libexecdir', - 'localedir', - 'localstatedir', - 'mandir', - 'prefix', - 'sbindir', - 'sharedstatedir', - 'sysconfdir'] + dir_option_names = list(cdata.BUILTIN_DIR_OPTIONS) test_option_names = ['errorlogs', 'stdsplit'] core_option_names = [k for k in coredata.builtins if k not in dir_option_names + test_option_names] -- cgit v1.1 From bbba6a7f365f8b7dc7f2d4c3ce7f3e5f4c05fc5e Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Thu, 6 Feb 2020 12:18:10 -0800 Subject: Allow setting built-in options from cross/native files This is like the project options, but for meson builtin options. The only real differences here have to do with the differences between meson builtin options and project options. Some meson options can be set on a per-machine basis (build.pkg_config_path vs pkg_config_path) others can be set on a per-subproject basis, but should inherit the parent setting. --- cross/armcc.txt | 2 +- cross/armclang-linux.txt | 5 +- cross/armclang.txt | 2 +- cross/c2000.txt | 6 +- cross/ccrx.txt | 2 +- cross/iphone.txt | 6 +- cross/tvos.txt | 7 +- cross/ubuntu-armhf.txt | 6 +- cross/wasm.txt | 3 +- cross/xc16.txt | 2 + docs/markdown/Machine-files.md | 56 +++++++- .../snippets/project_options_in_machine_files.md | 17 ++- mesonbuild/coredata.py | 49 +++++-- mesonbuild/environment.py | 28 +++- mesonbuild/interpreter.py | 1 + run_unittests.py | 153 ++++++++++++++++++++- 16 files changed, 307 insertions(+), 38 deletions(-) diff --git a/cross/armcc.txt b/cross/armcc.txt index c884ffa..ae65c9e 100644 --- a/cross/armcc.txt +++ b/cross/armcc.txt @@ -7,7 +7,7 @@ cpp = 'armcc' ar = 'armar' strip = 'armar' -[properties] +[built-in options] # The '--cpu' option with the appropriate target type should be mentioned # to cross compile c/c++ code with armcc,. c_args = ['--cpu=Cortex-M0plus'] diff --git a/cross/armclang-linux.txt b/cross/armclang-linux.txt index 6df78d6..10f6fa4 100644 --- a/cross/armclang-linux.txt +++ b/cross/armclang-linux.txt @@ -12,7 +12,7 @@ # Armcc is only available in toolchain version 5. # Armclang is only available in toolchain version 6. # Start shell with /opt/arm/developmentstudio-2019.0/bin/suite_exec zsh -# Now the compilers will work. +# Now the compilers will work. [binaries] # we could set exe_wrapper = qemu-arm-static but to test the case @@ -24,8 +24,7 @@ ar = '/opt/arm/developmentstudio-2019.0/sw/ARMCompiler6.12/bin/armar' #strip = '/usr/arm-linux-gnueabihf/bin/strip' #pkgconfig = '/usr/bin/arm-linux-gnueabihf-pkg-config' -[properties] - +[built-in options] c_args = ['--target=aarch64-arm-none-eabi'] [host_machine] diff --git a/cross/armclang.txt b/cross/armclang.txt index 955b7ef..6146e0d 100644 --- a/cross/armclang.txt +++ b/cross/armclang.txt @@ -7,7 +7,7 @@ cpp = 'armclang' ar = 'armar' strip = 'armar' -[properties] +[built-in options] # The '--target', '-mcpu' options with the appropriate values should be mentioned # to cross compile c/c++ code with armclang. c_args = ['--target=arm-arm-none-eabi', '-mcpu=cortex-m0plus'] diff --git a/cross/c2000.txt b/cross/c2000.txt index e624f25..61c0310 100644 --- a/cross/c2000.txt +++ b/cross/c2000.txt @@ -12,8 +12,7 @@ cpu_family = 'c2000' cpu = 'c28x' endian = 'little' -[properties] -needs_exe_wrapper = true +[built-in options] c_args = [ '-v28', '-ml', @@ -24,3 +23,6 @@ c_link_args = [ '\f28004x_flash.cmd'] cpp_args = [] cpp_link_args = [] + +[properties] +needs_exe_wrapper = true diff --git a/cross/ccrx.txt b/cross/ccrx.txt index 097ec06..f1b536c 100644 --- a/cross/ccrx.txt +++ b/cross/ccrx.txt @@ -7,7 +7,7 @@ cpp = 'ccrx' ar = 'rlink' strip = 'rlink' -[properties] +[built-in options] # The '--cpu' option with the appropriate target type should be mentioned # to cross compile c/c++ code with ccrx,. c_args = ['-cpu=rx600'] diff --git a/cross/iphone.txt b/cross/iphone.txt index e714da5..9659407 100644 --- a/cross/iphone.txt +++ b/cross/iphone.txt @@ -8,14 +8,14 @@ cpp = 'clang++' ar = 'ar' strip = 'strip' -[properties] -root = '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer' - +[built-in options] c_args = ['-arch', 'armv7', '-miphoneos-version-min=8.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.4.sdk'] cpp_args = ['-arch', 'armv7', '-miphoneos-version-min=8.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.4.sdk'] c_link_args = ['-arch', 'armv7', '-miphoneos-version-min=8.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.4.sdk'] cpp_link_args = ['-arch', 'armv7', '-miphoneos-version-min=8.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.4.sdk'] +[properties] +root = '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer' has_function_printf = true has_function_hfkerhisadf = false diff --git a/cross/tvos.txt b/cross/tvos.txt index dd6d5c1..833f04b 100644 --- a/cross/tvos.txt +++ b/cross/tvos.txt @@ -8,14 +8,15 @@ cpp = 'clang++' ar = 'ar' strip = 'strip' -[properties] -root = '/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer' - +[built-in options] c_args = ['-arch', 'arm64', '-mtvos-version-min=12.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk'] cpp_args = ['-arch', 'arm64', '-mtvos-version-min=12.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk'] c_link_args = ['-arch', 'arm64', '-mtvos-version-min=12.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk'] cpp_link_args = ['-arch', 'arm64', '-mtvos-version-min=12.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk'] +[properties] +root = '/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer' + has_function_printf = true has_function_hfkerhisadf = false diff --git a/cross/ubuntu-armhf.txt b/cross/ubuntu-armhf.txt index 4600c22..69e0c86 100644 --- a/cross/ubuntu-armhf.txt +++ b/cross/ubuntu-armhf.txt @@ -9,12 +9,14 @@ strip = '/usr/arm-linux-gnueabihf/bin/strip' pkgconfig = '/usr/bin/arm-linux-gnueabihf-pkg-config' ld = '/usr/bin/arm-linux/gnueabihf-ld' -[properties] -root = '/usr/arm-linux-gnueabihf' +[built-in options] # Used in unit test '140 get define' c_args = ['-DMESON_TEST_ISSUE_1665=1'] cpp_args = '-DMESON_TEST_ISSUE_1665=1' +[properties] +root = '/usr/arm-linux-gnueabihf' + has_function_printf = true has_function_hfkerhisadf = false diff --git a/cross/wasm.txt b/cross/wasm.txt index a43636f..f2d0cd7 100644 --- a/cross/wasm.txt +++ b/cross/wasm.txt @@ -3,8 +3,7 @@ c = '/home/jpakkane/emsdk/fastcomp/emscripten/emcc' cpp = '/home/jpakkane/emsdk/fastcomp/emscripten/em++' ar = '/home/jpakkane/emsdk/fastcomp/emscripten/emar' -[properties] - +[built-in options] c_args = ['-s', 'WASM=1', '-s', 'EXPORT_ALL=1'] c_link_args = ['-s','EXPORT_ALL=1'] cpp_args = ['-s', 'WASM=1', '-s', 'EXPORT_ALL=1'] diff --git a/cross/xc16.txt b/cross/xc16.txt index 1e67362..c66889d 100644 --- a/cross/xc16.txt +++ b/cross/xc16.txt @@ -14,6 +14,8 @@ endian = 'little' [properties] needs_exe_wrapper = true + +[built-in options] c_args = [ '-c', '-mcpu=33EP64MC203', diff --git a/docs/markdown/Machine-files.md b/docs/markdown/Machine-files.md index ae0219b..e3de808 100644 --- a/docs/markdown/Machine-files.md +++ b/docs/markdown/Machine-files.md @@ -13,6 +13,7 @@ The following sections are allowed: - paths - properties - project options +- built-in options ### constants @@ -158,17 +159,23 @@ command line will override any options in the native file. For example, passing In addition to special data that may be specified in cross files, this section may contain random key value pairs accessed using the -`meson.get_external_property`, or `meson.get_cross_property`. +`meson.get_external_property()`, or `meson.get_cross_property()`. + +*Changed in 0.55.0* putting `_args` and `_link_args` in the +properties section has been deprecated, and should be put in the built-in +options section. ### Project specific options -*New in 0.54.0* +*New in 0.55.0* + +Path options are not allowed, those must be set in the `[paths]` section. -Being able to set project specific options in a native or cross files can be +Being able to set project specific options in a cross or native file can be done using the `[project options]` section of the specific file (if doing a cross build the options from the native file will be ignored) -For setting options in supbprojects use the `:project options` +For setting options in subprojects use the `[:project options]` section instead. ```ini @@ -179,6 +186,47 @@ build-tests = true build-tests = false ``` + +### Meson built-in options + +Meson built-in options can be set the same way: + +```ini +[built-in options] +c_std = 'c99' +``` + +You can set some meson built-in options on a per-subproject basis, such as +`default_library` and `werror`. The order of precedence is: +1) Command line +2) Machine file +3) Build system definitions + +```ini +[zlib:built-in options] +default_library = 'static' +werror = false +``` + +Options set on a per-subproject basis will inherit the +option from the parent if the parent has a setting but the subproject +doesn't, even when there is a default set meson language. + +```ini +[built-in options] +default_library = 'static' +``` + +will make subprojects use default_library as static. + +Some options can be set on a per-machine basis (in other words, the value of +the build machine can be different than the host machine in a cross compile). +In these cases the values from both a cross file and a native file are used. + +An incomplete list of options is: +- pkg_config_path +- cmake_prefix_path + ## Loading multiple machine files Native files allow layering (cross files can be layered since meson 0.52.0). diff --git a/docs/markdown/snippets/project_options_in_machine_files.md b/docs/markdown/snippets/project_options_in_machine_files.md index 78b129a..8dab951 100644 --- a/docs/markdown/snippets/project_options_in_machine_files.md +++ b/docs/markdown/snippets/project_options_in_machine_files.md @@ -1,4 +1,4 @@ -## Project options can be set in native or cross files +## Project and built-in options can be set in native or cross files A new set of sections has been added to the cross and native files, `[project options]` and `[:project options]`, where `subproject_name` @@ -35,3 +35,18 @@ Subproject options are assigned like this: [zlib:project options] foo = 'some val' ``` + +Additionally meson level options can be set in the same way, using the +`[built-in options]` section. + +```ini +[built-in options] +c_std = 'c99' +``` + +These options can also be set on a per-subproject basis, although only +`default_library` and `werror` can currently be set: +```ini +[zlib:built-in options] +default_library = 'static' +``` diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 3330ae5..0cac029 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -361,15 +361,15 @@ class CoreData: self.install_guid = str(uuid.uuid4()).upper() self.target_guids = {} self.version = version - self.builtins = {} # : OptionDictType + self.builtins = {} # type: OptionDictType self.builtins_per_machine = PerMachine({}, {}) - self.backend_options = {} # : OptionDictType - self.user_options = {} # : OptionDictType + self.backend_options = {} # type: OptionDictType + self.user_options = {} # type: OptionDictType self.compiler_options = PerMachine( defaultdict(dict), defaultdict(dict), ) # : PerMachine[T.defaultdict[str, OptionDictType]] - self.base_options = {} # : OptionDictType + self.base_options = {} # type: OptionDictType self.cross_files = self.__load_config_files(options, scratch_dir, 'cross') self.compilers = PerMachine(OrderedDict(), OrderedDict()) @@ -743,19 +743,28 @@ class CoreData: mlog.warning('Recommend using either -Dbuildtype or -Doptimization + -Ddebug. ' 'Using both is redundant since they override each other. ' 'See: https://mesonbuild.com/Builtin-options.html#build-type-options') + cmd_line_options = OrderedDict() - # Set project default_options as if they were passed to the cmdline. + # Set default options as if they were passed to the command line. # Subprojects can only define default for user options and not yielding # builtin option. from . import optinterpreter - for k, v in default_options.items(): + for k, v in chain(default_options.items(), env.meson_options.host.get('', {}).items()): if subproject: if (k not in builtin_options or builtin_options[k].yielding) \ and optinterpreter.is_invalid_name(k, log=False): continue - k = subproject + ':' + k cmd_line_options[k] = v + # IF the subproject options comes from a machine file, then we need to + # set the option as subproject:option + if subproject: + for k, v in env.meson_options.host.get(subproject, {}).items(): + if (k not in builtin_options or builtin_options[k].yielding) \ + and optinterpreter.is_invalid_name(k, log=False): + continue + cmd_line_options['{}:{}'.format(subproject, k)] = v + # load the values for user options out of the appropriate machine file, # then overload the command line for k, v in env.user_options.get(subproject, {}).items(): @@ -768,8 +777,32 @@ class CoreData: if v is not None: cmd_line_options[k] = v + from .compilers import all_languages + # Report that [properties]c_args + for lang in all_languages: + for args in ['{}_args'.format(lang), '{}_link_args'.format(lang)]: + msg = ('{} in the [properties] section of the machine file is deprecated, ' + 'use the [built-in options] section.') + if args in env.properties.host or args in env.properties.build: + mlog.deprecation(msg.format(args)) + + # Currently we don't support any options that are both per-subproject + # and per-machine, but when we do this will need to account for that. + # For cross builds we need to get the build specifc options + if env.meson_options.host != env.meson_options.build and subproject in env.meson_options.build: + for k in builtin_options_per_machine.keys(): + if k in env.meson_options.build[subproject]: + cmd_line_options['build.{}'.format(k)] = env.meson_options.build[subproject][k] + + # compiler options are always per-machine + for lang in all_languages: + prefix = '{}_'.format(lang) + for k in env.meson_options.build[subproject]: + if k.startswith(prefix): + cmd_line_options['build.{}'.format(k)] = env.meson_options.build[subproject][k] + # Override all the above defaults using the command-line arguments - # actually passed to us + # actually passed to use cmd_line_options.update(env.cmd_line_options) env.cmd_line_options = cmd_line_options diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index c872aee..dc674fd 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -556,6 +556,9 @@ class Environment: # We only need one of these as project options are not per machine user_options = {} + # meson builtin options, as passed through cross or native files + meson_options = PerMachineDefaultable() + ## Setup build machine defaults # Will be fully initialized later using compilers later. @@ -568,14 +571,15 @@ class Environment: ## Read in native file(s) to override build machine configuration - def load_user_options(): + def load_options(tag: str, store: T.Dict[str, T.Any]) -> None: for section in config.keys(): - if section.endswith('project options'): + if section.endswith(tag): if ':' in section: project = section.split(':')[0] else: project = '' - user_options[project] = config.get(section, {}) + store[project] = config.get(section, {}) + if self.coredata.config_files is not None: config = coredata.parse_machine_files(self.coredata.config_files) @@ -586,7 +590,9 @@ class Environment: # Don't run this if there are any cross files, we don't want to use # the native values if we're doing a cross build if not self.coredata.cross_files: - load_user_options() + load_options('project options', user_options) + meson_options.build = {} + load_options('built-in options', meson_options.build) ## Read in cross file(s) to override host machine configuration @@ -599,7 +605,9 @@ class Environment: if 'target_machine' in config: machines.target = MachineInfo.from_literal(config['target_machine']) paths.host = Directories(**config.get('paths', {})) - load_user_options() + load_options('project options', user_options) + meson_options.host = {} + load_options('built-in options', meson_options.host) ## "freeze" now initialized configuration, and "save" to the class. @@ -608,6 +616,16 @@ class Environment: self.properties = properties.default_missing() self.paths = paths.default_missing() self.user_options = user_options + self.meson_options = meson_options.default_missing() + + # Ensure that no paths are passed via built-in options: + if '' in self.meson_options.host: + for each in coredata.BUILTIN_DIR_OPTIONS.keys(): + # These are not per-subdirectory and probably never will be + if each in self.meson_options.host['']: + raise EnvironmentException( + 'Invalid entry {} in [built-in options] section. ' + 'Use the [paths] section instead.'.format(each)) exe_wrapper = self.lookup_binary_entry(MachineChoice.HOST, 'exe_wrapper') if exe_wrapper is not None: diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index 45813c1..317793d 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -2791,6 +2791,7 @@ external dependencies (including libraries) must go to "dependencies".''') default_options = mesonlib.stringlistify(kwargs.get('default_options', [])) default_options = coredata.create_options_dict(default_options) + if dirname == '': raise InterpreterException('Subproject dir name must not be empty.') if dirname[0] == '.': diff --git a/run_unittests.py b/run_unittests.py index 9d96ce0..bce0bda 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -7672,8 +7672,10 @@ class NativeFileTests(BasePlatformTests): for section, entries in values.items(): f.write('[{}]\n'.format(section)) for k, v in entries.items(): - if isinstance(v, bool): + if isinstance(v, (bool, int, float)): f.write("{}={}\n".format(k, v)) + elif isinstance(v, list): + f.write("{}=[{}]\n".format(k, ', '.join(["'{}'".format(w) for w in v]))) else: f.write("{}='{}'\n".format(k, v)) return filename @@ -8047,6 +8049,108 @@ class NativeFileTests(BasePlatformTests): else: self.fail('Did not find werror in build options?') + def test_option_integer(self): + # Bools are allowed to be unquoted + testcase = os.path.join(self.common_test_dir, '1 trivial') + config = self.helper_create_native_file({'built-in options': {'unity_size': 100}}) + self.init(testcase, extra_args=['--native-file', config]) + configuration = self.introspect('--buildoptions') + for each in configuration: + # Test that no-per subproject options are inherited from the parent + if 'unity_size' in each['name']: + self.assertEqual(each['value'], 100) + break + else: + self.fail('Did not find unity_size in build options?') + + def test_builtin_options(self): + testcase = os.path.join(self.common_test_dir, '2 cpp') + config = self.helper_create_native_file({'built-in options': {'cpp_std': 'c++14'}}) + + self.init(testcase, extra_args=['--native-file', config]) + configuration = self.introspect('--buildoptions') + for each in configuration: + if each['name'] == 'cpp_std': + self.assertEqual(each['value'], 'c++14') + break + else: + self.fail('Did not find werror in build options?') + + def test_builtin_options_subprojects(self): + testcase = os.path.join(self.common_test_dir, '102 subproject subdir') + config = self.helper_create_native_file({'built-in options': {'default_library': 'both', 'c_args': ['-Dfoo']}, 'sub:built-in options': {'default_library': 'static'}}) + + self.init(testcase, extra_args=['--native-file', config]) + configuration = self.introspect('--buildoptions') + found = 0 + for each in configuration: + # Test that no-per subproject options are inherited from the parent + if 'c_args' in each['name']: + # This path will be hit twice, once for build and once for host, + self.assertEqual(each['value'], ['-Dfoo']) + found += 1 + elif each['name'] == 'default_library': + self.assertEqual(each['value'], 'both') + found += 1 + elif each['name'] == 'sub:default_library': + self.assertEqual(each['value'], 'static') + found += 1 + self.assertEqual(found, 4, 'Did not find all three sections') + + def test_builtin_options_subprojects_overrides_buildfiles(self): + # If the buildfile says subproject(... default_library: shared), ensure that's overwritten + testcase = os.path.join(self.common_test_dir, '230 persubproject options') + config = self.helper_create_native_file({'sub2:built-in options': {'default_library': 'shared'}}) + + with self.assertRaises(subprocess.CalledProcessError) as cm: + self.init(testcase, extra_args=['--native-file', config]) + self.assertIn(cm.exception.stdout, 'Parent should override default_library') + + def test_builtin_options_subprojects_inherits_parent_override(self): + # If the buildfile says subproject(... default_library: shared), ensure that's overwritten + testcase = os.path.join(self.common_test_dir, '230 persubproject options') + config = self.helper_create_native_file({'built-in options': {'default_library': 'both'}}) + + with self.assertRaises(subprocess.CalledProcessError) as cm: + self.init(testcase, extra_args=['--native-file', config]) + self.assertIn(cm.exception.stdout, 'Parent should override default_library') + + def test_builtin_options_compiler_properties(self): + # the properties section can have lang_args, and those need to be + # overwritten by the built-in options + testcase = os.path.join(self.common_test_dir, '1 trivial') + config = self.helper_create_native_file({ + 'built-in options': {'c_args': ['-DFOO']}, + 'properties': {'c_args': ['-DBAR']}, + }) + + self.init(testcase, extra_args=['--native-file', config]) + configuration = self.introspect('--buildoptions') + for each in configuration: + if each['name'] == 'c_args': + self.assertEqual(each['value'], ['-DFOO']) + break + else: + self.fail('Did not find c_args in build options?') + + def test_builtin_options_compiler_properties_legacy(self): + # The legacy placement in properties is still valid if a 'built-in + # options' setting is present, but doesn't have the lang_args + testcase = os.path.join(self.common_test_dir, '1 trivial') + config = self.helper_create_native_file({ + 'built-in options': {'default_library': 'static'}, + 'properties': {'c_args': ['-DBAR']}, + }) + + self.init(testcase, extra_args=['--native-file', config]) + configuration = self.introspect('--buildoptions') + for each in configuration: + if each['name'] == 'c_args': + self.assertEqual(each['value'], ['-DBAR']) + break + else: + self.fail('Did not find c_args in build options?') + class CrossFileTests(BasePlatformTests): @@ -8266,9 +8370,54 @@ class CrossFileTests(BasePlatformTests): testcase = os.path.join(self.common_test_dir, '43 options') config = self.helper_create_cross_file({'project options': {'testoption': 'some other value'}}) with self.assertRaises(subprocess.CalledProcessError) as cm: - self.init(testcase, extra_args=['--native-file', config]) + self.init(testcase, extra_args=['--cross-file', config]) self.assertRegex(cm.exception.stdout, r'Incorrect value to [a-z]+ option') + def test_builtin_options(self): + testcase = os.path.join(self.common_test_dir, '2 cpp') + config = self.helper_create_cross_file({'built-in options': {'cpp_std': 'c++14'}}) + + self.init(testcase, extra_args=['--cross-file', config]) + configuration = self.introspect('--buildoptions') + for each in configuration: + if each['name'] == 'cpp_std': + self.assertEqual(each['value'], 'c++14') + break + else: + self.fail('No c++ standard set?') + + def test_builtin_options_per_machine(self): + """Test options that are allowed to be set on a per-machine basis. + + Such options could be passed twice, once for the build machine, and + once for the host machine. I've picked pkg-config path, but any would + do that can be set for both. + """ + testcase = os.path.join(self.common_test_dir, '2 cpp') + cross = self.helper_create_cross_file({'built-in options': {'pkg_config_path': '/cross/path', 'cpp_std': 'c++17'}}) + native = self.helper_create_cross_file({'built-in options': {'pkg_config_path': '/native/path', 'cpp_std': 'c++14'}}) + + self.init(testcase, extra_args=['--cross-file', cross, '--native-file', native]) + configuration = self.introspect('--buildoptions') + found = 0 + for each in configuration: + if each['name'] == 'pkg_config_path': + self.assertEqual(each['value'], ['/cross/path']) + found += 1 + elif each['name'] == 'cpp_std': + self.assertEqual(each['value'], 'c++17') + found += 1 + elif each['name'] == 'build.pkg_config_path': + self.assertEqual(each['value'], ['/native/path']) + found += 1 + elif each['name'] == 'build.cpp_std': + self.assertEqual(each['value'], 'c++14') + found += 1 + + if found == 4: + break + self.assertEqual(found, 4, 'Did not find all sections.') + class TAPParserTests(unittest.TestCase): def assert_test(self, events, **kwargs): -- cgit v1.1 From 17c8193615e5fafbbfcf99b1d028f5da36d79cc4 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Tue, 16 Jun 2020 11:11:15 -0700 Subject: machine-files: give better error messages about using integers --- mesonbuild/coredata.py | 12 +++++++++--- test cases/failing/106 number in combo/meson.build | 1 + test cases/failing/106 number in combo/nativefile.ini | 2 ++ test cases/failing/106 number in combo/test.json | 5 +++++ test cases/failing/107 bool in combo/meson.build | 1 + test cases/failing/107 bool in combo/meson_options.txt | 5 +++++ test cases/failing/107 bool in combo/nativefile.ini | 2 ++ test cases/failing/107 bool in combo/test.json | 5 +++++ 8 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 test cases/failing/106 number in combo/meson.build create mode 100644 test cases/failing/106 number in combo/nativefile.ini create mode 100644 test cases/failing/106 number in combo/test.json create mode 100644 test cases/failing/107 bool in combo/meson.build create mode 100644 test cases/failing/107 bool in combo/meson_options.txt create mode 100644 test cases/failing/107 bool in combo/nativefile.ini create mode 100644 test cases/failing/107 bool in combo/test.json diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 0cac029..b7efe30 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -161,10 +161,16 @@ class UserComboOption(UserOption[str]): def validate_value(self, value): if value not in self.choices: + if isinstance(value, bool): + _type = 'boolean' + elif isinstance(value, (int, float)): + _type = 'number' + else: + _type = 'string' optionsstring = ', '.join(['"%s"' % (item,) for item in self.choices]) - raise MesonException('Value "{}" for combo option "{}" is not one of the choices.' - ' Possible choices are: {}.'.format( - value, self.description, optionsstring)) + raise MesonException('Value "{}" (of type "{}") for combo option "{}" is not one of the choices.' + ' Possible choices are (as string): {}.'.format( + value, _type, self.description, optionsstring)) return value class UserArrayOption(UserOption[T.List[str]]): diff --git a/test cases/failing/106 number in combo/meson.build b/test cases/failing/106 number in combo/meson.build new file mode 100644 index 0000000..1a647df --- /dev/null +++ b/test cases/failing/106 number in combo/meson.build @@ -0,0 +1 @@ +project('number in combo') diff --git a/test cases/failing/106 number in combo/nativefile.ini b/test cases/failing/106 number in combo/nativefile.ini new file mode 100644 index 0000000..55f10fc --- /dev/null +++ b/test cases/failing/106 number in combo/nativefile.ini @@ -0,0 +1,2 @@ +[built-in options] +optimization = 1 diff --git a/test cases/failing/106 number in combo/test.json b/test cases/failing/106 number in combo/test.json new file mode 100644 index 0000000..a32c358 --- /dev/null +++ b/test cases/failing/106 number in combo/test.json @@ -0,0 +1,5 @@ +{ + "stdout": [ + { "line": "test cases/failing/106 number in combo/meson.build:1:0: ERROR: Value \"1\" (of type \"number\") for combo option \"Optimization level\" is not one of the choices. Possible choices are (as string): \"0\", \"g\", \"1\", \"2\", \"3\", \"s\"." } + ] +} diff --git a/test cases/failing/107 bool in combo/meson.build b/test cases/failing/107 bool in combo/meson.build new file mode 100644 index 0000000..c5efd67 --- /dev/null +++ b/test cases/failing/107 bool in combo/meson.build @@ -0,0 +1 @@ +project('bool in combo') diff --git a/test cases/failing/107 bool in combo/meson_options.txt b/test cases/failing/107 bool in combo/meson_options.txt new file mode 100644 index 0000000..0c8f5de --- /dev/null +++ b/test cases/failing/107 bool in combo/meson_options.txt @@ -0,0 +1,5 @@ +option( + 'opt', + type : 'combo', + choices : ['true', 'false'] +) diff --git a/test cases/failing/107 bool in combo/nativefile.ini b/test cases/failing/107 bool in combo/nativefile.ini new file mode 100644 index 0000000..b423957 --- /dev/null +++ b/test cases/failing/107 bool in combo/nativefile.ini @@ -0,0 +1,2 @@ +[project options] +opt = true diff --git a/test cases/failing/107 bool in combo/test.json b/test cases/failing/107 bool in combo/test.json new file mode 100644 index 0000000..37218e8 --- /dev/null +++ b/test cases/failing/107 bool in combo/test.json @@ -0,0 +1,5 @@ +{ + "stdout": [ + { "line": "test cases/failing/107 bool in combo/meson.build:1:0: ERROR: Value \"True\" (of type \"boolean\") for combo option \"opt\" is not one of the choices. Possible choices are (as string): \"true\", \"false\"." } + ] +} -- cgit v1.1 From 1ca17dc853ece6225a46b46330e436d46d74bc4b Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Wed, 10 Jun 2020 13:02:30 -0700 Subject: docs/machine-files: Add a section on data types This attempts to clarify the usage of strings and arrays, as well as document the boolean type that has been exposed via the project and built-in options --- docs/markdown/Machine-files.md | 48 +++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/docs/markdown/Machine-files.md b/docs/markdown/Machine-files.md index e3de808..9affdca 100644 --- a/docs/markdown/Machine-files.md +++ b/docs/markdown/Machine-files.md @@ -5,6 +5,37 @@ documentation on the common values used by both, for the specific values of one or the other see the [cross compilation](Cross-compilation.md) and [native environments](Native-environments.md). +## Data Types + +There are four basic data types in a machine file: +- strings +- arrays +- booleans +- integers + +A string is specified single quoted: +```ini +[section] +option1 = 'false' +option2 = '2' +``` + +An array is enclosed in square brackets, and must consist of strings or booleans +```ini +[section] +option = ['value'] +``` + +A boolean must be either `true` or `false`, and unquoted. +```ini +option = false +``` + +An integer must be either an unquoted numeric constant; +```ini +option = 42 +``` + ## Sections The following sections are allowed: @@ -90,14 +121,16 @@ a = 'Hello' ### Binaries The binaries section contains a list of binaries. These can be used -internally by meson, or by the `find_program` function: +internally by meson, or by the `find_program` function. + +These values must be either strings or an array of strings Compilers and linkers are defined here using `` and `_ld`. `_ld` is special because it is compiler specific. For compilers like gcc and clang which are used to invoke the linker this is a value to pass to their "choose the linker" argument (-fuse-ld= in this case). For compilers like MSVC and Clang-Cl, this is the path to a linker for meson to invoke, -such as `link.exe` or `lld-link.exe`. Support for ls is *new in 0.53.0* +such as `link.exe` or `lld-link.exe`. Support for `ld` is *new in 0.53.0* *changed in 0.53.1* the `ld` variable was replaced by `_ld`, because it *regressed a large number of projects. in 0.53.0 the `ld` variable was used @@ -115,8 +148,8 @@ llvm-config = '/usr/lib/llvm8/bin/llvm-config' Cross example: ```ini -c = '/usr/bin/i586-mingw32msvc-gcc' -cpp = '/usr/bin/i586-mingw32msvc-g++' +c = ['ccache', '/usr/bin/i586-mingw32msvc-gcc'] +cpp = ['ccache', '/usr/bin/i586-mingw32msvc-g++'] c_ld = 'gold' cpp_ld = 'gold' ar = '/usr/i586-mingw32msvc/bin/ar' @@ -140,7 +173,7 @@ An incomplete list of internally used programs that can be overridden here is: ### Paths and Directories As of 0.50.0 paths and directories such as libdir can be defined in the native -file in a paths section +and cross files in a paths section. These should be strings ```ini [paths] @@ -186,7 +219,6 @@ build-tests = true build-tests = false ``` - ### Meson built-in options Meson built-in options can be set the same way: @@ -230,9 +262,9 @@ An incomplete list of options is: ## Loading multiple machine files Native files allow layering (cross files can be layered since meson 0.52.0). -More than one native file can be loaded, with values from a previous file being +More than one file can be loaded, with values from a previous file being overridden by the next. The intention of this is not overriding, but to allow -composing native files. This composition is done by passing the command line +composing files. This composition is done by passing the command line argument multiple times: ```console -- cgit v1.1 From e981798e0b5ccb53cdb94a616c9bccc20f091e6b Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Tue, 16 Jun 2020 11:33:02 -0700 Subject: coredata: fix type annotation --- mesonbuild/coredata.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index b7efe30..e3b6dab 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -374,7 +374,7 @@ class CoreData: self.compiler_options = PerMachine( defaultdict(dict), defaultdict(dict), - ) # : PerMachine[T.defaultdict[str, OptionDictType]] + ) # type: PerMachine[T.defaultdict[str, OptionDictType]] self.base_options = {} # type: OptionDictType self.cross_files = self.__load_config_files(options, scratch_dir, 'cross') self.compilers = PerMachine(OrderedDict(), OrderedDict()) -- cgit v1.1 From 601789cc7ce3692fbefe14047d8b8cc68a3d5160 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Tue, 16 Jun 2020 15:23:15 -0700 Subject: machine-files: deprecate the paths section --- docs/markdown/Machine-files.md | 4 +++- mesonbuild/coredata.py | 5 ----- mesonbuild/envconfig.py | 40 ---------------------------------------- mesonbuild/environment.py | 26 +++++++------------------- run_unittests.py | 34 ++++++++++++++++++++++++++++++++++ 5 files changed, 44 insertions(+), 65 deletions(-) diff --git a/docs/markdown/Machine-files.md b/docs/markdown/Machine-files.md index 9affdca..60c4dd5 100644 --- a/docs/markdown/Machine-files.md +++ b/docs/markdown/Machine-files.md @@ -172,8 +172,10 @@ An incomplete list of internally used programs that can be overridden here is: ### Paths and Directories +*Deprecated in 0.55.0* use the built-in section instead. + As of 0.50.0 paths and directories such as libdir can be defined in the native -and cross files in a paths section. These should be strings +and cross files in a paths section. These should be strings. ```ini [paths] diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index e3b6dab..99da034 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -778,11 +778,6 @@ class CoreData: k = '{}:{}'.format(subproject, k) cmd_line_options[k] = v - # Override project default_options using conf files (cross or native) - for k, v in env.paths.host: - if v is not None: - cmd_line_options[k] = v - from .compilers import all_languages # Report that [properties]c_args for lang in all_languages: diff --git a/mesonbuild/envconfig.py b/mesonbuild/envconfig.py index 219b62e..9402d38 100644 --- a/mesonbuild/envconfig.py +++ b/mesonbuild/envconfig.py @@ -407,43 +407,3 @@ class BinaryTable: if command is not None and (len(command) == 0 or len(command[0].strip()) == 0): command = None return command - -class Directories: - - """Data class that holds information about directories for native and cross - builds. - """ - - def __init__(self, bindir: T.Optional[str] = None, datadir: T.Optional[str] = None, - includedir: T.Optional[str] = None, infodir: T.Optional[str] = None, - libdir: T.Optional[str] = None, libexecdir: T.Optional[str] = None, - localedir: T.Optional[str] = None, localstatedir: T.Optional[str] = None, - mandir: T.Optional[str] = None, prefix: T.Optional[str] = None, - sbindir: T.Optional[str] = None, sharedstatedir: T.Optional[str] = None, - sysconfdir: T.Optional[str] = None): - self.bindir = bindir - self.datadir = datadir - self.includedir = includedir - self.infodir = infodir - self.libdir = libdir - self.libexecdir = libexecdir - self.localedir = localedir - self.localstatedir = localstatedir - self.mandir = mandir - self.prefix = prefix - self.sbindir = sbindir - self.sharedstatedir = sharedstatedir - self.sysconfdir = sysconfdir - - def __contains__(self, key: str) -> bool: - return hasattr(self, key) - - def __getitem__(self, key: str) -> T.Optional[str]: - # Mypy can't figure out what to do with getattr here, so we'll case for it - return T.cast(T.Optional[str], getattr(self, key)) - - def __setitem__(self, key: str, value: T.Optional[str]) -> None: - setattr(self, key, value) - - def __iter__(self) -> T.Iterator[T.Tuple[str, str]]: - return iter(self.__dict__.items()) diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index dc674fd..7dfffa2 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -27,7 +27,7 @@ from .mesonlib import ( from . import mlog from .envconfig import ( - BinaryTable, Directories, MachineInfo, + BinaryTable, MachineInfo, Properties, known_cpu_families, ) from . import compilers @@ -548,11 +548,6 @@ class Environment: # Misc other properties about each machine. properties = PerMachineDefaultable() - # Store paths for native and cross build files. There is no target - # machine information here because nothing is installed for the target - # architecture, just the build and host architectures - paths = PerMachineDefaultable() - # We only need one of these as project options are not per machine user_options = {} @@ -580,11 +575,9 @@ class Environment: project = '' store[project] = config.get(section, {}) - if self.coredata.config_files is not None: config = coredata.parse_machine_files(self.coredata.config_files) binaries.build = BinaryTable(config.get('binaries', {})) - paths.build = Directories(**config.get('paths', {})) properties.build = Properties(config.get('properties', {})) # Don't run this if there are any cross files, we don't want to use @@ -592,6 +585,9 @@ class Environment: if not self.coredata.cross_files: load_options('project options', user_options) meson_options.build = {} + if config.get('paths') is not None: + mlog.deprecation('The [paths] section is deprecated, use the [built-in options] section instead.') + load_options('paths', meson_options.build) load_options('built-in options', meson_options.build) ## Read in cross file(s) to override host machine configuration @@ -604,9 +600,11 @@ class Environment: machines.host = MachineInfo.from_literal(config['host_machine']) if 'target_machine' in config: machines.target = MachineInfo.from_literal(config['target_machine']) - paths.host = Directories(**config.get('paths', {})) load_options('project options', user_options) meson_options.host = {} + if config.get('paths') is not None: + mlog.deprecation('The [paths] section is deprecated, use the [built-in options] section instead.') + load_options('paths', meson_options.host) load_options('built-in options', meson_options.host) ## "freeze" now initialized configuration, and "save" to the class. @@ -614,19 +612,9 @@ class Environment: self.machines = machines.default_missing() self.binaries = binaries.default_missing() self.properties = properties.default_missing() - self.paths = paths.default_missing() self.user_options = user_options self.meson_options = meson_options.default_missing() - # Ensure that no paths are passed via built-in options: - if '' in self.meson_options.host: - for each in coredata.BUILTIN_DIR_OPTIONS.keys(): - # These are not per-subdirectory and probably never will be - if each in self.meson_options.host['']: - raise EnvironmentException( - 'Invalid entry {} in [built-in options] section. ' - 'Use the [paths] section instead.'.format(each)) - exe_wrapper = self.lookup_binary_entry(MachineChoice.HOST, 'exe_wrapper') if exe_wrapper is not None: from .dependencies import ExternalProgram diff --git a/run_unittests.py b/run_unittests.py index bce0bda..7bab408 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -8151,6 +8151,40 @@ class NativeFileTests(BasePlatformTests): else: self.fail('Did not find c_args in build options?') + def test_builtin_options_paths(self): + # the properties section can have lang_args, and those need to be + # overwritten by the built-in options + testcase = os.path.join(self.common_test_dir, '1 trivial') + config = self.helper_create_native_file({ + 'built-in options': {'bindir': 'foo'}, + 'paths': {'bindir': 'bar'}, + }) + + self.init(testcase, extra_args=['--native-file', config]) + configuration = self.introspect('--buildoptions') + for each in configuration: + if each['name'] == 'bindir': + self.assertEqual(each['value'], 'foo') + break + else: + self.fail('Did not find bindir in build options?') + + def test_builtin_options_paths_legacy(self): + testcase = os.path.join(self.common_test_dir, '1 trivial') + config = self.helper_create_native_file({ + 'built-in options': {'default_library': 'static'}, + 'paths': {'bindir': 'bar'}, + }) + + self.init(testcase, extra_args=['--native-file', config]) + configuration = self.introspect('--buildoptions') + for each in configuration: + if each['name'] == 'bindir': + self.assertEqual(each['value'], 'bar') + break + else: + self.fail('Did not find bindir in build options?') + class CrossFileTests(BasePlatformTests): -- cgit v1.1 From 5358765806909de8a7179c7becb3ee6ae1a54215 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 19 Jun 2020 21:13:35 -0700 Subject: mesonlib: Add repr() methods to PerMachine classes Which is super helpful in debuggers --- mesonbuild/mesonlib.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py index a43d4c4..2c563e4 100644 --- a/mesonbuild/mesonlib.py +++ b/mesonbuild/mesonlib.py @@ -389,6 +389,9 @@ class PerMachine(T.Generic[_T]): unfreeze.host = None return unfreeze + def __repr__(self) -> str: + return 'PerMachine({!r}, {!r})'.format(self.build, self.host) + class PerThreeMachine(PerMachine[_T]): """Like `PerMachine` but includes `target` too. @@ -421,6 +424,9 @@ class PerThreeMachine(PerMachine[_T]): def matches_build_machine(self, machine: MachineChoice) -> bool: return self.build == self[machine] + def __repr__(self) -> str: + return 'PerThreeMachine({!r}, {!r}, {!r})'.format(self.build, self.host, self.target) + class PerMachineDefaultable(PerMachine[T.Optional[_T]]): """Extends `PerMachine` with the ability to default from `None`s. @@ -439,6 +445,9 @@ class PerMachineDefaultable(PerMachine[T.Optional[_T]]): freeze.host = freeze.build return freeze + def __repr__(self) -> str: + return 'PerMachineDefaultable({!r}, {!r})'.format(self.build, self.host) + class PerThreeMachineDefaultable(PerMachineDefaultable, PerThreeMachine[T.Optional[_T]]): """Extends `PerThreeMachine` with the ability to default from `None`s. @@ -460,6 +469,9 @@ class PerThreeMachineDefaultable(PerMachineDefaultable, PerThreeMachine[T.Option freeze.target = freeze.host return freeze + def __repr__(self) -> str: + return 'PerThreeMachineDefaultable({!r}, {!r}, {!r})'.format(self.build, self.host, self.target) + def is_sunos() -> bool: return platform.system().lower() == 'sunos' -- cgit v1.1 From 5db3860abf6a27b0dd4653fa8c7143f4a70df7a7 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 19 Jun 2020 10:53:20 -0700 Subject: push all config-file settings into coredata.set_default_options This puts all of them together, in the next patch they'll be pulled back out, but it's convenient to start that refactor by moving them all there, then moving them into env as a whole. --- mesonbuild/coredata.py | 69 +++++++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 37 deletions(-) diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 99da034..aaf31aa 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -751,34 +751,44 @@ class CoreData: 'See: https://mesonbuild.com/Builtin-options.html#build-type-options') cmd_line_options = OrderedDict() - # Set default options as if they were passed to the command line. - # Subprojects can only define default for user options and not yielding - # builtin option. - from . import optinterpreter - for k, v in chain(default_options.items(), env.meson_options.host.get('', {}).items()): - if subproject: - if (k not in builtin_options or builtin_options[k].yielding) \ - and optinterpreter.is_invalid_name(k, log=False): - continue - cmd_line_options[k] = v - # IF the subproject options comes from a machine file, then we need to - # set the option as subproject:option - if subproject: - for k, v in env.meson_options.host.get(subproject, {}).items(): + from . import optinterpreter + from .compilers import all_languages + if not subproject: + # Set default options as if they were passed to the command line. + # Subprojects can only define default for user options and not yielding + # builtin option. + for k, v in chain(default_options.items(), env.meson_options.host.get('', {}).items()): + cmd_line_options[k] = v + + # compiler options are always per-machine, but not per sub-project + if '' in env.meson_options.build: + for lang in all_languages: + prefix = '{}_'.format(lang) + for k in env.meson_options.build['']: + if k.startswith(prefix): + cmd_line_options['build.{}'.format(k)] = env.meson_options.build[subproject][k] + else: + # If the subproject options comes from a machine file, then we need to + # set the option as subproject:option + for k, v in chain(default_options.items(), env.meson_options.host.get('', {}).items(), + env.meson_options.host.get(subproject, {}).items()): if (k not in builtin_options or builtin_options[k].yielding) \ and optinterpreter.is_invalid_name(k, log=False): continue cmd_line_options['{}:{}'.format(subproject, k)] = v + cmd_line_options.update(env.cmd_line_options) + env.cmd_line_options = cmd_line_options + + options = OrderedDict() # load the values for user options out of the appropriate machine file, # then overload the command line for k, v in env.user_options.get(subproject, {}).items(): if subproject: k = '{}:{}'.format(subproject, k) - cmd_line_options[k] = v + options[k] = v - from .compilers import all_languages # Report that [properties]c_args for lang in all_languages: for args in ['{}_args'.format(lang), '{}_link_args'.format(lang)]: @@ -791,28 +801,13 @@ class CoreData: # and per-machine, but when we do this will need to account for that. # For cross builds we need to get the build specifc options if env.meson_options.host != env.meson_options.build and subproject in env.meson_options.build: + if subproject: + template = '{s}:build.{k}' + else: + template = 'build.{k}' for k in builtin_options_per_machine.keys(): if k in env.meson_options.build[subproject]: - cmd_line_options['build.{}'.format(k)] = env.meson_options.build[subproject][k] - - # compiler options are always per-machine - for lang in all_languages: - prefix = '{}_'.format(lang) - for k in env.meson_options.build[subproject]: - if k.startswith(prefix): - cmd_line_options['build.{}'.format(k)] = env.meson_options.build[subproject][k] - - # Override all the above defaults using the command-line arguments - # actually passed to use - cmd_line_options.update(env.cmd_line_options) - env.cmd_line_options = cmd_line_options - - # Create a subset of cmd_line_options, keeping only options for this - # subproject. Also take builtin options if it's the main project. - # Language and backend specific options will be set later when adding - # languages and setting the backend (builtin options must be set first - # to know which backend we'll use). - options = OrderedDict() + options[template.format(s=subproject, k=k)] = env.meson_options.build[subproject][k] # Some options default to environment variables if they are # unset, set those now. These will either be overwritten @@ -846,7 +841,7 @@ class CoreData: return text[len(prefix):] return text - for k, v in env.cmd_line_options.items(): + for k, v in cmd_line_options.items(): if subproject: if not k.startswith(subproject + ':'): continue -- cgit v1.1 From 591e6e94b9fccfc49ee7093cb21735a27fd64005 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 19 Jun 2020 17:01:10 -0700 Subject: Put machine file and cmd line parsing in Environment This creates a full set of option in environment that mirror those in coredata, this mirroring of the coredata structure is convenient because lookups int env (such as when initializing compilers) becomes a straight dict lookup, with no list iteration. It also means that all of the command line and machine files are read and stored in the correct order before they're ever accessed, simplifying the logic of using them. --- mesonbuild/ast/introspection.py | 2 +- mesonbuild/coredata.py | 172 ++++++++++++---------------------------- mesonbuild/environment.py | 130 ++++++++++++++++++++++++++++-- mesonbuild/interpreter.py | 8 +- run_unittests.py | 61 +++++++++++++- 5 files changed, 238 insertions(+), 135 deletions(-) diff --git a/mesonbuild/ast/introspection.py b/mesonbuild/ast/introspection.py index 142c219..6e6927f 100644 --- a/mesonbuild/ast/introspection.py +++ b/mesonbuild/ast/introspection.py @@ -120,7 +120,7 @@ class IntrospectionInterpreter(AstInterpreter): self.do_subproject(i) self.coredata.init_backend_options(self.backend) - options = {k: v for k, v in self.environment.cmd_line_options.items() if k.startswith('backend_')} + options = {k: v for k, v in self.environment.meson_options.host[''].items() if k.startswith('backend_')} self.coredata.set_options(options) self.func_add_languages(None, proj_langs, None) diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index aaf31aa..724e111 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -20,10 +20,8 @@ from pathlib import PurePath from collections import OrderedDict, defaultdict from .mesonlib import ( MesonException, EnvironmentException, MachineChoice, PerMachine, - OrderedSet, default_libdir, default_libexecdir, default_prefix, - split_args + default_libdir, default_libexecdir, default_prefix, split_args ) -from .envconfig import get_env_var_pair from .wrap import WrapMode import ast import argparse @@ -741,117 +739,54 @@ class CoreData: if not self.is_cross_build(): self.copy_build_options_from_regular_ones() - def set_default_options(self, default_options: T.Mapping[str, str], subproject: str, env: 'Environment') -> None: - # Warn if the user is using two different ways of setting build-type - # options that override each other - if 'buildtype' in env.cmd_line_options and \ - ('optimization' in env.cmd_line_options or 'debug' in env.cmd_line_options): - mlog.warning('Recommend using either -Dbuildtype or -Doptimization + -Ddebug. ' - 'Using both is redundant since they override each other. ' - 'See: https://mesonbuild.com/Builtin-options.html#build-type-options') - - cmd_line_options = OrderedDict() - - from . import optinterpreter - from .compilers import all_languages - if not subproject: - # Set default options as if they were passed to the command line. - # Subprojects can only define default for user options and not yielding - # builtin option. - for k, v in chain(default_options.items(), env.meson_options.host.get('', {}).items()): - cmd_line_options[k] = v - - # compiler options are always per-machine, but not per sub-project - if '' in env.meson_options.build: - for lang in all_languages: - prefix = '{}_'.format(lang) - for k in env.meson_options.build['']: - if k.startswith(prefix): - cmd_line_options['build.{}'.format(k)] = env.meson_options.build[subproject][k] - else: - # If the subproject options comes from a machine file, then we need to - # set the option as subproject:option - for k, v in chain(default_options.items(), env.meson_options.host.get('', {}).items(), - env.meson_options.host.get(subproject, {}).items()): - if (k not in builtin_options or builtin_options[k].yielding) \ - and optinterpreter.is_invalid_name(k, log=False): - continue - cmd_line_options['{}:{}'.format(subproject, k)] = v - cmd_line_options.update(env.cmd_line_options) - env.cmd_line_options = cmd_line_options + def set_default_options(self, default_options: 'T.OrderedDict[str, str]', subproject: str, env: 'Environment') -> None: + def make_key(key: str) -> str: + if subproject: + return '{}:{}'.format(subproject, key) + return key options = OrderedDict() - # load the values for user options out of the appropriate machine file, - # then overload the command line - for k, v in env.user_options.get(subproject, {}).items(): - if subproject: - k = '{}:{}'.format(subproject, k) - options[k] = v - - # Report that [properties]c_args - for lang in all_languages: - for args in ['{}_args'.format(lang), '{}_link_args'.format(lang)]: - msg = ('{} in the [properties] section of the machine file is deprecated, ' - 'use the [built-in options] section.') - if args in env.properties.host or args in env.properties.build: - mlog.deprecation(msg.format(args)) - - # Currently we don't support any options that are both per-subproject - # and per-machine, but when we do this will need to account for that. - # For cross builds we need to get the build specifc options - if env.meson_options.host != env.meson_options.build and subproject in env.meson_options.build: - if subproject: - template = '{s}:build.{k}' + # TODO: validate these + from .compilers import all_languages, base_options + lang_prefixes = tuple('{}_'.format(l) for l in all_languages) + # split arguments that can be set now, and those that cannot so they + # can be set later, when they've been initialized. + for k, v in default_options.items(): + if k.startswith(lang_prefixes): + lang, key = k.split('_', 1) + for machine in MachineChoice: + if key not in env.compiler_options[machine][lang]: + env.compiler_options[machine][lang][key] = v + elif k in base_options: + if not subproject and k not in env.base_options: + env.base_options[k] = v else: - template = 'build.{k}' - for k in builtin_options_per_machine.keys(): - if k in env.meson_options.build[subproject]: - options[template.format(s=subproject, k=k)] = env.meson_options.build[subproject][k] - - # Some options default to environment variables if they are - # unset, set those now. These will either be overwritten - # below, or they won't. These should only be set on the first run. - for for_machine in MachineChoice: - p_env_pair = get_env_var_pair(for_machine, self.is_cross_build(), 'PKG_CONFIG_PATH') - if p_env_pair is not None: - p_env_var, p_env = p_env_pair - - # PKG_CONFIG_PATH may contain duplicates, which must be - # removed, else a duplicates-in-array-option warning arises. - p_list = list(OrderedSet(p_env.split(':'))) - - key = 'pkg_config_path' - if for_machine == MachineChoice.BUILD: - key = 'build.' + key - - if env.first_invocation: - options[key] = p_list - elif options.get(key, []) != p_list: - mlog.warning( - p_env_var + - ' environment variable has changed ' - 'between configurations, meson ignores this. ' - 'Use -Dpkg_config_path to change pkg-config search ' - 'path instead.' - ) - - def remove_prefix(text, prefix): - if text.startswith(prefix): - return text[len(prefix):] - return text - - for k, v in cmd_line_options.items(): - if subproject: - if not k.startswith(subproject + ':'): - continue - elif k not in builtin_options.keys() \ - and remove_prefix(k, 'build.') not in builtin_options_per_machine.keys(): - if ':' in k: - continue - if optinterpreter.is_invalid_name(k, log=False): + options[make_key(k)] = v + + for k, v in chain(env.meson_options.host.get('', {}).items(), + env.meson_options.host.get(subproject, {}).items()): + options[make_key(k)] = v + + for k, v in chain(env.meson_options.build.get('', {}).items(), + env.meson_options.build.get(subproject, {}).items()): + if k in builtin_options_per_machine: + options[make_key('build.{}'.format(k))] = v + + options.update({make_key(k): v for k, v in env.user_options.get(subproject, {}).items()}) + + # Some options (namely the compiler options) are not preasant in + # coredata until the compiler is fully initialized. As such, we need to + # put those options into env.meson_options, only if they're not already + # in there, as the machine files and command line have precendence. + for k, v in default_options.items(): + if k in builtin_options and not builtin_options[k].yielding: + continue + for machine in MachineChoice: + if machine is MachineChoice.BUILD and not self.is_cross_build(): continue - options[k] = v + if k not in env.meson_options[machine][subproject]: + env.meson_options[machine][subproject][k] = v self.set_options(options, subproject=subproject) @@ -867,24 +802,19 @@ class CoreData: env.is_cross_build(), env.properties[for_machine]).items(): # prefixed compiler options affect just this machine - opt_prefix = for_machine.get_prefix() - user_k = opt_prefix + lang + '_' + k - if user_k in env.cmd_line_options: - o.set_value(env.cmd_line_options[user_k]) + if k in env.compiler_options[for_machine].get(lang, {}): + o.set_value(env.compiler_options[for_machine][lang][k]) self.compiler_options[for_machine][lang].setdefault(k, o) - def process_new_compiler(self, lang: str, comp: T.Type['Compiler'], env: 'Environment') -> None: + def process_new_compiler(self, lang: str, comp: 'Compiler', env: 'Environment') -> None: from . import compilers self.compilers[comp.for_machine][lang] = comp - enabled_opts = [] for k, o in comp.get_options().items(): # prefixed compiler options affect just this machine - opt_prefix = comp.for_machine.get_prefix() - user_k = opt_prefix + lang + '_' + k - if user_k in env.cmd_line_options: - o.set_value(env.cmd_line_options[user_k]) + if k in env.compiler_options[comp.for_machine].get(lang, {}): + o.set_value(env.compiler_options[comp.for_machine][lang][k]) self.compiler_options[comp.for_machine][lang].setdefault(k, o) enabled_opts = [] @@ -892,8 +822,8 @@ class CoreData: if optname in self.base_options: continue oobj = compilers.base_options[optname] - if optname in env.cmd_line_options: - oobj.set_value(env.cmd_line_options[optname]) + if optname in env.base_options: + oobj.set_value(env.base_options[optname]) enabled_opts.append(optname) self.base_options[optname] = oobj self.emit_base_options_warnings(enabled_opts) diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index 7dfffa2..9830b45 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -16,6 +16,7 @@ import os, platform, re, sys, shutil, subprocess import tempfile import shlex import typing as T +import collections from . import coredata from .linkers import ArLinker, ArmarLinker, VisualStudioLinker, DLinker, CcrxLinker, Xc16Linker, C2000Linker, IntelVisualStudioLinker @@ -28,11 +29,13 @@ from . import mlog from .envconfig import ( BinaryTable, MachineInfo, - Properties, known_cpu_families, + Properties, known_cpu_families, get_env_var_pair, ) from . import compilers from .compilers import ( Compiler, + all_languages, + base_options, is_assembly, is_header, is_library, @@ -549,10 +552,10 @@ class Environment: properties = PerMachineDefaultable() # We only need one of these as project options are not per machine - user_options = {} + user_options = collections.defaultdict(dict) # type: T.DefaultDict[str, T.Dict[str, object]] # meson builtin options, as passed through cross or native files - meson_options = PerMachineDefaultable() + meson_options = PerMachineDefaultable() # type: PerMachineDefaultable[T.DefaultDict[str, T.Dict[str, object]]] ## Setup build machine defaults @@ -564,6 +567,13 @@ class Environment: binaries.build = BinaryTable() properties.build = Properties() + # meson base options + _base_options = {} # type: T.Dict[str, object] + + # Per language compiler arguments + compiler_options = PerMachineDefaultable() # type: PerMachineDefaultable[T.DefaultDict[str, T.Dict[str, object]]] + compiler_options.build = collections.defaultdict(dict) + ## Read in native file(s) to override build machine configuration def load_options(tag: str, store: T.Dict[str, T.Any]) -> None: @@ -573,7 +583,44 @@ class Environment: project = section.split(':')[0] else: project = '' - store[project] = config.get(section, {}) + store[project].update(config.get(section, {})) + + def split_base_options(mopts: T.DefaultDict[str, T.Dict[str, object]]) -> None: + for k, v in list(mopts.get('', {}).items()): + if k in base_options: + _base_options[k] = v + del mopts[k] + + lang_prefixes = tuple('{}_'.format(l) for l in all_languages) + def split_compiler_options(mopts: T.DefaultDict[str, T.Dict[str, object]], machine: MachineChoice) -> None: + for k, v in list(mopts.get('', {}).items()): + if k.startswith(lang_prefixes): + lang, key = k.split('_', 1) + if compiler_options[machine] is None: + compiler_options[machine] = collections.defaultdict(dict) + if lang not in compiler_options[machine]: + compiler_options[machine][lang] = collections.defaultdict(dict) + compiler_options[machine][lang][key] = v + del mopts[''][k] + + def move_compiler_options(properties: Properties, compopts: T.Dict[str, T.DefaultDict[str, object]]) -> None: + for k, v in properties.properties.copy().items(): + for lang in all_languages: + if k == '{}_args'.format(lang): + if 'args' not in compopts[lang]: + compopts[lang]['args'] = v + else: + mlog.warning('Ignoring {}_args in [properties] section for those in the [built-in options]'.format(lang)) + elif k == '{}_link_args'.format(lang): + if 'link_args' not in compopts[lang]: + compopts[lang]['link_args'] = v + else: + mlog.warning('Ignoring {}_link_args in [properties] section in favor of the [built-in options] section.') + else: + continue + mlog.deprecation('{} in the [properties] section of the machine file is deprecated, use the [built-in options] section.'.format(k)) + del properties.properties[k] + break if self.coredata.config_files is not None: config = coredata.parse_machine_files(self.coredata.config_files) @@ -584,11 +631,15 @@ class Environment: # the native values if we're doing a cross build if not self.coredata.cross_files: load_options('project options', user_options) - meson_options.build = {} + meson_options.build = collections.defaultdict(dict) if config.get('paths') is not None: mlog.deprecation('The [paths] section is deprecated, use the [built-in options] section instead.') load_options('paths', meson_options.build) load_options('built-in options', meson_options.build) + if not self.coredata.cross_files: + split_base_options(meson_options.build) + split_compiler_options(meson_options.build, MachineChoice.BUILD) + move_compiler_options(properties.build, compiler_options.build) ## Read in cross file(s) to override host machine configuration @@ -601,11 +652,15 @@ class Environment: if 'target_machine' in config: machines.target = MachineInfo.from_literal(config['target_machine']) load_options('project options', user_options) - meson_options.host = {} + meson_options.host = collections.defaultdict(dict) + compiler_options.host = collections.defaultdict(dict) if config.get('paths') is not None: mlog.deprecation('The [paths] section is deprecated, use the [built-in options] section instead.') load_options('paths', meson_options.host) load_options('built-in options', meson_options.host) + split_base_options(meson_options.host) + split_compiler_options(meson_options.host, MachineChoice.HOST) + move_compiler_options(properties.host, compiler_options.host) ## "freeze" now initialized configuration, and "save" to the class. @@ -614,6 +669,67 @@ class Environment: self.properties = properties.default_missing() self.user_options = user_options self.meson_options = meson_options.default_missing() + self.base_options = _base_options + self.compiler_options = compiler_options.default_missing() + + # Some options default to environment variables if they are + # unset, set those now. + + for for_machine in MachineChoice: + p_env_pair = get_env_var_pair(for_machine, self.coredata.is_cross_build(), 'PKG_CONFIG_PATH') + if p_env_pair is not None: + p_env_var, p_env = p_env_pair + + # PKG_CONFIG_PATH may contain duplicates, which must be + # removed, else a duplicates-in-array-option warning arises. + p_list = list(mesonlib.OrderedSet(p_env.split(':'))) + + key = 'pkg_config_path' + + if self.first_invocation: + # Environment variables override config + self.meson_options[for_machine][''][key] = p_list + elif self.meson_options[for_machine][''].get(key, []) != p_list: + mlog.warning( + p_env_var, + 'environment variable does not match configured', + 'between configurations, meson ignores this.', + 'Use -Dpkg_config_path to change pkg-config search', + 'path instead.' + ) + + # Read in command line and populate options + # TODO: validate all of this + all_builtins = set(coredata.builtin_options) | set(coredata.builtin_options_per_machine) | set(coredata.builtin_dir_noprefix_options) + for k, v in options.cmd_line_options.items(): + try: + subproject, k = k.split(':') + except ValueError: + subproject = '' + if k in base_options: + self.base_options[k] = v + elif k.startswith(lang_prefixes): + lang, key = k.split('_', 1) + self.compiler_options.host[lang][key] = v + elif k in all_builtins or k.startswith('backend_'): + self.meson_options.host[subproject][k] = v + elif k.startswith('build.'): + k = k.lstrip('build.') + if k in coredata.builtin_options_per_machine: + if self.meson_options.build is None: + self.meson_options.build = collections.defaultdict(dict) + self.meson_options.build[subproject][k] = v + else: + assert not k.startswith('build.') + self.user_options[subproject][k] = v + + # Warn if the user is using two different ways of setting build-type + # options that override each other + if meson_options.build and 'buildtype' in meson_options.build[''] and \ + ('optimization' in meson_options.build[''] or 'debug' in meson_options.build['']): + mlog.warning('Recommend using either -Dbuildtype or -Doptimization + -Ddebug. ' + 'Using both is redundant since they override each other. ' + 'See: https://mesonbuild.com/Builtin-options.html#build-type-options') exe_wrapper = self.lookup_binary_entry(MachineChoice.HOST, 'exe_wrapper') if exe_wrapper is not None: @@ -622,8 +738,6 @@ class Environment: else: self.exe_wrapper = None - self.cmd_line_options = options.cmd_line_options.copy() - # List of potential compilers. if mesonlib.is_windows(): # Intel C and C++ compiler is icl on Windows, but icc and icpc elsewhere. diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index 317793d..cf7f282 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -2946,6 +2946,7 @@ external dependencies (including libraries) must go to "dependencies".''') if self.is_subproject(): optname = self.subproject + ':' + optname + for opts in [ self.coredata.base_options, compilers.base_options, self.coredata.builtins, dict(self.coredata.get_prefixed_options_per_machine(self.coredata.builtins_per_machine)), @@ -3031,8 +3032,9 @@ external dependencies (including libraries) must go to "dependencies".''') if self.environment.first_invocation: self.coredata.init_backend_options(backend) - options = {k: v for k, v in self.environment.cmd_line_options.items() if k.startswith('backend_')} - self.coredata.set_options(options) + if '' in self.environment.meson_options.host: + options = {k: v for k, v in self.environment.meson_options.host[''].items() if k.startswith('backend_')} + self.coredata.set_options(options) @stringArgs @permittedKwargs(permitted_kwargs['project']) @@ -3065,7 +3067,7 @@ external dependencies (including libraries) must go to "dependencies".''') self.project_default_options = mesonlib.stringlistify(kwargs.get('default_options', [])) self.project_default_options = coredata.create_options_dict(self.project_default_options) if self.environment.first_invocation: - default_options = self.project_default_options + default_options = self.project_default_options.copy() default_options.update(self.default_project_options) self.coredata.init_builtins(self.subproject) else: diff --git a/run_unittests.py b/run_unittests.py index 7bab408..21eabde 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -8030,7 +8030,7 @@ class NativeFileTests(BasePlatformTests): for opt, value in [('testoption', 'some other val'), ('other_one', True), ('combo_opt', 'one'), ('array_opt', ['two']), ('integer_opt', 0)]: - config = self.helper_create_native_file({'project options': {'sub:{}'.format(opt): value}}) + config = self.helper_create_native_file({'sub:project options': {opt: value}}) with self.assertRaises(subprocess.CalledProcessError) as cm: self.init(testcase, extra_args=['--native-file', config]) self.assertRegex(cm.exception.stdout, r'Incorrect value to [a-z]+ option') @@ -8076,6 +8076,19 @@ class NativeFileTests(BasePlatformTests): else: self.fail('Did not find werror in build options?') + def test_builtin_options_env_overrides_conf(self): + testcase = os.path.join(self.common_test_dir, '2 cpp') + config = self.helper_create_native_file({'built-in options': {'pkg_config_path': '/foo'}}) + + self.init(testcase, extra_args=['--native-file', config], override_envvars={'PKG_CONFIG_PATH': '/bar'}) + configuration = self.introspect('--buildoptions') + for each in configuration: + if each['name'] == 'pkg_config_path': + self.assertEqual(each['value'], ['/bar']) + break + else: + self.fail('Did not find pkg_config_path in build options?') + def test_builtin_options_subprojects(self): testcase = os.path.join(self.common_test_dir, '102 subproject subdir') config = self.helper_create_native_file({'built-in options': {'default_library': 'both', 'c_args': ['-Dfoo']}, 'sub:built-in options': {'default_library': 'static'}}) @@ -8185,6 +8198,22 @@ class NativeFileTests(BasePlatformTests): else: self.fail('Did not find bindir in build options?') + def test_builtin_options_paths_legacy(self): + testcase = os.path.join(self.common_test_dir, '1 trivial') + config = self.helper_create_native_file({ + 'built-in options': {'default_library': 'static'}, + 'paths': {'bindir': 'bar'}, + }) + + self.init(testcase, extra_args=['--native-file', config]) + configuration = self.introspect('--buildoptions') + for each in configuration: + if each['name'] == 'bindir': + self.assertEqual(each['value'], 'bar') + break + else: + self.fail('Did not find bindir in build options?') + class CrossFileTests(BasePlatformTests): @@ -8431,7 +8460,15 @@ class CrossFileTests(BasePlatformTests): cross = self.helper_create_cross_file({'built-in options': {'pkg_config_path': '/cross/path', 'cpp_std': 'c++17'}}) native = self.helper_create_cross_file({'built-in options': {'pkg_config_path': '/native/path', 'cpp_std': 'c++14'}}) - self.init(testcase, extra_args=['--cross-file', cross, '--native-file', native]) + # Ensure that PKG_CONFIG_PATH is not set in the environment + with mock.patch.dict('os.environ'): + for k in ['PKG_CONFIG_PATH', 'PKG_CONFIG_PATH_FOR_BUILD']: + try: + del os.environ[k] + except KeyError: + pass + self.init(testcase, extra_args=['--cross-file', cross, '--native-file', native]) + configuration = self.introspect('--buildoptions') found = 0 for each in configuration: @@ -8452,6 +8489,26 @@ class CrossFileTests(BasePlatformTests): break self.assertEqual(found, 4, 'Did not find all sections.') + def test_builtin_options_env_overrides_conf(self): + testcase = os.path.join(self.common_test_dir, '2 cpp') + config = self.helper_create_cross_file({'built-in options': {'pkg_config_path': '/foo'}}) + cross = self.helper_create_cross_file({'built-in options': {'pkg_config_path': '/foo'}}) + + self.init(testcase, extra_args=['--native-file', config, '--cross-file', cross], + override_envvars={'PKG_CONFIG_PATH': '/bar', 'PKG_CONFIG_PATH_FOR_BUILD': '/dir'}) + configuration = self.introspect('--buildoptions') + found = 0 + for each in configuration: + if each['name'] == 'pkg_config_path': + self.assertEqual(each['value'], ['/bar']) + found += 1 + elif each['name'] == 'build.pkg_config_path': + self.assertEqual(each['value'], ['/dir']) + found += 1 + if found == 2: + break + self.assertEqual(found, 2, 'Did not find all sections.') + class TAPParserTests(unittest.TestCase): def assert_test(self, events, **kwargs): -- cgit v1.1 From 3a4d8dde52a5755901ec97784e9f3d883162873b Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Thu, 30 Jul 2020 19:46:36 -0700 Subject: update version from 0.55. to 0.56 --- docs/markdown/Machine-files.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/markdown/Machine-files.md b/docs/markdown/Machine-files.md index 60c4dd5..5ac66a8 100644 --- a/docs/markdown/Machine-files.md +++ b/docs/markdown/Machine-files.md @@ -48,7 +48,7 @@ The following sections are allowed: ### constants -*Since 0.55.0* +*Since 0.56.0* String and list concatenation is supported using the `+` operator, joining paths is supported using the `/` operator. @@ -172,7 +172,7 @@ An incomplete list of internally used programs that can be overridden here is: ### Paths and Directories -*Deprecated in 0.55.0* use the built-in section instead. +*Deprecated in 0.56.0* use the built-in section instead. As of 0.50.0 paths and directories such as libdir can be defined in the native and cross files in a paths section. These should be strings. @@ -196,13 +196,13 @@ In addition to special data that may be specified in cross files, this section may contain random key value pairs accessed using the `meson.get_external_property()`, or `meson.get_cross_property()`. -*Changed in 0.55.0* putting `_args` and `_link_args` in the +*Changed in 0.56.0* putting `_args` and `_link_args` in the properties section has been deprecated, and should be put in the built-in options section. ### Project specific options -*New in 0.55.0* +*New in 0.56.0* Path options are not allowed, those must be set in the `[paths]` section. -- cgit v1.1 From 4d2a17041f0dd54001a7d32b36e75608330f41f5 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Thu, 30 Jul 2020 19:46:57 -0700 Subject: run dircondensor.py --- run_unittests.py | 14 +++++++------- test cases/cmake/19 cmake file/foolib.cmake.in | 1 - test cases/cmake/19 cmake file/meson.build | 14 -------------- test cases/cmake/19 cmake file/test.json | 5 ----- test cases/cmake/20 cmake file/foolib.cmake.in | 1 + test cases/cmake/20 cmake file/meson.build | 14 ++++++++++++++ test cases/cmake/20 cmake file/test.json | 5 +++++ test cases/failing/106 number in combo/meson.build | 1 - test cases/failing/106 number in combo/nativefile.ini | 2 -- test cases/failing/106 number in combo/test.json | 5 ----- test cases/failing/107 bool in combo/meson.build | 1 - test cases/failing/107 bool in combo/meson_options.txt | 5 ----- test cases/failing/107 bool in combo/nativefile.ini | 2 -- test cases/failing/107 bool in combo/test.json | 5 ----- test cases/failing/107 number in combo/meson.build | 1 + test cases/failing/107 number in combo/nativefile.ini | 2 ++ test cases/failing/107 number in combo/test.json | 5 +++++ test cases/failing/108 bool in combo/meson.build | 1 + test cases/failing/108 bool in combo/meson_options.txt | 5 +++++ test cases/failing/108 bool in combo/nativefile.ini | 2 ++ test cases/failing/108 bool in combo/test.json | 5 +++++ test cases/unit/75 user options for subproject/.gitignore | 1 - test cases/unit/75 user options for subproject/meson.build | 3 --- test cases/unit/76 pkgconfig prefixes/client/client.c | 8 -------- test cases/unit/76 pkgconfig prefixes/client/meson.build | 3 --- test cases/unit/76 pkgconfig prefixes/val1/meson.build | 5 ----- test cases/unit/76 pkgconfig prefixes/val1/val1.c | 3 --- test cases/unit/76 pkgconfig prefixes/val1/val1.h | 1 - test cases/unit/76 pkgconfig prefixes/val2/meson.build | 8 -------- test cases/unit/76 pkgconfig prefixes/val2/val2.c | 4 ---- test cases/unit/76 pkgconfig prefixes/val2/val2.h | 1 - test cases/unit/76 subdir libdir/meson.build | 2 -- .../unit/76 subdir libdir/subprojects/flub/meson.build | 1 - test cases/unit/77 global-rpath/meson.build | 3 --- test cases/unit/77 global-rpath/rpathified.cpp | 6 ------ test cases/unit/77 global-rpath/yonder/meson.build | 5 ----- test cases/unit/77 global-rpath/yonder/yonder.cpp | 3 --- test cases/unit/77 global-rpath/yonder/yonder.h | 1 - test cases/unit/77 pkgconfig prefixes/client/client.c | 8 ++++++++ test cases/unit/77 pkgconfig prefixes/client/meson.build | 3 +++ test cases/unit/77 pkgconfig prefixes/val1/meson.build | 5 +++++ test cases/unit/77 pkgconfig prefixes/val1/val1.c | 3 +++ test cases/unit/77 pkgconfig prefixes/val1/val1.h | 1 + test cases/unit/77 pkgconfig prefixes/val2/meson.build | 8 ++++++++ test cases/unit/77 pkgconfig prefixes/val2/val2.c | 4 ++++ test cases/unit/77 pkgconfig prefixes/val2/val2.h | 1 + test cases/unit/78 subdir libdir/meson.build | 2 ++ .../unit/78 subdir libdir/subprojects/flub/meson.build | 1 + test cases/unit/78 wrap-git/meson.build | 4 ---- .../subprojects/packagefiles/wrap_git_builddef/meson.build | 3 --- .../unit/78 wrap-git/subprojects/wrap_git_upstream/main.c | 4 ---- .../75 user options for subproject/.gitignore | 1 + .../75 user options for subproject/meson.build | 3 +++ test cases/unit/80 global-rpath/meson.build | 3 +++ test cases/unit/80 global-rpath/rpathified.cpp | 6 ++++++ test cases/unit/80 global-rpath/yonder/meson.build | 5 +++++ test cases/unit/80 global-rpath/yonder/yonder.cpp | 3 +++ test cases/unit/80 global-rpath/yonder/yonder.h | 1 + test cases/unit/81 wrap-git/meson.build | 4 ++++ .../subprojects/packagefiles/wrap_git_builddef/meson.build | 3 +++ .../unit/81 wrap-git/subprojects/wrap_git_upstream/main.c | 4 ++++ 61 files changed, 117 insertions(+), 117 deletions(-) delete mode 100644 test cases/cmake/19 cmake file/foolib.cmake.in delete mode 100644 test cases/cmake/19 cmake file/meson.build delete mode 100644 test cases/cmake/19 cmake file/test.json create mode 100644 test cases/cmake/20 cmake file/foolib.cmake.in create mode 100644 test cases/cmake/20 cmake file/meson.build create mode 100644 test cases/cmake/20 cmake file/test.json delete mode 100644 test cases/failing/106 number in combo/meson.build delete mode 100644 test cases/failing/106 number in combo/nativefile.ini delete mode 100644 test cases/failing/106 number in combo/test.json delete mode 100644 test cases/failing/107 bool in combo/meson.build delete mode 100644 test cases/failing/107 bool in combo/meson_options.txt delete mode 100644 test cases/failing/107 bool in combo/nativefile.ini delete mode 100644 test cases/failing/107 bool in combo/test.json create mode 100644 test cases/failing/107 number in combo/meson.build create mode 100644 test cases/failing/107 number in combo/nativefile.ini create mode 100644 test cases/failing/107 number in combo/test.json create mode 100644 test cases/failing/108 bool in combo/meson.build create mode 100644 test cases/failing/108 bool in combo/meson_options.txt create mode 100644 test cases/failing/108 bool in combo/nativefile.ini create mode 100644 test cases/failing/108 bool in combo/test.json delete mode 100644 test cases/unit/75 user options for subproject/.gitignore delete mode 100644 test cases/unit/75 user options for subproject/meson.build delete mode 100644 test cases/unit/76 pkgconfig prefixes/client/client.c delete mode 100644 test cases/unit/76 pkgconfig prefixes/client/meson.build delete mode 100644 test cases/unit/76 pkgconfig prefixes/val1/meson.build delete mode 100644 test cases/unit/76 pkgconfig prefixes/val1/val1.c delete mode 100644 test cases/unit/76 pkgconfig prefixes/val1/val1.h delete mode 100644 test cases/unit/76 pkgconfig prefixes/val2/meson.build delete mode 100644 test cases/unit/76 pkgconfig prefixes/val2/val2.c delete mode 100644 test cases/unit/76 pkgconfig prefixes/val2/val2.h delete mode 100644 test cases/unit/76 subdir libdir/meson.build delete mode 100644 test cases/unit/76 subdir libdir/subprojects/flub/meson.build delete mode 100644 test cases/unit/77 global-rpath/meson.build delete mode 100644 test cases/unit/77 global-rpath/rpathified.cpp delete mode 100644 test cases/unit/77 global-rpath/yonder/meson.build delete mode 100644 test cases/unit/77 global-rpath/yonder/yonder.cpp delete mode 100644 test cases/unit/77 global-rpath/yonder/yonder.h create mode 100644 test cases/unit/77 pkgconfig prefixes/client/client.c create mode 100644 test cases/unit/77 pkgconfig prefixes/client/meson.build create mode 100644 test cases/unit/77 pkgconfig prefixes/val1/meson.build create mode 100644 test cases/unit/77 pkgconfig prefixes/val1/val1.c create mode 100644 test cases/unit/77 pkgconfig prefixes/val1/val1.h create mode 100644 test cases/unit/77 pkgconfig prefixes/val2/meson.build create mode 100644 test cases/unit/77 pkgconfig prefixes/val2/val2.c create mode 100644 test cases/unit/77 pkgconfig prefixes/val2/val2.h create mode 100644 test cases/unit/78 subdir libdir/meson.build create mode 100644 test cases/unit/78 subdir libdir/subprojects/flub/meson.build delete mode 100644 test cases/unit/78 wrap-git/meson.build delete mode 100644 test cases/unit/78 wrap-git/subprojects/packagefiles/wrap_git_builddef/meson.build delete mode 100644 test cases/unit/78 wrap-git/subprojects/wrap_git_upstream/main.c create mode 100644 test cases/unit/79 user options for subproject/75 user options for subproject/.gitignore create mode 100644 test cases/unit/79 user options for subproject/75 user options for subproject/meson.build create mode 100644 test cases/unit/80 global-rpath/meson.build create mode 100644 test cases/unit/80 global-rpath/rpathified.cpp create mode 100644 test cases/unit/80 global-rpath/yonder/meson.build create mode 100644 test cases/unit/80 global-rpath/yonder/yonder.cpp create mode 100644 test cases/unit/80 global-rpath/yonder/yonder.h create mode 100644 test cases/unit/81 wrap-git/meson.build create mode 100644 test cases/unit/81 wrap-git/subprojects/packagefiles/wrap_git_builddef/meson.build create mode 100644 test cases/unit/81 wrap-git/subprojects/wrap_git_upstream/main.c diff --git a/run_unittests.py b/run_unittests.py index 21eabde..6d7eba2 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -5014,7 +5014,7 @@ recommended as it is not supported on some platforms''') def test_wrap_git(self): with tempfile.TemporaryDirectory() as tmpdir: srcdir = os.path.join(tmpdir, 'src') - shutil.copytree(os.path.join(self.unit_test_dir, '78 wrap-git'), srcdir) + shutil.copytree(os.path.join(self.unit_test_dir, '81 wrap-git'), srcdir) upstream = os.path.join(srcdir, 'subprojects', 'wrap_git_upstream') upstream_uri = Path(upstream).as_uri() _git_init(upstream) @@ -6473,7 +6473,7 @@ class LinuxlikeTests(BasePlatformTests): if is_osx(): raise unittest.SkipTest('Global RPATHs via LDFLAGS not yet supported on MacOS (does anybody need it?)') - testdir = os.path.join(self.unit_test_dir, '77 global-rpath') + testdir = os.path.join(self.unit_test_dir, '80 global-rpath') oldinstalldir = self.installdir # Build and install an external library without DESTDIR. @@ -6846,7 +6846,7 @@ class LinuxlikeTests(BasePlatformTests): oldinstalldir = self.installdir # Build and install both external libraries without DESTDIR - val1dir = os.path.join(self.unit_test_dir, '76 pkgconfig prefixes', 'val1') + val1dir = os.path.join(self.unit_test_dir, '77 pkgconfig prefixes', 'val1') val1prefix = os.path.join(oldinstalldir, 'val1') self.prefix = val1prefix self.installdir = val1prefix @@ -6857,7 +6857,7 @@ class LinuxlikeTests(BasePlatformTests): env1 = {} env1['PKG_CONFIG_PATH'] = os.path.join(val1prefix, self.libdir, 'pkgconfig') - val2dir = os.path.join(self.unit_test_dir, '76 pkgconfig prefixes', 'val2') + val2dir = os.path.join(self.unit_test_dir, '77 pkgconfig prefixes', 'val2') val2prefix = os.path.join(oldinstalldir, 'val2') self.prefix = val2prefix self.installdir = val2prefix @@ -6869,7 +6869,7 @@ class LinuxlikeTests(BasePlatformTests): # Build, install, and run the client program env2 = {} env2['PKG_CONFIG_PATH'] = os.path.join(val2prefix, self.libdir, 'pkgconfig') - testdir = os.path.join(self.unit_test_dir, '76 pkgconfig prefixes', 'client') + testdir = os.path.join(self.unit_test_dir, '77 pkgconfig prefixes', 'client') testprefix = os.path.join(oldinstalldir, 'client') self.prefix = testprefix self.installdir = testprefix @@ -7180,7 +7180,7 @@ class LinuxCrossArmTests(BaseLinuxCrossTests): def test_cross_libdir_subproject(self): # Guard against a regression where calling "subproject" # would reset the value of libdir to its default value. - testdir = os.path.join(self.unit_test_dir, '76 subdir libdir') + testdir = os.path.join(self.unit_test_dir, '78 subdir libdir') self.init(testdir, extra_args=['--libdir=fuf']) for i in self.introspect('--buildoptions'): if i['name'] == 'libdir': @@ -8017,7 +8017,7 @@ class NativeFileTests(BasePlatformTests): self.init(testcase, extra_args=['--native-file', config, '-Dother_one=false']) def test_user_options_subproject(self): - testcase = os.path.join(self.unit_test_dir, '75 user options for subproject') + testcase = os.path.join(self.unit_test_dir, '79 user options for subproject') s = os.path.join(testcase, 'subprojects') if not os.path.exists(s): diff --git a/test cases/cmake/19 cmake file/foolib.cmake.in b/test cases/cmake/19 cmake file/foolib.cmake.in deleted file mode 100644 index 16e992b..0000000 --- a/test cases/cmake/19 cmake file/foolib.cmake.in +++ /dev/null @@ -1 +0,0 @@ -@foo@ diff --git a/test cases/cmake/19 cmake file/meson.build b/test cases/cmake/19 cmake file/meson.build deleted file mode 100644 index 758bbee..0000000 --- a/test cases/cmake/19 cmake file/meson.build +++ /dev/null @@ -1,14 +0,0 @@ -project( - 'cmake config file', -) - -cmake = import('cmake') - -cmake_conf = configuration_data() -cmake_conf.set_quoted('foo', 'bar') -cmake.configure_package_config_file( - name : 'foolib', - input : 'foolib.cmake.in', - install_dir : get_option('libdir') / 'cmake', - configuration : cmake_conf, -) diff --git a/test cases/cmake/19 cmake file/test.json b/test cases/cmake/19 cmake file/test.json deleted file mode 100644 index a8c4ba3..0000000 --- a/test cases/cmake/19 cmake file/test.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "installed": [ - {"file": "usr/lib/cmake/foolibConfig.cmake", "type": "file"} - ] -} diff --git a/test cases/cmake/20 cmake file/foolib.cmake.in b/test cases/cmake/20 cmake file/foolib.cmake.in new file mode 100644 index 0000000..16e992b --- /dev/null +++ b/test cases/cmake/20 cmake file/foolib.cmake.in @@ -0,0 +1 @@ +@foo@ diff --git a/test cases/cmake/20 cmake file/meson.build b/test cases/cmake/20 cmake file/meson.build new file mode 100644 index 0000000..758bbee --- /dev/null +++ b/test cases/cmake/20 cmake file/meson.build @@ -0,0 +1,14 @@ +project( + 'cmake config file', +) + +cmake = import('cmake') + +cmake_conf = configuration_data() +cmake_conf.set_quoted('foo', 'bar') +cmake.configure_package_config_file( + name : 'foolib', + input : 'foolib.cmake.in', + install_dir : get_option('libdir') / 'cmake', + configuration : cmake_conf, +) diff --git a/test cases/cmake/20 cmake file/test.json b/test cases/cmake/20 cmake file/test.json new file mode 100644 index 0000000..a8c4ba3 --- /dev/null +++ b/test cases/cmake/20 cmake file/test.json @@ -0,0 +1,5 @@ +{ + "installed": [ + {"file": "usr/lib/cmake/foolibConfig.cmake", "type": "file"} + ] +} diff --git a/test cases/failing/106 number in combo/meson.build b/test cases/failing/106 number in combo/meson.build deleted file mode 100644 index 1a647df..0000000 --- a/test cases/failing/106 number in combo/meson.build +++ /dev/null @@ -1 +0,0 @@ -project('number in combo') diff --git a/test cases/failing/106 number in combo/nativefile.ini b/test cases/failing/106 number in combo/nativefile.ini deleted file mode 100644 index 55f10fc..0000000 --- a/test cases/failing/106 number in combo/nativefile.ini +++ /dev/null @@ -1,2 +0,0 @@ -[built-in options] -optimization = 1 diff --git a/test cases/failing/106 number in combo/test.json b/test cases/failing/106 number in combo/test.json deleted file mode 100644 index a32c358..0000000 --- a/test cases/failing/106 number in combo/test.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "stdout": [ - { "line": "test cases/failing/106 number in combo/meson.build:1:0: ERROR: Value \"1\" (of type \"number\") for combo option \"Optimization level\" is not one of the choices. Possible choices are (as string): \"0\", \"g\", \"1\", \"2\", \"3\", \"s\"." } - ] -} diff --git a/test cases/failing/107 bool in combo/meson.build b/test cases/failing/107 bool in combo/meson.build deleted file mode 100644 index c5efd67..0000000 --- a/test cases/failing/107 bool in combo/meson.build +++ /dev/null @@ -1 +0,0 @@ -project('bool in combo') diff --git a/test cases/failing/107 bool in combo/meson_options.txt b/test cases/failing/107 bool in combo/meson_options.txt deleted file mode 100644 index 0c8f5de..0000000 --- a/test cases/failing/107 bool in combo/meson_options.txt +++ /dev/null @@ -1,5 +0,0 @@ -option( - 'opt', - type : 'combo', - choices : ['true', 'false'] -) diff --git a/test cases/failing/107 bool in combo/nativefile.ini b/test cases/failing/107 bool in combo/nativefile.ini deleted file mode 100644 index b423957..0000000 --- a/test cases/failing/107 bool in combo/nativefile.ini +++ /dev/null @@ -1,2 +0,0 @@ -[project options] -opt = true diff --git a/test cases/failing/107 bool in combo/test.json b/test cases/failing/107 bool in combo/test.json deleted file mode 100644 index 37218e8..0000000 --- a/test cases/failing/107 bool in combo/test.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "stdout": [ - { "line": "test cases/failing/107 bool in combo/meson.build:1:0: ERROR: Value \"True\" (of type \"boolean\") for combo option \"opt\" is not one of the choices. Possible choices are (as string): \"true\", \"false\"." } - ] -} diff --git a/test cases/failing/107 number in combo/meson.build b/test cases/failing/107 number in combo/meson.build new file mode 100644 index 0000000..1a647df --- /dev/null +++ b/test cases/failing/107 number in combo/meson.build @@ -0,0 +1 @@ +project('number in combo') diff --git a/test cases/failing/107 number in combo/nativefile.ini b/test cases/failing/107 number in combo/nativefile.ini new file mode 100644 index 0000000..55f10fc --- /dev/null +++ b/test cases/failing/107 number in combo/nativefile.ini @@ -0,0 +1,2 @@ +[built-in options] +optimization = 1 diff --git a/test cases/failing/107 number in combo/test.json b/test cases/failing/107 number in combo/test.json new file mode 100644 index 0000000..f5aeb4e --- /dev/null +++ b/test cases/failing/107 number in combo/test.json @@ -0,0 +1,5 @@ +{ + "stdout": [ + { "line": "test cases/failing/107 number in combo/meson.build:1:0: ERROR: Value \"1\" (of type \"number\") for combo option \"Optimization level\" is not one of the choices. Possible choices are (as string): \"0\", \"g\", \"1\", \"2\", \"3\", \"s\"." } + ] +} diff --git a/test cases/failing/108 bool in combo/meson.build b/test cases/failing/108 bool in combo/meson.build new file mode 100644 index 0000000..c5efd67 --- /dev/null +++ b/test cases/failing/108 bool in combo/meson.build @@ -0,0 +1 @@ +project('bool in combo') diff --git a/test cases/failing/108 bool in combo/meson_options.txt b/test cases/failing/108 bool in combo/meson_options.txt new file mode 100644 index 0000000..0c8f5de --- /dev/null +++ b/test cases/failing/108 bool in combo/meson_options.txt @@ -0,0 +1,5 @@ +option( + 'opt', + type : 'combo', + choices : ['true', 'false'] +) diff --git a/test cases/failing/108 bool in combo/nativefile.ini b/test cases/failing/108 bool in combo/nativefile.ini new file mode 100644 index 0000000..b423957 --- /dev/null +++ b/test cases/failing/108 bool in combo/nativefile.ini @@ -0,0 +1,2 @@ +[project options] +opt = true diff --git a/test cases/failing/108 bool in combo/test.json b/test cases/failing/108 bool in combo/test.json new file mode 100644 index 0000000..729ad3d --- /dev/null +++ b/test cases/failing/108 bool in combo/test.json @@ -0,0 +1,5 @@ +{ + "stdout": [ + { "line": "test cases/failing/108 bool in combo/meson.build:1:0: ERROR: Value \"True\" (of type \"boolean\") for combo option \"opt\" is not one of the choices. Possible choices are (as string): \"true\", \"false\"." } + ] +} diff --git a/test cases/unit/75 user options for subproject/.gitignore b/test cases/unit/75 user options for subproject/.gitignore deleted file mode 100644 index 4976afc..0000000 --- a/test cases/unit/75 user options for subproject/.gitignore +++ /dev/null @@ -1 +0,0 @@ -subprojects/* diff --git a/test cases/unit/75 user options for subproject/meson.build b/test cases/unit/75 user options for subproject/meson.build deleted file mode 100644 index 0bc395b..0000000 --- a/test cases/unit/75 user options for subproject/meson.build +++ /dev/null @@ -1,3 +0,0 @@ -project('user option for subproject') - -p = subproject('sub') diff --git a/test cases/unit/76 pkgconfig prefixes/client/client.c b/test cases/unit/76 pkgconfig prefixes/client/client.c deleted file mode 100644 index be9bead..0000000 --- a/test cases/unit/76 pkgconfig prefixes/client/client.c +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include - -int main(int argc, char **argv) -{ - printf("%d\n", val2()); - return 0; -} diff --git a/test cases/unit/76 pkgconfig prefixes/client/meson.build b/test cases/unit/76 pkgconfig prefixes/client/meson.build deleted file mode 100644 index 491937b..0000000 --- a/test cases/unit/76 pkgconfig prefixes/client/meson.build +++ /dev/null @@ -1,3 +0,0 @@ -project('client', 'c') -val2_dep = dependency('val2') -executable('client', 'client.c', dependencies : [val2_dep], install: true) diff --git a/test cases/unit/76 pkgconfig prefixes/val1/meson.build b/test cases/unit/76 pkgconfig prefixes/val1/meson.build deleted file mode 100644 index cc63e31..0000000 --- a/test cases/unit/76 pkgconfig prefixes/val1/meson.build +++ /dev/null @@ -1,5 +0,0 @@ -project('val1', 'c') -val1 = shared_library('val1', 'val1.c', install: true) -install_headers('val1.h') -pkgconfig = import('pkgconfig') -pkgconfig.generate(val1, libraries : ['-Wl,-rpath,${libdir}']) diff --git a/test cases/unit/76 pkgconfig prefixes/val1/val1.c b/test cases/unit/76 pkgconfig prefixes/val1/val1.c deleted file mode 100644 index 591e521..0000000 --- a/test cases/unit/76 pkgconfig prefixes/val1/val1.c +++ /dev/null @@ -1,3 +0,0 @@ -#include "val1.h" - -int val1(void) { return 1; } diff --git a/test cases/unit/76 pkgconfig prefixes/val1/val1.h b/test cases/unit/76 pkgconfig prefixes/val1/val1.h deleted file mode 100644 index 6bd435e..0000000 --- a/test cases/unit/76 pkgconfig prefixes/val1/val1.h +++ /dev/null @@ -1 +0,0 @@ -int val1(void); diff --git a/test cases/unit/76 pkgconfig prefixes/val2/meson.build b/test cases/unit/76 pkgconfig prefixes/val2/meson.build deleted file mode 100644 index ce69481..0000000 --- a/test cases/unit/76 pkgconfig prefixes/val2/meson.build +++ /dev/null @@ -1,8 +0,0 @@ -project('val2', 'c') -val1_dep = dependency('val1') -val2 = shared_library('val2', 'val2.c', - dependencies : [val1_dep], - install: true) -install_headers('val2.h') -pkgconfig = import('pkgconfig') -pkgconfig.generate(val2, libraries : ['-Wl,-rpath,${libdir}']) diff --git a/test cases/unit/76 pkgconfig prefixes/val2/val2.c b/test cases/unit/76 pkgconfig prefixes/val2/val2.c deleted file mode 100644 index d7d4857..0000000 --- a/test cases/unit/76 pkgconfig prefixes/val2/val2.c +++ /dev/null @@ -1,4 +0,0 @@ -#include "val1.h" -#include "val2.h" - -int val2(void) { return val1() + 2; } diff --git a/test cases/unit/76 pkgconfig prefixes/val2/val2.h b/test cases/unit/76 pkgconfig prefixes/val2/val2.h deleted file mode 100644 index 995023d..0000000 --- a/test cases/unit/76 pkgconfig prefixes/val2/val2.h +++ /dev/null @@ -1 +0,0 @@ -int val2(void); diff --git a/test cases/unit/76 subdir libdir/meson.build b/test cases/unit/76 subdir libdir/meson.build deleted file mode 100644 index 5099c91..0000000 --- a/test cases/unit/76 subdir libdir/meson.build +++ /dev/null @@ -1,2 +0,0 @@ -project('toplevel', 'c') -subproject('flub') diff --git a/test cases/unit/76 subdir libdir/subprojects/flub/meson.build b/test cases/unit/76 subdir libdir/subprojects/flub/meson.build deleted file mode 100644 index 7bfd2c5..0000000 --- a/test cases/unit/76 subdir libdir/subprojects/flub/meson.build +++ /dev/null @@ -1 +0,0 @@ -project('subflub', 'c') diff --git a/test cases/unit/77 global-rpath/meson.build b/test cases/unit/77 global-rpath/meson.build deleted file mode 100644 index c67d9e0..0000000 --- a/test cases/unit/77 global-rpath/meson.build +++ /dev/null @@ -1,3 +0,0 @@ -project('global-rpath', 'cpp') -yonder_dep = dependency('yonder') -executable('rpathified', 'rpathified.cpp', dependencies: [yonder_dep], install: true) diff --git a/test cases/unit/77 global-rpath/rpathified.cpp b/test cases/unit/77 global-rpath/rpathified.cpp deleted file mode 100644 index 3788906..0000000 --- a/test cases/unit/77 global-rpath/rpathified.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include -#include -int main(int argc, char **argv) -{ - return strcmp(yonder(), "AB54 6BR"); -} diff --git a/test cases/unit/77 global-rpath/yonder/meson.build b/test cases/unit/77 global-rpath/yonder/meson.build deleted file mode 100644 index e32f383..0000000 --- a/test cases/unit/77 global-rpath/yonder/meson.build +++ /dev/null @@ -1,5 +0,0 @@ -project('yonder', 'cpp') -yonder = shared_library('yonder', 'yonder.cpp', install: true) -install_headers('yonder.h') -pkgconfig = import('pkgconfig') -pkgconfig.generate(yonder) diff --git a/test cases/unit/77 global-rpath/yonder/yonder.cpp b/test cases/unit/77 global-rpath/yonder/yonder.cpp deleted file mode 100644 index b182d34..0000000 --- a/test cases/unit/77 global-rpath/yonder/yonder.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "yonder.h" - -char *yonder(void) { return "AB54 6BR"; } diff --git a/test cases/unit/77 global-rpath/yonder/yonder.h b/test cases/unit/77 global-rpath/yonder/yonder.h deleted file mode 100644 index 9d9ad16..0000000 --- a/test cases/unit/77 global-rpath/yonder/yonder.h +++ /dev/null @@ -1 +0,0 @@ -char *yonder(void); diff --git a/test cases/unit/77 pkgconfig prefixes/client/client.c b/test cases/unit/77 pkgconfig prefixes/client/client.c new file mode 100644 index 0000000..be9bead --- /dev/null +++ b/test cases/unit/77 pkgconfig prefixes/client/client.c @@ -0,0 +1,8 @@ +#include +#include + +int main(int argc, char **argv) +{ + printf("%d\n", val2()); + return 0; +} diff --git a/test cases/unit/77 pkgconfig prefixes/client/meson.build b/test cases/unit/77 pkgconfig prefixes/client/meson.build new file mode 100644 index 0000000..491937b --- /dev/null +++ b/test cases/unit/77 pkgconfig prefixes/client/meson.build @@ -0,0 +1,3 @@ +project('client', 'c') +val2_dep = dependency('val2') +executable('client', 'client.c', dependencies : [val2_dep], install: true) diff --git a/test cases/unit/77 pkgconfig prefixes/val1/meson.build b/test cases/unit/77 pkgconfig prefixes/val1/meson.build new file mode 100644 index 0000000..cc63e31 --- /dev/null +++ b/test cases/unit/77 pkgconfig prefixes/val1/meson.build @@ -0,0 +1,5 @@ +project('val1', 'c') +val1 = shared_library('val1', 'val1.c', install: true) +install_headers('val1.h') +pkgconfig = import('pkgconfig') +pkgconfig.generate(val1, libraries : ['-Wl,-rpath,${libdir}']) diff --git a/test cases/unit/77 pkgconfig prefixes/val1/val1.c b/test cases/unit/77 pkgconfig prefixes/val1/val1.c new file mode 100644 index 0000000..591e521 --- /dev/null +++ b/test cases/unit/77 pkgconfig prefixes/val1/val1.c @@ -0,0 +1,3 @@ +#include "val1.h" + +int val1(void) { return 1; } diff --git a/test cases/unit/77 pkgconfig prefixes/val1/val1.h b/test cases/unit/77 pkgconfig prefixes/val1/val1.h new file mode 100644 index 0000000..6bd435e --- /dev/null +++ b/test cases/unit/77 pkgconfig prefixes/val1/val1.h @@ -0,0 +1 @@ +int val1(void); diff --git a/test cases/unit/77 pkgconfig prefixes/val2/meson.build b/test cases/unit/77 pkgconfig prefixes/val2/meson.build new file mode 100644 index 0000000..ce69481 --- /dev/null +++ b/test cases/unit/77 pkgconfig prefixes/val2/meson.build @@ -0,0 +1,8 @@ +project('val2', 'c') +val1_dep = dependency('val1') +val2 = shared_library('val2', 'val2.c', + dependencies : [val1_dep], + install: true) +install_headers('val2.h') +pkgconfig = import('pkgconfig') +pkgconfig.generate(val2, libraries : ['-Wl,-rpath,${libdir}']) diff --git a/test cases/unit/77 pkgconfig prefixes/val2/val2.c b/test cases/unit/77 pkgconfig prefixes/val2/val2.c new file mode 100644 index 0000000..d7d4857 --- /dev/null +++ b/test cases/unit/77 pkgconfig prefixes/val2/val2.c @@ -0,0 +1,4 @@ +#include "val1.h" +#include "val2.h" + +int val2(void) { return val1() + 2; } diff --git a/test cases/unit/77 pkgconfig prefixes/val2/val2.h b/test cases/unit/77 pkgconfig prefixes/val2/val2.h new file mode 100644 index 0000000..995023d --- /dev/null +++ b/test cases/unit/77 pkgconfig prefixes/val2/val2.h @@ -0,0 +1 @@ +int val2(void); diff --git a/test cases/unit/78 subdir libdir/meson.build b/test cases/unit/78 subdir libdir/meson.build new file mode 100644 index 0000000..5099c91 --- /dev/null +++ b/test cases/unit/78 subdir libdir/meson.build @@ -0,0 +1,2 @@ +project('toplevel', 'c') +subproject('flub') diff --git a/test cases/unit/78 subdir libdir/subprojects/flub/meson.build b/test cases/unit/78 subdir libdir/subprojects/flub/meson.build new file mode 100644 index 0000000..7bfd2c5 --- /dev/null +++ b/test cases/unit/78 subdir libdir/subprojects/flub/meson.build @@ -0,0 +1 @@ +project('subflub', 'c') diff --git a/test cases/unit/78 wrap-git/meson.build b/test cases/unit/78 wrap-git/meson.build deleted file mode 100644 index b0af30a..0000000 --- a/test cases/unit/78 wrap-git/meson.build +++ /dev/null @@ -1,4 +0,0 @@ -project('test-wrap-git') - -exe = subproject('wrap_git').get_variable('exe') -test('test1', exe) diff --git a/test cases/unit/78 wrap-git/subprojects/packagefiles/wrap_git_builddef/meson.build b/test cases/unit/78 wrap-git/subprojects/packagefiles/wrap_git_builddef/meson.build deleted file mode 100644 index 2570f77..0000000 --- a/test cases/unit/78 wrap-git/subprojects/packagefiles/wrap_git_builddef/meson.build +++ /dev/null @@ -1,3 +0,0 @@ -project('foo', 'c') - -exe = executable('app', 'main.c') diff --git a/test cases/unit/78 wrap-git/subprojects/wrap_git_upstream/main.c b/test cases/unit/78 wrap-git/subprojects/wrap_git_upstream/main.c deleted file mode 100644 index 8488f4e..0000000 --- a/test cases/unit/78 wrap-git/subprojects/wrap_git_upstream/main.c +++ /dev/null @@ -1,4 +0,0 @@ -int main(void) -{ - return 0; -} diff --git a/test cases/unit/79 user options for subproject/75 user options for subproject/.gitignore b/test cases/unit/79 user options for subproject/75 user options for subproject/.gitignore new file mode 100644 index 0000000..4976afc --- /dev/null +++ b/test cases/unit/79 user options for subproject/75 user options for subproject/.gitignore @@ -0,0 +1 @@ +subprojects/* diff --git a/test cases/unit/79 user options for subproject/75 user options for subproject/meson.build b/test cases/unit/79 user options for subproject/75 user options for subproject/meson.build new file mode 100644 index 0000000..0bc395b --- /dev/null +++ b/test cases/unit/79 user options for subproject/75 user options for subproject/meson.build @@ -0,0 +1,3 @@ +project('user option for subproject') + +p = subproject('sub') diff --git a/test cases/unit/80 global-rpath/meson.build b/test cases/unit/80 global-rpath/meson.build new file mode 100644 index 0000000..c67d9e0 --- /dev/null +++ b/test cases/unit/80 global-rpath/meson.build @@ -0,0 +1,3 @@ +project('global-rpath', 'cpp') +yonder_dep = dependency('yonder') +executable('rpathified', 'rpathified.cpp', dependencies: [yonder_dep], install: true) diff --git a/test cases/unit/80 global-rpath/rpathified.cpp b/test cases/unit/80 global-rpath/rpathified.cpp new file mode 100644 index 0000000..3788906 --- /dev/null +++ b/test cases/unit/80 global-rpath/rpathified.cpp @@ -0,0 +1,6 @@ +#include +#include +int main(int argc, char **argv) +{ + return strcmp(yonder(), "AB54 6BR"); +} diff --git a/test cases/unit/80 global-rpath/yonder/meson.build b/test cases/unit/80 global-rpath/yonder/meson.build new file mode 100644 index 0000000..e32f383 --- /dev/null +++ b/test cases/unit/80 global-rpath/yonder/meson.build @@ -0,0 +1,5 @@ +project('yonder', 'cpp') +yonder = shared_library('yonder', 'yonder.cpp', install: true) +install_headers('yonder.h') +pkgconfig = import('pkgconfig') +pkgconfig.generate(yonder) diff --git a/test cases/unit/80 global-rpath/yonder/yonder.cpp b/test cases/unit/80 global-rpath/yonder/yonder.cpp new file mode 100644 index 0000000..b182d34 --- /dev/null +++ b/test cases/unit/80 global-rpath/yonder/yonder.cpp @@ -0,0 +1,3 @@ +#include "yonder.h" + +char *yonder(void) { return "AB54 6BR"; } diff --git a/test cases/unit/80 global-rpath/yonder/yonder.h b/test cases/unit/80 global-rpath/yonder/yonder.h new file mode 100644 index 0000000..9d9ad16 --- /dev/null +++ b/test cases/unit/80 global-rpath/yonder/yonder.h @@ -0,0 +1 @@ +char *yonder(void); diff --git a/test cases/unit/81 wrap-git/meson.build b/test cases/unit/81 wrap-git/meson.build new file mode 100644 index 0000000..b0af30a --- /dev/null +++ b/test cases/unit/81 wrap-git/meson.build @@ -0,0 +1,4 @@ +project('test-wrap-git') + +exe = subproject('wrap_git').get_variable('exe') +test('test1', exe) diff --git a/test cases/unit/81 wrap-git/subprojects/packagefiles/wrap_git_builddef/meson.build b/test cases/unit/81 wrap-git/subprojects/packagefiles/wrap_git_builddef/meson.build new file mode 100644 index 0000000..2570f77 --- /dev/null +++ b/test cases/unit/81 wrap-git/subprojects/packagefiles/wrap_git_builddef/meson.build @@ -0,0 +1,3 @@ +project('foo', 'c') + +exe = executable('app', 'main.c') diff --git a/test cases/unit/81 wrap-git/subprojects/wrap_git_upstream/main.c b/test cases/unit/81 wrap-git/subprojects/wrap_git_upstream/main.c new file mode 100644 index 0000000..8488f4e --- /dev/null +++ b/test cases/unit/81 wrap-git/subprojects/wrap_git_upstream/main.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} -- cgit v1.1