diff options
Diffstat (limited to 'mesonbuild/compilers/cpp.py')
| -rw-r--r-- | mesonbuild/compilers/cpp.py | 366 |
1 files changed, 189 insertions, 177 deletions
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 01b9bb9..5ed4aea 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -32,11 +32,11 @@ from .mixins.pgi import PGICompiler from .mixins.emscripten import EmscriptenMixin from .mixins.metrowerks import MetrowerksCompiler from .mixins.metrowerks import mwccarm_instruction_set_args, mwcceppc_instruction_set_args +from .mixins.microchip import Xc32Compiler, Xc32CPPStds if T.TYPE_CHECKING: from ..options import MutableKeyedOptionDictType from ..dependencies import Dependency - from ..envconfig import MachineInfo from ..environment import Environment from ..linkers.linkers import DynamicLinker from ..mesonlib import MachineChoice @@ -66,14 +66,12 @@ class CPPCompiler(CLikeCompiler, Compiler): language = 'cpp' - def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, - info: 'MachineInfo', - linker: T.Optional['DynamicLinker'] = None, + def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, + env: Environment, linker: T.Optional['DynamicLinker'] = None, full_version: T.Optional[str] = None): # If a child ObjCPP class has already set it, don't set it ourselves - Compiler.__init__(self, ccache, exelist, version, for_machine, info, - is_cross=is_cross, linker=linker, - full_version=full_version) + Compiler.__init__(self, ccache, exelist, version, for_machine, env, + linker=linker, full_version=full_version) CLikeCompiler.__init__(self) @classmethod @@ -86,9 +84,9 @@ class CPPCompiler(CLikeCompiler, Compiler): def get_no_stdlib_link_args(self) -> T.List[str]: return ['-nostdlib++'] - def sanity_check(self, work_dir: str, environment: 'Environment') -> None: + def sanity_check(self, work_dir: str) -> None: code = 'class breakCCompiler;int main(void) { return 0; }\n' - return self._sanity_check_impl(work_dir, environment, 'sanitycheckcpp.cc', code) + return self._sanity_check_impl(work_dir, 'sanitycheckcpp.cc', code) def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: # -fpermissive allows non-conforming code to compile which is necessary @@ -96,12 +94,11 @@ class CPPCompiler(CLikeCompiler, Compiler): # too strict without this and always fails. return super().get_compiler_check_args(mode) + ['-fpermissive'] - def has_header_symbol(self, hname: str, symbol: str, prefix: str, - env: 'Environment', *, + def has_header_symbol(self, hname: str, symbol: str, prefix: str, *, extra_args: T.Union[None, T.List[str], T.Callable[[CompileCheckMode], T.List[str]]] = None, dependencies: T.Optional[T.List['Dependency']] = None) -> T.Tuple[bool, bool]: # Check if it's a C-like symbol - found, cached = super().has_header_symbol(hname, symbol, prefix, env, + found, cached = super().has_header_symbol(hname, symbol, prefix, extra_args=extra_args, dependencies=dependencies) if found: @@ -113,7 +110,7 @@ class CPPCompiler(CLikeCompiler, Compiler): #include <{hname}> using {symbol}; int main(void) {{ return 0; }}''' - return self.compiles(t, env, extra_args=extra_args, + return self.compiles(t, extra_args=extra_args, dependencies=dependencies) def _test_cpp_std_arg(self, cpp_std_value: str) -> bool: @@ -158,7 +155,7 @@ class CPPCompiler(CLikeCompiler, Compiler): } # Currently, remapping is only supported for Clang, Elbrus and GCC - assert self.id in frozenset(['clang', 'lcc', 'gcc', 'emscripten', 'armltdclang', 'intel-llvm']) + assert self.id in frozenset(['clang', 'lcc', 'gcc', 'emscripten', 'armltdclang', 'intel-llvm', 'nvidia_hpc', 'xc32-gcc']) if cpp_std not in CPP_FALLBACKS: # 'c++03' and 'c++98' don't have fallback types @@ -186,13 +183,13 @@ class _StdCPPLibMixin(CompilerMixinBase): def language_stdlib_provider(self, env: Environment) -> str: # https://stackoverflow.com/a/31658120 - header = 'version' if self.has_header('version', '', env)[0] else 'ciso646' - is_libcxx = self.has_header_symbol(header, '_LIBCPP_VERSION', '', env)[0] + header = 'version' if self.has_header('version', '')[0] else 'ciso646' + is_libcxx = self.has_header_symbol(header, '_LIBCPP_VERSION', '')[0] lib = 'c++' if is_libcxx else 'stdc++' return lib @functools.lru_cache(None) - def language_stdlib_only_link_flags(self, env: Environment) -> T.List[str]: + def language_stdlib_only_link_flags(self) -> T.List[str]: """Detect the C++ stdlib and default search dirs As an optimization, this method will cache the value, to avoid building the same values over and over @@ -205,13 +202,10 @@ class _StdCPPLibMixin(CompilerMixinBase): # be passed to a different compiler with a different set of default # search paths, such as when using Clang for C/C++ and gfortran for # fortran. - search_dirs = [f'-L{d}' for d in self.get_compiler_dirs(env, 'libraries')] - - machine = env.machines[self.for_machine] - assert machine is not None, 'for mypy' + search_dirs = [f'-L{d}' for d in self.get_compiler_dirs('libraries')] - lib = self.language_stdlib_provider(env) - if self.find_library(lib, env, []) is not None: + lib = self.language_stdlib_provider(self.environment) + if self.find_library(lib, []) is not None: return search_dirs + [f'-l{lib}'] # TODO: maybe a bug exception? @@ -220,13 +214,12 @@ class _StdCPPLibMixin(CompilerMixinBase): class ClangCPPCompiler(_StdCPPLibMixin, ClangCPPStds, ClangCompiler, CPPCompiler): - def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, - info: 'MachineInfo', - linker: T.Optional['DynamicLinker'] = None, + def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, + env: Environment, linker: T.Optional['DynamicLinker'] = None, defines: T.Optional[T.Dict[str, str]] = None, full_version: T.Optional[str] = None): - CPPCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross, - info, linker=linker, full_version=full_version) + CPPCompiler.__init__(self, ccache, exelist, version, for_machine, + env, linker=linker, full_version=full_version) ClangCompiler.__init__(self, defines) default_warn_args = ['-Wall', '-Winvalid-pch'] self.warn_args = {'0': [], @@ -265,12 +258,12 @@ class ClangCPPCompiler(_StdCPPLibMixin, ClangCPPStds, ClangCompiler, CPPCompiler gnu_winlibs) return opts - def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: args: T.List[str] = [] - 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) + rtti = self.get_compileropt_value('rtti', target, subproject) + debugstl = self.get_compileropt_value('debugstl', target, subproject) + eh = self.get_compileropt_value('eh', target, subproject) assert isinstance(rtti, bool) assert isinstance(eh, str) @@ -285,6 +278,7 @@ class ClangCPPCompiler(_StdCPPLibMixin, ClangCPPStds, ClangCompiler, CPPCompiler # https://discourse.llvm.org/t/building-a-program-with-d-libcpp-debug-1-against-a-libc-that-is-not-itself-built-with-that-define/59176/3 # Note that unlike _GLIBCXX_DEBUG, _MODE_DEBUG doesn't break ABI. It's just slow. if version_compare(self.version, '>=18'): + args.append('-U_LIBCPP_HARDENING_MODE') args.append('-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG') if not rtti: @@ -292,18 +286,18 @@ class ClangCPPCompiler(_StdCPPLibMixin, ClangCPPStds, ClangCompiler, CPPCompiler return args - def get_option_std_args(self, target: BuildTarget, env: Environment, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: args: T.List[str] = [] - std = self.get_compileropt_value('std', env, target, subproject) + std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != 'none': args.append(self._find_best_cpp_std(std)) return args - def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: 'BuildTarget', 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. - retval = self.get_compileropt_value('winlibs', env, target, subproject) + retval = self.get_compileropt_value('winlibs', target, subproject) assert isinstance(retval, list) libs = retval[:] for l in libs: @@ -311,7 +305,7 @@ class ClangCPPCompiler(_StdCPPLibMixin, ClangCPPStds, ClangCompiler, CPPCompiler return libs return [] - def get_assert_args(self, disable: bool, env: 'Environment') -> T.List[str]: + def get_assert_args(self, disable: bool) -> T.List[str]: if disable: return ['-DNDEBUG'] @@ -320,15 +314,10 @@ class ClangCPPCompiler(_StdCPPLibMixin, ClangCPPStds, ClangCompiler, CPPCompiler if self.defines.get(macro) is not None: return [] - if self.language_stdlib_provider(env) == 'stdc++': + if self.language_stdlib_provider(self.environment) == 'stdc++': return ['-D_GLIBCXX_ASSERTIONS=1'] - else: - if version_compare(self.version, '>=18'): - return ['-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST'] - elif version_compare(self.version, '>=15'): - return ['-D_LIBCPP_ENABLE_ASSERTIONS=1'] - return [] + return ['-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST'] def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]: args = super().get_pch_use_args(pch_dir, header) @@ -359,22 +348,20 @@ class EmscriptenCPPCompiler(EmscriptenMixin, ClangCPPCompiler): _CPP23_VERSION = '>=2.0.10' _CPP26_VERSION = '>=3.1.39' - def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, - info: 'MachineInfo', - linker: T.Optional['DynamicLinker'] = None, + def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, + env: Environment, linker: T.Optional['DynamicLinker'] = None, defines: T.Optional[T.Dict[str, str]] = None, full_version: T.Optional[str] = None): - if not is_cross: + if not env.is_cross_build(for_machine): raise MesonException('Emscripten compiler can only be used for cross compilation.') if not version_compare(version, '>=1.39.19'): raise MesonException('Meson requires Emscripten >= 1.39.19') - ClangCPPCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross, - info, linker=linker, - defines=defines, full_version=full_version) + ClangCPPCompiler.__init__(self, ccache, exelist, version, for_machine, env, + linker=linker, defines=defines, full_version=full_version) - def get_option_std_args(self, target: BuildTarget, env: Environment, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: args: T.List[str] = [] - std = self.get_compileropt_value('std', env, target, subproject) + std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != 'none': args.append(self._find_best_cpp_std(std)) @@ -386,12 +373,11 @@ class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler): Keil armclang ''' - def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, - info: 'MachineInfo', - linker: T.Optional['DynamicLinker'] = None, + def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, + env: Environment, linker: T.Optional['DynamicLinker'] = None, full_version: T.Optional[str] = None): - CPPCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross, - info, linker=linker, full_version=full_version) + CPPCompiler.__init__(self, ccache, exelist, version, for_machine, + env, linker=linker, full_version=full_version) ArmclangCompiler.__init__(self) default_warn_args = ['-Wall', '-Winvalid-pch'] self.warn_args = {'0': [], @@ -416,31 +402,30 @@ 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_std_args(self, target: BuildTarget, env: Environment, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: args: T.List[str] = [] - std = self.get_compileropt_value('std', env, target, subproject) + std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != 'none': args.append('-std=' + std) - eh = self.get_compileropt_value('eh', env, target, subproject) + eh = self.get_compileropt_value('eh', target, subproject) assert isinstance(eh, str) non_msvc_eh_options(eh, args) return args - def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: return [] class GnuCPPCompiler(_StdCPPLibMixin, GnuCPPStds, GnuCompiler, CPPCompiler): - def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, - info: 'MachineInfo', - linker: T.Optional['DynamicLinker'] = None, + def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, + env: Environment, linker: T.Optional['DynamicLinker'] = None, defines: T.Optional[T.Dict[str, str]] = None, full_version: T.Optional[str] = None): - CPPCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross, - info, linker=linker, full_version=full_version) + CPPCompiler.__init__(self, ccache, exelist, version, for_machine, + env, linker=linker, full_version=full_version) GnuCompiler.__init__(self, defines) default_warn_args = ['-Wall', '-Winvalid-pch'] self.warn_args = {'0': [], @@ -480,14 +465,21 @@ class GnuCPPCompiler(_StdCPPLibMixin, GnuCPPStds, GnuCompiler, CPPCompiler): 'Standard Win libraries to link against', gnu_winlibs) + if version_compare(self.version, '>=15.1'): + key = key.evolve(name='cpp_importstd') + opts[key] = options.UserComboOption(self.make_option_name(key), + 'Use #import std.', + 'false', + choices=['false', 'true']) + return opts - def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: args: T.List[str] = [] - 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) + rtti = self.get_compileropt_value('rtti', target, subproject) + debugstl = self.get_compileropt_value('debugstl', target, subproject) + eh = self.get_compileropt_value('eh', target, subproject) assert isinstance(rtti, bool) assert isinstance(eh, str) @@ -498,22 +490,23 @@ class GnuCPPCompiler(_StdCPPLibMixin, GnuCPPStds, GnuCompiler, CPPCompiler): if not rtti: args.append('-fno-rtti') + # We may want to handle libc++'s debugstl mode here too if debugstl: args.append('-D_GLIBCXX_DEBUG=1') return args - def get_option_std_args(self, target: BuildTarget, env: Environment, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: args: T.List[str] = [] - std = self.get_compileropt_value('std', env, target, subproject) + std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != 'none': args.append(self._find_best_cpp_std(std)) return args - def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: 'BuildTarget', 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. - retval = self.get_compileropt_value('winlibs', env, target, subproject) + retval = self.get_compileropt_value('winlibs', target, subproject) assert isinstance(retval, list) libs: T.List[str] = retval[:] for l in libs: @@ -521,7 +514,7 @@ class GnuCPPCompiler(_StdCPPLibMixin, GnuCPPStds, GnuCompiler, CPPCompiler): return libs return [] - def get_assert_args(self, disable: bool, env: 'Environment') -> T.List[str]: + def get_assert_args(self, disable: bool) -> T.List[str]: if disable: return ['-DNDEBUG'] @@ -530,13 +523,17 @@ class GnuCPPCompiler(_StdCPPLibMixin, GnuCPPStds, GnuCompiler, CPPCompiler): if self.defines.get(macro) is not None: return [] - if self.language_stdlib_provider(env) == 'stdc++': + # For GCC, we can assume that the libstdc++ version is the same as + # the compiler itself. Anything else isn't supported. + if self.language_stdlib_provider(self.environment) == 'stdc++': return ['-D_GLIBCXX_ASSERTIONS=1'] else: + # One can use -stdlib=libc++ with GCC, it just (as of 2025) requires + # an experimental configure arg to expose that. libc++ supports "multiple" + # versions of GCC (only ever one version of GCC per libc++ version), but + # that is "multiple" for our purposes as we can't assume a mapping. if version_compare(self.version, '>=18'): return ['-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST'] - elif version_compare(self.version, '>=15'): - return ['-D_LIBCPP_ENABLE_ASSERTIONS=1'] return [] @@ -545,12 +542,11 @@ class GnuCPPCompiler(_StdCPPLibMixin, GnuCPPStds, GnuCompiler, CPPCompiler): class PGICPPCompiler(PGICompiler, CPPCompiler): - def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, - info: 'MachineInfo', - linker: T.Optional['DynamicLinker'] = None, + def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, + env: Environment, linker: T.Optional['DynamicLinker'] = None, full_version: T.Optional[str] = None): - CPPCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross, - info, linker=linker, full_version=full_version) + CPPCompiler.__init__(self, ccache, exelist, version, for_machine, + env, linker=linker, full_version=full_version) PGICompiler.__init__(self) @@ -558,12 +554,11 @@ class NvidiaHPC_CPPCompiler(PGICompiler, CPPCompiler): id = 'nvidia_hpc' - def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, - info: 'MachineInfo', - linker: T.Optional['DynamicLinker'] = None, + def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, + env: Environment, linker: T.Optional['DynamicLinker'] = None, full_version: T.Optional[str] = None): - CPPCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross, - info, linker=linker, full_version=full_version) + CPPCompiler.__init__(self, ccache, exelist, version, for_machine, + env, linker=linker, full_version=full_version) PGICompiler.__init__(self) def get_options(self) -> 'MutableKeyedOptionDictType': @@ -577,15 +572,22 @@ class NvidiaHPC_CPPCompiler(PGICompiler, CPPCompiler): std_opt.set_versions(cppstd_choices) return opts + def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + args: T.List[str] = [] + std = self.get_compileropt_value('std', target, subproject) + assert isinstance(std, str) + if std != 'none': + args.append(self._find_best_cpp_std(std)) + return args + class ElbrusCPPCompiler(ElbrusCompiler, CPPCompiler): - def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, - info: 'MachineInfo', - linker: T.Optional['DynamicLinker'] = None, + def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, + env: Environment, linker: T.Optional['DynamicLinker'] = None, defines: T.Optional[T.Dict[str, str]] = None, full_version: T.Optional[str] = None): - CPPCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross, - info, linker=linker, full_version=full_version) + CPPCompiler.__init__(self, ccache, exelist, version, for_machine, + env, linker=linker, full_version=full_version) ElbrusCompiler.__init__(self) def get_options(self) -> 'MutableKeyedOptionDictType': @@ -628,33 +630,30 @@ class ElbrusCPPCompiler(ElbrusCompiler, CPPCompiler): # Elbrus C++ compiler does not have lchmod, but there is only linker warning, not compiler error. # So we should explicitly fail at this case. - def has_function(self, funcname: str, prefix: str, env: 'Environment', *, + def has_function(self, funcname: str, prefix: str, *, extra_args: T.Optional[T.List[str]] = None, dependencies: T.Optional[T.List['Dependency']] = None) -> T.Tuple[bool, bool]: if funcname == 'lchmod': return False, False - else: - return super().has_function(funcname, prefix, env, - extra_args=extra_args, - dependencies=dependencies) + return super().has_function(funcname, prefix, extra_args=extra_args, dependencies=dependencies) # Elbrus C++ compiler does not support RTTI, so don't check for it. - def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: args: T.List[str] = [] - eh = self.get_compileropt_value('eh', env, target, subproject) + eh = self.get_compileropt_value('eh', target, subproject) assert isinstance(eh, str) non_msvc_eh_options(eh, args) - debugstl = self.get_compileropt_value('debugstl', env, target, subproject) + debugstl = self.get_compileropt_value('debugstl', target, subproject) assert isinstance(debugstl, str) if debugstl: args.append('-D_GLIBCXX_DEBUG=1') return args - def get_option_std_args(self, target: BuildTarget, env: Environment, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: args: T.List[str] = [] - std = self.get_compileropt_value('std', env, target, subproject) + std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != 'none': args.append(self._find_best_cpp_std(std)) @@ -662,12 +661,11 @@ class ElbrusCPPCompiler(ElbrusCompiler, CPPCompiler): class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler): - def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, - info: 'MachineInfo', - linker: T.Optional['DynamicLinker'] = None, + def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, + env: Environment, linker: T.Optional['DynamicLinker'] = None, full_version: T.Optional[str] = None): - CPPCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross, - info, linker=linker, full_version=full_version) + CPPCompiler.__init__(self, ccache, exelist, version, for_machine, + env, linker=linker, full_version=full_version) IntelGnuLikeCompiler.__init__(self) self.lang_header = 'c++-header' default_warn_args = ['-Wall', '-w3', '-Wpch-messages'] @@ -718,12 +716,12 @@ class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler): self._update_language_stds(opts, c_stds + g_stds) return opts - def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: args: T.List[str] = [] - 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) + rtti = self.get_compileropt_value('rtti', target, subproject) + debugstl = self.get_compileropt_value('debugstl', target, subproject) + eh = self.get_compileropt_value('eh', target, subproject) assert isinstance(rtti, bool) assert isinstance(eh, str) @@ -731,15 +729,15 @@ class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler): if eh == 'none': args.append('-fno-exceptions') - if rtti: + if not rtti: args.append('-fno-rtti') if debugstl: args.append('-D_GLIBCXX_DEBUG=1') return args - def get_option_std_args(self, target: BuildTarget, env: Environment, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: args: T.List[str] = [] - std = self.get_compileropt_value('std', env, target, subproject) + std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != 'none': remap_cpp03 = { @@ -750,7 +748,7 @@ class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler): return args - def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: return [] @@ -777,13 +775,13 @@ class VisualStudioLikeCPPCompilerMixin(CompilerMixinBase): 'c++latest': (False, "latest"), } - def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: # need a typeddict for this key = self.form_compileropt_key('winlibs').evolve(subproject=subproject) if target: - value = env.coredata.get_option_for_target(target, key) + value = self.environment.coredata.get_option_for_target(target, key) else: - value = env.coredata.optstore.get_value_for(key) + value = self.environment.coredata.optstore.get_value_for(key) return T.cast('T.List[str]', value)[:] def _get_options_impl(self, opts: 'MutableKeyedOptionDictType', cpp_stds: T.List[str]) -> 'MutableKeyedOptionDictType': @@ -811,13 +809,20 @@ class VisualStudioLikeCPPCompilerMixin(CompilerMixinBase): std_opt = opts[self.form_compileropt_key('std')] assert isinstance(std_opt, options.UserStdOption), 'for mypy' std_opt.set_versions(cpp_stds) + + if version_compare(self.version, '>=19.44.35219'): + key = self.form_compileropt_key('importstd') + opts[key] = options.UserComboOption(self.make_option_name(key), + 'Use #import std.', + 'false', + choices=['false', 'true']) return opts - def get_option_compile_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: args: T.List[str] = [] - eh = self.get_compileropt_value('eh', env, target, subproject) - rtti = self.get_compileropt_value('rtti', env, target, subproject) + eh = self.get_compileropt_value('eh', target, subproject) + rtti = self.get_compileropt_value('rtti', target, subproject) assert isinstance(rtti, bool) assert isinstance(eh, str) @@ -834,9 +839,9 @@ class VisualStudioLikeCPPCompilerMixin(CompilerMixinBase): return args - def get_option_std_args(self, target: BuildTarget, env: Environment, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: args: T.List[str] = [] - std = self.get_compileropt_value('std', env, target, subproject) + std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) permissive, ver = self.VC_VERSION_MAP[std] @@ -857,23 +862,22 @@ class CPP11AsCPP14Mixin(CompilerMixinBase): This is a limitation of Clang and MSVC that ICL doesn't share. """ - def get_option_std_args(self, target: BuildTarget, env: Environment, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: BuildTarget, 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. stdkey = self.form_compileropt_key('std').evolve(subproject=subproject) if target is not None: - std = env.coredata.get_option_for_target(target, stdkey) + std = self.environment.coredata.get_option_for_target(target, stdkey) else: - std = env.coredata.optstore.get_value_for(stdkey) + std = self.environment.coredata.optstore.get_value_for(stdkey) 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) - original_args = super().get_option_std_args(target, env, subproject) - std_mapping = {'/std:c++11': '/std:c++14', - '/std:c++14': '/std:vc++14'} + original_args = super().get_option_std_args(target, subproject) + std_mapping = {'/std:c++11': '/std:c++14'} processed_args = [std_mapping.get(x, x) for x in original_args] return processed_args @@ -883,11 +887,11 @@ class VisualStudioCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixi id = 'msvc' def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, - is_cross: bool, info: 'MachineInfo', target: str, + env: Environment, target: str, linker: T.Optional['DynamicLinker'] = None, full_version: T.Optional[str] = None): - CPPCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross, - info, linker=linker, full_version=full_version) + CPPCompiler.__init__(self, ccache, exelist, version, for_machine, + env, linker=linker, full_version=full_version) MSVCCompiler.__init__(self, target) # By default, MSVC has a broken __cplusplus define that pretends to be c++98: @@ -908,12 +912,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_std_args(self, target: BuildTarget, env: Environment, subproject: T.Optional[str] = None) -> T.List[str]: - std = self.get_compileropt_value('std', env, target, subproject) + def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + std = self.get_compileropt_value('std', 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) - args = super().get_option_std_args(target, env, subproject) + args = super().get_option_std_args(target, subproject) if version_compare(self.version, '<19.11'): try: @@ -928,11 +932,11 @@ class ClangClCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixin, Cl id = 'clang-cl' def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, - is_cross: bool, info: 'MachineInfo', target: str, + env: Environment, target: str, linker: T.Optional['DynamicLinker'] = None, full_version: T.Optional[str] = None): - CPPCompiler.__init__(self, [], exelist, version, for_machine, is_cross, - info, linker=linker, full_version=full_version) + CPPCompiler.__init__(self, [], exelist, version, for_machine, + env, linker=linker, full_version=full_version) ClangClCompiler.__init__(self, target) def get_options(self) -> 'MutableKeyedOptionDictType': @@ -943,11 +947,11 @@ class ClangClCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixin, Cl class IntelClCPPCompiler(VisualStudioLikeCPPCompilerMixin, IntelVisualStudioLikeCompiler, CPPCompiler): def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, - is_cross: bool, info: 'MachineInfo', target: str, + env: Environment, target: str, linker: T.Optional['DynamicLinker'] = None, full_version: T.Optional[str] = None): - CPPCompiler.__init__(self, [], exelist, version, for_machine, is_cross, - info, linker=linker, full_version=full_version) + CPPCompiler.__init__(self, [], exelist, version, for_machine, + env, linker=linker, full_version=full_version) IntelVisualStudioLikeCompiler.__init__(self, target) def get_options(self) -> 'MutableKeyedOptionDictType': @@ -971,12 +975,11 @@ class IntelLLVMClCPPCompiler(IntelClCPPCompiler): class ArmCPPCompiler(ArmCompiler, CPPCompiler): - def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, - info: 'MachineInfo', - linker: T.Optional['DynamicLinker'] = None, + def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, + env: Environment, linker: T.Optional['DynamicLinker'] = None, full_version: T.Optional[str] = None): - CPPCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross, - info, linker=linker, full_version=full_version) + CPPCompiler.__init__(self, ccache, exelist, version, for_machine, + env, linker=linker, full_version=full_version) ArmCompiler.__init__(self) def get_options(self) -> 'MutableKeyedOptionDictType': @@ -986,9 +989,9 @@ class ArmCPPCompiler(ArmCompiler, CPPCompiler): std_opt.set_versions(['c++03', 'c++11']) return opts - def get_option_std_args(self, target: BuildTarget, env: Environment, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: args: T.List[str] = [] - std = self.get_compileropt_value('std', env, target, subproject) + std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std == 'c++11': args.append('--cpp11') @@ -996,7 +999,7 @@ class ArmCPPCompiler(ArmCompiler, CPPCompiler): args.append('--cpp') return args - def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: return [] def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: @@ -1004,12 +1007,11 @@ class ArmCPPCompiler(ArmCompiler, CPPCompiler): class CcrxCPPCompiler(CcrxCompiler, CPPCompiler): - def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, - info: 'MachineInfo', - linker: T.Optional['DynamicLinker'] = None, + def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, + env: Environment, linker: T.Optional['DynamicLinker'] = None, full_version: T.Optional[str] = None): - CPPCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross, - info, linker=linker, full_version=full_version) + CPPCompiler.__init__(self, ccache, exelist, version, for_machine, + env, linker=linker, full_version=full_version) CcrxCompiler.__init__(self) # Override CCompiler.get_always_args @@ -1022,19 +1024,18 @@ 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, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: return [] def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: return [] class TICPPCompiler(TICompiler, CPPCompiler): - def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, - info: 'MachineInfo', - linker: T.Optional['DynamicLinker'] = None, + def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, + env: Environment, linker: T.Optional['DynamicLinker'] = None, full_version: T.Optional[str] = None): - CPPCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross, - info, linker=linker, full_version=full_version) + CPPCompiler.__init__(self, ccache, exelist, version, for_machine, + env, linker=linker, full_version=full_version) TICompiler.__init__(self) def get_options(self) -> 'MutableKeyedOptionDictType': @@ -1045,9 +1046,9 @@ class TICPPCompiler(TICompiler, CPPCompiler): std_opt.set_versions(['c++03']) return opts - def get_option_std_args(self, target: BuildTarget, env: Environment, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: args: T.List[str] = [] - std = self.get_compileropt_value('std', env, target, subproject) + std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != 'none': args.append('--' + std) @@ -1056,7 +1057,7 @@ class TICPPCompiler(TICompiler, CPPCompiler): def get_always_args(self) -> T.List[str]: return [] - def get_option_link_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: return [] class C2000CPPCompiler(TICPPCompiler): @@ -1070,11 +1071,10 @@ class MetrowerksCPPCompilerARM(MetrowerksCompiler, CPPCompiler): id = 'mwccarm' def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, - is_cross: bool, info: 'MachineInfo', - linker: T.Optional['DynamicLinker'] = None, + env: Environment, linker: T.Optional['DynamicLinker'] = None, full_version: T.Optional[str] = None): - CPPCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross, - info, linker=linker, full_version=full_version) + CPPCompiler.__init__(self, ccache, exelist, version, for_machine, + env, linker=linker, full_version=full_version) MetrowerksCompiler.__init__(self) def get_instruction_set_args(self, instruction_set: str) -> T.Optional[T.List[str]]: @@ -1085,9 +1085,9 @@ class MetrowerksCPPCompilerARM(MetrowerksCompiler, CPPCompiler): self._update_language_stds(opts, []) return opts - def get_option_std_args(self, target: BuildTarget, env: Environment, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: args: T.List[str] = [] - std = self.get_compileropt_value('std', env, target, subproject) + std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != 'none': args.append('-lang') @@ -1098,11 +1098,10 @@ class MetrowerksCPPCompilerEmbeddedPowerPC(MetrowerksCompiler, CPPCompiler): id = 'mwcceppc' def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, - is_cross: bool, info: 'MachineInfo', - linker: T.Optional['DynamicLinker'] = None, + env: Environment, linker: T.Optional['DynamicLinker'] = None, full_version: T.Optional[str] = None): - CPPCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross, - info, linker=linker, full_version=full_version) + CPPCompiler.__init__(self, ccache, exelist, version, for_machine, + env, linker=linker, full_version=full_version) MetrowerksCompiler.__init__(self) def get_instruction_set_args(self, instruction_set: str) -> T.Optional[T.List[str]]: @@ -1113,10 +1112,23 @@ class MetrowerksCPPCompilerEmbeddedPowerPC(MetrowerksCompiler, CPPCompiler): self._update_language_stds(opts, []) return opts - def get_option_std_args(self, target: BuildTarget, env: Environment, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: args: T.List[str] = [] - std = self.get_compileropt_value('std', env, target, subproject) + std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != 'none': args.append('-lang ' + std) return args + + +class Xc32CPPCompiler(Xc32CPPStds, Xc32Compiler, GnuCPPCompiler): + + """Microchip XC32 C++ compiler.""" + + def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, + env: Environment, linker: T.Optional[DynamicLinker] = None, + defines: T.Optional[T.Dict[str, str]] = None, + full_version: T.Optional[str] = None): + GnuCPPCompiler.__init__(self, ccache, exelist, version, for_machine, env, + linker=linker, full_version=full_version, defines=defines) + Xc32Compiler.__init__(self) |
