use OptionKey for builtin and base options

I would have prefered to do these seperatately, but they are combined in
some cases, so it was much easier to convert them together.

this eliminates the builtins_per_machine dict, as it's duplicated with
the OptionKey's machine parameter.
pull/8080/head
Dylan Baker 4 years ago
parent f9b19e73a5
commit 71db6b04a3
  1. 29
      mesonbuild/backend/backends.py
  2. 39
      mesonbuild/backend/ninjabackend.py
  3. 8
      mesonbuild/backend/vs2010backend.py
  4. 35
      mesonbuild/build.py
  5. 4
      mesonbuild/cmake/executor.py
  6. 2
      mesonbuild/cmake/interpreter.py
  7. 106
      mesonbuild/compilers/compilers.py
  8. 2
      mesonbuild/compilers/cpp.py
  9. 12
      mesonbuild/compilers/d.py
  10. 7
      mesonbuild/compilers/mixins/arm.py
  11. 7
      mesonbuild/compilers/mixins/clang.py
  12. 7
      mesonbuild/compilers/mixins/clike.py
  13. 6
      mesonbuild/compilers/mixins/elbrus.py
  14. 2
      mesonbuild/compilers/mixins/emscripten.py
  15. 14
      mesonbuild/compilers/mixins/gnu.py
  16. 5
      mesonbuild/compilers/mixins/intel.py
  17. 3
      mesonbuild/compilers/mixins/pgi.py
  18. 2
      mesonbuild/compilers/mixins/visualstudio.py
  19. 4
      mesonbuild/compilers/rust.py
  20. 4
      mesonbuild/compilers/vala.py
  21. 244
      mesonbuild/coredata.py
  22. 11
      mesonbuild/dependencies/base.py
  23. 4
      mesonbuild/dependencies/boost.py
  24. 4
      mesonbuild/dependencies/ui.py
  25. 43
      mesonbuild/interpreter.py
  26. 60
      mesonbuild/mconf.py
  27. 78
      mesonbuild/mesonlib.py
  28. 38
      mesonbuild/mintro.py
  29. 14
      mesonbuild/modules/gnome.py
  30. 2
      mesonbuild/msetup.py
  31. 6
      mesonbuild/rewriter.py
  32. 73
      run_unittests.py

@ -32,7 +32,7 @@ from .. import mlog
from ..compilers import languages_using_ldflags
from ..mesonlib import (
File, MachineChoice, MesonException, OrderedSet, OptionOverrideProxy,
classify_unity_sources, unholder
classify_unity_sources, unholder, OptionKey
)
if T.TYPE_CHECKING:
@ -211,21 +211,21 @@ class Backend:
def get_target_filename_abs(self, target):
return os.path.join(self.environment.get_build_dir(), self.get_target_filename(target))
def get_base_options_for_target(self, target):
def get_base_options_for_target(self, target: build.BuildTarget) -> OptionOverrideProxy:
return OptionOverrideProxy(target.option_overrides_base,
self.environment.coredata.builtins,
self.environment.coredata.base_options)
{k: v for k, v in self.environment.coredata.base_options.items()})
def get_compiler_options_for_target(self, target: build.BuildTarget) -> OptionOverrideProxy:
comp_reg = self.environment.coredata.compiler_options
comp_override = target.option_overrides_compiler
return OptionOverrideProxy(comp_override, comp_reg)
def get_option_for_target(self, option_name, target):
def get_option_for_target(self, option_name: 'OptionKey', target: build.BuildTarget):
if option_name in target.option_overrides_base:
override = target.option_overrides_base[option_name]
return self.environment.coredata.validate_option_value(option_name, override)
return self.environment.coredata.get_builtin_option(option_name, target.subproject)
return self.environment.coredata.get_builtin_option(str(option_name), target.subproject)
def get_target_filename_for_linking(self, target):
# On some platforms (msvc for instance), the file that is used for
@ -299,7 +299,7 @@ class Backend:
abs_files = []
result = []
compsrcs = classify_unity_sources(target.compilers.values(), unity_src)
unity_size = self.get_option_for_target('unity_size', target)
unity_size = self.get_option_for_target(OptionKey('unity_size'), target)
def init_language_file(suffix, unity_file_number):
unity_src = self.get_unity_source_file(target, suffix, unity_file_number)
@ -620,7 +620,8 @@ class Backend:
if self.is_unity(extobj.target):
compsrcs = classify_unity_sources(extobj.target.compilers.values(), sources)
sources = []
unity_size = self.get_option_for_target('unity_size', extobj.target)
unity_size = self.get_option_for_target(OptionKey('unity_size'), extobj.target)
for comp, srcs in compsrcs.items():
for i in range(len(srcs) // unity_size + 1):
osrc = self.get_unity_source_file(extobj.target,
@ -689,20 +690,20 @@ class Backend:
if no_warn_args:
commands += compiler.get_no_warn_args()
else:
commands += compiler.get_warn_args(self.get_option_for_target('warning_level', target))
commands += compiler.get_warn_args(self.get_option_for_target(OptionKey('warning_level'), target))
# Add -Werror if werror=true is set in the build options set on the
# command-line or default_options inside project(). This only sets the
# action to be done for warnings if/when they are emitted, so it's ok
# to set it after get_no_warn_args() or get_warn_args().
if self.get_option_for_target('werror', target):
if self.get_option_for_target(OptionKey('werror'), target):
commands += compiler.get_werror_args()
# Add compile args for c_* or cpp_* build options set on the
# command-line or default_options inside project().
commands += compiler.get_option_compile_args(copt_proxy)
# Add buildtype args: optimization level, debugging, etc.
commands += compiler.get_buildtype_args(self.get_option_for_target('buildtype', target))
commands += compiler.get_optimization_args(self.get_option_for_target('optimization', target))
commands += compiler.get_debug_args(self.get_option_for_target('debug', target))
commands += compiler.get_buildtype_args(self.get_option_for_target(OptionKey('buildtype'), target))
commands += compiler.get_optimization_args(self.get_option_for_target(OptionKey('optimization'), target))
commands += compiler.get_debug_args(self.get_option_for_target(OptionKey('debug'), target))
# MSVC debug builds have /ZI argument by default and /Zi is added with debug flag
# /ZI needs to be removed in that case to avoid cl's warning to that effect (D9025 : overriding '/ZI' with '/Zi')
if ('/ZI' in commands) and ('/Zi' in commands):
@ -1021,7 +1022,7 @@ class Backend:
return libs
def is_unity(self, target):
optval = self.get_option_for_target('unity', target)
optval = self.get_option_for_target(OptionKey('unity'), target)
if optval == 'on' or (optval == 'subprojects' and target.subproject != ''):
return True
return False
@ -1227,7 +1228,7 @@ class Backend:
#
# TODO: Create GNUStrip/AppleStrip/etc. hierarchy for more
# fine-grained stripping of static archives.
should_strip = not isinstance(t, build.StaticLibrary) and self.get_option_for_target('strip', t)
should_strip = not isinstance(t, build.StaticLibrary) and self.get_option_for_target(OptionKey('strip'), t)
# Install primary build output (library/executable/jar, etc)
# Done separately because of strip/aliases/rpath
if outdirs[0] is not False:

@ -537,8 +537,9 @@ int dummy;
self.add_build_comment(NinjaComment('Install rules'))
self.generate_install()
self.generate_dist()
if 'b_coverage' in self.environment.coredata.base_options and \
self.environment.coredata.base_options['b_coverage'].value:
key = OptionKey('b_coverage')
if (key in self.environment.coredata.base_options and
self.environment.coredata.base_options[key].value):
self.add_build_comment(NinjaComment('Coverage rules'))
self.generate_coverage_rules()
self.add_build_comment(NinjaComment('Suffix'))
@ -814,7 +815,7 @@ int dummy;
source2object[s] = o
obj_list.append(o)
use_pch = self.environment.coredata.base_options.get('b_pch', False)
use_pch = self.environment.coredata.base_options.get(OptionKey('b_pch'))
if use_pch and target.has_pch():
pch_objects = self.generate_pch(target, header_deps=header_deps)
else:
@ -1297,8 +1298,8 @@ int dummy;
args.append(a)
return args, deps
def generate_cs_target(self, target):
buildtype = self.get_option_for_target('buildtype', target)
def generate_cs_target(self, target: build.BuildTarget):
buildtype = self.get_option_for_target(OptionKey('buildtype'), target)
fname = target.get_filename()
outname_rel = os.path.join(self.get_target_dir(target), fname)
src_list = target.get_sources()
@ -1307,8 +1308,8 @@ int dummy;
deps = []
commands = compiler.compiler_args(target.extra_args.get('cs', []))
commands += compiler.get_buildtype_args(buildtype)
commands += compiler.get_optimization_args(self.get_option_for_target('optimization', target))
commands += compiler.get_debug_args(self.get_option_for_target('debug', target))
commands += compiler.get_optimization_args(self.get_option_for_target(OptionKey('optimization'), target))
commands += compiler.get_debug_args(self.get_option_for_target(OptionKey('debug'), target))
if isinstance(target, build.Executable):
commands.append('-target:exe')
elif isinstance(target, build.SharedLibrary):
@ -1349,7 +1350,7 @@ int dummy;
def determine_single_java_compile_args(self, target, compiler):
args = []
args += compiler.get_buildtype_args(self.get_option_for_target('buildtype', target))
args += compiler.get_buildtype_args(self.get_option_for_target(OptionKey('buildtype'), target))
args += self.build.get_global_args(compiler, target.for_machine)
args += self.build.get_project_args(compiler, target.subproject, target.for_machine)
args += target.get_java_args()
@ -1512,7 +1513,7 @@ int dummy;
valac_outputs.append(vala_c_file)
args = self.generate_basic_compiler_args(target, valac)
args += valac.get_colorout_args(self.environment.coredata.base_options.get('b_colorout').value)
args += valac.get_colorout_args(self.environment.coredata.base_options.get(OptionKey('b_colorout')).value)
# Tell Valac to output everything in our private directory. Sadly this
# means it will also preserve the directory components of Vala sources
# found inside the build tree (generated sources).
@ -1619,9 +1620,9 @@ int dummy;
opt_proxy = self.get_compiler_options_for_target(target)
args += ['--crate-name', target.name]
args += rustc.get_buildtype_args(self.get_option_for_target('buildtype', target))
args += rustc.get_debug_args(self.get_option_for_target('debug', target))
args += rustc.get_optimization_args(self.get_option_for_target('optimization', target))
args += rustc.get_buildtype_args(self.get_option_for_target(OptionKey('buildtype'), target))
args += rustc.get_debug_args(self.get_option_for_target(OptionKey('debug'), target))
args += rustc.get_optimization_args(self.get_option_for_target(OptionKey('optimization'), target))
args += rustc.get_option_compile_args(opt_proxy)
args += self.build.get_global_args(rustc, target.for_machine)
args += self.build.get_project_args(rustc, target.subproject, target.for_machine)
@ -1772,8 +1773,8 @@ int dummy;
raise InvalidArguments('Swift target {} contains a non-swift source file.'.format(target.get_basename()))
os.makedirs(self.get_target_private_dir_abs(target), exist_ok=True)
compile_args = swiftc.get_compile_only_args()
compile_args += swiftc.get_optimization_args(self.get_option_for_target('optimization', target))
compile_args += swiftc.get_debug_args(self.get_option_for_target('debug', target))
compile_args += swiftc.get_optimization_args(self.get_option_for_target(OptionKey('optimization'), target))
compile_args += swiftc.get_debug_args(self.get_option_for_target(OptionKey('debug'), target))
compile_args += swiftc.get_module_args(module_name)
compile_args += self.build.get_project_args(swiftc, target.subproject, target.for_machine)
compile_args += self.build.get_global_args(swiftc, target.for_machine)
@ -2498,7 +2499,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
commands += self.get_compile_debugfile_args(compiler, target, rel_obj)
# PCH handling
if self.environment.coredata.base_options.get('b_pch', False):
if self.environment.coredata.base_options.get(OptionKey('b_pch')):
commands += self.get_pch_include_args(compiler, target)
pchlist = target.get_pch(compiler.language)
else:
@ -2869,9 +2870,9 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
# Add things like /NOLOGO; usually can't be overridden
commands += linker.get_linker_always_args()
# Add buildtype linker args: optimization level, etc.
commands += linker.get_buildtype_linker_args(self.get_option_for_target('buildtype', target))
commands += linker.get_buildtype_linker_args(self.get_option_for_target(OptionKey('buildtype'), target))
# Add /DEBUG and the pdb filename when using MSVC
if self.get_option_for_target('debug', target):
if self.get_option_for_target(OptionKey('debug'), target):
commands += self.get_link_debugfile_args(linker, target, outname)
debugfile = self.get_link_debugfile_name(linker, target, outname)
if debugfile is not None:
@ -3155,8 +3156,8 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
if ctlist:
elem.add_dep(self.generate_custom_target_clean(ctlist))
if 'b_coverage' in self.environment.coredata.base_options and \
self.environment.coredata.base_options['b_coverage'].value:
if OptionKey('b_coverage') in self.environment.coredata.base_options and \
self.environment.coredata.base_options[OptionKey('b_coverage')].value:
self.generate_gcov_clean()
elem.add_dep('clean-gcda')
elem.add_dep('clean-gcno')

@ -785,7 +785,7 @@ class Vs2010Backend(backends.Backend):
build_args += compiler.get_optimization_args(self.optimization)
build_args += compiler.get_debug_args(self.debug)
buildtype_link_args = compiler.get_buildtype_linker_args(self.buildtype)
vscrt_type = self.environment.coredata.base_options['b_vscrt']
vscrt_type = self.environment.coredata.base_options[OptionKey('b_vscrt')]
project_name = target.name
target_name = target.name
root = ET.Element('Project', {'DefaultTargets': "Build",
@ -1048,9 +1048,9 @@ class Vs2010Backend(backends.Backend):
ET.SubElement(clconf, 'PreprocessorDefinitions').text = ';'.join(target_defines)
ET.SubElement(clconf, 'FunctionLevelLinking').text = 'true'
# Warning level
warning_level = self.get_option_for_target('warning_level', target)
warning_level = self.get_option_for_target(OptionKey('warning_level'), target)
ET.SubElement(clconf, 'WarningLevel').text = 'Level' + str(1 + int(warning_level))
if self.get_option_for_target('werror', target):
if self.get_option_for_target(OptionKey('werror'), target):
ET.SubElement(clconf, 'TreatWarningAsError').text = 'true'
# Optimization flags
o_flags = split_o_flags_args(build_args)
@ -1075,7 +1075,7 @@ class Vs2010Backend(backends.Backend):
ET.SubElement(clconf, 'FavorSizeOrSpeed').text = 'Speed'
# Note: SuppressStartupBanner is /NOLOGO and is 'true' by default
pch_sources = {}
if self.environment.coredata.base_options.get('b_pch', False):
if self.environment.coredata.base_options.get(OptionKey('b_pch')):
for lang in ['c', 'cpp']:
pch = target.get_pch(lang)
if not pch:

@ -404,7 +404,7 @@ class EnvironmentVariables:
return env
class Target:
def __init__(self, name, subdir, subproject, build_by_default, for_machine: MachineChoice):
def __init__(self, name, subdir, subproject, build_by_default: bool, for_machine: MachineChoice):
if has_path_sep(name):
# Fix failing test 53 when this becomes an error.
mlog.warning('''Target "{}" has a path separator in its name.
@ -417,7 +417,7 @@ a hard error in the future.'''.format(name))
self.for_machine = for_machine
self.install = False
self.build_always_stale = False
self.option_overrides_base: 'OptionDictType' = {}
self.option_overrides_base: T.Dict[OptionKey, str] = {}
self.option_overrides_compiler: 'KeyedOptionDictType' = {}
self.extra_files = [] # type: T.List[File]
if not hasattr(self, 'typename'):
@ -499,7 +499,7 @@ a hard error in the future.'''.format(name))
return self.construct_id_from_path(
self.subdir, self.name, self.type_suffix())
def process_kwargs_base(self, kwargs):
def process_kwargs_base(self, kwargs: T.Dict[str, T.Any]) -> None:
if 'build_by_default' in kwargs:
self.build_by_default = kwargs['build_by_default']
if not isinstance(self.build_by_default, bool):
@ -512,23 +512,22 @@ a hard error in the future.'''.format(name))
option_overrides = self.parse_overrides(kwargs)
for k, v in option_overrides.items():
if '_' in k:
key = OptionKey.from_string(k)
if key.lang:
self.option_overrides_compiler[key.evolve(machine=self.for_machine)] = v
continue
if k.lang:
self.option_overrides_compiler[k.evolve(machine=self.for_machine)] = v
continue
self.option_overrides_base[k] = v
def parse_overrides(self, kwargs) -> dict:
result = {}
@staticmethod
def parse_overrides(kwargs: T.Dict[str, T.Any]) -> T.Dict[OptionKey, str]:
result: T.Dict[OptionKey, str] = {}
overrides = stringlistify(kwargs.get('override_options', []))
for o in overrides:
if '=' not in o:
raise InvalidArguments('Overrides must be of form "key=value"')
k, v = o.split('=', 1)
k = k.strip()
key = OptionKey.from_string(k.strip())
v = v.strip()
result[k] = v
result[key] = v
return result
def is_linkable_target(self) -> bool:
@ -1066,17 +1065,18 @@ This will become a hard error in a future Meson release.''')
raise InvalidArguments('Invalid value for win_subsystem: {}.'.format(value))
return value
def _extract_pic_pie(self, kwargs, arg, environment, option):
def _extract_pic_pie(self, kwargs, arg: str, environment, option: str):
# Check if we have -fPIC, -fpic, -fPIE, or -fpie in cflags
all_flags = self.extra_args['c'] + self.extra_args['cpp']
if '-f' + arg.lower() in all_flags or '-f' + arg.upper() in all_flags:
mlog.warning("Use the '{}' kwarg instead of passing '{}' manually to {!r}".format(arg, '-f' + arg, self.name))
return True
k = OptionKey(option)
if arg in kwargs:
val = kwargs[arg]
elif option in environment.coredata.base_options:
val = environment.coredata.base_options[option].value
elif k in environment.coredata.base_options:
val = environment.coredata.base_options[k].value
else:
val = False
@ -1597,8 +1597,9 @@ class Executable(BuildTarget):
def __init__(self, name: str, subdir: str, subproject: str, for_machine: MachineChoice,
sources: T.List[File], objects, environment: environment.Environment, kwargs):
self.typename = 'executable'
if 'pie' not in kwargs and 'b_pie' in environment.coredata.base_options:
kwargs['pie'] = environment.coredata.base_options['b_pie'].value
key = OptionKey('b_pie')
if 'pie' not in kwargs and key in environment.coredata.base_options:
kwargs['pie'] = environment.coredata.base_options[key].value
super().__init__(name, subdir, subproject, for_machine, sources, objects, environment, kwargs)
# Unless overridden, executables have no suffix or prefix. Except on
# Windows and with C#/Mono executables where the suffix is 'exe'

@ -23,7 +23,7 @@ import re
import os
from .. import mlog
from ..mesonlib import PerMachine, Popen_safe, version_compare, MachineChoice, is_windows
from ..mesonlib import PerMachine, Popen_safe, version_compare, MachineChoice, is_windows, OptionKey
from ..envconfig import get_env_var
if T.TYPE_CHECKING:
@ -62,7 +62,7 @@ class CMakeExecutor:
self.cmakebin = None
return
self.prefix_paths = self.environment.coredata.builtins_per_machine[self.for_machine]['cmake_prefix_path'].value
self.prefix_paths = self.environment.coredata.builtins[OptionKey('cmake_prefix_path', machine=self.for_machine)].value
env_pref_path_raw = get_env_var(
self.for_machine,
self.environment.is_cross_build(),

@ -578,7 +578,7 @@ class ConverterTarget:
@lru_cache(maxsize=None)
def _all_lang_stds(self, lang: str) -> T.List[str]:
try:
res = self.env.coredata.compiler_options[OptionKey('std', machine=MachineChoice.BUILD, lang=lang)].choices # type: ignore
res = self.env.coredata.compiler_options[OptionKey('std', machine=MachineChoice.BUILD, lang=lang)].choices
except KeyError:
return []

@ -265,36 +265,32 @@ cuda_debug_args = {False: [],
clike_debug_args = {False: [],
True: ['-g']} # type: T.Dict[bool, T.List[str]]
base_options = {'b_pch': coredata.UserBooleanOption('Use precompiled headers', True),
'b_lto': coredata.UserBooleanOption('Use link time optimization', False),
'b_sanitize': coredata.UserComboOption('Code sanitizer to use',
['none', 'address', 'thread', 'undefined', 'memory', 'address,undefined'],
'none'),
'b_lundef': coredata.UserBooleanOption('Use -Wl,--no-undefined when linking', True),
'b_asneeded': coredata.UserBooleanOption('Use -Wl,--as-needed when linking', True),
'b_pgo': coredata.UserComboOption('Use profile guided optimization',
['off', 'generate', 'use'],
'off'),
'b_coverage': coredata.UserBooleanOption('Enable coverage tracking.',
False),
'b_colorout': coredata.UserComboOption('Use colored output',
['auto', 'always', 'never'],
'always'),
'b_ndebug': coredata.UserComboOption('Disable asserts',
['true', 'false', 'if-release'], 'false'),
'b_staticpic': coredata.UserBooleanOption('Build static libraries as position independent',
True),
'b_pie': coredata.UserBooleanOption('Build executables as position independent',
False),
'b_bitcode': coredata.UserBooleanOption('Generate and embed bitcode (only macOS/iOS/tvOS)',
False),
'b_vscrt': coredata.UserComboOption('VS run-time library type to use.',
['none', 'md', 'mdd', 'mt', 'mtd', 'from_buildtype', 'static_from_buildtype'],
'from_buildtype'),
} # type: OptionDictType
def option_enabled(boptions: T.List[str], options: 'OptionDictType',
option: str) -> bool:
base_options: 'KeyedOptionDictType' = {
OptionKey('b_pch'): coredata.UserBooleanOption('Use precompiled headers', True),
OptionKey('b_lto'): coredata.UserBooleanOption('Use link time optimization', False),
OptionKey('b_sanitize'): coredata.UserComboOption('Code sanitizer to use',
['none', 'address', 'thread', 'undefined', 'memory', 'address,undefined'],
'none'),
OptionKey('b_lundef'): coredata.UserBooleanOption('Use -Wl,--no-undefined when linking', True),
OptionKey('b_asneeded'): coredata.UserBooleanOption('Use -Wl,--as-needed when linking', True),
OptionKey('b_pgo'): coredata.UserComboOption('Use profile guided optimization',
['off', 'generate', 'use'],
'off'),
OptionKey('b_coverage'): coredata.UserBooleanOption('Enable coverage tracking.', False),
OptionKey('b_colorout'): coredata.UserComboOption('Use colored output',
['auto', 'always', 'never'],
'always'),
OptionKey('b_ndebug'): coredata.UserComboOption('Disable asserts', ['true', 'false', 'if-release'], 'false'),
OptionKey('b_staticpic'): coredata.UserBooleanOption('Build static libraries as position independent', True),
OptionKey('b_pie'): coredata.UserBooleanOption('Build executables as position independent', False),
OptionKey('b_bitcode'): coredata.UserBooleanOption('Generate and embed bitcode (only macOS/iOS/tvOS)', False),
OptionKey('b_vscrt'): coredata.UserComboOption('VS run-time library type to use.',
['none', 'md', 'mdd', 'mt', 'mtd', 'from_buildtype', 'static_from_buildtype'],
'from_buildtype'),
}
def option_enabled(boptions: T.Set[OptionKey], options: 'KeyedOptionDictType',
option: OptionKey) -> bool:
try:
if option not in boptions:
return False
@ -304,23 +300,23 @@ def option_enabled(boptions: T.List[str], options: 'OptionDictType',
except KeyError:
return False
def get_base_compile_args(options: 'OptionDictType', compiler: 'Compiler') -> T.List[str]:
def get_base_compile_args(options: 'KeyedOptionDictType', compiler: 'Compiler') -> T.List[str]:
args = [] # type T.List[str]
try:
if options['b_lto'].value:
if options[OptionKey('b_lto')].value:
args.extend(compiler.get_lto_compile_args())
except KeyError:
pass
try:
args += compiler.get_colorout_args(options['b_colorout'].value)
args += compiler.get_colorout_args(options[OptionKey('b_colorout')].value)
except KeyError:
pass
try:
args += compiler.sanitizer_compile_args(options['b_sanitize'].value)
args += compiler.sanitizer_compile_args(options[OptionKey('b_sanitize')].value)
except KeyError:
pass
try:
pgo_val = options['b_pgo'].value
pgo_val = options[OptionKey('b_pgo')].value
if pgo_val == 'generate':
args.extend(compiler.get_profile_generate_args())
elif pgo_val == 'use':
@ -328,23 +324,23 @@ def get_base_compile_args(options: 'OptionDictType', compiler: 'Compiler') -> T.
except KeyError:
pass
try:
if options['b_coverage'].value:
if options[OptionKey('b_coverage')].value:
args += compiler.get_coverage_args()
except KeyError:
pass
try:
if (options['b_ndebug'].value == 'true' or
(options['b_ndebug'].value == 'if-release' and
options['buildtype'].value in {'release', 'plain'})):
if (options[OptionKey('b_ndebug')].value == 'true' or
(options[OptionKey('b_ndebug')].value == 'if-release' and
options[OptionKey('buildtype')].value in {'release', 'plain'})):
args += compiler.get_disable_assert_args()
except KeyError:
pass
# This does not need a try...except
if option_enabled(compiler.base_options, options, 'b_bitcode'):
if option_enabled(compiler.base_options, options, OptionKey('b_bitcode')):
args.append('-fembed-bitcode')
try:
crt_val = options['b_vscrt'].value
buildtype = options['buildtype'].value
crt_val = options[OptionKey('b_vscrt')].value
buildtype = options[OptionKey('buildtype')].value
try:
args += compiler.get_crt_compile_args(crt_val, buildtype)
except AttributeError:
@ -353,20 +349,20 @@ def get_base_compile_args(options: 'OptionDictType', compiler: 'Compiler') -> T.
pass
return args
def get_base_link_args(options: 'OptionDictType', linker: 'Compiler',
def get_base_link_args(options: 'KeyedOptionDictType', linker: 'Compiler',
is_shared_module: bool) -> T.List[str]:
args = [] # type: T.List[str]
try:
if options['b_lto'].value:
if options[OptionKey('b_lto')].value:
args.extend(linker.get_lto_link_args())
except KeyError:
pass
try:
args += linker.sanitizer_link_args(options['b_sanitize'].value)
args += linker.sanitizer_link_args(options[OptionKey('b_sanitize')].value)
except KeyError:
pass
try:
pgo_val = options['b_pgo'].value
pgo_val = options[OptionKey('b_pgo')].value
if pgo_val == 'generate':
args.extend(linker.get_profile_generate_args())
elif pgo_val == 'use':
@ -374,13 +370,13 @@ def get_base_link_args(options: 'OptionDictType', linker: 'Compiler',
except KeyError:
pass
try:
if options['b_coverage'].value:
if options[OptionKey('b_coverage')].value:
args += linker.get_coverage_link_args()
except KeyError:
pass
as_needed = option_enabled(linker.base_options, options, 'b_asneeded')
bitcode = option_enabled(linker.base_options, options, 'b_bitcode')
as_needed = option_enabled(linker.base_options, options, OptionKey('b_asneeded'))
bitcode = option_enabled(linker.base_options, options, OptionKey('b_bitcode'))
# Shared modules cannot be built with bitcode_bundle because
# -bitcode_bundle is incompatible with -undefined and -bundle
if bitcode and not is_shared_module:
@ -394,14 +390,14 @@ def get_base_link_args(options: 'OptionDictType', linker: 'Compiler',
if not bitcode:
args.extend(linker.headerpad_args())
if (not is_shared_module and
option_enabled(linker.base_options, options, 'b_lundef')):
option_enabled(linker.base_options, options, OptionKey('b_lundef'))):
args.extend(linker.no_undefined_link_args())
else:
args.extend(linker.get_allow_undefined_link_args())
try:
crt_val = options['b_vscrt'].value
buildtype = options['buildtype'].value
crt_val = options[OptionKey('b_vscrt')].value
buildtype = options[OptionKey('buildtype')].value
try:
args += linker.get_crt_link_args(crt_val, buildtype)
except AttributeError:
@ -477,7 +473,7 @@ class Compiler(metaclass=abc.ABCMeta):
self.version = version
self.full_version = full_version
self.for_machine = for_machine
self.base_options = [] # type: T.List[str]
self.base_options: T.Set[OptionKey] = set()
self.linker = linker
self.info = info
self.is_cross = is_cross
@ -1248,14 +1244,14 @@ def get_global_options(lang: str,
description = 'Extra arguments passed to the {}'.format(lang)
argkey = OptionKey('args', lang=lang, machine=for_machine)
largkey = argkey.evolve('link_args')
opts = {
opts: 'KeyedOptionDictType' = {
argkey: coredata.UserArrayOption(
description + ' compiler',
[], split_args=True, user_input=True, allow_dups=True),
largkey: coredata.UserArrayOption(
description + ' linker',
[], split_args=True, user_input=True, allow_dups=True),
} # type: OptionDictType
}
# Get from env vars.
compile_args, link_args = get_args_from_envvars(

@ -664,7 +664,7 @@ class VisualStudioCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixi
CPPCompiler.__init__(self, exelist, version, for_machine, is_cross,
info, exe_wrapper, linker=linker, full_version=full_version)
MSVCCompiler.__init__(self, target)
self.base_options = ['b_pch', 'b_vscrt', 'b_ndebug'] # FIXME add lto, pgo and the like
self.base_options = {OptionKey(o) for o in ['b_pch', 'b_vscrt', 'b_ndebug']} # FIXME add lto, pgo and the like
self.id = 'msvc'
def get_options(self) -> 'KeyedOptionDictType':

@ -18,7 +18,7 @@ import subprocess
import typing as T
from ..mesonlib import (
EnvironmentException, MachineChoice, version_compare,
EnvironmentException, MachineChoice, version_compare, OptionKey,
)
from ..arglist import CompilerArgs
@ -653,8 +653,10 @@ class GnuDCompiler(GnuCompiler, DCompiler):
'1': default_warn_args,
'2': default_warn_args + ['-Wextra'],
'3': default_warn_args + ['-Wextra', '-Wpedantic']}
self.base_options = ['b_colorout', 'b_sanitize', 'b_staticpic',
'b_vscrt', 'b_coverage', 'b_pgo', 'b_ndebug']
self.base_options = {
OptionKey(o) for o in [
'b_colorout', 'b_sanitize', 'b_staticpic', 'b_vscrt',
'b_coverage', 'b_pgo', 'b_ndebug']}
self._has_color_support = version_compare(self.version, '>=4.9')
# dependencies were implemented before, but broken - support was fixed in GCC 7.1+
@ -724,7 +726,7 @@ class LLVMDCompiler(DmdLikeCompilerMixin, DCompiler):
full_version=full_version, is_cross=is_cross)
DmdLikeCompilerMixin.__init__(self, dmd_frontend_version=find_ldc_dmd_frontend_version(version_output))
self.id = 'llvm'
self.base_options = ['b_coverage', 'b_colorout', 'b_vscrt', 'b_ndebug']
self.base_options = {OptionKey(o) for o in ['b_coverage', 'b_colorout', 'b_vscrt', 'b_ndebug']}
def get_colorout_args(self, colortype: str) -> T.List[str]:
if colortype == 'always':
@ -782,7 +784,7 @@ class DmdDCompiler(DmdLikeCompilerMixin, DCompiler):
full_version=full_version, is_cross=is_cross)
DmdLikeCompilerMixin.__init__(self, version)
self.id = 'dmd'
self.base_options = ['b_coverage', 'b_colorout', 'b_vscrt', 'b_ndebug']
self.base_options = {OptionKey(o) for o in ['b_coverage', 'b_colorout', 'b_vscrt', 'b_ndebug']}
def get_colorout_args(self, colortype: str) -> T.List[str]:
if colortype == 'always':

@ -19,6 +19,7 @@ import typing as T
from ... import mesonlib
from ...linkers import ArmClangDynamicLinker
from ...mesonlib import OptionKey
from ..compilers import clike_debug_args
from .clang import clang_color_args
@ -145,8 +146,10 @@ class ArmclangCompiler(Compiler):
if not mesonlib.version_compare(self.version, '==' + self.linker.version):
raise mesonlib.EnvironmentException('armlink version does not match with compiler version')
self.id = 'armclang'
self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage',
'b_ndebug', 'b_staticpic', 'b_colorout']
self.base_options = {
OptionKey(o) for o in
['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage',
'b_ndebug', 'b_staticpic', 'b_colorout']}
# Assembly
self.can_compile_suffixes.add('s')

@ -20,6 +20,7 @@ import typing as T
from ... import mesonlib
from ...linkers import AppleDynamicLinker
from ...mesonlib import OptionKey
from ..compilers import CompileCheckMode
from .gnu import GnuLikeCompiler
@ -48,11 +49,11 @@ class ClangCompiler(GnuLikeCompiler):
super().__init__()
self.id = 'clang'
self.defines = defines or {}
self.base_options.append('b_colorout')
self.base_options.add(OptionKey('b_colorout'))
# TODO: this really should be part of the linker base_options, but
# linkers don't have base_options.
if isinstance(self.linker, AppleDynamicLinker):
self.base_options.append('b_bitcode')
self.base_options.add(OptionKey('b_bitcode'))
# All Clang backends can also do LLVM IR
self.can_compile_suffixes.add('ll')
@ -108,7 +109,7 @@ class ClangCompiler(GnuLikeCompiler):
else:
# Shouldn't work, but it'll be checked explicitly in the OpenMP dependency.
return []
@classmethod
def use_linker_args(cls, linker: str) -> T.List[str]:
# Clang additionally can use a linker specified as a path, which GCC

@ -35,6 +35,7 @@ from ... import mesonlib
from ... import mlog
from ...linkers import GnuLikeDynamicLinkerMixin, SolarisDynamicLinker, CompCertDynamicLinker
from ...mesonlib import LibType
from ...coredata import OptionKey
from .. import compilers
from ..compilers import CompileCheckMode
from .visualstudio import VisualStudioLikeCompiler
@ -393,14 +394,16 @@ class CLikeCompiler(Compiler):
# linking with static libraries since MSVC won't select a CRT for
# us in that case and will error out asking us to pick one.
try:
crt_val = env.coredata.base_options['b_vscrt'].value
buildtype = env.coredata.builtins['buildtype'].value
crt_val = env.coredata.base_options[OptionKey('b_vscrt')].value
buildtype = env.coredata.builtins[OptionKey('buildtype')].value
cargs += self.get_crt_compile_args(crt_val, buildtype)
except (KeyError, AttributeError):
pass
# Add CFLAGS/CXXFLAGS/OBJCFLAGS/OBJCXXFLAGS and CPPFLAGS from the env
sys_args = env.coredata.get_external_args(self.for_machine, self.language)
if isinstance(sys_args, str):
sys_args = [sys_args]
# Apparently it is a thing to inject linker flags both
# via CFLAGS _and_ LDFLAGS, even though the former are
# also used during linking. These flags can break

@ -21,7 +21,7 @@ import re
from .gnu import GnuLikeCompiler
from .gnu import gnu_optimization_args
from ...mesonlib import Popen_safe
from ...mesonlib import Popen_safe, OptionKey
if T.TYPE_CHECKING:
from ...environment import Environment
@ -34,9 +34,7 @@ class ElbrusCompiler(GnuLikeCompiler):
def __init__(self) -> None:
super().__init__()
self.id = 'lcc'
self.base_options = ['b_pgo', 'b_coverage',
'b_ndebug', 'b_staticpic',
'b_lundef', 'b_asneeded']
self.base_options = {OptionKey(o) for o in ['b_pgo', 'b_coverage', 'b_ndebug', 'b_staticpic', 'b_lundef', 'b_asneeded']}
# FIXME: use _build_wrapper to call this so that linker flags from the env
# get applied

@ -51,7 +51,7 @@ class EmscriptenMixin(Compiler):
def thread_link_flags(self, env: 'Environment') -> T.List[str]:
args = ['-s', 'USE_PTHREADS=1']
count: int = env.coredata.compiler_options[OptionKey('thread_count', lang=self.language, machine=self.for_machine)].value # type: ignore
count: int = env.coredata.compiler_options[OptionKey('thread_count', lang=self.language, machine=self.for_machine)].value
if count:
args.extend(['-s', 'PTHREAD_POOL_SIZE={}'.format(count)])
return args

@ -24,6 +24,7 @@ import typing as T
from ... import mesonlib
from ... import mlog
from ...mesonlib import OptionKey
if T.TYPE_CHECKING:
from ...environment import Environment
@ -146,14 +147,15 @@ class GnuLikeCompiler(Compiler, metaclass=abc.ABCMeta):
LINKER_PREFIX = '-Wl,'
def __init__(self) -> None:
self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_coverage',
'b_ndebug', 'b_staticpic', 'b_pie']
self.base_options = {
OptionKey(o) for o in ['b_pch', 'b_lto', 'b_pgo', 'b_coverage',
'b_ndebug', 'b_staticpic', 'b_pie']}
if not (self.info.is_windows() or self.info.is_cygwin() or self.info.is_openbsd()):
self.base_options.append('b_lundef')
self.base_options.add(OptionKey('b_lundef'))
if not self.info.is_windows() or self.info.is_cygwin():
self.base_options.append('b_asneeded')
self.base_options.add(OptionKey('b_asneeded'))
if not self.info.is_hurd():
self.base_options.append('b_sanitize')
self.base_options.add(OptionKey('b_sanitize'))
# All GCC-like backends can do assembly
self.can_compile_suffixes.add('s')
@ -328,7 +330,7 @@ class GnuCompiler(GnuLikeCompiler):
super().__init__()
self.id = 'gcc'
self.defines = defines or {}
self.base_options.append('b_colorout')
self.base_options.add(OptionKey('b_colorout'))
def get_colorout_args(self, colortype: str) -> T.List[str]:
if mesonlib.version_compare(self.version, '>=4.9.0'):

@ -79,8 +79,9 @@ class IntelGnuLikeCompiler(GnuLikeCompiler):
# It does have IPO, which serves much the same purpose as LOT, but
# there is an unfortunate rule for using IPO (you can't control the
# name of the output file) which break assumptions meson makes
self.base_options = ['b_pch', 'b_lundef', 'b_asneeded', 'b_pgo',
'b_coverage', 'b_ndebug', 'b_staticpic', 'b_pie']
self.base_options = {mesonlib.OptionKey(o) for o in [
'b_pch', 'b_lundef', 'b_asneeded', 'b_pgo', 'b_coverage',
'b_ndebug', 'b_staticpic', 'b_pie']}
self.id = 'intel'
self.lang_header = 'none'

@ -19,6 +19,7 @@ import os
from pathlib import Path
from ..compilers import clike_debug_args, clike_optimization_args
from ...mesonlib import OptionKey
if T.TYPE_CHECKING:
from ...environment import Environment
@ -43,7 +44,7 @@ pgi_buildtype_args = {
class PGICompiler(Compiler):
def __init__(self) -> None:
self.base_options = ['b_pch']
self.base_options = {OptionKey('b_pch')}
self.id = 'pgi'
default_warn_args = ['-Minform=inform']

@ -129,7 +129,7 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta):
INVOKES_LINKER = False
def __init__(self, target: str):
self.base_options = ['b_pch', 'b_ndebug', 'b_vscrt'] # FIXME add lto, pgo and the like
self.base_options = {mesonlib.OptionKey(o) for o in ['b_pch', 'b_ndebug', 'b_vscrt']} # FIXME add lto, pgo and the like
self.target = target
self.is_64 = ('x64' in target) or ('x86_64' in target)
# do some canonicalization of target machine

@ -55,9 +55,9 @@ class RustCompiler(Compiler):
linker=linker)
self.exe_wrapper = exe_wrapper
self.id = 'rustc'
self.base_options.append('b_colorout')
self.base_options.add(OptionKey('b_colorout'))
if 'link' in self.linker.id:
self.base_options.append('b_vscrt')
self.base_options.add(OptionKey('b_vscrt'))
def needs_static_linker(self) -> bool:
return False

@ -16,7 +16,7 @@ import os.path
import typing as T
from .. import mlog
from ..mesonlib import EnvironmentException, MachineChoice, version_compare
from ..mesonlib import EnvironmentException, MachineChoice, version_compare, OptionKey
from .compilers import Compiler, LibType
@ -33,7 +33,7 @@ class ValaCompiler(Compiler):
super().__init__(exelist, version, for_machine, info, is_cross=is_cross)
self.version = version
self.id = 'valac'
self.base_options = ['b_colorout']
self.base_options = {OptionKey('b_colorout')}
def needs_static_linker(self) -> bool:
return False # Because compiles into C.

@ -21,7 +21,7 @@ from collections import OrderedDict, defaultdict
from .mesonlib import (
MesonException, EnvironmentException, MachineChoice, PerMachine,
default_libdir, default_libexecdir, default_prefix, split_args,
OptionKey,
OptionKey, OptionType,
)
from .wrap import WrapMode
import ast
@ -301,16 +301,17 @@ class DependencyCache:
successfully lookup by providing a simple get/put interface.
"""
def __init__(self, builtins_per_machine: PerMachine[T.Dict[str, UserOption[T.Any]]], for_machine: MachineChoice):
def __init__(self, builtins: 'KeyedOptionDictType', for_machine: MachineChoice):
self.__cache = OrderedDict() # type: T.MutableMapping[CacheKeyType, DependencySubCache]
self.__builtins_per_machine = builtins_per_machine
self.__for_machine = for_machine
self.__builtins = builtins
self.__pkg_conf_key = OptionKey('pkg_config_path', machine=for_machine)
self.__cmake_key = OptionKey('cmake_prefix_path', machine=for_machine)
def __calculate_subkey(self, type_: DependencyCacheType) -> T.Tuple[T.Any, ...]:
if type_ is DependencyCacheType.PKG_CONFIG:
return tuple(self.__builtins_per_machine[self.__for_machine]['pkg_config_path'].value)
return tuple(self.__builtins[self.__pkg_conf_key].value)
elif type_ is DependencyCacheType.CMAKE:
return tuple(self.__builtins_per_machine[self.__for_machine]['cmake_prefix_path'].value)
return tuple(self.__builtins[self.__cmake_key].value)
assert type_ is DependencyCacheType.OTHER, 'Someone forgot to update subkey calculations for a new type'
return tuple()
@ -384,17 +385,16 @@ class CoreData:
self.meson_command = meson_command
self.target_guids = {}
self.version = version
self.builtins = {} # type: OptionDictType
self.builtins_per_machine: PerMachine['OptionDictType'] = PerMachine({}, {})
self.builtins: 'KeyedOptionDictType' = {}
self.backend_options: 'KeyedOptionDictType' = {}
self.user_options: 'KeyedOptionDictType' = {}
self.compiler_options: 'KeyedOptionDictType' = {}
self.base_options = {} # type: OptionDictType
self.base_options: 'KeyedOptionDictType' = {}
self.cross_files = self.__load_config_files(options, scratch_dir, 'cross')
self.compilers = PerMachine(OrderedDict(), OrderedDict()) # type: PerMachine[T.Dict[str, Compiler]]
build_cache = DependencyCache(self.builtins_per_machine, MachineChoice.BUILD)
host_cache = DependencyCache(self.builtins_per_machine, MachineChoice.BUILD)
build_cache = DependencyCache(self.builtins, MachineChoice.BUILD)
host_cache = DependencyCache(self.builtins, MachineChoice.BUILD)
self.deps = PerMachine(build_cache, host_cache) # type: PerMachine[DependencyCache]
self.compiler_check_cache = OrderedDict() # type: T.Dict[CompilerCheckCacheKey, compiler.CompileResult]
@ -466,7 +466,7 @@ class CoreData:
# getting the "system default" is always wrong on multiarch
# platforms as it gets a value like lib/x86_64-linux-gnu.
if self.cross_files:
BUILTIN_OPTIONS['libdir'].default = 'lib'
BUILTIN_OPTIONS[OptionKey('libdir')].default = 'lib'
def sanitize_prefix(self, prefix):
prefix = os.path.expanduser(prefix)
@ -486,7 +486,7 @@ class CoreData:
prefix = prefix[:-1]
return prefix
def sanitize_dir_option_value(self, prefix: str, option: str, value: T.Any) -> T.Any:
def sanitize_dir_option_value(self, prefix: str, option: OptionKey, value: T.Any) -> T.Any:
'''
If the option is an installation directory option and the value is an
absolute path, check that it resides within prefix and return the value
@ -501,13 +501,13 @@ class CoreData:
value = PurePath(value)
except TypeError:
return value
if option.endswith('dir') and value.is_absolute() and \
option not in builtin_dir_noprefix_options:
if option.name.endswith('dir') and value.is_absolute() and \
option not in BULITIN_DIR_NOPREFIX_OPTIONS:
# Value must be a subdir of the prefix
# commonpath will always return a path in the native format, so we
# must use pathlib.PurePath to do the same conversion before
# comparing.
msg = ('The value of the {!r} option is \'{!s}\' which must be a '
msg = ('The value of the \'{!s}\' option is \'{!s}\' which must be a '
'subdir of the prefix {!r}.\nNote that if you pass a '
'relative path, it is assumed to be a subdir of prefix.')
# os.path.commonpath doesn't understand case-insensitive filesystems,
@ -520,25 +520,25 @@ class CoreData:
raise MesonException(msg.format(option, value, prefix))
return value.as_posix()
def init_builtins(self, subproject: str):
def init_builtins(self, subproject: str) -> None:
# Create builtin options with default values
for key, opt in BUILTIN_OPTIONS.items():
self.add_builtin_option(self.builtins, key, opt, subproject)
self.add_builtin_option(self.builtins, key.evolve(subproject=subproject), opt)
for for_machine in iter(MachineChoice):
for key, opt in BUILTIN_OPTIONS_PER_MACHINE.items():
self.add_builtin_option(self.builtins_per_machine[for_machine], key, opt, subproject)
self.add_builtin_option(self.builtins, key.evolve(subproject=subproject, machine=for_machine), opt)
def add_builtin_option(self, opts_map, key, opt, subproject):
if subproject:
@staticmethod
def add_builtin_option(opts_map: 'KeyedOptionDictType', key: OptionKey,
opt: 'BuiltinOption') -> None:
if key.subproject:
if opt.yielding:
# This option is global and not per-subproject
return
optname = subproject + ':' + key
value = opts_map[key].value
value = opts_map[key.as_root()].value
else:
optname = key
value = None
opts_map[optname] = opt.init_option(key, value, default_prefix())
opts_map[key] = opt.init_option(key, value, default_prefix())
def init_backend_options(self, backend_name: str) -> None:
if backend_name == 'ninja':
@ -552,45 +552,43 @@ class CoreData:
'')
def get_builtin_option(self, optname: str, subproject: str = '') -> T.Union[str, int, bool]:
raw_optname = optname
if subproject:
optname = subproject + ':' + optname
key = OptionKey.from_string(optname).evolve(subproject=subproject)
for opts in self._get_all_builtin_options():
v = opts.get(optname)
v = opts.get(str(key))
if v is None or v.yielding:
v = opts.get(raw_optname)
v = opts.get(str(key.as_root()))
if v is None:
continue
if raw_optname == 'wrap_mode':
if key.name == 'wrap_mode':
return WrapMode.from_string(v.value)
return v.value
raise RuntimeError('Tried to get unknown builtin option %s.' % raw_optname)
raise RuntimeError(f'Tried to get unknown builtin option {key.name}.')
def _try_set_builtin_option(self, optname, value):
def _try_set_builtin_option(self, key: OptionKey, value) -> bool:
for opts in self._get_all_builtin_options():
opt = opts.get(optname)
opt = opts.get(str(key))
if opt is None:
continue
if optname == 'prefix':
if key.name == 'prefix':
value = self.sanitize_prefix(value)
else:
prefix = self.builtins['prefix'].value
value = self.sanitize_dir_option_value(prefix, optname, value)
prefix = self.builtins[OptionKey('prefix')].value
value = self.sanitize_dir_option_value(prefix, key, value)
break
else:
return False
opt.set_value(value)
# Make sure that buildtype matches other settings.
if optname == 'buildtype':
if key.name == 'buildtype':
self.set_others_from_buildtype(value)
else:
self.set_buildtype_from_others()
return True
def set_builtin_option(self, optname, value):
def set_builtin_option(self, optname: OptionKey, value) -> None:
res = self._try_set_builtin_option(optname, value)
if not res:
raise RuntimeError('Tried to set unknown builtin option %s.' % optname)
raise RuntimeError(f'Tried to set unknown builtin option {str(optname)}')
def set_others_from_buildtype(self, value):
if value == 'plain':
@ -611,12 +609,12 @@ class CoreData:
else:
assert(value == 'custom')
return
self.builtins['optimization'].set_value(opt)
self.builtins['debug'].set_value(debug)
self.builtins[OptionKey('optimization')].set_value(opt)
self.builtins[OptionKey('debug')].set_value(debug)
def set_buildtype_from_others(self):
opt = self.builtins['optimization'].value
debug = self.builtins['debug'].value
opt = self.builtins[OptionKey('optimization')].value
debug = self.builtins[OptionKey('debug')].value
if opt == '0' and not debug:
mode = 'plain'
elif opt == '0' and debug:
@ -629,7 +627,7 @@ class CoreData:
mode = 'minsize'
else:
mode = 'custom'
self.builtins['buildtype'].set_value(mode)
self.builtins[OptionKey('buildtype')].set_value(mode)
@classmethod
def get_prefixed_options_per_machine(
@ -666,19 +664,18 @@ class CoreData:
yield {str(k): v for k, v in self.backend_options.items()}
yield {str(k): v for k, v in self.user_options.items()}
yield {str(k): v for k, v in self.compiler_options.items()}
yield self.base_options
yield {str(k): v for k, v in self.base_options.items()}
def _get_all_builtin_options(self) -> T.Iterable[T.Dict[str, UserOption]]:
yield dict(self.get_prefixed_options_per_machine(self.builtins_per_machine))
yield self.builtins
yield {str(k): v for k, v in self.builtins.items()}
def get_all_options(self) -> T.Iterable[T.Dict[str, UserOption]]:
yield from self._get_all_nonbuiltin_options()
yield from self._get_all_builtin_options()
def validate_option_value(self, option_name, override_value):
def validate_option_value(self, option_name: OptionKey, override_value):
for opts in self.get_all_options():
opt = opts.get(option_name)
opt = opts.get(str(option_name))
if opt is not None:
try:
return opt.validate_value(override_value)
@ -718,10 +715,11 @@ class CoreData:
return False
return len(self.cross_files) > 0
def copy_build_options_from_regular_ones(self):
def copy_build_options_from_regular_ones(self) -> None:
assert not self.is_cross_build()
for k, o in self.builtins_per_machine.host.items():
self.builtins_per_machine.build[k].set_value(o.value)
for k in BUILTIN_OPTIONS_PER_MACHINE:
o = self.builtins[k]
self.builtins[k.as_build()].set_value(o.value)
for bk, bv in self.compiler_options.items():
if bk.machine is MachineChoice.BUILD:
hk = bk.as_host()
@ -738,8 +736,8 @@ class CoreData:
pfk = OptionKey('prefix')
if pfk in options:
prefix = self.sanitize_prefix(options[pfk])
self.builtins['prefix'].set_value(prefix)
for key in builtin_dir_noprefix_options:
self.builtins[OptionKey('prefix')].set_value(prefix)
for key in BULITIN_DIR_NOPREFIX_OPTIONS:
if key not in options:
self.builtins[key].set_value(BUILTIN_OPTIONS[key].prefixed_default(key, prefix))
@ -747,7 +745,7 @@ class CoreData:
for k, v in options.items():
if k == pfk:
continue
if self._try_set_builtin_option(str(k), v):
if self._try_set_builtin_option(k, v):
continue
for opts in self._get_all_nonbuiltin_options():
tgt = opts.get(str(k))
@ -783,15 +781,13 @@ class CoreData:
# to know which backend we'll use).
options: T.MutableMapping[OptionKey, T.Any] = OrderedDict()
from . import optinterpreter
for k, v in chain(default_options.items(), env.options.items()):
# Subproject: skip options for other subprojects
if k.subproject and k.subproject != subproject:
continue
# Skip base, compiler, and backend options, they are handled when
# adding languages and setting backend.
if (k.name not in self.builtins and k.name not in self.builtins_per_machine[k.machine] and
optinterpreter.is_invalid_name(str(k), log=False)):
if k.type in {OptionType.COMPILER, OptionType.BACKEND, OptionType.BASE}:
continue
options[k] = v
@ -818,20 +814,19 @@ class CoreData:
self.compilers[comp.for_machine][lang] = comp
self.add_compiler_options(comp.get_options(), lang, comp.for_machine, env)
enabled_opts = []
for optname in comp.base_options:
if optname in self.base_options:
enabled_opts: T.List[OptionKey] = []
for key in comp.base_options:
if key in self.base_options:
continue
oobj = compilers.base_options[optname]
key = OptionKey(optname, machine=comp.for_machine)
oobj = compilers.base_options[key]
if key in env.options:
oobj.set_value(env.options[key])
enabled_opts.append(optname)
self.base_options[optname] = oobj
enabled_opts.append(key)
self.base_options[key] = oobj
self.emit_base_options_warnings(enabled_opts)
def emit_base_options_warnings(self, enabled_opts: list):
if 'b_bitcode' in enabled_opts:
def emit_base_options_warnings(self, enabled_opts: T.List[OptionKey]) -> None:
if OptionKey('b_bitcode') in enabled_opts:
mlog.warning('Base option \'b_bitcode\' is enabled, which is incompatible with many linker options. Incompatible options such as \'b_asneeded\' have been disabled.', fatal=False)
mlog.warning('Please see https://mesonbuild.com/Builtin-options.html#Notes_about_Apple_Bitcode_support for more details.', fatal=False)
@ -1007,10 +1002,10 @@ def save(obj: CoreData, build_dir: str) -> str:
def register_builtin_arguments(parser: argparse.ArgumentParser) -> None:
for n, b in BUILTIN_OPTIONS.items():
b.add_to_argparse(n, parser, '', '')
b.add_to_argparse(str(n), parser, '')
for n, b in BUILTIN_OPTIONS_PER_MACHINE.items():
b.add_to_argparse(n, parser, '', ' (just for host machine)')
b.add_to_argparse(n, parser, 'build.', ' (just for build machine)')
b.add_to_argparse(str(n), parser, ' (just for host machine)')
b.add_to_argparse(str(n.as_build()), parser, ' (just for build machine)')
parser.add_argument('-D', action='append', dest='projectoptions', default=[], metavar="option",
help='Set the value of an option, can be used several times to set multiple options.')
@ -1031,14 +1026,14 @@ def parse_cmd_line_options(args: argparse.Namespace) -> None:
args.cmd_line_options = create_options_dict(args.projectoptions)
# Merge builtin options set with --option into the dict.
for name in chain(
for key in chain(
BUILTIN_OPTIONS.keys(),
('build.' + k for k in BUILTIN_OPTIONS_PER_MACHINE.keys()),
(k.as_build() for k in BUILTIN_OPTIONS_PER_MACHINE.keys()),
BUILTIN_OPTIONS_PER_MACHINE.keys(),
):
name = str(key)
value = getattr(args, name, None)
if value is not None:
key = OptionKey.from_string(name)
if key in args.cmd_line_options:
cmdline_name = BuiltinOption.argparse_name_to_arg(name)
raise MesonException(
@ -1064,7 +1059,7 @@ class BuiltinOption(T.Generic[_T, _U]):
self.choices = choices
self.yielding = yielding
def init_option(self, name: str, value: T.Optional[T.Any], prefix: str) -> _U:
def init_option(self, name: 'OptionKey', value: T.Optional[T.Any], prefix: str) -> _U:
"""Create an instance of opt_type and return it."""
if value is None:
value = self.prefixed_default(name, prefix)
@ -1095,16 +1090,16 @@ class BuiltinOption(T.Generic[_T, _U]):
else:
return '--' + name.replace('_', '-')
def prefixed_default(self, name: str, prefix: str = '') -> T.Any:
def prefixed_default(self, name: 'OptionKey', prefix: str = '') -> T.Any:
if self.opt_type in [UserComboOption, UserIntegerOption]:
return self.default
try:
return builtin_dir_noprefix_options[name][prefix]
return BULITIN_DIR_NOPREFIX_OPTIONS[name][prefix]
except KeyError:
pass
return self.default
def add_to_argparse(self, name: str, parser: argparse.ArgumentParser, prefix: str, help_suffix: str) -> None:
def add_to_argparse(self, name: str, parser: argparse.ArgumentParser, help_suffix: str) -> None:
kwargs = OrderedDict()
c = self._argparse_choices()
@ -1117,64 +1112,65 @@ class BuiltinOption(T.Generic[_T, _U]):
if c and not b:
kwargs['choices'] = c
kwargs['default'] = argparse.SUPPRESS
kwargs['dest'] = prefix + name
kwargs['dest'] = name
cmdline_name = self.argparse_name_to_arg(prefix + name)
cmdline_name = self.argparse_name_to_arg(name)
parser.add_argument(cmdline_name, help=h + help_suffix, **kwargs)
# Update `docs/markdown/Builtin-options.md` after changing the options below
BUILTIN_DIR_OPTIONS = OrderedDict([
('prefix', BuiltinOption(UserStringOption, 'Installation prefix', default_prefix())),
('bindir', BuiltinOption(UserStringOption, 'Executable directory', 'bin')),
('datadir', BuiltinOption(UserStringOption, 'Data file directory', 'share')),
('includedir', BuiltinOption(UserStringOption, 'Header file directory', 'include')),
('infodir', BuiltinOption(UserStringOption, 'Info page directory', 'share/info')),
('libdir', BuiltinOption(UserStringOption, 'Library directory', default_libdir())),
('libexecdir', BuiltinOption(UserStringOption, 'Library executable directory', default_libexecdir())),
('localedir', BuiltinOption(UserStringOption, 'Locale data directory', 'share/locale')),
('localstatedir', BuiltinOption(UserStringOption, 'Localstate data directory', 'var')),
('mandir', BuiltinOption(UserStringOption, 'Manual page directory', 'share/man')),
('sbindir', BuiltinOption(UserStringOption, 'System executable directory', 'sbin')),
('sharedstatedir', BuiltinOption(UserStringOption, 'Architecture-independent data directory', 'com')),
('sysconfdir', BuiltinOption(UserStringOption, 'Sysconf data directory', 'etc')),
]) # type: OptionDictType
BUILTIN_CORE_OPTIONS = OrderedDict([
('auto_features', BuiltinOption(UserFeatureOption, "Override value of all 'auto' features", 'auto')),
('backend', BuiltinOption(UserComboOption, 'Backend to use', 'ninja', choices=backendlist)),
('buildtype', BuiltinOption(UserComboOption, 'Build type to use', 'debug',
choices=['plain', 'debug', 'debugoptimized', 'release', 'minsize', 'custom'])),
('debug', BuiltinOption(UserBooleanOption, 'Debug', True)),
('default_library', BuiltinOption(UserComboOption, 'Default library type', 'shared', choices=['shared', 'static', 'both'],
yielding=False)),
('errorlogs', BuiltinOption(UserBooleanOption, "Whether to print the logs from failing tests", True)),
('install_umask', BuiltinOption(UserUmaskOption, 'Default umask to apply on permissions of installed files', '022')),
('layout', BuiltinOption(UserComboOption, 'Build directory layout', 'mirror', choices=['mirror', 'flat'])),
('optimization', BuiltinOption(UserComboOption, 'Optimization level', '0', choices=['0', 'g', '1', '2', '3', 's'])),
('stdsplit', BuiltinOption(UserBooleanOption, 'Split stdout and stderr in test logs', True)),
('strip', BuiltinOption(UserBooleanOption, 'Strip targets on install', False)),
('unity', BuiltinOption(UserComboOption, 'Unity build', 'off', choices=['on', 'off', 'subprojects'])),
('unity_size', BuiltinOption(UserIntegerOption, 'Unity block size', (2, None, 4))),
('warning_level', BuiltinOption(UserComboOption, 'Compiler warning level to use', '1', choices=['0', '1', '2', '3'], yielding=False)),
('werror', BuiltinOption(UserBooleanOption, 'Treat warnings as errors', False, yielding=False)),
('wrap_mode', BuiltinOption(UserComboOption, 'Wrap mode', 'default', choices=['default', 'nofallback', 'nodownload', 'forcefallback'])),
('force_fallback_for', BuiltinOption(UserArrayOption, 'Force fallback for those subprojects', [])),
]) # type: OptionDictType
# Also update mesonlib._BUILTIN_NAMES. See the comment there for why this is required.
BUILTIN_DIR_OPTIONS: 'KeyedOptionDictType' = OrderedDict([
(OptionKey('prefix'), BuiltinOption(UserStringOption, 'Installation prefix', default_prefix())),
(OptionKey('bindir'), BuiltinOption(UserStringOption, 'Executable directory', 'bin')),
(OptionKey('datadir'), BuiltinOption(UserStringOption, 'Data file directory', 'share')),
(OptionKey('includedir'), BuiltinOption(UserStringOption, 'Header file directory', 'include')),
(OptionKey('infodir'), BuiltinOption(UserStringOption, 'Info page directory', 'share/info')),
(OptionKey('libdir'), BuiltinOption(UserStringOption, 'Library directory', default_libdir())),
(OptionKey('libexecdir'), BuiltinOption(UserStringOption, 'Library executable directory', default_libexecdir())),
(OptionKey('localedir'), BuiltinOption(UserStringOption, 'Locale data directory', 'share/locale')),
(OptionKey('localstatedir'), BuiltinOption(UserStringOption, 'Localstate data directory', 'var')),
(OptionKey('mandir'), BuiltinOption(UserStringOption, 'Manual page directory', 'share/man')),
(OptionKey('sbindir'), BuiltinOption(UserStringOption, 'System executable directory', 'sbin')),
(OptionKey('sharedstatedir'), BuiltinOption(UserStringOption, 'Architecture-independent data directory', 'com')),
(OptionKey('sysconfdir'), BuiltinOption(UserStringOption, 'Sysconf data directory', 'etc')),
])
BUILTIN_CORE_OPTIONS: 'KeyedOptionDictType' = OrderedDict([
(OptionKey('auto_features'), BuiltinOption(UserFeatureOption, "Override value of all 'auto' features", 'auto')),
(OptionKey('backend'), BuiltinOption(UserComboOption, 'Backend to use', 'ninja', choices=backendlist)),
(OptionKey('buildtype'), BuiltinOption(UserComboOption, 'Build type to use', 'debug',
choices=['plain', 'debug', 'debugoptimized', 'release', 'minsize', 'custom'])),
(OptionKey('debug'), BuiltinOption(UserBooleanOption, 'Debug', True)),
(OptionKey('default_library'), BuiltinOption(UserComboOption, 'Default library type', 'shared', choices=['shared', 'static', 'both'],
yielding=False)),
(OptionKey('errorlogs'), BuiltinOption(UserBooleanOption, "Whether to print the logs from failing tests", True)),
(OptionKey('install_umask'), BuiltinOption(UserUmaskOption, 'Default umask to apply on permissions of installed files', '022')),
(OptionKey('layout'), BuiltinOption(UserComboOption, 'Build directory layout', 'mirror', choices=['mirror', 'flat'])),
(OptionKey('optimization'), BuiltinOption(UserComboOption, 'Optimization level', '0', choices=['0', 'g', '1', '2', '3', 's'])),
(OptionKey('stdsplit'), BuiltinOption(UserBooleanOption, 'Split stdout and stderr in test logs', True)),
(OptionKey('strip'), BuiltinOption(UserBooleanOption, 'Strip targets on install', False)),
(OptionKey('unity'), BuiltinOption(UserComboOption, 'Unity build', 'off', choices=['on', 'off', 'subprojects'])),
(OptionKey('unity_size'), BuiltinOption(UserIntegerOption, 'Unity block size', (2, None, 4))),
(OptionKey('warning_level'), BuiltinOption(UserComboOption, 'Compiler warning level to use', '1', choices=['0', '1', '2', '3'], yielding=False)),
(OptionKey('werror'), BuiltinOption(UserBooleanOption, 'Treat warnings as errors', False, yielding=False)),
(OptionKey('wrap_mode'), BuiltinOption(UserComboOption, 'Wrap mode', 'default', choices=['default', 'nofallback', 'nodownload', 'forcefallback'])),
(OptionKey('force_fallback_for'), BuiltinOption(UserArrayOption, 'Force fallback for those subprojects', [])),
])
BUILTIN_OPTIONS = OrderedDict(chain(BUILTIN_DIR_OPTIONS.items(), BUILTIN_CORE_OPTIONS.items()))
BUILTIN_OPTIONS_PER_MACHINE = OrderedDict([
('pkg_config_path', BuiltinOption(UserArrayOption, 'List of additional paths for pkg-config to search', [])),
('cmake_prefix_path', BuiltinOption(UserArrayOption, 'List of additional prefixes for cmake to search', [])),
BUILTIN_OPTIONS_PER_MACHINE: 'KeyedOptionDictType' = OrderedDict([
(OptionKey('pkg_config_path'), BuiltinOption(UserArrayOption, 'List of additional paths for pkg-config to search', [])),
(OptionKey('cmake_prefix_path'), BuiltinOption(UserArrayOption, 'List of additional prefixes for cmake to search', [])),
])
# Special prefix-dependent defaults for installation directories that reside in
# a path outside of the prefix in FHS and common usage.
builtin_dir_noprefix_options = {
'sysconfdir': {'/usr': '/etc'},
'localstatedir': {'/usr': '/var', '/usr/local': '/var/local'},
'sharedstatedir': {'/usr': '/var/lib', '/usr/local': '/var/local/lib'},
BULITIN_DIR_NOPREFIX_OPTIONS: T.Dict[OptionKey, T.Dict[str, str]] = {
OptionKey('sysconfdir'): {'/usr': '/etc'},
OptionKey('localstatedir'): {'/usr': '/var', '/usr/local': '/var/local'},
OptionKey('sharedstatedir'): {'/usr': '/var/lib', '/usr/local': '/var/local/lib'},
}
FORBIDDEN_TARGET_NAMES = {'clean': None,

@ -37,7 +37,7 @@ from ..environment import Environment, MachineInfo
from ..cmake import CMakeExecutor, CMakeTraceParser, CMakeException, CMakeToolchain, CMakeExecScope, check_cmake_args
from ..mesonlib import MachineChoice, MesonException, OrderedSet, PerMachine
from ..mesonlib import Popen_safe, version_compare_many, version_compare, listify, stringlistify, extract_as_list, split_args
from ..mesonlib import Version, LibType
from ..mesonlib import Version, LibType, OptionKey
from ..mesondata import mesondata
if T.TYPE_CHECKING:
@ -656,8 +656,9 @@ class PkgConfigDependency(ExternalDependency):
return rc, out, err
@staticmethod
def setup_env(env, environment, for_machine, extra_path=None):
extra_paths = environment.coredata.builtins_per_machine[for_machine]['pkg_config_path'].value
def setup_env(env: T.MutableMapping[str, str], environment: 'Environment', for_machine: MachineChoice,
extra_path: T.Optional[str] = None) -> None:
extra_paths: T.List[str] = environment.coredata.builtins[OptionKey('pkg_config_path', machine=for_machine)].value
if extra_path:
extra_paths.append(extra_path)
sysroot = environment.properties[for_machine].get_sys_root()
@ -1484,9 +1485,9 @@ class CMakeDependency(ExternalDependency):
cfgs = [x for x in tgt.properties['IMPORTED_CONFIGURATIONS'] if x]
cfg = cfgs[0]
if 'b_vscrt' in self.env.coredata.base_options:
if OptionKey('b_vscrt') in self.env.coredata.base_options:
is_debug = self.env.coredata.get_builtin_option('buildtype') == 'debug'
if self.env.coredata.base_options['b_vscrt'].value in ('mdd', 'mtd'):
if self.env.coredata.base_options[OptionKey('b_vscrt')].value in {'mdd', 'mtd'}:
is_debug = True
else:
is_debug = self.env.coredata.get_builtin_option('debug')

@ -616,8 +616,8 @@ class BoostDependency(ExternalDependency):
# MSVC is very picky with the library tags
vscrt = ''
try:
crt_val = self.env.coredata.base_options['b_vscrt'].value
buildtype = self.env.coredata.builtins['buildtype'].value
crt_val = self.env.coredata.base_options[mesonlib.OptionKey('b_vscrt')].value
buildtype = self.env.coredata.builtins[mesonlib.OptionKey('buildtype')].value
vscrt = self.clib_compiler.get_crt_compile_args(crt_val, buildtype)[0]
except (KeyError, IndexError, AttributeError):
pass

@ -383,8 +383,8 @@ class QtBaseDependency(ExternalDependency):
# Use the buildtype by default, but look at the b_vscrt option if the
# compiler supports it.
is_debug = self.env.coredata.get_builtin_option('buildtype') == 'debug'
if 'b_vscrt' in self.env.coredata.base_options:
if self.env.coredata.base_options['b_vscrt'].value in ('mdd', 'mtd'):
if mesonlib.OptionKey('b_vscrt') in self.env.coredata.base_options:
if self.env.coredata.base_options[mesonlib.OptionKey('b_vscrt')].value in {'mdd', 'mtd'}:
is_debug = True
modules_lib_suffix = self._get_modules_lib_suffix(is_debug)

@ -11,7 +11,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import pdb
from . import mparser
from . import environment
from . import coredata
@ -22,7 +21,7 @@ from . import optinterpreter
from . import compilers
from .wrap import wrap, WrapMode
from . import mesonlib
from .mesonlib import FileMode, MachineChoice, Popen_safe, listify, extract_as_list, has_path_sep, unholder
from .mesonlib import FileMode, MachineChoice, OptionKey, Popen_safe, listify, extract_as_list, has_path_sep, unholder
from .dependencies import ExternalProgram
from .dependencies import InternalDependency, Dependency, NotFoundDependency, DependencyException
from .depfile import DepFile
@ -83,7 +82,7 @@ class FeatureOptionHolder(InterpreterObject, ObjectHolder):
InterpreterObject.__init__(self)
ObjectHolder.__init__(self, option)
if option.is_auto():
self.held_object = env.coredata.builtins['auto_features']
self.held_object = env.coredata.builtins[OptionKey('auto_features')]
self.name = name
self.methods.update({'enabled': self.enabled_method,
'disabled': self.disabled_method,
@ -3010,7 +3009,7 @@ external dependencies (including libraries) must go to "dependencies".''')
def _do_subproject_cmake(self, subp_name, subdir, subdir_abs, default_options, kwargs):
with mlog.nested():
new_build = self.build.copy()
prefix = self.coredata.builtins['prefix'].value
prefix = self.coredata.builtins[OptionKey('prefix')].value
from .modules.cmake import CMakeSubprojectOptions
options = kwargs.get('options', CMakeSubprojectOptions())
@ -3052,23 +3051,10 @@ external dependencies (including libraries) must go to "dependencies".''')
return result
def get_option_internal(self, optname: str):
raw_optname = optname
if self.is_subproject():
optname = self.subproject + ':' + optname
for opts in [
self.coredata.base_options, compilers.base_options, self.coredata.builtins,
dict(self.coredata.get_prefixed_options_per_machine(self.coredata.builtins_per_machine)),
]:
v = opts.get(optname)
if v is None or v.yielding:
v = opts.get(raw_optname)
if v is not None:
return v
# TODO: this optname may be a compiler option
key = OptionKey.from_string(optname).evolve(subproject=self.subproject)
key = mesonlib.OptionKey.from_string(optname)
for opts in [self.coredata.compiler_options]:
for opts in [self.coredata.builtins, self.coredata.base_options, compilers.base_options, self.coredata.compiler_options]:
v = opts.get(key)
if v is None or v.yielding:
v = opts.get(key.as_root())
@ -3090,7 +3076,7 @@ external dependencies (including libraries) must go to "dependencies".''')
mlog.warning('Option {0!r} of type {1!r} in subproject {2!r} cannot yield '
'to parent option of type {3!r}, ignoring parent value. '
'Use -D{2}:{0}=value to set the value for this option manually'
'.'.format(raw_optname, opt_type, self.subproject, popt_type),
'.'.format(optname, opt_type, self.subproject, popt_type),
location=self.current_node)
return opt
except KeyError:
@ -4786,15 +4772,15 @@ different subdirectory.
break
def check_clang_asan_lundef(self) -> None:
if 'b_lundef' not in self.coredata.base_options:
if OptionKey('b_lundef') not in self.coredata.base_options:
return
if 'b_sanitize' not in self.coredata.base_options:
if OptionKey('b_sanitize') not in self.coredata.base_options:
return
if (self.coredata.base_options['b_lundef'].value and
self.coredata.base_options['b_sanitize'].value != 'none'):
if (self.coredata.base_options[OptionKey('b_lundef')].value and
self.coredata.base_options[OptionKey('b_sanitize')].value != 'none'):
mlog.warning('''Trying to use {} sanitizer on Clang with b_lundef.
This will probably not work.
Try setting b_lundef to false instead.'''.format(self.coredata.base_options['b_sanitize'].value),
Try setting b_lundef to false instead.'''.format(self.coredata.base_options[OptionKey('b_sanitize')].value),
location=self.current_node)
def evaluate_subproject_info(self, path_from_source_root, subproject_dir):
@ -4889,10 +4875,11 @@ Try setting b_lundef to false instead.'''.format(self.coredata.base_options['b_s
# Check if user forces non-PIC static library.
pic = True
key = OptionKey('b_staticpic')
if 'pic' in kwargs:
pic = kwargs['pic']
elif 'b_staticpic' in self.environment.coredata.base_options:
pic = self.environment.coredata.base_options['b_staticpic'].value
elif key in self.environment.coredata.base_options:
pic = self.environment.coredata.base_options[key].value
if pic:
# Exclude sources from args and kwargs to avoid building them twice

@ -17,12 +17,11 @@ from . import coredata, environment, mesonlib, build, mintro, mlog
from .ast import AstIDGenerator
import typing as T
from .mesonlib import MachineChoice
from .mesonlib import MachineChoice, OptionKey
if T.TYPE_CHECKING:
import argparse
from .coredata import UserOption
from .mesonlib import OptionKey
def add_arguments(parser: 'argparse.ArgumentParser') -> None:
coredata.register_builtin_arguments(parser)
@ -30,7 +29,6 @@ def add_arguments(parser: 'argparse.ArgumentParser') -> None:
parser.add_argument('--clearcache', action='store_true', default=False,
help='Clear cached state (e.g. found dependencies)')
def make_lower_case(val: T.Any) -> T.Union[str, T.List[T.Any]]: # T.Any because of recursion...
if isinstance(val, bool):
return str(val).lower()
@ -39,12 +37,6 @@ def make_lower_case(val: T.Any) -> T.Union[str, T.List[T.Any]]: # T.Any because
else:
return str(val)
def insert_build_prefix(k: str) -> str:
idx = k.find(':')
if idx < 0:
return 'build.' + k
return k[:idx + 1] + 'build.' + k[idx + 1:]
class ConfException(mesonlib.MesonException):
pass
@ -62,8 +54,8 @@ class Conf:
self.choices_col = []
self.descr_col = []
self.has_choices = False
self.all_subprojects = set()
self.yielding_options = set()
self.all_subprojects: T.Set[str] = set()
self.yielding_options: T.Set[OptionKey] = set()
if os.path.isdir(os.path.join(self.build_dir, 'meson-private')):
self.build = build.load(self.build_dir)
@ -111,20 +103,8 @@ class Conf:
else:
print('{0:{width[0]}} {1:{width[1]}} {3}'.format(*line, width=col_widths))
def split_options_per_subproject(self, options: T.Dict[str, 'UserOption']) -> T.Dict[str, T.Dict[str, 'UserOption']]:
result = {}
for k, o in options.items():
subproject = ''
if ':' in k:
subproject, optname = k.split(':')
if o.yielding and optname in options:
self.yielding_options.add(k)
self.all_subprojects.add(subproject)
result.setdefault(subproject, {})[k] = o
return result
def split_options_per_subproject2(self, options: 'coredata.KeyedOptionDictType') -> T.Dict[str, T.Dict[str, 'UserOption']]:
result = {}
def split_options_per_subproject(self, options: 'coredata.KeyedOptionDictType') -> T.Dict[str, T.Dict[str, 'UserOption']]:
result: T.Dict[str, T.Dict[str, 'UserOption']] = {}
for k, o in options.items():
subproject = k.subproject
if k.subproject:
@ -135,8 +115,8 @@ class Conf:
result.setdefault(subproject, {})[str(k)] = o
return result
def _add_line(self, name, value, choices, descr):
self.name_col.append(' ' * self.print_margin + name)
def _add_line(self, name: OptionKey, value, choices, descr) -> None:
self.name_col.append(' ' * self.print_margin + str(name))
self.value_col.append(value)
self.choices_col.append(choices)
self.descr_col.append(descr)
@ -185,7 +165,7 @@ class Conf:
self._add_line(section + ':', '', '', '')
self.print_margin = 2
def print_options(self, title: str, options: 'coredata.OptionDictType') -> None:
def print_options(self, title: str, options: 'coredata.KeyedOptionDictType') -> None:
if not options:
return
if title:
@ -210,28 +190,28 @@ class Conf:
if not self.default_values_only:
print(' Build dir ', self.build_dir)
dir_option_names = list(coredata.BUILTIN_DIR_OPTIONS)
test_option_names = ['errorlogs',
'stdsplit']
core_option_names = [k for k in self.coredata.builtins if k not in dir_option_names + test_option_names]
dir_option_names = set(coredata.BUILTIN_DIR_OPTIONS)
test_option_names = {OptionKey('errorlogs'),
OptionKey('stdsplit')}
core_option_names = [k for k in self.coredata.builtins if k not in dir_option_names | test_option_names]
dir_options = {k: o for k, o in self.coredata.builtins.items() if k in dir_option_names}
test_options = {k: o for k, o in self.coredata.builtins.items() if k in test_option_names}
core_options = {k: o for k, o in self.coredata.builtins.items() if k in core_option_names}
core_options = self.split_options_per_subproject(core_options)
host_compiler_options = self.split_options_per_subproject2({k: v for k, v in self.coredata.compiler_options.items() if k.machine is MachineChoice.HOST})
build_compiler_options = self.split_options_per_subproject2({k: v for k, v in self.coredata.compiler_options.items() if k.machine is MachineChoice.BUILD})
project_options = self.split_options_per_subproject2(self.coredata.user_options)
host_core_options = self.split_options_per_subproject({k: v for k, v in self.coredata.builtins.items() if k.machine is MachineChoice.HOST})
build_core_options = self.split_options_per_subproject({k: v for k, v in self.coredata.builtins.items() if k.machine is MachineChoice.BUILD})
host_compiler_options = self.split_options_per_subproject({k: v for k, v in self.coredata.compiler_options.items() if k.machine is MachineChoice.HOST})
build_compiler_options = self.split_options_per_subproject({k: v for k, v in self.coredata.compiler_options.items() if k.machine is MachineChoice.BUILD})
project_options = self.split_options_per_subproject(self.coredata.user_options)
show_build_options = self.default_values_only or self.build.environment.is_cross_build()
self.add_section('Main project options')
self.print_options('Core options', core_options[''])
self.print_options('', self.coredata.builtins_per_machine.host)
self.print_options('Core options', host_core_options[''])
if show_build_options:
self.print_options('', {insert_build_prefix(k): o for k, o in self.coredata.builtins_per_machine.build.items()})
self.print_options('', build_core_options[''])
self.print_options('Backend options', {str(k): v for k, v in self.coredata.backend_options.items()})
self.print_options('Base options', self.coredata.base_options)
self.print_options('Base options', {str(k): v for k, v in self.coredata.base_options.items()})
self.print_options('Compiler options', host_compiler_options.get('', {}))
if show_build_options:
self.print_options('', build_compiler_options.get('', {}))

@ -32,7 +32,7 @@ from mesonbuild import mlog
if T.TYPE_CHECKING:
from .build import ConfigurationData
from .coredata import OptionDictType, UserOption
from .coredata import KeyedOptionDictType, UserOption
from .compilers.compilers import CompilerType
from .interpreterbase import ObjectHolder
@ -1743,6 +1743,10 @@ class OptionProxy(T.Generic[_T]):
self.value = value
self.choices = choices
def set_value(self, v: _T) -> None:
# XXX: should this be an error
self.value = v
class OptionOverrideProxy(collections.abc.MutableMapping):
@ -1753,13 +1757,13 @@ class OptionOverrideProxy(collections.abc.MutableMapping):
# TODO: the typing here could be made more explicit using a TypeDict from
# python 3.8 or typing_extensions
def __init__(self, overrides: T.Dict[str, T.Any], *options: 'OptionDictType'):
def __init__(self, overrides: T.Dict['OptionKey', T.Any], *options: 'KeyedOptionDictType'):
self.overrides = overrides.copy()
self.options = {} # type: T.Dict[str, UserOption]
self.options: T.Dict['OptionKey', UserOption] = {}
for o in options:
self.options.update(o)
def __getitem__(self, key: str) -> T.Union['UserOption', OptionProxy]:
def __getitem__(self, key: 'OptionKey') -> T.Union['UserOption', OptionProxy]:
if key in self.options:
opt = self.options[key]
if key in self.overrides:
@ -1767,13 +1771,13 @@ class OptionOverrideProxy(collections.abc.MutableMapping):
return opt
raise KeyError('Option not found', key)
def __setitem__(self, key: str, value: T.Union['UserOption', OptionProxy]) -> None:
def __setitem__(self, key: 'OptionKey', value: T.Union['UserOption', OptionProxy]) -> None:
self.overrides[key] = value.value
def __delitem__(self, key: str) -> None:
def __delitem__(self, key: 'OptionKey') -> None:
del self.overrides[key]
def __iter__(self) -> T.Iterator[str]:
def __iter__(self) -> T.Iterator['OptionKey']:
return iter(self.options)
def __len__(self) -> int:
@ -1793,20 +1797,54 @@ class OptionType(enum.Enum):
PROJECT = 3
BACKEND = 4
# This is copied from coredata. There is no way to share this, because this
# is used in the OptionKey constructor, and the coredata lists are
# OptionKeys...
_BUILTIN_NAMES = {
'prefix',
'bindir',
'datadir',
'includedir',
'infodir',
'libdir',
'libexecdir',
'localedir',
'localstatedir',
'mandir',
'sbindir',
'sharedstatedir',
'sysconfdir',
'auto_features',
'backend',
'buildtype',
'debug',
'default_library',
'errorlogs',
'install_umask',
'layout',
'optimization',
'stdsplit',
'strip',
'unity',
'unity_size',
'warning_level',
'werror',
'wrap_mode',
'force_fallback_for',
'pkg_config_path',
'cmake_prefix_path',
}
def _classify_argument(key: 'OptionKey') -> OptionType:
"""Classify arguments into groups so we know which dict to assign them to."""
from .compilers import base_options
from .coredata import BUILTIN_OPTIONS, BUILTIN_OPTIONS_PER_MACHINE, builtin_dir_noprefix_options
all_builtins = set(BUILTIN_OPTIONS) | set(BUILTIN_OPTIONS_PER_MACHINE) | set(builtin_dir_noprefix_options)
if key.name in base_options:
if key.name.startswith('b_'):
assert key.machine is MachineChoice.HOST, str(key)
return OptionType.BASE
elif key.lang is not None:
return OptionType.COMPILER
elif key.name in all_builtins:
elif key.name in _BUILTIN_NAMES:
return OptionType.BUILTIN
elif key.name.startswith('backend_'):
assert key.machine is MachineChoice.HOST, str(key)
@ -1868,9 +1906,10 @@ class OptionKey:
This is very clever. __init__ is not a constructor, it's an
initializer, therefore it's safe to call more than once. We create a
state in the custom __getstate__ method, which is valid to pass
unsplatted to the initializer.
splatted to the initializer.
"""
self.__init__(**state)
# Mypy doesn't like this, because it's so clever.
self.__init__(**state) # type: ignore
def __hash__(self) -> int:
return self._hash
@ -1884,6 +1923,15 @@ class OptionKey:
self.lang == other.lang)
return NotImplemented
def __lt__(self, other: object) -> bool:
if isinstance(other, OptionKey):
return (
self.name < other.name and
self.subproject < other.subproject and
self.machine < other.machine and
self.lang < other.lang)
return NotImplemented
def __str__(self) -> str:
out = self.name
if self.lang:

@ -33,7 +33,7 @@ import typing as T
import os
import argparse
from .mesonlib import MachineChoice
from .mesonlib import MachineChoice, OptionKey
def get_meson_info_file(info_dir: str) -> str:
return os.path.join(info_dir, 'meson-info.json')
@ -213,24 +213,16 @@ def list_buildoptions_from_source(intr: IntrospectionInterpreter) -> T.List[T.Di
def list_buildoptions(coredata: cdata.CoreData, subprojects: T.Optional[T.List[str]] = None) -> T.List[T.Dict[str, T.Union[str, bool, int, T.List[str]]]]:
optlist = [] # type: T.List[T.Dict[str, T.Union[str, bool, int, T.List[str]]]]
dir_option_names = list(cdata.BUILTIN_DIR_OPTIONS)
test_option_names = ['errorlogs',
'stdsplit']
core_option_names = [k for k in coredata.builtins if k not in dir_option_names + test_option_names]
dir_options = {k: o for k, o in coredata.builtins.items() if k in dir_option_names}
test_options = {k: o for k, o in coredata.builtins.items() if k in test_option_names}
core_options = {k: o for k, o in coredata.builtins.items() if k in core_option_names}
if subprojects:
# Add per subproject built-in options
sub_core_options = {}
for sub in subprojects:
for k, o in core_options.items():
if o.yielding:
continue
sub_core_options[sub + ':' + k] = o
core_options.update(sub_core_options)
dir_option_names = set(cdata.BUILTIN_DIR_OPTIONS)
test_option_names = {OptionKey('errorlogs'),
OptionKey('stdsplit')}
core_option_names = {k for k in coredata.builtins if k not in dir_option_names | test_option_names}
dir_options = {str(k): o for k, o in coredata.builtins.items() if k in dir_option_names}
test_options = {str(k): o for k, o in coredata.builtins.items() if k in test_option_names}
core_options = {str(k): o for k, o in coredata.builtins.items() if k in core_option_names}
for s in subprojects or []:
core_options.update({str(k.evolve(subproject=s)): v for k, v in coredata.builtins.items() if not v.yielding})
def add_keys(options: 'cdata.OptionDictType', section: str, machine: str = 'any') -> None:
for key, opt in sorted(options.items()):
@ -253,14 +245,8 @@ def list_buildoptions(coredata: cdata.CoreData, subprojects: T.Optional[T.List[s
optlist.append(optdict)
add_keys(core_options, 'core')
add_keys(coredata.builtins_per_machine.host, 'core', machine='host')
add_keys(
{'build.' + k: o for k, o in coredata.builtins_per_machine.build.items()},
'core',
machine='build',
)
add_keys({str(k): v for k, v in coredata.backend_options.items()}, 'backend')
add_keys(coredata.base_options, 'base')
add_keys({str(k): v for k, v in coredata.base_options.items()}, 'base')
add_keys(
{str(k): v for k, v in coredata.compiler_options.items() if k.machine is MachineChoice.HOST},
'compiler',

@ -19,6 +19,7 @@ import os
import copy
import subprocess
import functools
import typing as T
from .. import build
from .. import mlog
@ -35,6 +36,9 @@ from ..mesonlib import (
from ..dependencies import Dependency, PkgConfigDependency, InternalDependency, ExternalProgram
from ..interpreterbase import noKwargs, permittedKwargs, FeatureNew, FeatureNewKwargs, FeatureDeprecatedKwargs
if T.TYPE_CHECKING:
from ..compilers import Compiler
# gresource compilation is broken due to the way
# the resource compiler and Ninja clash about it
#
@ -574,8 +578,8 @@ class GnomeModule(ExtensionModule):
return ret
def _get_girtargets_langs_compilers(self, girtargets):
ret = []
def _get_girtargets_langs_compilers(self, girtargets: T.List[GirTarget]) -> T.List[T.Tuple[str, 'Compiler']]:
ret: T.List[T.Tuple[str, 'Compiler']] = []
for girtarget in girtargets:
for lang, compiler in girtarget.compilers.items():
# XXX: Can you use g-i with any other language?
@ -598,7 +602,7 @@ class GnomeModule(ExtensionModule):
ret += girtarget.get_include_dirs()
return ret
def _get_langs_compilers_flags(self, state, langs_compilers):
def _get_langs_compilers_flags(self, state, langs_compilers: T.List[T.Tuple[str, 'Compiler']]):
cflags = []
internal_ldflags = []
external_ldflags = []
@ -608,8 +612,8 @@ class GnomeModule(ExtensionModule):
cflags += state.global_args[lang]
if state.project_args.get(lang):
cflags += state.project_args[lang]
if 'b_sanitize' in compiler.base_options:
sanitize = state.environment.coredata.base_options['b_sanitize'].value
if mesonlib.OptionKey('b_sanitize') in compiler.base_options:
sanitize = state.environment.coredata.base_options[mesonlib.OptionKey('b_sanitize')].value
cflags += compiler.sanitizer_compile_args(sanitize)
sanitize = sanitize.split(',')
# These must be first in ldflags

@ -177,7 +177,7 @@ class MesonApp:
mlog.initialize(env.get_log_dir(), self.options.fatal_warnings)
if self.options.profile:
mlog.set_timestamp_start(time.monotonic())
if env.coredata.builtins['backend'].value == 'xcode':
if env.coredata.builtins[mesonlib.OptionKey('backend')].value == 'xcode':
mlog.warning('xcode backend is currently unmaintained, patches welcome')
with mesonlib.BuildDirLock(self.build_dir):
self._generate(env)

@ -464,11 +464,9 @@ class Rewriter:
cdata = self.interpreter.coredata
options = {
**cdata.builtins,
**cdata.builtins_per_machine.host,
**{'build.' + k: o for k, o in cdata.builtins_per_machine.build.items()},
**{str(k): v for k, v in cdata.builtins.items()},
**{str(k): v for k, v in cdata.backend_options.items()},
**cdata.base_options,
**{str(k): v for k, v in cdata.base_options.items()},
**{str(k): v for k, v in cdata.compiler_options.items()},
**{str(k): v for k, v in cdata.user_options.items()},
}

@ -263,7 +263,8 @@ def skip_if_not_base_option(feature):
def wrapped(*args, **kwargs):
env = get_fake_env()
cc = env.detect_c_compiler(MachineChoice.HOST)
if feature not in cc.base_options:
key = OptionKey(feature)
if key not in cc.base_options:
raise unittest.SkipTest(
'{} not available with {}'.format(feature, cc.id))
return f(*args, **kwargs)
@ -1390,8 +1391,8 @@ class DataTests(unittest.TestCase):
found_entries |= options
self.assertEqual(found_entries, set([
*mesonbuild.coredata.BUILTIN_OPTIONS.keys(),
*mesonbuild.coredata.BUILTIN_OPTIONS_PER_MACHINE.keys()
*[str(k) for k in mesonbuild.coredata.BUILTIN_OPTIONS],
*[str(k) for k in mesonbuild.coredata.BUILTIN_OPTIONS_PER_MACHINE],
]))
# Check that `buildtype` table inside `Core options` matches how
@ -1412,10 +1413,10 @@ class DataTests(unittest.TestCase):
debug = False
else:
raise RuntimeError('Invalid debug value {!r} in row:\n{}'.format(debug, m.group()))
env.coredata.set_builtin_option('buildtype', buildtype)
self.assertEqual(env.coredata.builtins['buildtype'].value, buildtype)
self.assertEqual(env.coredata.builtins['optimization'].value, opt)
self.assertEqual(env.coredata.builtins['debug'].value, debug)
env.coredata.set_builtin_option(OptionKey('buildtype'), buildtype)
self.assertEqual(env.coredata.builtins[OptionKey('buildtype')].value, buildtype)
self.assertEqual(env.coredata.builtins[OptionKey('optimization')].value, opt)
self.assertEqual(env.coredata.builtins[OptionKey('debug')].value, debug)
def test_cpu_families_documented(self):
with open("docs/markdown/Reference-tables.md", encoding='utf-8') as f:
@ -1903,11 +1904,14 @@ class AllPlatformTests(BasePlatformTests):
https://github.com/mesonbuild/meson/issues/1349
'''
testdir = os.path.join(self.common_test_dir, '88 default options')
self.init(testdir, default_args=False)
self.init(testdir, default_args=False, inprocess=True)
opts = self.introspect('--buildoptions')
for opt in opts:
if opt['name'] == 'prefix':
prefix = opt['value']
break
else:
raise self.fail('Did not find option "prefix"')
self.assertEqual(prefix, '/absoluteprefix')
def test_do_conf_file_preserve_newlines(self):
@ -3679,35 +3683,34 @@ class AllPlatformTests(BasePlatformTests):
def test_command_line(self):
testdir = os.path.join(self.unit_test_dir, '34 command line')
K = OptionKey
# Verify default values when passing no args that affect the
# configuration, and as a bonus, test that --profile-self works.
self.init(testdir, extra_args=['--profile-self', '--fatal-meson-warnings'])
obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins['default_library'].value, 'static')
self.assertEqual(obj.builtins['warning_level'].value, '1')
self.assertEqual(obj.user_options[K('set_sub_opt')].value, True)
self.assertEqual(obj.user_options[K('subp_opt', 'subp')].value, 'default3')
self.assertEqual(obj.builtins[OptionKey('default_library')].value, 'static')
self.assertEqual(obj.builtins[OptionKey('warning_level')].value, '1')
self.assertEqual(obj.user_options[OptionKey('set_sub_opt')].value, True)
self.assertEqual(obj.user_options[OptionKey('subp_opt', 'subp')].value, 'default3')
self.wipe()
# warning_level is special, it's --warnlevel instead of --warning-level
# for historical reasons
self.init(testdir, extra_args=['--warnlevel=2', '--fatal-meson-warnings'])
obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins['warning_level'].value, '2')
self.assertEqual(obj.builtins[OptionKey('warning_level')].value, '2')
self.setconf('--warnlevel=3')
obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins['warning_level'].value, '3')
self.assertEqual(obj.builtins[OptionKey('warning_level')].value, '3')
self.wipe()
# But when using -D syntax, it should be 'warning_level'
self.init(testdir, extra_args=['-Dwarning_level=2', '--fatal-meson-warnings'])
obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins['warning_level'].value, '2')
self.assertEqual(obj.builtins[OptionKey('warning_level')].value, '2')
self.setconf('-Dwarning_level=3')
obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins['warning_level'].value, '3')
self.assertEqual(obj.builtins[OptionKey('warning_level')].value, '3')
self.wipe()
# Mixing --option and -Doption is forbidden
@ -3731,15 +3734,15 @@ class AllPlatformTests(BasePlatformTests):
# --default-library should override default value from project()
self.init(testdir, extra_args=['--default-library=both', '--fatal-meson-warnings'])
obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins['default_library'].value, 'both')
self.assertEqual(obj.builtins[OptionKey('default_library')].value, 'both')
self.setconf('--default-library=shared')
obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins['default_library'].value, 'shared')
self.assertEqual(obj.builtins[OptionKey('default_library')].value, 'shared')
if self.backend is Backend.ninja:
# reconfigure target works only with ninja backend
self.build('reconfigure')
obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins['default_library'].value, 'shared')
self.assertEqual(obj.builtins[OptionKey('default_library')].value, 'shared')
self.wipe()
# Should warn on unknown options
@ -3774,7 +3777,7 @@ class AllPlatformTests(BasePlatformTests):
# Test we can set subproject option
self.init(testdir, extra_args=['-Dsubp:subp_opt=foo', '--fatal-meson-warnings'])
obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.user_options[K('subp_opt', 'subp')].value, 'foo')
self.assertEqual(obj.user_options[OptionKey('subp_opt', 'subp')].value, 'foo')
self.wipe()
# c_args value should be parsed with split_args
@ -3789,7 +3792,7 @@ class AllPlatformTests(BasePlatformTests):
self.init(testdir, extra_args=['-Dset_percent_opt=myoption%', '--fatal-meson-warnings'])
obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.user_options[K('set_percent_opt')].value, 'myoption%')
self.assertEqual(obj.user_options[OptionKey('set_percent_opt')].value, 'myoption%')
self.wipe()
# Setting a 2nd time the same option should override the first value
@ -3800,18 +3803,18 @@ class AllPlatformTests(BasePlatformTests):
'-Dc_args=-Dfoo', '-Dc_args=-Dbar',
'-Db_lundef=false', '--fatal-meson-warnings'])
obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins['bindir'].value, 'bar')
self.assertEqual(obj.builtins['buildtype'].value, 'release')
self.assertEqual(obj.base_options['b_sanitize'].value, 'thread')
self.assertEqual(obj.builtins[OptionKey('bindir')].value, 'bar')
self.assertEqual(obj.builtins[OptionKey('buildtype')].value, 'release')
self.assertEqual(obj.base_options[OptionKey('b_sanitize')].value, 'thread')
self.assertEqual(obj.compiler_options[OptionKey('args', lang='c')].value, ['-Dbar'])
self.setconf(['--bindir=bar', '--bindir=foo',
'-Dbuildtype=release', '-Dbuildtype=plain',
'-Db_sanitize=thread', '-Db_sanitize=address',
'-Dc_args=-Dbar', '-Dc_args=-Dfoo'])
obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins['bindir'].value, 'foo')
self.assertEqual(obj.builtins['buildtype'].value, 'plain')
self.assertEqual(obj.base_options['b_sanitize'].value, 'address')
self.assertEqual(obj.builtins[OptionKey('bindir')].value, 'foo')
self.assertEqual(obj.builtins[OptionKey('buildtype')].value, 'plain')
self.assertEqual(obj.base_options[OptionKey('b_sanitize')].value, 'address')
self.assertEqual(obj.compiler_options[OptionKey('args', lang='c')].value, ['-Dfoo'])
self.wipe()
except KeyError:
@ -3826,25 +3829,25 @@ class AllPlatformTests(BasePlatformTests):
# Verify default values when passing no args
self.init(testdir)
obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins['warning_level'].value, '0')
self.assertEqual(obj.builtins[OptionKey('warning_level')].value, '0')
self.wipe()
# verify we can override w/ --warnlevel
self.init(testdir, extra_args=['--warnlevel=1'])
obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins['warning_level'].value, '1')
self.assertEqual(obj.builtins[OptionKey('warning_level')].value, '1')
self.setconf('--warnlevel=0')
obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins['warning_level'].value, '0')
self.assertEqual(obj.builtins[OptionKey('warning_level')].value, '0')
self.wipe()
# verify we can override w/ -Dwarning_level
self.init(testdir, extra_args=['-Dwarning_level=1'])
obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins['warning_level'].value, '1')
self.assertEqual(obj.builtins[OptionKey('warning_level')].value, '1')
self.setconf('-Dwarning_level=0')
obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins['warning_level'].value, '0')
self.assertEqual(obj.builtins[OptionKey('warning_level')].value, '0')
self.wipe()
def test_feature_check_usage_subprojects(self):
@ -5771,7 +5774,7 @@ class WindowsTests(BasePlatformTests):
# Verify that the `b_vscrt` option is available
env = get_fake_env()
cc = env.detect_c_compiler(MachineChoice.HOST)
if 'b_vscrt' not in cc.base_options:
if OptionKey('b_vscrt') not in cc.base_options:
raise unittest.SkipTest('Compiler does not support setting the VS CRT')
# Verify that qmake is for Qt5
if not shutil.which('qmake-qt5'):
@ -5797,7 +5800,7 @@ class WindowsTests(BasePlatformTests):
# Verify that the `b_vscrt` option is available
env = get_fake_env()
cc = env.detect_c_compiler(MachineChoice.HOST)
if 'b_vscrt' not in cc.base_options:
if OptionKey('b_vscrt') not in cc.base_options:
raise unittest.SkipTest('Compiler does not support setting the VS CRT')
def sanitycheck_vscrt(vscrt):

Loading…
Cancel
Save