From 7c4736d27f4c5d7844a44addc0305e4354440074 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Sun, 13 May 2018 10:36:58 -0400 Subject: [PATCH] Convert args.projectoptions into a dict This simplifies a lot of code, and centralize "key=value" parsing in a single place. Unknown command line options becomes an hard error instead of merely printing warning message. It has been warning it would become an hard error for a while now. This has exceptions though, any unknown option starting with "_" or "b_" are ignored because they depend on which languages gets added and which compiler gets selected. Also any option for unknown subproject are ignored because they depend on which subproject actually gets built. Also write more command line parsing tests. "19 bad command line options" is removed because bad cmd line option became hard error and it's covered with new tests in "30 command line". --- mesonbuild/coredata.py | 41 ++--- mesonbuild/environment.py | 2 +- mesonbuild/interpreter.py | 142 ++++++++---------- mesonbuild/optinterpreter.py | 45 +----- run_tests.py | 1 + run_unittests.py | 60 +++++--- .../19 bad command line options/meson.build | 17 --- .../meson_options.txt | 16 -- .../subprojects/one/meson.build | 15 -- .../subprojects/one/meson_options.txt | 15 -- test cases/unit/27 forcefallback/meson.build | 2 +- test cases/unit/30 command line/meson.build | 8 +- .../unit/30 command line/meson_options.txt | 1 + .../subprojects/subp/meson.build | 3 + .../subprojects/subp/meson_options.txt | 1 + 15 files changed, 130 insertions(+), 239 deletions(-) delete mode 100644 test cases/unit/19 bad command line options/meson.build delete mode 100644 test cases/unit/19 bad command line options/meson_options.txt delete mode 100644 test cases/unit/19 bad command line options/subprojects/one/meson.build delete mode 100644 test cases/unit/19 bad command line options/subprojects/one/meson_options.txt create mode 100644 test cases/unit/30 command line/meson_options.txt create mode 100644 test cases/unit/30 command line/subprojects/subp/meson.build create mode 100644 test cases/unit/30 command line/subprojects/subp/meson_options.txt diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index d0521b6c0..2d44b9967 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -301,18 +301,11 @@ class CoreData: args = [key] + builtin_options[key][1:-1] + [value] self.builtins[key] = builtin_options[key][0](*args) - def init_backend_options(self, backend_name, options): + def init_backend_options(self, backend_name): if backend_name == 'ninja': self.backend_options['backend_max_links'] = UserIntegerOption('backend_max_links', 'Maximum number of linker processes to run or 0 for no limit', 0, None, 0) - for o in options: - key, value = o.split('=', 1) - if not key.startswith('backend_'): - continue - if key not in self.backend_options: - raise MesonException('Unknown backend option %s' % key) - self.backend_options[key].set_value(value) def get_builtin_option(self, optname): if optname in self.builtins: @@ -497,27 +490,6 @@ def register_builtin_arguments(parser): parser.add_argument('-D', action='append', dest='projectoptions', default=[], metavar="option", help='Set the value of an option, can be used several times to set multiple options.') -def filter_builtin_options(args): - """Filter out any builtin arguments passed as -- instead of -D. - - Error if an argument is passed with -- and -D - """ - for name in builtin_options: - cmdline_name = get_builtin_option_cmdline_name(name) - # Chekc if user passed -Doption=value or --option=value - has_dashdash = hasattr(args, name) - has_dashd = any([a.startswith('{}='.format(name)) for a in args.projectoptions]) - - # Passing both is ambigous, abort - if has_dashdash and has_dashd: - raise MesonException( - 'Got argument {0} as both -D{0} and {1}. Pick one.'.format(name, cmdline_name)) - - # Pretend --option never existed - if has_dashdash: - args.projectoptions.append('{}={}'.format(name, getattr(args, name))) - delattr(args, name) - def create_options_dict(options): result = {} for o in options: @@ -529,9 +501,18 @@ def create_options_dict(options): return result def parse_cmd_line_options(args): - filter_builtin_options(args) args.cmd_line_options = create_options_dict(args.projectoptions) + # Merge builtin options set with --option into the dict. + for name in builtin_options: + value = getattr(args, name, None) + if value is not None: + if name in args.cmd_line_options: + cmdline_name = get_builtin_option_cmdline_name(name) + raise MesonException( + 'Got argument {0} as both -D{0} and {1}. Pick one.'.format(name, cmdline_name)) + args.cmd_line_options[name] = value + delattr(args, name) builtin_options = { 'buildtype': [UserComboOption, 'Build type to use.', ['plain', 'debug', 'debugoptimized', 'release', 'minsize'], 'debug'], diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index 9b252a2bf..074bd75e8 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -288,7 +288,7 @@ class Environment: self.cross_info = CrossBuildInfo(self.coredata.cross_file) else: self.cross_info = None - self.cmd_line_options = options + self.cmd_line_options = options.cmd_line_options # List of potential compilers. if mesonlib.is_windows(): diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index ffe942fc8..86c55e4ee 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -1755,7 +1755,7 @@ permitted_kwargs = {'add_global_arguments': {'language'}, class Interpreter(InterpreterBase): def __init__(self, build, backend=None, subproject='', subdir='', subproject_dir='subprojects', - modules = None, default_project_options=[]): + modules = None, default_project_options=None): super().__init__(build.environment.get_source_dir(), subdir) self.an_unpicklable_object = mesonlib.an_unpicklable_object self.build = build @@ -1781,7 +1781,11 @@ class Interpreter(InterpreterBase): self.global_args_frozen = False # implies self.project_args_frozen self.subprojects = {} self.subproject_stack = [] - self.default_project_options = default_project_options[:] # Passed from the outside, only used in subprojects. + # Passed from the outside, only used in subprojects. + if default_project_options: + self.default_project_options = default_project_options.copy() + else: + self.default_project_options = {} self.build_func_dict() # build_def_files needs to be defined before parse_project is called self.build_def_files = [os.path.join(self.subdir, environment.build_filename)] @@ -2106,6 +2110,8 @@ external dependencies (including libraries) must go to "dependencies".''') return self.do_subproject(dirname, kwargs) def do_subproject(self, dirname, kwargs): + 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] == '.': @@ -2142,7 +2148,7 @@ external dependencies (including libraries) must go to "dependencies".''') with mlog.nested(): mlog.log('\nExecuting subproject ', mlog.bold(dirname), '.\n', sep='') subi = Interpreter(self.build, self.backend, dirname, subdir, self.subproject_dir, - self.modules, mesonlib.stringlistify(kwargs.get('default_options', []))) + self.modules, default_options) subi.subprojects = self.subprojects subi.subproject_stack = self.subproject_stack + [dirname] @@ -2206,53 +2212,34 @@ to directly access options of other subprojects.''') raise InterpreterException('configuration_data takes no arguments') return ConfigurationDataHolder() - def parse_default_options(self, default_options): - default_options = listify(default_options) - for option in default_options: - if not isinstance(option, str): - mlog.debug(option) - raise InterpreterException('Default options must be strings') - if '=' not in option: - raise InterpreterException('All default options must be of type key=value.') - key, value = option.split('=', 1) - if coredata.is_builtin_option(key): - if self.subproject != '': - continue # Only the master project is allowed to set global options. - newoptions = [option] + self.environment.cmd_line_options.projectoptions - self.environment.cmd_line_options.projectoptions = newoptions - else: - # Option values set with subproject() default_options override those - # set in project() default_options. - pref = key + '=' - for i in self.default_project_options: - if i.startswith(pref): - option = i - break - # If we are in a subproject, add the subproject prefix to option - # name. - if self.subproject != '': - option = self.subproject + ':' + option - newoptions = [option] + self.environment.cmd_line_options.projectoptions - self.environment.cmd_line_options.projectoptions = newoptions - # Add options that are only in default_options. - for defopt in self.default_project_options: - key, value = defopt.split('=') - pref = key + '=' - for i in default_options: - if i.startswith(pref): - break - else: - defopt = self.subproject + ':' + defopt - newoptions = [defopt] + self.environment.cmd_line_options.projectoptions - self.environment.cmd_line_options.projectoptions = newoptions - - def set_builtin_options(self): - # Create a dict containing only builtin options, then use - # coredata.set_options() because it already has code to set the prefix - # option first to sanitize all other options. - options = coredata.create_options_dict(self.environment.cmd_line_options.projectoptions) - options = {k: v for k, v in options.items() if coredata.is_builtin_option(k)} - self.coredata.set_options(options) + def set_options(self, default_options): + # Set default options as if they were passed to the command line. + # Subprojects can only define default for user options. + for k, v in default_options.items(): + if self.subproject: + if optinterpreter.is_invalid_name(k): + continue + k = self.subproject + ':' + k + self.environment.cmd_line_options.setdefault(k, v) + + # 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 = {} + for k, v in self.environment.cmd_line_options.items(): + if self.subproject: + if not k.startswith(self.subproject + ':'): + continue + elif k not in coredata.get_builtin_options(): + if ':' in k: + continue + if optinterpreter.is_invalid_name(k): + continue + options[k] = v + + self.coredata.set_options(options, self.subproject) def set_backend(self): # The backend is already set when parsing subprojects @@ -2282,7 +2269,10 @@ to directly access options of other subprojects.''') else: raise InterpreterException('Unknown backend "%s".' % backend) - self.coredata.init_backend_options(backend, self.environment.cmd_line_options.projectoptions) + 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) @stringArgs @permittedKwargs(permitted_kwargs['project']) @@ -2293,20 +2283,20 @@ to directly access options of other subprojects.''') proj_langs = args[1:] if ':' in proj_name: raise InvalidArguments("Project name {!r} must not contain ':'".format(proj_name)) - default_options = kwargs.get('default_options', []) - if self.environment.first_invocation and (len(default_options) > 0 or - len(self.default_project_options) > 0): - self.parse_default_options(default_options) - if not self.is_subproject(): - self.build.project_name = proj_name - self.set_builtin_options() + if os.path.exists(self.option_file): - oi = optinterpreter.OptionInterpreter(self.subproject, - self.build.environment.cmd_line_options.projectoptions, - ) + oi = optinterpreter.OptionInterpreter(self.subproject) oi.process(self.option_file) self.coredata.merge_user_options(oi.options) + + default_options = mesonlib.stringlistify(kwargs.get('default_options', [])) + default_options = coredata.create_options_dict(default_options) + default_options.update(self.default_project_options) + self.set_options(default_options) self.set_backend() + + if not self.is_subproject(): + self.build.project_name = proj_name self.active_projectname = proj_name self.project_version = kwargs.get('version', 'undefined') if self.build.project_version is None: @@ -2450,17 +2440,14 @@ to directly access options of other subprojects.''') cross_comp.sanity_check(self.environment.get_scratch_dir(), self.environment) self.coredata.cross_compilers[lang] = cross_comp new_options.update(cross_comp.get_options()) + optprefix = lang + '_' - for i in new_options: - if not i.startswith(optprefix): - raise InterpreterException('Internal error, %s has incorrect prefix.' % i) - cmd_prefix = i + '=' - for cmd_arg in self.environment.cmd_line_options.projectoptions: - if cmd_arg.startswith(cmd_prefix): - value = cmd_arg.split('=', 1)[1] - new_options[i].set_value(value) - new_options.update(self.coredata.compiler_options) - self.coredata.compiler_options = new_options + for k, o in new_options.items(): + if not k.startswith(optprefix): + raise InterpreterException('Internal error, %s has incorrect prefix.' % k) + if k in self.environment.cmd_line_options: + o.set_value(self.environment.cmd_line_options[k]) + self.coredata.compiler_options.setdefault(k, o) # Unlike compiler and linker flags, preprocessor flags are not in # compiler_options because they are not visible to user. @@ -2510,19 +2497,14 @@ to directly access options of other subprojects.''') def add_base_options(self, compiler): enabled_opts = [] - proj_opt = self.environment.cmd_line_options.projectoptions for optname in compiler.base_options: if optname in self.coredata.base_options: continue oobj = compilers.base_options[optname] - for po in proj_opt: - if po.startswith(optname + '='): - opt, value = po.split('=', 1) - oobj.set_value(value) - if oobj.value: - enabled_opts.append(opt) - break - self.coredata.base_options[optname] = oobj + if optname in self.environment.cmd_line_options: + oobj.set_value(self.environment.cmd_line_options[optname]) + enabled_opts.append(optname) + self.coredata. base_options[optname] = oobj self.emit_base_options_warnings(enabled_opts) def program_from_cross_file(self, prognames, silent=False): diff --git a/mesonbuild/optinterpreter.py b/mesonbuild/optinterpreter.py index 7455c484e..4207f459f 100644 --- a/mesonbuild/optinterpreter.py +++ b/mesonbuild/optinterpreter.py @@ -15,7 +15,6 @@ import os, re import functools -from . import mlog from . import mparser from . import coredata from . import mesonlib @@ -125,48 +124,9 @@ option_types = {'string': StringParser, } class OptionInterpreter: - def __init__(self, subproject, command_line_options): + def __init__(self, subproject): self.options = {} self.subproject = subproject - self.sbprefix = subproject + ':' - self.cmd_line_options = {} - for o in command_line_options: - if self.subproject != '': # Strip the beginning. - # Ignore options that aren't for this subproject - if not o.startswith(self.sbprefix): - continue - try: - (key, value) = o.split('=', 1) - except ValueError: - raise OptionException('Option {!r} must have a value separated by equals sign.'.format(o)) - # Ignore subproject options if not fetching subproject options - if self.subproject == '' and ':' in key: - continue - self.cmd_line_options[key] = value - - def get_bad_options(self): - subproj_len = len(self.subproject) - if subproj_len > 0: - subproj_len += 1 - retval = [] - # The options need to be sorted (e.g. here) to get consistent - # error messages (on all platforms) which is required by some test - # cases that check (also) the order of these options. - for option in sorted(self.cmd_line_options): - if option in list(self.options) + forbidden_option_names: - continue - if any(option[subproj_len:].startswith(p) for p in forbidden_prefixes): - continue - retval += [option] - return retval - - def check_for_bad_options(self): - bad = self.get_bad_options() - if bad: - sub = 'In subproject {}: '.format(self.subproject) if self.subproject else '' - mlog.warning( - '{}Unknown command line options: "{}"\n' - 'This will become a hard error in a future Meson release.'.format(sub, ', '.join(bad))) def process(self, option_file): try: @@ -187,7 +147,6 @@ class OptionInterpreter: e.colno = cur.colno e.file = os.path.join('meson_options.txt') raise e - self.check_for_bad_options() def reduce_single(self, arg): if isinstance(arg, str): @@ -243,6 +202,4 @@ class OptionInterpreter: opt = option_types[opt_type](opt_name, kwargs.pop('description', ''), kwargs) if opt.description == '': opt.description = opt_name - if opt_name in self.cmd_line_options: - opt.set_value(self.cmd_line_options[opt_name]) self.options[opt_name] = opt diff --git a/run_tests.py b/run_tests.py index 1fd72b2df..d905e125d 100755 --- a/run_tests.py +++ b/run_tests.py @@ -153,6 +153,7 @@ def get_fake_options(prefix): opts.cross_file = None opts.wrap_mode = None opts.prefix = prefix + opts.cmd_line_options = {} return opts def should_run_linux_cross_tests(): diff --git a/run_unittests.py b/run_unittests.py index 5d60d99d0..313b07c9b 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -2072,6 +2072,8 @@ recommended as it can lead to undefined behaviour on some platforms''') obj = mesonbuild.coredata.load(self.builddir) self.assertEqual(obj.builtins['default_library'].value, 'static') self.assertEqual(obj.builtins['warning_level'].value, '1') + self.assertEqual(obj.user_options['set_sub_opt'].value, True) + self.assertEqual(obj.user_options['subp:subp_opt'].value, 'default3') self.wipe() # warning_level is special, it's --warnlevel instead of --warning-level @@ -2114,6 +2116,45 @@ recommended as it can lead to undefined behaviour on some platforms''') self.assertEqual(obj.builtins['default_library'].value, 'shared') self.wipe() + # Should fail on unknown options + with self.assertRaises(subprocess.CalledProcessError) as cm: + self.init(testdir, extra_args=['-Dbad=1', '-Dfoo=2', '-Dwrong_link_args=foo']) + self.assertNotEqual(0, cm.exception.returncode) + self.assertIn('Unknown options: "bad, foo, wrong_link_args"', cm.exception.output) + self.wipe() + + # Should fail on malformed option + with self.assertRaises(subprocess.CalledProcessError) as cm: + self.init(testdir, extra_args=['-Dfoo']) + self.assertNotEqual(0, cm.exception.returncode) + self.assertIn('Option \'foo\' must have a value separated by equals sign.', cm.exception.output) + self.init(testdir) + with self.assertRaises(subprocess.CalledProcessError) as cm: + self.setconf('-Dfoo') + self.assertNotEqual(0, cm.exception.returncode) + self.assertIn('Option \'foo\' must have a value separated by equals sign.', cm.exception.output) + self.wipe() + + # It is not an error to set wrong option for unknown subprojects or + # language because we don't have control on which one will be selected. + self.init(testdir, extra_args=['-Dc_wrong=1', '-Dwrong:bad=1', '-Db_wrong=1']) + self.wipe() + + # Test we can set subproject option + self.init(testdir, extra_args=['-Dsubp:subp_opt=foo']) + obj = mesonbuild.coredata.load(self.builddir) + self.assertEqual(obj.user_options['subp:subp_opt'].value, 'foo') + self.wipe() + + # c_args value should be parsed with shlex + self.init(testdir, extra_args=['-Dc_args=foo bar "one two"']) + obj = mesonbuild.coredata.load(self.builddir) + self.assertEqual(obj.compiler_options['c_args'].value, ['foo', 'bar', 'one two']) + self.setconf('-Dc_args="foo bar" one two') + obj = mesonbuild.coredata.load(self.builddir) + self.assertEqual(obj.compiler_options['c_args'].value, ['foo bar', 'one', 'two']) + self.wipe() + def test_compiler_options_documented(self): ''' Test that C and C++ compiler options and base options are documented in @@ -2271,25 +2312,6 @@ class FailureTests(BasePlatformTests): ''' self.assertMesonRaises(code, "Method.*configtool.*is invalid.*internal") - def test_bad_option(self): - tdir = os.path.join(self.unit_test_dir, '19 bad command line options') - os.environ['MESON_FORCE_BACKTRACE'] = '1' - self.init(tdir, extra_args=['-Dopt=bar', '-Dc_args=-Wall'], inprocess=True) - self.wipe() - out = self.init(tdir, extra_args=['-Dfoo=bar', '-Dbad=true'], inprocess=True) - self.assertRegex( - out, r'Unknown command line options: "bad, foo"') - - def test_bad_option_subproject(self): - tdir = os.path.join(self.unit_test_dir, '19 bad command line options') - os.environ['MESON_FORCE_BACKTRACE'] = '1' - self.init(tdir, extra_args=['-Done:one=bar'], inprocess=True) - self.wipe() - out = self.init(tdir, extra_args=['-Done:two=bar'], inprocess=True) - self.assertRegex( - out, - r'In subproject one: Unknown command line options: "one:two"') - def test_objc_cpp_detection(self): ''' Test that when we can't detect objc or objcpp, we fail gracefully. diff --git a/test cases/unit/19 bad command line options/meson.build b/test cases/unit/19 bad command line options/meson.build deleted file mode 100644 index b1670c0e3..000000000 --- a/test cases/unit/19 bad command line options/meson.build +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright © 2017 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -project('Bad command line options') - -one = subproject('one') diff --git a/test cases/unit/19 bad command line options/meson_options.txt b/test cases/unit/19 bad command line options/meson_options.txt deleted file mode 100644 index fc0971257..000000000 --- a/test cases/unit/19 bad command line options/meson_options.txt +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright © 2017 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -option('opt', type : 'string', description : 'An argument') -option('good', type : 'boolean', value : true, description : 'another argument') diff --git a/test cases/unit/19 bad command line options/subprojects/one/meson.build b/test cases/unit/19 bad command line options/subprojects/one/meson.build deleted file mode 100644 index 85ef74210..000000000 --- a/test cases/unit/19 bad command line options/subprojects/one/meson.build +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright © 2017 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -project('one subproject', default_options : [ 'b_colorout=never' ]) diff --git a/test cases/unit/19 bad command line options/subprojects/one/meson_options.txt b/test cases/unit/19 bad command line options/subprojects/one/meson_options.txt deleted file mode 100644 index 7d90fae80..000000000 --- a/test cases/unit/19 bad command line options/subprojects/one/meson_options.txt +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright © 2017 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -option('one', type : 'string', description : 'an option') diff --git a/test cases/unit/27 forcefallback/meson.build b/test cases/unit/27 forcefallback/meson.build index d5c06c342..8d84a6035 100644 --- a/test cases/unit/27 forcefallback/meson.build +++ b/test cases/unit/27 forcefallback/meson.build @@ -1,5 +1,5 @@ project('mainproj', 'c', - default_options : ['wrap_mode=forcefallback']) + default_options : []) zlib_dep = dependency('zlib', fallback: ['notzlib', 'zlib_dep']) notfound_dep = dependency('cannotabletofind', fallback: ['definitelynotfound', 'some_var'], required : false) diff --git a/test cases/unit/30 command line/meson.build b/test cases/unit/30 command line/meson.build index 1006f49cd..6207ca5e2 100644 --- a/test cases/unit/30 command line/meson.build +++ b/test cases/unit/30 command line/meson.build @@ -1,3 +1,9 @@ project('command line test', 'c', - default_options : ['default_library=static'] + default_options : ['default_library=static', 'set_sub_opt=true'] ) + +if get_option('set_sub_opt') + subproject('subp', default_options : ['subp_opt=default3']) +else + subproject('subp') +endif diff --git a/test cases/unit/30 command line/meson_options.txt b/test cases/unit/30 command line/meson_options.txt new file mode 100644 index 000000000..7acc112d8 --- /dev/null +++ b/test cases/unit/30 command line/meson_options.txt @@ -0,0 +1 @@ +option('set_sub_opt', type : 'boolean', value : false) diff --git a/test cases/unit/30 command line/subprojects/subp/meson.build b/test cases/unit/30 command line/subprojects/subp/meson.build new file mode 100644 index 000000000..cf79fa42a --- /dev/null +++ b/test cases/unit/30 command line/subprojects/subp/meson.build @@ -0,0 +1,3 @@ +project('subp', + default_options : ['subp_opt=default2'] +) diff --git a/test cases/unit/30 command line/subprojects/subp/meson_options.txt b/test cases/unit/30 command line/subprojects/subp/meson_options.txt new file mode 100644 index 000000000..8c50615dd --- /dev/null +++ b/test cases/unit/30 command line/subprojects/subp/meson_options.txt @@ -0,0 +1 @@ +option('subp_opt', type : 'string', value : 'default1')