From 61c742fae9ec74e81b3bb3caf815cf49992fb93c Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Fri, 12 Jul 2024 20:57:04 +0300 Subject: [PATCH] Remove language (AKA compiler) type from OptionKey. --- mesonbuild/backend/ninjabackend.py | 4 +- mesonbuild/backend/vs2010backend.py | 6 +-- mesonbuild/build.py | 14 +++++- mesonbuild/cmake/interpreter.py | 2 +- mesonbuild/compilers/c.py | 2 +- mesonbuild/compilers/compilers.py | 8 ++-- mesonbuild/compilers/cpp.py | 16 ++++--- mesonbuild/compilers/cuda.py | 2 +- mesonbuild/compilers/mixins/elbrus.py | 2 +- mesonbuild/compilers/mixins/emscripten.py | 4 +- mesonbuild/compilers/objc.py | 4 +- mesonbuild/compilers/objcpp.py | 4 +- mesonbuild/coredata.py | 14 +++--- mesonbuild/environment.py | 9 ++-- mesonbuild/modules/__init__.py | 5 +-- mesonbuild/modules/rust.py | 4 +- mesonbuild/options.py | 52 ++++++++++++----------- run_tests.py | 2 +- unittests/allplatformstests.py | 8 ++-- unittests/internaltests.py | 6 +-- unittests/linuxliketests.py | 2 +- 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