Merge pull request #275 from mesonbuild/compileroptions

Compiler options
pull/282/head
Jussi Pakkanen 10 years ago
commit 172fa2f8dd
  1. 1
      backends.py
  2. 230
      compilers.py
  3. 1
      coredata.py
  4. 20
      interpreter.py
  5. 40
      mesonconf.py
  6. 10
      mesongui.py
  7. 17
      mesonintrospect.py
  8. 76
      mesonlib.py
  9. 1
      ninjabackend.py
  10. 103
      optinterpreter.py
  11. 6
      test cases/frameworks/1 boost/meson.build
  12. 4
      test cases/frameworks/4 qt5/meson.build
  13. 2
      test cases/frameworks/9 wxwidgets/meson.build

@ -210,6 +210,7 @@ class Backend():
commands += compiler.get_always_args()
if self.environment.coredata.buildtype != 'plain':
commands += compiler.get_warn_args(self.environment.coredata.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())

@ -91,6 +91,13 @@ mono_buildtype_args = {'plain' : [],
'debugoptimized': ['-debug', '-optimize+'],
'release' : ['-optimize+']}
gnu_winlibs = ['-lkernel32', '-luser32', '-lgdi32', '-lwinspool', '-lshell32',
'-lole32', '-loleaut32', '-luuid', '-lcomdlg32', '-ladvapi32']
msvc_winlibs = ['kernel32.lib', 'user32.lib', 'gdi32.lib',
'winspool.lib', 'shell32.lib', 'ole32.lib', 'oleaut32.lib',
'uuid.lib', 'comdlg32.lib', 'advapi32.lib']
def build_unix_rpath_args(build_dir, rpath_paths, install_rpath):
if len(rpath_paths) == 0 and len(install_rpath) == 0:
return []
@ -118,8 +125,8 @@ class RunResult():
self.stdout = stdout
self.stderr = stderr
class CCompiler():
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
class Compiler():
def __init__(self, exelist, version):
if type(exelist) == type(''):
self.exelist = [exelist]
elif type(exelist) == type([]):
@ -127,6 +134,25 @@ class CCompiler():
else:
raise TypeError('Unknown argument to CCompiler')
self.version = version
def get_always_args(self):
return []
def get_linker_always_args(self):
return []
def get_options(self):
return {} # build afresh every time
def get_option_compile_args(self, options):
return []
def get_option_link_args(self, options):
return []
class CCompiler(Compiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
super().__init__(exelist, version)
self.language = 'c'
self.default_suffix = 'c'
self.id = 'unknown'
@ -142,9 +168,6 @@ class CCompiler():
def get_always_args(self):
return []
def get_linker_always_args(self):
return []
def get_warn_args(self, level):
return self.warn_args[level]
@ -539,29 +562,17 @@ class ObjCPPCompiler(CPPCompiler):
if pe.returncode != 0:
raise EnvironmentException('Executables created by ObjC++ compiler %s are not runnable.' % self.name_string())
class MonoCompiler():
class MonoCompiler(Compiler):
def __init__(self, exelist, version):
if type(exelist) == type(''):
self.exelist = [exelist]
elif type(exelist) == type([]):
self.exelist = exelist
else:
raise TypeError('Unknown argument to Mono compiler')
self.version = version
super().__init__(exelist, version)
self.language = 'cs'
self.default_suffix = 'cs'
self.id = 'mono'
self.monorunner = 'mono'
def get_always_args(self):
return []
def get_output_args(self, fname):
return ['-out:' + fname]
def get_linker_always_args(self):
return []
def get_link_args(self, fname):
return ['-r:' + fname]
@ -679,26 +690,14 @@ class MonoCompiler():
def get_buildtype_args(self, buildtype):
return mono_buildtype_args[buildtype]
class JavaCompiler():
class JavaCompiler(Compiler):
def __init__(self, exelist, version):
if type(exelist) == type(''):
self.exelist = [exelist]
elif type(exelist) == type([]):
self.exelist = exelist
else:
raise TypeError('Unknown argument to JavaCompiler')
self.version = version
super().__init__(exelist, version)
self.language = 'java'
self.default_suffix = 'java'
self.id = 'unknown'
self.javarunner = 'java'
def get_always_args(self):
return []
def get_linker_always_args(self):
return []
def get_soname_args(self, shlib_name, path, soversion):
return []
@ -819,14 +818,9 @@ class JavaCompiler():
def has_function(self, funcname, prefix, env):
raise EnvironmentException('Java does not support function checks.')
class ValaCompiler():
class ValaCompiler(Compiler):
def __init__(self, exelist, version):
if isinstance(exelist, str):
self.exelist = [exelist]
elif type(exelist) == type([]):
self.exelist = exelist
else:
raise TypeError('Unknown argument to Vala compiler')
super().__init__(exelist, version)
self.version = version
self.id = 'unknown'
self.language = 'vala'
@ -863,15 +857,9 @@ class ValaCompiler():
suffix = filename.split('.')[-1]
return suffix in ('vala', 'vapi')
class RustCompiler():
class RustCompiler(Compiler):
def __init__(self, exelist, version):
if isinstance(exelist, str):
self.exelist = [exelist]
elif type(exelist) == type([]):
self.exelist = exelist
else:
raise TypeError('Unknown argument to Rust compiler')
self.version = version
super().__init__(exelist, version)
self.id = 'unknown'
self.language = 'rust'
@ -920,6 +908,7 @@ class VisualStudioCCompiler(CCompiler):
vs2010_always_args = ['/nologo', '/showIncludes']
vs2013_always_args = ['/nologo', '/showIncludes', '/FS']
def __init__(self, exelist, version, is_cross, exe_wrap):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
self.id = 'msvc'
@ -1012,6 +1001,15 @@ class VisualStudioCCompiler(CCompiler):
def thread_link_flags(self):
return []
def get_options(self):
return {'c_winlibs' : mesonlib.UserStringArrayOption('c_winlibs',
'Windows libs to link against.',
msvc_winlibs)
}
def get_option_link_args(self, options):
return options['c_winlibs'].value
class VisualStudioCPPCompiler(VisualStudioCCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap):
VisualStudioCCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
@ -1042,6 +1040,26 @@ class VisualStudioCPPCompiler(VisualStudioCCompiler):
if pe.returncode != 0:
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',
'C++ exception handling type.',
['none', 'a', 's', 'sc'],
'sc'),
'cpp_winlibs' : mesonlib.UserStringArrayOption('cpp_winlibs',
'Windows libs to link against.',
msvc_winlibs)
}
def get_option_compile_args(self, options):
args = []
std = options['cpp_eh']
if std.value != 'none':
args.append('/EH' + std.value)
return args
def get_option_link_args(self, options):
return options['cpp_winlibs'].value
GCC_STANDARD = 0
GCC_OSX = 1
GCC_MINGW = 2
@ -1059,6 +1077,7 @@ def get_gcc_soname_args(gcc_type, shlib_name, path, soversion):
else:
raise RuntimeError('Not implemented yet.')
class GnuCCompiler(CCompiler):
def __init__(self, exelist, version, gcc_type, is_cross, exe_wrapper=None):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
@ -1094,6 +1113,29 @@ class GnuCCompiler(CCompiler):
def can_compile(self, filename):
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',
['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',
gnu_winlibs),
})
return opts
def get_option_compile_args(self, options):
args = []
std = options['c_std']
if std.value != 'none':
args.append('-std=' + std.value)
return args
def get_option_link_args(self, options):
if self.gcc_type == GCC_MINGW:
return options['c_winlibs'].value
return []
class GnuObjCCompiler(ObjCCompiler):
std_opt_args = ['-O2']
@ -1182,6 +1224,22 @@ class ClangCCompiler(CCompiler):
# so it might change semantics at any time.
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',
['none', 'c89', 'c99', 'c11'],
'c11')}
def get_option_compile_args(self, options):
args = []
std = options['c_std']
if std.value != 'none':
args.append('-std=' + std.value)
return args
def get_option_link_args(self, options):
if self.gcc_type == GCC_MINGW:
return options['c_winlibs'].value
return []
class GnuCPPCompiler(CPPCompiler):
# may need to separate the latter to extra_debug_args or something
@ -1210,6 +1268,29 @@ class GnuCPPCompiler(CPPCompiler):
def get_soname_args(self, shlib_name, path, soversion):
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',
['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',
gnu_winlibs),
})
return opts
def get_option_compile_args(self, options):
args = []
std = options['cpp_std']
if std.value != 'none':
args.append('-std=' + std.value)
return args
def get_option_link_args(self, options):
if self.gcc_type == GCC_MINGW:
return options['cpp_winlibs'].value
return []
class ClangCPPCompiler(CPPCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
@ -1233,11 +1314,24 @@ class ClangCPPCompiler(CPPCompiler):
# so it might change semantics at any time.
return ['-include-pch', os.path.join (pch_dir, self.get_pch_name (header))]
class FortranCompiler():
def __init__(self, exelist, version,is_cross, exe_wrapper=None):
super().__init__()
self.exelist = exelist
self.version = version
def get_options(self):
return {'cpp_std' : mesonlib.UserComboOption('cpp_std', 'C++ language standard to use',
['none', 'c++03', 'c++11', 'c++1y'],
'c++11')}
def get_option_compile_args(self, options):
args = []
std = options['cpp_std']
if std.value != 'none':
args.append('-std=' + std.value)
return args
def get_option_link_args(self, options):
return []
class FortranCompiler(Compiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
super().__init__(exelist, version)
self.is_cross = is_cross
self.exe_wrapper = exe_wrapper
self.language = 'fortran'
@ -1293,12 +1387,6 @@ end program prog
if pe.returncode != 0:
raise EnvironmentException('Executables created by Fortran compiler %s are not runnable.' % self.name_string())
def get_always_args(self):
return ['-pipe']
def get_linker_always_args(self):
return []
def get_std_warn_args(self, level):
return FortranCompiler.std_warn_args
@ -1368,6 +1456,9 @@ class GnuFortranCompiler(FortranCompiler):
self.gcc_type = gcc_type
self.id = 'gcc'
def get_always_args(self):
return ['-pipe']
class G95FortranCompiler(FortranCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
super().__init__(exelist, version, is_cross, exe_wrapper=None)
@ -1376,6 +1467,9 @@ class G95FortranCompiler(FortranCompiler):
def get_module_outdir_args(self, path):
return ['-fmod='+path]
def get_always_args(self):
return ['-pipe']
class SunFortranCompiler(FortranCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
super().__init__(exelist, version, is_cross, exe_wrapper=None)
@ -1403,9 +1497,6 @@ class IntelFortranCompiler(FortranCompiler):
def get_module_outdir_args(self, path):
return ['-module', path]
def get_always_args(self):
return []
def can_compile(self, src):
suffix = os.path.splitext(src)[1].lower()
if suffix == '.f' or suffix == '.f90':
@ -1425,9 +1516,6 @@ class PathScaleFortranCompiler(FortranCompiler):
def get_module_outdir_args(self, path):
return ['-module', path]
def get_always_args(self):
return []
def can_compile(self, src):
suffix = os.path.splitext(src)[1].lower()
if suffix == '.f' or suffix == '.f90' or suffix == '.f95':
@ -1447,9 +1535,6 @@ class PGIFortranCompiler(FortranCompiler):
def get_module_outdir_args(self, path):
return ['-module', path]
def get_always_args(self):
return []
def can_compile(self, src):
suffix = os.path.splitext(src)[1].lower()
if suffix == '.f' or suffix == '.f90' or suffix == '.f95':
@ -1470,9 +1555,6 @@ class Open64FortranCompiler(FortranCompiler):
def get_module_outdir_args(self, path):
return ['-module', path]
def get_always_args(self):
return []
def can_compile(self, src):
suffix = os.path.splitext(src)[1].lower()
if suffix == '.f' or suffix == '.f90' or suffix == '.f95':
@ -1537,6 +1619,9 @@ class VisualStudioLinker():
def thread_link_flags(self):
return []
def get_option_link_args(self, options):
return []
class ArLinker():
std_args = ['csr']
@ -1570,3 +1655,6 @@ class ArLinker():
def thread_link_flags(self):
return []
def get_option_link_args(self, options):
return []

@ -61,6 +61,7 @@ class CoreData():
self.werror = options.werror
self.layout = options.layout
self.user_options = {}
self.compiler_options = {}
self.external_args = {} # These are set from "the outside" with e.g. mesonconf
self.external_link_args = {}
if options.cross_file is not None:

@ -1239,15 +1239,20 @@ class Interpreter():
if len(args) != 1:
raise InterpreterException('Argument required for get_option.')
optname = args[0]
if optname not in coredata.builtin_options and self.is_subproject():
optname = self.subproject + ':' + optname
try:
return self.environment.get_coredata().get_builtin_option(optname)
except RuntimeError:
pass
if optname not in self.environment.coredata.user_options:
try:
return self.environment.coredata.compiler_options[optname].value
except KeyError:
pass
if optname not in coredata.builtin_options and self.is_subproject():
optname = self.subproject + ':' + optname
try:
return self.environment.coredata.user_options[optname].value
except KeyError:
raise InterpreterException('Tried to access unknown option "%s".' % optname)
return self.environment.coredata.user_options[optname].value
@noKwargs
def func_configuration_data(self, node, args, kwargs):
@ -1365,6 +1370,13 @@ class Interpreter():
if cross_comp is not None:
cross_comp.sanity_check(self.environment.get_scratch_dir())
self.coredata.cross_compilers[lang] = cross_comp
new_options = comp.get_options()
optprefix = lang + '_'
for i in new_options:
if not i.startswith(optprefix):
raise InterpreterException('Internal error, %s has incorrect prefix.' % i)
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='')
if not comp.get_language() in self.coredata.external_args:
(ext_compile_args, ext_link_args) = environment.get_args_from_envvars(comp.get_language())

@ -1,6 +1,6 @@
#!/usr/bin/env python3
# Copyright 2014 The Meson development team
# Copyright 2014-2015 The Meson development team
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -17,7 +17,7 @@
import sys, os
import pickle
import argparse
import coredata, optinterpreter
import coredata, mesonlib
from meson import build_types, layouts, warning_levels
parser = argparse.ArgumentParser()
@ -64,13 +64,6 @@ class Conf:
f = '%s%s %s%s' % (name, namepad, descr, descrpad)
print(f, value)
def tobool(self, thing):
if thing.lower() == 'true':
return True
if thing.lower() == 'false':
return False
raise ConfException('Value %s is not boolean (true or false).' % thing)
def set_options(self, options):
for o in options:
if '=' not in o:
@ -127,18 +120,10 @@ class Conf:
self.coredata.localedir = v
elif k in self.coredata.user_options:
tgt = self.coredata.user_options[k]
if isinstance(tgt, optinterpreter.UserBooleanOption):
tgt.set_value(self.tobool(v))
elif isinstance(tgt, optinterpreter.UserComboOption):
try:
tgt.set_value(v)
except optinterpreter.OptionException:
raise ConfException('Value of %s must be one of %s.' %
(k, tgt.choices))
elif isinstance(tgt, optinterpreter.UserStringOption):
tgt.set_value(v)
else:
raise ConfException('Internal error, unknown option type.')
tgt.set_value(v)
elif k in self.coredata.compiler_options:
tgt = self.coredata.compiler_options[k]
tgt.set_value(v)
elif k.endswith('linkargs'):
lang = k[:-8]
if not lang in self.coredata.external_link_args:
@ -181,6 +166,17 @@ class Conf:
for (lang, args) in self.coredata.external_link_args.items():
print(lang + 'linkargs', str(args))
print('')
okeys = sorted(self.coredata.compiler_options.keys())
if len(okeys) == 0:
print('No compiler options\n')
else:
print('Compiler options\n')
coarr = []
for k in okeys:
o = self.coredata.compiler_options[k]
coarr.append([k, o.description, o.value])
self.print_aligned(coarr)
print('')
print('Directories\n')
parr = []
parr.append(['prefix', 'Install prefix', self.coredata.prefix])
@ -193,7 +189,7 @@ class Conf:
self.print_aligned(parr)
print('')
if len(self.coredata.user_options) == 0:
print('This project does not have any options')
print('This project does not have user options')
else:
print('Project options\n')
options = self.coredata.user_options

@ -1,6 +1,6 @@
#!/usr/bin/env python3
# Copyright 2013 The Meson development team
# Copyright 2013-2015 The Meson development team
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -15,7 +15,7 @@
# limitations under the License.
import sys, os, pickle, time, shutil
import build, coredata, environment, optinterpreter
import build, coredata, environment, mesonlib
from PyQt5 import uic
from PyQt5.QtWidgets import QApplication, QMainWindow, QHeaderView
from PyQt5.QtWidgets import QComboBox, QCheckBox
@ -272,14 +272,14 @@ class OptionForm:
self.opt_widgets = []
for key in keys:
opt = options[key]
if isinstance(opt, optinterpreter.UserStringOption):
if isinstance(opt, mesonlib.UserStringOption):
w = PyQt5.QtWidgets.QLineEdit(opt.value)
w.textChanged.connect(self.user_option_changed)
elif isinstance(opt, optinterpreter.UserBooleanOption):
elif isinstance(opt, mesonlib.UserBooleanOption):
w = QCheckBox('')
w.setChecked(opt.value)
w.stateChanged.connect(self.user_option_changed)
elif isinstance(opt, optinterpreter.UserComboOption):
elif isinstance(opt, mesonlib.UserComboOption):
w = QComboBox()
for i in opt.choices:
w.addItem(i)

@ -22,7 +22,7 @@ Currently only works for the Ninja backend. Others use generated
project files and don't need this info."""
import json, pickle
import coredata, build, optinterpreter
import coredata, build, mesonlib
import argparse
import sys, os
@ -107,7 +107,11 @@ def list_buildoptions(coredata, builddata):
'description' : 'Unity build',
'name' : 'unity'}
optlist = [buildtype, strip, coverage, pch, unity]
options = coredata.user_options
add_keys(optlist, coredata.user_options)
add_keys(optlist, coredata.compiler_options)
print(json.dumps(optlist))
def add_keys(optlist, options):
keys = list(options.keys())
keys.sort()
for key in keys:
@ -115,19 +119,20 @@ def list_buildoptions(coredata, builddata):
optdict = {}
optdict['name'] = key
optdict['value'] = opt.value
if isinstance(opt, optinterpreter.UserStringOption):
if isinstance(opt, mesonlib.UserStringOption):
typestr = 'string'
elif isinstance(opt, optinterpreter.UserBooleanOption):
elif isinstance(opt, mesonlib.UserBooleanOption):
typestr = 'boolean'
elif isinstance(opt, optinterpreter.UserComboOption):
elif isinstance(opt, mesonlib.UserComboOption):
optdict['choices'] = opt.choices
typestr = 'combo'
elif isinstance(opt, mesonlib.UserStringArrayOption):
typestr = 'stringarray'
else:
raise RuntimeError("Unknown option type")
optdict['type'] = typestr
optdict['description'] = opt.description
optlist.append(optdict)
print(json.dumps(optlist))
def list_buildsystem_files(coredata, builddata):
src_dir = builddata.environment.get_source_dir()

@ -255,3 +255,79 @@ def replace_if_different(dst, dst_tmp):
pass
os.replace(dst_tmp, dst)
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

@ -1454,6 +1454,7 @@ rule FORTRAN_DEP_HACK
commands = []
commands += linker.get_linker_always_args()
commands += linker.get_buildtype_linker_args(self.environment.coredata.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()]
if isinstance(target, build.Executable):

@ -1,4 +1,4 @@
# Copyright 2013-2014 The Meson development team
# Copyright 2013-2015 The Meson development team
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -13,74 +13,53 @@
# limitations under the License.
import mparser
import coredata
import coredata, mesonlib
import os, re
forbidden_option_names = coredata.builtin_options
forbidden_prefixes = {'c_': True,
'cpp_': True,
'rust_': True,
'fortran_': True,
'objc_': True,
'objcpp_': True,
'vala_': True,
'csharp_': True
}
def is_invalid_name(name):
if name in forbidden_option_names:
return True
if name in forbidden_prefixes:
return True
return False
class OptionException(coredata.MesonException):
pass
optname_regex = re.compile('[^a-zA-Z0-9_-]')
class UserOption:
def __init__(self, name, kwargs):
super().__init__()
self.description = kwargs.get('description', '')
self.name = name
def parse_string(self, valuestring):
return valuestring
class UserStringOption(UserOption):
def __init__(self, name, kwargs):
super().__init__(name, kwargs)
self.set_value(kwargs.get('value', ''))
def set_value(self, newvalue):
if not isinstance(newvalue, str):
raise OptionException('Value "%s" for string option "%s" is not a string.' % (str(newvalue), self.name))
self.value = newvalue
class UserBooleanOption(UserOption):
def __init__(self, name, kwargs):
super().__init__(name, kwargs)
self.set_value(kwargs.get('value', 'true'))
def set_value(self, newvalue):
if not isinstance(newvalue, bool):
raise OptionException('Value "%s" for boolean option "%s" is not a boolean.' % (str(newvalue), self.name))
self.value = newvalue
def parse_string(self, valuestring):
if valuestring == 'false':
return False
if valuestring == 'true':
return True
raise OptionException('Value "%s" for boolean option "%s" is not a boolean.' % (valuestring, self.name))
class UserComboOption(UserOption):
def __init__(self, name, kwargs):
super().__init__(name, kwargs)
if 'choices' not in kwargs:
raise OptionException('Combo option missing "choices" keyword.')
self.choices = kwargs['choices']
if not isinstance(self.choices, list):
raise OptionException('Combo choices must be an array.')
for i in self.choices:
if not isinstance(i, str):
raise OptionException('Combo choice elements must be strings.')
self.value = kwargs.get('value', self.choices[0])
def set_value(self, newvalue):
if newvalue not in self.choices:
optionsstring = ', '.join(['"%s"' % (item,) for item in self.choices])
raise OptionException('Value "%s" for combo option "%s" is not one of the choices. Possible choices are: %s.' % (newvalue, self.name, optionsstring))
self.value = newvalue
option_types = {'string' : UserStringOption,
'boolean' : UserBooleanOption,
'combo' : UserComboOption,
def StringParser(name, description, kwargs):
return mesonlib.UserStringOption(name, description,
kwargs.get('value', ''))
def BooleanParser(name, description, kwargs):
return mesonlib.UserBooleanOption(name, description, kwargs.get('value', True))
def ComboParser(name, description, kwargs):
if 'choices' not in kwargs:
raise OptionException('Combo option missing "choices" keyword.')
choices = kwargs['choices']
if not isinstance(choices, list):
raise OptionException('Combo choices must be an array.')
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]))
option_types = {'string' : StringParser,
'boolean' : BooleanParser,
'combo' : ComboParser,
}
class OptionInterpreter:
@ -157,11 +136,11 @@ class OptionInterpreter:
raise OptionException('Positional argument must be a string.')
if optname_regex.search(opt_name) is not None:
raise OptionException('Option names can only contain letters, numbers or dashes.')
if opt_name in forbidden_option_names:
if is_invalid_name(opt_name):
raise OptionException('Option name %s is reserved.' % opt_name)
if self.subproject != '':
opt_name = self.subproject + ':' + opt_name
opt = option_types[opt_type](opt_name, kwargs)
opt = option_types[opt_type](opt_name, kwargs.get('description', ''), kwargs)
if opt.description == '':
opt.description = opt_name
if opt_name in self.cmd_line_options:

@ -1,11 +1,5 @@
project('boosttest', 'cpp')
if meson.get_compiler('cpp').get_id() != 'msvc'
add_global_arguments('-std=c++11', language : 'cpp')
else
add_global_arguments('/EHsc', language : 'cpp')
endif
# We want to have multiple separate configurations of Boost
# within one project. The need to be independent of each other.
# Use one without a library dependency and one with it.

@ -3,10 +3,6 @@ project('qt5 build test', 'cpp')
qt5 = import('qt5')
qt5dep = dependency('qt5', modules : ['Core', 'Gui', 'Widgets'])
if meson.get_compiler('cpp').get_id() != 'msvc'
add_global_arguments('-std=c++11', language : 'cpp')
endif
prep = qt5.preprocess(
moc_headers : ['mainWindow.h'], # These need to be fed through the moc tool before use.
ui_files : 'mainWindow.ui', # XML files that need to be compiled with the uic tol.

@ -1,7 +1,5 @@
project('wxwidgets test', 'cpp')
add_global_arguments('-std=c++11', language : 'cpp')
wxd = dependency('wxwidgets', version : '>=3.0.0')
wp = executable('wxprog', 'wxprog.cpp',

Loading…
Cancel
Save