From 38c66b1ee87be17f3e5e1957bcbba1ebcc85b30a Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 9 Oct 2025 22:06:04 +0200 Subject: [PATCH 1/2] ninjabackend: fix cut and paste issue The variable for the .a here is called "a", not "lib". Signed-off-by: Paolo Bonzini --- mesonbuild/backend/ninjabackend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 72a4633d103e..a713ae33b861 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -2122,7 +2122,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}') From 5f83e442a342edae487b2f88a72cce67db423843 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 9 Oct 2025 17:53:59 +0200 Subject: [PATCH 2/2] fix rustc -l argument on Windows On Windows, rustc searches both FOO.lib and libFOO.a when passed -lfoo. This means that the check for nonstandard names in the Unix sense is too struct, and indeed it breaks passing for example -lkernel32 (which adds kernel32.lib to the link). Fix this by special casing Windows. Extract the logic to the Rust compiler class for clarity. Signed-off-by: Paolo Bonzini --- mesonbuild/backend/ninjabackend.py | 10 ++-------- mesonbuild/compilers/rust.py | 27 ++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index a713ae33b861..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: 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]