aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/compilers
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild/compilers')
-rw-r--r--mesonbuild/compilers/__init__.py2
-rw-r--r--mesonbuild/compilers/c.py2
-rw-r--r--mesonbuild/compilers/compilers.py73
-rw-r--r--mesonbuild/compilers/cpp.py16
-rw-r--r--mesonbuild/compilers/cs.py5
-rw-r--r--mesonbuild/compilers/cuda.py42
-rw-r--r--mesonbuild/compilers/d.py21
-rw-r--r--mesonbuild/compilers/detect.py62
-rw-r--r--mesonbuild/compilers/fortran.py15
-rw-r--r--mesonbuild/compilers/java.py5
-rw-r--r--mesonbuild/compilers/mixins/clang.py5
-rw-r--r--mesonbuild/compilers/mixins/clike.py48
-rw-r--r--mesonbuild/compilers/mixins/emscripten.py2
-rw-r--r--mesonbuild/compilers/mixins/gnu.py2
-rw-r--r--mesonbuild/compilers/mixins/islinker.py5
-rw-r--r--mesonbuild/compilers/mixins/pgi.py6
-rw-r--r--mesonbuild/compilers/rust.py67
-rw-r--r--mesonbuild/compilers/swift.py32
-rw-r--r--mesonbuild/compilers/vala.py2
19 files changed, 212 insertions, 200 deletions
diff --git a/mesonbuild/compilers/__init__.py b/mesonbuild/compilers/__init__.py
index aab761a..f645090 100644
--- a/mesonbuild/compilers/__init__.py
+++ b/mesonbuild/compilers/__init__.py
@@ -18,6 +18,7 @@ __all__ = [
'is_library',
'is_llvm_ir',
'is_object',
+ 'is_separate_compile',
'is_source',
'is_java',
'is_known_suffix',
@@ -62,6 +63,7 @@ from .compilers import (
is_object,
is_library,
is_known_suffix,
+ is_separate_compile,
lang_suffixes,
LANGUAGES_USING_LDFLAGS,
sort_clink,
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index 7a2fec5..424b612 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -504,7 +504,7 @@ class IntelClCCompiler(IntelVisualStudioLikeCompiler, VisualStudioLikeCCompilerM
def get_option_std_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)
+ std = self.get_compileropt_value('std', 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)
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index 3c1d58b..a823aeb 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -42,7 +42,7 @@ _T = T.TypeVar('_T')
about. To support a new compiler, add its information below.
Also add corresponding autodetection code in detect.py."""
-header_suffixes = {'h', 'hh', 'hpp', 'hxx', 'H', 'ipp', 'moc', 'vapi', 'di'}
+header_suffixes = {'h', 'hh', 'hpp', 'hxx', 'H', 'ipp', 'moc', 'vapi', 'di', 'pxd', 'pxi'}
obj_suffixes = {'o', 'obj', 'res'}
# To the emscripten compiler, .js files are libraries
lib_suffixes = {'a', 'lib', 'dll', 'dll.a', 'dylib', 'so', 'js'}
@@ -84,7 +84,7 @@ clib_langs = ('objcpp', 'cpp', 'objc', 'c', 'nasm', 'fortran')
# List of languages that can be linked with C code directly by the linker
# used in build.py:process_compilers() and build.py:get_dynamic_linker()
# This must be sorted, see sort_clink().
-clink_langs = ('d', 'cuda') + clib_langs
+clink_langs = ('rust', 'd', 'cuda') + clib_langs
SUFFIX_TO_LANG = dict(itertools.chain(*(
[(suffix, lang) for suffix in v] for lang, v in lang_suffixes.items())))
@@ -154,6 +154,9 @@ def is_java(fname: mesonlib.FileOrString) -> bool:
suffix = fname.split('.')[-1]
return suffix in lang_suffixes['java']
+def is_separate_compile(fname: mesonlib.FileOrString) -> bool:
+ return not fname.endswith('.rs')
+
def is_llvm_ir(fname: 'mesonlib.FileOrString') -> bool:
if isinstance(fname, mesonlib.File):
fname = fname.fname
@@ -749,7 +752,7 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
return args.copy()
def find_library(self, libname: str, env: 'Environment', extra_dirs: T.List[str],
- libtype: LibType = LibType.PREFER_SHARED, lib_prefix_warning: bool = True) -> T.Optional[T.List[str]]:
+ libtype: LibType = LibType.PREFER_SHARED, lib_prefix_warning: bool = True, ignore_system_dirs: bool = False) -> T.Optional[T.List[str]]:
raise EnvironmentException(f'Language {self.get_display_language()} does not support library finding.')
def get_library_naming(self, env: 'Environment', libtype: LibType,
@@ -933,11 +936,10 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
"""
return None
- def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
- rpath_paths: T.Tuple[str, ...], build_rpath: str,
- install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]:
+ def build_rpath_args(self, env: Environment, build_dir: str, from_dir: str,
+ target: BuildTarget, extra_paths: T.Optional[T.List[str]] = None) -> T.Tuple[T.List[str], T.Set[bytes]]:
return self.linker.build_rpath_args(
- env, build_dir, from_dir, rpath_paths, build_rpath, install_rpath)
+ env, build_dir, from_dir, target, extra_paths)
def get_archive_name(self, filename: str) -> str:
return self.linker.get_archive_name(filename)
@@ -1200,6 +1202,23 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
is good enough here.
"""
+ def run_sanity_check(self, environment: Environment, cmdlist: T.List[str], work_dir: str, use_exe_wrapper_for_cross: bool = True) -> T.Tuple[str, str]:
+ # Run sanity check
+ if self.is_cross and use_exe_wrapper_for_cross:
+ if not environment.has_exe_wrapper():
+ # Can't check if the binaries run so we have to assume they do
+ return ('', '')
+ cmdlist = environment.exe_wrapper.get_command() + cmdlist
+ mlog.debug('Running test binary command: ', mesonlib.join_args(cmdlist))
+ try:
+ pe, stdo, stde = Popen_safe_logged(cmdlist, 'Sanity check', cwd=work_dir)
+ except Exception as e:
+ raise mesonlib.EnvironmentException(f'Could not invoke sanity check executable: {e!s}.')
+
+ if pe.returncode != 0:
+ raise mesonlib.EnvironmentException(f'Executables created by {self.language} compiler {self.name_string()} are not runnable.')
+ return stdo, stde
+
def split_shlib_to_parts(self, fname: str) -> T.Tuple[T.Optional[str], str]:
return None, fname
@@ -1397,43 +1416,3 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
if 'none' not in value:
value = ['none'] + value
std.choices = value
-
-
-def get_global_options(lang: str,
- comp: T.Type[Compiler],
- for_machine: MachineChoice,
- 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 = 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
-
- comp_options = env.options.get(comp_key, [])
- link_options = env.options.get(largkey, [])
- assert isinstance(comp_options, (str, list)), 'for mypy'
- assert isinstance(link_options, (str, list)), 'for mypy'
-
- cargs = options.UserStringArrayOption(
- argkey.name,
- description + ' compiler',
- comp_options, split_args=True, allow_dups=True)
-
- largs = options.UserStringArrayOption(
- largkey.name,
- description + ' linker',
- link_options, split_args=True, allow_dups=True)
-
- if comp.INVOKES_LINKER and comp_key == envkey:
- # If the compiler acts as a linker driver, and we're using the
- # environment variable flags for both the compiler and linker
- # arguments, then put the compiler flags in the linker flags as well.
- # This is how autotools works, and the env vars feature is for
- # autotools compatibility.
- largs.extend_value(comp_options)
-
- opts: dict[OptionKey, options.AnyOptionType] = {argkey: cargs, largkey: largs}
-
- return opts
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index 01b9bb9..fa032ec 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -311,6 +311,9 @@ class ClangCPPCompiler(_StdCPPLibMixin, ClangCPPStds, ClangCompiler, CPPCompiler
return libs
return []
+ def is_libcpp_enable_assertions_deprecated(self) -> bool:
+ return version_compare(self.version, ">=18")
+
def get_assert_args(self, disable: bool, env: 'Environment') -> T.List[str]:
if disable:
return ['-DNDEBUG']
@@ -323,7 +326,7 @@ class ClangCPPCompiler(_StdCPPLibMixin, ClangCPPStds, ClangCompiler, CPPCompiler
if self.language_stdlib_provider(env) == 'stdc++':
return ['-D_GLIBCXX_ASSERTIONS=1']
else:
- if version_compare(self.version, '>=18'):
+ if self.is_libcpp_enable_assertions_deprecated():
return ['-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST']
elif version_compare(self.version, '>=15'):
return ['-D_LIBCPP_ENABLE_ASSERTIONS=1']
@@ -343,7 +346,13 @@ class ArmLtdClangCPPCompiler(ClangCPPCompiler):
class AppleClangCPPCompiler(AppleCompilerMixin, AppleCPPStdsMixin, ClangCPPCompiler):
- pass
+ def is_libcpp_enable_assertions_deprecated(self) -> bool:
+ # Upstream libc++ deprecated _LIBCPP_ENABLE_ASSERTIONS
+ # in favor of _LIBCPP_HARDENING_MODE from version 18 onwards,
+ # but Apple Clang 16's libc++ has back-ported that change.
+ # See: https://github.com/mesonbuild/meson/issues/14440 and
+ # https://github.com/mesonbuild/meson/issues/14856
+ return version_compare(self.version, ">=16")
class EmscriptenCPPCompiler(EmscriptenMixin, ClangCPPCompiler):
@@ -872,8 +881,7 @@ class CPP11AsCPP14Mixin(CompilerMixinBase):
'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'}
+ std_mapping = {'/std:c++11': '/std:c++14'}
processed_args = [std_mapping.get(x, x) for x in original_args]
return processed_args
diff --git a/mesonbuild/compilers/cs.py b/mesonbuild/compilers/cs.py
index 38bb338..4bbddeb 100644
--- a/mesonbuild/compilers/cs.py
+++ b/mesonbuild/compilers/cs.py
@@ -102,10 +102,7 @@ class CsCompiler(BasicLinkerIsCompilerMixin, Compiler):
cmdlist = [self.runner, obj]
else:
cmdlist = [os.path.join(work_dir, obj)]
- pe = subprocess.Popen(cmdlist, cwd=work_dir)
- pe.wait()
- if pe.returncode != 0:
- raise EnvironmentException('Executables created by Mono compiler %s are not runnable.' % self.name_string())
+ self.run_sanity_check(environment, cmdlist, work_dir, use_exe_wrapper_for_cross=False)
def needs_static_linker(self) -> bool:
return False
diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py
index 6cc6f96..7e050f1 100644
--- a/mesonbuild/compilers/cuda.py
+++ b/mesonbuild/compilers/cuda.py
@@ -198,6 +198,7 @@ class CudaCompiler(Compiler):
for level, flags in host_compiler.warn_args.items()
}
self.host_werror_args = ['-Xcompiler=' + x for x in self.host_compiler.get_werror_args()]
+ self.debug_macros_available = version_compare(self.version, '>=12.9')
@classmethod
def _shield_nvcc_list_arg(cls, arg: str, listmode: bool = True) -> str:
@@ -577,21 +578,12 @@ class CudaCompiler(Compiler):
# Run sanity check (if possible)
if self.is_cross:
- if not env.has_exe_wrapper():
- return
- else:
- cmdlist = env.exe_wrapper.get_command() + [binary_name]
- else:
- cmdlist = self.exelist + ['--run', '"' + binary_name + '"']
- mlog.debug('Sanity check run command line: ', ' '.join(cmdlist))
- pe, stdo, stde = Popen_safe(cmdlist, cwd=work_dir)
- mlog.debug('Sanity check run stdout: ')
- mlog.debug(stdo)
- mlog.debug('-----\nSanity check run stderr:')
- mlog.debug(stde)
- mlog.debug('-----')
- pe.wait()
- if pe.returncode != 0:
+ return
+
+ cmdlist = self.exelist + ['--run', f'"{binary_name}"']
+ try:
+ stdo, stde = self.run_sanity_check(env, cmdlist, work_dir)
+ except EnvironmentException:
raise EnvironmentException(f'Executables created by {self.language} compiler {self.name_string()} are not runnable.')
# Interpret the result of the sanity test.
@@ -599,8 +591,6 @@ class CudaCompiler(Compiler):
# architecture detection test.
if stde == '':
self.detected_cc = stdo
- else:
- mlog.debug('cudaGetDeviceCount() returned ' + stde)
def has_header_symbol(self, hname: str, symbol: str, prefix: str,
env: 'Environment', *,
@@ -741,11 +731,10 @@ class CudaCompiler(Compiler):
def get_optimization_link_args(self, optimization_level: str) -> T.List[str]:
return self._to_host_flags(self.host_compiler.get_optimization_link_args(optimization_level), Phase.LINKER)
- def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
- rpath_paths: T.Tuple[str, ...], build_rpath: str,
- install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]:
+ def build_rpath_args(self, env: Environment, build_dir: str, from_dir: str,
+ target: BuildTarget, extra_paths: T.Optional[T.List[str]] = None) -> T.Tuple[T.List[str], T.Set[bytes]]:
(rpath_args, rpath_dirs_to_remove) = self.host_compiler.build_rpath_args(
- env, build_dir, from_dir, rpath_paths, build_rpath, install_rpath)
+ env, build_dir, from_dir, target, extra_paths)
return (self._to_host_flags(rpath_args, Phase.LINKER), rpath_dirs_to_remove)
def linker_to_compiler_args(self, args: T.List[str]) -> T.List[str]:
@@ -774,8 +763,8 @@ class CudaCompiler(Compiler):
return self._to_host_flags(self.host_compiler.get_std_exe_link_args(), Phase.LINKER)
def find_library(self, libname: str, env: 'Environment', extra_dirs: T.List[str],
- libtype: LibType = LibType.PREFER_SHARED, lib_prefix_warning: bool = True) -> T.Optional[T.List[str]]:
- return self.host_compiler.find_library(libname, env, extra_dirs, libtype, lib_prefix_warning)
+ libtype: LibType = LibType.PREFER_SHARED, lib_prefix_warning: bool = True, ignore_system_dirs: bool = False) -> T.Optional[T.List[str]]:
+ return self.host_compiler.find_library(libname, env, extra_dirs, libtype, lib_prefix_warning, ignore_system_dirs)
def get_crt_compile_args(self, crt_val: str, buildtype: str) -> T.List[str]:
return self._to_host_flags(self.host_compiler.get_crt_compile_args(crt_val, buildtype))
@@ -819,7 +808,12 @@ class CudaCompiler(Compiler):
return ['-Xcompiler=' + x for x in self.host_compiler.get_profile_use_args()]
def get_assert_args(self, disable: bool, env: 'Environment') -> T.List[str]:
- return self.host_compiler.get_assert_args(disable, env)
+ cccl_macros = []
+ if not disable and self.debug_macros_available:
+ # https://github.com/NVIDIA/cccl/pull/2382
+ cccl_macros = ['-DCCCL_ENABLE_ASSERTIONS=1']
+
+ return self.host_compiler.get_assert_args(disable, env) + cccl_macros
def has_multi_arguments(self, args: T.List[str], env: Environment) -> T.Tuple[bool, bool]:
args = self._to_host_flags(args)
diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py
index 8ee6ebf..9f662ad 100644
--- a/mesonbuild/compilers/d.py
+++ b/mesonbuild/compilers/d.py
@@ -26,7 +26,7 @@ from .mixins.gnu import gnu_common_warning_args
if T.TYPE_CHECKING:
from . import compilers
- from ..build import DFeatures
+ from ..build import BuildTarget, DFeatures
from ..dependencies import Dependency
from ..envconfig import MachineInfo
from ..environment import Environment
@@ -175,9 +175,8 @@ class DmdLikeCompilerMixin(CompilerMixinBase):
def gen_import_library_args(self, implibname: str) -> T.List[str]:
return self.linker.import_library_args(implibname)
- def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
- rpath_paths: T.Tuple[str, ...], build_rpath: str,
- install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]:
+ def build_rpath_args(self, env: Environment, build_dir: str, from_dir: str,
+ target: BuildTarget, extra_paths: T.Optional[T.List[str]] = None) -> T.Tuple[T.List[str], T.Set[bytes]]:
if self.info.is_windows():
return ([], set())
@@ -188,7 +187,7 @@ class DmdLikeCompilerMixin(CompilerMixinBase):
# split into two separate arguments both prefaced with the -L=.
args: T.List[str] = []
(rpath_args, rpath_dirs_to_remove) = super().build_rpath_args(
- env, build_dir, from_dir, rpath_paths, build_rpath, install_rpath)
+ env, build_dir, from_dir, target)
for r in rpath_args:
if ',' in r:
a, b = r.split(',', maxsplit=1)
@@ -199,7 +198,7 @@ class DmdLikeCompilerMixin(CompilerMixinBase):
return (args, rpath_dirs_to_remove)
return super().build_rpath_args(
- env, build_dir, from_dir, rpath_paths, build_rpath, install_rpath)
+ env, build_dir, from_dir, target)
@classmethod
def _translate_args_to_nongnu(cls, args: T.List[str], info: MachineInfo, link_id: str) -> T.List[str]:
@@ -456,15 +455,7 @@ class DCompiler(Compiler):
if pc.returncode != 0:
raise EnvironmentException('D compiler %s cannot compile programs.' % self.name_string())
- if self.is_cross:
- if not environment.has_exe_wrapper():
- # Can't check if the binaries run so we have to assume they do
- return
- cmdlist = environment.exe_wrapper.get_command() + [output_name]
- else:
- cmdlist = [output_name]
- if subprocess.call(cmdlist) != 0:
- raise EnvironmentException('Executables created by D compiler %s are not runnable.' % self.name_string())
+ stdo, stde = self.run_sanity_check(environment, [output_name], work_dir)
def needs_static_linker(self) -> bool:
return True
diff --git a/mesonbuild/compilers/detect.py b/mesonbuild/compilers/detect.py
index 53bdd85..f57957f 100644
--- a/mesonbuild/compilers/detect.py
+++ b/mesonbuild/compilers/detect.py
@@ -107,7 +107,7 @@ def detect_compiler_for(env: 'Environment', lang: str, for_machine: MachineChoic
if comp is None:
return comp
assert comp.for_machine == for_machine
- env.coredata.process_compiler_options(lang, comp, env, subproject)
+ env.coredata.process_compiler_options(lang, comp, subproject)
if not skip_sanity_check:
comp.sanity_check(env.get_scratch_dir(), env)
env.coredata.compilers[comp.for_machine][lang] = comp
@@ -366,7 +366,7 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
if 'Emscripten' in out:
cls = c.EmscriptenCCompiler if lang == 'c' else cpp.EmscriptenCPPCompiler
- env.coredata.add_lang_args(cls.language, cls, for_machine, env)
+ env.add_lang_args(cls.language, cls, for_machine)
# emcc requires a file input in order to pass arguments to the
# linker. It'll exit with an error code, but still print the
@@ -410,7 +410,7 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
full_version = arm_ver_str
cls = c.ArmclangCCompiler if lang == 'c' else cpp.ArmclangCPPCompiler
linker = linkers.ArmClangDynamicLinker(for_machine, version=version)
- env.coredata.add_lang_args(cls.language, cls, for_machine, env)
+ env.add_lang_args(cls.language, cls, for_machine)
return cls(
ccache, compiler, version, for_machine, is_cross, info,
full_version=full_version, linker=linker)
@@ -445,7 +445,7 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
if identifier in out:
cls = compiler_classes[0] if lang == 'c' else compiler_classes[1]
lnk = compiler_classes[2]
- env.coredata.add_lang_args(cls.language, cls, for_machine, env)
+ env.add_lang_args(cls.language, cls, for_machine)
linker = lnk(compiler, for_machine, version=version)
return cls(
ccache, compiler, version, for_machine, is_cross, info,
@@ -482,7 +482,7 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
version = search_version(err)
target = 'x86' if 'IA-32' in err else 'x86_64'
cls = c.IntelClCCompiler if lang == 'c' else cpp.IntelClCPPCompiler
- env.coredata.add_lang_args(cls.language, cls, for_machine, env)
+ env.add_lang_args(cls.language, cls, for_machine)
linker = linkers.XilinkDynamicLinker(for_machine, [], version=version)
return cls(
compiler, version, for_machine, is_cross, info, target,
@@ -491,7 +491,7 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
version = search_version(err)
target = 'x86' if 'IA-32' in err else 'x86_64'
cls = c.IntelLLVMClCCompiler if lang == 'c' else cpp.IntelLLVMClCPPCompiler
- env.coredata.add_lang_args(cls.language, cls, for_machine, env)
+ env.add_lang_args(cls.language, cls, for_machine)
linker = linkers.XilinkDynamicLinker(for_machine, [], version=version)
return cls(
compiler, version, for_machine, is_cross, info, target,
@@ -524,14 +524,14 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
full_version=cl_signature, linker=linker)
if 'PGI Compilers' in out:
cls = c.PGICCompiler if lang == 'c' else cpp.PGICPPCompiler
- env.coredata.add_lang_args(cls.language, cls, for_machine, env)
+ env.add_lang_args(cls.language, cls, for_machine)
linker = linkers.PGIDynamicLinker(compiler, for_machine, cls.LINKER_PREFIX, [], version=version)
return cls(
ccache, compiler, version, for_machine, is_cross,
info, linker=linker)
if 'NVIDIA Compilers and Tools' in out:
cls = c.NvidiaHPC_CCompiler if lang == 'c' else cpp.NvidiaHPC_CPPCompiler
- env.coredata.add_lang_args(cls.language, cls, for_machine, env)
+ env.add_lang_args(cls.language, cls, for_machine)
linker = linkers.NvidiaHPC_DynamicLinker(compiler, for_machine, cls.LINKER_PREFIX, [], version=version)
return cls(
ccache, compiler, version, for_machine, is_cross,
@@ -550,14 +550,14 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
full_version=full_version, linker=l)
if 'ARM' in out and not ('Metrowerks' in out or 'Freescale' in out):
cls = c.ArmCCompiler if lang == 'c' else cpp.ArmCPPCompiler
- env.coredata.add_lang_args(cls.language, cls, for_machine, env)
+ env.add_lang_args(cls.language, cls, for_machine)
linker = linkers.ArmDynamicLinker(for_machine, version=version)
return cls(
ccache, compiler, version, for_machine, is_cross,
info, full_version=full_version, linker=linker)
if 'RX Family' in out:
cls = c.CcrxCCompiler if lang == 'c' else cpp.CcrxCPPCompiler
- env.coredata.add_lang_args(cls.language, cls, for_machine, env)
+ env.add_lang_args(cls.language, cls, for_machine)
linker = linkers.CcrxDynamicLinker(for_machine, version=version)
return cls(
ccache, compiler, version, for_machine, is_cross, info,
@@ -565,7 +565,7 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
if 'Microchip Technology' in out:
cls = c.Xc16CCompiler
- env.coredata.add_lang_args(cls.language, cls, for_machine, env)
+ env.add_lang_args(cls.language, cls, for_machine)
linker = linkers.Xc16DynamicLinker(for_machine, version=version)
return cls(
ccache, compiler, version, for_machine, is_cross, info,
@@ -573,7 +573,7 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
if 'CompCert' in out:
cls = c.CompCertCCompiler
- env.coredata.add_lang_args(cls.language, cls, for_machine, env)
+ env.add_lang_args(cls.language, cls, for_machine)
linker = linkers.CompCertDynamicLinker(for_machine, version=version)
return cls(
ccache, compiler, version, for_machine, is_cross, info,
@@ -591,7 +591,7 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
assert mwcc_ver_match is not None, 'for mypy' # because mypy *should* be complaining that this could be None
compiler_version = '.'.join(x for x in mwcc_ver_match.groups() if x is not None)
- env.coredata.add_lang_args(cls.language, cls, for_machine, env)
+ env.add_lang_args(cls.language, cls, for_machine)
ld = env.lookup_binary_entry(for_machine, cls.language + '_ld')
if ld is not None:
@@ -616,7 +616,7 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
assert tasking_ver_match is not None, 'for mypy'
tasking_version = '.'.join(x for x in tasking_ver_match.groups() if x is not None)
- env.coredata.add_lang_args(cls.language, cls, for_machine, env)
+ env.add_lang_args(cls.language, cls, for_machine)
ld = env.lookup_binary_entry(for_machine, cls.language + '_ld')
if ld is None:
raise MesonException(f'{cls.language}_ld was not properly defined in your cross file')
@@ -668,7 +668,7 @@ def detect_cuda_compiler(env: 'Environment', for_machine: MachineChoice) -> Comp
version = out.strip().rsplit('V', maxsplit=1)[-1]
cpp_compiler = detect_cpp_compiler(env, for_machine)
cls = CudaCompiler
- env.coredata.add_lang_args(cls.language, cls, for_machine, env)
+ env.add_lang_args(cls.language, cls, for_machine)
key = OptionKey('cuda_link_args', machine=for_machine)
if key in env.options:
# To fix LDFLAGS issue
@@ -759,7 +759,7 @@ def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> C
version = search_version(err)
target = 'x86' if 'IA-32' in err else 'x86_64'
cls = fortran.IntelLLVMClFortranCompiler
- env.coredata.add_lang_args(cls.language, cls, for_machine, env)
+ env.add_lang_args(cls.language, cls, for_machine)
linker = linkers.XilinkDynamicLinker(for_machine, [], version=version)
return cls(
compiler, version, for_machine, is_cross, info,
@@ -769,7 +769,7 @@ def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> C
version = search_version(err)
target = 'x86' if 'IA-32' in err else 'x86_64'
cls = fortran.IntelClFortranCompiler
- env.coredata.add_lang_args(cls.language, cls, for_machine, env)
+ env.add_lang_args(cls.language, cls, for_machine)
linker = linkers.XilinkDynamicLinker(for_machine, [], version=version)
return cls(
compiler, version, for_machine, is_cross, info,
@@ -796,7 +796,7 @@ def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> C
if 'PGI Compilers' in out:
cls = fortran.PGIFortranCompiler
- env.coredata.add_lang_args(cls.language, cls, for_machine, env)
+ env.add_lang_args(cls.language, cls, for_machine)
linker = linkers.PGIDynamicLinker(compiler, for_machine,
cls.LINKER_PREFIX, [], version=version)
return cls(
@@ -805,7 +805,7 @@ def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> C
if 'NVIDIA Compilers and Tools' in out:
cls = fortran.NvidiaHPC_FortranCompiler
- env.coredata.add_lang_args(cls.language, cls, for_machine, env)
+ env.add_lang_args(cls.language, cls, for_machine)
linker = linkers.PGIDynamicLinker(compiler, for_machine,
cls.LINKER_PREFIX, [], version=version)
return cls(
@@ -856,7 +856,7 @@ def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> C
full_version = err.split('\n', 1)[0]
version = full_version.split()[-1]
cls = fortran.NAGFortranCompiler
- env.coredata.add_lang_args(cls.language, cls, for_machine, env)
+ env.add_lang_args(cls.language, cls, for_machine)
linker = linkers.NAGDynamicLinker(
compiler, for_machine, cls.LINKER_PREFIX, [],
version=version)
@@ -948,7 +948,7 @@ def detect_java_compiler(env: 'Environment', for_machine: MachineChoice) -> Comp
if len(parts) > 1:
version = parts[1]
comp_class = JavaCompiler
- env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
+ env.add_lang_args(comp_class.language, comp_class, for_machine)
return comp_class(exelist, version, for_machine, info)
raise EnvironmentException('Unknown compiler: ' + join_args(exelist))
@@ -972,7 +972,7 @@ def detect_cs_compiler(env: 'Environment', for_machine: MachineChoice) -> Compil
cls = cs.VisualStudioCsCompiler
else:
continue
- env.coredata.add_lang_args(cls.language, cls, for_machine, env)
+ env.add_lang_args(cls.language, cls, for_machine)
return cls(comp, version, for_machine, info)
_handle_exceptions(popen_exceptions, compilers)
@@ -1002,7 +1002,7 @@ def detect_cython_compiler(env: 'Environment', for_machine: MachineChoice) -> Co
version = search_version(err)
if version is not None:
comp_class = CythonCompiler
- env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
+ env.add_lang_args(comp_class.language, comp_class, for_machine)
return comp_class([], comp, version, for_machine, info, is_cross=is_cross)
_handle_exceptions(popen_exceptions, compilers)
raise EnvironmentException('Unreachable code (exception to make mypy happy)')
@@ -1023,7 +1023,7 @@ def detect_vala_compiler(env: 'Environment', for_machine: MachineChoice) -> Comp
version = search_version(out)
if 'Vala' in out:
comp_class = ValaCompiler
- env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
+ env.add_lang_args(comp_class.language, comp_class, for_machine)
return comp_class(exelist, version, for_machine, is_cross, info)
raise EnvironmentException('Unknown compiler: ' + join_args(exelist))
@@ -1145,7 +1145,7 @@ def detect_rust_compiler(env: 'Environment', for_machine: MachineChoice) -> Rust
c = linker.exelist[1] if linker.exelist[0].endswith('ccache') else linker.exelist[0]
compiler.extend(cls.use_linker_args(c, ''))
- env.coredata.add_lang_args(cls.language, cls, for_machine, env)
+ env.add_lang_args(cls.language, cls, for_machine)
return cls(
compiler, version, for_machine, is_cross, info,
linker=linker, full_version=full_version)
@@ -1329,20 +1329,20 @@ def detect_nasm_compiler(env: 'Environment', for_machine: MachineChoice) -> Comp
version = search_version(output)
if 'NASM' in output:
comp_class = NasmCompiler
- env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
+ env.add_lang_args(comp_class.language, comp_class, for_machine)
return comp_class([], comp, version, for_machine, info, cc.linker, is_cross=is_cross)
elif 'yasm' in output:
comp_class = YasmCompiler
- env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
+ env.add_lang_args(comp_class.language, comp_class, for_machine)
return comp_class([], comp, version, for_machine, info, cc.linker, is_cross=is_cross)
elif 'Metrowerks' in output or 'Freescale' in output:
if 'ARM' in output:
comp_class_mwasmarm = MetrowerksAsmCompilerARM
- env.coredata.add_lang_args(comp_class_mwasmarm.language, comp_class_mwasmarm, for_machine, env)
+ env.add_lang_args(comp_class_mwasmarm.language, comp_class_mwasmarm, for_machine)
return comp_class_mwasmarm([], comp, version, for_machine, info, cc.linker, is_cross=is_cross)
else:
comp_class_mwasmeppc = MetrowerksAsmCompilerEmbeddedPowerPC
- env.coredata.add_lang_args(comp_class_mwasmeppc.language, comp_class_mwasmeppc, for_machine, env)
+ env.add_lang_args(comp_class_mwasmeppc.language, comp_class_mwasmeppc, for_machine)
return comp_class_mwasmeppc([], comp, version, for_machine, info, cc.linker, is_cross=is_cross)
_handle_exceptions(popen_exceptions, compilers)
@@ -1383,7 +1383,7 @@ def detect_masm_compiler(env: 'Environment', for_machine: MachineChoice) -> Comp
try:
output = Popen_safe(comp + [arg])[2]
version = search_version(output)
- env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
+ env.add_lang_args(comp_class.language, comp_class, for_machine)
return comp_class([], comp, version, for_machine, info, cc.linker, is_cross=is_cross)
except OSError as e:
popen_exceptions[' '.join(comp + [arg])] = e
@@ -1403,7 +1403,7 @@ def detect_linearasm_compiler(env: Environment, for_machine: MachineChoice) -> C
try:
output = Popen_safe(comp + [arg])[2]
version = search_version(output)
- env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
+ env.add_lang_args(comp_class.language, comp_class, for_machine)
return comp_class([], comp, version, for_machine, info, cc.linker, is_cross=is_cross)
except OSError as e:
popen_exceptions[' '.join(comp + [arg])] = e
diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py
index 5794db0..6f4f3d2 100644
--- a/mesonbuild/compilers/fortran.py
+++ b/mesonbuild/compilers/fortran.py
@@ -104,9 +104,9 @@ class FortranCompiler(CLikeCompiler, Compiler):
return filename
def find_library(self, libname: str, env: 'Environment', extra_dirs: T.List[str],
- libtype: LibType = LibType.PREFER_SHARED, lib_prefix_warning: bool = True) -> T.Optional[T.List[str]]:
+ libtype: LibType = LibType.PREFER_SHARED, lib_prefix_warning: bool = True, ignore_system_dirs: bool = False) -> T.Optional[T.List[str]]:
code = 'stop; end program'
- return self._find_library_impl(libname, env, extra_dirs, code, libtype, lib_prefix_warning)
+ return self._find_library_impl(libname, env, extra_dirs, code, libtype, lib_prefix_warning, ignore_system_dirs)
def has_multi_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]:
return self._has_multi_arguments(args, env, 'stop; end program')
@@ -446,6 +446,11 @@ class IntelLLVMFortranCompiler(IntelFortranCompiler):
id = 'intel-llvm'
+ def get_preprocess_only_args(self) -> T.List[str]:
+ return ['-preprocess-only']
+
+ def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]:
+ return []
class IntelClFortranCompiler(IntelVisualStudioLikeCompiler, FortranCompiler):
@@ -643,7 +648,11 @@ class LlvmFlangFortranCompiler(ClangCompiler, FortranCompiler):
# https://github.com/llvm/llvm-project/commit/8d5386669ed63548daf1bee415596582d6d78d7d;
# it seems flang 18 doesn't work if something accidentally includes a program unit, see
# https://github.com/llvm/llvm-project/issues/92496
- return search_dirs + ['-lFortranRuntime', '-lFortranDecimal']
+ # Only link FortranRuntime and FortranDecimal for flang < 19, see
+ # https://github.com/scipy/scipy/issues/21562#issuecomment-2942938509
+ if version_compare(self.version, '<19'):
+ search_dirs += ['-lFortranRuntime', '-lFortranDecimal']
+ return search_dirs
class Open64FortranCompiler(FortranCompiler):
diff --git a/mesonbuild/compilers/java.py b/mesonbuild/compilers/java.py
index 540e2aa..47d2ac9 100644
--- a/mesonbuild/compilers/java.py
+++ b/mesonbuild/compilers/java.py
@@ -91,10 +91,7 @@ class JavaCompiler(BasicLinkerIsCompilerMixin, Compiler):
runner = shutil.which(self.javarunner)
if runner:
cmdlist = [runner, '-cp', '.', obj]
- pe = subprocess.Popen(cmdlist, cwd=work_dir)
- pe.wait()
- if pe.returncode != 0:
- raise EnvironmentException(f'Executables created by Java compiler {self.name_string()} are not runnable.')
+ self.run_sanity_check(environment, cmdlist, work_dir, use_exe_wrapper_for_cross=False)
else:
m = "Java Virtual Machine wasn't found, but it's needed by Meson. " \
"Please install a JRE.\nIf you have specific needs where this " \
diff --git a/mesonbuild/compilers/mixins/clang.py b/mesonbuild/compilers/mixins/clang.py
index ae5ab63..72b987a 100644
--- a/mesonbuild/compilers/mixins/clang.py
+++ b/mesonbuild/compilers/mixins/clang.py
@@ -155,7 +155,10 @@ class ClangCompiler(GnuLikeCompiler):
# llvm based) is retargetable, while GCC is not.
#
- # qcld: Qualcomm Snapdragon linker, based on LLVM
+ # eld: Qualcomm's opensource embedded linker
+ if linker == 'eld':
+ return ['-fuse-ld=eld']
+ # qcld: Qualcomm's deprecated linker
if linker == 'qcld':
return ['-fuse-ld=qcld']
if linker == 'mold':
diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py
index b163407..d2eb611 100644
--- a/mesonbuild/compilers/mixins/clike.py
+++ b/mesonbuild/compilers/mixins/clike.py
@@ -128,7 +128,7 @@ class CLikeCompiler(Compiler):
warn_args: T.Dict[str, T.List[str]] = {}
# TODO: Replace this manual cache with functools.lru_cache
- find_library_cache: T.Dict[T.Tuple[T.Tuple[str, ...], str, T.Tuple[str, ...], str, LibType], T.Optional[T.List[str]]] = {}
+ find_library_cache: T.Dict[T.Tuple[T.Tuple[str, ...], str, T.Tuple[str, ...], str, LibType, bool], T.Optional[T.List[str]]] = {}
find_framework_cache: T.Dict[T.Tuple[T.Tuple[str, ...], str, T.Tuple[str, ...], bool], T.Optional[T.List[str]]] = {}
internal_libs = arglist.UNIXY_COMPILER_INTERNAL_LIBS
@@ -307,22 +307,7 @@ class CLikeCompiler(Compiler):
mlog.debug('-----')
if pc.returncode != 0:
raise mesonlib.EnvironmentException(f'Compiler {self.name_string()} cannot compile programs.')
- # Run sanity check
- if self.is_cross:
- if not environment.has_exe_wrapper():
- # Can't check if the binaries run so we have to assume they do
- return
- cmdlist = environment.exe_wrapper.get_command() + [binary_name]
- else:
- cmdlist = [binary_name]
- mlog.debug('Running test binary command: ', mesonlib.join_args(cmdlist))
- try:
- # fortran code writes to stdout
- pe = subprocess.run(cmdlist, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
- except Exception as e:
- raise mesonlib.EnvironmentException(f'Could not invoke sanity test executable: {e!s}.')
- if pe.returncode != 0:
- raise mesonlib.EnvironmentException(f'Executables created by {self.language} compiler {self.name_string()} are not runnable.')
+ self.run_sanity_check(environment, [binary_name], work_dir)
def sanity_check(self, work_dir: str, environment: 'Environment') -> None:
code = 'int main(void) { int class=0; return class; }\n'
@@ -1128,7 +1113,7 @@ class CLikeCompiler(Compiler):
'''
return self.sizeof('void *', '', env)[0] == 8
- def _find_library_real(self, libname: str, env: 'Environment', extra_dirs: T.List[str], code: str, libtype: LibType, lib_prefix_warning: bool) -> T.Optional[T.List[str]]:
+ def _find_library_real(self, libname: str, env: 'Environment', extra_dirs: T.List[str], code: str, libtype: LibType, lib_prefix_warning: bool, ignore_system_dirs: bool) -> T.Optional[T.List[str]]:
# First try if we can just add the library as -l.
# Gcc + co seem to prefer builtin lib dirs to -L dirs.
# Only try to find std libs if no extra dirs specified.
@@ -1159,7 +1144,7 @@ class CLikeCompiler(Compiler):
except (mesonlib.MesonException, KeyError): # TODO evaluate if catching KeyError is wanted here
elf_class = 0
# Search in the specified dirs, and then in the system libraries
- for d in itertools.chain(extra_dirs, self.get_library_dirs(env, elf_class)):
+ for d in itertools.chain(extra_dirs, [] if ignore_system_dirs else self.get_library_dirs(env, elf_class)):
for p in patterns:
trials = self._get_trials_from_pattern(p, d, libname)
if not trials:
@@ -1173,15 +1158,15 @@ class CLikeCompiler(Compiler):
return None
def _find_library_impl(self, libname: str, env: 'Environment', extra_dirs: T.List[str],
- code: str, libtype: LibType, lib_prefix_warning: bool) -> T.Optional[T.List[str]]:
+ code: str, libtype: LibType, lib_prefix_warning: bool, ignore_system_dirs: bool) -> T.Optional[T.List[str]]:
# These libraries are either built-in or invalid
if libname in self.ignore_libs:
return []
if isinstance(extra_dirs, str):
extra_dirs = [extra_dirs]
- key = (tuple(self.exelist), libname, tuple(extra_dirs), code, libtype)
+ key = (tuple(self.exelist), libname, tuple(extra_dirs), code, libtype, ignore_system_dirs)
if key not in self.find_library_cache:
- value = self._find_library_real(libname, env, extra_dirs, code, libtype, lib_prefix_warning)
+ value = self._find_library_real(libname, env, extra_dirs, code, libtype, lib_prefix_warning, ignore_system_dirs)
self.find_library_cache[key] = value
else:
value = self.find_library_cache[key]
@@ -1190,9 +1175,9 @@ class CLikeCompiler(Compiler):
return value.copy()
def find_library(self, libname: str, env: 'Environment', extra_dirs: T.List[str],
- libtype: LibType = LibType.PREFER_SHARED, lib_prefix_warning: bool = True) -> T.Optional[T.List[str]]:
+ libtype: LibType = LibType.PREFER_SHARED, lib_prefix_warning: bool = True, ignore_system_dirs: bool = False) -> T.Optional[T.List[str]]:
code = 'int main(void) { return 0; }\n'
- return self._find_library_impl(libname, env, extra_dirs, code, libtype, lib_prefix_warning)
+ return self._find_library_impl(libname, env, extra_dirs, code, libtype, lib_prefix_warning, ignore_system_dirs)
def find_framework_paths(self, env: 'Environment') -> T.List[str]:
'''
@@ -1287,12 +1272,19 @@ class CLikeCompiler(Compiler):
# check the equivalent enable flag too "-Wforgotten-towel".
if arg.startswith('-Wno-'):
# Make an exception for -Wno-attributes=x as -Wattributes=x is invalid
- # for GCC at least. Also, the opposite of -Wno-vla-larger-than is
- # -Wvla-larger-than=N
+ # for GCC at least. Also, the positive form of some flags require a
+ # value to be specified, i.e. we need to pass -Wfoo=N rather than just
+ # -Wfoo.
if arg.startswith('-Wno-attributes='):
pass
- elif arg == '-Wno-vla-larger-than':
- new_args.append('-Wvla-larger-than=1000')
+ elif arg in {'-Wno-alloc-size-larger-than',
+ '-Wno-alloca-larger-than',
+ '-Wno-frame-larger-than',
+ '-Wno-stack-usage',
+ '-Wno-vla-larger-than'}:
+ # Pass an arbitrary value to the enabling flag; since the test program
+ # is trivial, it is unlikely to provoke any of these warnings.
+ new_args.append('-W' + arg[5:] + '=1000')
else:
new_args.append('-W' + arg[5:])
if arg.startswith('-Wl,'):
diff --git a/mesonbuild/compilers/mixins/emscripten.py b/mesonbuild/compilers/mixins/emscripten.py
index 91b25e8..83534e1 100644
--- a/mesonbuild/compilers/mixins/emscripten.py
+++ b/mesonbuild/compilers/mixins/emscripten.py
@@ -76,7 +76,7 @@ class EmscriptenMixin(Compiler):
return wrap_js_includes(super().get_dependency_link_args(dep))
def find_library(self, libname: str, env: 'Environment', extra_dirs: T.List[str],
- libtype: LibType = LibType.PREFER_SHARED, lib_prefix_warning: bool = True) -> T.Optional[T.List[str]]:
+ libtype: LibType = LibType.PREFER_SHARED, lib_prefix_warning: bool = True, ignore_system_dirs: bool = False) -> T.Optional[T.List[str]]:
if not libname.endswith('.js'):
return super().find_library(libname, env, extra_dirs, libtype, lib_prefix_warning)
if os.path.isabs(libname):
diff --git a/mesonbuild/compilers/mixins/gnu.py b/mesonbuild/compilers/mixins/gnu.py
index 9ea591e..ddcd14a 100644
--- a/mesonbuild/compilers/mixins/gnu.py
+++ b/mesonbuild/compilers/mixins/gnu.py
@@ -534,6 +534,8 @@ class GnuLikeCompiler(Compiler, metaclass=abc.ABCMeta):
# We want to allow preprocessing files with any extension, such as
# foo.c.in. In that case we need to tell GCC/CLANG to treat them as
# assembly file.
+ if self.language == 'fortran':
+ return self.get_preprocess_only_args()
lang = gnu_lang_map.get(self.language, 'assembler-with-cpp')
return self.get_preprocess_only_args() + [f'-x{lang}']
diff --git a/mesonbuild/compilers/mixins/islinker.py b/mesonbuild/compilers/mixins/islinker.py
index 3f35619..e359fb3 100644
--- a/mesonbuild/compilers/mixins/islinker.py
+++ b/mesonbuild/compilers/mixins/islinker.py
@@ -101,9 +101,8 @@ class BasicLinkerIsCompilerMixin(Compiler):
darwin_versions: T.Tuple[str, str]) -> T.List[str]:
raise MesonException("This linker doesn't support soname args")
- def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
- rpath_paths: T.Tuple[str, ...], build_rpath: str,
- install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]:
+ def build_rpath_args(self, env: Environment, build_dir: str, from_dir: str,
+ target: BuildTarget, extra_paths: T.Optional[T.List[str]] = None) -> T.Tuple[T.List[str], T.Set[bytes]]:
return ([], set())
def get_asneeded_args(self) -> T.List[str]:
diff --git a/mesonbuild/compilers/mixins/pgi.py b/mesonbuild/compilers/mixins/pgi.py
index 50335c8..fddc837 100644
--- a/mesonbuild/compilers/mixins/pgi.py
+++ b/mesonbuild/compilers/mixins/pgi.py
@@ -54,6 +54,12 @@ class PGICompiler(Compiler):
def openmp_flags(self, env: Environment) -> T.List[str]:
return ['-mp']
+ def get_preprocess_only_args(self) -> T.List[str]:
+ return ['-E', '-P', '-o', '-']
+
+ def get_preprocess_to_file_args(self) -> T.List[str]:
+ return ['-E', '-P']
+
def get_optimization_args(self, optimization_level: str) -> T.List[str]:
return clike_optimization_args[optimization_level]
diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py
index d0d2e69..bc27779 100644
--- a/mesonbuild/compilers/rust.py
+++ b/mesonbuild/compilers/rust.py
@@ -5,7 +5,7 @@
from __future__ import annotations
import functools
-import subprocess, os.path
+import os.path
import textwrap
import re
import typing as T
@@ -141,17 +141,7 @@ class RustCompiler(Compiler):
if pc.returncode != 0:
raise EnvironmentException(f'Rust compiler {self.name_string()} cannot compile programs.')
self._native_static_libs(work_dir, source_name)
- if self.is_cross:
- if not environment.has_exe_wrapper():
- # Can't check if the binaries run so we have to assume they do
- return
- cmdlist = environment.exe_wrapper.get_command() + [output_name]
- else:
- cmdlist = [output_name]
- pe = subprocess.Popen(cmdlist, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
- pe.wait()
- if pe.returncode != 0:
- raise EnvironmentException(f'Executables created by Rust compiler {self.name_string()} are not runnable.')
+ self.run_sanity_check(environment, [output_name], work_dir)
def _native_static_libs(self, work_dir: str, source_name: str) -> None:
# Get libraries needed to link with a Rust staticlib
@@ -192,10 +182,14 @@ class RustCompiler(Compiler):
return stdo.split('\n', maxsplit=1)[0]
@functools.lru_cache(maxsize=None)
- def get_crt_static(self) -> bool:
+ def get_cfgs(self) -> T.List[str]:
cmd = self.get_exelist(ccache=False) + ['--print', 'cfg']
p, stdo, stde = Popen_safe_logged(cmd)
- return bool(re.search('^target_feature="crt-static"$', stdo, re.MULTILINE))
+ return stdo.splitlines()
+
+ @functools.lru_cache(maxsize=None)
+ def get_crt_static(self) -> bool:
+ return 'target_feature="crt-static"' in self.get_cfgs()
def get_debug_args(self, is_debug: bool) -> T.List[str]:
return clike_debug_args[is_debug]
@@ -203,18 +197,15 @@ class RustCompiler(Compiler):
def get_optimization_args(self, optimization_level: str) -> T.List[str]:
return rust_optimization_args[optimization_level]
- def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
- rpath_paths: T.Tuple[str, ...], build_rpath: str,
- install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]:
- args, to_remove = super().build_rpath_args(env, build_dir, from_dir, rpath_paths,
- build_rpath, install_rpath)
+ def build_rpath_args(self, env: Environment, build_dir: str, from_dir: str,
+ target: BuildTarget, extra_paths: T.Optional[T.List[str]] = None) -> T.Tuple[T.List[str], T.Set[bytes]]:
+ # add rustc's sysroot to account for rustup installations
+ args, to_remove = super().build_rpath_args(env, build_dir, from_dir, target, [self.get_target_libdir()])
- # ... but then add rustc's sysroot to account for rustup
- # installations
rustc_rpath_args = []
for arg in args:
rustc_rpath_args.append('-C')
- rustc_rpath_args.append(f'link-arg={arg}:{self.get_target_libdir()}')
+ rustc_rpath_args.append(f'link-arg={arg}')
return rustc_rpath_args, to_remove
def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str],
@@ -247,6 +238,12 @@ class RustCompiler(Compiler):
'none',
choices=['none', '2015', '2018', '2021', '2024'])
+ key = self.form_compileropt_key('dynamic_std')
+ opts[key] = options.UserBooleanOption(
+ self.make_option_name(key),
+ 'Whether to link Rust build targets to a dynamic libstd',
+ False)
+
return opts
def get_dependency_compile_args(self, dep: 'Dependency') -> T.List[str]:
@@ -327,11 +324,11 @@ class RustCompiler(Compiler):
return exelist + args
def has_multi_arguments(self, args: T.List[str], env: Environment) -> T.Tuple[bool, bool]:
- return self.compiles('fn main { std::process::exit(0) };\n', env, extra_args=args, mode=CompileCheckMode.COMPILE)
+ return self.compiles('fn main() { std::process::exit(0) }\n', env, extra_args=args, mode=CompileCheckMode.COMPILE)
def has_multi_link_arguments(self, args: T.List[str], env: Environment) -> T.Tuple[bool, bool]:
args = self.linker.fatal_warnings() + args
- return self.compiles('fn main { std::process::exit(0) };\n', env, extra_args=args, mode=CompileCheckMode.LINK)
+ return self.compiles('fn main() { std::process::exit(0) }\n', env, extra_args=args, mode=CompileCheckMode.LINK)
@functools.lru_cache(maxsize=None)
def get_rustdoc(self, env: 'Environment') -> T.Optional[RustdocTestCompiler]:
@@ -341,7 +338,7 @@ class RustCompiler(Compiler):
return RustdocTestCompiler(exelist, self.version, self.for_machine,
self.is_cross, self.info, full_version=self.full_version,
- linker=self.linker)
+ linker=self.linker, rustc=self)
class ClippyRustCompiler(RustCompiler):
@@ -361,6 +358,26 @@ class RustdocTestCompiler(RustCompiler):
id = 'rustdoc --test'
+ def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice,
+ is_cross: bool, info: 'MachineInfo',
+ full_version: T.Optional[str],
+ linker: T.Optional['DynamicLinker'], rustc: RustCompiler):
+ super().__init__(exelist, version, for_machine,
+ is_cross, info, full_version, linker)
+ self.rustc = rustc
+
+ @functools.lru_cache(maxsize=None)
+ def get_sysroot(self) -> str:
+ return self.rustc.get_sysroot()
+
+ @functools.lru_cache(maxsize=None)
+ def get_target_libdir(self) -> str:
+ return self.rustc.get_target_libdir()
+
+ @functools.lru_cache(maxsize=None)
+ def get_cfgs(self) -> T.List[str]:
+ return self.rustc.get_cfgs()
+
def get_debug_args(self, is_debug: bool) -> T.List[str]:
return []
diff --git a/mesonbuild/compilers/swift.py b/mesonbuild/compilers/swift.py
index 8410fbb..4ad3aff 100644
--- a/mesonbuild/compilers/swift.py
+++ b/mesonbuild/compilers/swift.py
@@ -8,7 +8,7 @@ import subprocess, os.path
import typing as T
from .. import mlog, options
-from ..mesonlib import EnvironmentException, MesonException, version_compare
+from ..mesonlib import first, MesonException, version_compare
from .compilers import Compiler, clike_debug_args
@@ -139,6 +139,16 @@ class SwiftCompiler(Compiler):
if std != 'none':
args += ['-swift-version', std]
+ # Pass C compiler -std=... arg to swiftc
+ c_langs = ['objc', 'c']
+ if target.uses_swift_cpp_interop():
+ c_langs = ['objcpp', 'cpp', *c_langs]
+
+ c_lang = first(c_langs, lambda x: x in target.compilers)
+ if c_lang is not None:
+ cc = target.compilers[c_lang]
+ args.extend(arg for c_arg in cc.get_option_std_args(target, env, subproject) for arg in ['-Xcc', c_arg])
+
return args
def get_working_directory_args(self, path: str) -> T.Optional[T.List[str]]:
@@ -147,6 +157,18 @@ class SwiftCompiler(Compiler):
return ['-working-directory', path]
+ def get_cxx_interoperability_args(self, target: T.Optional[build.BuildTarget] = None) -> T.List[str]:
+ if target is not None and not target.uses_swift_cpp_interop():
+ return []
+
+ if version_compare(self.version, '<5.9'):
+ raise MesonException(f'Compiler {self} does not support C++ interoperability')
+
+ return ['-cxx-interoperability-mode=default']
+
+ def get_library_args(self) -> T.List[str]:
+ return ['-parse-as-library']
+
def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str],
build_dir: str) -> T.List[str]:
for idx, i in enumerate(parameter_list):
@@ -170,13 +192,7 @@ class SwiftCompiler(Compiler):
''')
pc = subprocess.Popen(self.exelist + extra_flags + ['-emit-executable', '-o', output_name, src], cwd=work_dir)
pc.wait()
- if pc.returncode != 0:
- raise EnvironmentException('Swift compiler %s cannot compile programs.' % self.name_string())
- if self.is_cross:
- # Can't check if the binaries run so we have to assume they do
- return
- if subprocess.call(output_name) != 0:
- raise EnvironmentException('Executables created by Swift compiler %s are not runnable.' % self.name_string())
+ self.run_sanity_check(environment, [output_name], work_dir)
def get_debug_args(self, is_debug: bool) -> T.List[str]:
return clike_debug_args[is_debug]
diff --git a/mesonbuild/compilers/vala.py b/mesonbuild/compilers/vala.py
index 28861a6..bbaefed 100644
--- a/mesonbuild/compilers/vala.py
+++ b/mesonbuild/compilers/vala.py
@@ -113,7 +113,7 @@ class ValaCompiler(Compiler):
raise EnvironmentException(msg)
def find_library(self, libname: str, env: 'Environment', extra_dirs: T.List[str],
- libtype: LibType = LibType.PREFER_SHARED, lib_prefix_warning: bool = True) -> T.Optional[T.List[str]]:
+ libtype: LibType = LibType.PREFER_SHARED, lib_prefix_warning: bool = True, ignore_system_dirs: bool = False) -> T.Optional[T.List[str]]:
if extra_dirs and isinstance(extra_dirs, str):
extra_dirs = [extra_dirs]
# Valac always looks in the default vapi dir, so only search there if