aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/coredata.py41
-rw-r--r--mesonbuild/environment.py2
-rw-r--r--mesonbuild/interpreter.py142
-rw-r--r--mesonbuild/optinterpreter.py45
-rwxr-xr-xrun_tests.py1
-rwxr-xr-xrun_unittests.py60
-rw-r--r--test cases/unit/19 bad command line options/meson.build17
-rw-r--r--test cases/unit/19 bad command line options/meson_options.txt16
-rw-r--r--test cases/unit/19 bad command line options/subprojects/one/meson.build15
-rw-r--r--test cases/unit/19 bad command line options/subprojects/one/meson_options.txt15
-rw-r--r--test cases/unit/27 forcefallback/meson.build2
-rw-r--r--test cases/unit/30 command line/meson.build8
-rw-r--r--test cases/unit/30 command line/meson_options.txt1
-rw-r--r--test cases/unit/30 command line/subprojects/subp/meson.build3
-rw-r--r--test cases/unit/30 command line/subprojects/subp/meson_options.txt1
15 files changed, 130 insertions, 239 deletions
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index d0521b6..2d44b99 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 9b252a2..074bd75 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 ffe942f..86c55e4 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 7455c48..4207f45 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 1fd72b2..d905e12 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 5d60d99..313b07c 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 b1670c0..0000000
--- 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 fc09712..0000000
--- 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 85ef742..0000000
--- 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 7d90fae..0000000
--- 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 d5c06c3..8d84a60 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 1006f49..6207ca5 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 0000000..7acc112
--- /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 0000000..cf79fa4
--- /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 0000000..8c50615
--- /dev/null
+++ b/test cases/unit/30 command line/subprojects/subp/meson_options.txt
@@ -0,0 +1 @@
+option('subp_opt', type : 'string', value : 'default1')