aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/compilers
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2024-04-14 12:58:30 +0300
committerJussi Pakkanen <jpakkane@gmail.com>2025-02-13 15:26:44 +0200
commit518c732ea9b0f1975f6f28accff3286be4106538 (patch)
tree2be9544828545a2f9f0676efc6eb82ac197ec4bd /mesonbuild/compilers
parentea678ed82938ceac00682b2695b57193d36b71b4 (diff)
downloadmeson-optionrefactor3.zip
meson-optionrefactor3.tar.gz
meson-optionrefactor3.tar.bz2
Make all Meson level options overridable per subproject.optionrefactor3
Diffstat (limited to 'mesonbuild/compilers')
-rw-r--r--mesonbuild/compilers/c.py120
-rw-r--r--mesonbuild/compilers/compilers.py179
-rw-r--r--mesonbuild/compilers/cpp.py216
-rw-r--r--mesonbuild/compilers/cuda.py49
-rw-r--r--mesonbuild/compilers/cython.py14
-rw-r--r--mesonbuild/compilers/fortran.py21
-rw-r--r--mesonbuild/compilers/mixins/clike.py2
-rw-r--r--mesonbuild/compilers/mixins/elbrus.py11
-rw-r--r--mesonbuild/compilers/mixins/emscripten.py3
-rw-r--r--mesonbuild/compilers/mixins/islinker.py3
-rw-r--r--mesonbuild/compilers/objc.py19
-rw-r--r--mesonbuild/compilers/objcpp.py19
-rw-r--r--mesonbuild/compilers/rust.py9
-rw-r--r--mesonbuild/compilers/vala.py4
14 files changed, 395 insertions, 274 deletions
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index 4f93ea1..4f2bd2f 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -8,6 +8,7 @@ import os.path
import typing as T
from .. import options
+from ..options import OptionKey
from .. import mlog
from ..mesonlib import MesonException, version_compare
from .c_function_attributes import C_FUNC_ATTRIBUTES
@@ -36,13 +37,14 @@ from .compilers import (
)
if T.TYPE_CHECKING:
- from ..coredata import MutableKeyedOptionDictType, KeyedOptionDictType
+ from ..coredata import MutableKeyedOptionDictType
from ..dependencies import Dependency
from ..envconfig import MachineInfo
from ..environment import Environment
from ..linkers.linkers import DynamicLinker
from ..mesonlib import MachineChoice
from .compilers import CompileCheckMode
+ from ..build import BuildTarget
CompilerMixinBase = Compiler
else:
@@ -130,20 +132,19 @@ class ClangCCompiler(ClangCStds, ClangCompiler, CCompiler):
gnu_winlibs)
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ std = self.get_compileropt_value('std', env, target, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append('-std=' + std)
return args
- def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
if self.info.is_windows() or self.info.is_cygwin():
- # without a typedict mypy can't understand this.
- key = self.form_compileropt_key('winlibs')
- libs = options.get_value(key).copy()
- assert isinstance(libs, list)
+ retval = self.get_compileropt_value('winlibs', env, target, subproject)
+ assert isinstance(retval, list)
+ libs: T.List[str] = retval.copy()
for l in libs:
assert isinstance(l, str)
return libs
@@ -219,15 +220,15 @@ class ArmclangCCompiler(ArmclangCompiler, CCompiler):
std_opt.set_versions(['c90', 'c99', 'c11'], gnu=True)
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: BuildTarget, env: Environment, subproject: T.Optional[str] = None) -> T.List[str]:
args = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ std = self.get_compileropt_value('std', env, target, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append('-std=' + std)
return args
- def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
return []
@@ -263,20 +264,22 @@ class GnuCCompiler(GnuCStds, GnuCompiler, CCompiler):
gnu_winlibs)
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ key = OptionKey('c_std', machine=self.for_machine)
+ std = self.get_compileropt_value(key, env, target, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append('-std=' + std)
return args
- def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
if self.info.is_windows() or self.info.is_cygwin():
# without a typeddict mypy can't figure this out
- key = self.form_compileropt_key('winlibs')
- libs: T.List[str] = options.get_value(key).copy()
- assert isinstance(libs, list)
+ retval = self.get_compileropt_value('winlibs', env, target, subproject)
+
+ assert isinstance(retval, list)
+ libs: T.List[str] = retval.copy()
for l in libs:
assert isinstance(l, str)
return libs
@@ -385,10 +388,10 @@ class IntelCCompiler(IntelGnuLikeCompiler, CCompiler):
std_opt.set_versions(stds, gnu=True)
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
- args = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
+ args: T.List[str] = []
+ std = self.get_compileropt_value('std', env, target, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append('-std=' + std)
return args
@@ -412,11 +415,10 @@ class VisualStudioLikeCCompilerMixin(CompilerMixinBase):
msvc_winlibs)
return opts
- def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
- # need a TypeDict to make this work
- key = self.form_compileropt_key('winlibs')
- libs = options.get_value(key).copy()
- assert isinstance(libs, list)
+ def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
+ retval = self.get_compileropt_value('winlibs', env, target, subproject)
+ assert isinstance(retval, list)
+ libs: T.List[str] = retval.copy()
for l in libs:
assert isinstance(l, str)
return libs
@@ -449,12 +451,12 @@ class VisualStudioCCompiler(MSVCCompiler, VisualStudioLikeCCompilerMixin, CCompi
std_opt.set_versions(stds, gnu=True, gnu_deprecated=True)
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ std = self.get_compileropt_value('std', env, target, subproject)
+
# As of MVSC 16.8, /std:c11 and /std:c17 are the only valid C standard options.
- if std == 'c11':
+ if std in {'c11'}:
args.append('/std:c11')
elif std in {'c17', 'c18'}:
args.append('/std:c17')
@@ -471,9 +473,9 @@ class ClangClCCompiler(ClangCStds, ClangClCompiler, VisualStudioLikeCCompilerMix
full_version=full_version)
ClangClCompiler.__init__(self, target)
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
+ std = self.get_compileropt_value('std', env, target, subproject)
+ assert isinstance(std, str)
if std != "none":
return [f'/clang:-std={std}']
return []
@@ -503,10 +505,10 @@ class IntelClCCompiler(IntelVisualStudioLikeCompiler, VisualStudioLikeCCompilerM
std_opt.set_versions(['c89', 'c99', 'c11'])
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
- args = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
+ args: T.List[str] = []
+ std = self.get_compileropt_value('winlibs', env, target, subproject)
+ assert isinstance(std, str)
if std == 'c89':
mlog.log("ICL doesn't explicitly implement c89, setting the standard to 'none', which is close.", once=True)
elif std != 'none':
@@ -537,10 +539,10 @@ class ArmCCompiler(ArmCompiler, CCompiler):
std_opt.set_versions(['c89', 'c99', 'c11'])
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ std = self.get_compileropt_value('std', env, target, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append('--' + std)
return args
@@ -570,10 +572,10 @@ class CcrxCCompiler(CcrxCompiler, CCompiler):
def get_no_stdinc_args(self) -> T.List[str]:
return []
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ std = self.get_compileropt_value('std', env, target, subproject)
+ assert isinstance(std, str)
if std == 'c89':
args.append('-lang=c')
elif std == 'c99':
@@ -618,10 +620,10 @@ class Xc16CCompiler(Xc16Compiler, CCompiler):
def get_no_stdinc_args(self) -> T.List[str]:
return []
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ std = self.get_compileropt_value('std', env, target, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append('-ansi')
args.append('-std=' + std)
@@ -661,7 +663,7 @@ class CompCertCCompiler(CompCertCompiler, CCompiler):
std_opt.set_versions(['c89', 'c99'])
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
return []
def get_no_optimization_args(self) -> T.List[str]:
@@ -702,10 +704,10 @@ class TICCompiler(TICompiler, CCompiler):
def get_no_stdinc_args(self) -> T.List[str]:
return []
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ std = self.get_compileropt_value('std', env, target, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append('--' + std)
return args
@@ -736,10 +738,10 @@ class MetrowerksCCompilerARM(MetrowerksCompiler, CCompiler):
self._update_language_stds(opts, ['c99'])
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ std = self.get_compileropt_value('std', env, target, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append('-lang')
args.append(std)
@@ -764,10 +766,10 @@ class MetrowerksCCompilerEmbeddedPowerPC(MetrowerksCompiler, CCompiler):
self._update_language_stds(opts, ['c99'])
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ std = self.get_compileropt_value('std', env, target, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append('-lang ' + std)
return args
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index 0f7ef17..e4c7f77 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -256,12 +256,16 @@ BASE_OPTIONS: T.Mapping[OptionKey, BaseOption] = {
base_options = {key: base_opt.init_option(key) for key, base_opt in BASE_OPTIONS.items()}
-def option_enabled(boptions: T.Set[OptionKey], options: 'KeyedOptionDictType',
- option: OptionKey) -> bool:
+def option_enabled(boptions: T.Set[OptionKey],
+ target: 'BuildTarget',
+ env: 'Environment',
+ option: T.Union[str, OptionKey]) -> bool:
+ if isinstance(option, str):
+ option = OptionKey(option)
try:
if option not in boptions:
return False
- ret = options.get_value(option)
+ ret = env.coredata.get_option_for_target(target, option)
assert isinstance(ret, bool), 'must return bool' # could also be str
return ret
except KeyError:
@@ -271,7 +275,7 @@ def option_enabled(boptions: T.Set[OptionKey], options: 'KeyedOptionDictType',
def get_option_value(options: 'KeyedOptionDictType', opt: OptionKey, fallback: '_T') -> '_T':
"""Get the value of an option, or the fallback value."""
try:
- v: '_T' = options.get_value(opt)
+ v: '_T' = options.get_value(opt) # type: ignore [assignment]
except (KeyError, AttributeError):
return fallback
@@ -279,37 +283,75 @@ def get_option_value(options: 'KeyedOptionDictType', opt: OptionKey, fallback: '
# Mypy doesn't understand that the above assert ensures that v is type _T
return v
+def get_option_value_for_target(env: 'Environment', target: 'BuildTarget', opt: OptionKey, fallback: '_T') -> '_T':
+ """Get the value of an option, or the fallback value."""
+ try:
+ v = env.coredata.get_option_for_target(target, opt)
+ except (KeyError, AttributeError):
+ return fallback
+
+ assert isinstance(v, type(fallback)), f'Should have {type(fallback)!r} but was {type(v)!r}'
+ # Mypy doesn't understand that the above assert ensures that v is type _T
+ return v
+
+
+def get_target_option_value(target: 'BuildTarget',
+ env: 'Environment',
+ opt: T.Union[OptionKey, str],
+ fallback: '_T') -> '_T':
+ """Get the value of an option, or the fallback value."""
+ try:
+ v = env.coredata.get_option_for_target(target, opt)
+ except KeyError:
+ return fallback
+
+ assert isinstance(v, type(fallback)), f'Should have {type(fallback)!r} but was {type(v)!r}'
+ # Mypy doesn't understand that the above assert ensures that v is type _T
+ return v
+
-def are_asserts_disabled(options: KeyedOptionDictType) -> bool:
+def are_asserts_disabled(target: 'BuildTarget', env: 'Environment') -> bool:
"""Should debug assertions be disabled
- :param options: OptionDictionary
+ :param target: a target to check for
+ :param env: the environment
:return: whether to disable assertions or not
"""
- return (options.get_value('b_ndebug') == 'true' or
- (options.get_value('b_ndebug') == 'if-release' and
- options.get_value('buildtype') in {'release', 'plain'}))
+ return (env.coredata.get_option_for_target(target, 'b_ndebug') == 'true' or
+ (env.coredata.get_option_for_target(target, 'b_ndebug') == 'if-release' and
+ env.coredata.get_option_for_target(target, 'buildtype') in {'release', 'plain'}))
+def are_asserts_disabled_for_subproject(subproject: str, env: 'Environment') -> bool:
+ return (env.coredata.get_option_for_subproject('b_ndebug', subproject) == 'true' or
+ (env.coredata.get_option_for_subproject('b_ndebug', subproject) == 'if-release' and
+ env.coredata.get_option_for_subproject('buildtype', subproject) in {'release', 'plain'}))
-def get_base_compile_args(options: 'KeyedOptionDictType', compiler: 'Compiler', env: 'Environment') -> T.List[str]:
+
+def get_base_compile_args(target: 'BuildTarget', compiler: 'Compiler', env: 'Environment') -> T.List[str]:
args: T.List[str] = []
try:
- if options.get_value(OptionKey('b_lto')):
+ if env.coredata.get_option_for_target(target, 'b_lto'):
+ num_threads = get_option_value_for_target(env, target, OptionKey('b_lto_threads'), 0)
+ ltomode = get_option_value_for_target(env, target, OptionKey('b_lto_mode'), 'default')
args.extend(compiler.get_lto_compile_args(
- threads=get_option_value(options, OptionKey('b_lto_threads'), 0),
- mode=get_option_value(options, OptionKey('b_lto_mode'), 'default')))
+ threads=num_threads,
+ mode=ltomode))
except (KeyError, AttributeError):
pass
try:
- args += compiler.get_colorout_args(options.get_value(OptionKey('b_colorout')))
- except (KeyError, AttributeError):
+ clrout = env.coredata.get_option_for_target(target, 'b_colorout')
+ assert isinstance(clrout, str)
+ args += compiler.get_colorout_args(clrout)
+ except KeyError:
pass
try:
- args += compiler.sanitizer_compile_args(options.get_value(OptionKey('b_sanitize')))
- except (KeyError, AttributeError):
+ sanitize = env.coredata.get_option_for_target(target, 'b_sanitize')
+ assert isinstance(sanitize, str)
+ args += compiler.sanitizer_compile_args(sanitize)
+ except KeyError:
pass
try:
- pgo_val = options.get_value(OptionKey('b_pgo'))
+ pgo_val = env.coredata.get_option_for_target(target, 'b_pgo')
if pgo_val == 'generate':
args.extend(compiler.get_profile_generate_args())
elif pgo_val == 'use':
@@ -317,21 +359,23 @@ def get_base_compile_args(options: 'KeyedOptionDictType', compiler: 'Compiler',
except (KeyError, AttributeError):
pass
try:
- if options.get_value(OptionKey('b_coverage')):
+ if env.coredata.get_option_for_target(target, 'b_coverage'):
args += compiler.get_coverage_args()
except (KeyError, AttributeError):
pass
try:
- args += compiler.get_assert_args(are_asserts_disabled(options), env)
- except (KeyError, AttributeError):
+ args += compiler.get_assert_args(are_asserts_disabled(target, env), env)
+ except KeyError:
pass
# This does not need a try...except
- if option_enabled(compiler.base_options, options, OptionKey('b_bitcode')):
+ if option_enabled(compiler.base_options, target, env, 'b_bitcode'):
args.append('-fembed-bitcode')
try:
+ crt_val = env.coredata.get_option_for_target(target, 'b_vscrt')
+ assert isinstance(crt_val, str)
+ buildtype = env.coredata.get_option_for_target(target, 'buildtype')
+ assert isinstance(buildtype, str)
try:
- crt_val = options.get_value(OptionKey('b_vscrt'))
- buildtype = options.get_value(OptionKey('buildtype'))
args += compiler.get_crt_compile_args(crt_val, buildtype)
except AttributeError:
pass
@@ -339,31 +383,38 @@ def get_base_compile_args(options: 'KeyedOptionDictType', compiler: 'Compiler',
pass
return args
-def get_base_link_args(options: 'KeyedOptionDictType', linker: 'Compiler',
- is_shared_module: bool, build_dir: str) -> T.List[str]:
+def get_base_link_args(target: 'BuildTarget',
+ linker: 'Compiler',
+ env: 'Environment') -> T.List[str]:
args: T.List[str] = []
+ build_dir = env.get_build_dir()
try:
- if options.get_value('b_lto'):
- if options.get_value('werror'):
+ if env.coredata.get_option_for_target(target, 'b_lto'):
+ if env.coredata.get_option_for_target(target, 'werror'):
args.extend(linker.get_werror_args())
thinlto_cache_dir = None
- if get_option_value(options, OptionKey('b_thinlto_cache'), False):
- thinlto_cache_dir = get_option_value(options, OptionKey('b_thinlto_cache_dir'), '')
+ cachedir_key = OptionKey('b_thinlto_cache')
+ if get_option_value_for_target(env, target, cachedir_key, False):
+ thinlto_cache_dir = get_option_value_for_target(env, target, OptionKey('b_thinlto_cache_dir'), '')
if thinlto_cache_dir == '':
thinlto_cache_dir = os.path.join(build_dir, 'meson-private', 'thinlto-cache')
+ num_threads = get_option_value_for_target(env, target, OptionKey('b_lto_threads'), 0)
+ lto_mode = get_option_value_for_target(env, target, OptionKey('b_lto_mode'), 'default')
args.extend(linker.get_lto_link_args(
- threads=get_option_value(options, OptionKey('b_lto_threads'), 0),
- mode=get_option_value(options, OptionKey('b_lto_mode'), 'default'),
+ threads=num_threads,
+ mode=lto_mode,
thinlto_cache_dir=thinlto_cache_dir))
except (KeyError, AttributeError):
pass
try:
- args += linker.sanitizer_link_args(options.get_value('b_sanitize'))
- except (KeyError, AttributeError):
+ sanitizer = env.coredata.get_option_for_target(target, 'b_sanitize')
+ assert isinstance(sanitizer, str)
+ args += linker.sanitizer_link_args(sanitizer)
+ except KeyError:
pass
try:
- pgo_val = options.get_value('b_pgo')
+ pgo_val = env.coredata.get_option_for_target(target, 'b_pgo')
if pgo_val == 'generate':
args.extend(linker.get_profile_generate_args())
elif pgo_val == 'use':
@@ -371,16 +422,16 @@ def get_base_link_args(options: 'KeyedOptionDictType', linker: 'Compiler',
except (KeyError, AttributeError):
pass
try:
- if options.get_value('b_coverage'):
+ if env.coredata.get_option_for_target(target, 'b_coverage'):
args += linker.get_coverage_link_args()
except (KeyError, AttributeError):
pass
- as_needed = option_enabled(linker.base_options, options, OptionKey('b_asneeded'))
- bitcode = option_enabled(linker.base_options, options, OptionKey('b_bitcode'))
+ as_needed = option_enabled(linker.base_options, target, env, 'b_asneeded')
+ bitcode = option_enabled(linker.base_options, target, env, '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:
+ if bitcode and not target.typename == 'shared module':
args.extend(linker.bitcode_args())
elif as_needed:
# -Wl,-dead_strip_dylibs is incompatible with bitcode
@@ -389,18 +440,23 @@ def get_base_link_args(options: 'KeyedOptionDictType', linker: 'Compiler',
# Apple's ld (the only one that supports bitcode) does not like -undefined
# arguments or -headerpad_max_install_names when bitcode is enabled
if not bitcode:
+ from ..build import SharedModule
args.extend(linker.headerpad_args())
- if (not is_shared_module and
- option_enabled(linker.base_options, options, OptionKey('b_lundef'))):
+ if (not isinstance(target, SharedModule) and
+ option_enabled(linker.base_options, target, env, 'b_lundef')):
args.extend(linker.no_undefined_link_args())
else:
args.extend(linker.get_allow_undefined_link_args())
try:
+ crt_val = env.coredata.get_option_for_target(target, 'b_vscrt')
+ assert isinstance(crt_val, str)
+ buildtype = env.coredata.get_option_for_target(target, 'buildtype')
+ assert isinstance(buildtype, str)
try:
- crt_val = options.get_value(OptionKey('b_vscrt'))
- buildtype = options.get_value(OptionKey('buildtype'))
- args += linker.get_crt_link_args(crt_val, buildtype)
+ crtargs = linker.get_crt_link_args(crt_val, buildtype)
+ assert isinstance(crtargs, list)
+ args += crtargs
except AttributeError:
pass
except KeyError:
@@ -598,11 +654,11 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
def get_options(self) -> 'MutableKeyedOptionDictType':
return {}
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
return []
- def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
- return self.linker.get_option_args(options)
+ def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
+ return self.linker.get_option_link_args(target, env, subproject)
def check_header(self, hname: str, prefix: str, env: 'Environment', *,
extra_args: T.Union[None, T.List[str], T.Callable[[CompileCheckMode], T.List[str]]] = None,
@@ -894,8 +950,8 @@ class Compiler(HoldableObject, 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: 'KeyedOptionDictType') -> T.List[str]:
- return self.linker.get_std_shared_module_args(options)
+ def get_std_shared_module_link_args(self, target: 'BuildTarget') -> T.List[str]:
+ return self.linker.get_std_shared_module_args(target)
def get_link_whole_for(self, args: T.List[str]) -> T.List[str]:
return self.linker.get_link_whole_for(args)
@@ -1358,6 +1414,19 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
def form_compileropt_key(self, basename: str) -> OptionKey:
return OptionKey(f'{self.language}_{basename}', machine=self.for_machine)
+ def get_compileropt_value(self,
+ key: T.Union[str, OptionKey],
+ env: Environment,
+ target: T.Optional[BuildTarget],
+ subproject: T.Optional[str] = None
+ ) -> T.Union[str, int, bool, T.List[str]]:
+ if isinstance(key, str):
+ key = self.form_compileropt_key(key)
+ if target:
+ return env.coredata.get_option_for_target(target, key)
+ else:
+ return env.coredata.get_option_for_subproject(key, subproject)
+
def _update_language_stds(self, opts: MutableKeyedOptionDictType, value: T.List[str]) -> None:
key = self.form_compileropt_key('std')
std = opts[key]
@@ -1370,12 +1439,12 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
def get_global_options(lang: str,
comp: T.Type[Compiler],
for_machine: MachineChoice,
- env: 'Environment') -> dict[OptionKey, options.UserOption[T.Any]]:
+ env: 'Environment') -> dict[OptionKey, options.AnyOptionType]:
"""Retrieve options that apply to all compilers for a given language."""
description = f'Extra arguments passed to the {lang}'
argkey = OptionKey(f'{lang}_args', machine=for_machine)
- largkey = argkey.evolve(f'{lang}_link_args')
- envkey = argkey.evolve(f'{lang}_env_args')
+ largkey = OptionKey(f'{lang}_link_args', machine=for_machine)
+ envkey = OptionKey(f'{lang}_env_args', machine=for_machine)
comp_key = argkey if argkey in env.options else envkey
@@ -1383,12 +1452,12 @@ def get_global_options(lang: str,
link_options = env.options.get(largkey, [])
cargs = options.UserStringArrayOption(
- f'{lang}_{argkey.name}',
+ argkey.name,
description + ' compiler',
comp_options, split_args=True, allow_dups=True)
largs = options.UserStringArrayOption(
- f'{lang}_{largkey.name}',
+ largkey.name,
description + ' linker',
link_options, split_args=True, allow_dups=True)
@@ -1400,6 +1469,6 @@ def get_global_options(lang: str,
# autotools compatibility.
largs.extend_value(comp_options)
- opts: dict[OptionKey, options.UserOption[T.Any]] = {argkey: cargs, largkey: largs}
+ opts: dict[OptionKey, options.AnyOptionType] = {argkey: cargs, largkey: largs}
return opts
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index 80f84b3..b21a62e 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -3,7 +3,6 @@
from __future__ import annotations
-import copy
import functools
import os.path
import typing as T
@@ -35,12 +34,13 @@ from .mixins.metrowerks import MetrowerksCompiler
from .mixins.metrowerks import mwccarm_instruction_set_args, mwcceppc_instruction_set_args
if T.TYPE_CHECKING:
- from ..coredata import MutableKeyedOptionDictType, KeyedOptionDictType
+ from ..coredata import MutableKeyedOptionDictType
from ..dependencies import Dependency
from ..envconfig import MachineInfo
from ..environment import Environment
from ..linkers.linkers import DynamicLinker
from ..mesonlib import MachineChoice
+ from ..build import BuildTarget
CompilerMixinBase = CLikeCompiler
else:
CompilerMixinBase = object
@@ -265,18 +265,24 @@ class ClangCPPCompiler(_StdCPPLibMixin, ClangCPPStds, ClangCompiler, CPPCompiler
gnu_winlibs)
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args: T.List[str] = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+
+ std = self.get_compileropt_value('std', env, target, subproject)
+ rtti = self.get_compileropt_value('rtti', env, target, subproject)
+ debugstl = self.get_compileropt_value('debugstl', env, target, subproject)
+ eh = self.get_compileropt_value('eh', env, target, subproject)
+
+ assert isinstance(std, str)
+ assert isinstance(rtti, bool)
+ assert isinstance(eh, str)
+ assert isinstance(debugstl, bool)
if std != 'none':
args.append(self._find_best_cpp_std(std))
- key = self.form_compileropt_key('eh')
- non_msvc_eh_options(options.get_value(key), args)
+ non_msvc_eh_options(eh, args)
- key = self.form_compileropt_key('debugstl')
- if options.get_value(key):
+ if debugstl:
args.append('-D_GLIBCXX_DEBUG=1')
# We can't do _LIBCPP_DEBUG because it's unreliable unless libc++ was built with it too:
@@ -285,18 +291,17 @@ class ClangCPPCompiler(_StdCPPLibMixin, ClangCPPStds, ClangCompiler, CPPCompiler
if version_compare(self.version, '>=18'):
args.append('-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG')
- key = self.form_compileropt_key('rtti')
- if not options.get_value(key):
+ if not rtti:
args.append('-fno-rtti')
return args
- def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
if self.info.is_windows() or self.info.is_cygwin():
# without a typedict mypy can't understand this.
- key = self.form_compileropt_key('winlibs')
- libs = options.get_value(key).copy()
- assert isinstance(libs, list)
+ retval = self.get_compileropt_value('winlibs', env, target, subproject)
+ assert isinstance(retval, list)
+ libs = retval[:]
for l in libs:
assert isinstance(l, str)
return libs
@@ -363,10 +368,10 @@ class EmscriptenCPPCompiler(EmscriptenMixin, ClangCPPCompiler):
info, linker=linker,
defines=defines, full_version=full_version)
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args: T.List[str] = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ std = self.get_compileropt_value('std', env, target, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append(self._find_best_cpp_std(std))
return args
@@ -407,19 +412,20 @@ class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler):
std_opt.set_versions(['c++98', 'c++03', 'c++11', 'c++14', 'c++17'], gnu=True)
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args: T.List[str] = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ std = self.get_compileropt_value('std', env, target, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append('-std=' + std)
- key = self.form_compileropt_key('eh')
- non_msvc_eh_options(options.get_value(key), args)
+ eh = self.get_compileropt_value('eh', env, target, subproject)
+ assert isinstance(eh, str)
+ non_msvc_eh_options(eh, args)
return args
- def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
return []
@@ -472,32 +478,37 @@ class GnuCPPCompiler(_StdCPPLibMixin, GnuCPPStds, GnuCompiler, CPPCompiler):
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args: T.List[str] = []
- stdkey = self.form_compileropt_key('std')
- ehkey = self.form_compileropt_key('eh')
- rttikey = self.form_compileropt_key('rtti')
- debugstlkey = self.form_compileropt_key('debugstl')
- std = options.get_value(stdkey)
+ std = self.get_compileropt_value('std', env, target, subproject)
+ rtti = self.get_compileropt_value('rtti', env, target, subproject)
+ debugstl = self.get_compileropt_value('debugstl', env, target, subproject)
+ eh = self.get_compileropt_value('eh', env, target, subproject)
+
+ assert isinstance(std, str)
+ assert isinstance(rtti, bool)
+ assert isinstance(eh, str)
+ assert isinstance(debugstl, bool)
+
if std != 'none':
args.append(self._find_best_cpp_std(std))
- non_msvc_eh_options(options.get_value(ehkey), args)
+ non_msvc_eh_options(eh, args)
- if not options.get_value(rttikey):
+ if not rtti:
args.append('-fno-rtti')
- if options.get_value(debugstlkey):
+ if debugstl:
args.append('-D_GLIBCXX_DEBUG=1')
return args
- def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
if self.info.is_windows() or self.info.is_cygwin():
# without a typedict mypy can't understand this.
- key = self.form_compileropt_key('winlibs')
- libs = options.get_value(key).copy()
- assert isinstance(libs, list)
+ retval = self.get_compileropt_value('winlibs', env, target, subproject)
+ assert isinstance(retval, list)
+ libs: T.List[str] = retval[:]
for l in libs:
assert isinstance(l, str)
return libs
@@ -621,18 +632,21 @@ class ElbrusCPPCompiler(ElbrusCompiler, CPPCompiler):
dependencies=dependencies)
# Elbrus C++ compiler does not support RTTI, so don't check for it.
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args: T.List[str] = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ std = self.get_compileropt_value('std', env, target, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append(self._find_best_cpp_std(std))
- key = self.form_compileropt_key('eh')
- non_msvc_eh_options(options.get_value(key), args)
+ eh = self.get_compileropt_value('eh', env, target, subproject)
+ assert isinstance(eh, str)
- key = self.form_compileropt_key('debugstl')
- if options.get_value(key):
+ non_msvc_eh_options(eh, args)
+
+ debugstl = self.get_compileropt_value('debugstl', env, target, subproject)
+ assert isinstance(debugstl, str)
+ if debugstl:
args.append('-D_GLIBCXX_DEBUG=1')
return args
@@ -694,25 +708,34 @@ class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler):
self._update_language_stds(opts, c_stds + g_stds)
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args: T.List[str] = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+
+ std = self.get_compileropt_value('std', env, target, subproject)
+ rtti = self.get_compileropt_value('rtti', env, target, subproject)
+ debugstl = self.get_compileropt_value('debugstl', env, target, subproject)
+ eh = self.get_compileropt_value('eh', env, target, subproject)
+
+ assert isinstance(std, str)
+ assert isinstance(rtti, bool)
+ assert isinstance(eh, str)
+ assert isinstance(debugstl, bool)
+
if std != 'none':
remap_cpp03 = {
'c++03': 'c++98',
'gnu++03': 'gnu++98'
}
args.append('-std=' + remap_cpp03.get(std, std))
- if options.get_value(key.evolve('eh')) == 'none':
+ if eh == 'none':
args.append('-fno-exceptions')
- if not options.get_value(key.evolve('rtti')):
+ if rtti:
args.append('-fno-rtti')
- if options.get_value(key.evolve('debugstl')):
+ if debugstl:
args.append('-D_GLIBCXX_DEBUG=1')
return args
- def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
return []
@@ -739,10 +762,14 @@ class VisualStudioLikeCPPCompilerMixin(CompilerMixinBase):
'c++latest': (False, "latest"),
}
- def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
# need a typeddict for this
key = self.form_compileropt_key('winlibs')
- return T.cast('T.List[str]', options.get_value(key)[:])
+ if target:
+ value = env.coredata.get_option_for_target(target, key)
+ else:
+ value = env.coredata.get_option_for_subproject(key, subproject)
+ return T.cast('T.List[str]', value)[:]
def _get_options_impl(self, opts: 'MutableKeyedOptionDictType', cpp_stds: T.List[str]) -> 'MutableKeyedOptionDictType':
opts = super().get_options()
@@ -771,11 +798,17 @@ class VisualStudioLikeCPPCompilerMixin(CompilerMixinBase):
std_opt.set_versions(cpp_stds)
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args: T.List[str] = []
- key = self.form_compileropt_key('std')
- eh = options.get_value(self.form_compileropt_key('eh'))
+ std = self.get_compileropt_value('std', env, target, subproject)
+ eh = self.get_compileropt_value('eh', env, target, subproject)
+ rtti = self.get_compileropt_value('rtti', env, target, subproject)
+
+ assert isinstance(std, str)
+ assert isinstance(rtti, bool)
+ assert isinstance(eh, str)
+
if eh == 'default':
args.append('/EHsc')
elif eh == 'none':
@@ -783,10 +816,10 @@ class VisualStudioLikeCPPCompilerMixin(CompilerMixinBase):
else:
args.append('/EH' + eh)
- if not options.get_value(self.form_compileropt_key('rtti')):
+ if not rtti:
args.append('/GR-')
- permissive, ver = self.VC_VERSION_MAP[options.get_value(key)]
+ permissive, ver = self.VC_VERSION_MAP[std]
if ver is not None:
args.append(f'/std:c++{ver}')
@@ -800,7 +833,6 @@ class VisualStudioLikeCPPCompilerMixin(CompilerMixinBase):
# XXX: this is a hack because so much GnuLike stuff is in the base CPPCompiler class.
return Compiler.get_compiler_check_args(self, mode)
-
class CPP11AsCPP14Mixin(CompilerMixinBase):
"""Mixin class for VisualStudio and ClangCl to replace C++11 std with C++14.
@@ -808,25 +840,25 @@ class CPP11AsCPP14Mixin(CompilerMixinBase):
This is a limitation of Clang and MSVC that ICL doesn't share.
"""
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> 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.
- key = self.form_compileropt_key('std')
- if options.get_value(key) in {'vc++11', 'c++11'}:
+ stdkey = self.form_compileropt_key('std')
+ if target is not None:
+ std = env.coredata.get_option_for_target(target, stdkey)
+ else:
+ std = env.coredata.get_option_for_subproject(stdkey, subproject)
+ if std 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, fatal=False)
- # 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.get_value(key) == 'vc++11':
- options.set_value(key, 'vc++14')
- else:
- options.set_value(key, 'c++14')
- return super().get_option_compile_args(options)
+ original_args = super().get_option_compile_args(target, env, subproject)
+ std_mapping = {'/std:c++11': '/std:c++14',
+ '/std:c++14': '/std:vc++14'}
+ processed_args = [std_mapping.get(x, x) for x in original_args]
+ return processed_args
class VisualStudioCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixin, MSVCCompiler, CPPCompiler):
@@ -859,14 +891,12 @@ class VisualStudioCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixi
cpp_stds.extend(['c++20', 'vc++20'])
return self._get_options_impl(super().get_options(), cpp_stds)
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
- key = self.form_compileropt_key('std')
- if options.get_value(key) != 'none' and version_compare(self.version, '<19.00.24210'):
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
+ std = self.get_compileropt_value('std', env, target, subproject)
+ if std != 'none' and version_compare(self.version, '<19.00.24210'):
mlog.warning('This version of MSVC does not support cpp_std arguments', fatal=False)
- options = copy.copy(options)
- options.set_value(key, 'none')
- args = super().get_option_compile_args(options)
+ args = super().get_option_compile_args(target, env, subproject)
if version_compare(self.version, '<19.11'):
try:
@@ -939,17 +969,17 @@ class ArmCPPCompiler(ArmCompiler, CPPCompiler):
std_opt.set_versions(['c++03', 'c++11'])
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args: T.List[str] = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ std = self.get_compileropt_value('std', env, target, subproject)
+ assert isinstance(std, str)
if std == 'c++11':
args.append('--cpp11')
elif std == 'c++03':
args.append('--cpp')
return args
- def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
return []
def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]:
@@ -969,7 +999,7 @@ class CcrxCPPCompiler(CcrxCompiler, CPPCompiler):
def get_always_args(self) -> T.List[str]:
return ['-nologo', '-lang=cpp']
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
return []
def get_compile_only_args(self) -> T.List[str]:
@@ -978,7 +1008,7 @@ class CcrxCPPCompiler(CcrxCompiler, CPPCompiler):
def get_output_args(self, outputname: str) -> T.List[str]:
return [f'-output=obj={outputname}']
- def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
return []
def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]:
@@ -1001,10 +1031,10 @@ class TICPPCompiler(TICompiler, CPPCompiler):
std_opt.set_versions(['c++03'])
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args: T.List[str] = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ std = self.get_compileropt_value('std', env, target, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append('--' + std)
return args
@@ -1012,7 +1042,7 @@ class TICPPCompiler(TICompiler, CPPCompiler):
def get_always_args(self) -> T.List[str]:
return []
- def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
return []
class C2000CPPCompiler(TICPPCompiler):
@@ -1041,10 +1071,10 @@ class MetrowerksCPPCompilerARM(MetrowerksCompiler, CPPCompiler):
self._update_language_stds(opts, [])
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args: T.List[str] = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ std = self.get_compileropt_value('std', env, target, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append('-lang')
args.append(std)
@@ -1069,10 +1099,10 @@ class MetrowerksCPPCompilerEmbeddedPowerPC(MetrowerksCompiler, CPPCompiler):
self._update_language_stds(opts, [])
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args: T.List[str] = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ std = self.get_compileropt_value('std', env, target, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append('-lang ' + std)
return args
diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py
index 6a49d95..284f284 100644
--- a/mesonbuild/compilers/cuda.py
+++ b/mesonbuild/compilers/cuda.py
@@ -8,20 +8,18 @@ import os.path
import string
import typing as T
-from .. import coredata
from .. import options
from .. import mlog
from ..mesonlib import (
EnvironmentException, Popen_safe,
is_windows, LibType, version_compare
)
-from ..options import OptionKey
from .compilers import Compiler
if T.TYPE_CHECKING:
from .compilers import CompileCheckMode
from ..build import BuildTarget
- from ..coredata import MutableKeyedOptionDictType, KeyedOptionDictType
+ from ..coredata import MutableKeyedOptionDictType
from ..dependencies import Dependency
from ..environment import Environment # noqa: F401
from ..envconfig import MachineInfo
@@ -553,7 +551,7 @@ class CudaCompiler(Compiler):
# Use the -ccbin option, if available, even during sanity checking.
# Otherwise, on systems where CUDA does not support the default compiler,
# NVCC becomes unusable.
- flags += self.get_ccbin_args(env.coredata.optstore)
+ flags += self.get_ccbin_args(None, env, '')
# If cross-compiling, we can't run the sanity check, only compile it.
if self.is_cross and not env.has_exe_wrapper():
@@ -663,35 +661,26 @@ class CudaCompiler(Compiler):
return opts
- def _to_host_compiler_options(self, master_options: 'KeyedOptionDictType') -> 'KeyedOptionDictType':
- """
- Convert an NVCC Option set to a host compiler's option set.
- """
-
- # We must strip the -std option from the host compiler option set, as NVCC has
- # its own -std flag that may not agree with the host compiler's.
- host_options = {key: master_options.get(key, opt) for key, opt in self.host_compiler.get_options().items()}
- std_key = OptionKey(f'{self.host_compiler.language}_std', machine=self.for_machine)
- overrides = {std_key: 'none'}
- # To shut up mypy.
- return coredata.OptionsView(host_options, overrides=overrides)
-
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
- args = self.get_ccbin_args(options)
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
+ args = self.get_ccbin_args(target, env, subproject)
# 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():
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ std = self.get_compileropt_value('std', env, target, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append('--std=' + std)
- return args + self._to_host_flags(self.host_compiler.get_option_compile_args(self._to_host_compiler_options(options)))
+ try:
+ host_compiler_args = self.host_compiler.get_option_compile_args(target, env, subproject)
+ except KeyError:
+ host_compiler_args = []
+ return args + self._to_host_flags(host_compiler_args)
- def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
- args = self.get_ccbin_args(options)
- return args + self._to_host_flags(self.host_compiler.get_option_link_args(self._to_host_compiler_options(options)), Phase.LINKER)
+ def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
+ args = self.get_ccbin_args(target, env, subproject)
+ return args + self._to_host_flags(self.host_compiler.get_option_link_args(target, env, subproject), Phase.LINKER)
def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str,
suffix: str, soversion: str,
@@ -801,9 +790,15 @@ class CudaCompiler(Compiler):
def get_dependency_link_args(self, dep: 'Dependency') -> T.List[str]:
return self._to_host_flags(super().get_dependency_link_args(dep), Phase.LINKER)
- def get_ccbin_args(self, ccoptions: 'KeyedOptionDictType') -> T.List[str]:
+ def get_ccbin_args(self,
+ target: 'T.Optional[BuildTarget]',
+ env: 'Environment',
+ subproject: T.Optional[str] = None) -> T.List[str]:
key = self.form_compileropt_key('ccbindir')
- ccbindir = ccoptions.get_value(key)
+ if target:
+ ccbindir = env.coredata.get_option_for_target(target, key)
+ else:
+ ccbindir = env.coredata.get_option_for_subproject(key, subproject)
if isinstance(ccbindir, str) and ccbindir != '':
return [self._shield_nvcc_list_arg('-ccbin='+ccbindir, False)]
else:
diff --git a/mesonbuild/compilers/cython.py b/mesonbuild/compilers/cython.py
index ed0ab31..27cad55 100644
--- a/mesonbuild/compilers/cython.py
+++ b/mesonbuild/compilers/cython.py
@@ -11,8 +11,9 @@ from ..mesonlib import EnvironmentException, version_compare
from .compilers import Compiler
if T.TYPE_CHECKING:
- from ..coredata import MutableKeyedOptionDictType, KeyedOptionDictType
+ from ..coredata import MutableKeyedOptionDictType
from ..environment import Environment
+ from ..build import BuildTarget
class CythonCompiler(Compiler):
@@ -85,13 +86,14 @@ class CythonCompiler(Compiler):
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args: T.List[str] = []
- key = self.form_compileropt_key('version')
- version = options.get_value(key)
+ version = self.get_compileropt_value('version', env, target, subproject)
+ assert isinstance(version, str)
args.append(f'-{version}')
- key = self.form_compileropt_key('language')
- lang = options.get_value(key)
+
+ lang = self.get_compileropt_value('language', env, target, subproject)
+ assert isinstance(lang, str)
if lang == 'cpp':
args.append('--cplus')
return args
diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py
index 72c9a5a..0885518 100644
--- a/mesonbuild/compilers/fortran.py
+++ b/mesonbuild/compilers/fortran.py
@@ -27,12 +27,13 @@ from mesonbuild.mesonlib import (
)
if T.TYPE_CHECKING:
- from ..coredata import MutableKeyedOptionDictType, KeyedOptionDictType
+ from ..coredata import MutableKeyedOptionDictType
from ..dependencies import Dependency
from ..envconfig import MachineInfo
from ..environment import Environment
from ..linkers.linkers import DynamicLinker
from ..mesonlib import MachineChoice
+ from ..build import BuildTarget
class FortranCompiler(CLikeCompiler, Compiler):
@@ -284,10 +285,10 @@ class GnuFortranCompiler(GnuCompiler, FortranCompiler):
self._update_language_stds(opts, fortran_stds)
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args: T.List[str] = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ std = self.get_compileropt_value('std', env, target, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append('-std=' + std)
return args
@@ -418,11 +419,11 @@ class IntelFortranCompiler(IntelGnuLikeCompiler, FortranCompiler):
self._update_language_stds(opts, ['none', 'legacy', 'f95', 'f2003', 'f2008', 'f2018'])
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args: T.List[str] = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ std = self.get_compileropt_value('std', env, target, subproject)
stds = {'legacy': 'none', 'f95': 'f95', 'f2003': 'f03', 'f2008': 'f08', 'f2018': 'f18'}
+ assert isinstance(std, str)
if std != 'none':
args.append('-stand=' + stds[std])
return args
@@ -472,11 +473,11 @@ class IntelClFortranCompiler(IntelVisualStudioLikeCompiler, FortranCompiler):
self._update_language_stds(opts, ['none', 'legacy', 'f95', 'f2003', 'f2008', 'f2018'])
return opts
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args: T.List[str] = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ std = self.get_compileropt_value('std', env, target, subproject)
stds = {'legacy': 'none', 'f95': 'f95', 'f2003': 'f03', 'f2008': 'f08', 'f2018': 'f18'}
+ assert isinstance(std, str)
if std != 'none':
args.append('/stand:' + stds[std])
return args
diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py
index 19a6bb4..4792a8a 100644
--- a/mesonbuild/compilers/mixins/clike.py
+++ b/mesonbuild/compilers/mixins/clike.py
@@ -378,7 +378,7 @@ class CLikeCompiler(Compiler):
try:
crt_val = env.coredata.optstore.get_value('b_vscrt')
buildtype = env.coredata.optstore.get_value('buildtype')
- cargs += self.get_crt_compile_args(crt_val, buildtype)
+ cargs += self.get_crt_compile_args(crt_val, buildtype) # type: ignore[arg-type]
except (KeyError, AttributeError):
pass
diff --git a/mesonbuild/compilers/mixins/elbrus.py b/mesonbuild/compilers/mixins/elbrus.py
index 5818d8d..4bf0826 100644
--- a/mesonbuild/compilers/mixins/elbrus.py
+++ b/mesonbuild/compilers/mixins/elbrus.py
@@ -18,7 +18,7 @@ from ...options import OptionKey
if T.TYPE_CHECKING:
from ...environment import Environment
- from ...coredata import KeyedOptionDictType
+ from ...build import BuildTarget
class ElbrusCompiler(GnuLikeCompiler):
@@ -83,9 +83,14 @@ class ElbrusCompiler(GnuLikeCompiler):
# Actually it's not supported for now, but probably will be supported in future
return 'pch'
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args: T.List[str] = []
- std = options.get_value(OptionKey(f'{self.language}_std', machine=self.for_machine))
+ key = OptionKey(f'{self.language}_std', machine=self.for_machine)
+ if target:
+ std = env.coredata.get_option_for_target(target, key)
+ else:
+ std = env.coredata.get_option_for_subproject(key, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append('-std=' + std)
return args
diff --git a/mesonbuild/compilers/mixins/emscripten.py b/mesonbuild/compilers/mixins/emscripten.py
index 24ffced..c5b2e6d 100644
--- a/mesonbuild/compilers/mixins/emscripten.py
+++ b/mesonbuild/compilers/mixins/emscripten.py
@@ -51,7 +51,8 @@ class EmscriptenMixin(Compiler):
def thread_link_flags(self, env: 'Environment') -> T.List[str]:
args = ['-pthread']
- count: int = env.coredata.optstore.get_value(OptionKey(f'{self.language}_thread_count', machine=self.for_machine))
+ count = env.coredata.optstore.get_value(OptionKey(f'{self.language}_thread_count', machine=self.for_machine))
+ assert isinstance(count, int)
if count:
args.append(f'-sPTHREAD_POOL_SIZE={count}')
return args
diff --git a/mesonbuild/compilers/mixins/islinker.py b/mesonbuild/compilers/mixins/islinker.py
index 8d17a94..6c9daf3 100644
--- a/mesonbuild/compilers/mixins/islinker.py
+++ b/mesonbuild/compilers/mixins/islinker.py
@@ -19,6 +19,7 @@ if T.TYPE_CHECKING:
from ...coredata import KeyedOptionDictType
from ...environment import Environment
from ...compilers.compilers import Compiler
+ from ...build import BuildTarget
else:
# This is a bit clever, for mypy we pretend that these mixins descend from
# Compiler, so we get all of the methods and attributes defined for us, but
@@ -58,7 +59,7 @@ class BasicLinkerIsCompilerMixin(Compiler):
def get_linker_lib_prefix(self) -> str:
return ''
- def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_link_args(self, target: BuildTarget, env: Environment, subproject: T.Optional[str] = None) -> T.List[str]:
return []
def has_multi_link_args(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]:
diff --git a/mesonbuild/compilers/objc.py b/mesonbuild/compilers/objc.py
index 262a4c4..b133d47 100644
--- a/mesonbuild/compilers/objc.py
+++ b/mesonbuild/compilers/objc.py
@@ -20,6 +20,7 @@ if T.TYPE_CHECKING:
from ..environment import Environment
from ..linkers.linkers import DynamicLinker
from ..mesonlib import MachineChoice
+ from ..build import BuildTarget
class ObjCCompiler(CLikeCompiler, Compiler):
@@ -75,14 +76,18 @@ class GnuObjCCompiler(GnuCStds, GnuCompiler, ObjCCompiler):
self.supported_warn_args(gnu_common_warning_args) +
self.supported_warn_args(gnu_objc_warning_args))}
- def get_option_compile_args(self, options: 'coredata.KeyedOptionDictType') -> T.List[str]:
- args = []
- std = options.get_value(self.form_compileropt_key('std'))
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
+ args: T.List[str] = []
+ key = OptionKey('c_std', machine=self.for_machine)
+ if target:
+ std = env.coredata.get_option_for_target(target, key)
+ else:
+ std = env.coredata.get_option_for_subproject(key, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append('-std=' + std)
return args
-
class ClangObjCCompiler(ClangCStds, ClangCompiler, ObjCCompiler):
def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
is_cross: bool, info: 'MachineInfo',
@@ -109,9 +114,11 @@ class ClangObjCCompiler(ClangCStds, ClangCompiler, ObjCCompiler):
return 'c_std'
return super().make_option_name(key)
- def get_option_compile_args(self, options: 'coredata.KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args = []
- std = options.get_value(self.form_compileropt_key('std'))
+ key = OptionKey('c_std', machine=self.for_machine)
+ std = self.get_compileropt_value(key, env, target, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append('-std=' + std)
return args
diff --git a/mesonbuild/compilers/objcpp.py b/mesonbuild/compilers/objcpp.py
index 104d0cb..743bbb9 100644
--- a/mesonbuild/compilers/objcpp.py
+++ b/mesonbuild/compilers/objcpp.py
@@ -20,6 +20,7 @@ if T.TYPE_CHECKING:
from ..environment import Environment
from ..linkers.linkers import DynamicLinker
from ..mesonlib import MachineChoice
+ from ..build import BuildTarget
class ObjCPPCompiler(CLikeCompiler, Compiler):
@@ -80,14 +81,18 @@ class GnuObjCPPCompiler(GnuCPPStds, GnuCompiler, ObjCPPCompiler):
self.supported_warn_args(gnu_common_warning_args) +
self.supported_warn_args(gnu_objc_warning_args))}
- def get_option_compile_args(self, options: 'coredata.KeyedOptionDictType') -> T.List[str]:
- args = []
- std = options.get_value(self.form_compileropt_key('std'))
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
+ args: T.List[str] = []
+ key = OptionKey('cpp_std', machine=self.for_machine)
+ if target:
+ std = env.coredata.get_option_for_target(target, key)
+ else:
+ std = env.coredata.get_option_for_subproject(key, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append('-std=' + std)
return args
-
class ClangObjCPPCompiler(ClangCPPStds, ClangCompiler, ObjCPPCompiler):
def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
@@ -105,9 +110,11 @@ class ClangObjCPPCompiler(ClangCPPStds, ClangCompiler, ObjCPPCompiler):
'3': default_warn_args + ['-Wextra', '-Wpedantic'],
'everything': ['-Weverything']}
- def get_option_compile_args(self, options: 'coredata.KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args = []
- std = options.get_value(self.form_compileropt_key('std'))
+ key = OptionKey('cpp_std', machine=self.for_machine)
+ std = self.get_compileropt_value(key, env, target, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append('-std=' + std)
return args
diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py
index aacdc07..3acc30e 100644
--- a/mesonbuild/compilers/rust.py
+++ b/mesonbuild/compilers/rust.py
@@ -15,12 +15,13 @@ from ..options import OptionKey
from .compilers import Compiler, clike_debug_args
if T.TYPE_CHECKING:
- from ..coredata import MutableKeyedOptionDictType, KeyedOptionDictType
+ from ..coredata import MutableKeyedOptionDictType
from ..envconfig import MachineInfo
from ..environment import Environment # noqa: F401
from ..linkers.linkers import DynamicLinker
from ..mesonlib import MachineChoice
from ..dependencies import Dependency
+ from ..build import BuildTarget
rust_optimization_args: T.Dict[str, T.List[str]] = {
@@ -251,10 +252,10 @@ class RustCompiler(Compiler):
# provided by the linker flags.
return []
- def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
args = []
- key = self.form_compileropt_key('std')
- std = options.get_value(key)
+ std = self.get_compileropt_value('std', env, target, subproject)
+ assert isinstance(std, str)
if std != 'none':
args.append('--edition=' + std)
return args
diff --git a/mesonbuild/compilers/vala.py b/mesonbuild/compilers/vala.py
index 35c7a68..28861a6 100644
--- a/mesonbuild/compilers/vala.py
+++ b/mesonbuild/compilers/vala.py
@@ -14,11 +14,11 @@ from .compilers import CompileCheckMode, Compiler
if T.TYPE_CHECKING:
from ..arglist import CompilerArgs
- from ..coredata import KeyedOptionDictType
from ..envconfig import MachineInfo
from ..environment import Environment
from ..mesonlib import MachineChoice
from ..dependencies import Dependency
+ from ..build import BuildTarget
class ValaCompiler(Compiler):
@@ -141,7 +141,7 @@ class ValaCompiler(Compiler):
def thread_link_flags(self, env: 'Environment') -> T.List[str]:
return []
- def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]:
return []
def build_wrapper_args(self, env: 'Environment',