diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 72a4633d103e..91f4129a857d 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -2050,14 +2050,8 @@ def _link_library(libname: str, static: bool, bundle: bool = False) -> None: if rustc.has_verbatim(): modifiers.append('+verbatim') else: - # undo the effects of -l without verbatim - badname = not is_library(libname) - libname, ext = os.path.splitext(libname) - if libname.startswith('lib'): - libname = libname[3:] - else: - badname = True - if badname: + libname = rustc.lib_file_to_l_arg(self.environment, libname) + if libname is None: raise MesonException(f"rustc does not implement '-l{type_}:+verbatim'; cannot link to '{orig_libname}' due to nonstandard name") if modifiers: @@ -2122,7 +2116,7 @@ def _link_library(libname: str, static: bool, bundle: bool = False) -> None: _link_library(a, static) continue - dir_, _ = os.path.split(lib) + dir_, _ = os.path.split(a) linkdirs.add(dir_) args.append(f'-Clink-arg={a}') diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py index c0b01bb3fcef..8f8febdb0eb0 100644 --- a/mesonbuild/compilers/rust.py +++ b/mesonbuild/compilers/rust.py @@ -13,7 +13,7 @@ from .. import options from ..mesonlib import EnvironmentException, MesonException, Popen_safe_logged, version_compare from ..options import OptionKey -from .compilers import Compiler, CompileCheckMode, clike_debug_args +from .compilers import Compiler, CompileCheckMode, clike_debug_args, is_library if T.TYPE_CHECKING: from ..options import MutableKeyedOptionDictType @@ -208,6 +208,31 @@ def has_verbatim(self) -> bool: # being linked. However, Meson uses "bundle", not "whole_archive". return False + def lib_file_to_l_arg(self, env: Environment, libname: str) -> T.Optional[str]: + """Undo the effects of -l on the filename, returning the + argument that can be passed to -l, or None if the + library name is not supported.""" + if not is_library(libname): + return None + libname, ext = os.path.splitext(libname) + + # On Windows, rustc's -lfoo searches either foo.lib or libfoo.a. + # Elsewhere, it searches both static and shared libraries and always with + # the "lib" prefix; for simplicity just skip .lib on non-Windows. + if env.machines[self.for_machine].is_windows(): + if ext == '.lib': + return libname + if ext != '.a': + return None + else: + if ext == '.lib': + return None + + if not libname.startswith('lib'): + return None + libname = libname[3:] + return libname + def get_debug_args(self, is_debug: bool) -> T.List[str]: return clike_debug_args[is_debug]