diff options
author | Eli Schwartz <eschwartz@archlinux.org> | 2023-02-06 23:29:27 -0500 |
---|---|---|
committer | Eli Schwartz <eschwartz@archlinux.org> | 2023-06-26 13:10:33 -0400 |
commit | a1ef957e349583f9affdce5b5a4f094860e91037 (patch) | |
tree | 01e0fd479c9b5c47b63b779bfb698e6c0785df4e /mesonbuild/linkers | |
parent | 6fad02db04534519e96f1ba66a178c6c9735554f (diff) | |
download | meson-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__.py | 130 | ||||
-rw-r--r-- | mesonbuild/linkers/base.py | 50 | ||||
-rw-r--r-- | mesonbuild/linkers/detect.py | 46 | ||||
-rw-r--r-- | mesonbuild/linkers/linkers.py | 36 |
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'] |