Merged default library branch.

pull/278/head
Jussi Pakkanen 9 years ago
commit 7bfc04ecdb
  1. 19
      backends.py
  2. 19
      compilers.py
  3. 173
      coredata.py
  4. 12
      environment.py
  5. 17
      interpreter.py
  6. 11
      meson.py
  7. 82
      mesonconf.py
  8. 77
      mesonlib.py
  9. 28
      ninjabackend.py
  10. 6
      optinterpreter.py
  11. 8
      test cases/common/96 default library/ef.cpp
  12. 11
      test cases/common/96 default library/ef.h
  13. 14
      test cases/common/96 default library/eftest.cpp
  14. 5
      test cases/common/96 default library/meson.build

@ -68,7 +68,7 @@ class Backend():
return filename return filename
def get_target_dir(self, target): 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() dirname = target.get_subdir()
else: else:
dirname = 'meson-out' dirname = 'meson-out'
@ -208,16 +208,16 @@ class Backend():
def generate_basic_compiler_args(self, target, compiler): def generate_basic_compiler_args(self, target, compiler):
commands = [] commands = []
commands += compiler.get_always_args() commands += compiler.get_always_args()
if self.environment.coredata.buildtype != 'plain': if self.environment.coredata.get_builtin_option('buildtype') != 'plain':
commands += compiler.get_warn_args(self.environment.coredata.warning_level) 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 += compiler.get_option_compile_args(self.environment.coredata.compiler_options)
commands += self.build.get_global_args(compiler) commands += self.build.get_global_args(compiler)
commands += self.environment.coredata.external_args[compiler.get_language()] commands += self.environment.coredata.external_args[compiler.get_language()]
commands += target.get_extra_args(compiler.get_language()) commands += target.get_extra_args(compiler.get_language())
commands += compiler.get_buildtype_args(self.environment.coredata.buildtype) commands += compiler.get_buildtype_args(self.environment.coredata.get_builtin_option('buildtype'))
if self.environment.coredata.coverage: if self.environment.coredata.get_builtin_option('coverage'):
commands += compiler.get_coverage_args() commands += compiler.get_coverage_args()
if self.environment.coredata.werror: if self.environment.coredata.get_builtin_option('werror'):
commands += compiler.get_werror_args() commands += compiler.get_werror_args()
if isinstance(target, build.SharedLibrary): if isinstance(target, build.SharedLibrary):
commands += compiler.get_pic_args() commands += compiler.get_pic_args()
@ -302,9 +302,10 @@ class Backend():
outdir = self.environment.scratch_dir outdir = self.environment.scratch_dir
fname = os.path.join(outdir, p.filebase + '.pc') fname = os.path.join(outdir, p.filebase + '.pc')
ofile = open(fname, 'w') ofile = open(fname, 'w')
ofile.write('prefix=%s\n' % self.environment.get_coredata().prefix) coredata = self.environment.get_coredata()
ofile.write('libdir=${prefix}/%s\n' % self.environment.get_coredata().libdir) ofile.write('prefix=%s\n' % coredata.get_builtin_option('prefix'))
ofile.write('includedir=${prefix}/%s\n\n' % self.environment.get_coredata().includedir) 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) ofile.write('Name: %s\n' % p.name)
if len(p.description) > 0: if len(p.description) > 0:
ofile.write('Description: %s\n' % p.description) ofile.write('Description: %s\n' % p.description)

@ -17,6 +17,7 @@ import tempfile
import mesonlib import mesonlib
import mlog import mlog
from coredata import MesonException from coredata import MesonException
import coredata
"""This file contains the data files of all compilers Meson knows """This file contains the data files of all compilers Meson knows
about. To support a new compiler, add its information below. about. To support a new compiler, add its information below.
@ -1017,7 +1018,7 @@ class VisualStudioCCompiler(CCompiler):
return [] return []
def get_options(self): def get_options(self):
return {'c_winlibs' : mesonlib.UserStringArrayOption('c_winlibs', return {'c_winlibs' : coredata.UserStringArrayOption('c_winlibs',
'Windows libs to link against.', 'Windows libs to link against.',
msvc_winlibs) msvc_winlibs)
} }
@ -1056,11 +1057,11 @@ class VisualStudioCPPCompiler(VisualStudioCCompiler):
raise EnvironmentException('Executables created by C++ compiler %s are not runnable.' % self.name_string()) raise EnvironmentException('Executables created by C++ compiler %s are not runnable.' % self.name_string())
def get_options(self): def get_options(self):
return {'cpp_eh' : mesonlib.UserComboOption('cpp_eh', return {'cpp_eh' : coredata.UserComboOption('cpp_eh',
'C++ exception handling type.', 'C++ exception handling type.',
['none', 'a', 's', 'sc'], ['none', 'a', 's', 'sc'],
'sc'), 'sc'),
'cpp_winlibs' : mesonlib.UserStringArrayOption('cpp_winlibs', 'cpp_winlibs' : coredata.UserStringArrayOption('cpp_winlibs',
'Windows libs to link against.', 'Windows libs to link against.',
msvc_winlibs) 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. return super().can_compile(filename) or filename.split('.')[-1].lower() == 's' # Gcc can do asm, too.
def get_options(self): 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'], ['none', 'c89', 'c99', 'c11', 'gnu89', 'gnu99', 'gnu11'],
'c11')} 'c11')}
if self.gcc_type == GCC_MINGW: if self.gcc_type == GCC_MINGW:
opts.update({ 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), gnu_winlibs),
}) })
return opts return opts
@ -1240,7 +1241,7 @@ class ClangCCompiler(CCompiler):
return ['-include-pch', os.path.join (pch_dir, self.get_pch_name (header))] return ['-include-pch', os.path.join (pch_dir, self.get_pch_name (header))]
def get_options(self): 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'], ['none', 'c89', 'c99', 'c11'],
'c11')} 'c11')}
@ -1282,12 +1283,12 @@ class GnuCPPCompiler(CPPCompiler):
return get_gcc_soname_args(self.gcc_type, shlib_name, path, soversion) return get_gcc_soname_args(self.gcc_type, shlib_name, path, soversion)
def get_options(self): 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'], ['none', 'c++03', 'c++11', 'c++1y'],
'c++11')} 'c++11')}
if self.gcc_type == GCC_MINGW: if self.gcc_type == GCC_MINGW:
opts.update({ 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), gnu_winlibs),
}) })
return opts return opts
@ -1328,7 +1329,7 @@ class ClangCPPCompiler(CPPCompiler):
return ['-include-pch', os.path.join (pch_dir, self.get_pch_name (header))] return ['-include-pch', os.path.join (pch_dir, self.get_pch_name (header))]
def get_options(self): 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'], ['none', 'c++03', 'c++11', 'c++1y'],
'c++11')} 'c++11')}

@ -16,6 +16,11 @@ import pickle, os, uuid
version = '0.27.0-research' 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, builtin_options = {'buildtype': True,
'strip': True, 'strip': True,
'coverage': True, 'coverage': True,
@ -31,8 +36,98 @@ builtin_options = {'buildtype': True,
'werror' : True, 'werror' : True,
'warning_level': True, 'warning_level': True,
'layout' : 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 # This class contains all data that must persist over multiple
# invocations of Meson. It is roughly the same thing as # invocations of Meson. It is roughly the same thing as
# cmakecache. # cmakecache.
@ -45,22 +140,8 @@ class CoreData():
self.regen_guid = str(uuid.uuid4()).upper() self.regen_guid = str(uuid.uuid4()).upper()
self.target_guids = {} self.target_guids = {}
self.version = version self.version = version
self.prefix = options.prefix self.builtin_options = {}
self.libdir = options.libdir self.init_builtins(options)
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.user_options = {} self.user_options = {}
self.compiler_options = {} self.compiler_options = {}
self.external_args = {} # These are set from "the outside" with e.g. mesonconf self.external_args = {} # These are set from "the outside" with e.g. mesonconf
@ -77,35 +158,39 @@ class CoreData():
self.ext_libs = {} self.ext_libs = {}
self.modules = {} 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): def get_builtin_option(self, optname):
if optname == 'buildtype': if optname in self.builtin_options:
return self.buildtype return self.builtin_options[optname].value
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
raise RuntimeError('Tried to get unknown builtin option %s' % optname) 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): def load(filename):
obj = pickle.load(open(filename, 'rb')) obj = pickle.load(open(filename, 'rb'))
if not isinstance(obj, CoreData): if not isinstance(obj, CoreData):
@ -134,7 +219,3 @@ forbidden_target_names = {'clean': None,
'install': None, 'install': None,
'build.ninja': None, 'build.ninja': None,
} }
class MesonException(Exception):
def __init__(self, *args, **kwargs):
Exception.__init__(self, *args, **kwargs)

@ -543,22 +543,22 @@ class Environment():
return self.object_suffix return self.object_suffix
def get_prefix(self): def get_prefix(self):
return self.coredata.prefix return self.coredata.get_builtin_option('prefix')
def get_libdir(self): def get_libdir(self):
return self.coredata.libdir return self.coredata.get_builtin_option('libdir')
def get_bindir(self): def get_bindir(self):
return self.coredata.bindir return self.coredata.get_builtin_option('bindir')
def get_includedir(self): def get_includedir(self):
return self.coredata.includedir return self.coredata.get_builtin_option('includedir')
def get_mandir(self): def get_mandir(self):
return self.coredata.mandir return self.coredata.get_builtin_option('mandir')
def get_datadir(self): def get_datadir(self):
return self.coredata.datadir return self.coredata.get_builtin_option('datadir')
def find_library(self, libname, dirs): def find_library(self, libname, dirs):
if dirs is None: if dirs is None:

@ -855,7 +855,7 @@ class MesonMain(InterpreterObject):
raise InterpreterException('Tried to access compiler for unspecified language "%s".' % cname) raise InterpreterException('Tried to access compiler for unspecified language "%s".' % cname)
def is_unity_method(self, args, kwargs): 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): def is_subproject_method(self, args, kwargs):
return self.interpreter.is_subproject() return self.interpreter.is_subproject()
@ -933,6 +933,7 @@ class Interpreter():
'dependency' : self.func_dependency, 'dependency' : self.func_dependency,
'static_library' : self.func_static_lib, 'static_library' : self.func_static_lib,
'shared_library' : self.func_shared_lib, 'shared_library' : self.func_shared_lib,
'library' : self.func_library,
'jar' : self.func_jar, 'jar' : self.func_jar,
'build_target': self.func_build_target, 'build_target': self.func_build_target,
'custom_target' : self.func_custom_target, 'custom_target' : self.func_custom_target,
@ -1351,9 +1352,10 @@ class Interpreter():
if '=' not in option: if '=' not in option:
raise InterpreterException('All default options must be of type key=value.') raise InterpreterException('All default options must be of type key=value.')
key, value = option.split('=', 1) 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): 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. # If this was set on the command line, do not override.
else: else:
newoptions = [option] + self.environment.cmd_line_options.projectoptions newoptions = [option] + self.environment.cmd_line_options.projectoptions
@ -1579,6 +1581,11 @@ class Interpreter():
def func_shared_lib(self, node, args, kwargs): def func_shared_lib(self, node, args, kwargs):
return self.build_target(node, args, kwargs, SharedLibraryHolder) 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): def func_jar(self, node, args, kwargs):
return self.build_target(node, args, kwargs, JarHolder) return self.build_target(node, args, kwargs, JarHolder)
@ -1592,6 +1599,8 @@ class Interpreter():
return self.func_shared_lib(node, args, kwargs) return self.func_shared_lib(node, args, kwargs)
elif target_type == 'static_library': elif target_type == 'static_library':
return self.func_static_lib(node, args, kwargs) return self.func_static_lib(node, args, kwargs)
elif target_type == 'library':
return self.func_library(node, args, kwargs)
elif target_type == 'jar': elif target_type == 'jar':
return self.func_jar(node, args, kwargs) return self.func_jar(node, args, kwargs)
else: else:
@ -2021,7 +2030,7 @@ class Interpreter():
else: else:
obj = self.evaluate_statement(invokable) obj = self.evaluate_statement(invokable)
method_name = node.name 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.') raise InterpreterException('Single object files can not be extracted in Unity builds.')
args = node.args args = node.args
if isinstance(obj, mparser.StringNode): if isinstance(obj, mparser.StringNode):

@ -22,14 +22,11 @@ import build
import platform import platform
import mlog, coredata import mlog, coredata
from coredata import MesonException from coredata import MesonException, build_types, layouts, warning_levels, libtypelist
parser = argparse.ArgumentParser()
backendlist = ['ninja', 'vs2010', 'xcode'] backendlist = ['ninja', 'vs2010', 'xcode']
build_types = ['plain', 'debug', 'debugoptimized', 'release']
layouts = ['mirror', 'flat'] parser = argparse.ArgumentParser()
warning_levels = ['1', '2', '3']
default_warning = '2' default_warning = '2'
@ -68,6 +65,8 @@ parser.add_argument('--werror', action='store_true', dest='werror', default=Fals
help='Treat warnings as errors') help='Treat warnings as errors')
parser.add_argument('--layout', choices=layouts, dest='layout', default='mirror',\ parser.add_argument('--layout', choices=layouts, dest='layout', default='mirror',\
help='Build directory layout.') 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,\ 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)') help='Level of compiler warnings to use (larger is more, default is %(default)s)')
parser.add_argument('--cross-file', default=None, dest='cross_file', parser.add_argument('--cross-file', default=None, dest='cross_file',

@ -26,7 +26,7 @@ parser.add_argument('-D', action='append', default=[], dest='sets',
help='Set an option to the given value.') help='Set an option to the given value.')
parser.add_argument('directory', nargs='*') parser.add_argument('directory', nargs='*')
class ConfException(Exception): class ConfException(coredata.MesonException):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@ -69,55 +69,8 @@ class Conf:
if '=' not in o: if '=' not in o:
raise ConfException('Value "%s" not of type "a=b".' % o) raise ConfException('Value "%s" not of type "a=b".' % o)
(k, v) = o.split('=', 1) (k, v) = o.split('=', 1)
if k == 'buildtype': if self.coredata.is_builtin_option(k):
if v not in build_types: self.coredata.set_builtin_option(k, v)
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
elif k in self.coredata.user_options: elif k in self.coredata.user_options:
tgt = self.coredata.user_options[k] tgt = self.coredata.user_options[k]
tgt.set_value(v) tgt.set_value(v)
@ -150,12 +103,13 @@ class Conf:
print('') print('')
print('Core options\n') print('Core options\n')
carr = [] carr = []
carr.append(['buildtype', 'Build type', self.coredata.buildtype]) carr.append(['buildtype', 'Build type', self.coredata.get_builtin_option('buildtype')])
carr.append(['warnlevel', 'Warning level', self.coredata.warning_level]) carr.append(['warning_level', 'Warning level', self.coredata.get_builtin_option('warning_level')])
carr.append(['strip', 'Strip on install', self.coredata.strip]) carr.append(['strip', 'Strip on install', self.coredata.get_builtin_option('strip')])
carr.append(['coverage', 'Coverage report', self.coredata.coverage]) carr.append(['coverage', 'Coverage report', self.coredata.get_builtin_option('coverage')])
carr.append(['pch', 'Precompiled headers', self.coredata.use_pch]) carr.append(['use_pch', 'Precompiled headers', self.coredata.get_builtin_option('use_pch')])
carr.append(['unity', 'Unity build', self.coredata.unity]) 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) self.print_aligned(carr)
print('') print('')
print('Compiler arguments\n') print('Compiler arguments\n')
@ -179,13 +133,13 @@ class Conf:
print('') print('')
print('Directories\n') print('Directories\n')
parr = [] parr = []
parr.append(['prefix', 'Install prefix', self.coredata.prefix]) parr.append(['prefix', 'Install prefix', self.coredata.get_builtin_option('prefix')])
parr.append(['libdir', 'Library directory', self.coredata.libdir]) parr.append(['libdir', 'Library directory', self.coredata.get_builtin_option('libdir')])
parr.append(['bindir', 'Binary directory', self.coredata.bindir]) parr.append(['bindir', 'Binary directory', self.coredata.get_builtin_option('bindir')])
parr.append(['includedir', 'Header directory', self.coredata.includedir]) parr.append(['includedir', 'Header directory', self.coredata.get_builtin_option('includedir')])
parr.append(['datadir', 'Data directory', self.coredata.datadir]) parr.append(['datadir', 'Data directory', self.coredata.get_builtin_option('datadir')])
parr.append(['mandir', 'Man page directory', self.coredata.mandir]) parr.append(['mandir', 'Man page directory', self.coredata.get_builtin_option('mandir')])
parr.append(['localedir', 'Locale file directory', self.coredata.localedir]) parr.append(['localedir', 'Locale file directory', self.coredata.get_builtin_option('localedir')])
self.print_aligned(parr) self.print_aligned(parr)
print('') print('')
if len(self.coredata.user_options) == 0: if len(self.coredata.user_options) == 0:
@ -218,7 +172,7 @@ if __name__ == '__main__':
c.save() c.save()
else: else:
c.print_conf() c.print_conf()
except ConfException as e: except coredata.MesonException as e:
print('Meson configurator encountered an error:\n') print('Meson configurator encountered an error:\n')
print(e) print(e)

@ -264,80 +264,3 @@ def stringlistify(item):
if not isinstance(i, str): if not isinstance(i, str):
raise MesonException('List item not a string.') raise MesonException('List item not a string.')
return item 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

@ -150,7 +150,7 @@ class NinjaBackend(backends.Backend):
self.generate_tests(outfile) self.generate_tests(outfile)
outfile.write('# Install rules\n\n') outfile.write('# Install rules\n\n')
self.generate_install(outfile) self.generate_install(outfile)
if self.environment.coredata.coverage: if self.environment.coredata.get_builtin_option('coverage'):
outfile.write('# Coverage rules\n\n') outfile.write('# Coverage rules\n\n')
self.generate_coverage_rules(outfile) self.generate_coverage_rules(outfile)
outfile.write('# Suffix\n\n') outfile.write('# Suffix\n\n')
@ -203,8 +203,8 @@ class NinjaBackend(backends.Backend):
self.generate_custom_generator_rules(target, outfile) self.generate_custom_generator_rules(target, outfile)
outname = self.get_target_filename(target) outname = self.get_target_filename(target)
obj_list = [] obj_list = []
use_pch = self.environment.coredata.use_pch use_pch = self.environment.coredata.get_builtin_option('use_pch')
is_unity = self.environment.coredata.unity is_unity = self.environment.coredata.get_builtin_option('unity')
if use_pch and target.has_pch(): if use_pch and target.has_pch():
pch_objects = self.generate_pch(target, outfile) pch_objects = self.generate_pch(target, outfile)
else: else:
@ -444,14 +444,14 @@ class NinjaBackend(backends.Backend):
for lang in languages: for lang in languages:
rel_src = os.path.join(subdir, lang + '.gmo') rel_src = os.path.join(subdir, lang + '.gmo')
src_file = os.path.join(self.environment.get_build_dir(), rel_src) 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) elem.add_dep(rel_src)
def generate_target_install(self, d): def generate_target_install(self, d):
libdir = self.environment.get_libdir() libdir = self.environment.get_libdir()
bindir = self.environment.get_bindir() 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(): for t in self.build.get_targets().values():
if t.should_install(): if t.should_install():
outdir = t.get_custom_install_dir() outdir = t.get_custom_install_dir()
@ -465,7 +465,7 @@ class NinjaBackend(backends.Backend):
d.targets.append(i) d.targets.append(i)
def generate_pkgconfig_install(self, d): 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: for p in self.build.pkgconfig_gens:
pcfile = p.filebase + '.pc' pcfile = p.filebase + '.pc'
@ -647,7 +647,7 @@ class NinjaBackend(backends.Backend):
return (args, deps) return (args, deps)
def generate_cs_target(self, target, outfile): def generate_cs_target(self, target, outfile):
buildtype = self.environment.coredata.buildtype buildtype = self.environment.coredata.get_builtin_option('buildtype')
fname = target.get_filename() fname = target.get_filename()
outname_rel = os.path.join(self.get_target_dir(target), fname) outname_rel = os.path.join(self.get_target_dir(target), fname)
src_list = target.get_sources() src_list = target.get_sources()
@ -683,7 +683,7 @@ class NinjaBackend(backends.Backend):
def generate_single_java_compile(self, src, target, compiler, outfile): def generate_single_java_compile(self, src, target, compiler, outfile):
args = [] 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)) args += compiler.get_output_args(self.get_target_private_dir(target))
rel_src = src.rel_to_builddir(self.build_to_src) rel_src = src.rel_to_builddir(self.build_to_src)
plain_class_path = src.fname[:-4] + 'class' 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) relsc = os.path.join(self.get_target_private_dir_abs(target), sc)
rel_s = s.rel_to_builddir(self.build_to_src) rel_s = s.rel_to_builddir(self.build_to_src)
args += ['--deps', relsc + '.d'] args += ['--deps', relsc + '.d']
if self.environment.coredata.werror: if self.environment.coredata.get_builtin_option('werror'):
args += valac.get_werror_args() args += valac.get_werror_args()
for d in target.external_deps: for d in target.external_deps:
if isinstance(d, dependencies.PkgConfigDependency): 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 = os.path.join(self.get_target_private_dir(target), obj_basename)
rel_obj += '.' + self.environment.get_object_suffix() rel_obj += '.' + self.environment.get_object_suffix()
dep_file = rel_obj + '.' + compiler.get_depfile_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) pchlist = target.get_pch(compiler.language)
else: else:
pchlist = [] pchlist = []
@ -1287,7 +1287,7 @@ rule FORTRAN_DEP_HACK
custom_target_include_dirs.append(idir) custom_target_include_dirs.append(idir)
for i in custom_target_include_dirs: for i in custom_target_include_dirs:
commands+= compiler.get_include_args(i) 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) commands += self.get_pch_include_args(compiler, target)
crstr = '' crstr = ''
if target.is_cross: if target.is_cross:
@ -1425,7 +1425,7 @@ rule FORTRAN_DEP_HACK
abspath = os.path.join(self.environment.get_build_dir(), target.subdir) abspath = os.path.join(self.environment.get_build_dir(), target.subdir)
commands = [] commands = []
commands += linker.get_linker_always_args() 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) commands += linker.get_option_link_args(self.environment.coredata.compiler_options)
if not(isinstance(target, build.StaticLibrary)): if not(isinstance(target, build.StaticLibrary)):
commands += self.environment.coredata.external_link_args[linker.get_language()] commands += self.environment.coredata.external_link_args[linker.get_language()]
@ -1465,7 +1465,7 @@ rule FORTRAN_DEP_HACK
commands += dep.get_link_args() commands += dep.get_link_args()
commands += linker.build_rpath_args(self.environment.get_build_dir(),\ commands += linker.build_rpath_args(self.environment.get_build_dir(),\
self.determine_rpath_dirs(target), target.install_rpath) 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 += linker.get_coverage_link_args()
commands += extra_args commands += extra_args
dep_targets = [self.get_dependency_filename(t) for t in dependencies] 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 = NinjaBuildElement('clean', 'CUSTOM_COMMAND', 'PHONY')
elem.add_item('COMMAND', [ninja_command, '-t', 'clean']) elem.add_item('COMMAND', [ninja_command, '-t', 'clean'])
elem.add_item('description', 'Cleaning') elem.add_item('description', 'Cleaning')
if self.environment.coredata.coverage: if self.environment.coredata.get_builtin_option('coverage'):
self.generate_gcov_clean(outfile) self.generate_gcov_clean(outfile)
elem.add_dep('clean-gcda') elem.add_dep('clean-gcda')
elem.add_dep('clean-gcno') elem.add_dep('clean-gcno')

@ -40,11 +40,11 @@ class OptionException(coredata.MesonException):
optname_regex = re.compile('[^a-zA-Z0-9_-]') optname_regex = re.compile('[^a-zA-Z0-9_-]')
def StringParser(name, description, kwargs): def StringParser(name, description, kwargs):
return mesonlib.UserStringOption(name, description, return coredata.UserStringOption(name, description,
kwargs.get('value', '')) kwargs.get('value', ''))
def BooleanParser(name, description, kwargs): 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): def ComboParser(name, description, kwargs):
if 'choices' not in kwargs: if 'choices' not in kwargs:
@ -55,7 +55,7 @@ def ComboParser(name, description, kwargs):
for i in choices: for i in choices:
if not isinstance(i, str): if not isinstance(i, str):
raise OptionException('Combo choice elements must be strings.') 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, option_types = {'string' : StringParser,
'boolean' : BooleanParser, 'boolean' : BooleanParser,

@ -0,0 +1,8 @@
#include"ef.h"
Ef::Ef() : x(99) {
}
int Ef::get_x() const {
return x;
}

@ -0,0 +1,11 @@
#pragma once
class Ef {
private:
int x;
public:
Ef();
int get_x() const;
};

@ -0,0 +1,14 @@
#include"ef.h"
#include<iostream>
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;
}
}

@ -0,0 +1,5 @@
project('default library', 'cpp')
flib = library('ef', 'ef.cpp')
exe = executable('eftest', 'eftest.cpp', link_with : flib)
test('eftest', exe)
Loading…
Cancel
Save