Skip to content

Commit ee8a4fe

Browse files
committed
.cargo: Define default linker for different targets
GCC and clang on Ubuntu tend to report different system library paths, e.g. ``` $ gcc -print-search-dirs [...] libraries: =/usr/lib/gcc/x86_64-linux-gnu/11/: /usr/lib/gcc/x86_64-linux-gnu/11/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/11/: /usr/lib/gcc/x86_64-linux-gnu/11/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/: /usr/lib/gcc/x86_64-linux-gnu/11/../../../../x86_64-linux-gnu/lib/../lib/: /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/11/: /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/: /usr/lib/gcc/x86_64-linux-gnu/11/../../../../lib/: /lib/x86_64-linux-gnu/11/:/lib/x86_64-linux-gnu/: /lib/../lib/:/usr/lib/x86_64-linux-gnu/11/:/usr/lib/x86_64-linux-gnu/: /usr/lib/../lib/: /usr/lib/gcc/x86_64-linux-gnu/11/../../../../x86_64-linux-gnu/lib/: /usr/lib/gcc/x86_64-linux-gnu/11/../../../:/lib/:/usr/lib/ ``` ``` $ clang -print-search-dirs [...] libraries: =/usr/lib/llvm-15/lib/clang/15.0.7: /usr/lib/gcc/x86_64-linux-gnu/12: /usr/lib/gcc/x86_64-linux-gnu/12/../../../../lib64: /lib/x86_64-linux-gnu:/lib/../lib64:/usr/lib/x86_64-linux-gnu: /usr/lib/../lib64:/lib:/usr/lib ``` In consequence, GCC and clang select different versions of libstdc++ when linking statically - GCC selects libstdc++ 11, clang selects libstdc++ 12. We build LLVM from source (`cargo xtask build-llvm`) using clang, which causes our libLLVM artifacts to be linked to libstdc++ 12. Building a static bpf-linker binary with GCC leads to linking errors, because GCC attempts to statically link the older version of libstdc++. To avoid such mismatches, and given that bpf-linker heavily relies on LLVM ecosystem, use clang as a linker on all Linux targets. Rust since 1.90.0 uses rust-lld as a default linker for `x86_64-unknown-linux-gnu` target [0][1] and it does so by feeding rust-lld into a C compiler, that is still used as a driver as a part of `gnu-lld-cc` linker flavor (formerly implemented as `-Z gcc-ld=lld` option)[2][3][4]. To benefit from faster linking times of lld (compared to bfd) on other Linux targets, use `-fuse-ld` to force the usage of lld, that has to be available in the system. Unfortunately, enabling rust-lld with `-C linker-features=+lld`, `-C linker-flavor=gnu-lld-cc` or `-C link-self-contained=+linker` is not stabilized. Using `-C link-self-contained` (currently stabilized only with all options enabled) does not work, as rustup toolchains do not provide all necessary libraries for Linux targets. Neither does using rust-lld directly due to lack of awarness about system search paths. Use rust-lld directly on macOS without worrying about system search paths. [0] https://blog.rust-lang.org/2025/09/01/rust-lld-on-1.90.0-stable/ [1] rust-lang/rust#140525 [2] rust-lang/rust#71519 [3] rust-lang/rust#85961 [4] rust-lang/rust#112910
1 parent 83bc2ee commit ee8a4fe

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

.cargo/config.toml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,34 @@
11
[alias]
22
xtask = "run --package xtask --"
3+
4+
# On Linux we let clang drive the link so it contributes the right system
5+
# search paths.
6+
#
7+
# `x86_64-unknown-linux-gnu` target uses rust-lld as a default linker[0][1] and
8+
# it does so by feeding rust-lld into a C compiler, that is still used as a
9+
# driver as a part of `gnu-lld-cc` linker flavor (formerly implemented as
10+
# `-Z gcc-ld=lld` option)[2][3][4].
11+
#
12+
# [0] https://blog.rust-lang.org/2025/09/01/rust-lld-on-1.90.0-stable/
13+
# [1] https://github.com/rust-lang/rust/pull/140525
14+
# [2] https://github.com/rust-lang/rust/issues/71519
15+
# [3] https://github.com/rust-lang/rust/pull/85961
16+
# [4] https://github.com/rust-lang/rust/pull/112910
17+
[target.'cfg(target_os = "linux")']
18+
linker = "clang"
19+
20+
# On other Linux targets we use `-fuse-ld` to force the usage of lld, that has
21+
# to be available in the system. Unfortunately, enabling rust-lld with
22+
# `-C linker-features=+lld`, `-C linker-flavor=gnu-lld-cc` or
23+
# `-C link-self-contained=+linker` is not stabilized. Using
24+
# `-C link-self-contained` (currently stabilized only with all options enabled)
25+
# does not work, as rustup toolchains do not provide all necessary libraries
26+
# for Linux targets. Neither does using rust-lld directly due to lack of
27+
# awarness about system search paths.
28+
[target.'cfg(all(target_os = "linux", any(not(target_arch = "x86_64"), not(target_env = "gnu"))))']
29+
rustflags = ["-C", "link-arg=-fuse-ld=lld"]
30+
31+
# On macOS we can use rust-lld directly without worrying about system search
32+
# paths.
33+
[target.'cfg(target_os = "macos")']
34+
linker = "rust-lld"

0 commit comments

Comments
 (0)