diff --git a/backends.py b/backends.py index e98cef474..86cf6aab2 100644 --- a/backends.py +++ b/backends.py @@ -68,7 +68,7 @@ class Backend(): return filename def get_target_dir(self, target): - if self.environment.coredata.layout == 'mirror': + if self.environment.coredata.get_builtin_option('layout') == 'mirror': dirname = target.get_subdir() else: dirname = 'meson-out' @@ -208,16 +208,16 @@ class Backend(): def generate_basic_compiler_args(self, target, compiler): commands = [] commands += compiler.get_always_args() - if self.environment.coredata.buildtype != 'plain': - commands += compiler.get_warn_args(self.environment.coredata.warning_level) + if self.environment.coredata.get_builtin_option('buildtype') != 'plain': + commands += compiler.get_warn_args(self.environment.coredata.get_builtin_option('warning_level')) commands += compiler.get_option_compile_args(self.environment.coredata.compiler_options) commands += self.build.get_global_args(compiler) commands += self.environment.coredata.external_args[compiler.get_language()] commands += target.get_extra_args(compiler.get_language()) - commands += compiler.get_buildtype_args(self.environment.coredata.buildtype) - if self.environment.coredata.coverage: + commands += compiler.get_buildtype_args(self.environment.coredata.get_builtin_option('buildtype')) + if self.environment.coredata.get_builtin_option('coverage'): commands += compiler.get_coverage_args() - if self.environment.coredata.werror: + if self.environment.coredata.get_builtin_option('werror'): commands += compiler.get_werror_args() if isinstance(target, build.SharedLibrary): commands += compiler.get_pic_args() @@ -302,9 +302,10 @@ class Backend(): outdir = self.environment.scratch_dir fname = os.path.join(outdir, p.filebase + '.pc') ofile = open(fname, 'w') - ofile.write('prefix=%s\n' % self.environment.get_coredata().prefix) - ofile.write('libdir=${prefix}/%s\n' % self.environment.get_coredata().libdir) - ofile.write('includedir=${prefix}/%s\n\n' % self.environment.get_coredata().includedir) + coredata = self.environment.get_coredata() + ofile.write('prefix=%s\n' % coredata.get_builtin_option('prefix')) + ofile.write('libdir=${prefix}/%s\n' % coredata.get_builtin_option('libdir')) + ofile.write('includedir=${prefix}/%s\n\n' % coredata.get_builtin_option('includedir')) ofile.write('Name: %s\n' % p.name) if len(p.description) > 0: ofile.write('Description: %s\n' % p.description) diff --git a/compilers.py b/compilers.py index 85b57b320..862a4f062 100644 --- a/compilers.py +++ b/compilers.py @@ -17,6 +17,7 @@ import tempfile import mesonlib import mlog from coredata import MesonException +import coredata """This file contains the data files of all compilers Meson knows about. To support a new compiler, add its information below. @@ -1017,7 +1018,7 @@ class VisualStudioCCompiler(CCompiler): return [] def get_options(self): - return {'c_winlibs' : mesonlib.UserStringArrayOption('c_winlibs', + return {'c_winlibs' : coredata.UserStringArrayOption('c_winlibs', 'Windows libs to link against.', msvc_winlibs) } @@ -1056,11 +1057,11 @@ class VisualStudioCPPCompiler(VisualStudioCCompiler): raise EnvironmentException('Executables created by C++ compiler %s are not runnable.' % self.name_string()) def get_options(self): - return {'cpp_eh' : mesonlib.UserComboOption('cpp_eh', + return {'cpp_eh' : coredata.UserComboOption('cpp_eh', 'C++ exception handling type.', ['none', 'a', 's', 'sc'], 'sc'), - 'cpp_winlibs' : mesonlib.UserStringArrayOption('cpp_winlibs', + 'cpp_winlibs' : coredata.UserStringArrayOption('cpp_winlibs', 'Windows libs to link against.', msvc_winlibs) } @@ -1129,12 +1130,12 @@ class GnuCCompiler(CCompiler): return super().can_compile(filename) or filename.split('.')[-1].lower() == 's' # Gcc can do asm, too. def get_options(self): - opts = {'c_std' : mesonlib.UserComboOption('c_std', 'C language standard to use', + opts = {'c_std' : coredata.UserComboOption('c_std', 'C language standard to use', ['none', 'c89', 'c99', 'c11', 'gnu89', 'gnu99', 'gnu11'], 'c11')} if self.gcc_type == GCC_MINGW: opts.update({ - 'c_winlibs': mesonlib.UserStringArrayOption('c_winlibs', 'Standard Win libraries to link against', + 'c_winlibs': coredata.UserStringArrayOption('c_winlibs', 'Standard Win libraries to link against', gnu_winlibs), }) return opts @@ -1240,7 +1241,7 @@ class ClangCCompiler(CCompiler): return ['-include-pch', os.path.join (pch_dir, self.get_pch_name (header))] def get_options(self): - return {'c_std' : mesonlib.UserComboOption('c_std', 'C language standard to use', + return {'c_std' : coredata.UserComboOption('c_std', 'C language standard to use', ['none', 'c89', 'c99', 'c11'], 'c11')} @@ -1282,12 +1283,12 @@ class GnuCPPCompiler(CPPCompiler): return get_gcc_soname_args(self.gcc_type, shlib_name, path, soversion) def get_options(self): - opts = {'cpp_std' : mesonlib.UserComboOption('cpp_std', 'C language standard to use', + opts = {'cpp_std' : coredata.UserComboOption('cpp_std', 'C language standard to use', ['none', 'c++03', 'c++11', 'c++1y'], 'c++11')} if self.gcc_type == GCC_MINGW: opts.update({ - 'cpp_winlibs': mesonlib.UserStringArrayOption('c_winlibs', 'Standard Win libraries to link against', + 'cpp_winlibs': coredata.UserStringArrayOption('c_winlibs', 'Standard Win libraries to link against', gnu_winlibs), }) return opts @@ -1328,7 +1329,7 @@ class ClangCPPCompiler(CPPCompiler): return ['-include-pch', os.path.join (pch_dir, self.get_pch_name (header))] def get_options(self): - return {'cpp_std' : mesonlib.UserComboOption('cpp_std', 'C++ language standard to use', + return {'cpp_std' : coredata.UserComboOption('cpp_std', 'C++ language standard to use', ['none', 'c++03', 'c++11', 'c++1y'], 'c++11')} diff --git a/coredata.py b/coredata.py index 711dddf8b..b1a9919f0 100644 --- a/coredata.py +++ b/coredata.py @@ -16,6 +16,11 @@ import pickle, os, uuid version = '0.27.0-research' +build_types = ['plain', 'debug', 'debugoptimized', 'release'] +layouts = ['mirror', 'flat'] +warning_levels = ['1', '2', '3'] +libtypelist = ['shared', 'static'] + builtin_options = {'buildtype': True, 'strip': True, 'coverage': True, @@ -31,8 +36,98 @@ builtin_options = {'buildtype': True, 'werror' : True, 'warning_level': True, 'layout' : True, + 'default_library': True, } +class MesonException(Exception): + def __init__(self, *args, **kwargs): + Exception.__init__(self, *args, **kwargs) + +class UserOption: + def __init__(self, name, description): + super().__init__() + self.name = name + self.description = description + + def parse_string(self, valuestring): + return valuestring + +class UserStringOption(UserOption): + def __init__(self, name, description, value): + super().__init__(name, description) + self.set_value(value) + + def validate(self, value): + if not isinstance(value, str): + raise MesonException('Value "%s" for string option "%s" is not a string.' % (str(newvalue), self.name)) + if self.name == 'prefix' and not os.path.isabs(value): + raise MesonException('Prefix option must be an absolute path.') + if self.name in ('libdir', 'bindir', 'includedir', 'datadir', 'mandir', 'localedir') \ + and os.path.isabs(value): + raise MesonException('Option %s must not be an absolute path.' % self.name) + + def set_value(self, newvalue): + self.validate(newvalue) + self.value = newvalue + +class UserBooleanOption(UserOption): + def __init__(self, name, description, value): + super().__init__(name, description) + self.set_value(value) + + def tobool(self, thing): + if isinstance(thing, bool): + return thing + if thing.lower() == 'true': + return True + if thing.lower() == 'false': + return False + raise MesonException('Value %s is not boolean (true or false).' % thing) + + def set_value(self, newvalue): + self.value = self.tobool(newvalue) + + def parse_string(self, valuestring): + if valuestring == 'false': + return False + if valuestring == 'true': + return True + raise MesonException('Value "%s" for boolean option "%s" is not a boolean.' % (valuestring, self.name)) + +class UserComboOption(UserOption): + def __init__(self, name, description, choices, value): + super().__init__(name, description) + self.choices = choices + if not isinstance(self.choices, list): + raise MesonException('Combo choices must be an array.') + for i in self.choices: + if not isinstance(i, str): + raise MesonException('Combo choice elements must be strings.') + self.set_value(value) + + def set_value(self, newvalue): + if newvalue not in self.choices: + optionsstring = ', '.join(['"%s"' % (item,) for item in self.choices]) + raise MesonException('Value "%s" for combo option "%s" is not one of the choices. Possible choices are: %s.' % (newvalue, self.name, optionsstring)) + self.value = newvalue + +class UserStringArrayOption(UserOption): + def __init__(self, name, description, value): + super().__init__(name, description) + self.set_value(value) + + def set_value(self, newvalue): + if isinstance(newvalue, str): + if not newvalue.startswith('['): + raise MesonException('Valuestring does not define an array: ' + newvalue) + newvalue = eval(newvalue, {}, {}) # Yes, it is unsafe. + if not isinstance(newvalue, list): + raise MesonException('String array value is not an array.') + for i in newvalue: + if not isinstance(i, str): + raise MesonException('String array element not a string.') + self.value = newvalue + # This class contains all data that must persist over multiple # invocations of Meson. It is roughly the same thing as # cmakecache. @@ -45,22 +140,8 @@ class CoreData(): self.regen_guid = str(uuid.uuid4()).upper() self.target_guids = {} self.version = version - self.prefix = options.prefix - self.libdir = options.libdir - self.bindir = options.bindir - self.includedir = options.includedir - self.datadir = options.datadir - self.mandir = options.mandir - self.localedir = options.localedir - self.backend = options.backend - self.buildtype = options.buildtype - self.strip = options.strip - self.use_pch = options.use_pch - self.unity = options.unity - self.coverage = options.coverage - self.warning_level = options.warning_level - self.werror = options.werror - self.layout = options.layout + self.builtin_options = {} + self.init_builtins(options) self.user_options = {} self.compiler_options = {} self.external_args = {} # These are set from "the outside" with e.g. mesonconf @@ -77,35 +158,39 @@ class CoreData(): self.ext_libs = {} self.modules = {} + def init_builtins(self, options): + self.builtin_options['prefix'] = UserStringOption('prefix', 'Installation prefix', options.prefix) + self.builtin_options['libdir'] = UserStringOption('libdir', 'Library dir', options.libdir) + self.builtin_options['bindir'] = UserStringOption('bindir', 'Executable dir', options.bindir) + self.builtin_options['includedir'] = UserStringOption('includedir', 'Include dir', options.includedir) + self.builtin_options['datadir'] = UserStringOption('datadir', 'Data directory', options.datadir) + self.builtin_options['mandir'] = UserStringOption('mandir', 'Man page dir', options.mandir) + self.builtin_options['localedir'] = UserStringOption('localedir', 'Locale dir', options.localedir) + self.builtin_options['backend'] = UserStringOption('backend', 'Backend to use', options.backend) + self.builtin_options['buildtype'] = UserComboOption('buildtype', 'Build type', build_types, options.buildtype) + self.builtin_options['strip'] = UserBooleanOption('strip', 'Strip on install', options.strip) + self.builtin_options['use_pch'] = UserBooleanOption('use_pch', 'Use precompiled headers', options.use_pch) + self.builtin_options['unity'] = UserBooleanOption('unity', 'Unity build', options.unity) + self.builtin_options['coverage'] = UserBooleanOption('coverage', 'Enable coverage', options.coverage) + self.builtin_options['warning_level'] = UserComboOption('warning_level', 'Warning level', warning_levels, options.warning_level) + self.builtin_options['werror'] = UserBooleanOption('werror', 'Warnings are errors', options.werror) + self.builtin_options['layout'] = UserComboOption('layout', 'Build dir layout', layouts, options.layout) + self.builtin_options['default_library'] = UserComboOption('default_library', 'Default_library type', libtypelist, options.default_library) + def get_builtin_option(self, optname): - if optname == 'buildtype': - return self.buildtype - if optname == 'strip': - return self.strip - if optname == 'coverage': - return self.coverage - if optname == 'pch': - return self.use_pch - if optname == 'unity': - return self.unity - if optname == 'prefix': - return self.prefix - if optname == 'libdir': - return self.libdir - if optname == 'bindir': - return self.bindir - if optname == 'includedir': - return self.includedir - if optname == 'datadir': - return self.datadir - if optname == 'mandir': - return self.mandir - if optname == 'localedir': - return self.localedir - if optname == 'layout': - return self.layout + if optname in self.builtin_options: + return self.builtin_options[optname].value raise RuntimeError('Tried to get unknown builtin option %s' % optname) + def set_builtin_option(self, optname, value): + if optname in self.builtin_options: + self.builtin_options[optname].set_value(value) + else: + raise RuntimeError('Tried to set unknown builtin option %s' % optname) + + def is_builtin_option(self, optname): + return optname in self.builtin_options + def load(filename): obj = pickle.load(open(filename, 'rb')) if not isinstance(obj, CoreData): @@ -134,7 +219,3 @@ forbidden_target_names = {'clean': None, 'install': None, 'build.ninja': None, } - -class MesonException(Exception): - def __init__(self, *args, **kwargs): - Exception.__init__(self, *args, **kwargs) diff --git a/environment.py b/environment.py index c4878f447..697957dee 100644 --- a/environment.py +++ b/environment.py @@ -543,22 +543,22 @@ class Environment(): return self.object_suffix def get_prefix(self): - return self.coredata.prefix + return self.coredata.get_builtin_option('prefix') def get_libdir(self): - return self.coredata.libdir + return self.coredata.get_builtin_option('libdir') def get_bindir(self): - return self.coredata.bindir + return self.coredata.get_builtin_option('bindir') def get_includedir(self): - return self.coredata.includedir + return self.coredata.get_builtin_option('includedir') def get_mandir(self): - return self.coredata.mandir + return self.coredata.get_builtin_option('mandir') def get_datadir(self): - return self.coredata.datadir + return self.coredata.get_builtin_option('datadir') def find_library(self, libname, dirs): if dirs is None: diff --git a/interpreter.py b/interpreter.py index 507694136..f71d7f51d 100644 --- a/interpreter.py +++ b/interpreter.py @@ -855,7 +855,7 @@ class MesonMain(InterpreterObject): raise InterpreterException('Tried to access compiler for unspecified language "%s".' % cname) def is_unity_method(self, args, kwargs): - return self.build.environment.coredata.unity + return self.build.environment.coredata.get_builtin_option('unity') def is_subproject_method(self, args, kwargs): return self.interpreter.is_subproject() @@ -933,6 +933,7 @@ class Interpreter(): 'dependency' : self.func_dependency, 'static_library' : self.func_static_lib, 'shared_library' : self.func_shared_lib, + 'library' : self.func_library, 'jar' : self.func_jar, 'build_target': self.func_build_target, 'custom_target' : self.func_custom_target, @@ -1351,9 +1352,10 @@ class Interpreter(): 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): + builtin_options = self.coredata.builtin_options + if key in builtin_options: if not hasattr(self.environment.cmd_line_options, value): - setattr(self.coredata, key, value) + self.coredata.set_builtin_option(key, value) # If this was set on the command line, do not override. else: newoptions = [option] + self.environment.cmd_line_options.projectoptions @@ -1579,6 +1581,11 @@ class Interpreter(): def func_shared_lib(self, node, args, kwargs): return self.build_target(node, args, kwargs, SharedLibraryHolder) + def func_library(self, node, args, kwargs): + if self.coredata.get_builtin_option('default_library') == 'shared': + return self.func_shared_lib(node, args, kwargs) + return self.func_static_lib(node, args, kwargs) + def func_jar(self, node, args, kwargs): return self.build_target(node, args, kwargs, JarHolder) @@ -1592,6 +1599,8 @@ class Interpreter(): return self.func_shared_lib(node, args, kwargs) elif target_type == 'static_library': return self.func_static_lib(node, args, kwargs) + elif target_type == 'library': + return self.func_library(node, args, kwargs) elif target_type == 'jar': return self.func_jar(node, args, kwargs) else: @@ -2021,7 +2030,7 @@ class Interpreter(): else: obj = self.evaluate_statement(invokable) method_name = node.name - if method_name == 'extract_objects' and self.environment.coredata.unity: + if method_name == 'extract_objects' and self.environment.coredata.get_builtin_option('unity'): raise InterpreterException('Single object files can not be extracted in Unity builds.') args = node.args if isinstance(obj, mparser.StringNode): diff --git a/meson.py b/meson.py index 4c8e171e6..1720117b2 100755 --- a/meson.py +++ b/meson.py @@ -22,14 +22,11 @@ import build import platform import mlog, coredata -from coredata import MesonException - -parser = argparse.ArgumentParser() +from coredata import MesonException, build_types, layouts, warning_levels, libtypelist backendlist = ['ninja', 'vs2010', 'xcode'] -build_types = ['plain', 'debug', 'debugoptimized', 'release'] -layouts = ['mirror', 'flat'] -warning_levels = ['1', '2', '3'] + +parser = argparse.ArgumentParser() default_warning = '2' @@ -68,6 +65,8 @@ parser.add_argument('--werror', action='store_true', dest='werror', default=Fals help='Treat warnings as errors') parser.add_argument('--layout', choices=layouts, dest='layout', default='mirror',\ help='Build directory layout.') +parser.add_argument('--default-library', choices=libtypelist, dest='default_library', + default='shared', help='Default library type.') parser.add_argument('--warnlevel', default=default_warning, dest='warning_level', choices=warning_levels,\ help='Level of compiler warnings to use (larger is more, default is %(default)s)') parser.add_argument('--cross-file', default=None, dest='cross_file', diff --git a/mesonconf.py b/mesonconf.py index 963585ad4..14fd8f4f5 100755 --- a/mesonconf.py +++ b/mesonconf.py @@ -26,7 +26,7 @@ parser.add_argument('-D', action='append', default=[], dest='sets', help='Set an option to the given value.') parser.add_argument('directory', nargs='*') -class ConfException(Exception): +class ConfException(coredata.MesonException): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -69,55 +69,8 @@ class Conf: if '=' not in o: raise ConfException('Value "%s" not of type "a=b".' % o) (k, v) = o.split('=', 1) - if k == 'buildtype': - if v not in build_types: - raise ConfException('Invalid build type %s.' % v) - self.coredata.buildtype = v - elif k == 'layout': - if v not in layouts: - raise ConfException('Invalid layout type %s.' % v) - self.coredata.layout = v - elif k == 'warnlevel': - if not v in warning_levels: - raise ConfException('Invalid warning level %s.' % v) - self.coredata.warning_level = v - elif k == 'strip': - self.coredata.strip = self.tobool(v) - elif k == 'coverage': - v = self.tobool(v) - self.coredata.coverage = self.tobool(v) - elif k == 'pch': - self.coredata.use_pch = self.tobool(v) - elif k == 'unity': - self.coredata.unity = self.tobool(v) - elif k == 'prefix': - if not os.path.isabs(v): - raise ConfException('Install prefix %s is not an absolute path.' % v) - self.coredata.prefix = v - elif k == 'libdir': - if os.path.isabs(v): - raise ConfException('Library dir %s must not be an absolute path.' % v) - self.coredata.libdir = v - elif k == 'bindir': - if os.path.isabs(v): - raise ConfException('Binary dir %s must not be an absolute path.' % v) - self.coredata.bindir = v - elif k == 'includedir': - if os.path.isabs(v): - raise ConfException('Include dir %s must not be an absolute path.' % v) - self.coredata.includedir = v - elif k == 'datadir': - if os.path.isabs(v): - raise ConfException('Data dir %s must not be an absolute path.' % v) - self.coredata.datadir = v - elif k == 'mandir': - if os.path.isabs(v): - raise ConfException('Man dir %s must not be an absolute path.' % v) - self.coredata.mandir = v - elif k == 'localedir': - if os.path.isabs(v): - raise ConfException('Locale dir %s must not be an absolute path.' % v) - self.coredata.localedir = v + if self.coredata.is_builtin_option(k): + self.coredata.set_builtin_option(k, v) elif k in self.coredata.user_options: tgt = self.coredata.user_options[k] tgt.set_value(v) @@ -150,12 +103,13 @@ class Conf: print('') print('Core options\n') carr = [] - carr.append(['buildtype', 'Build type', self.coredata.buildtype]) - carr.append(['warnlevel', 'Warning level', self.coredata.warning_level]) - carr.append(['strip', 'Strip on install', self.coredata.strip]) - carr.append(['coverage', 'Coverage report', self.coredata.coverage]) - carr.append(['pch', 'Precompiled headers', self.coredata.use_pch]) - carr.append(['unity', 'Unity build', self.coredata.unity]) + carr.append(['buildtype', 'Build type', self.coredata.get_builtin_option('buildtype')]) + carr.append(['warning_level', 'Warning level', self.coredata.get_builtin_option('warning_level')]) + carr.append(['strip', 'Strip on install', self.coredata.get_builtin_option('strip')]) + carr.append(['coverage', 'Coverage report', self.coredata.get_builtin_option('coverage')]) + carr.append(['use_pch', 'Precompiled headers', self.coredata.get_builtin_option('use_pch')]) + carr.append(['unity', 'Unity build', self.coredata.get_builtin_option('unity')]) + carr.append(['default_library', 'Default library type', self.coredata.get_builtin_option('default_library')]) self.print_aligned(carr) print('') print('Compiler arguments\n') @@ -179,13 +133,13 @@ class Conf: print('') print('Directories\n') parr = [] - parr.append(['prefix', 'Install prefix', self.coredata.prefix]) - parr.append(['libdir', 'Library directory', self.coredata.libdir]) - parr.append(['bindir', 'Binary directory', self.coredata.bindir]) - parr.append(['includedir', 'Header directory', self.coredata.includedir]) - parr.append(['datadir', 'Data directory', self.coredata.datadir]) - parr.append(['mandir', 'Man page directory', self.coredata.mandir]) - parr.append(['localedir', 'Locale file directory', self.coredata.localedir]) + parr.append(['prefix', 'Install prefix', self.coredata.get_builtin_option('prefix')]) + parr.append(['libdir', 'Library directory', self.coredata.get_builtin_option('libdir')]) + parr.append(['bindir', 'Binary directory', self.coredata.get_builtin_option('bindir')]) + parr.append(['includedir', 'Header directory', self.coredata.get_builtin_option('includedir')]) + parr.append(['datadir', 'Data directory', self.coredata.get_builtin_option('datadir')]) + parr.append(['mandir', 'Man page directory', self.coredata.get_builtin_option('mandir')]) + parr.append(['localedir', 'Locale file directory', self.coredata.get_builtin_option('localedir')]) self.print_aligned(parr) print('') if len(self.coredata.user_options) == 0: @@ -218,7 +172,7 @@ if __name__ == '__main__': c.save() else: c.print_conf() - except ConfException as e: + except coredata.MesonException as e: print('Meson configurator encountered an error:\n') print(e) diff --git a/mesonlib.py b/mesonlib.py index f42209534..bb69632db 100644 --- a/mesonlib.py +++ b/mesonlib.py @@ -264,80 +264,3 @@ def stringlistify(item): if not isinstance(i, str): raise MesonException('List item not a string.') return item - -class UserOption: - def __init__(self, name, description): - super().__init__() - self.name = name - self.description = description - - def parse_string(self, valuestring): - return valuestring - -class UserStringOption(UserOption): - def __init__(self, name, description, value): - super().__init__(name, description) - self.set_value(value) - - def set_value(self, newvalue): - if not isinstance(newvalue, str): - raise MesonException('Value "%s" for string option "%s" is not a string.' % (str(newvalue), self.name)) - self.value = newvalue - -class UserBooleanOption(UserOption): - def __init__(self, name, description, value): - super().__init__(name, description) - self.set_value(value) - - def tobool(self, thing): - if isinstance(thing, bool): - return thing - if thing.lower() == 'true': - return True - if thing.lower() == 'false': - return False - raise MesonException('Value %s is not boolean (true or false).' % thing) - - def set_value(self, newvalue): - self.value = self.tobool(newvalue) - - def parse_string(self, valuestring): - if valuestring == 'false': - return False - if valuestring == 'true': - return True - raise MesonException('Value "%s" for boolean option "%s" is not a boolean.' % (valuestring, self.name)) - -class UserComboOption(UserOption): - def __init__(self, name, description, choices, value): - super().__init__(name, description) - self.choices = choices - if not isinstance(self.choices, list): - raise MesonException('Combo choices must be an array.') - for i in self.choices: - if not isinstance(i, str): - raise MesonException('Combo choice elements must be strings.') - self.set_value(value) - - def set_value(self, newvalue): - if newvalue not in self.choices: - optionsstring = ', '.join(['"%s"' % (item,) for item in self.choices]) - raise MesonException('Value "%s" for combo option "%s" is not one of the choices. Possible choices are: %s.' % (newvalue, self.name, optionsstring)) - self.value = newvalue - -class UserStringArrayOption(UserOption): - def __init__(self, name, description, value): - super().__init__(name, description) - self.set_value(value) - - def set_value(self, newvalue): - if isinstance(newvalue, str): - if not newvalue.startswith('['): - raise MesonException('Valuestring does not define an array: ' + newvalue) - newvalue = eval(newvalue, {}, {}) # Yes, it is unsafe. - if not isinstance(newvalue, list): - raise MesonException('String array value is not an array.') - for i in newvalue: - if not isinstance(i, str): - raise MesonException('String array element not a string.') - self.value = newvalue diff --git a/ninjabackend.py b/ninjabackend.py index f1274a74c..9081736ee 100644 --- a/ninjabackend.py +++ b/ninjabackend.py @@ -150,7 +150,7 @@ class NinjaBackend(backends.Backend): self.generate_tests(outfile) outfile.write('# Install rules\n\n') self.generate_install(outfile) - if self.environment.coredata.coverage: + if self.environment.coredata.get_builtin_option('coverage'): outfile.write('# Coverage rules\n\n') self.generate_coverage_rules(outfile) outfile.write('# Suffix\n\n') @@ -203,8 +203,8 @@ class NinjaBackend(backends.Backend): self.generate_custom_generator_rules(target, outfile) outname = self.get_target_filename(target) obj_list = [] - use_pch = self.environment.coredata.use_pch - is_unity = self.environment.coredata.unity + use_pch = self.environment.coredata.get_builtin_option('use_pch') + is_unity = self.environment.coredata.get_builtin_option('unity') if use_pch and target.has_pch(): pch_objects = self.generate_pch(target, outfile) else: @@ -444,14 +444,14 @@ class NinjaBackend(backends.Backend): for lang in languages: rel_src = os.path.join(subdir, lang + '.gmo') src_file = os.path.join(self.environment.get_build_dir(), rel_src) - d.po.append((src_file, self.environment.coredata.localedir, lang)) + d.po.append((src_file, self.environment.coredata.get_builtin_option('localedir'), lang)) elem.add_dep(rel_src) def generate_target_install(self, d): libdir = self.environment.get_libdir() bindir = self.environment.get_bindir() - should_strip = self.environment.coredata.strip + should_strip = self.environment.coredata.get_builtin_option('strip') for t in self.build.get_targets().values(): if t.should_install(): outdir = t.get_custom_install_dir() @@ -465,7 +465,7 @@ class NinjaBackend(backends.Backend): d.targets.append(i) def generate_pkgconfig_install(self, d): - pkgroot = os.path.join(self.environment.coredata.libdir, 'pkgconfig') + pkgroot = os.path.join(self.environment.coredata.get_builtin_option('libdir'), 'pkgconfig') for p in self.build.pkgconfig_gens: pcfile = p.filebase + '.pc' @@ -647,7 +647,7 @@ class NinjaBackend(backends.Backend): return (args, deps) def generate_cs_target(self, target, outfile): - buildtype = self.environment.coredata.buildtype + buildtype = self.environment.coredata.get_builtin_option('buildtype') fname = target.get_filename() outname_rel = os.path.join(self.get_target_dir(target), fname) src_list = target.get_sources() @@ -683,7 +683,7 @@ class NinjaBackend(backends.Backend): def generate_single_java_compile(self, src, target, compiler, outfile): args = [] - args += compiler.get_buildtype_args(self.environment.coredata.buildtype) + args += compiler.get_buildtype_args(self.environment.coredata.get_builtin_option('buildtype')) args += compiler.get_output_args(self.get_target_private_dir(target)) rel_src = src.rel_to_builddir(self.build_to_src) plain_class_path = src.fname[:-4] + 'class' @@ -753,7 +753,7 @@ class NinjaBackend(backends.Backend): relsc = os.path.join(self.get_target_private_dir_abs(target), sc) rel_s = s.rel_to_builddir(self.build_to_src) args += ['--deps', relsc + '.d'] - if self.environment.coredata.werror: + if self.environment.coredata.get_builtin_option('werror'): args += valac.get_werror_args() for d in target.external_deps: if isinstance(d, dependencies.PkgConfigDependency): @@ -1257,7 +1257,7 @@ rule FORTRAN_DEP_HACK rel_obj = os.path.join(self.get_target_private_dir(target), obj_basename) rel_obj += '.' + self.environment.get_object_suffix() dep_file = rel_obj + '.' + compiler.get_depfile_suffix() - if self.environment.coredata.use_pch: + if self.environment.coredata.get_builtin_option('use_pch'): pchlist = target.get_pch(compiler.language) else: pchlist = [] @@ -1287,7 +1287,7 @@ rule FORTRAN_DEP_HACK custom_target_include_dirs.append(idir) for i in custom_target_include_dirs: commands+= compiler.get_include_args(i) - if self.environment.coredata.use_pch: + if self.environment.coredata.get_builtin_option('use_pch'): commands += self.get_pch_include_args(compiler, target) crstr = '' if target.is_cross: @@ -1425,7 +1425,7 @@ rule FORTRAN_DEP_HACK abspath = os.path.join(self.environment.get_build_dir(), target.subdir) commands = [] commands += linker.get_linker_always_args() - commands += linker.get_buildtype_linker_args(self.environment.coredata.buildtype) + commands += linker.get_buildtype_linker_args(self.environment.coredata.get_builtin_option('buildtype')) commands += linker.get_option_link_args(self.environment.coredata.compiler_options) if not(isinstance(target, build.StaticLibrary)): commands += self.environment.coredata.external_link_args[linker.get_language()] @@ -1465,7 +1465,7 @@ rule FORTRAN_DEP_HACK commands += dep.get_link_args() commands += linker.build_rpath_args(self.environment.get_build_dir(),\ self.determine_rpath_dirs(target), target.install_rpath) - if self.environment.coredata.coverage: + if self.environment.coredata.get_builtin_option('coverage'): commands += linker.get_coverage_link_args() commands += extra_args dep_targets = [self.get_dependency_filename(t) for t in dependencies] @@ -1570,7 +1570,7 @@ rule FORTRAN_DEP_HACK elem = NinjaBuildElement('clean', 'CUSTOM_COMMAND', 'PHONY') elem.add_item('COMMAND', [ninja_command, '-t', 'clean']) elem.add_item('description', 'Cleaning') - if self.environment.coredata.coverage: + if self.environment.coredata.get_builtin_option('coverage'): self.generate_gcov_clean(outfile) elem.add_dep('clean-gcda') elem.add_dep('clean-gcno') diff --git a/optinterpreter.py b/optinterpreter.py index d66aa1f32..f10632630 100644 --- a/optinterpreter.py +++ b/optinterpreter.py @@ -40,11 +40,11 @@ class OptionException(coredata.MesonException): optname_regex = re.compile('[^a-zA-Z0-9_-]') def StringParser(name, description, kwargs): - return mesonlib.UserStringOption(name, description, + return coredata.UserStringOption(name, description, kwargs.get('value', '')) def BooleanParser(name, description, kwargs): - return mesonlib.UserBooleanOption(name, description, kwargs.get('value', True)) + return coredata.UserBooleanOption(name, description, kwargs.get('value', True)) def ComboParser(name, description, kwargs): if 'choices' not in kwargs: @@ -55,7 +55,7 @@ def ComboParser(name, description, kwargs): for i in choices: if not isinstance(i, str): raise OptionException('Combo choice elements must be strings.') - return mesonlib.UserComboOption(name, description, choices, kwargs.get('value', choices[0])) + return coredata.UserComboOption(name, description, choices, kwargs.get('value', choices[0])) option_types = {'string' : StringParser, 'boolean' : BooleanParser, diff --git a/test cases/common/96 default library/ef.cpp b/test cases/common/96 default library/ef.cpp new file mode 100644 index 000000000..79983c6bd --- /dev/null +++ b/test cases/common/96 default library/ef.cpp @@ -0,0 +1,8 @@ +#include"ef.h" + +Ef::Ef() : x(99) { +} + +int Ef::get_x() const { + return x; +} diff --git a/test cases/common/96 default library/ef.h b/test cases/common/96 default library/ef.h new file mode 100644 index 000000000..cae5c1392 --- /dev/null +++ b/test cases/common/96 default library/ef.h @@ -0,0 +1,11 @@ +#pragma once + +class Ef { +private: + int x; + +public: + + Ef(); + int get_x() const; +}; diff --git a/test cases/common/96 default library/eftest.cpp b/test cases/common/96 default library/eftest.cpp new file mode 100644 index 000000000..4d4412d75 --- /dev/null +++ b/test cases/common/96 default library/eftest.cpp @@ -0,0 +1,14 @@ +#include"ef.h" + +#include + +int main(int, char **) { + Ef var; + if(var.get_x() == 99) { + std::cout << "All is fine.\n"; + return 0; + } else { + std::cout << "Something went wrong.\n"; + return 1; + } +} diff --git a/test cases/common/96 default library/meson.build b/test cases/common/96 default library/meson.build new file mode 100644 index 000000000..903cfe40a --- /dev/null +++ b/test cases/common/96 default library/meson.build @@ -0,0 +1,5 @@ +project('default library', 'cpp') + +flib = library('ef', 'ef.cpp') +exe = executable('eftest', 'eftest.cpp', link_with : flib) +test('eftest', exe)