Use a single coredata dictionary for options

This patches takes the options work to it's logical conclusion: A single
flat dictionary of OptionKey: UserOptions. This allows us to simplify a
large number of cases, as we don't need to check if an option is in this
dict or that one (or any of 5 or 6, actually).
pull/8080/head
Dylan Baker 4 years ago
parent 71db6b04a3
commit e81acbd606
  1. 4
      mesonbuild/ast/introspection.py
  2. 16
      mesonbuild/backend/backends.py
  3. 32
      mesonbuild/backend/ninjabackend.py
  4. 31
      mesonbuild/backend/vs2010backend.py
  5. 2
      mesonbuild/backend/xcodebackend.py
  6. 14
      mesonbuild/build.py
  7. 2
      mesonbuild/cmake/executor.py
  8. 4
      mesonbuild/cmake/interpreter.py
  9. 4
      mesonbuild/compilers/mixins/clike.py
  10. 2
      mesonbuild/compilers/mixins/emscripten.py
  11. 216
      mesonbuild/coredata.py
  12. 10
      mesonbuild/dependencies/base.py
  13. 6
      mesonbuild/dependencies/boost.py
  14. 6
      mesonbuild/dependencies/ui.py
  15. 19
      mesonbuild/environment.py
  16. 77
      mesonbuild/interpreter.py
  17. 2
      mesonbuild/mcompile.py
  18. 34
      mesonbuild/mconf.py
  19. 42
      mesonbuild/mintro.py
  20. 6
      mesonbuild/modules/cmake.py
  21. 12
      mesonbuild/modules/gnome.py
  22. 2
      mesonbuild/modules/hotdoc.py
  23. 2
      mesonbuild/modules/i18n.py
  24. 10
      mesonbuild/modules/pkgconfig.py
  25. 2
      mesonbuild/modules/python.py
  26. 7
      mesonbuild/modules/unstable_external_project.py
  27. 2
      mesonbuild/msetup.py
  28. 4
      mesonbuild/munstable_coredata.py
  29. 7
      mesonbuild/optinterpreter.py
  30. 10
      mesonbuild/rewriter.py
  31. 3
      mesonbuild/scripts/regen_checker.py
  32. 2
      run_tests.py
  33. 87
      run_unittests.py

@ -103,7 +103,7 @@ class IntrospectionInterpreter(AstInterpreter):
if os.path.exists(self.option_file): if os.path.exists(self.option_file):
oi = optinterpreter.OptionInterpreter(self.subproject) oi = optinterpreter.OptionInterpreter(self.subproject)
oi.process(self.option_file) oi.process(self.option_file)
self.coredata.merge_user_options(oi.options) self.coredata.update_project_options(oi.options)
def_opts = self.flatten_args(kwargs.get('default_options', [])) def_opts = self.flatten_args(kwargs.get('default_options', []))
_project_default_options = mesonlib.stringlistify(def_opts) _project_default_options = mesonlib.stringlistify(def_opts)
@ -269,7 +269,7 @@ class IntrospectionInterpreter(AstInterpreter):
return new_target return new_target
def build_library(self, node: BaseNode, args: T.List[TYPE_nvar], kwargs: T.Dict[str, TYPE_nvar]) -> T.Optional[T.Dict[str, T.Any]]: def build_library(self, node: BaseNode, args: T.List[TYPE_nvar], kwargs: T.Dict[str, TYPE_nvar]) -> T.Optional[T.Dict[str, T.Any]]:
default_library = self.coredata.get_builtin_option('default_library') default_library = self.coredata.get_option(OptionKey('default_library'))
if default_library == 'shared': if default_library == 'shared':
return self.build_target(node, args, kwargs, SharedLibrary) return self.build_target(node, args, kwargs, SharedLibrary)
elif default_library == 'static': elif default_library == 'static':

@ -31,7 +31,7 @@ from .. import mesonlib
from .. import mlog from .. import mlog
from ..compilers import languages_using_ldflags from ..compilers import languages_using_ldflags
from ..mesonlib import ( from ..mesonlib import (
File, MachineChoice, MesonException, OrderedSet, OptionOverrideProxy, File, MachineChoice, MesonException, OptionType, OrderedSet, OptionOverrideProxy,
classify_unity_sources, unholder, OptionKey classify_unity_sources, unholder, OptionKey
) )
@ -213,11 +213,11 @@ class Backend:
def get_base_options_for_target(self, target: build.BuildTarget) -> OptionOverrideProxy: def get_base_options_for_target(self, target: build.BuildTarget) -> OptionOverrideProxy:
return OptionOverrideProxy(target.option_overrides_base, return OptionOverrideProxy(target.option_overrides_base,
self.environment.coredata.builtins, {k: v for k, v in self.environment.coredata.options.items()
{k: v for k, v in self.environment.coredata.base_options.items()}) if k.type in {OptionType.BASE, OptionType.BUILTIN}})
def get_compiler_options_for_target(self, target: build.BuildTarget) -> OptionOverrideProxy: def get_compiler_options_for_target(self, target: build.BuildTarget) -> OptionOverrideProxy:
comp_reg = self.environment.coredata.compiler_options comp_reg = {k: v for k, v in self.environment.coredata.options.items() if k.is_compiler()}
comp_override = target.option_overrides_compiler comp_override = target.option_overrides_compiler
return OptionOverrideProxy(comp_override, comp_reg) return OptionOverrideProxy(comp_override, comp_reg)
@ -225,7 +225,7 @@ class Backend:
if option_name in target.option_overrides_base: if option_name in target.option_overrides_base:
override = target.option_overrides_base[option_name] override = target.option_overrides_base[option_name]
return self.environment.coredata.validate_option_value(option_name, override) return self.environment.coredata.validate_option_value(option_name, override)
return self.environment.coredata.get_builtin_option(str(option_name), target.subproject) return self.environment.coredata.get_option(option_name.evolve(subproject=target.subproject))
def get_target_filename_for_linking(self, target): def get_target_filename_for_linking(self, target):
# On some platforms (msvc for instance), the file that is used for # On some platforms (msvc for instance), the file that is used for
@ -250,7 +250,7 @@ class Backend:
@lru_cache(maxsize=None) @lru_cache(maxsize=None)
def get_target_dir(self, target): def get_target_dir(self, target):
if self.environment.coredata.get_builtin_option('layout') == 'mirror': if self.environment.coredata.get_option(OptionKey('layout')) == 'mirror':
dirname = target.get_subdir() dirname = target.get_subdir()
else: else:
dirname = 'meson-out' dirname = 'meson-out'
@ -541,7 +541,7 @@ class Backend:
return paths return paths
def determine_rpath_dirs(self, target): def determine_rpath_dirs(self, target):
if self.environment.coredata.get_builtin_option('layout') == 'mirror': if self.environment.coredata.get_option(OptionKey('layout')) == 'mirror':
result = target.get_link_dep_subdirs() result = target.get_link_dep_subdirs()
else: else:
result = OrderedSet() result = OrderedSet()
@ -1183,7 +1183,7 @@ class Backend:
self.environment.get_build_dir(), self.environment.get_build_dir(),
self.environment.get_prefix(), self.environment.get_prefix(),
strip_bin, strip_bin,
self.environment.coredata.get_builtin_option('install_umask'), self.environment.coredata.get_option(OptionKey('install_umask')),
self.environment.get_build_command() + ['introspect'], self.environment.get_build_command() + ['introspect'],
self.environment.coredata.version) self.environment.coredata.version)
self.generate_depmf_install(d) self.generate_depmf_install(d)

@ -517,7 +517,7 @@ int dummy;
outfile.write('# Do not edit by hand.\n\n') outfile.write('# Do not edit by hand.\n\n')
outfile.write('ninja_required_version = 1.8.2\n\n') outfile.write('ninja_required_version = 1.8.2\n\n')
num_pools = self.environment.coredata.backend_options[OptionKey('backend_max_links')].value num_pools = self.environment.coredata.options[OptionKey('backend_max_links')].value
if num_pools > 0: if num_pools > 0:
outfile.write('''pool link_pool outfile.write('''pool link_pool
depth = {} depth = {}
@ -538,8 +538,8 @@ int dummy;
self.generate_install() self.generate_install()
self.generate_dist() self.generate_dist()
key = OptionKey('b_coverage') key = OptionKey('b_coverage')
if (key in self.environment.coredata.base_options and if (key in self.environment.coredata.options and
self.environment.coredata.base_options[key].value): self.environment.coredata.options[key].value):
self.add_build_comment(NinjaComment('Coverage rules')) self.add_build_comment(NinjaComment('Coverage rules'))
self.generate_coverage_rules() self.generate_coverage_rules()
self.add_build_comment(NinjaComment('Suffix')) self.add_build_comment(NinjaComment('Suffix'))
@ -815,7 +815,7 @@ int dummy;
source2object[s] = o source2object[s] = o
obj_list.append(o) obj_list.append(o)
use_pch = self.environment.coredata.base_options.get(OptionKey('b_pch')) use_pch = self.environment.coredata.options.get(OptionKey('b_pch'))
if use_pch and target.has_pch(): if use_pch and target.has_pch():
pch_objects = self.generate_pch(target, header_deps=header_deps) pch_objects = self.generate_pch(target, header_deps=header_deps)
else: else:
@ -894,7 +894,7 @@ int dummy;
cpp = target.compilers['cpp'] cpp = target.compilers['cpp']
if cpp.get_id() != 'msvc': if cpp.get_id() != 'msvc':
return False return False
if self.environment.coredata.compiler_options[OptionKey('std', machine=target.for_machine, lang='cpp')] != 'latest': if self.environment.coredata.options[OptionKey('std', machine=target.for_machine, lang='cpp')] != 'latest':
return False return False
if not mesonlib.current_vs_supports_modules(): if not mesonlib.current_vs_supports_modules():
return False return False
@ -1128,9 +1128,9 @@ int dummy;
def generate_tests(self): def generate_tests(self):
self.serialize_tests() self.serialize_tests()
cmd = self.environment.get_build_command(True) + ['test', '--no-rebuild'] cmd = self.environment.get_build_command(True) + ['test', '--no-rebuild']
if not self.environment.coredata.get_builtin_option('stdsplit'): if not self.environment.coredata.get_option(OptionKey('stdsplit')):
cmd += ['--no-stdsplit'] cmd += ['--no-stdsplit']
if self.environment.coredata.get_builtin_option('errorlogs'): if self.environment.coredata.get_option(OptionKey('errorlogs')):
cmd += ['--print-errorlogs'] cmd += ['--print-errorlogs']
elem = NinjaBuildElement(self.all_outputs, 'meson-test', 'CUSTOM_COMMAND', ['all', 'PHONY']) elem = NinjaBuildElement(self.all_outputs, 'meson-test', 'CUSTOM_COMMAND', ['all', 'PHONY'])
elem.add_item('COMMAND', cmd) elem.add_item('COMMAND', cmd)
@ -1513,7 +1513,7 @@ int dummy;
valac_outputs.append(vala_c_file) valac_outputs.append(vala_c_file)
args = self.generate_basic_compiler_args(target, valac) args = self.generate_basic_compiler_args(target, valac)
args += valac.get_colorout_args(self.environment.coredata.base_options.get(OptionKey('b_colorout')).value) args += valac.get_colorout_args(self.environment.coredata.options.get(OptionKey('b_colorout')).value)
# Tell Valac to output everything in our private directory. Sadly this # Tell Valac to output everything in our private directory. Sadly this
# means it will also preserve the directory components of Vala sources # means it will also preserve the directory components of Vala sources
# found inside the build tree (generated sources). # found inside the build tree (generated sources).
@ -1850,7 +1850,7 @@ int dummy;
self.create_target_source_introspection(target, swiftc, compile_args + header_imports + module_includes, relsrc, rel_generated) self.create_target_source_introspection(target, swiftc, compile_args + header_imports + module_includes, relsrc, rel_generated)
def generate_static_link_rules(self): def generate_static_link_rules(self):
num_pools = self.environment.coredata.backend_options[OptionKey('backend_max_links')].value num_pools = self.environment.coredata.options[OptionKey('backend_max_links')].value
if 'java' in self.environment.coredata.compilers.host: if 'java' in self.environment.coredata.compilers.host:
self.generate_java_link() self.generate_java_link()
for for_machine in MachineChoice: for for_machine in MachineChoice:
@ -1883,7 +1883,7 @@ int dummy;
extra=pool)) extra=pool))
def generate_dynamic_link_rules(self): def generate_dynamic_link_rules(self):
num_pools = self.environment.coredata.backend_options[OptionKey('backend_max_links')].value num_pools = self.environment.coredata.options[OptionKey('backend_max_links')].value
for for_machine in MachineChoice: for for_machine in MachineChoice:
complist = self.environment.coredata.compilers[for_machine] complist = self.environment.coredata.compilers[for_machine]
for langname, compiler in complist.items(): for langname, compiler in complist.items():
@ -2499,7 +2499,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
commands += self.get_compile_debugfile_args(compiler, target, rel_obj) commands += self.get_compile_debugfile_args(compiler, target, rel_obj)
# PCH handling # PCH handling
if self.environment.coredata.base_options.get(OptionKey('b_pch')): if self.environment.coredata.options.get(OptionKey('b_pch')):
commands += self.get_pch_include_args(compiler, target) commands += self.get_pch_include_args(compiler, target)
pchlist = target.get_pch(compiler.language) pchlist = target.get_pch(compiler.language)
else: else:
@ -2699,7 +2699,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
commands += linker.get_pie_link_args() commands += linker.get_pie_link_args()
elif isinstance(target, build.SharedLibrary): elif isinstance(target, build.SharedLibrary):
if isinstance(target, build.SharedModule): if isinstance(target, build.SharedModule):
options = self.environment.coredata.base_options options = self.environment.coredata.options
commands += linker.get_std_shared_module_link_args(options) commands += linker.get_std_shared_module_link_args(options)
else: else:
commands += linker.get_std_shared_lib_link_args() commands += linker.get_std_shared_lib_link_args()
@ -2939,7 +2939,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
# #
# We shouldn't check whether we are making a static library, because # We shouldn't check whether we are making a static library, because
# in the LTO case we do use a real compiler here. # in the LTO case we do use a real compiler here.
commands += linker.get_option_link_args(self.environment.coredata.compiler_options) commands += linker.get_option_link_args(self.environment.coredata.options)
dep_targets = [] dep_targets = []
dep_targets.extend(self.guess_external_link_dependencies(linker, target, commands, internal)) dep_targets.extend(self.guess_external_link_dependencies(linker, target, commands, internal))
@ -3033,7 +3033,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
def get_user_option_args(self): def get_user_option_args(self):
cmds = [] cmds = []
for (k, v) in self.environment.coredata.user_options.items(): for (k, v) in self.environment.coredata.options.items():
cmds.append('-D' + str(k) + '=' + (v.value if isinstance(v.value, str) else str(v.value).lower())) cmds.append('-D' + str(k) + '=' + (v.value if isinstance(v.value, str) else str(v.value).lower()))
# The order of these arguments must be the same between runs of Meson # The order of these arguments must be the same between runs of Meson
# to ensure reproducible output. The order we pass them shouldn't # to ensure reproducible output. The order we pass them shouldn't
@ -3156,8 +3156,8 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
if ctlist: if ctlist:
elem.add_dep(self.generate_custom_target_clean(ctlist)) elem.add_dep(self.generate_custom_target_clean(ctlist))
if OptionKey('b_coverage') in self.environment.coredata.base_options and \ if OptionKey('b_coverage') in self.environment.coredata.options and \
self.environment.coredata.base_options[OptionKey('b_coverage')].value: self.environment.coredata.options[OptionKey('b_coverage')].value:
self.generate_gcov_clean() self.generate_gcov_clean()
elem.add_dep('clean-gcda') elem.add_dep('clean-gcda')
elem.add_dep('clean-gcno') elem.add_dep('clean-gcno')

@ -181,9 +181,9 @@ class Vs2010Backend(backends.Backend):
self.platform = 'ARM' self.platform = 'ARM'
else: else:
raise MesonException('Unsupported Visual Studio platform: ' + target_machine) raise MesonException('Unsupported Visual Studio platform: ' + target_machine)
self.buildtype = self.environment.coredata.get_builtin_option('buildtype') self.buildtype = self.environment.coredata.get_option(OptionKey('buildtype'))
self.optimization = self.environment.coredata.get_builtin_option('optimization') self.optimization = self.environment.coredata.get_option(OptionKey('optimization'))
self.debug = self.environment.coredata.get_builtin_option('debug') self.debug = self.environment.coredata.get_option(OptionKey('debug'))
sln_filename = os.path.join(self.environment.get_build_dir(), self.build.project_name + '.sln') sln_filename = os.path.join(self.environment.get_build_dir(), self.build.project_name + '.sln')
projlist = self.generate_projects() projlist = self.generate_projects()
self.gen_testproj('RUN_TESTS', os.path.join(self.environment.get_build_dir(), 'RUN_TESTS.vcxproj')) self.gen_testproj('RUN_TESTS', os.path.join(self.environment.get_build_dir(), 'RUN_TESTS.vcxproj'))
@ -316,7 +316,7 @@ class Vs2010Backend(backends.Backend):
prj_templ = 'Project("{%s}") = "%s", "%s", "{%s}"\n' prj_templ = 'Project("{%s}") = "%s", "%s", "{%s}"\n'
for prj in projlist: for prj in projlist:
coredata = self.environment.coredata coredata = self.environment.coredata
if coredata.get_builtin_option('layout') == 'mirror': if coredata.get_option(OptionKey('layout')) == 'mirror':
self.generate_solution_dirs(ofile, prj[1].parents) self.generate_solution_dirs(ofile, prj[1].parents)
target = self.build.targets[prj[0]] target = self.build.targets[prj[0]]
lang = 'default' lang = 'default'
@ -403,7 +403,7 @@ class Vs2010Backend(backends.Backend):
replace_if_different(sln_filename, sln_filename_tmp) replace_if_different(sln_filename, sln_filename_tmp)
def generate_projects(self): def generate_projects(self):
startup_project = self.environment.coredata.backend_options[OptionKey('backend_startup_project')].value startup_project = self.environment.coredata.options[OptionKey('backend_startup_project')].value
projlist = [] projlist = []
startup_idx = 0 startup_idx = 0
for (i, (name, target)) in enumerate(self.build.targets.items()): for (i, (name, target)) in enumerate(self.build.targets.items()):
@ -785,7 +785,7 @@ class Vs2010Backend(backends.Backend):
build_args += compiler.get_optimization_args(self.optimization) build_args += compiler.get_optimization_args(self.optimization)
build_args += compiler.get_debug_args(self.debug) build_args += compiler.get_debug_args(self.debug)
buildtype_link_args = compiler.get_buildtype_linker_args(self.buildtype) buildtype_link_args = compiler.get_buildtype_linker_args(self.buildtype)
vscrt_type = self.environment.coredata.base_options[OptionKey('b_vscrt')] vscrt_type = self.environment.coredata.options[OptionKey('b_vscrt')]
project_name = target.name project_name = target.name
target_name = target.name target_name = target.name
root = ET.Element('Project', {'DefaultTargets': "Build", root = ET.Element('Project', {'DefaultTargets': "Build",
@ -878,7 +878,7 @@ class Vs2010Backend(backends.Backend):
# Exception handling has to be set in the xml in addition to the "AdditionalOptions" because otherwise # Exception handling has to be set in the xml in addition to the "AdditionalOptions" because otherwise
# cl will give warning D9025: overriding '/Ehs' with cpp_eh value # cl will give warning D9025: overriding '/Ehs' with cpp_eh value
if 'cpp' in target.compilers: if 'cpp' in target.compilers:
eh = self.environment.coredata.compiler_options[OptionKey('eh', machine=target.for_machine, lang='cpp')] eh = self.environment.coredata.options[OptionKey('eh', machine=target.for_machine, lang='cpp')]
if eh.value == 'a': if eh.value == 'a':
ET.SubElement(clconf, 'ExceptionHandling').text = 'Async' ET.SubElement(clconf, 'ExceptionHandling').text = 'Async'
elif eh.value == 's': elif eh.value == 's':
@ -926,7 +926,7 @@ class Vs2010Backend(backends.Backend):
file_args[l] += compilers.get_base_compile_args( file_args[l] += compilers.get_base_compile_args(
self.get_base_options_for_target(target), comp) self.get_base_options_for_target(target), comp)
file_args[l] += comp.get_option_compile_args( file_args[l] += comp.get_option_compile_args(
self.environment.coredata.compiler_options) self.environment.coredata.options)
# Add compile args added using add_project_arguments() # Add compile args added using add_project_arguments()
for l, args in self.build.projects_args[target.for_machine].get(target.subproject, {}).items(): for l, args in self.build.projects_args[target.for_machine].get(target.subproject, {}).items():
@ -940,7 +940,7 @@ class Vs2010Backend(backends.Backend):
# Compile args added from the env or cross file: CFLAGS/CXXFLAGS, etc. We want these # Compile args added from the env or cross file: CFLAGS/CXXFLAGS, etc. We want these
# to override all the defaults, but not the per-target compile args. # to override all the defaults, but not the per-target compile args.
for l in file_args.keys(): for l in file_args.keys():
opts = self.environment.coredata.compiler_options[OptionKey('args', machine=target.for_machine, lang=l)] opts = self.environment.coredata.options[OptionKey('args', machine=target.for_machine, lang=l)]
file_args[l] += opts.value file_args[l] += opts.value
for args in file_args.values(): for args in file_args.values():
# This is where Visual Studio will insert target_args, target_defines, # This is where Visual Studio will insert target_args, target_defines,
@ -1075,7 +1075,7 @@ class Vs2010Backend(backends.Backend):
ET.SubElement(clconf, 'FavorSizeOrSpeed').text = 'Speed' ET.SubElement(clconf, 'FavorSizeOrSpeed').text = 'Speed'
# Note: SuppressStartupBanner is /NOLOGO and is 'true' by default # Note: SuppressStartupBanner is /NOLOGO and is 'true' by default
pch_sources = {} pch_sources = {}
if self.environment.coredata.base_options.get(OptionKey('b_pch')): if self.environment.coredata.options.get(OptionKey('b_pch')):
for lang in ['c', 'cpp']: for lang in ['c', 'cpp']:
pch = target.get_pch(lang) pch = target.get_pch(lang)
if not pch: if not pch:
@ -1111,7 +1111,7 @@ class Vs2010Backend(backends.Backend):
ET.SubElement(link, 'GenerateDebugInformation').text = 'false' ET.SubElement(link, 'GenerateDebugInformation').text = 'false'
if not isinstance(target, build.StaticLibrary): if not isinstance(target, build.StaticLibrary):
if isinstance(target, build.SharedModule): if isinstance(target, build.SharedModule):
options = self.environment.coredata.base_options options = self.environment.coredata.options
extra_link_args += compiler.get_std_shared_module_link_args(options) extra_link_args += compiler.get_std_shared_module_link_args(options)
# Add link args added using add_project_link_arguments() # Add link args added using add_project_link_arguments()
extra_link_args += self.build.get_project_link_args(compiler, target.subproject, target.for_machine) extra_link_args += self.build.get_project_link_args(compiler, target.subproject, target.for_machine)
@ -1144,8 +1144,7 @@ class Vs2010Backend(backends.Backend):
# to be after all internal and external libraries so that unresolved # to be after all internal and external libraries so that unresolved
# symbols from those can be found here. This is needed when the # symbols from those can be found here. This is needed when the
# *_winlibs that we want to link to are static mingw64 libraries. # *_winlibs that we want to link to are static mingw64 libraries.
extra_link_args += compiler.get_option_link_args( extra_link_args += compiler.get_option_link_args(self.environment.coredata.options)
self.environment.coredata.compiler_options[compiler.for_machine][comp.language])
(additional_libpaths, additional_links, extra_link_args) = self.split_link_args(extra_link_args.to_native()) (additional_libpaths, additional_links, extra_link_args) = self.split_link_args(extra_link_args.to_native())
# Add more libraries to be linked if needed # Add more libraries to be linked if needed
@ -1224,7 +1223,7 @@ class Vs2010Backend(backends.Backend):
# /nologo # /nologo
ET.SubElement(link, 'SuppressStartupBanner').text = 'true' ET.SubElement(link, 'SuppressStartupBanner').text = 'true'
# /release # /release
if not self.environment.coredata.get_builtin_option('debug'): if not self.environment.coredata.get_option(OptionKey('debug')):
ET.SubElement(link, 'SetChecksum').text = 'true' ET.SubElement(link, 'SetChecksum').text = 'true'
meson_file_group = ET.SubElement(root, 'ItemGroup') meson_file_group = ET.SubElement(root, 'ItemGroup')
@ -1424,9 +1423,9 @@ class Vs2010Backend(backends.Backend):
ET.SubElement(midl, 'ProxyFileName').text = '%(Filename)_p.c' ET.SubElement(midl, 'ProxyFileName').text = '%(Filename)_p.c'
# FIXME: No benchmarks? # FIXME: No benchmarks?
test_command = self.environment.get_build_command() + ['test', '--no-rebuild'] test_command = self.environment.get_build_command() + ['test', '--no-rebuild']
if not self.environment.coredata.get_builtin_option('stdsplit'): if not self.environment.coredata.get_option(OptionKey('stdsplit')):
test_command += ['--no-stdsplit'] test_command += ['--no-stdsplit']
if self.environment.coredata.get_builtin_option('errorlogs'): if self.environment.coredata.get_option(OptionKey('errorlogs')):
test_command += ['--print-errorlogs'] test_command += ['--print-errorlogs']
self.serialize_tests() self.serialize_tests()
self.add_custom_build(root, 'run_tests', '"%s"' % ('" "'.join(test_command))) self.add_custom_build(root, 'run_tests', '"%s"' % ('" "'.join(test_command)))

@ -61,7 +61,7 @@ class XCodeBackend(backends.Backend):
return str(uuid.uuid4()).upper().replace('-', '')[:24] return str(uuid.uuid4()).upper().replace('-', '')[:24]
def get_target_dir(self, target): def get_target_dir(self, target):
dirname = os.path.join(target.get_subdir(), self.environment.coredata.get_builtin_option('buildtype')) dirname = os.path.join(target.get_subdir(), self.environment.coredata.get_option(mesonlib.OptionKey('buildtype')))
os.makedirs(os.path.join(self.environment.get_build_dir(), dirname), exist_ok=True) os.makedirs(os.path.join(self.environment.get_build_dir(), dirname), exist_ok=True)
return dirname return dirname

@ -404,7 +404,7 @@ class EnvironmentVariables:
return env return env
class Target: class Target:
def __init__(self, name, subdir, subproject, build_by_default: bool, for_machine: MachineChoice): def __init__(self, name: str, subdir: str, subproject: str, build_by_default: bool, for_machine: MachineChoice):
if has_path_sep(name): if has_path_sep(name):
# Fix failing test 53 when this becomes an error. # Fix failing test 53 when this becomes an error.
mlog.warning('''Target "{}" has a path separator in its name. mlog.warning('''Target "{}" has a path separator in its name.
@ -418,7 +418,7 @@ a hard error in the future.'''.format(name))
self.install = False self.install = False
self.build_always_stale = False self.build_always_stale = False
self.option_overrides_base: T.Dict[OptionKey, str] = {} self.option_overrides_base: T.Dict[OptionKey, str] = {}
self.option_overrides_compiler: 'KeyedOptionDictType' = {} self.option_overrides_compiler: T.Dict[OptionKey, str] = {}
self.extra_files = [] # type: T.List[File] self.extra_files = [] # type: T.List[File]
if not hasattr(self, 'typename'): if not hasattr(self, 'typename'):
raise RuntimeError('Target type is not set for target class "{}". This is a bug'.format(type(self).__name__)) raise RuntimeError('Target type is not set for target class "{}". This is a bug'.format(type(self).__name__))
@ -545,7 +545,7 @@ class BuildTarget(Target):
def __init__(self, name: str, subdir: str, subproject: str, for_machine: MachineChoice, def __init__(self, name: str, subdir: str, subproject: str, for_machine: MachineChoice,
sources: T.List[File], objects, environment: environment.Environment, kwargs): sources: T.List[File], objects, environment: environment.Environment, kwargs):
super().__init__(name, subdir, subproject, True, for_machine) super().__init__(name, subdir, subproject, True, for_machine)
unity_opt = environment.coredata.get_builtin_option('unity') unity_opt = environment.coredata.get_option(OptionKey('unity'))
self.is_unity = unity_opt == 'on' or (unity_opt == 'subprojects' and subproject != '') self.is_unity = unity_opt == 'on' or (unity_opt == 'subprojects' and subproject != '')
self.environment = environment self.environment = environment
self.sources = [] self.sources = []
@ -1075,8 +1075,8 @@ This will become a hard error in a future Meson release.''')
k = OptionKey(option) k = OptionKey(option)
if arg in kwargs: if arg in kwargs:
val = kwargs[arg] val = kwargs[arg]
elif k in environment.coredata.base_options: elif k in environment.coredata.options:
val = environment.coredata.base_options[k].value val = environment.coredata.options[k].value
else: else:
val = False val = False
@ -1598,8 +1598,8 @@ class Executable(BuildTarget):
sources: T.List[File], objects, environment: environment.Environment, kwargs): sources: T.List[File], objects, environment: environment.Environment, kwargs):
self.typename = 'executable' self.typename = 'executable'
key = OptionKey('b_pie') key = OptionKey('b_pie')
if 'pie' not in kwargs and key in environment.coredata.base_options: if 'pie' not in kwargs and key in environment.coredata.options:
kwargs['pie'] = environment.coredata.base_options[key].value kwargs['pie'] = environment.coredata.options[key].value
super().__init__(name, subdir, subproject, for_machine, sources, objects, environment, kwargs) super().__init__(name, subdir, subproject, for_machine, sources, objects, environment, kwargs)
# Unless overridden, executables have no suffix or prefix. Except on # Unless overridden, executables have no suffix or prefix. Except on
# Windows and with C#/Mono executables where the suffix is 'exe' # Windows and with C#/Mono executables where the suffix is 'exe'

@ -62,7 +62,7 @@ class CMakeExecutor:
self.cmakebin = None self.cmakebin = None
return return
self.prefix_paths = self.environment.coredata.builtins[OptionKey('cmake_prefix_path', machine=self.for_machine)].value self.prefix_paths = self.environment.coredata.options[OptionKey('cmake_prefix_path', machine=self.for_machine)].value
env_pref_path_raw = get_env_var( env_pref_path_raw = get_env_var(
self.for_machine, self.for_machine,
self.environment.is_cross_build(), self.environment.is_cross_build(),

@ -362,7 +362,7 @@ class ConverterTarget:
cfgs += [x for x in tgt.properties['CONFIGURATIONS'] if x] cfgs += [x for x in tgt.properties['CONFIGURATIONS'] if x]
cfg = cfgs[0] cfg = cfgs[0]
is_debug = self.env.coredata.get_builtin_option('debug'); is_debug = self.env.coredata.get_option(OptionKey('debug'));
if is_debug: if is_debug:
if 'DEBUG' in cfgs: if 'DEBUG' in cfgs:
cfg = 'DEBUG' cfg = 'DEBUG'
@ -578,7 +578,7 @@ class ConverterTarget:
@lru_cache(maxsize=None) @lru_cache(maxsize=None)
def _all_lang_stds(self, lang: str) -> T.List[str]: def _all_lang_stds(self, lang: str) -> T.List[str]:
try: try:
res = self.env.coredata.compiler_options[OptionKey('std', machine=MachineChoice.BUILD, lang=lang)].choices res = self.env.coredata.options[OptionKey('std', machine=MachineChoice.BUILD, lang=lang)].choices
except KeyError: except KeyError:
return [] return []

@ -394,8 +394,8 @@ class CLikeCompiler(Compiler):
# linking with static libraries since MSVC won't select a CRT for # 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. # us in that case and will error out asking us to pick one.
try: try:
crt_val = env.coredata.base_options[OptionKey('b_vscrt')].value crt_val = env.coredata.options[OptionKey('b_vscrt')].value
buildtype = env.coredata.builtins[OptionKey('buildtype')].value buildtype = env.coredata.options[OptionKey('buildtype')].value
cargs += self.get_crt_compile_args(crt_val, buildtype) cargs += self.get_crt_compile_args(crt_val, buildtype)
except (KeyError, AttributeError): except (KeyError, AttributeError):
pass pass

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

@ -385,16 +385,12 @@ class CoreData:
self.meson_command = meson_command self.meson_command = meson_command
self.target_guids = {} self.target_guids = {}
self.version = version self.version = version
self.builtins: 'KeyedOptionDictType' = {} self.options: 'KeyedOptionDictType' = {}
self.backend_options: 'KeyedOptionDictType' = {}
self.user_options: 'KeyedOptionDictType' = {}
self.compiler_options: 'KeyedOptionDictType' = {}
self.base_options: 'KeyedOptionDictType' = {}
self.cross_files = self.__load_config_files(options, scratch_dir, 'cross') self.cross_files = self.__load_config_files(options, scratch_dir, 'cross')
self.compilers = PerMachine(OrderedDict(), OrderedDict()) # type: PerMachine[T.Dict[str, Compiler]] self.compilers = PerMachine(OrderedDict(), OrderedDict()) # type: PerMachine[T.Dict[str, Compiler]]
build_cache = DependencyCache(self.builtins, MachineChoice.BUILD) build_cache = DependencyCache(self.options, MachineChoice.BUILD)
host_cache = DependencyCache(self.builtins, MachineChoice.BUILD) host_cache = DependencyCache(self.options, MachineChoice.BUILD)
self.deps = PerMachine(build_cache, host_cache) # type: PerMachine[DependencyCache] self.deps = PerMachine(build_cache, host_cache) # type: PerMachine[DependencyCache]
self.compiler_check_cache = OrderedDict() # type: T.Dict[CompilerCheckCacheKey, compiler.CompileResult] self.compiler_check_cache = OrderedDict() # type: T.Dict[CompilerCheckCacheKey, compiler.CompileResult]
@ -523,10 +519,10 @@ class CoreData:
def init_builtins(self, subproject: str) -> None: def init_builtins(self, subproject: str) -> None:
# Create builtin options with default values # Create builtin options with default values
for key, opt in BUILTIN_OPTIONS.items(): for key, opt in BUILTIN_OPTIONS.items():
self.add_builtin_option(self.builtins, key.evolve(subproject=subproject), opt) self.add_builtin_option(self.options, key.evolve(subproject=subproject), opt)
for for_machine in iter(MachineChoice): for for_machine in iter(MachineChoice):
for key, opt in BUILTIN_OPTIONS_PER_MACHINE.items(): for key, opt in BUILTIN_OPTIONS_PER_MACHINE.items():
self.add_builtin_option(self.builtins, key.evolve(subproject=subproject, machine=for_machine), opt) self.add_builtin_option(self.options, key.evolve(subproject=subproject, machine=for_machine), opt)
@staticmethod @staticmethod
def add_builtin_option(opts_map: 'KeyedOptionDictType', key: OptionKey, def add_builtin_option(opts_map: 'KeyedOptionDictType', key: OptionKey,
@ -542,55 +538,54 @@ class CoreData:
def init_backend_options(self, backend_name: str) -> None: def init_backend_options(self, backend_name: str) -> None:
if backend_name == 'ninja': if backend_name == 'ninja':
self.backend_options[OptionKey('backend_max_links')] = UserIntegerOption( self.options[OptionKey('backend_max_links')] = UserIntegerOption(
'Maximum number of linker processes to run or 0 for no ' 'Maximum number of linker processes to run or 0 for no '
'limit', 'limit',
(0, None, 0)) (0, None, 0))
elif backend_name.startswith('vs'): elif backend_name.startswith('vs'):
self.backend_options[OptionKey('backend_startup_project')] = UserStringOption( self.options[OptionKey('backend_startup_project')] = UserStringOption(
'Default project to execute in Visual Studio', 'Default project to execute in Visual Studio',
'') '')
def get_builtin_option(self, optname: str, subproject: str = '') -> T.Union[str, int, bool]: def get_option(self, key: OptionKey) -> T.Union[str, int, bool, WrapMode]:
key = OptionKey.from_string(optname).evolve(subproject=subproject) try:
for opts in self._get_all_builtin_options(): v = self.options[key].value
v = opts.get(str(key))
if v is None or v.yielding:
v = opts.get(str(key.as_root()))
if v is None:
continue
if key.name == 'wrap_mode': if key.name == 'wrap_mode':
return WrapMode.from_string(v.value) return WrapMode[v]
return v.value return v
raise RuntimeError(f'Tried to get unknown builtin option {key.name}.') except KeyError:
pass
def _try_set_builtin_option(self, key: OptionKey, value) -> bool:
for opts in self._get_all_builtin_options(): try:
opt = opts.get(str(key)) v = self.options[key.as_root()]
if opt is None: if v.yielding:
continue if key.name == 'wrap_mode':
return WrapMode[v.value]
return v.value
except KeyError:
pass
raise MesonException(f'Tried to get unknown builtin option {str(key)}')
def set_option(self, key: OptionKey, value) -> None:
if key.is_builtin():
if key.name == 'prefix': if key.name == 'prefix':
value = self.sanitize_prefix(value) value = self.sanitize_prefix(value)
else: else:
prefix = self.builtins[OptionKey('prefix')].value prefix = self.options[OptionKey('prefix')].value
value = self.sanitize_dir_option_value(prefix, key, 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 key.name == 'buildtype':
self.set_others_from_buildtype(value)
else:
self.set_buildtype_from_others()
return True
def set_builtin_option(self, optname: OptionKey, value) -> None: try:
res = self._try_set_builtin_option(optname, value) self.options[key].set_value(value)
if not res: except KeyError:
raise RuntimeError(f'Tried to set unknown builtin option {str(optname)}') raise MesonException(f'Tried to set unknown builtin option {str(key)}')
def set_others_from_buildtype(self, value): if key.name == 'buildtype':
self._set_others_from_buildtype(value)
elif key.name in {'debug', 'optimization'}:
self._set_buildtype_from_others()
def _set_others_from_buildtype(self, value: str) -> None:
if value == 'plain': if value == 'plain':
opt = '0' opt = '0'
debug = False debug = False
@ -609,12 +604,12 @@ class CoreData:
else: else:
assert(value == 'custom') assert(value == 'custom')
return return
self.builtins[OptionKey('optimization')].set_value(opt) self.options[OptionKey('optimization')].set_value(opt)
self.builtins[OptionKey('debug')].set_value(debug) self.options[OptionKey('debug')].set_value(debug)
def set_buildtype_from_others(self): def _set_buildtype_from_others(self) -> None:
opt = self.builtins[OptionKey('optimization')].value opt = self.options[OptionKey('optimization')].value
debug = self.builtins[OptionKey('debug')].value debug = self.options[OptionKey('debug')].value
if opt == '0' and not debug: if opt == '0' and not debug:
mode = 'plain' mode = 'plain'
elif opt == '0' and debug: elif opt == '0' and debug:
@ -627,84 +622,47 @@ class CoreData:
mode = 'minsize' mode = 'minsize'
else: else:
mode = 'custom' mode = 'custom'
self.builtins[OptionKey('buildtype')].set_value(mode) self.options[OptionKey('buildtype')].set_value(mode)
@classmethod
def get_prefixed_options_per_machine(
cls,
options_per_machine # : PerMachine[T.Dict[str, _V]]]
) -> T.Iterable[T.Tuple[str, _V]]:
return cls._flatten_pair_iterator(
(for_machine.get_prefix(), options_per_machine[for_machine])
for for_machine in iter(MachineChoice)
)
@classmethod
def flatten_lang_iterator(
cls,
outer # : T.Iterable[T.Tuple[str, T.Dict[str, _V]]]
) -> T.Iterable[T.Tuple[str, _V]]:
return cls._flatten_pair_iterator((lang + '_', opts) for lang, opts in outer)
@staticmethod @staticmethod
def _flatten_pair_iterator( def is_per_machine_option(optname: OptionKey) -> bool:
outer # : T.Iterable[T.Tuple[str, T.Dict[str, _V]]]
) -> T.Iterable[T.Tuple[str, _V]]:
for k0, v0 in outer:
for k1, v1 in v0.items():
yield (k0 + k1, v1)
@classmethod
def is_per_machine_option(cls, optname: OptionKey) -> bool:
if optname.name in BUILTIN_OPTIONS_PER_MACHINE: if optname.name in BUILTIN_OPTIONS_PER_MACHINE:
return True return True
return optname.lang is not None return optname.lang is not None
def _get_all_nonbuiltin_options(self) -> T.Iterable[T.Dict[str, UserOption]]:
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 {str(k): v for k, v in self.base_options.items()}
def _get_all_builtin_options(self) -> T.Iterable[T.Dict[str, UserOption]]:
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: OptionKey, override_value): def validate_option_value(self, option_name: OptionKey, override_value):
for opts in self.get_all_options(): try:
opt = opts.get(str(option_name)) opt = self.options[option_name]
if opt is not None: except KeyError:
try: raise MesonException(f'Tried to validate unknown option {str(option_name)}')
return opt.validate_value(override_value) try:
except MesonException as e: return opt.validate_value(override_value)
raise type(e)(('Validation failed for option %s: ' % option_name) + str(e)) \ except MesonException as e:
.with_traceback(sys.exc_info()[2]) raise type(e)(('Validation failed for option %s: ' % option_name) + str(e)) \
raise MesonException('Tried to validate unknown option %s.' % option_name) .with_traceback(sys.exc_info()[2])
def get_external_args(self, for_machine: MachineChoice, lang: str) -> T.Union[str, T.List[str]]: def get_external_args(self, for_machine: MachineChoice, lang: str) -> T.Union[str, T.List[str]]:
return self.compiler_options[OptionKey('args', machine=for_machine, lang=lang)].value return self.options[OptionKey('args', machine=for_machine, lang=lang)].value
def get_external_link_args(self, for_machine: MachineChoice, lang: str) -> T.Union[str, T.List[str]]: def get_external_link_args(self, for_machine: MachineChoice, lang: str) -> T.Union[str, T.List[str]]:
return self.compiler_options[OptionKey('link_args', machine=for_machine, lang=lang)].value return self.options[OptionKey('link_args', machine=for_machine, lang=lang)].value
def merge_user_options(self, options: T.Dict[str, UserOption[T.Any]]) -> None: def update_project_options(self, options: 'KeyedOptionDictType') -> None:
for name, value in options.items(): for key, value in options.items():
key = OptionKey.from_string(name) if not key.is_project():
if key not in self.user_options: continue
self.user_options[key] = value if key not in self.options:
self.options[key] = value
continue continue
oldval = self.user_options[key] oldval = self.options[key]
if type(oldval) != type(value): if type(oldval) != type(value):
self.user_options[key] = value self.options[key] = value
elif oldval.choices != value.choices: elif oldval.choices != value.choices:
# If the choices have changed, use the new value, but attempt # If the choices have changed, use the new value, but attempt
# to keep the old options. If they are not valid keep the new # to keep the old options. If they are not valid keep the new
# defaults but warn. # defaults but warn.
self.user_options[key] = value self.options[key] = value
try: try:
value.set_value(oldval.value) value.set_value(oldval.value)
except MesonException as e: except MesonException as e:
@ -718,13 +676,13 @@ class CoreData:
def copy_build_options_from_regular_ones(self) -> None: def copy_build_options_from_regular_ones(self) -> None:
assert not self.is_cross_build() assert not self.is_cross_build()
for k in BUILTIN_OPTIONS_PER_MACHINE: for k in BUILTIN_OPTIONS_PER_MACHINE:
o = self.builtins[k] o = self.options[k]
self.builtins[k.as_build()].set_value(o.value) self.options[k.as_build()].set_value(o.value)
for bk, bv in self.compiler_options.items(): for bk, bv in self.options.items():
if bk.machine is MachineChoice.BUILD: if bk.machine is MachineChoice.BUILD:
hk = bk.as_host() hk = bk.as_host()
try: try:
hv = self.compiler_options[hk] hv = self.options[hk]
bv.set_value(hv.value) bv.set_value(hv.value)
except KeyError: except KeyError:
continue continue
@ -736,25 +694,19 @@ class CoreData:
pfk = OptionKey('prefix') pfk = OptionKey('prefix')
if pfk in options: if pfk in options:
prefix = self.sanitize_prefix(options[pfk]) prefix = self.sanitize_prefix(options[pfk])
self.builtins[OptionKey('prefix')].set_value(prefix) self.options[OptionKey('prefix')].set_value(prefix)
for key in BULITIN_DIR_NOPREFIX_OPTIONS: for key in BULITIN_DIR_NOPREFIX_OPTIONS:
if key not in options: if key not in options:
self.builtins[key].set_value(BUILTIN_OPTIONS[key].prefixed_default(key, prefix)) self.options[key].set_value(BUILTIN_OPTIONS[key].prefixed_default(key, prefix))
unknown_options: T.List[OptionKey] = [] unknown_options: T.List[OptionKey] = []
for k, v in options.items(): for k, v in options.items():
if k == pfk: if k == pfk:
continue continue
if self._try_set_builtin_option(k, v): elif k not in self.options:
continue
for opts in self._get_all_nonbuiltin_options():
tgt = opts.get(str(k))
if tgt is None:
continue
tgt.set_value(v)
break
else:
unknown_options.append(k) unknown_options.append(k)
else:
self.set_option(k, v)
if unknown_options and warn_unknown: if unknown_options and warn_unknown:
unknown_options_str = ', '.join(sorted(str(s) for s in unknown_options)) unknown_options_str = ', '.join(sorted(str(s) for s in unknown_options))
sub = 'In subproject {}: '.format(subproject) if subproject else '' sub = 'In subproject {}: '.format(subproject) if subproject else ''
@ -767,10 +719,9 @@ class CoreData:
def set_default_options(self, default_options: T.MutableMapping[OptionKey, str], subproject: str, env: 'Environment') -> None: def set_default_options(self, default_options: T.MutableMapping[OptionKey, str], subproject: str, env: 'Environment') -> None:
# Preserve order: if env.options has 'buildtype' it must come after # Preserve order: if env.options has 'buildtype' it must come after
# 'optimization' if it is in default_options. # 'optimization' if it is in default_options.
options: T.MutableMapping[OptionKey, T.Any]
if not subproject: if not subproject:
options: T.MutableMapping[OptionKey, T.Any] = OrderedDict() options = OrderedDict(default_options)
for k, v in default_options.items():
options[k] = v
options.update(env.options) options.update(env.options)
env.options = options env.options = options
@ -779,12 +730,15 @@ class CoreData:
# Language and backend specific options will be set later when adding # Language and backend specific options will be set later when adding
# languages and setting the backend (builtin options must be set first # languages and setting the backend (builtin options must be set first
# to know which backend we'll use). # to know which backend we'll use).
options: T.MutableMapping[OptionKey, T.Any] = OrderedDict() options = OrderedDict()
for k, v in chain(default_options.items(), env.options.items()): for k, v in chain(default_options.items(), env.options.items()):
# Subproject: skip options for other subprojects # If this is a subproject, don't use other subproject options
if k.subproject and k.subproject != subproject: if k.subproject and k.subproject != subproject:
continue continue
# If the option is a builtin and is yielding then it's not allowed per subproject.
if subproject and k.is_builtin() and self.options[k.as_root()].yielding:
continue
# Skip base, compiler, and backend options, they are handled when # Skip base, compiler, and backend options, they are handled when
# adding languages and setting backend. # adding languages and setting backend.
if k.type in {OptionType.COMPILER, OptionType.BACKEND, OptionType.BASE}: if k.type in {OptionType.COMPILER, OptionType.BACKEND, OptionType.BASE}:
@ -799,7 +753,7 @@ class CoreData:
value = env.options.get(k) value = env.options.get(k)
if value is not None: if value is not None:
o.set_value(value) o.set_value(value)
self.compiler_options.setdefault(k, o) self.options.setdefault(k, o)
def add_lang_args(self, lang: str, comp: T.Type['Compiler'], def add_lang_args(self, lang: str, comp: T.Type['Compiler'],
for_machine: MachineChoice, env: 'Environment') -> None: for_machine: MachineChoice, env: 'Environment') -> None:
@ -816,13 +770,13 @@ class CoreData:
enabled_opts: T.List[OptionKey] = [] enabled_opts: T.List[OptionKey] = []
for key in comp.base_options: for key in comp.base_options:
if key in self.base_options: if key in self.options:
continue continue
oobj = compilers.base_options[key] oobj = compilers.base_options[key]
if key in env.options: if key in env.options:
oobj.set_value(env.options[key]) oobj.set_value(env.options[key])
enabled_opts.append(key) enabled_opts.append(key)
self.base_options[key] = oobj self.options[key] = oobj
self.emit_base_options_warnings(enabled_opts) self.emit_base_options_warnings(enabled_opts)
def emit_base_options_warnings(self, enabled_opts: T.List[OptionKey]) -> None: def emit_base_options_warnings(self, enabled_opts: T.List[OptionKey]) -> None:

@ -658,7 +658,7 @@ class PkgConfigDependency(ExternalDependency):
@staticmethod @staticmethod
def setup_env(env: T.MutableMapping[str, str], environment: 'Environment', for_machine: MachineChoice, def setup_env(env: T.MutableMapping[str, str], environment: 'Environment', for_machine: MachineChoice,
extra_path: T.Optional[str] = None) -> None: extra_path: T.Optional[str] = None) -> None:
extra_paths: T.List[str] = environment.coredata.builtins[OptionKey('pkg_config_path', machine=for_machine)].value extra_paths: T.List[str] = environment.coredata.options[OptionKey('pkg_config_path', machine=for_machine)].value
if extra_path: if extra_path:
extra_paths.append(extra_path) extra_paths.append(extra_path)
sysroot = environment.properties[for_machine].get_sys_root() sysroot = environment.properties[for_machine].get_sys_root()
@ -1485,12 +1485,12 @@ class CMakeDependency(ExternalDependency):
cfgs = [x for x in tgt.properties['IMPORTED_CONFIGURATIONS'] if x] cfgs = [x for x in tgt.properties['IMPORTED_CONFIGURATIONS'] if x]
cfg = cfgs[0] cfg = cfgs[0]
if OptionKey('b_vscrt') in self.env.coredata.base_options: if OptionKey('b_vscrt') in self.env.coredata.options:
is_debug = self.env.coredata.get_builtin_option('buildtype') == 'debug' is_debug = self.env.coredata.get_option(OptionKey('buildtype')) == 'debug'
if self.env.coredata.base_options[OptionKey('b_vscrt')].value in {'mdd', 'mtd'}: if self.env.coredata.options[OptionKey('b_vscrt')].value in {'mdd', 'mtd'}:
is_debug = True is_debug = True
else: else:
is_debug = self.env.coredata.get_builtin_option('debug') is_debug = self.env.coredata.get_option(OptionKey('debug'))
if is_debug: if is_debug:
if 'DEBUG' in cfgs: if 'DEBUG' in cfgs:
cfg = 'DEBUG' cfg = 'DEBUG'

@ -341,7 +341,7 @@ class BoostLibraryFile():
class BoostDependency(ExternalDependency): class BoostDependency(ExternalDependency):
def __init__(self, environment: Environment, kwargs: T.Dict[str, T.Any]) -> None: def __init__(self, environment: Environment, kwargs: T.Dict[str, T.Any]) -> None:
super().__init__('boost', environment, kwargs, language='cpp') super().__init__('boost', environment, kwargs, language='cpp')
buildtype = environment.coredata.get_builtin_option('buildtype') buildtype = environment.coredata.get_option(mesonlib.OptionKey('buildtype'))
assert isinstance(buildtype, str) assert isinstance(buildtype, str)
self.debug = buildtype.startswith('debug') self.debug = buildtype.startswith('debug')
self.multithreading = kwargs.get('threading', 'multi') == 'multi' self.multithreading = kwargs.get('threading', 'multi') == 'multi'
@ -616,8 +616,8 @@ class BoostDependency(ExternalDependency):
# MSVC is very picky with the library tags # MSVC is very picky with the library tags
vscrt = '' vscrt = ''
try: try:
crt_val = self.env.coredata.base_options[mesonlib.OptionKey('b_vscrt')].value crt_val = self.env.coredata.options[mesonlib.OptionKey('b_vscrt')].value
buildtype = self.env.coredata.builtins[mesonlib.OptionKey('buildtype')].value buildtype = self.env.coredata.options[mesonlib.OptionKey('buildtype')].value
vscrt = self.clib_compiler.get_crt_compile_args(crt_val, buildtype)[0] vscrt = self.clib_compiler.get_crt_compile_args(crt_val, buildtype)[0]
except (KeyError, IndexError, AttributeError): except (KeyError, IndexError, AttributeError):
pass pass

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

@ -640,6 +640,7 @@ class Environment:
# interfaces which talk about native and cross. # interfaces which talk about native and cross.
self.options = {k.as_host(): v for k, v in self.options.items()} self.options = {k.as_host(): v for k, v in self.options.items()}
## "freeze" now initialized configuration, and "save" to the class. ## "freeze" now initialized configuration, and "save" to the class.
self.machines = machines.default_missing() self.machines = machines.default_missing()
@ -938,7 +939,7 @@ class Environment:
elif isinstance(comp_class.LINKER_PREFIX, list): elif isinstance(comp_class.LINKER_PREFIX, list):
check_args = comp_class.LINKER_PREFIX + ['/logo'] + comp_class.LINKER_PREFIX + ['--version'] check_args = comp_class.LINKER_PREFIX + ['/logo'] + comp_class.LINKER_PREFIX + ['--version']
check_args += self.coredata.compiler_options[OptionKey('args', lang=comp_class.language, machine=for_machine)].value check_args += self.coredata.options[OptionKey('args', lang=comp_class.language, machine=for_machine)].value
override = [] # type: T.List[str] override = [] # type: T.List[str]
value = self.lookup_binary_entry(for_machine, comp_class.language + '_ld') value = self.lookup_binary_entry(for_machine, comp_class.language + '_ld')
@ -1004,7 +1005,7 @@ class Environment:
""" """
self.coredata.add_lang_args(comp_class.language, comp_class, for_machine, self) self.coredata.add_lang_args(comp_class.language, comp_class, for_machine, self)
extra_args = extra_args or [] extra_args = extra_args or []
extra_args += self.coredata.compiler_options[OptionKey('args', lang=comp_class.language, machine=for_machine)].value extra_args += self.coredata.options[OptionKey('args', lang=comp_class.language, machine=for_machine)].value
if isinstance(comp_class.LINKER_PREFIX, str): if isinstance(comp_class.LINKER_PREFIX, str):
check_args = [comp_class.LINKER_PREFIX + '--version'] + extra_args check_args = [comp_class.LINKER_PREFIX + '--version'] + extra_args
@ -2009,25 +2010,25 @@ class Environment:
return self.get_libdir() return self.get_libdir()
def get_prefix(self) -> str: def get_prefix(self) -> str:
return self.coredata.get_builtin_option('prefix') return self.coredata.get_option(OptionKey('prefix'))
def get_libdir(self) -> str: def get_libdir(self) -> str:
return self.coredata.get_builtin_option('libdir') return self.coredata.get_option(OptionKey('libdir'))
def get_libexecdir(self) -> str: def get_libexecdir(self) -> str:
return self.coredata.get_builtin_option('libexecdir') return self.coredata.get_option(OptionKey('libexecdir'))
def get_bindir(self) -> str: def get_bindir(self) -> str:
return self.coredata.get_builtin_option('bindir') return self.coredata.get_option(OptionKey('bindir'))
def get_includedir(self) -> str: def get_includedir(self) -> str:
return self.coredata.get_builtin_option('includedir') return self.coredata.get_option(OptionKey('includedir'))
def get_mandir(self) -> str: def get_mandir(self) -> str:
return self.coredata.get_builtin_option('mandir') return self.coredata.get_option(OptionKey('mandir'))
def get_datadir(self) -> str: def get_datadir(self) -> str:
return self.coredata.get_builtin_option('datadir') return self.coredata.get_option(OptionKey('datadir'))
def get_compiler_system_dirs(self, for_machine: MachineChoice): def get_compiler_system_dirs(self, for_machine: MachineChoice):
for comp in self.coredata.compilers[for_machine].values(): for comp in self.coredata.compilers[for_machine].values():

@ -78,11 +78,11 @@ class OverrideProgram(dependencies.ExternalProgram):
class FeatureOptionHolder(InterpreterObject, ObjectHolder): class FeatureOptionHolder(InterpreterObject, ObjectHolder):
def __init__(self, env, name, option): def __init__(self, env: 'Environment', name, option):
InterpreterObject.__init__(self) InterpreterObject.__init__(self)
ObjectHolder.__init__(self, option) ObjectHolder.__init__(self, option)
if option.is_auto(): if option.is_auto():
self.held_object = env.coredata.builtins[OptionKey('auto_features')] self.held_object = env.coredata.options[OptionKey('auto_features')]
self.name = name self.name = name
self.methods.update({'enabled': self.enabled_method, self.methods.update({'enabled': self.enabled_method,
'disabled': self.disabled_method, 'disabled': self.disabled_method,
@ -1143,7 +1143,7 @@ class CompilerHolder(InterpreterObject):
args += self.compiler.get_include_args(idir, False) args += self.compiler.get_include_args(idir, False)
if not nobuiltins: if not nobuiltins:
for_machine = Interpreter.machine_from_native_kwarg(kwargs) for_machine = Interpreter.machine_from_native_kwarg(kwargs)
opts = self.environment.coredata.compiler_options opts = self.environment.coredata.options
args += self.compiler.get_option_compile_args(opts) args += self.compiler.get_option_compile_args(opts)
if mode == 'link': if mode == 'link':
args += self.compiler.get_option_link_args(opts) args += self.compiler.get_option_link_args(opts)
@ -2151,7 +2151,7 @@ class MesonMain(InterpreterObject):
@noPosargs @noPosargs
@permittedKwargs({}) @permittedKwargs({})
def is_unity_method(self, args, kwargs): def is_unity_method(self, args, kwargs):
optval = self.interpreter.environment.coredata.get_builtin_option('unity') optval = self.interpreter.environment.coredata.get_option(OptionKey('unity'))
if optval == 'on' or (optval == 'subprojects' and self.interpreter.is_subproject()): if optval == 'on' or (optval == 'subprojects' and self.interpreter.is_subproject()):
return True return True
return False return False
@ -2474,12 +2474,11 @@ class Interpreter(InterpreterBase):
def get_non_matching_default_options(self) -> T.Iterator[T.Tuple[str, str, coredata.UserOption]]: def get_non_matching_default_options(self) -> T.Iterator[T.Tuple[str, str, coredata.UserOption]]:
env = self.environment env = self.environment
for def_opt_name, def_opt_value in self.project_default_options.items(): for def_opt_name, def_opt_value in self.project_default_options.items():
for opts in env.coredata.get_all_options(): cur_opt_value = self.coredata.options.get(def_opt_name)
cur_opt_value = opts.get(def_opt_name) if cur_opt_value is not None:
if cur_opt_value is not None: def_opt_value = env.coredata.validate_option_value(def_opt_name, def_opt_value)
def_opt_value = env.coredata.validate_option_value(def_opt_name, def_opt_value) if def_opt_value != cur_opt_value.value:
if def_opt_value != cur_opt_value.value: yield (str(def_opt_name), def_opt_value, cur_opt_value)
yield (def_opt_name, def_opt_value, cur_opt_value)
def build_func_dict(self): def build_func_dict(self):
self.funcs.update({'add_global_arguments': self.func_add_global_arguments, self.funcs.update({'add_global_arguments': self.func_add_global_arguments,
@ -3009,7 +3008,7 @@ external dependencies (including libraries) must go to "dependencies".''')
def _do_subproject_cmake(self, subp_name, subdir, subdir_abs, default_options, kwargs): def _do_subproject_cmake(self, subp_name, subdir, subdir_abs, default_options, kwargs):
with mlog.nested(): with mlog.nested():
new_build = self.build.copy() new_build = self.build.copy()
prefix = self.coredata.builtins[OptionKey('prefix')].value prefix = self.coredata.options[OptionKey('prefix')].value
from .modules.cmake import CMakeSubprojectOptions from .modules.cmake import CMakeSubprojectOptions
options = kwargs.get('options', CMakeSubprojectOptions()) options = kwargs.get('options', CMakeSubprojectOptions())
@ -3051,20 +3050,20 @@ external dependencies (including libraries) must go to "dependencies".''')
return result return result
def get_option_internal(self, optname: str): def get_option_internal(self, optname: str):
# TODO: this optname may be a compiler option
key = OptionKey.from_string(optname).evolve(subproject=self.subproject) key = OptionKey.from_string(optname).evolve(subproject=self.subproject)
for opts in [self.coredata.builtins, self.coredata.base_options, compilers.base_options, self.coredata.compiler_options]: if not key.is_project():
v = opts.get(key) for opts in [self.coredata.options, compilers.base_options]:
if v is None or v.yielding: v = opts.get(key)
v = opts.get(key.as_root()) if v is None or v.yielding:
if v is not None: v = opts.get(key.as_root())
return v if v is not None:
return v
try: try:
opt = self.coredata.user_options[key] opt = self.coredata.options[key]
if opt.yielding and key.subproject and key.as_root() in self.coredata.user_options: if opt.yielding and key.subproject and key.as_root() in self.coredata.options:
popt = self.coredata.user_options[key.as_root()] popt = self.coredata.options[key.as_root()]
if type(opt) is type(popt): if type(opt) is type(popt):
opt = popt opt = popt
else: else:
@ -3118,7 +3117,7 @@ external dependencies (including libraries) must go to "dependencies".''')
# The backend is already set when parsing subprojects # The backend is already set when parsing subprojects
if self.backend is not None: if self.backend is not None:
return return
backend = self.coredata.get_builtin_option('backend') backend = self.coredata.get_option(OptionKey('backend'))
from .backend import backends from .backend import backends
self.backend = backends.get_backend_from_name(backend, self.build, self) self.backend = backends.get_backend_from_name(backend, self.build, self)
@ -3127,7 +3126,7 @@ external dependencies (including libraries) must go to "dependencies".''')
if backend != self.backend.name: if backend != self.backend.name:
if self.backend.name.startswith('vs'): if self.backend.name.startswith('vs'):
mlog.log('Auto detected Visual Studio backend:', mlog.bold(self.backend.name)) mlog.log('Auto detected Visual Studio backend:', mlog.bold(self.backend.name))
self.coredata.set_builtin_option('backend', self.backend.name) self.coredata.set_option(OptionKey('backend'), self.backend.name)
# Only init backend options on first invocation otherwise it would # Only init backend options on first invocation otherwise it would
# override values previously set from command line. # override values previously set from command line.
@ -3158,7 +3157,7 @@ external dependencies (including libraries) must go to "dependencies".''')
if os.path.exists(self.option_file): if os.path.exists(self.option_file):
oi = optinterpreter.OptionInterpreter(self.subproject) oi = optinterpreter.OptionInterpreter(self.subproject)
oi.process(self.option_file) oi.process(self.option_file)
self.coredata.merge_user_options(oi.options) self.coredata.update_project_options(oi.options)
self.add_build_def_file(self.option_file) self.add_build_def_file(self.option_file)
# Do not set default_options on reconfigure otherwise it would override # Do not set default_options on reconfigure otherwise it would override
@ -3208,7 +3207,7 @@ external dependencies (including libraries) must go to "dependencies".''')
self.build.subproject_dir = self.subproject_dir self.build.subproject_dir = self.subproject_dir
# Load wrap files from this (sub)project. # Load wrap files from this (sub)project.
wrap_mode = self.coredata.get_builtin_option('wrap_mode') wrap_mode = self.coredata.get_option(OptionKey('wrap_mode'))
if not self.is_subproject() or wrap_mode != WrapMode.nopromote: if not self.is_subproject() or wrap_mode != WrapMode.nopromote:
subdir = os.path.join(self.subdir, spdirname) subdir = os.path.join(self.subdir, spdirname)
r = wrap.Resolver(self.environment.get_source_dir(), subdir, wrap_mode) r = wrap.Resolver(self.environment.get_source_dir(), subdir, wrap_mode)
@ -3520,7 +3519,7 @@ external dependencies (including libraries) must go to "dependencies".''')
return progobj return progobj
fallback = None fallback = None
wrap_mode = self.coredata.get_builtin_option('wrap_mode') wrap_mode = self.coredata.get_option(OptionKey('wrap_mode'))
if wrap_mode != WrapMode.nofallback and self.environment.wrap_resolver: if wrap_mode != WrapMode.nofallback and self.environment.wrap_resolver:
fallback = self.environment.wrap_resolver.find_program_provider(args) fallback = self.environment.wrap_resolver.find_program_provider(args)
if fallback and wrap_mode == WrapMode.forcefallback: if fallback and wrap_mode == WrapMode.forcefallback:
@ -3824,8 +3823,8 @@ external dependencies (including libraries) must go to "dependencies".''')
if self.get_subproject(subp_name): if self.get_subproject(subp_name):
return self.get_subproject_dep(name, display_name, subp_name, varname, kwargs) return self.get_subproject_dep(name, display_name, subp_name, varname, kwargs)
wrap_mode = self.coredata.get_builtin_option('wrap_mode') wrap_mode = self.coredata.get_option(OptionKey('wrap_mode'))
force_fallback_for = self.coredata.get_builtin_option('force_fallback_for') force_fallback_for = self.coredata.get_option(OptionKey('force_fallback_for'))
force_fallback = (force_fallback or force_fallback = (force_fallback or
wrap_mode == WrapMode.forcefallback or wrap_mode == WrapMode.forcefallback or
name in force_fallback_for or name in force_fallback_for or
@ -3871,11 +3870,11 @@ external dependencies (including libraries) must go to "dependencies".''')
# Explicitly listed fallback preferences for specific subprojects # Explicitly listed fallback preferences for specific subprojects
# take precedence over wrap-mode # take precedence over wrap-mode
force_fallback_for = self.coredata.get_builtin_option('force_fallback_for') force_fallback_for = self.coredata.get_option(OptionKey('force_fallback_for'))
if name in force_fallback_for or subp_name in force_fallback_for: if name in force_fallback_for or subp_name in force_fallback_for:
mlog.log('Looking for a fallback subproject for the dependency', mlog.log('Looking for a fallback subproject for the dependency',
mlog.bold(display_name), 'because:\nUse of fallback was forced for that specific subproject') mlog.bold(display_name), 'because:\nUse of fallback was forced for that specific subproject')
elif self.coredata.get_builtin_option('wrap_mode') == WrapMode.nofallback: elif self.coredata.get_option(OptionKey('wrap_mode')) == WrapMode.nofallback:
mlog.log('Not looking for a fallback subproject for the dependency', mlog.log('Not looking for a fallback subproject for the dependency',
mlog.bold(display_name), 'because:\nUse of fallback ' mlog.bold(display_name), 'because:\nUse of fallback '
'dependencies is disabled.') 'dependencies is disabled.')
@ -3883,7 +3882,7 @@ external dependencies (including libraries) must go to "dependencies".''')
m = 'Dependency {!r} not found and fallback is disabled' m = 'Dependency {!r} not found and fallback is disabled'
raise DependencyException(m.format(display_name)) raise DependencyException(m.format(display_name))
return self.notfound_dependency() return self.notfound_dependency()
elif self.coredata.get_builtin_option('wrap_mode') == WrapMode.forcefallback: elif self.coredata.get_option(OptionKey('wrap_mode')) == WrapMode.forcefallback:
mlog.log('Looking for a fallback subproject for the dependency', mlog.log('Looking for a fallback subproject for the dependency',
mlog.bold(display_name), 'because:\nUse of fallback dependencies is forced.') mlog.bold(display_name), 'because:\nUse of fallback dependencies is forced.')
else: else:
@ -4772,15 +4771,15 @@ different subdirectory.
break break
def check_clang_asan_lundef(self) -> None: def check_clang_asan_lundef(self) -> None:
if OptionKey('b_lundef') not in self.coredata.base_options: if OptionKey('b_lundef') not in self.coredata.options:
return return
if OptionKey('b_sanitize') not in self.coredata.base_options: if OptionKey('b_sanitize') not in self.coredata.options:
return return
if (self.coredata.base_options[OptionKey('b_lundef')].value and if (self.coredata.options[OptionKey('b_lundef')].value and
self.coredata.base_options[OptionKey('b_sanitize')].value != 'none'): self.coredata.options[OptionKey('b_sanitize')].value != 'none'):
mlog.warning('''Trying to use {} sanitizer on Clang with b_lundef. mlog.warning('''Trying to use {} sanitizer on Clang with b_lundef.
This will probably not work. This will probably not work.
Try setting b_lundef to false instead.'''.format(self.coredata.base_options[OptionKey('b_sanitize')].value), Try setting b_lundef to false instead.'''.format(self.coredata.options[OptionKey('b_sanitize')].value),
location=self.current_node) location=self.current_node)
def evaluate_subproject_info(self, path_from_source_root, subproject_dir): def evaluate_subproject_info(self, path_from_source_root, subproject_dir):
@ -4878,8 +4877,8 @@ Try setting b_lundef to false instead.'''.format(self.coredata.base_options[Opti
key = OptionKey('b_staticpic') key = OptionKey('b_staticpic')
if 'pic' in kwargs: if 'pic' in kwargs:
pic = kwargs['pic'] pic = kwargs['pic']
elif key in self.environment.coredata.base_options: elif key in self.environment.coredata.options:
pic = self.environment.coredata.base_options[key].value pic = self.environment.coredata.options[key].value
if pic: if pic:
# Exclude sources from args and kwargs to avoid building them twice # Exclude sources from args and kwargs to avoid building them twice
@ -4896,7 +4895,7 @@ Try setting b_lundef to false instead.'''.format(self.coredata.base_options[Opti
return BothLibrariesHolder(shared_holder, static_holder, self) return BothLibrariesHolder(shared_holder, static_holder, self)
def build_library(self, node, args, kwargs): def build_library(self, node, args, kwargs):
default_library = self.coredata.get_builtin_option('default_library', self.subproject) default_library = self.coredata.get_option(OptionKey('default_library', subproject=self.subproject))
if default_library == 'shared': if default_library == 'shared':
return self.build_target(node, args, kwargs, SharedLibraryHolder) return self.build_target(node, args, kwargs, SharedLibraryHolder)
elif default_library == 'static': elif default_library == 'static':

@ -47,7 +47,7 @@ def get_backend_from_coredata(builddir: Path) -> str:
""" """
Gets `backend` option value from coredata Gets `backend` option value from coredata
""" """
backend = coredata.load(str(builddir)).get_builtin_option('backend') backend = coredata.load(str(builddir)).get_option(mesonlib.OptionKey('backend'))
assert isinstance(backend, str) assert isinstance(backend, str)
return backend return backend

@ -192,26 +192,32 @@ class Conf:
dir_option_names = set(coredata.BUILTIN_DIR_OPTIONS) dir_option_names = set(coredata.BUILTIN_DIR_OPTIONS)
test_option_names = {OptionKey('errorlogs'), test_option_names = {OptionKey('errorlogs'),
OptionKey('stdsplit')} OptionKey('stdsplit')}
core_option_names = [k for k in self.coredata.builtins if k not in dir_option_names | test_option_names]
dir_options: 'coredata.KeyedOptionDictType' = {}
dir_options = {k: o for k, o in self.coredata.builtins.items() if k in dir_option_names} test_options: 'coredata.KeyedOptionDictType' = {}
test_options = {k: o for k, o in self.coredata.builtins.items() if k in test_option_names} core_options: 'coredata.KeyedOptionDictType' = {}
core_options = {k: o for k, o in self.coredata.builtins.items() if k in core_option_names} for k, v in self.coredata.options.items():
if k in dir_option_names:
host_core_options = self.split_options_per_subproject({k: v for k, v in self.coredata.builtins.items() if k.machine is MachineChoice.HOST}) dir_options[k] = v
build_core_options = self.split_options_per_subproject({k: v for k, v in self.coredata.builtins.items() if k.machine is MachineChoice.BUILD}) elif k in test_option_names:
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}) test_options[k] = v
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}) elif k.is_builtin():
project_options = self.split_options_per_subproject(self.coredata.user_options) core_options[k] = v
host_core_options = self.split_options_per_subproject({k: v for k, v in core_options.items() if k.machine is MachineChoice.HOST})
build_core_options = self.split_options_per_subproject({k: v for k, v in core_options.items() if k.machine is MachineChoice.BUILD})
host_compiler_options = self.split_options_per_subproject({k: v for k, v in self.coredata.options.items() if k.is_compiler() and k.machine is MachineChoice.HOST})
build_compiler_options = self.split_options_per_subproject({k: v for k, v in self.coredata.options.items() if k.is_compiler() and k.machine is MachineChoice.BUILD})
project_options = self.split_options_per_subproject({k: v for k, v in self.coredata.options.items() if k.is_project()})
show_build_options = self.default_values_only or self.build.environment.is_cross_build() show_build_options = self.default_values_only or self.build.environment.is_cross_build()
self.add_section('Main project options') self.add_section('Main project options')
self.print_options('Core options', host_core_options['']) self.print_options('Core options', host_core_options[''])
if show_build_options: if show_build_options:
self.print_options('', build_core_options['']) 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('Backend options', {str(k): v for k, v in self.coredata.options.items()})
self.print_options('Base options', {str(k): v for k, v in self.coredata.base_options.items()}) self.print_options('Base options', {str(k): v for k, v in self.coredata.options.items()})
self.print_options('Compiler options', host_compiler_options.get('', {})) self.print_options('Compiler options', host_compiler_options.get('', {}))
if show_build_options: if show_build_options:
self.print_options('', build_compiler_options.get('', {})) self.print_options('', build_compiler_options.get('', {}))

@ -21,6 +21,7 @@ project files and don't need this info."""
import collections import collections
import json import json
from mesonbuild.compilers import d
from . import build, coredata as cdata from . import build, coredata as cdata
from . import mesonlib from . import mesonlib
from .ast import IntrospectionInterpreter, build_target_functions, AstConditionLevel, AstIDGenerator, AstIndentationGenerator, AstJSONPrinter from .ast import IntrospectionInterpreter, build_target_functions, AstConditionLevel, AstIDGenerator, AstIndentationGenerator, AstJSONPrinter
@ -212,21 +213,30 @@ 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]]]]: 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]]]] optlist = [] # type: T.List[T.Dict[str, T.Union[str, bool, int, T.List[str]]]]
subprojects = subprojects or []
dir_option_names = set(cdata.BUILTIN_DIR_OPTIONS) dir_option_names = set(cdata.BUILTIN_DIR_OPTIONS)
test_option_names = {OptionKey('errorlogs'), test_option_names = {OptionKey('errorlogs'),
OptionKey('stdsplit')} 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} dir_options: 'cdata.KeyedOptionDictType' = {}
test_options = {str(k): o for k, o in coredata.builtins.items() if k in test_option_names} test_options: 'cdata.KeyedOptionDictType' = {}
core_options = {str(k): o for k, o in coredata.builtins.items() if k in core_option_names} core_options: 'cdata.KeyedOptionDictType' = {}
for s in subprojects or []: for k, v in coredata.options.items():
core_options.update({str(k.evolve(subproject=s)): v for k, v in coredata.builtins.items() if not v.yielding}) if k in dir_option_names:
dir_options[k] = v
def add_keys(options: 'cdata.OptionDictType', section: str, machine: str = 'any') -> None: elif k in test_option_names:
test_options[k] = v
elif k.is_builtin():
core_options[k] = v
if not v.yielding:
for s in subprojects:
core_options[k.evolve(subproject=s)] = v
def add_keys(options: 'cdata.KeyedOptionDictType', section: str) -> None:
for key, opt in sorted(options.items()): for key, opt in sorted(options.items()):
optdict = {'name': key, 'value': opt.value, 'section': section, 'machine': machine} optdict = {'name': str(key), 'value': opt.value, 'section': section,
'machine': key.machine.get_lower_case_name() if coredata.is_per_machine_option(key) else 'any'}
if isinstance(opt, cdata.UserStringOption): if isinstance(opt, cdata.UserStringOption):
typestr = 'string' typestr = 'string'
elif isinstance(opt, cdata.UserBooleanOption): elif isinstance(opt, cdata.UserBooleanOption):
@ -245,20 +255,14 @@ def list_buildoptions(coredata: cdata.CoreData, subprojects: T.Optional[T.List[s
optlist.append(optdict) optlist.append(optdict)
add_keys(core_options, 'core') add_keys(core_options, 'core')
add_keys({str(k): v for k, v in coredata.backend_options.items()}, 'backend') add_keys({k: v for k, v in coredata.options.items() if k.is_backend()}, 'backend')
add_keys({str(k): v for k, v in coredata.base_options.items()}, 'base') add_keys({k: v for k, v in coredata.options.items() if k.is_base()}, 'base')
add_keys(
{str(k): v for k, v in coredata.compiler_options.items() if k.machine is MachineChoice.HOST},
'compiler',
machine='host',
)
add_keys( add_keys(
{str(k): v for k, v in coredata.compiler_options.items() if k.machine is MachineChoice.BUILD}, {k: v for k, v in sorted(coredata.options.items(), key=lambda i: i[0].machine) if k.is_compiler()},
'compiler', 'compiler',
machine='build',
) )
add_keys(dir_options, 'directory') add_keys(dir_options, 'directory')
add_keys({str(k): v for k, v in coredata.user_options.items()}, 'user') add_keys({k: v for k, v in coredata.options.items() if k.is_project()}, 'user')
add_keys(test_options, 'test') add_keys(test_options, 'test')
return optlist return optlist

@ -269,7 +269,7 @@ class CmakeModule(ExtensionModule):
pkgroot = kwargs.get('install_dir', None) pkgroot = kwargs.get('install_dir', None)
if pkgroot is None: if pkgroot is None:
pkgroot = os.path.join(state.environment.coredata.get_builtin_option('libdir'), 'cmake', name) pkgroot = os.path.join(state.environment.coredata.get_option(mesonlib.OptionKey('libdir')), 'cmake', name)
if not isinstance(pkgroot, str): if not isinstance(pkgroot, str):
raise mesonlib.MesonException('Install_dir must be a string.') raise mesonlib.MesonException('Install_dir must be a string.')
@ -342,7 +342,7 @@ class CmakeModule(ExtensionModule):
(ofile_path, ofile_fname) = os.path.split(os.path.join(state.subdir, '{}Config.cmake'.format(name))) (ofile_path, ofile_fname) = os.path.split(os.path.join(state.subdir, '{}Config.cmake'.format(name)))
ofile_abs = os.path.join(state.environment.build_dir, ofile_path, ofile_fname) ofile_abs = os.path.join(state.environment.build_dir, ofile_path, ofile_fname)
install_dir = kwargs.get('install_dir', os.path.join(state.environment.coredata.get_builtin_option('libdir'), 'cmake', name)) install_dir = kwargs.get('install_dir', os.path.join(state.environment.coredata.get_option(mesonlib.OptionKey('libdir')), 'cmake', name))
if not isinstance(install_dir, str): if not isinstance(install_dir, str):
raise mesonlib.MesonException('"install_dir" must be a string.') raise mesonlib.MesonException('"install_dir" must be a string.')
@ -352,7 +352,7 @@ class CmakeModule(ExtensionModule):
if not isinstance(conf, ConfigurationDataHolder): if not isinstance(conf, ConfigurationDataHolder):
raise mesonlib.MesonException('Argument "configuration" is not of type configuration_data') raise mesonlib.MesonException('Argument "configuration" is not of type configuration_data')
prefix = state.environment.coredata.get_builtin_option('prefix') prefix = state.environment.coredata.get_option(mesonlib.OptionKey('prefix'))
abs_install_dir = install_dir abs_install_dir = install_dir
if not os.path.isabs(abs_install_dir): if not os.path.isabs(abs_install_dir):
abs_install_dir = os.path.join(prefix, install_dir) abs_install_dir = os.path.join(prefix, install_dir)

@ -212,7 +212,7 @@ class GnomeModule(ExtensionModule):
if install_header: if install_header:
h_kwargs['install'] = install_header h_kwargs['install'] = install_header
h_kwargs['install_dir'] = kwargs.get('install_dir', h_kwargs['install_dir'] = kwargs.get('install_dir',
state.environment.coredata.get_builtin_option('includedir')) state.environment.coredata.get_option(mesonlib.OptionKey('includedir')))
target_h = GResourceHeaderTarget(args[0] + '_h', state.subdir, state.subproject, h_kwargs) target_h = GResourceHeaderTarget(args[0] + '_h', state.subdir, state.subproject, h_kwargs)
rv = [target_c, target_h] rv = [target_c, target_h]
return ModuleReturnValue(rv, rv) return ModuleReturnValue(rv, rv)
@ -613,7 +613,7 @@ class GnomeModule(ExtensionModule):
if state.project_args.get(lang): if state.project_args.get(lang):
cflags += state.project_args[lang] cflags += state.project_args[lang]
if mesonlib.OptionKey('b_sanitize') in compiler.base_options: if mesonlib.OptionKey('b_sanitize') in compiler.base_options:
sanitize = state.environment.coredata.base_options[mesonlib.OptionKey('b_sanitize')].value sanitize = state.environment.coredata.options[mesonlib.OptionKey('b_sanitize')].value
cflags += compiler.sanitizer_compile_args(sanitize) cflags += compiler.sanitizer_compile_args(sanitize)
sanitize = sanitize.split(',') sanitize = sanitize.split(',')
# These must be first in ldflags # These must be first in ldflags
@ -1175,7 +1175,7 @@ class GnomeModule(ExtensionModule):
targets = [] targets = []
install_header = kwargs.get('install_header', False) install_header = kwargs.get('install_header', False)
install_dir = kwargs.get('install_dir', state.environment.coredata.get_builtin_option('includedir')) install_dir = kwargs.get('install_dir', state.environment.coredata.get_option(mesonlib.OptionKey('includedir')))
output = namebase + '.c' output = namebase + '.c'
# Added in https://gitlab.gnome.org/GNOME/glib/commit/e4d68c7b3e8b01ab1a4231bf6da21d045cb5a816 (2.55.2) # Added in https://gitlab.gnome.org/GNOME/glib/commit/e4d68c7b3e8b01ab1a4231bf6da21d045cb5a816 (2.55.2)
@ -1332,7 +1332,7 @@ class GnomeModule(ExtensionModule):
custom_kwargs['install'] = install_header custom_kwargs['install'] = install_header
if 'install_dir' not in custom_kwargs: if 'install_dir' not in custom_kwargs:
custom_kwargs['install_dir'] = \ custom_kwargs['install_dir'] = \
state.environment.coredata.get_builtin_option('includedir') state.environment.coredata.get_option(mesonlib.OptionKey('includedir'))
h_target = self._make_mkenum_custom_target(state, h_sources, h_target = self._make_mkenum_custom_target(state, h_sources,
h_output, h_cmd, h_output, h_cmd,
custom_kwargs) custom_kwargs)
@ -1361,7 +1361,7 @@ class GnomeModule(ExtensionModule):
custom_kwargs['install'] = install_header custom_kwargs['install'] = install_header
if 'install_dir' not in custom_kwargs: if 'install_dir' not in custom_kwargs:
custom_kwargs['install_dir'] = \ custom_kwargs['install_dir'] = \
state.environment.coredata.get_builtin_option('includedir') state.environment.coredata.get_option(mesonlib.OptionKey('includedir'))
target = self._make_mkenum_custom_target(state, sources, basename, target = self._make_mkenum_custom_target(state, sources, basename,
generic_cmd, custom_kwargs) generic_cmd, custom_kwargs)
return ModuleReturnValue(target, [target]) return ModuleReturnValue(target, [target])
@ -1691,7 +1691,7 @@ G_END_DECLS'''
'depends': vapi_depends, 'depends': vapi_depends,
} }
install_dir = kwargs.get('install_dir', install_dir = kwargs.get('install_dir',
os.path.join(state.environment.coredata.get_builtin_option('datadir'), os.path.join(state.environment.coredata.get_option(mesonlib.OptionKey('datadir')),
'vala', 'vapi')) 'vala', 'vapi'))
if kwargs.get('install'): if kwargs.get('install'):
custom_kwargs['install'] = kwargs['install'] custom_kwargs['install'] = kwargs['install']

@ -326,7 +326,7 @@ class HotdocTargetBuilder:
for path in self.include_paths.keys(): for path in self.include_paths.keys():
self.cmd.extend(['--include-path', path]) self.cmd.extend(['--include-path', path])
if self.state.environment.coredata.get_builtin_option('werror', self.state.subproject): if self.state.environment.coredata.get_option(mesonlib.OptionKey('werror', subproject=self.state.subproject)):
self.cmd.append('--fatal-warning') self.cmd.append('--fatal-warning')
self.generate_hotdoc_config() self.generate_hotdoc_config()

@ -172,7 +172,7 @@ class I18nModule(ExtensionModule):
install = kwargs.get('install', True) install = kwargs.get('install', True)
if install: if install:
install_dir = kwargs.get('install_dir', state.environment.coredata.get_builtin_option('localedir')) install_dir = kwargs.get('install_dir', state.environment.coredata.get_option(mesonlib.OptionKey('localedir')))
script = state.environment.get_build_command() script = state.environment.get_build_command()
args = ['--internal', 'gettext', 'install', args = ['--internal', 'gettext', 'install',
'--subdir=' + state.subdir, '--subdir=' + state.subdir,

@ -331,10 +331,10 @@ class PkgConfigModule(ExtensionModule):
srcdir = PurePath(state.environment.get_source_dir()) srcdir = PurePath(state.environment.get_source_dir())
else: else:
outdir = state.environment.scratch_dir outdir = state.environment.scratch_dir
prefix = PurePath(coredata.get_builtin_option('prefix')) prefix = PurePath(coredata.get_option(mesonlib.OptionKey('prefix')))
# These always return paths relative to prefix # These always return paths relative to prefix
libdir = PurePath(coredata.get_builtin_option('libdir')) libdir = PurePath(coredata.get_option(mesonlib.OptionKey('libdir')))
incdir = PurePath(coredata.get_builtin_option('includedir')) incdir = PurePath(coredata.get_option(mesonlib.OptionKey('includedir')))
fname = os.path.join(outdir, pcfile) fname = os.path.join(outdir, pcfile)
with open(fname, 'w', encoding='utf-8') as ofile: with open(fname, 'w', encoding='utf-8') as ofile:
if not dataonly: if not dataonly:
@ -531,9 +531,9 @@ class PkgConfigModule(ExtensionModule):
pkgroot = kwargs.get('install_dir', default_install_dir) pkgroot = kwargs.get('install_dir', default_install_dir)
if pkgroot is None: if pkgroot is None:
if mesonlib.is_freebsd(): if mesonlib.is_freebsd():
pkgroot = os.path.join(state.environment.coredata.get_builtin_option('prefix'), 'libdata', 'pkgconfig') pkgroot = os.path.join(state.environment.coredata.get_option(mesonlib.OptionKey('prefix')), 'libdata', 'pkgconfig')
else: else:
pkgroot = os.path.join(state.environment.coredata.get_builtin_option('libdir'), 'pkgconfig') pkgroot = os.path.join(state.environment.coredata.get_option(mesonlib.OptionKey('libdir')), 'pkgconfig')
if not isinstance(pkgroot, str): if not isinstance(pkgroot, str):
raise mesonlib.MesonException('Install_dir must be a string.') raise mesonlib.MesonException('Install_dir must be a string.')
self.generate_pkgconfig_file(state, deps, subdirs, name, description, url, self.generate_pkgconfig_file(state, deps, subdirs, name, description, url,

@ -288,7 +288,7 @@ class PythonInstallation(ExternalProgramHolder):
ExternalProgramHolder.__init__(self, python, interpreter.subproject) ExternalProgramHolder.__init__(self, python, interpreter.subproject)
self.interpreter = interpreter self.interpreter = interpreter
self.subproject = self.interpreter.subproject self.subproject = self.interpreter.subproject
prefix = self.interpreter.environment.coredata.get_builtin_option('prefix') prefix = self.interpreter.environment.coredata.get_option(mesonlib.OptionKey('prefix'))
self.variables = info['variables'] self.variables = info['variables']
self.paths = info['paths'] self.paths = info['paths']
install_paths = info['install_paths'] install_paths = info['install_paths']

@ -26,6 +26,7 @@ from ..interpreter import Interpreter, DependencyHolder, InstallDir
from ..compilers.compilers import cflags_mapping, cexe_mapping from ..compilers.compilers import cflags_mapping, cexe_mapping
from ..dependencies.base import InternalDependency, PkgConfigDependency from ..dependencies.base import InternalDependency, PkgConfigDependency
from ..environment import Environment from ..environment import Environment
from ..mesonlib import OptionKey
class ExternalProject(InterpreterObject): class ExternalProject(InterpreterObject):
def __init__(self, def __init__(self,
@ -62,9 +63,9 @@ class ExternalProject(InterpreterObject):
self.src_dir = Path(self.env.get_source_dir(), self.subdir) self.src_dir = Path(self.env.get_source_dir(), self.subdir)
self.build_dir = Path(self.env.get_build_dir(), self.subdir, 'build') self.build_dir = Path(self.env.get_build_dir(), self.subdir, 'build')
self.install_dir = Path(self.env.get_build_dir(), self.subdir, 'dist') self.install_dir = Path(self.env.get_build_dir(), self.subdir, 'dist')
self.prefix = Path(self.env.coredata.get_builtin_option('prefix')) self.prefix = Path(self.env.coredata.get_option(OptionKey('prefix')))
self.libdir = Path(self.env.coredata.get_builtin_option('libdir')) self.libdir = Path(self.env.coredata.get_option(OptionKey('libdir')))
self.includedir = Path(self.env.coredata.get_builtin_option('includedir')) self.includedir = Path(self.env.coredata.get_option(OptionKey('includedir')))
# On Windows if the prefix is "c:/foo" and DESTDIR is "c:/bar", `make` # On Windows if the prefix is "c:/foo" and DESTDIR is "c:/bar", `make`
# will install files into "c:/bar/c:/foo" which is an invalid path. # will install files into "c:/bar/c:/foo" which is an invalid path.

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

@ -14,7 +14,7 @@
from . import coredata as cdata from . import coredata as cdata
from .mesonlib import MachineChoice from .mesonlib import MachineChoice, OptionKey
import os.path import os.path
import pprint import pprint
@ -59,7 +59,7 @@ def run(options):
print('') print('')
coredata = cdata.load(options.builddir) coredata = cdata.load(options.builddir)
backend = coredata.get_builtin_option('backend') backend = coredata.get_option(OptionKey('backend'))
for k, v in sorted(coredata.__dict__.items()): for k, v in sorted(coredata.__dict__.items()):
if k in ('backend_options', 'base_options', 'builtins', 'compiler_options', 'user_options'): if k in ('backend_options', 'base_options', 'builtins', 'compiler_options', 'user_options'):
# use `meson configure` to view these # use `meson configure` to view these

@ -137,7 +137,7 @@ option_types = {'string': string_parser,
class OptionInterpreter: class OptionInterpreter:
def __init__(self, subproject: str) -> None: def __init__(self, subproject: str) -> None:
self.options: T.Dict[str, coredata.UserOption] = {} self.options: 'coredata.KeyedOptionDictType' = {}
self.subproject = subproject self.subproject = subproject
def process(self, option_file: str) -> None: def process(self, option_file: str) -> None:
@ -227,8 +227,7 @@ class OptionInterpreter:
raise OptionException('Option names can only contain letters, numbers or dashes.') raise OptionException('Option names can only contain letters, numbers or dashes.')
if is_invalid_name(opt_name): if is_invalid_name(opt_name):
raise OptionException('Option name %s is reserved.' % opt_name) raise OptionException('Option name %s is reserved.' % opt_name)
if self.subproject != '': key = mesonlib.OptionKey(opt_name, self.subproject)
opt_name = self.subproject + ':' + opt_name
if 'yield' in kwargs: if 'yield' in kwargs:
FeatureNew.single_use('option yield', '0.45.0', self.subproject) FeatureNew.single_use('option yield', '0.45.0', self.subproject)
@ -248,4 +247,4 @@ class OptionInterpreter:
opt = option_types[opt_type](opt_name, description, kwargs) opt = option_types[opt_type](opt_name, description, kwargs)
if opt.description == '': if opt.description == '':
opt.description = opt_name opt.description = opt_name
self.options[opt_name] = opt self.options[key] = opt

@ -464,11 +464,11 @@ class Rewriter:
cdata = self.interpreter.coredata cdata = self.interpreter.coredata
options = { options = {
**{str(k): v for k, v in cdata.builtins.items()}, **{str(k): v for k, v in cdata.options.items()},
**{str(k): v for k, v in cdata.backend_options.items()}, **{str(k): v for k, v in cdata.options.items()},
**{str(k): v for k, v in cdata.base_options.items()}, **{str(k): v for k, v in cdata.options.items()},
**{str(k): v for k, v in cdata.compiler_options.items()}, **{str(k): v for k, v in cdata.options.items()},
**{str(k): v for k, v in cdata.user_options.items()}, **{str(k): v for k, v in cdata.options.items()},
} }
for key, val in sorted(cmd['options'].items()): for key, val in sorted(cmd['options'].items()):

@ -17,6 +17,7 @@ import pickle, subprocess
import typing as T import typing as T
from ..coredata import CoreData from ..coredata import CoreData
from ..backend.vs2010backend import RegenInfo from ..backend.vs2010backend import RegenInfo
from ..mesonlib import OptionKey
# This could also be used for XCode. # This could also be used for XCode.
@ -52,7 +53,7 @@ def run(args: T.List[str]) -> int:
with open(coredata_file, 'rb') as f: with open(coredata_file, 'rb') as f:
coredata = pickle.load(f) coredata = pickle.load(f)
assert isinstance(coredata, CoreData) assert isinstance(coredata, CoreData)
backend = coredata.get_builtin_option('backend') backend = coredata.get_option(OptionKey('backend'))
assert isinstance(backend, str) assert isinstance(backend, str)
regen_timestamp = os.stat(dumpfile).st_mtime regen_timestamp = os.stat(dumpfile).st_mtime
if need_regen(regeninfo, regen_timestamp): if need_regen(regeninfo, regen_timestamp):

@ -128,7 +128,7 @@ def get_fake_env(sdir='', bdir=None, prefix='', opts=None):
if opts is None: if opts is None:
opts = get_fake_options(prefix) opts = get_fake_options(prefix)
env = Environment(sdir, bdir, opts) env = Environment(sdir, bdir, opts)
env.coredata.compiler_options[OptionKey('args', lang='c')] = FakeCompilerOptions() env.coredata.options[OptionKey('args', lang='c')] = FakeCompilerOptions()
env.machines.host.cpu_family = 'x86_64' # Used on macOS inside find_library env.machines.host.cpu_family = 'x86_64' # Used on macOS inside find_library
return env return env

@ -873,7 +873,7 @@ class InternalTests(unittest.TestCase):
env = get_fake_env() env = get_fake_env()
compiler = env.detect_c_compiler(MachineChoice.HOST) compiler = env.detect_c_compiler(MachineChoice.HOST)
env.coredata.compilers.host = {'c': compiler} env.coredata.compilers.host = {'c': compiler}
env.coredata.compiler_options[OptionKey('link_args', lang='c')] = FakeCompilerOptions() env.coredata.options[OptionKey('link_args', lang='c')] = FakeCompilerOptions()
p1 = Path(tmpdir) / '1' p1 = Path(tmpdir) / '1'
p2 = Path(tmpdir) / '2' p2 = Path(tmpdir) / '2'
p1.mkdir() p1.mkdir()
@ -1413,10 +1413,10 @@ class DataTests(unittest.TestCase):
debug = False debug = False
else: else:
raise RuntimeError('Invalid debug value {!r} in row:\n{}'.format(debug, m.group())) raise RuntimeError('Invalid debug value {!r} in row:\n{}'.format(debug, m.group()))
env.coredata.set_builtin_option(OptionKey('buildtype'), buildtype) env.coredata.set_option(OptionKey('buildtype'), buildtype)
self.assertEqual(env.coredata.builtins[OptionKey('buildtype')].value, buildtype) self.assertEqual(env.coredata.options[OptionKey('buildtype')].value, buildtype)
self.assertEqual(env.coredata.builtins[OptionKey('optimization')].value, opt) self.assertEqual(env.coredata.options[OptionKey('optimization')].value, opt)
self.assertEqual(env.coredata.builtins[OptionKey('debug')].value, debug) self.assertEqual(env.coredata.options[OptionKey('debug')].value, debug)
def test_cpu_families_documented(self): def test_cpu_families_documented(self):
with open("docs/markdown/Reference-tables.md", encoding='utf-8') as f: with open("docs/markdown/Reference-tables.md", encoding='utf-8') as f:
@ -3688,29 +3688,29 @@ class AllPlatformTests(BasePlatformTests):
# configuration, and as a bonus, test that --profile-self works. # configuration, and as a bonus, test that --profile-self works.
self.init(testdir, extra_args=['--profile-self', '--fatal-meson-warnings']) self.init(testdir, extra_args=['--profile-self', '--fatal-meson-warnings'])
obj = mesonbuild.coredata.load(self.builddir) obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins[OptionKey('default_library')].value, 'static') self.assertEqual(obj.options[OptionKey('default_library')].value, 'static')
self.assertEqual(obj.builtins[OptionKey('warning_level')].value, '1') self.assertEqual(obj.options[OptionKey('warning_level')].value, '1')
self.assertEqual(obj.user_options[OptionKey('set_sub_opt')].value, True) self.assertEqual(obj.options[OptionKey('set_sub_opt')].value, True)
self.assertEqual(obj.user_options[OptionKey('subp_opt', 'subp')].value, 'default3') self.assertEqual(obj.options[OptionKey('subp_opt', 'subp')].value, 'default3')
self.wipe() self.wipe()
# warning_level is special, it's --warnlevel instead of --warning-level # warning_level is special, it's --warnlevel instead of --warning-level
# for historical reasons # for historical reasons
self.init(testdir, extra_args=['--warnlevel=2', '--fatal-meson-warnings']) self.init(testdir, extra_args=['--warnlevel=2', '--fatal-meson-warnings'])
obj = mesonbuild.coredata.load(self.builddir) obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins[OptionKey('warning_level')].value, '2') self.assertEqual(obj.options[OptionKey('warning_level')].value, '2')
self.setconf('--warnlevel=3') self.setconf('--warnlevel=3')
obj = mesonbuild.coredata.load(self.builddir) obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins[OptionKey('warning_level')].value, '3') self.assertEqual(obj.options[OptionKey('warning_level')].value, '3')
self.wipe() self.wipe()
# But when using -D syntax, it should be 'warning_level' # But when using -D syntax, it should be 'warning_level'
self.init(testdir, extra_args=['-Dwarning_level=2', '--fatal-meson-warnings']) self.init(testdir, extra_args=['-Dwarning_level=2', '--fatal-meson-warnings'])
obj = mesonbuild.coredata.load(self.builddir) obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins[OptionKey('warning_level')].value, '2') self.assertEqual(obj.options[OptionKey('warning_level')].value, '2')
self.setconf('-Dwarning_level=3') self.setconf('-Dwarning_level=3')
obj = mesonbuild.coredata.load(self.builddir) obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins[OptionKey('warning_level')].value, '3') self.assertEqual(obj.options[OptionKey('warning_level')].value, '3')
self.wipe() self.wipe()
# Mixing --option and -Doption is forbidden # Mixing --option and -Doption is forbidden
@ -3734,15 +3734,15 @@ class AllPlatformTests(BasePlatformTests):
# --default-library should override default value from project() # --default-library should override default value from project()
self.init(testdir, extra_args=['--default-library=both', '--fatal-meson-warnings']) self.init(testdir, extra_args=['--default-library=both', '--fatal-meson-warnings'])
obj = mesonbuild.coredata.load(self.builddir) obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins[OptionKey('default_library')].value, 'both') self.assertEqual(obj.options[OptionKey('default_library')].value, 'both')
self.setconf('--default-library=shared') self.setconf('--default-library=shared')
obj = mesonbuild.coredata.load(self.builddir) obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins[OptionKey('default_library')].value, 'shared') self.assertEqual(obj.options[OptionKey('default_library')].value, 'shared')
if self.backend is Backend.ninja: if self.backend is Backend.ninja:
# reconfigure target works only with ninja backend # reconfigure target works only with ninja backend
self.build('reconfigure') self.build('reconfigure')
obj = mesonbuild.coredata.load(self.builddir) obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins[OptionKey('default_library')].value, 'shared') self.assertEqual(obj.options[OptionKey('default_library')].value, 'shared')
self.wipe() self.wipe()
# Should warn on unknown options # Should warn on unknown options
@ -3777,22 +3777,22 @@ class AllPlatformTests(BasePlatformTests):
# Test we can set subproject option # Test we can set subproject option
self.init(testdir, extra_args=['-Dsubp:subp_opt=foo', '--fatal-meson-warnings']) self.init(testdir, extra_args=['-Dsubp:subp_opt=foo', '--fatal-meson-warnings'])
obj = mesonbuild.coredata.load(self.builddir) obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.user_options[OptionKey('subp_opt', 'subp')].value, 'foo') self.assertEqual(obj.options[OptionKey('subp_opt', 'subp')].value, 'foo')
self.wipe() self.wipe()
# c_args value should be parsed with split_args # c_args value should be parsed with split_args
self.init(testdir, extra_args=['-Dc_args=-Dfoo -Dbar "-Dthird=one two"', '--fatal-meson-warnings']) self.init(testdir, extra_args=['-Dc_args=-Dfoo -Dbar "-Dthird=one two"', '--fatal-meson-warnings'])
obj = mesonbuild.coredata.load(self.builddir) obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.compiler_options[OptionKey('args', lang='c')].value, ['-Dfoo', '-Dbar', '-Dthird=one two']) self.assertEqual(obj.options[OptionKey('args', lang='c')].value, ['-Dfoo', '-Dbar', '-Dthird=one two'])
self.setconf('-Dc_args="foo bar" one two') self.setconf('-Dc_args="foo bar" one two')
obj = mesonbuild.coredata.load(self.builddir) obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.compiler_options[OptionKey('args', lang='c')].value, ['foo bar', 'one', 'two']) self.assertEqual(obj.options[OptionKey('args', lang='c')].value, ['foo bar', 'one', 'two'])
self.wipe() self.wipe()
self.init(testdir, extra_args=['-Dset_percent_opt=myoption%', '--fatal-meson-warnings']) self.init(testdir, extra_args=['-Dset_percent_opt=myoption%', '--fatal-meson-warnings'])
obj = mesonbuild.coredata.load(self.builddir) obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.user_options[OptionKey('set_percent_opt')].value, 'myoption%') self.assertEqual(obj.options[OptionKey('set_percent_opt')].value, 'myoption%')
self.wipe() self.wipe()
# Setting a 2nd time the same option should override the first value # Setting a 2nd time the same option should override the first value
@ -3803,19 +3803,19 @@ class AllPlatformTests(BasePlatformTests):
'-Dc_args=-Dfoo', '-Dc_args=-Dbar', '-Dc_args=-Dfoo', '-Dc_args=-Dbar',
'-Db_lundef=false', '--fatal-meson-warnings']) '-Db_lundef=false', '--fatal-meson-warnings'])
obj = mesonbuild.coredata.load(self.builddir) obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins[OptionKey('bindir')].value, 'bar') self.assertEqual(obj.options[OptionKey('bindir')].value, 'bar')
self.assertEqual(obj.builtins[OptionKey('buildtype')].value, 'release') self.assertEqual(obj.options[OptionKey('buildtype')].value, 'release')
self.assertEqual(obj.base_options[OptionKey('b_sanitize')].value, 'thread') self.assertEqual(obj.options[OptionKey('b_sanitize')].value, 'thread')
self.assertEqual(obj.compiler_options[OptionKey('args', lang='c')].value, ['-Dbar']) self.assertEqual(obj.options[OptionKey('args', lang='c')].value, ['-Dbar'])
self.setconf(['--bindir=bar', '--bindir=foo', self.setconf(['--bindir=bar', '--bindir=foo',
'-Dbuildtype=release', '-Dbuildtype=plain', '-Dbuildtype=release', '-Dbuildtype=plain',
'-Db_sanitize=thread', '-Db_sanitize=address', '-Db_sanitize=thread', '-Db_sanitize=address',
'-Dc_args=-Dbar', '-Dc_args=-Dfoo']) '-Dc_args=-Dbar', '-Dc_args=-Dfoo'])
obj = mesonbuild.coredata.load(self.builddir) obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins[OptionKey('bindir')].value, 'foo') self.assertEqual(obj.options[OptionKey('bindir')].value, 'foo')
self.assertEqual(obj.builtins[OptionKey('buildtype')].value, 'plain') self.assertEqual(obj.options[OptionKey('buildtype')].value, 'plain')
self.assertEqual(obj.base_options[OptionKey('b_sanitize')].value, 'address') self.assertEqual(obj.options[OptionKey('b_sanitize')].value, 'address')
self.assertEqual(obj.compiler_options[OptionKey('args', lang='c')].value, ['-Dfoo']) self.assertEqual(obj.options[OptionKey('args', lang='c')].value, ['-Dfoo'])
self.wipe() self.wipe()
except KeyError: except KeyError:
# Ignore KeyError, it happens on CI for compilers that does not # Ignore KeyError, it happens on CI for compilers that does not
@ -3829,25 +3829,25 @@ class AllPlatformTests(BasePlatformTests):
# Verify default values when passing no args # Verify default values when passing no args
self.init(testdir) self.init(testdir)
obj = mesonbuild.coredata.load(self.builddir) obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins[OptionKey('warning_level')].value, '0') self.assertEqual(obj.options[OptionKey('warning_level')].value, '0')
self.wipe() self.wipe()
# verify we can override w/ --warnlevel # verify we can override w/ --warnlevel
self.init(testdir, extra_args=['--warnlevel=1']) self.init(testdir, extra_args=['--warnlevel=1'])
obj = mesonbuild.coredata.load(self.builddir) obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins[OptionKey('warning_level')].value, '1') self.assertEqual(obj.options[OptionKey('warning_level')].value, '1')
self.setconf('--warnlevel=0') self.setconf('--warnlevel=0')
obj = mesonbuild.coredata.load(self.builddir) obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins[OptionKey('warning_level')].value, '0') self.assertEqual(obj.options[OptionKey('warning_level')].value, '0')
self.wipe() self.wipe()
# verify we can override w/ -Dwarning_level # verify we can override w/ -Dwarning_level
self.init(testdir, extra_args=['-Dwarning_level=1']) self.init(testdir, extra_args=['-Dwarning_level=1'])
obj = mesonbuild.coredata.load(self.builddir) obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins[OptionKey('warning_level')].value, '1') self.assertEqual(obj.options[OptionKey('warning_level')].value, '1')
self.setconf('-Dwarning_level=0') self.setconf('-Dwarning_level=0')
obj = mesonbuild.coredata.load(self.builddir) obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins[OptionKey('warning_level')].value, '0') self.assertEqual(obj.options[OptionKey('warning_level')].value, '0')
self.wipe() self.wipe()
def test_feature_check_usage_subprojects(self): def test_feature_check_usage_subprojects(self):
@ -4254,7 +4254,8 @@ class AllPlatformTests(BasePlatformTests):
self.init(testdir, default_args=False) self.init(testdir, default_args=False)
res_wb = self.introspect('--buildoptions') res_wb = self.introspect('--buildoptions')
self.maxDiff = None self.maxDiff = None
self.assertListEqual(res_nb, res_wb) # XXX: These now generate in a different order, is that okay?
self.assertListEqual(sorted(res_nb, key=lambda x: x['name']), sorted(res_wb, key=lambda x: x['name']))
def test_meson_configure_from_source_does_not_crash(self): def test_meson_configure_from_source_does_not_crash(self):
testdir = os.path.join(self.unit_test_dir, '59 introspect buildoptions') testdir = os.path.join(self.unit_test_dir, '59 introspect buildoptions')
@ -4505,20 +4506,20 @@ class AllPlatformTests(BasePlatformTests):
with open(introfile, 'r') as fp: with open(introfile, 'r') as fp:
res1 = json.load(fp) res1 = json.load(fp)
self.setconf('-Dcpp_std=c++14') for i in res1:
self.setconf('-Dbuildtype=release')
for idx, i in enumerate(res1):
if i['name'] == 'cpp_std': if i['name'] == 'cpp_std':
res1[idx]['value'] = 'c++14' i['value'] = 'c++14'
if i['name'] == 'build.cpp_std': if i['name'] == 'build.cpp_std':
res1[idx]['value'] = 'c++14' i['value'] = 'c++14'
if i['name'] == 'buildtype': if i['name'] == 'buildtype':
res1[idx]['value'] = 'release' i['value'] = 'release'
if i['name'] == 'optimization': if i['name'] == 'optimization':
res1[idx]['value'] = '3' i['value'] = '3'
if i['name'] == 'debug': if i['name'] == 'debug':
res1[idx]['value'] = False i['value'] = False
self.setconf('-Dcpp_std=c++14')
self.setconf('-Dbuildtype=release')
with open(introfile, 'r') as fp: with open(introfile, 'r') as fp:
res2 = json.load(fp) res2 = json.load(fp)

Loading…
Cancel
Save