aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/compilers
diff options
context:
space:
mode:
authorFini Jastrow <ulf.fini.jastrow@desy.de>2022-03-08 18:41:08 +0100
committerXavier Claessens <xclaesse@gmail.com>2022-04-30 10:06:22 -0400
commitc16fdaeecafe94461d6048b90bd337a04c25ad3c (patch)
tree7ebffc621f5ad4d75459dff1d5b5f05cc6481993 /mesonbuild/compilers
parent93ed7531c4a1e08defc5ea3b37427e59f67582db (diff)
downloadmeson-c16fdaeecafe94461d6048b90bd337a04c25ad3c.zip
meson-c16fdaeecafe94461d6048b90bd337a04c25ad3c.tar.gz
meson-c16fdaeecafe94461d6048b90bd337a04c25ad3c.tar.bz2
linkers: Add support for mold linker
[why] Support for the relatively new mold linker is missing. If someone wants to use mold as linker `LDFLAGS="-B/path/to/mold"` has to be added instead of the usual `CC_LD=mold meson ...` or `CXX_LD=mold meson ...`. [how] Allow `mold' as linker for clang and newer GCC versions (that versions that have support). The error message can be a bit off, because it is generic for all GNU like compilers, but I guess that is ok. (i.e. 'mold' is not listed as possible linker, even if it would be possible for the given compiler.) [note] GCC Version 12.0.1 is not sufficient to say `mold` is supported. The expected release with support will be 12.1.0. On the other hand people that use the un-released 12.0.1 will probably have built it from trunk. Allowing 12.0.1 is helping bleeding edge developers to use mold in Meson already now. Fixes: #9072 Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
Diffstat (limited to 'mesonbuild/compilers')
-rw-r--r--mesonbuild/compilers/compilers.py4
-rw-r--r--mesonbuild/compilers/d.py4
-rw-r--r--mesonbuild/compilers/detect.py60
-rw-r--r--mesonbuild/compilers/mixins/clang.py8
-rw-r--r--mesonbuild/compilers/mixins/clike.py4
-rw-r--r--mesonbuild/compilers/mixins/gnu.py10
-rw-r--r--mesonbuild/compilers/rust.py4
7 files changed, 51 insertions, 43 deletions
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index 17c9f36..34f9a09 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -1,4 +1,4 @@
-# Copyright 2012-2019 The Meson development team
+# Copyright 2012-2022 The Meson development team
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -1007,7 +1007,7 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
return dep.get_link_args()
@classmethod
- def use_linker_args(cls, linker: str) -> T.List[str]:
+ def use_linker_args(cls, linker: str, version: str) -> T.List[str]:
"""Get a list of arguments to pass to the compiler to set the linker.
"""
return []
diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py
index 4e24e4e..ec0b155 100644
--- a/mesonbuild/compilers/d.py
+++ b/mesonbuild/compilers/d.py
@@ -1,4 +1,4 @@
-# Copyright 2012-2017 The Meson development team
+# Copyright 2012-2022 The Meson development team
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -806,7 +806,7 @@ class LLVMDCompiler(DmdLikeCompilerMixin, DCompiler):
return ldc_optimization_args[optimization_level]
@classmethod
- def use_linker_args(cls, linker: str) -> T.List[str]:
+ def use_linker_args(cls, linker: str, version: str) -> T.List[str]:
return [f'-linker={linker}']
def get_linker_always_args(self) -> T.List[str]:
diff --git a/mesonbuild/compilers/detect.py b/mesonbuild/compilers/detect.py
index 53948b0..74f2f17 100644
--- a/mesonbuild/compilers/detect.py
+++ b/mesonbuild/compilers/detect.py
@@ -1,4 +1,4 @@
-# Copyright 2012-2021 The Meson development team
+# Copyright 2012-2022 The Meson development team
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -448,7 +448,7 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
version = _get_gnu_version_from_defines(defines)
cls = GnuCCompiler if lang == 'c' else GnuCPPCompiler
- linker = guess_nix_linker(env, compiler, cls, for_machine)
+ linker = guess_nix_linker(env, compiler, cls, version, for_machine)
return cls(
ccache + compiler, version, for_machine, is_cross,
@@ -484,7 +484,7 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
cls = ArmLtdClangCCompiler
elif lang == 'cpp':
cls = ArmLtdClangCPPCompiler
- linker = guess_nix_linker(env, compiler, cls, for_machine)
+ linker = guess_nix_linker(env, compiler, cls, version, for_machine)
return cls(
ccache + compiler, version, for_machine, is_cross, info,
exe_wrap, linker=linker)
@@ -523,7 +523,7 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
else:
target = 'unknown target'
cls = ClangClCCompiler if lang == 'c' else ClangClCPPCompiler
- linker = guess_win_linker(env, ['lld-link'], cls, for_machine)
+ linker = guess_win_linker(env, ['lld-link'], cls, version, for_machine)
return cls(
compiler, version, for_machine, is_cross, info, target,
exe_wrap, linker=linker)
@@ -544,11 +544,11 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
# style ld, but for clang on "real" windows we'll use
# either link.exe or lld-link.exe
try:
- linker = guess_win_linker(env, compiler, cls, for_machine, invoked_directly=False)
+ linker = guess_win_linker(env, compiler, cls, version, for_machine, invoked_directly=False)
except MesonException:
pass
if linker is None:
- linker = guess_nix_linker(env, compiler, cls, for_machine)
+ linker = guess_nix_linker(env, compiler, cls, version, for_machine)
return cls(
ccache + compiler, version, for_machine, is_cross, info,
@@ -582,7 +582,7 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
m = f'Failed to detect MSVC compiler target architecture: \'cl /?\' output is\n{cl_signature}'
raise EnvironmentException(m)
cls = VisualStudioCCompiler if lang == 'c' else VisualStudioCPPCompiler
- linker = guess_win_linker(env, ['link'], cls, for_machine)
+ linker = guess_win_linker(env, ['link'], cls, version, for_machine)
# As of this writing, CCache does not support MSVC but sccache does.
if 'sccache' in ccache:
final_compiler = ccache + compiler
@@ -607,7 +607,7 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
info, exe_wrap, linker=linker)
if '(ICC)' in out:
cls = IntelCCompiler if lang == 'c' else IntelCPPCompiler
- l = guess_nix_linker(env, compiler, cls, for_machine)
+ l = guess_nix_linker(env, compiler, cls, version, for_machine)
return cls(
ccache + compiler, version, for_machine, is_cross, info,
exe_wrap, full_version=full_version, linker=l)
@@ -731,14 +731,14 @@ def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> C
if guess_gcc_or_lcc == 'lcc':
version = _get_lcc_version_from_defines(defines)
cls = ElbrusFortranCompiler
- linker = guess_nix_linker(env, compiler, cls, for_machine)
+ linker = guess_nix_linker(env, compiler, cls, version, for_machine)
return cls(
compiler, version, for_machine, is_cross, info,
exe_wrap, defines, full_version=full_version, linker=linker)
else:
version = _get_gnu_version_from_defines(defines)
cls = GnuFortranCompiler
- linker = guess_nix_linker(env, compiler, cls, for_machine)
+ linker = guess_nix_linker(env, compiler, cls, version, for_machine)
return cls(
compiler, version, for_machine, is_cross, info,
exe_wrap, defines, full_version=full_version, linker=linker)
@@ -750,13 +750,13 @@ def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> C
arm_ver_minor = arm_ver_match.group(2)
arm_ver_build = arm_ver_match.group(3)
version = '.'.join([arm_ver_major, arm_ver_minor, arm_ver_build])
- linker = guess_nix_linker(env, compiler, cls, for_machine)
+ linker = guess_nix_linker(env, compiler, cls, version, for_machine)
return cls(
ccache + compiler, version, for_machine, is_cross, info,
exe_wrap, linker=linker)
if 'G95' in out:
cls = G95FortranCompiler
- linker = guess_nix_linker(env, compiler, cls, for_machine)
+ linker = guess_nix_linker(env, compiler, cls, version, for_machine)
return G95FortranCompiler(
compiler, version, for_machine, is_cross, info,
exe_wrap, full_version=full_version, linker=linker)
@@ -764,7 +764,7 @@ def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> C
if 'Sun Fortran' in err:
version = search_version(err)
cls = SunFortranCompiler
- linker = guess_nix_linker(env, compiler, cls, for_machine)
+ linker = guess_nix_linker(env, compiler, cls, version, for_machine)
return SunFortranCompiler(
compiler, version, for_machine, is_cross, info,
exe_wrap, full_version=full_version, linker=linker)
@@ -780,7 +780,7 @@ def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> C
target, exe_wrap, linker=linker)
if 'ifort (IFORT)' in out:
- linker = guess_nix_linker(env, compiler, IntelFortranCompiler, for_machine)
+ linker = guess_nix_linker(env, compiler, IntelFortranCompiler, version, for_machine)
return IntelFortranCompiler(
compiler, version, for_machine, is_cross, info,
exe_wrap, full_version=full_version, linker=linker)
@@ -810,14 +810,14 @@ def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> C
if 'flang' in out or 'clang' in out:
linker = guess_nix_linker(env,
- compiler, FlangFortranCompiler, for_machine)
+ compiler, FlangFortranCompiler, version, for_machine)
return FlangFortranCompiler(
compiler, version, for_machine, is_cross, info,
exe_wrap, full_version=full_version, linker=linker)
if 'Open64 Compiler Suite' in err:
linker = guess_nix_linker(env,
- compiler, Open64FortranCompiler, for_machine)
+ compiler, Open64FortranCompiler, version, for_machine)
return Open64FortranCompiler(
compiler, version, for_machine, is_cross, info,
exe_wrap, full_version=full_version, linker=linker)
@@ -865,7 +865,7 @@ def _detect_objc_or_objcpp_compiler(env: 'Environment', for_machine: MachineChoi
continue
version = _get_gnu_version_from_defines(defines)
comp = GnuObjCCompiler if objc else GnuObjCPPCompiler
- linker = guess_nix_linker(env, compiler, comp, for_machine)
+ linker = guess_nix_linker(env, compiler, comp, version, for_machine)
return comp(
ccache + compiler, version, for_machine, is_cross, info,
exe_wrap, defines, linker=linker)
@@ -882,12 +882,12 @@ def _detect_objc_or_objcpp_compiler(env: 'Environment', for_machine: MachineChoi
if 'windows' in out or env.machines[for_machine].is_windows():
# If we're in a MINGW context this actually will use a gnu style ld
try:
- linker = guess_win_linker(env, compiler, comp, for_machine)
+ linker = guess_win_linker(env, compiler, comp, version, for_machine)
except MesonException:
pass
if not linker:
- linker = guess_nix_linker(env, compiler, comp, for_machine)
+ linker = guess_nix_linker(env, compiler, comp, version, for_machine)
return comp(
ccache + compiler, version, for_machine,
is_cross, info, exe_wrap, linker=linker, defines=defines)
@@ -1032,7 +1032,7 @@ def detect_rust_compiler(env: 'Environment', for_machine: MachineChoice) -> Rust
extra_args: T.Dict[str, T.Union[str, bool]] = {}
always_args: T.List[str] = []
if is_link_exe:
- compiler.extend(cls.use_linker_args(cc.linker.exelist[0]))
+ compiler.extend(cls.use_linker_args(cc.linker.exelist[0], ''))
extra_args['direct'] = True
extra_args['machine'] = cc.linker.machine
else:
@@ -1040,7 +1040,7 @@ def detect_rust_compiler(env: 'Environment', for_machine: MachineChoice) -> Rust
if 'ccache' in exelist[0]:
del exelist[0]
c = exelist.pop(0)
- compiler.extend(cls.use_linker_args(c))
+ compiler.extend(cls.use_linker_args(c, ''))
# Also ensure that we pass any extra arguments to the linker
for l in exelist:
@@ -1059,12 +1059,12 @@ def detect_rust_compiler(env: 'Environment', for_machine: MachineChoice) -> Rust
**extra_args)
elif 'link' in override[0]:
linker = guess_win_linker(env,
- override, cls, for_machine, use_linker_prefix=False)
+ override, cls, version, for_machine, use_linker_prefix=False)
# rustc takes linker arguments without a prefix, and
# inserts the correct prefix itself.
assert isinstance(linker, VisualStudioLikeLinkerMixin)
linker.direct = True
- compiler.extend(cls.use_linker_args(linker.exelist[0]))
+ compiler.extend(cls.use_linker_args(linker.exelist[0], ''))
else:
# On linux and macos rust will invoke the c compiler for
# linking, on windows it will use lld-link or link.exe.
@@ -1076,7 +1076,7 @@ def detect_rust_compiler(env: 'Environment', for_machine: MachineChoice) -> Rust
# Of course, we're not going to use any of that, we just
# need it to get the proper arguments to pass to rustc
c = linker.exelist[1] if linker.exelist[0].endswith('ccache') else linker.exelist[0]
- compiler.extend(cls.use_linker_args(c))
+ compiler.extend(cls.use_linker_args(c, ''))
env.coredata.add_lang_args(cls.language, cls, for_machine, env)
return cls(
@@ -1135,7 +1135,7 @@ def detect_d_compiler(env: 'Environment', for_machine: MachineChoice) -> Compile
objfile = os.path.basename(f)[:-1] + 'obj'
linker = guess_win_linker(env,
exelist,
- LLVMDCompiler, for_machine,
+ LLVMDCompiler, full_version, for_machine,
use_linker_prefix=True, invoked_directly=False,
extra_args=[f])
else:
@@ -1143,7 +1143,7 @@ def detect_d_compiler(env: 'Environment', for_machine: MachineChoice) -> Compile
# Clean it up.
objfile = os.path.basename(f)[:-1] + 'o'
linker = guess_nix_linker(env,
- exelist, LLVMDCompiler, for_machine,
+ exelist, LLVMDCompiler, full_version, for_machine,
extra_args=[f])
finally:
windows_proof_rm(f)
@@ -1153,7 +1153,7 @@ def detect_d_compiler(env: 'Environment', for_machine: MachineChoice) -> Compile
exelist, version, for_machine, info, arch,
full_version=full_version, linker=linker, version_output=out)
elif 'gdc' in out:
- linker = guess_nix_linker(env, exelist, GnuDCompiler, for_machine)
+ linker = guess_nix_linker(env, exelist, GnuDCompiler, version, for_machine)
return GnuDCompiler(
exelist, version, for_machine, info, arch,
exe_wrapper=exe_wrap, is_cross=is_cross,
@@ -1173,12 +1173,12 @@ def detect_d_compiler(env: 'Environment', for_machine: MachineChoice) -> Compile
if info.is_windows() or info.is_cygwin():
objfile = os.path.basename(f)[:-1] + 'obj'
linker = guess_win_linker(env,
- exelist, DmdDCompiler, for_machine,
+ exelist, DmdDCompiler, full_version, for_machine,
invoked_directly=False, extra_args=[f, arch_arg])
else:
objfile = os.path.basename(f)[:-1] + 'o'
linker = guess_nix_linker(env,
- exelist, DmdDCompiler, for_machine,
+ exelist, DmdDCompiler, full_version, for_machine,
extra_args=[f, arch_arg])
finally:
windows_proof_rm(f)
@@ -1209,7 +1209,7 @@ def detect_swift_compiler(env: 'Environment', for_machine: MachineChoice) -> Com
# As for 5.0.1 swiftc *requires* a file to check the linker:
with tempfile.NamedTemporaryFile(suffix='.swift') as f:
linker = guess_nix_linker(env,
- exelist, SwiftCompiler, for_machine,
+ exelist, SwiftCompiler, version, for_machine,
extra_args=[f.name])
return SwiftCompiler(
exelist, version, for_machine, is_cross, info, linker=linker)
diff --git a/mesonbuild/compilers/mixins/clang.py b/mesonbuild/compilers/mixins/clang.py
index a823b1c..5083ace 100644
--- a/mesonbuild/compilers/mixins/clang.py
+++ b/mesonbuild/compilers/mixins/clang.py
@@ -1,4 +1,4 @@
-# Copyright 2019 The meson development team
+# Copyright 2019-2022 The meson development team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -118,7 +118,7 @@ class ClangCompiler(GnuLikeCompiler):
return []
@classmethod
- def use_linker_args(cls, linker: str) -> T.List[str]:
+ def use_linker_args(cls, linker: str, version: str) -> T.List[str]:
# Clang additionally can use a linker specified as a path, which GCC
# (and other gcc-like compilers) cannot. This is because clang (being
# llvm based) is retargetable, while GCC is not.
@@ -127,13 +127,15 @@ class ClangCompiler(GnuLikeCompiler):
# qcld: Qualcomm Snapdragon linker, based on LLVM
if linker == 'qcld':
return ['-fuse-ld=qcld']
+ if linker == 'mold':
+ return ['-fuse-ld=mold']
if shutil.which(linker):
if not shutil.which(linker):
raise mesonlib.MesonException(
f'Cannot find linker {linker}.')
return [f'-fuse-ld={linker}']
- return super().use_linker_args(linker)
+ return super().use_linker_args(linker, version)
def get_has_func_attribute_extra_args(self, name: str) -> T.List[str]:
# Clang only warns about unknown or ignored attributes, so force an
diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py
index 162005f..4c2756e 100644
--- a/mesonbuild/compilers/mixins/clike.py
+++ b/mesonbuild/compilers/mixins/clike.py
@@ -1,4 +1,4 @@
-# Copyright 2012-2017 The Meson development team
+# Copyright 2012-2022 The Meson development team
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -410,7 +410,7 @@ class CLikeCompiler(Compiler):
if mode is CompileCheckMode.LINK:
ld_value = env.lookup_binary_entry(self.for_machine, self.language + '_ld')
if ld_value is not None:
- largs += self.use_linker_args(ld_value[0])
+ largs += self.use_linker_args(ld_value[0], self.version)
# Add LDFLAGS from the env
sys_ld_args = env.coredata.get_external_link_args(self.for_machine, self.language)
diff --git a/mesonbuild/compilers/mixins/gnu.py b/mesonbuild/compilers/mixins/gnu.py
index 91e07e5..2613038 100644
--- a/mesonbuild/compilers/mixins/gnu.py
+++ b/mesonbuild/compilers/mixins/gnu.py
@@ -1,4 +1,4 @@
-# Copyright 2019 The meson development team
+# Copyright 2019-2022 The meson development team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -306,7 +306,7 @@ class GnuLikeCompiler(Compiler, metaclass=abc.ABCMeta):
return ['-I' + path]
@classmethod
- def use_linker_args(cls, linker: str) -> T.List[str]:
+ def use_linker_args(cls, linker: str, version: str) -> T.List[str]:
if linker not in {'gold', 'bfd', 'lld'}:
raise mesonlib.MesonException(
f'Unsupported linker, only bfd, gold, and lld are supported, not {linker}.')
@@ -389,3 +389,9 @@ class GnuCompiler(GnuLikeCompiler):
elif threads > 0:
return [f'-flto={threads}']
return super().get_lto_compile_args(threads=threads)
+
+ @classmethod
+ def use_linker_args(cls, linker: str, version: str) -> T.List[str]:
+ if linker == 'mold' and mesonlib.version_compare(version, '>=12.0.1'):
+ return ['-fuse-ld=mold']
+ return super().use_linker_args(linker, version)
diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py
index a460b78..0967ada 100644
--- a/mesonbuild/compilers/rust.py
+++ b/mesonbuild/compilers/rust.py
@@ -1,4 +1,4 @@
-# Copyright 2012-2017 The Meson development team
+# Copyright 2012-2022 The Meson development team
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -136,7 +136,7 @@ class RustCompiler(Compiler):
return ['-o', outputname]
@classmethod
- def use_linker_args(cls, linker: str) -> T.List[str]:
+ def use_linker_args(cls, linker: str, version: str) -> T.List[str]:
return ['-C', f'linker={linker}']
# Rust does not have a use_linker_args because it dispatches to a gcc-like