summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2024-08-29 10:22:53 -0700
committerJussi Pakkanen <jpakkane@gmail.com>2025-02-05 17:45:38 +0200
commitfe9f8de1ab52af0a6f4c3a1ce054ee3e2eb7a74c (patch)
treefe25957a1db43513a0b61183d431b498dea40013
parentf0a6ba380989c68ecc5af61087157557b329f808 (diff)
downloadmeson-fe9f8de1ab52af0a6f4c3a1ce054ee3e2eb7a74c.tar.gz
compilers: remove Compiler.create_option
This saves a *tiny* bit of typing, but at the cost of requiring either the current solution of throwing up our hands and saying "typing is too hard, better to have bugs!" or an extensive amount of `TypedDict`s, `overloads`, and a very new version of mypy. Let's get our type safety back, even if it means writing a little bit more code.
-rw-r--r--mesonbuild/compilers/c.py40
-rw-r--r--mesonbuild/compilers/compilers.py4
-rw-r--r--mesonbuild/compilers/cpp.py218
-rw-r--r--mesonbuild/compilers/cuda.py28
-rw-r--r--mesonbuild/compilers/cython.py32
-rw-r--r--mesonbuild/compilers/fortran.py18
-rw-r--r--mesonbuild/compilers/mixins/emscripten.py18
-rw-r--r--mesonbuild/compilers/objc.py10
-rw-r--r--mesonbuild/compilers/objcpp.py15
-rw-r--r--mesonbuild/compilers/rust.py15
10 files changed, 217 insertions, 181 deletions
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index cec6fc3ae..d8ad9f793 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -123,13 +123,11 @@ class ClangCCompiler(ClangCStds, ClangCompiler, CCompiler):
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = super().get_options()
if self.info.is_windows() or self.info.is_cygwin():
- self.update_options(
- opts,
- self.create_option(options.UserArrayOption,
- self.form_compileropt_key('winlibs'),
- 'Standard Windows libs to link against',
- gnu_winlibs),
- )
+ key = self.form_compileropt_key('winlibs')
+ opts[key] = options.UserArrayOption(
+ self.make_option_name(key),
+ 'Standard Windows libraries to link against',
+ gnu_winlibs)
return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
@@ -258,13 +256,11 @@ class GnuCCompiler(GnuCStds, GnuCompiler, CCompiler):
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = super().get_options()
if self.info.is_windows() or self.info.is_cygwin():
- self.update_options(
- opts,
- self.create_option(options.UserArrayOption,
- self.form_compileropt_key('winlibs'),
- 'Standard Windows libs to link against',
- gnu_winlibs),
- )
+ key = self.form_compileropt_key('winlibs')
+ opts[key] = options.UserArrayOption(
+ self.make_option_name(key),
+ 'Standard Windows libraries to link against',
+ gnu_winlibs)
return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
@@ -408,15 +404,13 @@ class VisualStudioLikeCCompilerMixin(CompilerMixinBase):
"""Shared methods that apply to MSVC-like C compilers."""
def get_options(self) -> MutableKeyedOptionDictType:
- return self.update_options(
- super().get_options(),
- self.create_option(
- options.UserArrayOption,
- self.form_compileropt_key('winlibs'),
- 'Standard Windows libs to link against',
- msvc_winlibs,
- ),
- )
+ opts = super().get_options()
+ key = self.form_compileropt_key('winlibs')
+ opts[key] = options.UserArrayOption(
+ self.make_option_name(key),
+ 'Standard Windows libraries to link against',
+ msvc_winlibs)
+ return opts
def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
# need a TypeDict to make this work
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index 011dacfb7..12bcd1e4c 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -588,8 +588,8 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
"""
return []
- def create_option(self, option_type: T.Type[UserOptionType], option_key: OptionKey, *args: T.Any, **kwargs: T.Any) -> T.Tuple[OptionKey, UserOptionType]:
- return option_key, option_type(f'{self.language}_{option_key.name}', *args, **kwargs)
+ def make_option_name(self, key: OptionKey) -> str:
+ return f'{self.language}_{key.name}'
@staticmethod
def update_options(options: MutableKeyedOptionDictType, *args: T.Tuple[OptionKey, UserOptionType]) -> MutableKeyedOptionDictType:
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index fd0573ce9..b17e18b3e 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -237,30 +237,32 @@ class ClangCPPCompiler(_StdCPPLibMixin, ClangCPPStds, ClangCompiler, CPPCompiler
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = super().get_options()
- self.update_options(
- opts,
- self.create_option(options.UserComboOption,
- self.form_compileropt_key('eh'),
- 'C++ exception handling type',
- ['none', 'default', 'a', 's', 'sc'],
- 'default'),
- self.create_option(options.UserBooleanOption,
- self.form_compileropt_key('rtti'),
- 'Enable RTTI',
- True),
- self.create_option(options.UserBooleanOption,
- self.form_compileropt_key('debugstl'),
- 'STL debug mode',
- False),
- )
+
+ key = self.form_compileropt_key('eh')
+ opts[key] = options.UserComboOption(
+ self.make_option_name(key),
+ 'C++ exception handling type.',
+ ['none', 'default', 'a', 's', 'sc'],
+ 'default')
+
+ key = self.form_compileropt_key('rtti')
+ opts[key] = options.UserBooleanOption(
+ self.make_option_name(key),
+ 'Enable RTTI',
+ True)
+
+ key = self.form_compileropt_key('debugstl')
+ opts[key] = options.UserBooleanOption(
+ self.make_option_name(key),
+ 'STL debug mode',
+ False)
+
if self.info.is_windows() or self.info.is_cygwin():
- self.update_options(
- opts,
- self.create_option(options.UserArrayOption,
- self.form_compileropt_key('winlibs'),
- 'Standard Windows libs to link against',
- gnu_winlibs),
- )
+ key = self.form_compileropt_key('winlibs')
+ opts[key] = options.UserArrayOption(
+ self.make_option_name(key),
+ 'Standard Win libraries to link against',
+ gnu_winlibs)
return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
@@ -391,15 +393,15 @@ class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler):
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = super().get_options()
+
+ key = self.form_compileropt_key('eh')
+ opts[key] = options.UserComboOption(
+ self.make_option_name(key),
+ 'C++ exception handling type.',
+ ['none', 'default', 'a', 's', 'sc'],
+ 'default')
+
key = self.form_compileropt_key('std')
- self.update_options(
- opts,
- self.create_option(options.UserComboOption,
- key.evolve('eh'),
- 'C++ exception handling type',
- ['none', 'default', 'a', 's', 'sc'],
- 'default'),
- )
std_opt = opts[key]
assert isinstance(std_opt, options.UserStdOption), 'for mypy'
std_opt.set_versions(['c++98', 'c++03', 'c++11', 'c++14', 'c++17'], gnu=True)
@@ -440,32 +442,34 @@ class GnuCPPCompiler(_StdCPPLibMixin, GnuCPPStds, GnuCompiler, CPPCompiler):
self.supported_warn_args(gnu_cpp_warning_args))}
def get_options(self) -> 'MutableKeyedOptionDictType':
- key = self.form_compileropt_key('std')
opts = super().get_options()
- self.update_options(
- opts,
- self.create_option(options.UserComboOption,
- self.form_compileropt_key('eh'),
- 'C++ exception handling type',
- ['none', 'default', 'a', 's', 'sc'],
- 'default'),
- self.create_option(options.UserBooleanOption,
- self.form_compileropt_key('rtti'),
- 'Enable RTTI',
- True),
- self.create_option(options.UserBooleanOption,
- self.form_compileropt_key('debugstl'),
- 'STL debug mode',
- False),
- )
+
+ key = self.form_compileropt_key('eh')
+ opts[key] = options.UserComboOption(
+ self.make_option_name(key),
+ 'C++ exception handling type.',
+ ['none', 'default', 'a', 's', 'sc'],
+ 'default')
+
+ key = self.form_compileropt_key('rtti')
+ opts[key] = options.UserBooleanOption(
+ self.make_option_name(key),
+ 'Enable RTTI',
+ True)
+
+ key = self.form_compileropt_key('debugstl')
+ opts[key] = options.UserBooleanOption(
+ self.make_option_name(key),
+ 'STL debug mode',
+ False)
+
if self.info.is_windows() or self.info.is_cygwin():
- self.update_options(
- opts,
- self.create_option(options.UserArrayOption,
- key.evolve('cpp_winlibs'),
- 'Standard Windows libs to link against',
- gnu_winlibs),
- )
+ key = key.evolve(name='cpp_winlibs')
+ opts[key] = options.UserArrayOption(
+ self.make_option_name(key),
+ 'Standard Win libraries to link against',
+ gnu_winlibs)
+
return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
@@ -569,6 +573,19 @@ class ElbrusCPPCompiler(ElbrusCompiler, CPPCompiler):
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = super().get_options()
+ key = self.form_compileropt_key('eh')
+ opts[key] = options.UserComboOption(
+ self.make_option_name(key),
+ 'C++ exception handling type.',
+ ['none', 'default', 'a', 's', 'sc'],
+ 'default')
+
+ key = self.form_compileropt_key('debugstl')
+ opts[key] = options.UserBooleanOption(
+ self.make_option_name(key),
+ 'STL debug mode',
+ False)
+
cpp_stds = ['c++98']
if version_compare(self.version, '>=1.20.00'):
cpp_stds += ['c++03', 'c++0x', 'c++11']
@@ -586,18 +603,6 @@ class ElbrusCPPCompiler(ElbrusCompiler, CPPCompiler):
cpp_stds += ['c++20']
key = self.form_compileropt_key('std')
- self.update_options(
- opts,
- self.create_option(options.UserComboOption,
- self.form_compileropt_key('eh'),
- 'C++ exception handling type',
- ['none', 'default', 'a', 's', 'sc'],
- 'default'),
- self.create_option(options.UserBooleanOption,
- self.form_compileropt_key('debugstl'),
- 'STL debug mode',
- False),
- )
std_opt = opts[key]
assert isinstance(std_opt, options.UserStdOption), 'for mypy'
std_opt.set_versions(cpp_stds, gnu=True)
@@ -650,6 +655,26 @@ class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler):
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = super().get_options()
+
+ key = self.form_compileropt_key('eh')
+ opts[key] = options.UserComboOption(
+ self.make_option_name(key),
+ 'C++ exception handling type.',
+ ['none', 'default', 'a', 's', 'sc'],
+ 'default')
+
+ key = self.form_compileropt_key('rtti')
+ opts[key] = options.UserBooleanOption(
+ self.make_option_name(key),
+ 'Enable RTTI',
+ True)
+
+ key = self.form_compileropt_key('debugstl')
+ opts[key] = options.UserBooleanOption(
+ self.make_option_name(key),
+ 'STL debug mode',
+ False)
+
# Every Unix compiler under the sun seems to accept -std=c++03,
# with the exception of ICC. Instead of preventing the user from
# globally requesting C++03, we transparently remap it to C++98
@@ -666,24 +691,7 @@ class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler):
c_stds += ['c++2a']
g_stds += ['gnu++2a']
- key = self.form_compileropt_key('std')
- self.update_options(
- opts,
- self.create_option(options.UserComboOption,
- self.form_compileropt_key('eh'),
- 'C++ exception handling type',
- ['none', 'default', 'a', 's', 'sc'],
- 'default'),
- self.create_option(options.UserBooleanOption,
- self.form_compileropt_key('rtti'),
- 'Enable RTTI',
- True),
- self.create_option(options.UserBooleanOption,
- self.form_compileropt_key('debugstl'),
- 'STL debug mode',
- False),
- )
- std_opt = opts[key]
+ std_opt = opts[self.form_compileropt_key('std')]
assert isinstance(std_opt, options.UserStdOption), 'for mypy'
std_opt.set_versions(c_stds + g_stds)
return opts
@@ -739,24 +747,28 @@ class VisualStudioLikeCPPCompilerMixin(CompilerMixinBase):
return T.cast('T.List[str]', options.get_value(key)[:])
def _get_options_impl(self, opts: 'MutableKeyedOptionDictType', cpp_stds: T.List[str]) -> 'MutableKeyedOptionDictType':
- key = self.form_compileropt_key('std')
- self.update_options(
- opts,
- self.create_option(options.UserComboOption,
- self.form_compileropt_key('eh'),
- 'C++ exception handling type',
- ['none', 'default', 'a', 's', 'sc'],
- 'default'),
- self.create_option(options.UserBooleanOption,
- self.form_compileropt_key('rtti'),
- 'Enable RTTI',
- True),
- self.create_option(options.UserArrayOption,
- self.form_compileropt_key('winlibs'),
- 'Standard Windows libs to link against',
- msvc_winlibs),
- )
- std_opt = opts[key]
+ opts = super().get_options()
+
+ key = self.form_compileropt_key('eh')
+ opts[key] = options.UserComboOption(
+ self.make_option_name(key),
+ 'C++ exception handling type.',
+ ['none', 'default', 'a', 's', 'sc'],
+ 'default')
+
+ key = self.form_compileropt_key('rtti')
+ opts[key] = options.UserBooleanOption(
+ self.make_option_name(key),
+ 'Enable RTTI',
+ True)
+
+ key = self.form_compileropt_key('winlibs')
+ opts[key] = options.UserArrayOption(
+ self.make_option_name(key),
+ 'Standard Win libraries to link against',
+ msvc_winlibs)
+
+ std_opt = opts[self.form_compileropt_key('std')]
assert isinstance(std_opt, options.UserStdOption), 'for mypy'
std_opt.set_versions(cpp_stds)
return opts
diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py
index 38a938f24..07fda95dd 100644
--- a/mesonbuild/compilers/cuda.py
+++ b/mesonbuild/compilers/cuda.py
@@ -646,18 +646,22 @@ class CudaCompiler(Compiler):
if version_compare(self.version, self._CPP20_VERSION):
cpp_stds += ['c++20']
- return self.update_options(
- super().get_options(),
- self.create_option(options.UserComboOption,
- self.form_compileropt_key('std'),
- 'C++ language standard to use with CUDA',
- cpp_stds,
- 'none'),
- self.create_option(options.UserStringOption,
- self.form_compileropt_key('ccbindir'),
- 'CUDA non-default toolchain directory to use (-ccbin)',
- ''),
- )
+ opts = super().get_options()
+
+ key = self.form_compileropt_key('std')
+ opts[key] = options.UserComboOption(
+ self.make_option_name(key),
+ 'C++ language standard to use with CUDA',
+ cpp_stds,
+ 'none')
+
+ key = self.form_compileropt_key('ccbindir')
+ opts[key] = options.UserStringOption(
+ self.make_option_name(key),
+ 'CUDA non-default toolchain directory to use (-ccbin)',
+ '')
+
+ return opts
def _to_host_compiler_options(self, master_options: 'KeyedOptionDictType') -> 'KeyedOptionDictType':
"""
diff --git a/mesonbuild/compilers/cython.py b/mesonbuild/compilers/cython.py
index 5cc020045..2d0f21d00 100644
--- a/mesonbuild/compilers/cython.py
+++ b/mesonbuild/compilers/cython.py
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
-# Copyright © 2021 Intel Corporation
+# Copyright © 2021-2024 Intel Corporation
from __future__ import annotations
"""Abstraction for Cython language compilers."""
@@ -67,19 +67,23 @@ class CythonCompiler(Compiler):
return new
def get_options(self) -> 'MutableKeyedOptionDictType':
- return self.update_options(
- super().get_options(),
- self.create_option(options.UserComboOption,
- self.form_compileropt_key('version'),
- 'Python version to target',
- ['2', '3'],
- '3'),
- self.create_option(options.UserComboOption,
- self.form_compileropt_key('language'),
- 'Output C or C++ files',
- ['c', 'cpp'],
- 'c'),
- )
+ opts = super().get_options()
+
+ key = self.form_compileropt_key('version')
+ opts[key] = options.UserComboOption(
+ self.make_option_name(key),
+ 'Python version to target',
+ ['2', '3'],
+ '3')
+
+ key = self.form_compileropt_key('language')
+ opts[key] = options.UserComboOption(
+ self.make_option_name(key),
+ 'Output C or C++ files',
+ ['c', 'cpp'],
+ 'c')
+
+ return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args: T.List[str] = []
diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py
index 0e41b70e9..f771e4c40 100644
--- a/mesonbuild/compilers/fortran.py
+++ b/mesonbuild/compilers/fortran.py
@@ -114,14 +114,16 @@ class FortranCompiler(CLikeCompiler, Compiler):
return self._has_multi_link_arguments(args, env, 'stop; end program')
def get_options(self) -> 'MutableKeyedOptionDictType':
- return self.update_options(
- super().get_options(),
- self.create_option(options.UserComboOption,
- self.form_compileropt_key('std'),
- 'Fortran language standard to use',
- ['none'],
- 'none'),
- )
+ opts = super().get_options()
+
+ key = self.form_compileropt_key('std')
+ opts[key] = options.UserComboOption(
+ self.make_option_name(key),
+ 'Fortran language standard to use',
+ ['none'],
+ 'none')
+
+ return opts
def _compile_int(self, expression: str, prefix: str, env: 'Environment',
extra_args: T.Union[None, T.List[str], T.Callable[[CompileCheckMode], T.List[str]]],
diff --git a/mesonbuild/compilers/mixins/emscripten.py b/mesonbuild/compilers/mixins/emscripten.py
index 64315ae96..fa8620569 100644
--- a/mesonbuild/compilers/mixins/emscripten.py
+++ b/mesonbuild/compilers/mixins/emscripten.py
@@ -57,15 +57,15 @@ class EmscriptenMixin(Compiler):
return args
def get_options(self) -> coredata.MutableKeyedOptionDictType:
- return self.update_options(
- super().get_options(),
- self.create_option(
- options.UserIntegerOption,
- 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
- ),
- )
+ opts = super().get_options()
+
+ key = OptionKey(f'{self.language}_thread_count', machine=self.for_machine)
+ opts[key] = options.UserIntegerOption(
+ self.make_option_name(key),
+ 'Number of threads to use in web assembly, set to 0 to disable',
+ (0, None, 4)) # Default was picked at random
+
+ return opts
@classmethod
def native_args_to_unix(cls, args: T.List[str]) -> T.List[str]:
diff --git a/mesonbuild/compilers/objc.py b/mesonbuild/compilers/objc.py
index 56bc12d45..262a4c484 100644
--- a/mesonbuild/compilers/objc.py
+++ b/mesonbuild/compilers/objc.py
@@ -99,6 +99,16 @@ class ClangObjCCompiler(ClangCStds, ClangCompiler, ObjCCompiler):
'3': default_warn_args + ['-Wextra', '-Wpedantic'],
'everything': ['-Weverything']}
+ def form_compileropt_key(self, basename: str) -> OptionKey:
+ if basename == 'std':
+ return OptionKey('c_std', machine=self.for_machine)
+ return super().form_compileropt_key(basename)
+
+ def make_option_name(self, key: OptionKey) -> str:
+ if key.name == 'std':
+ return 'c_std'
+ return super().make_option_name(key)
+
def get_option_compile_args(self, options: 'coredata.KeyedOptionDictType') -> T.List[str]:
args = []
std = options.get_value(self.form_compileropt_key('std'))
diff --git a/mesonbuild/compilers/objcpp.py b/mesonbuild/compilers/objcpp.py
index de968be42..104d0cb82 100644
--- a/mesonbuild/compilers/objcpp.py
+++ b/mesonbuild/compilers/objcpp.py
@@ -35,6 +35,16 @@ class ObjCPPCompiler(CLikeCompiler, Compiler):
linker=linker)
CLikeCompiler.__init__(self)
+ def form_compileropt_key(self, basename: str) -> OptionKey:
+ if basename == 'std':
+ return OptionKey('cpp_std', machine=self.for_machine)
+ return super().form_compileropt_key(basename)
+
+ def make_option_name(self, key: OptionKey) -> str:
+ if key.name == 'std':
+ return 'cpp_std'
+ return super().make_option_name(key)
+
@staticmethod
def get_display_language() -> str:
return 'Objective-C++'
@@ -43,11 +53,6 @@ class ObjCPPCompiler(CLikeCompiler, Compiler):
code = '#import<stdio.h>\nclass MyClass;int main(void) { return 0; }\n'
return self._sanity_check_impl(work_dir, environment, 'sanitycheckobjcpp.mm', code)
- def form_compileropt_key(self, basename: str) -> OptionKey:
- if basename == 'std':
- return OptionKey(f'cpp_{basename}', machine=self.for_machine)
- return super().form_compileropt_key(basename)
-
def get_options(self) -> coredata.MutableKeyedOptionDictType:
opts = super().get_options()
key = self.form_compileropt_key('std')
diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py
index b8588b8d7..40c85ee68 100644
--- a/mesonbuild/compilers/rust.py
+++ b/mesonbuild/compilers/rust.py
@@ -234,11 +234,16 @@ class RustCompiler(Compiler):
# use_linker_args method instead.
def get_options(self) -> MutableKeyedOptionDictType:
- return dict((self.create_option(options.UserComboOption,
- self.form_compileropt_key('std'),
- 'Rust edition to use',
- ['none', '2015', '2018', '2021', '2024'],
- 'none'),))
+ opts = super().get_options()
+
+ key = self.form_compileropt_key('std')
+ opts[key] = options.UserComboOption(
+ self.make_option_name(key),
+ 'Rust edition to use',
+ ['none', '2015', '2018', '2021', '2024'],
+ 'none')
+
+ return opts
def get_dependency_compile_args(self, dep: 'Dependency') -> T.List[str]:
# Rust doesn't have dependency compile arguments so simply return