aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/linkers
diff options
context:
space:
mode:
authorEli Schwartz <eschwartz@archlinux.org>2023-02-06 23:29:27 -0500
committerEli Schwartz <eschwartz@archlinux.org>2023-06-26 13:10:33 -0400
commita1ef957e349583f9affdce5b5a4f094860e91037 (patch)
tree01e0fd479c9b5c47b63b779bfb698e6c0785df4e /mesonbuild/linkers
parent6fad02db04534519e96f1ba66a178c6c9735554f (diff)
downloadmeson-a1ef957e349583f9affdce5b5a4f094860e91037.zip
meson-a1ef957e349583f9affdce5b5a4f094860e91037.tar.gz
meson-a1ef957e349583f9affdce5b5a4f094860e91037.tar.bz2
linkers: delay implementations import until detect is run
This saves on a 1500-line import at startup and may be skipped entirely if no compiled languages are used. In exchange, we move the implementation to a new file that is imported instead. Followup to commit ab20eb5bbc21ae855bcd211131132d2778602bcf.
Diffstat (limited to 'mesonbuild/linkers')
-rw-r--r--mesonbuild/linkers/__init__.py130
-rw-r--r--mesonbuild/linkers/base.py50
-rw-r--r--mesonbuild/linkers/detect.py46
-rw-r--r--mesonbuild/linkers/linkers.py36
4 files changed, 77 insertions, 185 deletions
diff --git a/mesonbuild/linkers/__init__.py b/mesonbuild/linkers/__init__.py
index b9df8d7..7c35694 100644
--- a/mesonbuild/linkers/__init__.py
+++ b/mesonbuild/linkers/__init__.py
@@ -12,139 +12,21 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+
+from .base import ArLikeLinker, RSPFileSyntax
from .detect import (
defaults,
guess_win_linker,
guess_nix_linker,
)
-from .linkers import (
- RSPFileSyntax,
-
- StaticLinker,
- VisualStudioLikeLinker,
- VisualStudioLinker,
- IntelVisualStudioLinker,
- AppleArLinker,
- ArLikeLinker,
- ArLinker,
- ArmarLinker,
- DLinker,
- CcrxLinker,
- Xc16Linker,
- CompCertLinker,
- C2000Linker,
- TILinker,
- AIXArLinker,
- PGIStaticLinker,
- NvidiaHPC_StaticLinker,
- MetrowerksStaticLinker,
- MetrowerksStaticLinkerARM,
- MetrowerksStaticLinkerEmbeddedPowerPC,
-
- DynamicLinker,
- PosixDynamicLinkerMixin,
- GnuLikeDynamicLinkerMixin,
- AppleDynamicLinker,
- GnuDynamicLinker,
- GnuGoldDynamicLinker,
- GnuBFDDynamicLinker,
- LLVMDynamicLinker,
- MoldDynamicLinker,
- WASMDynamicLinker,
- CcrxDynamicLinker,
- Xc16DynamicLinker,
- CompCertDynamicLinker,
- C2000DynamicLinker,
- TIDynamicLinker,
- ArmDynamicLinker,
- ArmClangDynamicLinker,
- QualcommLLVMDynamicLinker,
- PGIDynamicLinker,
- NvidiaHPC_DynamicLinker,
- NAGDynamicLinker,
- MetrowerksLinker,
- MetrowerksLinkerARM,
- MetrowerksLinkerEmbeddedPowerPC,
-
- VisualStudioLikeLinkerMixin,
- MSVCDynamicLinker,
- ClangClDynamicLinker,
- XilinkDynamicLinker,
- SolarisDynamicLinker,
- AIXDynamicLinker,
- OptlinkDynamicLinker,
- CudaLinker,
-
- prepare_rpaths,
- order_rpaths,
- evaluate_rpath,
-)
__all__ = [
+ # base.py
+ 'ArLikeLinker',
+ 'RSPFileSyntax',
+
# detect.py
'defaults',
'guess_win_linker',
'guess_nix_linker',
-
- # linkers.py
- 'RSPFileSyntax',
-
- 'StaticLinker',
- 'VisualStudioLikeLinker',
- 'VisualStudioLinker',
- 'IntelVisualStudioLinker',
- 'ArLikeLinker',
- 'ArLinker',
- 'ArmarLinker',
- 'DLinker',
- 'CcrxLinker',
- 'Xc16Linker',
- 'CompCertLinker',
- 'C2000Linker',
- 'TILinker',
- 'AIXArLinker',
- 'AppleArLinker',
- 'PGIStaticLinker',
- 'NvidiaHPC_StaticLinker',
- 'MetrowerksStaticLinker',
- 'MetrowerksStaticLinkerARM',
- 'MetrowerksStaticLinkerEmbeddedPowerPC',
-
- 'DynamicLinker',
- 'PosixDynamicLinkerMixin',
- 'GnuLikeDynamicLinkerMixin',
- 'AppleDynamicLinker',
- 'GnuDynamicLinker',
- 'GnuGoldDynamicLinker',
- 'GnuBFDDynamicLinker',
- 'LLVMDynamicLinker',
- 'MoldDynamicLinker',
- 'WASMDynamicLinker',
- 'CcrxDynamicLinker',
- 'Xc16DynamicLinker',
- 'CompCertDynamicLinker',
- 'C2000DynamicLinker',
- 'TIDynamicLinker',
- 'ArmDynamicLinker',
- 'ArmClangDynamicLinker',
- 'QualcommLLVMDynamicLinker',
- 'PGIDynamicLinker',
- 'NvidiaHPC_DynamicLinker',
- 'NAGDynamicLinker',
- 'MetrowerksLinker',
- 'MetrowerksLinkerARM',
- 'MetrowerksLinkerEmbeddedPowerPC',
-
- 'VisualStudioLikeLinkerMixin',
- 'MSVCDynamicLinker',
- 'ClangClDynamicLinker',
- 'XilinkDynamicLinker',
- 'SolarisDynamicLinker',
- 'AIXDynamicLinker',
- 'OptlinkDynamicLinker',
- 'CudaLinker',
-
- 'prepare_rpaths',
- 'order_rpaths',
- 'evaluate_rpath',
]
diff --git a/mesonbuild/linkers/base.py b/mesonbuild/linkers/base.py
new file mode 100644
index 0000000..a656bb4
--- /dev/null
+++ b/mesonbuild/linkers/base.py
@@ -0,0 +1,50 @@
+# Copyright 2012-2023 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.
+# You may obtain a copy of the License at
+
+# https://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Core public classes for linkers.
+from __future__ import annotations
+
+import enum
+import typing as T
+
+if T.TYPE_CHECKING:
+ from ..environment import Environment
+
+
+@enum.unique
+class RSPFileSyntax(enum.Enum):
+
+ """Which RSP file syntax the compiler supports."""
+
+ MSVC = enum.auto()
+ GCC = enum.auto()
+
+
+class ArLikeLinker:
+ # POSIX requires supporting the dash, GNU permits omitting it
+ std_args = ['-csr']
+
+ def can_linker_accept_rsp(self) -> bool:
+ # armar / AIX can't accept arguments using the @rsp syntax
+ # in fact, only the 'ar' id can
+ return False
+
+ def get_std_link_args(self, env: 'Environment', is_thin: bool) -> T.List[str]:
+ return self.std_args
+
+ def get_output_args(self, target: str) -> T.List[str]:
+ return [target]
+
+ def rsp_file_syntax(self) -> RSPFileSyntax:
+ return RSPFileSyntax.GCC
diff --git a/mesonbuild/linkers/detect.py b/mesonbuild/linkers/detect.py
index 3f8de05..60be10f 100644
--- a/mesonbuild/linkers/detect.py
+++ b/mesonbuild/linkers/detect.py
@@ -19,20 +19,6 @@ from ..mesonlib import (
EnvironmentException,
Popen_safe, Popen_safe_logged, join_args, search_version
)
-from .linkers import (
- AppleDynamicLinker,
- LLVMLD64DynamicLinker,
- GnuGoldDynamicLinker,
- GnuBFDDynamicLinker,
- MoldDynamicLinker,
- LLVMDynamicLinker,
- QualcommLLVMDynamicLinker,
- MSVCDynamicLinker,
- ClangClDynamicLinker,
- SolarisDynamicLinker,
- AIXDynamicLinker,
- OptlinkDynamicLinker,
-)
import re
import shlex
@@ -62,6 +48,7 @@ def guess_win_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty
comp_version: str, for_machine: MachineChoice, *,
use_linker_prefix: bool = True, invoked_directly: bool = True,
extra_args: T.Optional[T.List[str]] = None) -> 'DynamicLinker':
+ from . import linkers
env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
# Explicitly pass logo here so that we can get the version of link.exe
@@ -86,11 +73,11 @@ def guess_win_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty
p, o, _ = Popen_safe(compiler + check_args)
if 'LLD' in o.split('\n', maxsplit=1)[0]:
if '(compatible with GNU linkers)' in o:
- return LLVMDynamicLinker(
+ return linkers.LLVMDynamicLinker(
compiler, for_machine, comp_class.LINKER_PREFIX,
override, version=search_version(o))
elif not invoked_directly:
- return ClangClDynamicLinker(
+ return linkers.ClangClDynamicLinker(
for_machine, override, exelist=compiler, prefix=comp_class.LINKER_PREFIX,
version=search_version(o), direct=False, machine=None)
@@ -100,13 +87,13 @@ def guess_win_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty
p, o, e = Popen_safe(compiler + check_args)
if 'LLD' in o.split('\n', maxsplit=1)[0]:
- return ClangClDynamicLinker(
+ return linkers.ClangClDynamicLinker(
for_machine, [],
prefix=comp_class.LINKER_PREFIX if use_linker_prefix else [],
exelist=compiler, version=search_version(o), direct=invoked_directly)
elif 'OPTLINK' in o:
# Optlink's stdout *may* begin with a \r character.
- return OptlinkDynamicLinker(compiler, for_machine, version=search_version(o))
+ return linkers.OptlinkDynamicLinker(compiler, for_machine, version=search_version(o))
elif o.startswith('Microsoft') or e.startswith('Microsoft'):
out = o or e
match = re.search(r'.*(X86|X64|ARM|ARM64).*', out)
@@ -115,7 +102,7 @@ def guess_win_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty
else:
target = 'x86'
- return MSVCDynamicLinker(
+ return linkers.MSVCDynamicLinker(
for_machine, [], machine=target, exelist=compiler,
prefix=comp_class.LINKER_PREFIX if use_linker_prefix else [],
version=search_version(out), direct=invoked_directly)
@@ -139,6 +126,7 @@ def guess_nix_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty
:for_machine: which machine this linker targets
:extra_args: Any additional arguments required (such as a source file)
"""
+ from . import linkers
env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
extra_args = extra_args or []
@@ -170,14 +158,14 @@ def guess_nix_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty
lld_cls: T.Type[DynamicLinker]
if 'ld64.lld' in newerr:
- lld_cls = LLVMLD64DynamicLinker
+ lld_cls = linkers.LLVMLD64DynamicLinker
else:
- lld_cls = LLVMDynamicLinker
+ lld_cls = linkers.LLVMDynamicLinker
linker = lld_cls(
compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v)
elif 'Snapdragon' in e and 'LLVM' in e:
- linker = QualcommLLVMDynamicLinker(
+ linker = linkers.QualcommLLVMDynamicLinker(
compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v)
elif e.startswith('lld-link: '):
# The LLD MinGW frontend didn't respond to --version before version 9.0.0,
@@ -196,7 +184,7 @@ def guess_nix_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty
_, o, e = Popen_safe([linker_cmd, '--version'])
v = search_version(o)
- linker = LLVMDynamicLinker(compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v)
+ linker = linkers.LLVMDynamicLinker(compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v)
# first might be apple clang, second is for real gcc, the third is icc
elif e.endswith('(use -v to see invocation)\n') or 'macosx_version' in e or 'ld: unknown option:' in e:
if isinstance(comp_class.LINKER_PREFIX, str):
@@ -211,17 +199,17 @@ def guess_nix_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty
break
else:
__failed_to_detect_linker(compiler, check_args, o, e)
- linker = AppleDynamicLinker(compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v)
+ linker = linkers.AppleDynamicLinker(compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v)
elif 'GNU' in o or 'GNU' in e:
gnu_cls: T.Type[GnuDynamicLinker]
# this is always the only thing on stdout, except for swift
# which may or may not redirect the linker stdout to stderr
if o.startswith('GNU gold') or e.startswith('GNU gold'):
- gnu_cls = GnuGoldDynamicLinker
+ gnu_cls = linkers.GnuGoldDynamicLinker
elif o.startswith('mold') or e.startswith('mold'):
- gnu_cls = MoldDynamicLinker
+ gnu_cls = linkers.MoldDynamicLinker
else:
- gnu_cls = GnuBFDDynamicLinker
+ gnu_cls = linkers.GnuBFDDynamicLinker
linker = gnu_cls(compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v)
elif 'Solaris' in e or 'Solaris' in o:
for line in (o+e).split('\n'):
@@ -230,7 +218,7 @@ def guess_nix_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty
break
else:
v = 'unknown version'
- linker = SolarisDynamicLinker(
+ linker = linkers.SolarisDynamicLinker(
compiler, for_machine, comp_class.LINKER_PREFIX, override,
version=v)
elif 'ld: 0706-012 The -- flag is not recognized' in e:
@@ -238,7 +226,7 @@ def guess_nix_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty
_, _, e = Popen_safe(compiler + [comp_class.LINKER_PREFIX + '-V'] + extra_args)
else:
_, _, e = Popen_safe(compiler + comp_class.LINKER_PREFIX + ['-V'] + extra_args)
- linker = AIXDynamicLinker(
+ linker = linkers.AIXDynamicLinker(
compiler, for_machine, comp_class.LINKER_PREFIX, override,
version=search_version(e))
else:
diff --git a/mesonbuild/linkers/linkers.py b/mesonbuild/linkers/linkers.py
index 21e0eeb..d7868f2 100644
--- a/mesonbuild/linkers/linkers.py
+++ b/mesonbuild/linkers/linkers.py
@@ -14,10 +14,10 @@
from __future__ import annotations
import abc
-import enum
import os
import typing as T
+from .base import ArLikeLinker, RSPFileSyntax
from .. import mesonlib
from ..mesonlib import EnvironmentException, MesonException
from ..arglist import CompilerArgs
@@ -28,15 +28,6 @@ if T.TYPE_CHECKING:
from ..mesonlib import MachineChoice
-@enum.unique
-class RSPFileSyntax(enum.Enum):
-
- """Which RSP file syntax the compiler supports."""
-
- MSVC = enum.auto()
- GCC = enum.auto()
-
-
class StaticLinker:
id: str
@@ -168,26 +159,7 @@ class IntelVisualStudioLinker(VisualStudioLikeLinker, StaticLinker):
VisualStudioLikeLinker.__init__(self, machine)
-class ArLikeLinker(StaticLinker):
- # POSIX requires supporting the dash, GNU permits omitting it
- std_args = ['-csr']
-
- def can_linker_accept_rsp(self) -> bool:
- # armar / AIX can't accept arguments using the @rsp syntax
- # in fact, only the 'ar' id can
- return False
-
- def get_std_link_args(self, env: 'Environment', is_thin: bool) -> T.List[str]:
- return self.std_args
-
- def get_output_args(self, target: str) -> T.List[str]:
- return [target]
-
- def rsp_file_syntax(self) -> RSPFileSyntax:
- return RSPFileSyntax.GCC
-
-
-class ArLinker(ArLikeLinker):
+class ArLinker(ArLikeLinker, StaticLinker):
id = 'ar'
def __init__(self, for_machine: mesonlib.MachineChoice, exelist: T.List[str]):
@@ -227,7 +199,7 @@ class AppleArLinker(ArLinker):
id = 'applear'
-class ArmarLinker(ArLikeLinker):
+class ArmarLinker(ArLikeLinker, StaticLinker):
id = 'armar'
@@ -322,7 +294,7 @@ class C2000Linker(TILinker):
id = 'ar2000'
-class AIXArLinker(ArLikeLinker):
+class AIXArLinker(ArLikeLinker, StaticLinker):
id = 'aixar'
std_args = ['-csr', '-Xany']