summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/backend/ninjabackend.py4
-rw-r--r--mesonbuild/backend/vs2010backend.py6
-rw-r--r--mesonbuild/build.py14
-rw-r--r--mesonbuild/cmake/interpreter.py2
-rw-r--r--mesonbuild/compilers/c.py2
-rw-r--r--mesonbuild/compilers/compilers.py8
-rw-r--r--mesonbuild/compilers/cpp.py16
-rw-r--r--mesonbuild/compilers/cuda.py2
-rw-r--r--mesonbuild/compilers/mixins/elbrus.py2
-rw-r--r--mesonbuild/compilers/mixins/emscripten.py4
-rw-r--r--mesonbuild/compilers/objc.py4
-rw-r--r--mesonbuild/compilers/objcpp.py4
-rw-r--r--mesonbuild/coredata.py14
-rw-r--r--mesonbuild/environment.py9
-rw-r--r--mesonbuild/modules/__init__.py5
-rw-r--r--mesonbuild/modules/rust.py4
-rw-r--r--mesonbuild/options.py52
-rwxr-xr-xrun_tests.py2
-rw-r--r--unittests/allplatformstests.py8
-rw-r--r--unittests/internaltests.py6
-rw-r--r--unittests/linuxliketests.py2
21 files changed, 93 insertions, 77 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index d46dfacba..e1c6d0ca8 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -1091,7 +1091,7 @@ class NinjaBackend(backends.Backend):
cpp = target.compilers['cpp']
if cpp.get_id() != 'msvc':
return False
- cppversion = target.get_option(OptionKey('std', machine=target.for_machine, lang='cpp'))
+ cppversion = target.get_option(OptionKey('cpp_std', machine=target.for_machine))
if cppversion not in ('latest', 'c++latest', 'vc++latest'):
return False
if not mesonlib.current_vs_supports_modules():
@@ -1783,7 +1783,7 @@ class NinjaBackend(backends.Backend):
args += self.build.get_project_args(cython, target.subproject, target.for_machine)
args += target.get_extra_args('cython')
- ext = target.get_option(OptionKey('language', machine=target.for_machine, lang='cython'))
+ ext = target.get_option(OptionKey('cython_language', machine=target.for_machine))
pyx_sources = [] # Keep track of sources we're adding to build
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index 2187b8fa0..a12963cde 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -1011,8 +1011,8 @@ class Vs2010Backend(backends.Backend):
file_args[l] += args
# 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.
- for l in file_args.keys():
- file_args[l] += target.get_option(OptionKey('args', machine=target.for_machine, lang=l))
+ for lang in file_args.keys():
+ file_args[lang] += target.get_option(OptionKey(f'{lang}_args', machine=target.for_machine))
for args in file_args.values():
# This is where Visual Studio will insert target_args, target_defines,
# etc, which are added later from external deps (see below).
@@ -1340,7 +1340,7 @@ class Vs2010Backend(backends.Backend):
# 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
if 'cpp' in target.compilers:
- eh = target.get_option(OptionKey('eh', machine=target.for_machine, lang='cpp'))
+ eh = target.get_option(OptionKey('cpp_eh', machine=target.for_machine))
if eh == 'a':
ET.SubElement(clconf, 'ExceptionHandling').text = 'Async'
elif eh == 's':
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index c86b66613..f40e8f70e 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -652,10 +652,20 @@ class Target(HoldableObject, metaclass=abc.ABCMeta):
self.set_option_overrides(self.parse_overrides(kwargs))
+ def is_compiler_option_hack(self, key):
+ # FIXME this method must be deleted when OptionsView goes away.
+ # At that point the build target only stores the original string.
+ # The decision on how to use those pieces of data is done elsewhere.
+ from .compilers import all_languages
+ if '_' not in key.name:
+ return False
+ prefix = key.name.split('_')[0]
+ return prefix in all_languages
+
def set_option_overrides(self, option_overrides: T.Dict[OptionKey, str]) -> None:
self.options.overrides = {}
for k, v in option_overrides.items():
- if k.lang:
+ if self.is_compiler_option_hack(k):
self.options.overrides[k.evolve(machine=self.for_machine)] = v
else:
self.options.overrides[k] = v
@@ -1002,7 +1012,7 @@ class BuildTarget(Target):
if 'vala' in self.compilers and 'c' not in self.compilers:
self.compilers['c'] = self.all_compilers['c']
if 'cython' in self.compilers:
- key = OptionKey('language', machine=self.for_machine, lang='cython')
+ key = OptionKey('cython_language', machine=self.for_machine)
value = self.get_option(key)
try:
diff --git a/mesonbuild/cmake/interpreter.py b/mesonbuild/cmake/interpreter.py
index 1f82f875b..7071fe4f8 100644
--- a/mesonbuild/cmake/interpreter.py
+++ b/mesonbuild/cmake/interpreter.py
@@ -535,7 +535,7 @@ class ConverterTarget:
@lru_cache(maxsize=None)
def _all_lang_stds(self, lang: str) -> 'ImmutableListProtocol[str]':
try:
- res = self.env.coredata.optstore.get_value_object(OptionKey('std', machine=MachineChoice.BUILD, lang=lang)).choices
+ res = self.env.coredata.optstore.get_value_object(OptionKey(f'{lang}_std', machine=MachineChoice.BUILD)).choices
except KeyError:
return []
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index bfadcdb35..819ef8bb8 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -310,7 +310,7 @@ class GnuCCompiler(GnuCompiler, CCompiler):
self.update_options(
opts,
self.create_option(options.UserArrayOption,
- key.evolve('winlibs'),
+ key.evolve('c_winlibs'),
'Standard Win libraries to link against',
gnu_winlibs),
)
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index 247d7e1c0..7057fc2a2 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -1355,7 +1355,7 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
raise EnvironmentException(f'{self.get_id()} does not support preprocessor')
def form_compileropt_key(self, basename: str) -> OptionKey:
- return OptionKey(basename, machine=self.for_machine, lang=self.language)
+ return OptionKey(f'{self.language}_{basename}', machine=self.for_machine)
def get_global_options(lang: str,
comp: T.Type[Compiler],
@@ -1363,9 +1363,9 @@ def get_global_options(lang: str,
env: 'Environment') -> 'dict[OptionKey, options.UserOption[Any]]':
"""Retrieve options that apply to all compilers for a given language."""
description = f'Extra arguments passed to the {lang}'
- argkey = OptionKey('args', lang=lang, machine=for_machine)
- largkey = argkey.evolve('link_args')
- envkey = argkey.evolve('env_args')
+ argkey = OptionKey(f'{lang}_args', machine=for_machine)
+ largkey = argkey.evolve(f'{lang}_link_args')
+ envkey = argkey.evolve(f'{lang}_env_args')
comp_key = argkey if argkey in env.options else envkey
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index ed840e6d5..1f0952455 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -475,7 +475,7 @@ class GnuCPPCompiler(_StdCPPLibMixin, GnuCompiler, CPPCompiler):
self.update_options(
opts,
self.create_option(options.UserArrayOption,
- key.evolve('winlibs'),
+ key.evolve('cpp_winlibs'),
'Standard Win libraries to link against',
gnu_winlibs),
)
@@ -483,17 +483,21 @@ class GnuCPPCompiler(_StdCPPLibMixin, GnuCompiler, CPPCompiler):
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args: T.List[str] = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ stdkey = self.form_compileropt_key('std')
+ ehkey = self.form_compileropt_key('eh')
+ rttikey = self.form_compileropt_key('rtti')
+ debugstlkey = self.form_compileropt_key('debugstl')
+
+ std = options.get_value(stdkey)
if std != 'none':
args.append(self._find_best_cpp_std(std))
- non_msvc_eh_options(options.get_value(key.evolve('eh')), args)
+ non_msvc_eh_options(options.get_value(ehkey), args)
- if not options.get_value(key.evolve('rtti')):
+ if not options.get_value(rttikey):
args.append('-fno-rtti')
- if options.get_value(key.evolve('debugstl')):
+ if options.get_value(debugstlkey):
args.append('-D_GLIBCXX_DEBUG=1')
return args
diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py
index 2fd6d17c9..090c1ab94 100644
--- a/mesonbuild/compilers/cuda.py
+++ b/mesonbuild/compilers/cuda.py
@@ -664,7 +664,7 @@ class CudaCompiler(Compiler):
# We must strip the -std option from the host compiler option set, as NVCC has
# its own -std flag that may not agree with the host compiler's.
host_options = {key: master_options.get(key, opt) for key, opt in self.host_compiler.get_options().items()}
- std_key = OptionKey('std', machine=self.for_machine, lang=self.host_compiler.language)
+ std_key = OptionKey(f'{self.host_compiler.language}_std', machine=self.for_machine)
overrides = {std_key: 'none'}
# To shut up mypy.
return coredata.OptionsView(host_options, overrides=overrides)
diff --git a/mesonbuild/compilers/mixins/elbrus.py b/mesonbuild/compilers/mixins/elbrus.py
index 7f853f221..66f419cf0 100644
--- a/mesonbuild/compilers/mixins/elbrus.py
+++ b/mesonbuild/compilers/mixins/elbrus.py
@@ -85,7 +85,7 @@ class ElbrusCompiler(GnuLikeCompiler):
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args: T.List[str] = []
- std = options.get_value(OptionKey('std', lang=self.language, machine=self.for_machine))
+ std = options.get_value(OptionKey(f'{self.language}_std', machine=self.for_machine))
if std != 'none':
args.append('-std=' + std)
return args
diff --git a/mesonbuild/compilers/mixins/emscripten.py b/mesonbuild/compilers/mixins/emscripten.py
index f8d156344..33b6134a3 100644
--- a/mesonbuild/compilers/mixins/emscripten.py
+++ b/mesonbuild/compilers/mixins/emscripten.py
@@ -51,7 +51,7 @@ class EmscriptenMixin(Compiler):
def thread_link_flags(self, env: 'Environment') -> T.List[str]:
args = ['-pthread']
- count: int = env.coredata.optstore.get_value(OptionKey('thread_count', lang=self.language, machine=self.for_machine))
+ count: int = env.coredata.optstore.get_value(OptionKey(f'{self.language}_thread_count', machine=self.for_machine))
if count:
args.append(f'-sPTHREAD_POOL_SIZE={count}')
return args
@@ -61,7 +61,7 @@ class EmscriptenMixin(Compiler):
super().get_options(),
self.create_option(
options.UserIntegerOption,
- OptionKey('thread_count', machine=self.for_machine, lang=self.language),
+ OptionKey(f'{self.language}_thread_count', machine=self.for_machine),
'Number of threads to use in web assembly, set to 0 to disable',
(0, None, 4), # Default was picked at random
),
diff --git a/mesonbuild/compilers/objc.py b/mesonbuild/compilers/objc.py
index 7846f04f4..37958d8a0 100644
--- a/mesonbuild/compilers/objc.py
+++ b/mesonbuild/compilers/objc.py
@@ -82,7 +82,7 @@ class ClangObjCCompiler(ClangCompiler, ObjCCompiler):
return self.update_options(
super().get_options(),
self.create_option(options.UserComboOption,
- OptionKey('std', machine=self.for_machine, lang='c'),
+ OptionKey('c_std', machine=self.for_machine),
'C language standard to use',
['none', 'c89', 'c99', 'c11', 'c17', 'gnu89', 'gnu99', 'gnu11', 'gnu17'],
'none'),
@@ -90,7 +90,7 @@ class ClangObjCCompiler(ClangCompiler, ObjCCompiler):
def get_option_compile_args(self, options: 'coredata.KeyedOptionDictType') -> T.List[str]:
args = []
- std = options.get_value(OptionKey('std', machine=self.for_machine, lang='c'))
+ std = options.get_value(OptionKey('c_std', machine=self.for_machine))
if std != 'none':
args.append('-std=' + std)
return args
diff --git a/mesonbuild/compilers/objcpp.py b/mesonbuild/compilers/objcpp.py
index af10c8389..6388d41c3 100644
--- a/mesonbuild/compilers/objcpp.py
+++ b/mesonbuild/compilers/objcpp.py
@@ -82,7 +82,7 @@ class ClangObjCPPCompiler(ClangCompiler, ObjCPPCompiler):
return self.update_options(
super().get_options(),
self.create_option(options.UserComboOption,
- OptionKey('std', machine=self.for_machine, lang='cpp'),
+ OptionKey('cpp_std', machine=self.for_machine),
'C++ language standard to use',
['none', 'c++98', 'c++11', 'c++14', 'c++17', 'c++20', 'c++2b',
'gnu++98', 'gnu++11', 'gnu++14', 'gnu++17', 'gnu++20',
@@ -92,7 +92,7 @@ class ClangObjCPPCompiler(ClangCompiler, ObjCPPCompiler):
def get_option_compile_args(self, options: 'coredata.KeyedOptionDictType') -> T.List[str]:
args = []
- std = options.get_value(OptionKey('std', machine=self.for_machine, lang='cpp'))
+ std = options.get_value(OptionKey('cpp_std', machine=self.for_machine))
if std != 'none':
args.append('-std=' + std)
return args
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 5150e6927..8c797cdb8 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -568,20 +568,19 @@ class CoreData:
return dirty
- @staticmethod
- def is_per_machine_option(optname: OptionKey) -> bool:
+ def is_per_machine_option(self, optname: OptionKey) -> bool:
if optname.as_host() in options.BUILTIN_OPTIONS_PER_MACHINE:
return True
- return optname.lang is not None
+ return self.optstore.is_compiler_option(optname)
def get_external_args(self, for_machine: MachineChoice, lang: str) -> T.List[str]:
# mypy cannot analyze type of OptionKey
- key = OptionKey('args', machine=for_machine, lang=lang)
+ key = OptionKey(f'{lang}_args', machine=for_machine)
return T.cast('T.List[str]', self.optstore.get_value(key))
def get_external_link_args(self, for_machine: MachineChoice, lang: str) -> T.List[str]:
# mypy cannot analyze type of OptionKey
- key = OptionKey('link_args', machine=for_machine, lang=lang)
+ key = OptionKey(f'{lang}_link_args', machine=for_machine)
return T.cast('T.List[str]', self.optstore.get_value(key))
def update_project_options(self, project_options: 'MutableKeyedOptionDictType', subproject: SubProject) -> None:
@@ -732,7 +731,8 @@ class CoreData:
# These options are all new at this point, because the compiler is
# responsible for adding its own options, thus calling
# `self.optstore.update()`` is perfectly safe.
- self.optstore.update(compilers.get_global_options(lang, comp, for_machine, env))
+ for gopt_key, gopt_valobj in compilers.get_global_options(lang, comp, for_machine, env).items():
+ self.optstore.add_compiler_option(lang, gopt_key, gopt_valobj)
def process_compiler_options(self, lang: str, comp: Compiler, env: Environment, subproject: str) -> None:
from . import compilers
@@ -924,7 +924,7 @@ class OptionsView(abc.Mapping):
# to hold overrides.
if isinstance(self.original_options, options.OptionStore):
if key2 not in self.original_options:
- raise KeyError
+ raise KeyError(f'{key} {key2}')
opt = self.original_options.get_value_object(key2)
else:
opt = self.original_options[key2]
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index de4dec8fe..d316f4f66 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -743,14 +743,12 @@ class Environment:
# if it changes on future invocations.
if self.first_invocation:
if keyname == 'ldflags':
- key = OptionKey('link_args', machine=for_machine, lang='c') # needs a language to initialize properly
for lang in compilers.compilers.LANGUAGES_USING_LDFLAGS:
- key = key.evolve(lang=lang)
+ key = OptionKey(name=f'{lang}_link_args', machine=for_machine)
env_opts[key].extend(p_list)
elif keyname == 'cppflags':
- key = OptionKey('env_args', machine=for_machine, lang='c')
for lang in compilers.compilers.LANGUAGES_USING_CPPFLAGS:
- key = key.evolve(lang=lang)
+ key = OptionKey(f'{lang}_env_args', machine=for_machine)
env_opts[key].extend(p_list)
else:
key = OptionKey.from_string(keyname).evolve(machine=for_machine)
@@ -770,7 +768,8 @@ class Environment:
# We still use the original key as the base here, as
# we want to inherit the machine and the compiler
# language
- key = key.evolve('env_args')
+ lang = key.name.split('_', 1)[0]
+ key = key.evolve(f'{lang}_env_args')
env_opts[key].extend(p_list)
# Only store options that are not already in self.options,
diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py
index e1b9eb27b..94d7e5da6 100644
--- a/mesonbuild/modules/__init__.py
+++ b/mesonbuild/modules/__init__.py
@@ -133,15 +133,14 @@ class ModuleState:
def get_option(self, name: str, subproject: str = '',
machine: MachineChoice = MachineChoice.HOST,
- lang: T.Optional[str] = None,
module: T.Optional[str] = None) -> T.Union[T.List[str], str, int, bool]:
- return self.environment.coredata.get_option(OptionKey(name, subproject, machine, lang, module))
+ return self.environment.coredata.get_option(OptionKey(name, subproject, machine, module))
def is_user_defined_option(self, name: str, subproject: str = '',
machine: MachineChoice = MachineChoice.HOST,
lang: T.Optional[str] = None,
module: T.Optional[str] = None) -> bool:
- key = OptionKey(name, subproject, machine, lang, module)
+ key = OptionKey(name, subproject, machine, module)
return key in self._interpreter.user_defined_options.cmd_line_options
def process_include_dirs(self, dirs: T.Iterable[T.Union[str, IncludeDirs]]) -> T.Iterable[IncludeDirs]:
diff --git a/mesonbuild/modules/rust.py b/mesonbuild/modules/rust.py
index a8e22541c..2e5f16f3c 100644
--- a/mesonbuild/modules/rust.py
+++ b/mesonbuild/modules/rust.py
@@ -269,7 +269,7 @@ class RustModule(ExtensionModule):
raise InterpreterException(f'Unknown file type extension for: {name}')
# We only want include directories and defines, other things may not be valid
- cargs = state.get_option('args', state.subproject, lang=language)
+ cargs = state.get_option(f'{language}_args', state.subproject)
assert isinstance(cargs, list), 'for mypy'
for a in itertools.chain(state.global_args.get(language, []), state.project_args.get(language, []), cargs):
if a.startswith(('-I', '/I', '-D', '/D', '-U', '/U')):
@@ -280,7 +280,7 @@ class RustModule(ExtensionModule):
# Add the C++ standard to the clang arguments. Attempt to translate VS
# extension versions into the nearest standard version
- std = state.get_option('std', lang=language)
+ std = state.get_option(f'{language}_std')
assert isinstance(std, str), 'for mypy'
if std.startswith('vc++'):
if std.endswith('latest'):
diff --git a/mesonbuild/options.py b/mesonbuild/options.py
index 013fd1ad6..e50aa431f 100644
--- a/mesonbuild/options.py
+++ b/mesonbuild/options.py
@@ -90,18 +90,16 @@ class OptionKey:
internally easier to reason about and produce.
"""
- __slots__ = ['name', 'subproject', 'machine', 'lang', '_hash', 'module']
+ __slots__ = ['name', 'subproject', 'machine', '_hash', 'module']
name: str
subproject: str
machine: MachineChoice
- lang: T.Optional[str]
_hash: int
module: T.Optional[str]
def __init__(self, name: str, subproject: str = '',
machine: MachineChoice = MachineChoice.HOST,
- lang: T.Optional[str] = None,
module: T.Optional[str] = None):
# the _type option to the constructor is kinda private. We want to be
# able tos ave the state and avoid the lookup function when
@@ -110,9 +108,8 @@ class OptionKey:
object.__setattr__(self, 'name', name)
object.__setattr__(self, 'subproject', subproject)
object.__setattr__(self, 'machine', machine)
- object.__setattr__(self, 'lang', lang)
object.__setattr__(self, 'module', module)
- object.__setattr__(self, '_hash', hash((name, subproject, machine, lang, module)))
+ object.__setattr__(self, '_hash', hash((name, subproject, machine, module)))
def __setattr__(self, key: str, value: T.Any) -> None:
raise AttributeError('OptionKey instances do not support mutation.')
@@ -122,7 +119,6 @@ class OptionKey:
'name': self.name,
'subproject': self.subproject,
'machine': self.machine,
- 'lang': self.lang,
'module': self.module,
}
@@ -141,7 +137,7 @@ class OptionKey:
return self._hash
def _to_tuple(self) -> T.Tuple[str, str, str, MachineChoice, str]:
- return (self.subproject, self.lang or '', self.module or '', self.machine, self.name)
+ return (self.subproject, self.module or '', self.machine, self.name)
def __eq__(self, other: object) -> bool:
if isinstance(other, OptionKey):
@@ -155,8 +151,6 @@ class OptionKey:
def __str__(self) -> str:
out = self.name
- if self.lang:
- out = f'{self.lang}_{out}'
if self.machine is MachineChoice.BUILD:
out = f'build.{out}'
if self.module:
@@ -166,7 +160,7 @@ class OptionKey:
return out
def __repr__(self) -> str:
- return f'OptionKey({self.name!r}, {self.subproject!r}, {self.machine!r}, {self.lang!r}, {self.module!r})'
+ return f'OptionKey({self.name!r}, {self.subproject!r}, {self.machine!r}, {self.module!r})'
@classmethod
def from_string(cls, raw: str) -> 'OptionKey':
@@ -191,18 +185,14 @@ class OptionKey:
except ValueError:
raw3 = raw2
- from .compilers import all_languages
- if any(raw3.startswith(f'{l}_') for l in all_languages):
- lang, opt = raw3.split('_', 1)
- else:
- lang, opt = None, raw3
+ opt = raw3
assert ':' not in opt
assert '.' not in opt
- return cls(opt, subproject, for_machine, lang, module)
+ return cls(opt, subproject, for_machine, module)
def evolve(self, name: T.Optional[str] = None, subproject: T.Optional[str] = None,
- machine: T.Optional[MachineChoice] = None, lang: T.Optional[str] = '',
+ machine: T.Optional[MachineChoice] = None,
module: T.Optional[str] = '') -> 'OptionKey':
"""Create a new copy of this key, but with altered members.
@@ -218,7 +208,6 @@ class OptionKey:
name if name is not None else self.name,
subproject if subproject is not None else self.subproject,
machine if machine is not None else self.machine,
- lang if lang != '' else self.lang,
module if module != '' else self.module
)
@@ -681,6 +670,10 @@ class OptionStore:
def __init__(self):
self.d: T.Dict['OptionKey', 'UserOption[T.Any]'] = {}
self.project_options = set()
+ self.all_languages = set()
+ from .compilers import all_languages
+ for lang in all_languages:
+ self.all_languages.add(lang)
def __len__(self):
return len(self.d)
@@ -698,8 +691,15 @@ class OptionStore:
def add_system_option(self, key: T.Union[OptionKey, str], valobj: 'UserOption[T.Any]'):
key = self.ensure_key(key)
+ assert isinstance(valobj, UserOption)
self.d[key] = valobj
+ def add_compiler_option(self, language: str, key: T.Union[OptionKey, str], valobj: 'UserOption[T.Any]'):
+ key = self.ensure_key(key)
+ if not key.name.startswith(language + '_'):
+ raise MesonException(f'Internal error: all compiler option names must start with language prefix. ({key.name} vs {language}_)')
+ self.add_system_option(key, valobj)
+
def add_project_option(self, key: T.Union[OptionKey, str], valobj: 'UserOption[T.Any]'):
key = self.ensure_key(key)
self.d[key] = valobj
@@ -733,6 +733,7 @@ class OptionStore:
def items(self) -> ItemsView['OptionKey', 'UserOption[T.Any]']:
return self.d.items()
+ # FIXME: this method must be deleted and users moved to use "add_xxx_option"s instead.
def update(self, *args, **kwargs):
return self.d.update(*args, **kwargs)
@@ -749,9 +750,6 @@ class OptionStore:
def is_reserved_name(self, key: OptionKey) -> bool:
if key.name in _BUILTIN_NAMES:
return True
- # FIXME, this hack is needed until the lang field is removed from OptionKey.
- if key.lang is not None:
- return True
if '_' not in key.name:
return False
prefix = key.name.split('_')[0]
@@ -760,8 +758,7 @@ class OptionStore:
# values. It is not, thank you very much.
if prefix in ('b', 'backend'): # pylint: disable=R6201
return True
- from .compilers import all_languages
- if prefix in all_languages:
+ if prefix in self.all_languages:
return True
return False
@@ -779,4 +776,11 @@ class OptionStore:
def is_compiler_option(self, key: OptionKey) -> bool:
"""Convenience method to check if this is a compiler option."""
- return key.lang is not None
+
+ # FIXME, duplicate of is_reserved_name above. Should maybe store a cache instead.
+ if '_' not in key.name:
+ return False
+ prefix = key.name.split('_')[0]
+ if prefix in self.all_languages:
+ return True
+ return False
diff --git a/run_tests.py b/run_tests.py
index d32a5ac74..4e22028b8 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -153,7 +153,7 @@ def get_fake_env(sdir: str = '', bdir: T.Optional[str] = None, prefix: str = '',
if opts is None:
opts = get_fake_options(prefix)
env = Environment(sdir, bdir, opts)
- env.coredata.optstore.set_value_object(OptionKey('args', lang='c'), FakeCompilerOptions())
+ env.coredata.optstore.set_value_object(OptionKey('c_args'), FakeCompilerOptions())
env.machines.host.cpu_family = 'x86_64' # Used on macOS inside find_library
# Invalidate cache when using a different Environment object.
clear_meson_configure_class_caches()
diff --git a/unittests/allplatformstests.py b/unittests/allplatformstests.py
index b96925e6a..726252611 100644
--- a/unittests/allplatformstests.py
+++ b/unittests/allplatformstests.py
@@ -2725,11 +2725,11 @@ class AllPlatformTests(BasePlatformTests):
# c_args value should be parsed with split_args
self.init(testdir, extra_args=['-Dc_args=-Dfoo -Dbar "-Dthird=one two"', '--fatal-meson-warnings'])
obj = mesonbuild.coredata.load(self.builddir)
- self.assertEqual(obj.optstore.get_value(OptionKey('args', lang='c')), ['-Dfoo', '-Dbar', '-Dthird=one two'])
+ self.assertEqual(obj.optstore.get_value(OptionKey('c_args')), ['-Dfoo', '-Dbar', '-Dthird=one two'])
self.setconf('-Dc_args="foo bar" one two')
obj = mesonbuild.coredata.load(self.builddir)
- self.assertEqual(obj.optstore.get_value(OptionKey('args', lang='c')), ['foo bar', 'one', 'two'])
+ self.assertEqual(obj.optstore.get_value(OptionKey('c_args')), ['foo bar', 'one', 'two'])
self.wipe()
self.init(testdir, extra_args=['-Dset_percent_opt=myoption%', '--fatal-meson-warnings'])
@@ -2748,7 +2748,7 @@ class AllPlatformTests(BasePlatformTests):
self.assertEqual(obj.optstore.get_value('bindir'), 'bar')
self.assertEqual(obj.optstore.get_value('buildtype'), 'release')
self.assertEqual(obj.optstore.get_value('b_sanitize'), 'thread')
- self.assertEqual(obj.optstore.get_value(OptionKey('args', lang='c')), ['-Dbar'])
+ self.assertEqual(obj.optstore.get_value(OptionKey('c_args')), ['-Dbar'])
self.setconf(['--bindir=bar', '--bindir=foo',
'-Dbuildtype=release', '-Dbuildtype=plain',
'-Db_sanitize=thread', '-Db_sanitize=address',
@@ -2757,7 +2757,7 @@ class AllPlatformTests(BasePlatformTests):
self.assertEqual(obj.optstore.get_value('bindir'), 'foo')
self.assertEqual(obj.optstore.get_value('buildtype'), 'plain')
self.assertEqual(obj.optstore.get_value('b_sanitize'), 'address')
- self.assertEqual(obj.optstore.get_value(OptionKey('args', lang='c')), ['-Dfoo'])
+ self.assertEqual(obj.optstore.get_value(OptionKey('c_args')), ['-Dfoo'])
self.wipe()
except KeyError:
# Ignore KeyError, it happens on CI for compilers that does not
diff --git a/unittests/internaltests.py b/unittests/internaltests.py
index bbdf2d9b7..ada6602ee 100644
--- a/unittests/internaltests.py
+++ b/unittests/internaltests.py
@@ -626,7 +626,7 @@ class InternalTests(unittest.TestCase):
env = get_fake_env()
compiler = detect_c_compiler(env, MachineChoice.HOST)
env.coredata.compilers.host = {'c': compiler}
- env.coredata.optstore.set_value_object(OptionKey('link_args', lang='c'), FakeCompilerOptions())
+ env.coredata.optstore.set_value_object(OptionKey('c_link_args'), FakeCompilerOptions())
p1 = Path(tmpdir) / '1'
p2 = Path(tmpdir) / '2'
p1.mkdir()
@@ -1704,8 +1704,8 @@ class InternalTests(unittest.TestCase):
def test_option_key_from_string(self) -> None:
cases = [
- ('c_args', OptionKey('args', lang='c')),
- ('build.cpp_args', OptionKey('args', machine=MachineChoice.BUILD, lang='cpp')),
+ ('c_args', OptionKey('c_args')),
+ ('build.cpp_args', OptionKey('cpp_args', machine=MachineChoice.BUILD)),
('prefix', OptionKey('prefix')),
('made_up', OptionKey('made_up')),
diff --git a/unittests/linuxliketests.py b/unittests/linuxliketests.py
index 6a751dd51..16997e393 100644
--- a/unittests/linuxliketests.py
+++ b/unittests/linuxliketests.py
@@ -486,7 +486,7 @@ class LinuxlikeTests(BasePlatformTests):
# Check that all the listed -std=xxx options for this compiler work just fine when used
# https://en.wikipedia.org/wiki/Xcode#Latest_versions
# https://www.gnu.org/software/gcc/projects/cxx-status.html
- key = OptionKey('std', lang=compiler.language)
+ key = OptionKey(f'{compiler.language}_std')
for v in compiler.get_options()[key].choices:
# we do it like this to handle gnu++17,c++17 and gnu17,c17 cleanly
# thus, C++ first