aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2017-01-03 16:03:18 -0500
committerGitHub <noreply@github.com>2017-01-03 16:03:18 -0500
commit55cdba635e61b68658e0d209a58cfb2f1537df93 (patch)
tree03ce2b4ba4aace32f64f8c43478ba60366fdac72
parent5ff97b0f357a79556667668e06914a50970f86d6 (diff)
parentd94f64ded1382ff768ce2c2900a8e6efcf3a11fb (diff)
downloadmeson-55cdba635e61b68658e0d209a58cfb2f1537df93.zip
meson-55cdba635e61b68658e0d209a58cfb2f1537df93.tar.gz
meson-55cdba635e61b68658e0d209a58cfb2f1537df93.tar.bz2
Merge pull request #1260 from mesonbuild/subproj_defaults
Can set subproject option defaults from command line and master project
-rw-r--r--mesonbuild/interpreter.py59
-rw-r--r--mesonbuild/optinterpreter.py7
-rw-r--r--test cases/unit/3 subproject defaults/meson.build11
-rw-r--r--test cases/unit/3 subproject defaults/meson_options.txt3
-rw-r--r--test cases/unit/3 subproject defaults/subprojects/foob/meson.build12
-rw-r--r--test cases/unit/3 subproject defaults/subprojects/foob/meson_options.txt5
6 files changed, 86 insertions, 11 deletions
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index b3edba1..ec82ec9 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -1140,7 +1140,8 @@ class MesonMain(InterpreterObject):
class Interpreter(InterpreterBase):
- def __init__(self, build, backend, subproject='', subdir='', subproject_dir='subprojects'):
+ def __init__(self, build, backend, subproject='', subdir='', subproject_dir='subprojects',
+ default_project_options=[]):
super().__init__(build.environment.get_source_dir(), subdir)
self.build = build
self.environment = build.environment
@@ -1148,12 +1149,7 @@ class Interpreter(InterpreterBase):
self.backend = backend
self.subproject = subproject
self.subproject_dir = subproject_dir
- option_file = os.path.join(self.source_root, self.subdir, 'meson_options.txt')
- if os.path.exists(option_file):
- oi = optinterpreter.OptionInterpreter(self.subproject, \
- self.build.environment.cmd_line_options.projectoptions)
- oi.process(option_file)
- self.build.environment.merge_options(oi.options)
+ self.option_file = os.path.join(self.source_root, self.subdir, 'meson_options.txt')
self.load_root_meson_file()
self.sanity_check_ast()
self.builtin.update({'meson': MesonMain(build, self)})
@@ -1162,6 +1158,7 @@ class Interpreter(InterpreterBase):
self.args_frozen = False
self.subprojects = {}
self.subproject_stack = []
+ self.default_project_options = default_project_options[:] # Passed from the outside, only used in subprojects.
self.build_func_dict()
self.parse_project()
self.builtin['build_machine'] = BuildMachine(self.coredata.compilers)
@@ -1420,7 +1417,8 @@ class Interpreter(InterpreterBase):
os.makedirs(os.path.join(self.build.environment.get_build_dir(), subdir), exist_ok=True)
self.args_frozen = True
mlog.log('\nExecuting subproject ', mlog.bold(dirname), '.\n', sep='')
- subi = Interpreter(self.build, self.backend, dirname, subdir, self.subproject_dir)
+ subi = Interpreter(self.build, self.backend, dirname, subdir, self.subproject_dir,
+ mesonlib.stringlistify(kwargs.get('default_options', [])))
subi.subprojects = self.subprojects
subi.subproject_stack = self.subproject_stack + [dirname]
@@ -1490,19 +1488,53 @@ class Interpreter(InterpreterBase):
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.
if not self.environment.had_argument_for(key):
self.coredata.set_builtin_option(key, value)
# If this was set on the command line, do not override.
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 + '='
+ was_found = False
+ for i in default_options:
+ if i.startswith(pref):
+ was_found = True
+ break
+ if was_found:
+ break
+ defopt = self.subproject + ':' + defopt
+ newoptions = [defopt] + self.environment.cmd_line_options.projectoptions
+ self.environment.cmd_line_options.projectoptions = newoptions
@stringArgs
def func_project(self, node, args, kwargs):
+ if self.environment.first_invocation and ('default_options' in kwargs or \
+ len(self.default_project_options) > 0):
+ self.parse_default_options(kwargs['default_options'])
if not self.is_subproject():
self.build.project_name = args[0]
- if self.environment.first_invocation and 'default_options' in kwargs:
- self.parse_default_options(kwargs['default_options'])
+ if os.path.exists(self.option_file):
+ oi = optinterpreter.OptionInterpreter(self.subproject, \
+ self.build.environment.cmd_line_options.projectoptions,
+ )
+ oi.process(self.option_file)
+ self.build.environment.merge_options(oi.options)
if len(args) < 2:
raise InvalidArguments('Not enough arguments to project(). Needs at least the project name and one language')
self.active_projectname = args[0]
@@ -1768,7 +1800,12 @@ requirements use the version keyword argument instead.''')
dirname, varname = self.get_subproject_infos(kwargs)
# Try to execute the subproject
try:
- self.do_subproject(dirname, {})
+ sp_kwargs = {}
+ try:
+ sp_kwargs['default_options'] = kwargs['default_options']
+ except KeyError:
+ pass
+ self.do_subproject(dirname, sp_kwargs)
# Invalid code is always an error
except InvalidCode:
raise
diff --git a/mesonbuild/optinterpreter.py b/mesonbuild/optinterpreter.py
index ac23fe8..089eb2c 100644
--- a/mesonbuild/optinterpreter.py
+++ b/mesonbuild/optinterpreter.py
@@ -71,8 +71,15 @@ class OptionInterpreter:
def __init__(self, subproject, command_line_options):
self.options = {}
self.subproject = subproject
+ self.sbprefix = subproject + ':'
self.cmd_line_options = {}
for o in command_line_options:
+ if self.subproject != '': # Strip the beginning.
+ if not o.startswith(self.sbprefix):
+ continue
+ else:
+ if ':' in o:
+ continue
try:
(key, value) = o.split('=', 1)
except ValueError:
diff --git a/test cases/unit/3 subproject defaults/meson.build b/test cases/unit/3 subproject defaults/meson.build
new file mode 100644
index 0000000..3bf05d0
--- /dev/null
+++ b/test cases/unit/3 subproject defaults/meson.build
@@ -0,0 +1,11 @@
+project('subproject defaults', 'c',
+ default_options : ['defopoverride=defopt', # This should be overridden.
+ 'fromcmdline=defopt'] # This should get the value set in command line.
+ )
+
+subproject('foob', default_options : ['fromspfunc=spfunc', 'fromspfunconly=spfunc'])
+
+assert(get_option('fromcmdline') == 'cmdline', 'Default option defined in cmd line is incorrect: ' + get_option('fromcmdline'))
+assert(get_option('defopoverride') == 'defopt', 'Default option without cmd line override is incorrect: ' + get_option('defopoverride'))
+assert(get_option('fromoptfile') == 'optfile', 'Default value from option file is incorrect: ' + get_option('fromoptfile'))
+
diff --git a/test cases/unit/3 subproject defaults/meson_options.txt b/test cases/unit/3 subproject defaults/meson_options.txt
new file mode 100644
index 0000000..b63f512
--- /dev/null
+++ b/test cases/unit/3 subproject defaults/meson_options.txt
@@ -0,0 +1,3 @@
+option('defopoverride', type : 'string', value : 'optfile', description : 'A value for overriding.')
+option('fromcmdline', type : 'string', value : 'optfile', description : 'A value for overriding.')
+option('fromoptfile', type : 'string', value : 'optfile', description : 'A value for not overriding.')
diff --git a/test cases/unit/3 subproject defaults/subprojects/foob/meson.build b/test cases/unit/3 subproject defaults/subprojects/foob/meson.build
new file mode 100644
index 0000000..69f01d1
--- /dev/null
+++ b/test cases/unit/3 subproject defaults/subprojects/foob/meson.build
@@ -0,0 +1,12 @@
+project('foob', 'c',
+ default_options : ['defopoverride=s_defopt', # This should be overridden.
+ 'fromspfunc=s_defopt', # This is specified with a default_options kwarg to subproject()
+ 'fromcmdline=s_defopt'] # This should get the value set in command line.
+ )
+
+assert(get_option('fromcmdline') == 's_cmdline', 'Default option defined in cmd line is incorrect: ' + get_option('fromcmdline'))
+assert(get_option('fromspfunc') == 'spfunc', 'Default option set with subproject() incorrect: ' + get_option('fromspfunc'))
+assert(get_option('fromspfunconly') == 'spfunc', 'Default option set with subproject() incorrect: ' + get_option('fromspfunc'))
+assert(get_option('defopoverride') == 's_defopt', 'Default option without cmd line override is incorrect: ' + get_option('defopoverride'))
+assert(get_option('fromoptfile') == 's_optfile', 'Default value from option file is incorrect: ' + get_option('fromoptfile'))
+
diff --git a/test cases/unit/3 subproject defaults/subprojects/foob/meson_options.txt b/test cases/unit/3 subproject defaults/subprojects/foob/meson_options.txt
new file mode 100644
index 0000000..a9a615e
--- /dev/null
+++ b/test cases/unit/3 subproject defaults/subprojects/foob/meson_options.txt
@@ -0,0 +1,5 @@
+option('defopoverride', type : 'string', value : 's_optfile', description : 'A value for overriding.')
+option('fromcmdline', type : 'string', value : 's_optfile', description : 'A value for overriding.')
+option('fromspfunc', type : 'string', value : 's_optfile', description : 'A value for overriding.')
+option('fromspfunconly', type : 'string', value : 's_optfile', description : 'A value for overriding.')
+option('fromoptfile', type : 'string', value : 's_optfile', description : 'A value for not overriding.')