nil: Fix Rust test link failure under Coverity due to missing -lm
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

The nil Rust test fails to link when built under Coverity (cov-build):

  /usr/bin/ld: src/util/libmesa_util.a.p/format_u_format_other.c.o:
    undefined reference to symbol 'sqrtf@@GLIBC_2.2.5'
  /usr/bin/ld: /lib/x86_64-linux-gnu/libm.so.6:
    error adding symbols: DSO missing from command line

This does not reproduce with plain GCC or Clang builds.

When rustc invokes the linker for the nil test binary, the generated
link command is structured as:

  cc ... [Rust rlibs] -Bdynamic -lm -ldl -lc ...
     -fuse-ld=lld -B.../gcc-ld ...
     [static archives: libmesa_util.a ...]

The -lm appears before libmesa_util.a in both Coverity and non-Coverity
builds. With --as-needed enabled, the linker only records a shared
library as needed if it resolves an undefined symbol at the point it
is encountered. Since no symbols need -lm when it is first seen, the
outcome depends on the linker implementation:

- lld (rustc's bundled linker, used in plain builds): Tolerates
  back-references from later static archives to earlier shared
  libraries, so libmesa_util.a's sqrtf reference is still resolved
  by the previously-seen libm.so.

- ld.bfd (GNU ld): Strict single-pass left-to-right. Once -lm is
  skipped by --as-needed, it cannot satisfy sqrtf when libmesa_util.a
  is processed later.

Coverity's cov-build wrapper intercepts rustc's call to the linker
and strips the -fuse-ld=lld and -B.../gcc-ld arguments, causing the
linker to fall back to the system's ld.bfd. This exposes the latent
link-order problem that lld was masking.

The underlying issue is that rustc places default libraries (-lm, -lc,
etc.) before user-specified static archives in the link command, which
is a known rustc limitation.
See also: https://github.com/rust-lang/rust/issues/154975

Fix this by passing -lm via rust_args with --no-as-needed brackets.
This forces ld.bfd to record libm as needed regardless of when it
appears on the command line, so sqrtf from libmesa_util.a is resolved
correctly under both lld and ld.bfd.

Fixes: 0920e0afb5 ("nil: Add zcull support")
Signed-off-by: Vinson Lee <vlee@freedesktop.org>
Reviewed-by: Mel Henning <mhenning@darkrefraction.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40793>
This commit is contained in:
Vinson Lee 2026-04-04 21:06:51 -07:00
parent cfdb3ddb93
commit ca6edbd9c8

View file

@ -93,9 +93,20 @@ if with_tests and get_option('b_sanitize') == 'none'
'nil',
_libnil,
suite : ['nouveau'],
# This is needed to ensure we link against glibc
# See also https://gitlab.freedesktop.org/mesa/mesa/-/issues/11632
rust_args: ['-C', 'default-linker-libraries'],
# This is needed to ensure we link against glibc.
# The --no-as-needed/-lm/--as-needed workaround forces the linker to
# keep libm for sqrtf in libmesa_util.a. This is needed because rustc
# places default libraries (-lm) before static archives in the link
# command, and Coverity's cov-build strips rustc's -fuse-ld=lld,
# falling back to ld.bfd which has strict left-to-right link order.
# Remove this workaround once rustc resolves link ordering of
# native libraries (https://github.com/rust-lang/rust/issues/154975).
rust_args: [
'-C', 'default-linker-libraries',
'-C', 'link-arg=-Wl,--no-as-needed',
'-C', 'link-arg=-lm',
'-C', 'link-arg=-Wl,--as-needed',
],
)
endif