From 37d1945beb4157a86064cc54e4946d263851f959 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 20 Dec 2024 00:35:24 +0100 Subject: [PATCH] rust: add start-group/end-group arguments for libraries Signed-off-by: Paolo Bonzini --- mesonbuild/compilers/rust.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py index 717d5635f842..c75e9780ac13 100644 --- a/mesonbuild/compilers/rust.py +++ b/mesonbuild/compilers/rust.py @@ -9,10 +9,13 @@ import re import typing as T +from .. import arglist from .. import options +from ..linkers.linkers import GnuLikeDynamicLinkerMixin, SolarisDynamicLinker, CompCertDynamicLinker from ..mesonlib import EnvironmentException, MesonException, Popen_safe_logged from ..options import OptionKey from .compilers import Compiler, clike_debug_args +from .mixins.clike import GROUP_FLAGS if T.TYPE_CHECKING: from ..coredata import MutableKeyedOptionDictType, KeyedOptionDictType @@ -62,6 +65,33 @@ def get_rustup_run_and_args(exelist: T.List[str]) -> T.Optional[T.Tuple[T.List[s except StopIteration: return None + +class RustcCompilerArgs(arglist.CompilerArgs): + def to_native_inplace(self): + # Check if we need to add --start/end-group for circular dependencies + # between static libraries, and for recursively searching for symbols + # needed by static libraries that are provided by object files or + # shared libraries. + # This covers all ld.bfd, ld.gold, ld.gold, and xild on Linux, which + # all act like (or are) gnu ld + # TODO: this could probably be added to the DynamicLinker instead + if isinstance(self.compiler.linker, (GnuLikeDynamicLinkerMixin, SolarisDynamicLinker, CompCertDynamicLinker)): + group_start = -1 + group_end = -1 + for i, each in enumerate(self): + if not GROUP_FLAGS.search(each): + continue + group_end = i + if group_start < 0: + # First occurrence of a library + group_start = i + # Only add groups if there are multiple libraries. + if group_end > group_start >= 0: + # Last occurrence of a library + self.insert(group_end + 1, '-Clink-arg=-Wl,--end-group') + self.insert(group_start, '-Clink-arg=-Wl,--start-group') + + class RustCompiler(Compiler): # rustc doesn't invoke the compiler itself, it doesn't need a LINKER_PREFIX @@ -100,6 +130,10 @@ def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoic self.base_options.add(OptionKey('b_vscrt')) self.native_static_libs: T.List[str] = [] + def compiler_args(self, args: T.Optional[T.Iterable[str]] = None) -> RustcCompilerArgs: + # This is correct, mypy just doesn't understand co-operative inheritance + return RustcCompilerArgs(self, args) + def needs_static_linker(self) -> bool: return False