diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index d46dfacbaeb6..e1c6d0ca863b 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -1091,7 +1091,7 @@ def should_use_dyndeps_for_target(self, target: 'build.BuildTarget') -> bool: 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 @@ def generate_cython_transpile(self, target: build.BuildTarget) -> \ 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 2187b8fa02cc..a12963cdee06 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -1011,8 +1011,8 @@ def get_args_defines_and_inc_dirs(self, target, compiler, generated_files_includ 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 @@ def add_non_makefile_vcxproj_elements( # 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 c86b6661336c..f40e8f70eaa7 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -652,10 +652,20 @@ def process_kwargs_base(self, kwargs: T.Dict[str, T.Any]) -> None: 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 @@ def process_compilers(self) -> T.List[str]: 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 1f82f875b32a..7071fe4f8a4f 100644 --- a/mesonbuild/cmake/interpreter.py +++ b/mesonbuild/cmake/interpreter.py @@ -535,7 +535,7 @@ def _all_source_suffixes(self) -> 'ImmutableListProtocol[str]': @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 bfadcdb35920..819ef8bb8628 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -310,7 +310,7 @@ def get_options(self) -> 'MutableKeyedOptionDictType': 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 247d7e1c0f41..7057fc2a2662 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -1355,7 +1355,7 @@ def get_preprocessor(self) -> Compiler: 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 ed840e6d53c2..1f095245514c 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -475,7 +475,7 @@ def get_options(self) -> 'MutableKeyedOptionDictType': 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 @@ def get_options(self) -> 'MutableKeyedOptionDictType': 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 2fd6d17c94f7..090c1ab94bae 100644 --- a/mesonbuild/compilers/cuda.py +++ b/mesonbuild/compilers/cuda.py @@ -664,7 +664,7 @@ def _to_host_compiler_options(self, master_options: 'KeyedOptionDictType') -> 'K # 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 7f853f221bbd..66f419cf02d8 100644 --- a/mesonbuild/compilers/mixins/elbrus.py +++ b/mesonbuild/compilers/mixins/elbrus.py @@ -85,7 +85,7 @@ def get_pch_suffix(self) -> str: 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 f8d15634470c..33b6134a344f 100644 --- a/mesonbuild/compilers/mixins/emscripten.py +++ b/mesonbuild/compilers/mixins/emscripten.py @@ -51,7 +51,7 @@ def _get_compile_output(self, dirname: str, mode: CompileCheckMode) -> str: 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 @@ def get_options(self) -> coredata.MutableKeyedOptionDictType: 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 7846f04f4295..37958d8a00c1 100644 --- a/mesonbuild/compilers/objc.py +++ b/mesonbuild/compilers/objc.py @@ -82,7 +82,7 @@ def get_options(self) -> 'coredata.MutableKeyedOptionDictType': 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 @@ def get_options(self) -> 'coredata.MutableKeyedOptionDictType': 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 af10c838906f..6388d41c3f37 100644 --- a/mesonbuild/compilers/objcpp.py +++ b/mesonbuild/compilers/objcpp.py @@ -82,7 +82,7 @@ def get_options(self) -> coredata.MutableKeyedOptionDictType: 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 @@ def get_options(self) -> coredata.MutableKeyedOptionDictType: 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 5150e6927c2c..8c797cdb80c9 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -568,20 +568,19 @@ def _set_others_from_buildtype(self, value: str) -> bool: 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 @@ def add_lang_args(self, lang: str, comp: T.Type['Compiler'], # 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 @@ def __getitem__(self, key: OptionKey) -> options.UserOption: # 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 de4dec8fe287..d316f4f6634b 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -743,14 +743,12 @@ def _set_default_options_from_env(self) -> None: # 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 @@ def _set_default_options_from_env(self) -> None: # 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 e1b9eb27b1ba..94d7e5da6885 100644 --- a/mesonbuild/modules/__init__.py +++ b/mesonbuild/modules/__init__.py @@ -133,15 +133,14 @@ def test(self, args: T.Tuple[str, T.Union[build.Executable, build.Jar, 'External 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 a8e22541c164..2e5f16f3c459 100644 --- a/mesonbuild/modules/rust.py +++ b/mesonbuild/modules/rust.py @@ -269,7 +269,7 @@ def bindgen(self, state: ModuleState, args: T.List, kwargs: FuncBindgen) -> Modu 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 @@ def bindgen(self, state: ModuleState, args: T.List, kwargs: FuncBindgen) -> Modu # 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 013fd1ad6196..e50aa431f1c5 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 @@ def __init__(self, name: str, subproject: str = '', 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 @@ def __getstate__(self) -> T.Dict[str, T.Any]: 'name': self.name, 'subproject': self.subproject, 'machine': self.machine, - 'lang': self.lang, 'module': self.module, } @@ -141,7 +137,7 @@ def __hash__(self) -> int: 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 @@ def __lt__(self, other: object) -> bool: 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 @@ def __str__(self) -> str: 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 @@ def from_string(cls, raw: str) -> '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 @@ def evolve(self, name: T.Optional[str] = None, subproject: T.Optional[str] = Non 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 @@ def get_value(self, key: T.Union[OptionKey, str]) -> 'T.Any': 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 @@ def values(self): 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 @@ def is_project_option(self, key: OptionKey) -> bool: 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 @@ def is_reserved_name(self, key: OptionKey) -> bool: # 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 @@ def is_backend_option(self, key: OptionKey) -> bool: 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 d32a5ac74caf..4e22028b830c 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 b96925e6aa40..726252611fb7 100644 --- a/unittests/allplatformstests.py +++ b/unittests/allplatformstests.py @@ -2725,11 +2725,11 @@ def test_command_line(self): # 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 @@ def test_command_line(self): 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 @@ def test_command_line(self): 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 bbdf2d9b7334..ada6602eefcf 100644 --- a/unittests/internaltests.py +++ b/unittests/internaltests.py @@ -626,7 +626,7 @@ def create_static_lib(name): 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 @@ def test_major_versions_differ(self) -> None: 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 6a751dd51d07..16997e393339 100644 --- a/unittests/linuxliketests.py +++ b/unittests/linuxliketests.py @@ -486,7 +486,7 @@ def _test_stds_impl(self, testdir: str, compiler: 'Compiler') -> None: # 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