diff options
Diffstat (limited to 'mesonbuild/compilers')
-rw-r--r-- | mesonbuild/compilers/c.py | 142 | ||||
-rw-r--r-- | mesonbuild/compilers/compilers.py | 133 | ||||
-rw-r--r-- | mesonbuild/compilers/cpp.py | 204 | ||||
-rw-r--r-- | mesonbuild/compilers/cuda.py | 21 | ||||
-rw-r--r-- | mesonbuild/compilers/d.py | 12 | ||||
-rw-r--r-- | mesonbuild/compilers/fortran.py | 42 | ||||
-rw-r--r-- | mesonbuild/compilers/mixins/arm.py | 7 | ||||
-rw-r--r-- | mesonbuild/compilers/mixins/clang.py | 7 | ||||
-rw-r--r-- | mesonbuild/compilers/mixins/clike.py | 7 | ||||
-rw-r--r-- | mesonbuild/compilers/mixins/elbrus.py | 6 | ||||
-rw-r--r-- | mesonbuild/compilers/mixins/emscripten.py | 8 | ||||
-rw-r--r-- | mesonbuild/compilers/mixins/gnu.py | 14 | ||||
-rw-r--r-- | mesonbuild/compilers/mixins/intel.py | 5 | ||||
-rw-r--r-- | mesonbuild/compilers/mixins/islinker.py | 6 | ||||
-rw-r--r-- | mesonbuild/compilers/mixins/pgi.py | 3 | ||||
-rw-r--r-- | mesonbuild/compilers/mixins/visualstudio.py | 2 | ||||
-rw-r--r-- | mesonbuild/compilers/objc.py | 2 | ||||
-rw-r--r-- | mesonbuild/compilers/objcpp.py | 2 | ||||
-rw-r--r-- | mesonbuild/compilers/rust.py | 21 | ||||
-rw-r--r-- | mesonbuild/compilers/swift.py | 2 | ||||
-rw-r--r-- | mesonbuild/compilers/vala.py | 8 |
21 files changed, 360 insertions, 294 deletions
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index 985f6f3..311e65a 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -16,7 +16,7 @@ import os.path import typing as T from .. import coredata -from ..mesonlib import MachineChoice, MesonException, mlog, version_compare +from ..mesonlib import MachineChoice, MesonException, mlog, version_compare, OptionKey from ..linkers import LinkerEnvVarsMixin from .c_function_attributes import C_FUNC_ATTRIBUTES from .mixins.clike import CLikeCompiler @@ -39,7 +39,7 @@ from .compilers import ( ) if T.TYPE_CHECKING: - from ..coredata import OptionDictType + from ..coredata import KeyedOptionDictType from ..dependencies import Dependency, ExternalProgram from ..envconfig import MachineInfo from ..environment import Environment @@ -95,10 +95,10 @@ class CCompiler(CLikeCompiler, Compiler): return self.compiles(t.format(**fargs), env, extra_args=extra_args, dependencies=dependencies) - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = super().get_options() opts.update({ - 'std': coredata.UserComboOption( + OptionKey('std', machine=self.for_machine, lang=self.language): coredata.UserComboOption( 'C langauge standard to use', ['none'], 'none', @@ -119,7 +119,7 @@ class _ClangCStds(CompilerMixinBase): _C18_VERSION = '>=8.0.0' _C2X_VERSION = '>=9.0.0' - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = super().get_options() c_stds = ['c89', 'c99', 'c11'] g_stds = ['gnu89', 'gnu99', 'gnu11'] @@ -134,7 +134,7 @@ class _ClangCStds(CompilerMixinBase): if version_compare(self.version, self._C2X_VERSION): c_stds += ['c2x'] g_stds += ['gnu2x'] - opts['std'].choices = ['none'] + c_stds + g_stds # type: ignore + opts[OptionKey('std', machine=self.for_machine, lang=self.language)].choices = ['none'] + c_stds + g_stds return opts @@ -153,28 +153,28 @@ class ClangCCompiler(_ClangCStds, ClangCompiler, CCompiler): '2': default_warn_args + ['-Wextra'], '3': default_warn_args + ['-Wextra', '-Wpedantic']} - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = super().get_options() if self.info.is_windows() or self.info.is_cygwin(): opts.update({ - 'winlibs': coredata.UserArrayOption( + OptionKey('winlibs', machine=self.for_machine, lang=self.language): coredata.UserArrayOption( 'Standard Win libraries to link against', gnu_winlibs, ), }) return opts - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] - std = options['std'] + std = options[OptionKey('std', machine=self.for_machine, lang=self.language)] if std.value != 'none': args.append('-std=' + std.value) return args - def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: if self.info.is_windows() or self.info.is_cygwin(): # without a typedict mypy can't understand this. - libs = options['winlibs'].value.copy() + libs = options[OptionKey('winlibs', machine=self.for_machine, lang=self.language)].value.copy() assert isinstance(libs, list) for l in libs: assert isinstance(l, str) @@ -223,19 +223,20 @@ class ArmclangCCompiler(ArmclangCompiler, CCompiler): '2': default_warn_args + ['-Wextra'], '3': default_warn_args + ['-Wextra', '-Wpedantic']} - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = CCompiler.get_options(self) - opts['std'].choices = ['none', 'c90', 'c99', 'c11', 'gnu90', 'gnu99', 'gnu11'] # type: ignore + key = OptionKey('std', machine=self.for_machine, lang=self.language) + opts[key].choices = ['none', 'c90', 'c99', 'c11', 'gnu90', 'gnu99', 'gnu11'] return opts - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] - std = options['std'] + std = options[OptionKey('std', machine=self.for_machine, lang=self.language)] if std.value != 'none': args.append('-std=' + std.value) return args - def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: return [] @@ -257,7 +258,7 @@ class GnuCCompiler(GnuCompiler, CCompiler): '2': default_warn_args + ['-Wextra'], '3': default_warn_args + ['-Wextra', '-Wpedantic']} - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = CCompiler.get_options(self) c_stds = ['c89', 'c99', 'c11'] g_stds = ['gnu89', 'gnu99', 'gnu11'] @@ -267,27 +268,28 @@ class GnuCCompiler(GnuCompiler, CCompiler): if version_compare(self.version, self._C2X_VERSION): c_stds += ['c2x'] g_stds += ['gnu2x'] - opts['std'].choices = ['none'] + c_stds + g_stds # type: ignore + key = OptionKey('std', machine=self.for_machine, lang=self.language) + opts[key].choices = ['none'] + c_stds + g_stds if self.info.is_windows() or self.info.is_cygwin(): opts.update({ - 'winlibs': coredata.UserArrayOption( + key.evolve('winlibs'): coredata.UserArrayOption( 'Standard Win libraries to link against', gnu_winlibs, ), }) return opts - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] - std = options['std'] + std = options[OptionKey('std', lang=self.language, machine=self.for_machine)] if std.value != 'none': args.append('-std=' + std.value) return args - def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: if self.info.is_windows() or self.info.is_cygwin(): # without a typeddict mypy can't figure this out - libs = options['winlibs'].value.copy() + libs: T.List[str] = options[OptionKey('winlibs', lang=self.language, machine=self.for_machine)].value.copy() assert isinstance(libs, list) for l in libs: assert isinstance(l, str) @@ -331,9 +333,9 @@ class ElbrusCCompiler(GnuCCompiler, ElbrusCompiler): ElbrusCompiler.__init__(self) # It does support some various ISO standards and c/gnu 90, 9x, 1x in addition to those which GNU CC supports. - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = CCompiler.get_options(self) - opts['std'].choices = [ # type: ignore + opts[OptionKey('std', machine=self.for_machine, lang=self.language)].choices = [ 'none', 'c89', 'c90', 'c9x', 'c99', 'c1x', 'c11', 'gnu89', 'gnu90', 'gnu9x', 'gnu99', 'gnu1x', 'gnu11', 'iso9899:2011', 'iso9899:1990', 'iso9899:199409', 'iso9899:1999', @@ -368,18 +370,18 @@ class IntelCCompiler(IntelGnuLikeCompiler, CCompiler): '2': default_warn_args + ['-Wextra'], '3': default_warn_args + ['-Wextra']} - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = CCompiler.get_options(self) c_stds = ['c89', 'c99'] g_stds = ['gnu89', 'gnu99'] if version_compare(self.version, '>=16.0.0'): c_stds += ['c11'] - opts['std'].choices = ['none'] + c_stds + g_stds # type: ignore + opts[OptionKey('std', machine=self.for_machine, lang=self.language)].choices = ['none'] + c_stds + g_stds return opts - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] - std = options['std'] + std = options[OptionKey('std', machine=self.for_machine, lang=self.language)] if std.value != 'none': args.append('-std=' + std.value) return args @@ -389,19 +391,20 @@ class VisualStudioLikeCCompilerMixin(CompilerMixinBase): """Shared methods that apply to MSVC-like C compilers.""" - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = super().get_options() opts.update({ - 'winlibs': coredata.UserArrayOption( + OptionKey('winlibs', machine=self.for_machine, lang=self.language): coredata.UserArrayOption( 'Windows libs to link against.', msvc_winlibs, ), }) return opts - def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: # need a TypeDict to make this work - libs = options['winlibs'].value.copy() + key = OptionKey('winlibs', machine=self.for_machine, lang=self.language) + libs = options[key].value.copy() assert isinstance(libs, list) for l in libs: assert isinstance(l, str) @@ -423,7 +426,7 @@ class VisualStudioCCompiler(MSVCCompiler, VisualStudioLikeCCompilerMixin, CCompi full_version=full_version) MSVCCompiler.__init__(self, target) - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = super().get_options() c_stds = ['c89', 'c99'] # Need to have these to be compatible with projects @@ -436,12 +439,13 @@ class VisualStudioCCompiler(MSVCCompiler, VisualStudioLikeCCompilerMixin, CCompi if version_compare(self.version, self._C17_VERSION): c_stds += ['c17', 'c18'] g_stds += ['gnu17', 'gnu18'] - opts['std'].choices = ['none'] + c_stds + g_stds # type: ignore + key = OptionKey('std', machine=self.for_machine, lang=self.language) + opts[key].choices = ['none'] + c_stds + g_stds return opts - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] - std = options['std'] + std = options[OptionKey('std', machine=self.for_machine, lang=self.language)] if std.value.startswith('gnu'): mlog.log_once( 'cl.exe does not actually support gnu standards, and meson ' @@ -466,8 +470,9 @@ class ClangClCCompiler(_ClangCStds, ClangClCompiler, VisualStudioLikeCCompilerMi full_version=full_version) ClangClCompiler.__init__(self, target) - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: - std = options['std'].value + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: + key = OptionKey('std', machine=self.for_machine, lang=self.language) + std = options[key].value if std != "none": return ['/clang:-std={}'.format(std)] return [] @@ -487,14 +492,16 @@ class IntelClCCompiler(IntelVisualStudioLikeCompiler, VisualStudioLikeCCompilerM full_version=full_version) IntelVisualStudioLikeCompiler.__init__(self, target) - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = super().get_options() - opts['std'].choices = ['none', 'c89', 'c99', 'c11'] # type: ignore + key = OptionKey('std', machine=self.for_machine, lang=self.language) + opts[key].choices = ['none', 'c89', 'c99', 'c11'] return opts - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] - std = options['std'] + key = OptionKey('std', machine=self.for_machine, lang=self.language) + std = options[key] if std.value == 'c89': mlog.log_once("ICL doesn't explicitly implement c89, setting the standard to 'none', which is close.") elif std.value != 'none': @@ -513,14 +520,16 @@ class ArmCCompiler(ArmCompiler, CCompiler): full_version=full_version) ArmCompiler.__init__(self) - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = CCompiler.get_options(self) - opts['std'].choices = ['none', 'c89', 'c99', 'c11'] # type: ignore + key = OptionKey('std', machine=self.for_machine, lang=self.language) + opts[key].choices = ['none', 'c89', 'c99', 'c11'] return opts - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] - std = options['std'] + key = OptionKey('std', machine=self.for_machine, lang=self.language) + std = options[key] if std.value != 'none': args.append('--' + std.value) return args @@ -540,17 +549,19 @@ class CcrxCCompiler(CcrxCompiler, CCompiler): def get_always_args(self) -> T.List[str]: return ['-nologo'] - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = CCompiler.get_options(self) - opts['std'].choices = ['none', 'c89', 'c99'] # type: ignore + key = OptionKey('std', machine=self.for_machine, lang=self.language) + opts[key].choices = ['none', 'c89', 'c99'] return opts def get_no_stdinc_args(self) -> T.List[str]: return [] - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] - std = options['std'] + key = OptionKey('std', machine=self.for_machine, lang=self.language) + std = options[key] if std.value == 'c89': args.append('-lang=c') elif std.value == 'c99': @@ -585,17 +596,19 @@ class Xc16CCompiler(Xc16Compiler, CCompiler): info, exe_wrapper, linker=linker, full_version=full_version) Xc16Compiler.__init__(self) - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = CCompiler.get_options(self) - opts['std'].choices = ['none', 'c89', 'c99', 'gnu89', 'gnu99'] # type: ignore + key = OptionKey('std', machine=self.for_machine, lang=self.language) + opts[key].choices = ['none', 'c89', 'c99', 'gnu89', 'gnu99'] return opts def get_no_stdinc_args(self) -> T.List[str]: return [] - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] - std = options['c_std'] + key = OptionKey('std', machine=self.for_machine, lang=self.language) + std = options[key] if std.value != 'none': args.append('-ansi') args.append('-std=' + std.value) @@ -628,12 +641,13 @@ class CompCertCCompiler(CompCertCompiler, CCompiler): info, exe_wrapper, linker=linker, full_version=full_version) CompCertCompiler.__init__(self) - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = CCompiler.get_options(self) - opts['std'].choices = ['none', 'c89', 'c99'] # type: ignore + key = OptionKey('std', machine=self.for_machine, lang=self.language) + opts[key].choices = ['none', 'c89', 'c99'] return opts - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: return [] def get_no_optimization_args(self) -> T.List[str]: @@ -664,17 +678,19 @@ class C2000CCompiler(C2000Compiler, CCompiler): def get_always_args(self) -> T.List[str]: return [] - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = CCompiler.get_options(self) - opts['std'].choices = ['none', 'c89', 'c99', 'c11'] # type: ignore + key = OptionKey('std', machine=self.for_machine, lang=self.language) + opts[key].choices = ['none', 'c89', 'c99', 'c11'] return opts def get_no_stdinc_args(self) -> T.List[str]: return [] - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] - std = options['c_std'] + key = OptionKey('std', machine=self.for_machine, lang=self.language) + std = options[key] if std.value != 'none': args.append('--' + std.value) return args diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 0bd2b4c..234ce06 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -25,7 +25,7 @@ from .. import mesonlib from ..linkers import LinkerEnvVarsMixin from ..mesonlib import ( EnvironmentException, MachineChoice, MesonException, - Popen_safe, split_args, LibType, TemporaryDirectoryWinProof + Popen_safe, split_args, LibType, TemporaryDirectoryWinProof, OptionKey, ) from ..envconfig import ( get_env_var @@ -35,7 +35,7 @@ from ..arglist import CompilerArgs if T.TYPE_CHECKING: from ..build import BuildTarget - from ..coredata import OptionDictType + from ..coredata import OptionDictType, KeyedOptionDictType from ..envconfig import MachineInfo from ..environment import Environment from ..linkers import DynamicLinker # noqa: F401 @@ -265,36 +265,32 @@ cuda_debug_args = {False: [], clike_debug_args = {False: [], True: ['-g']} # type: T.Dict[bool, T.List[str]] -base_options = {'b_pch': coredata.UserBooleanOption('Use precompiled headers', True), - 'b_lto': coredata.UserBooleanOption('Use link time optimization', False), - 'b_sanitize': coredata.UserComboOption('Code sanitizer to use', - ['none', 'address', 'thread', 'undefined', 'memory', 'address,undefined'], - 'none'), - 'b_lundef': coredata.UserBooleanOption('Use -Wl,--no-undefined when linking', True), - 'b_asneeded': coredata.UserBooleanOption('Use -Wl,--as-needed when linking', True), - 'b_pgo': coredata.UserComboOption('Use profile guided optimization', - ['off', 'generate', 'use'], - 'off'), - 'b_coverage': coredata.UserBooleanOption('Enable coverage tracking.', - False), - 'b_colorout': coredata.UserComboOption('Use colored output', - ['auto', 'always', 'never'], - 'always'), - 'b_ndebug': coredata.UserComboOption('Disable asserts', - ['true', 'false', 'if-release'], 'false'), - 'b_staticpic': coredata.UserBooleanOption('Build static libraries as position independent', - True), - 'b_pie': coredata.UserBooleanOption('Build executables as position independent', - False), - 'b_bitcode': coredata.UserBooleanOption('Generate and embed bitcode (only macOS/iOS/tvOS)', - False), - 'b_vscrt': coredata.UserComboOption('VS run-time library type to use.', - ['none', 'md', 'mdd', 'mt', 'mtd', 'from_buildtype', 'static_from_buildtype'], - 'from_buildtype'), - } # type: OptionDictType - -def option_enabled(boptions: T.List[str], options: 'OptionDictType', - option: str) -> bool: +base_options: 'KeyedOptionDictType' = { + OptionKey('b_pch'): coredata.UserBooleanOption('Use precompiled headers', True), + OptionKey('b_lto'): coredata.UserBooleanOption('Use link time optimization', False), + OptionKey('b_sanitize'): coredata.UserComboOption('Code sanitizer to use', + ['none', 'address', 'thread', 'undefined', 'memory', 'address,undefined'], + 'none'), + OptionKey('b_lundef'): coredata.UserBooleanOption('Use -Wl,--no-undefined when linking', True), + OptionKey('b_asneeded'): coredata.UserBooleanOption('Use -Wl,--as-needed when linking', True), + OptionKey('b_pgo'): coredata.UserComboOption('Use profile guided optimization', + ['off', 'generate', 'use'], + 'off'), + OptionKey('b_coverage'): coredata.UserBooleanOption('Enable coverage tracking.', False), + OptionKey('b_colorout'): coredata.UserComboOption('Use colored output', + ['auto', 'always', 'never'], + 'always'), + OptionKey('b_ndebug'): coredata.UserComboOption('Disable asserts', ['true', 'false', 'if-release'], 'false'), + OptionKey('b_staticpic'): coredata.UserBooleanOption('Build static libraries as position independent', True), + OptionKey('b_pie'): coredata.UserBooleanOption('Build executables as position independent', False), + OptionKey('b_bitcode'): coredata.UserBooleanOption('Generate and embed bitcode (only macOS/iOS/tvOS)', False), + OptionKey('b_vscrt'): coredata.UserComboOption('VS run-time library type to use.', + ['none', 'md', 'mdd', 'mt', 'mtd', 'from_buildtype', 'static_from_buildtype'], + 'from_buildtype'), +} + +def option_enabled(boptions: T.Set[OptionKey], options: 'KeyedOptionDictType', + option: OptionKey) -> bool: try: if option not in boptions: return False @@ -304,23 +300,23 @@ def option_enabled(boptions: T.List[str], options: 'OptionDictType', except KeyError: return False -def get_base_compile_args(options: 'OptionDictType', compiler: 'Compiler') -> T.List[str]: +def get_base_compile_args(options: 'KeyedOptionDictType', compiler: 'Compiler') -> T.List[str]: args = [] # type T.List[str] try: - if options['b_lto'].value: + if options[OptionKey('b_lto')].value: args.extend(compiler.get_lto_compile_args()) except KeyError: pass try: - args += compiler.get_colorout_args(options['b_colorout'].value) + args += compiler.get_colorout_args(options[OptionKey('b_colorout')].value) except KeyError: pass try: - args += compiler.sanitizer_compile_args(options['b_sanitize'].value) + args += compiler.sanitizer_compile_args(options[OptionKey('b_sanitize')].value) except KeyError: pass try: - pgo_val = options['b_pgo'].value + pgo_val = options[OptionKey('b_pgo')].value if pgo_val == 'generate': args.extend(compiler.get_profile_generate_args()) elif pgo_val == 'use': @@ -328,23 +324,23 @@ def get_base_compile_args(options: 'OptionDictType', compiler: 'Compiler') -> T. except KeyError: pass try: - if options['b_coverage'].value: + if options[OptionKey('b_coverage')].value: args += compiler.get_coverage_args() except KeyError: pass try: - if (options['b_ndebug'].value == 'true' or - (options['b_ndebug'].value == 'if-release' and - options['buildtype'].value in {'release', 'plain'})): + if (options[OptionKey('b_ndebug')].value == 'true' or + (options[OptionKey('b_ndebug')].value == 'if-release' and + options[OptionKey('buildtype')].value in {'release', 'plain'})): args += compiler.get_disable_assert_args() except KeyError: pass # This does not need a try...except - if option_enabled(compiler.base_options, options, 'b_bitcode'): + if option_enabled(compiler.base_options, options, OptionKey('b_bitcode')): args.append('-fembed-bitcode') try: - crt_val = options['b_vscrt'].value - buildtype = options['buildtype'].value + crt_val = options[OptionKey('b_vscrt')].value + buildtype = options[OptionKey('buildtype')].value try: args += compiler.get_crt_compile_args(crt_val, buildtype) except AttributeError: @@ -353,20 +349,20 @@ def get_base_compile_args(options: 'OptionDictType', compiler: 'Compiler') -> T. pass return args -def get_base_link_args(options: 'OptionDictType', linker: 'Compiler', +def get_base_link_args(options: 'KeyedOptionDictType', linker: 'Compiler', is_shared_module: bool) -> T.List[str]: args = [] # type: T.List[str] try: - if options['b_lto'].value: + if options[OptionKey('b_lto')].value: args.extend(linker.get_lto_link_args()) except KeyError: pass try: - args += linker.sanitizer_link_args(options['b_sanitize'].value) + args += linker.sanitizer_link_args(options[OptionKey('b_sanitize')].value) except KeyError: pass try: - pgo_val = options['b_pgo'].value + pgo_val = options[OptionKey('b_pgo')].value if pgo_val == 'generate': args.extend(linker.get_profile_generate_args()) elif pgo_val == 'use': @@ -374,13 +370,13 @@ def get_base_link_args(options: 'OptionDictType', linker: 'Compiler', except KeyError: pass try: - if options['b_coverage'].value: + if options[OptionKey('b_coverage')].value: args += linker.get_coverage_link_args() except KeyError: pass - as_needed = option_enabled(linker.base_options, options, 'b_asneeded') - bitcode = option_enabled(linker.base_options, options, 'b_bitcode') + as_needed = option_enabled(linker.base_options, options, OptionKey('b_asneeded')) + bitcode = option_enabled(linker.base_options, options, OptionKey('b_bitcode')) # Shared modules cannot be built with bitcode_bundle because # -bitcode_bundle is incompatible with -undefined and -bundle if bitcode and not is_shared_module: @@ -394,14 +390,14 @@ def get_base_link_args(options: 'OptionDictType', linker: 'Compiler', if not bitcode: args.extend(linker.headerpad_args()) if (not is_shared_module and - option_enabled(linker.base_options, options, 'b_lundef')): + option_enabled(linker.base_options, options, OptionKey('b_lundef'))): args.extend(linker.no_undefined_link_args()) else: args.extend(linker.get_allow_undefined_link_args()) try: - crt_val = options['b_vscrt'].value - buildtype = options['buildtype'].value + crt_val = options[OptionKey('b_vscrt')].value + buildtype = options[OptionKey('buildtype')].value try: args += linker.get_crt_link_args(crt_val, buildtype) except AttributeError: @@ -477,7 +473,7 @@ class Compiler(metaclass=abc.ABCMeta): self.version = version self.full_version = full_version self.for_machine = for_machine - self.base_options = [] # type: T.List[str] + self.base_options: T.Set[OptionKey] = set() self.linker = linker self.info = info self.is_cross = is_cross @@ -596,13 +592,13 @@ class Compiler(metaclass=abc.ABCMeta): is_cross: bool) -> T.List[str]: return self.linker.get_args_from_envvars(for_machine, is_cross) - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': return {} - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: return [] - def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: return self.linker.get_option_args(options) def check_header(self, hname: str, prefix: str, env: 'Environment', *, @@ -826,7 +822,7 @@ class Compiler(metaclass=abc.ABCMeta): def get_std_shared_lib_link_args(self) -> T.List[str]: return self.linker.get_std_shared_lib_args() - def get_std_shared_module_link_args(self, options: 'OptionDictType') -> T.List[str]: + def get_std_shared_module_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: return self.linker.get_std_shared_module_args(options) def get_link_whole_for(self, args: T.List[str]) -> T.List[str]: @@ -1243,17 +1239,19 @@ def get_args_from_envvars(lang: str, def get_global_options(lang: str, comp: T.Type[Compiler], for_machine: MachineChoice, - is_cross: bool) -> 'OptionDictType': + is_cross: bool) -> 'KeyedOptionDictType': """Retreive options that apply to all compilers for a given language.""" description = 'Extra arguments passed to the {}'.format(lang) - opts = { - 'args': coredata.UserArrayOption( + argkey = OptionKey('args', lang=lang, machine=for_machine) + largkey = argkey.evolve('link_args') + opts: 'KeyedOptionDictType' = { + argkey: coredata.UserArrayOption( description + ' compiler', [], split_args=True, user_input=True, allow_dups=True), - 'link_args': coredata.UserArrayOption( + largkey: coredata.UserArrayOption( description + ' linker', [], split_args=True, user_input=True, allow_dups=True), - } # type: OptionDictType + } # Get from env vars. compile_args, link_args = get_args_from_envvars( @@ -1262,10 +1260,7 @@ def get_global_options(lang: str, is_cross, comp.INVOKES_LINKER) - for k, o in opts.items(): - if k == 'args': - o.set_value(compile_args) - elif k == 'link_args': - o.set_value(link_args) + opts[argkey].set_value(compile_args) + opts[largkey].set_value(link_args) return opts diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 607bea7..2e94e48 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -19,7 +19,7 @@ import typing as T from .. import coredata from .. import mlog -from ..mesonlib import MesonException, MachineChoice, version_compare +from ..mesonlib import MesonException, MachineChoice, version_compare, OptionKey from ..linkers import LinkerEnvVarsMixin from .compilers import ( @@ -42,7 +42,7 @@ from .mixins.pgi import PGICompiler from .mixins.emscripten import EmscriptenMixin if T.TYPE_CHECKING: - from ..coredata import OptionDictType + from ..coredata import KeyedOptionDictType from ..dependencies import Dependency, ExternalProgram from ..envconfig import MachineInfo from ..environment import Environment @@ -169,10 +169,11 @@ class CPPCompiler(CLikeCompiler, Compiler): raise MesonException('C++ Compiler does not support -std={}'.format(cpp_std)) - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = super().get_options() + key = OptionKey('std', machine=self.for_machine, lang=self.language) opts.update({ - 'std': coredata.UserComboOption( + key: coredata.UserComboOption( 'C++ language standard to use', ['none'], 'none', @@ -196,47 +197,50 @@ class ClangCPPCompiler(ClangCompiler, CPPCompiler): '2': default_warn_args + ['-Wextra'], '3': default_warn_args + ['-Wextra', '-Wpedantic']} - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = CPPCompiler.get_options(self) + key = OptionKey('key', machine=self.for_machine, lang=self.language) opts.update({ - 'eh': coredata.UserComboOption( + key.evolve('eh'): coredata.UserComboOption( 'C++ exception handling type.', ['none', 'default', 'a', 's', 'sc'], 'default', ), - 'rtti': coredata.UserBooleanOption('Enable RTTI', True), + key.evolve('rtti'): coredata.UserBooleanOption('Enable RTTI', True), }) - opts['std'].choices = [ # type: ignore + opts[key.evolve('std')].choices = [ 'none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z', 'c++2a', 'c++20', 'gnu++11', 'gnu++14', 'gnu++17', 'gnu++1z', 'gnu++2a', 'gnu++20', ] if self.info.is_windows() or self.info.is_cygwin(): opts.update({ - 'winlibs': coredata.UserArrayOption( + key.evolve('winlibs'): coredata.UserArrayOption( 'Standard Win libraries to link against', gnu_winlibs, ), }) return opts - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] - std = options['std'] + key = OptionKey('std', machine=self.for_machine, lang=self.language) + std = options[key] if std.value != 'none': args.append(self._find_best_cpp_std(std.value)) - non_msvc_eh_options(options['eh'].value, args) + non_msvc_eh_options(options[key.evolve('eh')].value, args) - if not options['rtti'].value: + if not options[key.evolve('rtti')].value: args.append('-fno-rtti') return args - def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: if self.info.is_windows() or self.info.is_cygwin(): # without a typedict mypy can't understand this. - libs = options['winlibs'].value.copy() + key = OptionKey('winlibs', machine=self.for_machine, lang=self.language) + libs = options[key].value.copy() assert isinstance(libs, list) for l in libs: assert isinstance(l, str) @@ -265,9 +269,10 @@ class EmscriptenCPPCompiler(EmscriptenMixin, LinkerEnvVarsMixin, ClangCPPCompile defines=defines, full_version=full_version) self.id = 'emscripten' - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] - std = options['std'] + key = OptionKey('std', machine=self.for_machine, lang=self.language) + std = options[key] if std.value != 'none': args.append(self._find_best_cpp_std(std.value)) return args @@ -287,32 +292,34 @@ class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler): '2': default_warn_args + ['-Wextra'], '3': default_warn_args + ['-Wextra', '-Wpedantic']} - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = CPPCompiler.get_options(self) + key = OptionKey('std', machine=self.for_machine, lang=self.language) opts.update({ - 'eh': coredata.UserComboOption( + key.evolve('eh'): coredata.UserComboOption( 'C++ exception handling type.', ['none', 'default', 'a', 's', 'sc'], 'default', ), }) - opts['std'].choices = [ # type: ignore + opts[key].choices = [ 'none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'gnu++98', 'gnu++03', 'gnu++11', 'gnu++14', 'gnu++17', ] return opts - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] - std = options['std'] + key = OptionKey('std', machine=self.for_machine, lang=self.language) + std = options[key] if std.value != 'none': args.append('-std=' + std.value) - non_msvc_eh_options(options['eh'].value, args) + non_msvc_eh_options(options[key.evolve('eh')].value, args) return args - def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: return [] @@ -331,53 +338,56 @@ class GnuCPPCompiler(GnuCompiler, CPPCompiler): '2': default_warn_args + ['-Wextra'], '3': default_warn_args + ['-Wextra', '-Wpedantic']} - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': + key = OptionKey('std', machine=self.for_machine, lang=self.language) opts = CPPCompiler.get_options(self) opts.update({ - 'eh': coredata.UserComboOption( + key.evolve('eh'): coredata.UserComboOption( 'C++ exception handling type.', ['none', 'default', 'a', 's', 'sc'], 'default', ), - 'rtti': coredata.UserBooleanOption('Enable RTTI', True), - 'debugstl': coredata.UserBooleanOption( + key.evolve('rtti'): coredata.UserBooleanOption('Enable RTTI', True), + key.evolve('debugstl'): coredata.UserBooleanOption( 'STL debug mode', False, ) }) - opts['std'].choices = [ # type: ignore + opts[key].choices = [ 'none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z', 'c++2a', 'c++20', 'gnu++03', 'gnu++11', 'gnu++14', 'gnu++17', 'gnu++1z', 'gnu++2a', 'gnu++20', ] if self.info.is_windows() or self.info.is_cygwin(): opts.update({ - 'winlibs': coredata.UserArrayOption( + key.evolve('winlibs'): coredata.UserArrayOption( 'Standard Win libraries to link against', gnu_winlibs, ), }) return opts - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] - std = options['std'] + key = OptionKey('std', machine=self.for_machine, lang=self.language) + std = options[key] if std.value != 'none': args.append(self._find_best_cpp_std(std.value)) - non_msvc_eh_options(options['eh'].value, args) + non_msvc_eh_options(options[key.evolve('eh')].value, args) - if not options['rtti'].value: + if not options[key.evolve('rtti')].value: args.append('-fno-rtti') - if options['debugstl'].value: + if options[key.evolve('debugstl')].value: args.append('-D_GLIBCXX_DEBUG=1') return args - def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: if self.info.is_windows() or self.info.is_cygwin(): # without a typedict mypy can't understand this. - libs = options['winlibs'].value.copy() + key = OptionKey('winlibs', machine=self.for_machine, lang=self.language) + libs = options[key].value.copy() assert isinstance(libs, list) for l in libs: assert isinstance(l, str) @@ -424,7 +434,7 @@ class ElbrusCPPCompiler(GnuCPPCompiler, ElbrusCompiler): full_version=full_version, defines=defines) ElbrusCompiler.__init__(self) - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = CPPCompiler.get_options(self) cpp_stds = [ @@ -438,18 +448,19 @@ class ElbrusCPPCompiler(GnuCPPCompiler, ElbrusCompiler): if version_compare(self.version, '>=1.25.00'): cpp_stds += [ 'c++2a', 'gnu++2a' ] + key = OptionKey('std', machine=self.for_machine, lang=self.language) opts.update({ - 'eh': coredata.UserComboOption( + key.evolve('eh'): coredata.UserComboOption( 'C++ exception handling type.', ['none', 'default', 'a', 's', 'sc'], 'default', ), - 'debugstl': coredata.UserBooleanOption( + key.evolve('debugstl'): coredata.UserBooleanOption( 'STL debug mode', False, ), }) - opts['std'].choices = cpp_stds # type: ignore + opts[key].choices = cpp_stds return opts # Elbrus C++ compiler does not have lchmod, but there is only linker warning, not compiler error. @@ -465,15 +476,16 @@ class ElbrusCPPCompiler(GnuCPPCompiler, ElbrusCompiler): dependencies=dependencies) # Elbrus C++ compiler does not support RTTI, so don't check for it. - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] - std = options['std'] + key = OptionKey('std', machine=self.for_machine, lang=self.language) + std = options[key] if std.value != 'none': args.append(self._find_best_cpp_std(std.value)) - non_msvc_eh_options(options['eh'].value, args) + non_msvc_eh_options(options[key.evolve('eh')].value, args) - if options['debugstl'].value: + if options[key.evolve('debugstl')].value: args.append('-D_GLIBCXX_DEBUG=1') return args @@ -494,7 +506,7 @@ class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler): '2': default_warn_args + ['-Wextra'], '3': default_warn_args + ['-Wextra']} - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = CPPCompiler.get_options(self) # Every Unix compiler under the sun seems to accept -std=c++03, # with the exception of ICC. Instead of preventing the user from @@ -511,36 +523,40 @@ class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler): if version_compare(self.version, '>=19.1.0'): c_stds += ['c++2a'] g_stds += ['gnu++2a'] + + + key = OptionKey('std', machine=self.for_machine, lang=self.language) opts.update({ - 'eh': coredata.UserComboOption( + key.evolve('eh'): coredata.UserComboOption( 'C++ exception handling type.', ['none', 'default', 'a', 's', 'sc'], 'default', ), - 'rtti': coredata.UserBooleanOption('Enable RTTI', True), - 'debugstl': coredata.UserBooleanOption('STL debug mode', False), + key.evolve('rtti'): coredata.UserBooleanOption('Enable RTTI', True), + key.evolve('debugstl'): coredata.UserBooleanOption('STL debug mode', False), }) - opts['std'].choices = ['none'] + c_stds + g_stds # type: ignore + opts[key].choices = ['none'] + c_stds + g_stds return opts - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] - std = options['std'] + key = OptionKey('std', machine=self.for_machine, lang=self.language) + std = options[key] if std.value != 'none': remap_cpp03 = { 'c++03': 'c++98', 'gnu++03': 'gnu++98' } args.append('-std=' + remap_cpp03.get(std.value, std.value)) - if options['eh'].value == 'none': + if options[key.evolve('eh')].value == 'none': args.append('-fno-exceptions') - if not options['rtti'].value: + if not options[key.evolve('rtti')].value: args.append('-fno-rtti') - if options['debugstl'].value: + if options[key.evolve('debugstl')].value: args.append('-D_GLIBCXX_DEBUG=1') return args - def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: return [] @@ -560,30 +576,33 @@ class VisualStudioLikeCPPCompilerMixin(CompilerMixinBase): 'c++latest': (False, "latest"), } - def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: # need a typeddict for this - return T.cast(T.List[str], options['winlibs'].value[:]) + key = OptionKey('winlibs', machine=self.for_machine, lang=self.language) + return T.cast(T.List[str], options[key].value[:]) - def _get_options_impl(self, opts: 'OptionDictType', cpp_stds: T.List[str]) -> 'OptionDictType': + def _get_options_impl(self, opts: 'KeyedOptionDictType', cpp_stds: T.List[str]) -> 'KeyedOptionDictType': + key = OptionKey('std', machine=self.for_machine, lang=self.language) opts.update({ - 'eh': coredata.UserComboOption( + key.evolve('eh'): coredata.UserComboOption( 'C++ exception handling type.', ['none', 'default', 'a', 's', 'sc'], 'default', ), - 'rtti': coredata.UserBooleanOption('Enable RTTI', True), - 'winlibs': coredata.UserArrayOption( + key.evolve('rtti'): coredata.UserBooleanOption('Enable RTTI', True), + key.evolve('winlibs'): coredata.UserArrayOption( 'Windows libs to link against.', msvc_winlibs, ), }) - opts['std'].choices = cpp_stds # type: ignore + opts[key.evolve('std')].choices = cpp_stds return opts - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] + key = OptionKey('std', machine=self.for_machine, lang=self.language) - eh = options['eh'] + eh = options[key.evolve('eh')] if eh.value == 'default': args.append('/EHsc') elif eh.value == 'none': @@ -591,10 +610,10 @@ class VisualStudioLikeCPPCompilerMixin(CompilerMixinBase): else: args.append('/EH' + eh.value) - if not options['rtti'].value: + if not options[key.evolve('rtti')].value: args.append('/GR-') - permissive, ver = self.VC_VERSION_MAP[options['std'].value] + permissive, ver = self.VC_VERSION_MAP[options[key].value] if ver is not None: args.append('/std:c++{}'.format(ver)) @@ -616,22 +635,23 @@ class CPP11AsCPP14Mixin(CompilerMixinBase): This is a limitation of Clang and MSVC that ICL doesn't share. """ - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: # Note: there is no explicit flag for supporting C++11; we attempt to do the best we can # which means setting the C++ standard version to C++14, in compilers that support it # (i.e., after VS2015U3) # if one is using anything before that point, one cannot set the standard. - if options['std'].value in {'vc++11', 'c++11'}: + key = OptionKey('std', machine=self.for_machine, lang=self.language) + if options[key].value in {'vc++11', 'c++11'}: mlog.warning(self.id, 'does not support C++11;', 'attempting best effort; setting the standard to C++14', once=True) # Don't mutate anything we're going to change, we need to use # deepcopy since we're messing with members, and we can't simply # copy the members because the option proxy doesn't support it. options = copy.deepcopy(options) - if options['std'].value == 'vc++11': - options['std'].value = 'vc++14' + if options[key].value == 'vc++11': + options[key].value = 'vc++14' else: - options['std'].value = 'c++14' + options[key].value = 'c++14' return super().get_option_compile_args(options) @@ -644,10 +664,10 @@ class VisualStudioCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixi CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, info, exe_wrapper, linker=linker, full_version=full_version) MSVCCompiler.__init__(self, target) - self.base_options = ['b_pch', 'b_vscrt', 'b_ndebug'] # FIXME add lto, pgo and the like + self.base_options = {OptionKey(o) for o in ['b_pch', 'b_vscrt', 'b_ndebug']} # FIXME add lto, pgo and the like self.id = 'msvc' - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': cpp_stds = ['none', 'c++11', 'vc++11'] # Visual Studio 2015 and later if version_compare(self.version, '>=19'): @@ -657,11 +677,12 @@ class VisualStudioCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixi cpp_stds.extend(['vc++14', 'c++17', 'vc++17']) return self._get_options_impl(super().get_options(), cpp_stds) - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: - if options['std'].value != 'none' and version_compare(self.version, '<19.00.24210'): + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: + key = OptionKey('std', machine=self.for_machine, lang=self.language) + if options[key].value != 'none' and version_compare(self.version, '<19.00.24210'): mlog.warning('This version of MSVC does not support cpp_std arguments') options = copy.copy(options) - options['std'].value = 'none' + options[key].value = 'none' args = super().get_option_compile_args(options) @@ -684,7 +705,7 @@ class ClangClCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixin, Cl ClangClCompiler.__init__(self, target) self.id = 'clang-cl' - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': cpp_stds = ['none', 'c++11', 'vc++11', 'c++14', 'vc++14', 'c++17', 'vc++17', 'c++latest'] return self._get_options_impl(super().get_options(), cpp_stds) @@ -700,7 +721,7 @@ class IntelClCPPCompiler(VisualStudioLikeCPPCompilerMixin, IntelVisualStudioLike info, exe_wrapper, linker=linker, full_version=full_version) IntelVisualStudioLikeCompiler.__init__(self, target) - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': # This has only been tested with version 19.0, cpp_stds = ['none', 'c++11', 'vc++11', 'c++14', 'vc++14', 'c++17', 'vc++17', 'c++latest'] return self._get_options_impl(super().get_options(), cpp_stds) @@ -719,21 +740,23 @@ class ArmCPPCompiler(ArmCompiler, CPPCompiler): info, exe_wrapper, linker=linker, full_version=full_version) ArmCompiler.__init__(self) - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = CPPCompiler.get_options(self) - opts['std'].choices = ['none', 'c++03', 'c++11'] # type: ignore + key = OptionKey('std', machine=self.for_machine, lang=self.language) + opts[key].choices = ['none', 'c++03', 'c++11'] return opts - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] - std = options['std'] + key = OptionKey('std', machine=self.for_machine, lang=self.language) + std = options[key] if std.value == 'c++11': args.append('--cpp11') elif std.value == 'c++03': args.append('--cpp') return args - def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: return [] def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: @@ -753,7 +776,7 @@ class CcrxCPPCompiler(CcrxCompiler, CPPCompiler): def get_always_args(self) -> T.List[str]: return ['-nologo', '-lang=cpp'] - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: return [] def get_compile_only_args(self) -> T.List[str]: @@ -762,7 +785,7 @@ class CcrxCPPCompiler(CcrxCompiler, CPPCompiler): def get_output_args(self, target: str) -> T.List[str]: return ['-output=obj=%s' % target] - def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: return [] def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: @@ -777,15 +800,16 @@ class C2000CPPCompiler(C2000Compiler, CPPCompiler): info, exe_wrapper, linker=linker, full_version=full_version) C2000Compiler.__init__(self) - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = CPPCompiler.get_options(self) - opts['std'].choices = ['none', 'c++03'] # type: ignore + key = OptionKey('std', machine=self.for_machine, lang=self.language) + opts[key].choices = ['none', 'c++03'] return opts def get_always_args(self) -> T.List[str]: return ['-nologo', '-lang=cpp'] - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: return [] def get_compile_only_args(self) -> T.List[str]: @@ -794,7 +818,7 @@ class C2000CPPCompiler(C2000Compiler, CPPCompiler): def get_output_args(self, target: str) -> T.List[str]: return ['-output=obj=%s' % target] - def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: return [] def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py index 89fcf40..7fa3e4f 100644 --- a/mesonbuild/compilers/cuda.py +++ b/mesonbuild/compilers/cuda.py @@ -18,13 +18,16 @@ import typing as T from .. import coredata from .. import mlog -from ..mesonlib import EnvironmentException, MachineChoice, Popen_safe, OptionOverrideProxy, is_windows, LibType +from ..mesonlib import ( + EnvironmentException, MachineChoice, Popen_safe, OptionOverrideProxy, + is_windows, LibType, OptionKey, +) from .compilers import (Compiler, cuda_buildtype_args, cuda_optimization_args, cuda_debug_args) if T.TYPE_CHECKING: from ..build import BuildTarget - from ..coredata import OptionDictType + from ..coredata import KeyedOptionDictType from ..dependencies import Dependency, ExternalProgram from ..environment import Environment # noqa: F401 from ..envconfig import MachineInfo @@ -195,24 +198,26 @@ class CudaCompiler(Compiler): }}''' return self.compiles(t.format_map(fargs), env, extra_args=extra_args, dependencies=dependencies) - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = super().get_options() - opts.update({'std': coredata.UserComboOption('C++ language standard to use with cuda', + key = OptionKey('std', machine=self.for_machine, lang=self.language) + opts.update({key: coredata.UserComboOption('C++ language standard to use with cuda', ['none', 'c++03', 'c++11', 'c++14'], 'none')}) return opts - def _to_host_compiler_options(self, options: 'OptionDictType') -> 'OptionDictType': + def _to_host_compiler_options(self, options: 'KeyedOptionDictType') -> 'KeyedOptionDictType': overrides = {name: opt.value for name, opt in options.items()} return OptionOverrideProxy(overrides, self.host_compiler.get_options()) - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] # On Windows, the version of the C++ standard used by nvcc is dictated by # the combination of CUDA version and MSVC version; the --std= is thus ignored # and attempting to use it will result in a warning: https://stackoverflow.com/a/51272091/741027 if not is_windows(): - std = options['std'] + key = OptionKey('std', machine=self.for_machine, lang=self.language) + std = options[key] if std.value != 'none': args.append('--std=' + std.value) @@ -229,7 +234,7 @@ class CudaCompiler(Compiler): cooked.append(arg) return cls._to_host_flags(cooked, _Phase.LINKER) - def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: return self._cook_link_args(self.host_compiler.get_option_link_args(self._to_host_compiler_options(options))) def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str, diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py index ca6de38..eac2aa7 100644 --- a/mesonbuild/compilers/d.py +++ b/mesonbuild/compilers/d.py @@ -18,7 +18,7 @@ import subprocess import typing as T from ..mesonlib import ( - EnvironmentException, MachineChoice, version_compare, + EnvironmentException, MachineChoice, version_compare, OptionKey, ) from ..arglist import CompilerArgs @@ -653,8 +653,10 @@ class GnuDCompiler(GnuCompiler, DCompiler): '1': default_warn_args, '2': default_warn_args + ['-Wextra'], '3': default_warn_args + ['-Wextra', '-Wpedantic']} - self.base_options = ['b_colorout', 'b_sanitize', 'b_staticpic', - 'b_vscrt', 'b_coverage', 'b_pgo', 'b_ndebug'] + self.base_options = { + OptionKey(o) for o in [ + 'b_colorout', 'b_sanitize', 'b_staticpic', 'b_vscrt', + 'b_coverage', 'b_pgo', 'b_ndebug']} self._has_color_support = version_compare(self.version, '>=4.9') # dependencies were implemented before, but broken - support was fixed in GCC 7.1+ @@ -724,7 +726,7 @@ class LLVMDCompiler(DmdLikeCompilerMixin, DCompiler): full_version=full_version, is_cross=is_cross) DmdLikeCompilerMixin.__init__(self, dmd_frontend_version=find_ldc_dmd_frontend_version(version_output)) self.id = 'llvm' - self.base_options = ['b_coverage', 'b_colorout', 'b_vscrt', 'b_ndebug'] + self.base_options = {OptionKey(o) for o in ['b_coverage', 'b_colorout', 'b_vscrt', 'b_ndebug']} def get_colorout_args(self, colortype: str) -> T.List[str]: if colortype == 'always': @@ -782,7 +784,7 @@ class DmdDCompiler(DmdLikeCompilerMixin, DCompiler): full_version=full_version, is_cross=is_cross) DmdLikeCompilerMixin.__init__(self, version) self.id = 'dmd' - self.base_options = ['b_coverage', 'b_colorout', 'b_vscrt', 'b_ndebug'] + self.base_options = {OptionKey(o) for o in ['b_coverage', 'b_colorout', 'b_vscrt', 'b_ndebug']} def get_colorout_args(self, colortype: str) -> T.List[str]: if colortype == 'always': diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py index 4b49e36..d65d585 100644 --- a/mesonbuild/compilers/fortran.py +++ b/mesonbuild/compilers/fortran.py @@ -31,11 +31,12 @@ from .mixins.elbrus import ElbrusCompiler from .mixins.pgi import PGICompiler from mesonbuild.mesonlib import ( - version_compare, EnvironmentException, MesonException, MachineChoice, LibType + version_compare, EnvironmentException, MesonException, MachineChoice, + LibType, OptionKey, ) if T.TYPE_CHECKING: - from ..coredata import OptionDictType + from ..coredata import KeyedOptionDictType from ..dependencies import Dependency, ExternalProgram from ..envconfig import MachineInfo from ..environment import Environment @@ -71,7 +72,7 @@ class FortranCompiler(CLikeCompiler, Compiler): source_name.write_text('print *, "Fortran compilation is working."; end') - extra_flags = [] + extra_flags: T.List[str] = [] extra_flags += environment.coredata.get_external_args(self.for_machine, self.language) extra_flags += environment.coredata.get_external_link_args(self.for_machine, self.language) extra_flags += self.get_always_args() @@ -150,10 +151,11 @@ class FortranCompiler(CLikeCompiler, Compiler): def has_multi_link_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]: return self._has_multi_link_arguments(args, env, 'stop; end program') - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = super().get_options() + key = OptionKey('std', machine=self.for_machine, lang=self.language) opts.update({ - 'std': coredata.UserComboOption( + key: coredata.UserComboOption( 'Fortran language standard to use', ['none'], 'none', @@ -179,19 +181,21 @@ class GnuFortranCompiler(GnuCompiler, FortranCompiler): '2': default_warn_args + ['-Wextra'], '3': default_warn_args + ['-Wextra', '-Wpedantic', '-fimplicit-none']} - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = FortranCompiler.get_options(self) fortran_stds = ['legacy', 'f95', 'f2003'] if version_compare(self.version, '>=4.4.0'): fortran_stds += ['f2008'] if version_compare(self.version, '>=8.0.0'): fortran_stds += ['f2018'] - opts['std'].choices = ['none'] + fortran_stds # type: ignore + key = OptionKey('std', machine=self.for_machine, lang=self.language) + opts[key].choices = ['none'] + fortran_stds return opts - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] - std = options['std'] + key = OptionKey('std', machine=self.for_machine, lang=self.language) + std = options[key] if std.value != 'none': args.append('-std=' + std.value) return args @@ -313,14 +317,16 @@ class IntelFortranCompiler(IntelGnuLikeCompiler, FortranCompiler): '2': default_warn_args + ['-warn', 'unused'], '3': ['-warn', 'all']} - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = FortranCompiler.get_options(self) - opts['std'].choices = ['none', 'legacy', 'f95', 'f2003', 'f2008', 'f2018'] # type: ignore + key = OptionKey('std', machine=self.for_machine, lang=self.language) + opts[key].choices = ['none', 'legacy', 'f95', 'f2003', 'f2008', 'f2018'] return opts - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] - std = options['std'] + key = OptionKey('std', machine=self.for_machine, lang=self.language) + std = options[key] stds = {'legacy': 'none', 'f95': 'f95', 'f2003': 'f03', 'f2008': 'f08', 'f2018': 'f18'} if std.value != 'none': args.append('-stand=' + stds[std.value]) @@ -363,14 +369,16 @@ class IntelClFortranCompiler(IntelVisualStudioLikeCompiler, FortranCompiler): '2': default_warn_args + ['/warn:unused'], '3': ['/warn:all']} - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': opts = FortranCompiler.get_options(self) - opts['std'].choices = ['none', 'legacy', 'f95', 'f2003', 'f2008', 'f2018'] # type: ignore + key = OptionKey('std', machine=self.for_machine, lang=self.language) + opts[key].choices = ['none', 'legacy', 'f95', 'f2003', 'f2008', 'f2018'] return opts - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] - std = options['std'] + key = OptionKey('std', machine=self.for_machine, lang=self.language) + std = options[key] stds = {'legacy': 'none', 'f95': 'f95', 'f2003': 'f03', 'f2008': 'f08', 'f2018': 'f18'} if std.value != 'none': args.append('/stand:' + stds[std.value]) diff --git a/mesonbuild/compilers/mixins/arm.py b/mesonbuild/compilers/mixins/arm.py index ee7d337..beb5fd5 100644 --- a/mesonbuild/compilers/mixins/arm.py +++ b/mesonbuild/compilers/mixins/arm.py @@ -19,6 +19,7 @@ import typing as T from ... import mesonlib from ...linkers import ArmClangDynamicLinker +from ...mesonlib import OptionKey from ..compilers import clike_debug_args from .clang import clang_color_args @@ -145,8 +146,10 @@ class ArmclangCompiler(Compiler): if not mesonlib.version_compare(self.version, '==' + self.linker.version): raise mesonlib.EnvironmentException('armlink version does not match with compiler version') self.id = 'armclang' - self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage', - 'b_ndebug', 'b_staticpic', 'b_colorout'] + self.base_options = { + OptionKey(o) for o in + ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage', + 'b_ndebug', 'b_staticpic', 'b_colorout']} # Assembly self.can_compile_suffixes.add('s') diff --git a/mesonbuild/compilers/mixins/clang.py b/mesonbuild/compilers/mixins/clang.py index 2e50577..fcb2225 100644 --- a/mesonbuild/compilers/mixins/clang.py +++ b/mesonbuild/compilers/mixins/clang.py @@ -20,6 +20,7 @@ import typing as T from ... import mesonlib from ...linkers import AppleDynamicLinker +from ...mesonlib import OptionKey from ..compilers import CompileCheckMode from .gnu import GnuLikeCompiler @@ -48,11 +49,11 @@ class ClangCompiler(GnuLikeCompiler): super().__init__() self.id = 'clang' self.defines = defines or {} - self.base_options.append('b_colorout') + self.base_options.add(OptionKey('b_colorout')) # TODO: this really should be part of the linker base_options, but # linkers don't have base_options. if isinstance(self.linker, AppleDynamicLinker): - self.base_options.append('b_bitcode') + self.base_options.add(OptionKey('b_bitcode')) # All Clang backends can also do LLVM IR self.can_compile_suffixes.add('ll') @@ -108,7 +109,7 @@ class ClangCompiler(GnuLikeCompiler): else: # Shouldn't work, but it'll be checked explicitly in the OpenMP dependency. return [] - + @classmethod def use_linker_args(cls, linker: str) -> T.List[str]: # Clang additionally can use a linker specified as a path, which GCC diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index dca09ea..3288c00 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -35,6 +35,7 @@ from ... import mesonlib from ... import mlog from ...linkers import GnuLikeDynamicLinkerMixin, SolarisDynamicLinker, CompCertDynamicLinker from ...mesonlib import LibType +from ...coredata import OptionKey from .. import compilers from ..compilers import CompileCheckMode from .visualstudio import VisualStudioLikeCompiler @@ -393,14 +394,16 @@ class CLikeCompiler(Compiler): # linking with static libraries since MSVC won't select a CRT for # us in that case and will error out asking us to pick one. try: - crt_val = env.coredata.base_options['b_vscrt'].value - buildtype = env.coredata.builtins['buildtype'].value + crt_val = env.coredata.options[OptionKey('b_vscrt')].value + buildtype = env.coredata.options[OptionKey('buildtype')].value cargs += self.get_crt_compile_args(crt_val, buildtype) except (KeyError, AttributeError): pass # Add CFLAGS/CXXFLAGS/OBJCFLAGS/OBJCXXFLAGS and CPPFLAGS from the env sys_args = env.coredata.get_external_args(self.for_machine, self.language) + if isinstance(sys_args, str): + sys_args = [sys_args] # Apparently it is a thing to inject linker flags both # via CFLAGS _and_ LDFLAGS, even though the former are # also used during linking. These flags can break diff --git a/mesonbuild/compilers/mixins/elbrus.py b/mesonbuild/compilers/mixins/elbrus.py index 2ea3599..16f6210 100644 --- a/mesonbuild/compilers/mixins/elbrus.py +++ b/mesonbuild/compilers/mixins/elbrus.py @@ -21,7 +21,7 @@ import re from .gnu import GnuLikeCompiler from .gnu import gnu_optimization_args -from ...mesonlib import Popen_safe +from ...mesonlib import Popen_safe, OptionKey if T.TYPE_CHECKING: from ...environment import Environment @@ -34,9 +34,7 @@ class ElbrusCompiler(GnuLikeCompiler): def __init__(self) -> None: super().__init__() self.id = 'lcc' - self.base_options = ['b_pgo', 'b_coverage', - 'b_ndebug', 'b_staticpic', - 'b_lundef', 'b_asneeded'] + self.base_options = {OptionKey(o) for o in ['b_pgo', 'b_coverage', 'b_ndebug', 'b_staticpic', 'b_lundef', 'b_asneeded']} # FIXME: use _build_wrapper to call this so that linker flags from the env # get applied diff --git a/mesonbuild/compilers/mixins/emscripten.py b/mesonbuild/compilers/mixins/emscripten.py index cd18b35..fc0b21e 100644 --- a/mesonbuild/compilers/mixins/emscripten.py +++ b/mesonbuild/compilers/mixins/emscripten.py @@ -18,6 +18,7 @@ import os.path import typing as T from ... import coredata +from ...mesonlib import OptionKey if T.TYPE_CHECKING: from ...environment import Environment @@ -50,15 +51,16 @@ class EmscriptenMixin(Compiler): def thread_link_flags(self, env: 'Environment') -> T.List[str]: args = ['-s', 'USE_PTHREADS=1'] - count = env.coredata.compiler_options[self.for_machine][self.language]['thread_count'].value # type: int + count: int = env.coredata.options[OptionKey('thread_count', lang=self.language, machine=self.for_machine)].value if count: args.extend(['-s', 'PTHREAD_POOL_SIZE={}'.format(count)]) return args - def get_options(self) -> 'coredata.OptionDictType': + def get_options(self) -> 'coredata.KeyedOptionDictType': opts = super().get_options() + key = OptionKey('thread_count', machine=self.for_machine, lang=self.language) opts.update({ - 'thread_count': coredata.UserIntegerOption( + key: coredata.UserIntegerOption( '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/mixins/gnu.py b/mesonbuild/compilers/mixins/gnu.py index 3d43162..95bcd7c 100644 --- a/mesonbuild/compilers/mixins/gnu.py +++ b/mesonbuild/compilers/mixins/gnu.py @@ -24,6 +24,7 @@ import typing as T from ... import mesonlib from ... import mlog +from ...mesonlib import OptionKey if T.TYPE_CHECKING: from ...environment import Environment @@ -146,14 +147,15 @@ class GnuLikeCompiler(Compiler, metaclass=abc.ABCMeta): LINKER_PREFIX = '-Wl,' def __init__(self) -> None: - self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_coverage', - 'b_ndebug', 'b_staticpic', 'b_pie'] + self.base_options = { + OptionKey(o) for o in ['b_pch', 'b_lto', 'b_pgo', 'b_coverage', + 'b_ndebug', 'b_staticpic', 'b_pie']} if not (self.info.is_windows() or self.info.is_cygwin() or self.info.is_openbsd()): - self.base_options.append('b_lundef') + self.base_options.add(OptionKey('b_lundef')) if not self.info.is_windows() or self.info.is_cygwin(): - self.base_options.append('b_asneeded') + self.base_options.add(OptionKey('b_asneeded')) if not self.info.is_hurd(): - self.base_options.append('b_sanitize') + self.base_options.add(OptionKey('b_sanitize')) # All GCC-like backends can do assembly self.can_compile_suffixes.add('s') @@ -328,7 +330,7 @@ class GnuCompiler(GnuLikeCompiler): super().__init__() self.id = 'gcc' self.defines = defines or {} - self.base_options.append('b_colorout') + self.base_options.add(OptionKey('b_colorout')) def get_colorout_args(self, colortype: str) -> T.List[str]: if mesonlib.version_compare(self.version, '>=4.9.0'): diff --git a/mesonbuild/compilers/mixins/intel.py b/mesonbuild/compilers/mixins/intel.py index 442e8c7..5bca254 100644 --- a/mesonbuild/compilers/mixins/intel.py +++ b/mesonbuild/compilers/mixins/intel.py @@ -79,8 +79,9 @@ class IntelGnuLikeCompiler(GnuLikeCompiler): # It does have IPO, which serves much the same purpose as LOT, but # there is an unfortunate rule for using IPO (you can't control the # name of the output file) which break assumptions meson makes - self.base_options = ['b_pch', 'b_lundef', 'b_asneeded', 'b_pgo', - 'b_coverage', 'b_ndebug', 'b_staticpic', 'b_pie'] + self.base_options = {mesonlib.OptionKey(o) for o in [ + 'b_pch', 'b_lundef', 'b_asneeded', 'b_pgo', 'b_coverage', + 'b_ndebug', 'b_staticpic', 'b_pie']} self.id = 'intel' self.lang_header = 'none' diff --git a/mesonbuild/compilers/mixins/islinker.py b/mesonbuild/compilers/mixins/islinker.py index 2445eec..3fe3382 100644 --- a/mesonbuild/compilers/mixins/islinker.py +++ b/mesonbuild/compilers/mixins/islinker.py @@ -25,7 +25,7 @@ import typing as T from ... import mesonlib if T.TYPE_CHECKING: - from ...coredata import OptionDictType + from ...coredata import KeyedOptionDictType from ...environment import Environment from ...compilers.compilers import Compiler else: @@ -66,7 +66,7 @@ class BasicLinkerIsCompilerMixin(Compiler): def get_linker_lib_prefix(self) -> str: return '' - def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: return [] def has_multi_link_args(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]: @@ -78,7 +78,7 @@ class BasicLinkerIsCompilerMixin(Compiler): def get_std_shared_lib_link_args(self) -> T.List[str]: return [] - def get_std_shared_module_args(self, options: 'OptionDictType') -> T.List[str]: + def get_std_shared_module_args(self, options: 'KeyedOptionDictType') -> T.List[str]: return self.get_std_shared_lib_link_args() def get_link_whole_for(self, args: T.List[str]) -> T.List[str]: diff --git a/mesonbuild/compilers/mixins/pgi.py b/mesonbuild/compilers/mixins/pgi.py index 61dee8d..8461574 100644 --- a/mesonbuild/compilers/mixins/pgi.py +++ b/mesonbuild/compilers/mixins/pgi.py @@ -19,6 +19,7 @@ import os from pathlib import Path from ..compilers import clike_debug_args, clike_optimization_args +from ...mesonlib import OptionKey if T.TYPE_CHECKING: from ...environment import Environment @@ -43,7 +44,7 @@ pgi_buildtype_args = { class PGICompiler(Compiler): def __init__(self) -> None: - self.base_options = ['b_pch'] + self.base_options = {OptionKey('b_pch')} self.id = 'pgi' default_warn_args = ['-Minform=inform'] diff --git a/mesonbuild/compilers/mixins/visualstudio.py b/mesonbuild/compilers/mixins/visualstudio.py index c38d59a..92f4fcd 100644 --- a/mesonbuild/compilers/mixins/visualstudio.py +++ b/mesonbuild/compilers/mixins/visualstudio.py @@ -129,7 +129,7 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta): INVOKES_LINKER = False def __init__(self, target: str): - self.base_options = ['b_pch', 'b_ndebug', 'b_vscrt'] # FIXME add lto, pgo and the like + self.base_options = {mesonlib.OptionKey(o) for o in ['b_pch', 'b_ndebug', 'b_vscrt']} # FIXME add lto, pgo and the like self.target = target self.is_64 = ('x64' in target) or ('x86_64' in target) # do some canonicalization of target machine diff --git a/mesonbuild/compilers/objc.py b/mesonbuild/compilers/objc.py index 1b280eb..e47bf2f 100644 --- a/mesonbuild/compilers/objc.py +++ b/mesonbuild/compilers/objc.py @@ -51,7 +51,7 @@ class ObjCCompiler(CLikeCompiler, Compiler): # TODO try to use sanity_check_impl instead of duplicated code source_name = os.path.join(work_dir, 'sanitycheckobjc.m') binary_name = os.path.join(work_dir, 'sanitycheckobjc') - extra_flags = [] + extra_flags: T.List[str] = [] extra_flags += environment.coredata.get_external_args(self.for_machine, self.language) if self.is_cross: extra_flags += self.get_compile_only_args() diff --git a/mesonbuild/compilers/objcpp.py b/mesonbuild/compilers/objcpp.py index 16ba77e..c0f93d7 100644 --- a/mesonbuild/compilers/objcpp.py +++ b/mesonbuild/compilers/objcpp.py @@ -50,7 +50,7 @@ class ObjCPPCompiler(CLikeCompiler, Compiler): # TODO try to use sanity_check_impl instead of duplicated code source_name = os.path.join(work_dir, 'sanitycheckobjcpp.mm') binary_name = os.path.join(work_dir, 'sanitycheckobjcpp') - extra_flags = [] + extra_flags: T.List[str] = [] extra_flags += environment.coredata.get_external_args(self.for_machine, self.language) if self.is_cross: extra_flags += self.get_compile_only_args() diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py index 312b3b6..fd58819 100644 --- a/mesonbuild/compilers/rust.py +++ b/mesonbuild/compilers/rust.py @@ -17,11 +17,14 @@ import textwrap import typing as T from .. import coredata -from ..mesonlib import EnvironmentException, MachineChoice, MesonException, Popen_safe +from ..mesonlib import ( + EnvironmentException, MachineChoice, MesonException, Popen_safe, + OptionKey, +) from .compilers import Compiler, rust_buildtype_args, clike_debug_args if T.TYPE_CHECKING: - from ..coredata import OptionDictType + from ..coredata import KeyedOptionDictType from ..dependencies import ExternalProgram from ..envconfig import MachineInfo from ..environment import Environment # noqa: F401 @@ -52,9 +55,9 @@ class RustCompiler(Compiler): linker=linker) self.exe_wrapper = exe_wrapper self.id = 'rustc' - self.base_options.append('b_colorout') + self.base_options.add(OptionKey('b_colorout')) if 'link' in self.linker.id: - self.base_options.append('b_vscrt') + self.base_options.add(OptionKey('b_vscrt')) def needs_static_linker(self) -> bool: return False @@ -133,18 +136,20 @@ class RustCompiler(Compiler): # C compiler for dynamic linking, as such we invoke the C compiler's # use_linker_args method instead. - def get_options(self) -> 'OptionDictType': + def get_options(self) -> 'KeyedOptionDictType': + key = OptionKey('std', machine=self.for_machine, lang=self.language) return { - 'std': coredata.UserComboOption( + key: coredata.UserComboOption( 'Rust Eddition to use', ['none', '2015', '2018'], 'none', ), } - def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: + def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = [] - std = options['std'] + key = OptionKey('std', machine=self.for_machine, lang=self.language) + std = options[key] if std.value != 'none': args.append('--edition=' + std.value) return args diff --git a/mesonbuild/compilers/swift.py b/mesonbuild/compilers/swift.py index 8682e54..7b18591 100644 --- a/mesonbuild/compilers/swift.py +++ b/mesonbuild/compilers/swift.py @@ -101,7 +101,7 @@ class SwiftCompiler(Compiler): src = 'swifttest.swift' source_name = os.path.join(work_dir, src) output_name = os.path.join(work_dir, 'swifttest') - extra_flags = [] + extra_flags: T.List[str] = [] extra_flags += environment.coredata.get_external_args(self.for_machine, self.language) if self.is_cross: extra_flags += self.get_compile_only_args() diff --git a/mesonbuild/compilers/vala.py b/mesonbuild/compilers/vala.py index af800c2..80e91f6 100644 --- a/mesonbuild/compilers/vala.py +++ b/mesonbuild/compilers/vala.py @@ -16,7 +16,7 @@ import os.path import typing as T from .. import mlog -from ..mesonlib import EnvironmentException, MachineChoice, version_compare +from ..mesonlib import EnvironmentException, MachineChoice, version_compare, OptionKey from .compilers import Compiler, LibType @@ -33,7 +33,7 @@ class ValaCompiler(Compiler): super().__init__(exelist, version, for_machine, info, is_cross=is_cross) self.version = version self.id = 'valac' - self.base_options = ['b_colorout'] + self.base_options = {OptionKey('b_colorout')} def needs_static_linker(self) -> bool: return False # Because compiles into C. @@ -92,7 +92,7 @@ class ValaCompiler(Compiler): def sanity_check(self, work_dir: str, environment: 'Environment') -> None: code = 'class MesonSanityCheck : Object { }' - extra_flags = [] + extra_flags: T.List[str] = [] extra_flags += environment.coredata.get_external_args(self.for_machine, self.language) if self.is_cross: extra_flags += self.get_compile_only_args() @@ -116,7 +116,7 @@ class ValaCompiler(Compiler): # no extra dirs are specified. if not extra_dirs: code = 'class MesonFindLibrary : Object { }' - args = [] + args: T.List[str] = [] args += env.coredata.get_external_args(self.for_machine, self.language) vapi_args = ['--pkg', libname] args += vapi_args |