From 910dcbf290242fc099a7dd14f0c55cec9ce5dd7e Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Sun, 18 Oct 2015 03:33:34 +0300 Subject: [PATCH] Projects can specify default values for options. --- environment.py | 9 ++-- interpreter.py | 42 ++++++++++++++++++- .../common/94 default options/meson.build | 15 +++++++ test cases/failing/22 assert/meson.build | 3 ++ 4 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 test cases/common/94 default options/meson.build create mode 100644 test cases/failing/22 assert/meson.build diff --git a/environment.py b/environment.py index 41520d143..c4878f447 100644 --- a/environment.py +++ b/environment.py @@ -12,9 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -import re -import coredata -from glob import glob +import os, re, subprocess +import coredata, mesonlib from compilers import * import configparser @@ -68,13 +67,15 @@ class Environment(): try: cdf = os.path.join(self.get_build_dir(), Environment.coredata_file) self.coredata = coredata.load(cdf) + self.first_invocation = False except FileNotFoundError: self.coredata = coredata.CoreData(options) + self.first_invocation = True if self.coredata.cross_file: self.cross_info = CrossBuildInfo(self.coredata.cross_file) else: self.cross_info = None - self.cmd_line_options = options.projectoptions + self.cmd_line_options = options # List of potential compilers. if mesonlib.is_windows(): diff --git a/interpreter.py b/interpreter.py index d0f23c675..968b2b958 100644 --- a/interpreter.py +++ b/interpreter.py @@ -843,7 +843,7 @@ class Interpreter(): 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) + self.build.environment.cmd_line_options.projectoptions) oi.process(option_file) self.build.environment.merge_options(oi.options) mesonfile = os.path.join(self.source_root, self.subdir, environment.build_filename) @@ -925,6 +925,7 @@ class Interpreter(): 'import' : self.func_import, 'files' : self.func_files, 'declare_dependency': self.func_declare_dependency, + 'assert': self.func_assert, } def module_method_callback(self, invalues): @@ -1074,6 +1075,18 @@ class Interpreter(): dep = dependencies.InternalDependency(incs, libs, sources) return InternalDependencyHolder(dep) + @noKwargs + def func_assert(self, node, args, kwargs): + if len(args) != 2: + raise InterpreterException('Assert takes exactly two arguments') + value, message = args + if not isinstance(value, bool): + raise InterpreterException('Assert value not bool.') + if not isinstance(message, str): + raise InterpreterException('Assert message not a string.') + if not value: + raise InterpreterException('Assert failed: ' + message) + def set_variable(self, varname, variable): if variable is None: raise InvalidCode('Can not assign None to variable.') @@ -1274,6 +1287,24 @@ class Interpreter(): raise InterpreterException('configuration_data takes no arguments') return ConfigurationDataHolder() + def parse_default_options(self, default_options): + if not isinstance(default_options, list): + default_options = [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 hasattr(self.coredata, key): + if not hasattr(self.environment.cmd_line_options, value): + setattr(self.coredata, key, value) + # If this was set on the command line, do not override. + else: + self.environment.cmd_line_options.projectoptions.insert(0, option) + + @stringArgs def func_project(self, node, args, kwargs): if len(args) < 2: @@ -1281,6 +1312,8 @@ class Interpreter(): 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']) self.active_projectname = args[0] self.project_version = kwargs.get('version', 'undefined') self.build.dep_manifest[args[0]] = self.project_version @@ -1310,7 +1343,7 @@ class Interpreter(): @noKwargs def func_message(self, node, args, kwargs): # reduce arguments again to avoid flattening posargs - (posargs, kwargs) = self.reduce_arguments(node.args) + (posargs, _) = self.reduce_arguments(node.args) if len(posargs) != 1: raise InvalidArguments('Expected 1 argument, got %d' % len(posargs)) @@ -1390,6 +1423,11 @@ class Interpreter(): 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].value = value new_options.update(self.coredata.compiler_options) self.coredata.compiler_options = new_options mlog.log('Native %s compiler: ' % lang, mlog.bold(' '.join(comp.get_exelist())), ' (%s %s)' % (comp.id, comp.version), sep='') diff --git a/test cases/common/94 default options/meson.build b/test cases/common/94 default options/meson.build new file mode 100644 index 000000000..9c881bb5e --- /dev/null +++ b/test cases/common/94 default options/meson.build @@ -0,0 +1,15 @@ +project('default options', 'cpp', default_options : [ + 'buildtype=debugoptimized', + 'cpp_std=c++03', + 'cpp_eh=none' + ]) + +cc = meson.get_compiler('cpp') + +assert(get_option('buildtype') == 'debugoptimized', 'Build type default value wrong.') + +if cc.get_id() == 'msvc' + assert(get_option('cpp_eh') == 'none', 'MSVC eh value wrong.') +else + assert(get_option('cpp_std') == 'c++03', 'C++ std value wrong.') +endif diff --git a/test cases/failing/22 assert/meson.build b/test cases/failing/22 assert/meson.build new file mode 100644 index 000000000..ae3a19ca1 --- /dev/null +++ b/test cases/failing/22 assert/meson.build @@ -0,0 +1,3 @@ +project('failing assert', 'c') + +assert(false, 'I am fail.')