Skip to content

Commit e583763

Browse files
committed
feat: opt a target triple's stdlib out of the bundled libc
rustc puts the prebuilt stdlib's `self-contained` directory on the linker search path ahead of the CC toolchain's `-L`, so `-lc` always resolves to the libc rustc ships. A workspace that builds its own sysroot -- a distro, an OS image, an embedded target -- silently links the wrong libc, and any patch it carries in that libc never reaches a Rust binary. `-C link-self-contained=no` does not help: it leaves the search path in place (verified on 1.95.0, byte-identical output). The files have to leave the sandbox instead, so the stdlib repo grows a second filegroup without the archives, and `declare_rustc_toolchains` grows a triple list that selects it. The CRT objects stay in the filtered filegroup. Remove the directory altogether and rustc stops using self-contained CRT, emitting bare `rcrt1.o` / `crti.o` names that the clang driver cannot resolve.
1 parent 8133604 commit e583763

2 files changed

Lines changed: 27 additions & 1 deletion

File tree

rs/private/stdlib_repository.bzl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,26 @@ rust_stdlib_filegroup(
2020
visibility = ["//visibility:public"],
2121
)
2222
23+
# The same stdlib without the libc and CRT archives rustc bundles beside it.
24+
# rustc searches `self-contained` ahead of the CC toolchain's -L, so dropping
25+
# the archives there lets `-lc` fall through to the platform sysroot. The CRT
26+
# objects stay: rustc names bare crt files the driver cannot find when the
27+
# directory is absent altogether.
28+
rust_stdlib_filegroup(
29+
name = "rust_std-{target_triple}-external-libc",
30+
srcs = glob(
31+
[
32+
"lib/rustlib/{target_triple}/lib/*.rlib",
33+
"lib/rustlib/{target_triple}/lib/*.rmeta",
34+
"lib/rustlib/{target_triple}/lib/*{dylib_ext}*",
35+
"lib/rustlib/{target_triple}/lib/*{staticlib_ext}",
36+
"lib/rustlib/{target_triple}/lib/self-contained/*.o",
37+
],
38+
allow_empty = True,
39+
),
40+
visibility = ["//visibility:public"],
41+
)
42+
2343
alias(
2444
name = "rust_lib-{target_triple}",
2545
actual = "rust_std-{target_triple}",

rs/toolchains/declare_rustc_toolchains.bzl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ def declare_rustc_toolchains(
4242
rust_objcopy = None,
4343
rust_lld = None,
4444
bpf_linker = None,
45-
rust_std = None):
45+
rust_std = None,
46+
external_libc_triples = []):
4647
"""Declares generated or custom Rust compiler toolchains.
4748
4849
Args:
@@ -64,6 +65,9 @@ def declare_rustc_toolchains(
6465
rust_lld: Optional rust-lld label or labels keyed by execution triple.
6566
bpf_linker: Optional bpf-linker label or labels keyed by execution triple.
6667
rust_std: Optional standard-library label or labels keyed by target triple.
68+
external_libc_triples: Target triples whose standard library should link
69+
the platform's libc instead of the copy rustc bundles. Ignored for a
70+
triple whose standard library is given explicitly in `rust_std`.
6771
"""
6872
if type(rustc) == "dict":
6973
for exec_triple in rustc:
@@ -99,6 +103,8 @@ def declare_rustc_toolchains(
99103
stdlib_repo = "rust_stdlib_%s_%s" % (target_key, version_key)
100104
if target_triple in SUPPORTED_TIER_3_TRIPLES:
101105
default_rust_std = "@rustc_src_" + version_key + "//src:rust_std"
106+
elif target_triple in external_libc_triples:
107+
default_rust_std = "@%s//:rust_std-%s-external-libc" % (stdlib_repo, target_triple)
102108
else:
103109
default_rust_std = "@%s//:rust_std-%s" % (stdlib_repo, target_triple)
104110
rust_std_select[config_label] = _component(rust_std, target_triple, default_rust_std)

0 commit comments

Comments
 (0)