Skip to content

Commit eb93609

Browse files
committed
Auto merge of #151021 - mati865:wild-experiments, r=<try>
Experiment linking with Wild
2 parents b7e97a9 + 0175b77 commit eb93609

13 files changed

Lines changed: 1720 additions & 10 deletions

File tree

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ members = [
4545
"src/tools/unicode-table-generator",
4646
"src/tools/unstable-book-gen",
4747
"src/tools/wasm-component-ld",
48+
# "src/tools/wild-linker",
4849
"src/tools/x",
4950
# tidy-alphabetical-end
5051
]
@@ -53,6 +54,7 @@ exclude = [
5354
"build",
5455
"compiler/rustc_codegen_cranelift",
5556
"compiler/rustc_codegen_gcc",
57+
"src/tools/wild-linker",
5658
"src/bootstrap",
5759
"tests/rustdoc-gui",
5860
# HACK(eddyb) This hardcodes the fact that our CI uses `/checkout/obj`.
@@ -92,4 +94,3 @@ codegen-units = 1
9294
# If you want to use a crate with local modifications, you can set a path or git dependency here.
9395
# For git dependencies, also add your source to ALLOWED_SOURCES in src/tools/tidy/src/extdeps.rs.
9496
#[patch.crates-io]
95-

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1494,7 +1494,8 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
14941494
LinkerFlavor::Gnu(Cc::Yes, _)
14951495
| LinkerFlavor::Darwin(Cc::Yes, _)
14961496
| LinkerFlavor::WasmLld(Cc::Yes)
1497-
| LinkerFlavor::Unix(Cc::Yes) => {
1497+
| LinkerFlavor::Unix(Cc::Yes)
1498+
| LinkerFlavor::Wild => {
14981499
if cfg!(any(target_os = "solaris", target_os = "illumos")) {
14991500
// On historical Solaris systems, "cc" may have
15001501
// been Sun Studio, which is not flag-compatible
@@ -1534,6 +1535,8 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
15341535
});
15351536
let flavor = sess.target.linker_flavor.with_linker_hints(stem);
15361537
let flavor = adjust_flavor_to_features(flavor, features);
1538+
let linker =
1539+
if flavor == LinkerFlavor::Wild { PathBuf::from("cc") } else { linker };
15371540
Some((linker, flavor))
15381541
}
15391542
(None, None) => None,
@@ -2715,6 +2718,8 @@ fn add_order_independent_options(
27152718
// Take care of the flavors and CLI options requesting the `lld` linker.
27162719
add_lld_args(cmd, sess, flavor, self_contained_components);
27172720

2721+
add_wild_args(cmd, sess, flavor, self_contained_components);
2722+
27182723
add_apple_link_args(cmd, sess, flavor);
27192724

27202725
let apple_sdk_root = add_apple_sdk(cmd, sess, flavor);
@@ -3625,6 +3630,58 @@ fn add_lld_args(
36253630
}
36263631
}
36273632

3633+
fn add_wild_args(
3634+
cmd: &mut dyn Linker,
3635+
sess: &Session,
3636+
flavor: LinkerFlavor,
3637+
self_contained_components: LinkSelfContainedComponents,
3638+
) {
3639+
// Either Wild or LLD to make it work with CI
3640+
if flavor != LinkerFlavor::Wild || std::env::var_os("BUILDING_RUSTC").is_some() {
3641+
let self_contained_cli = sess.opts.cg.link_self_contained.is_linker_enabled();
3642+
let self_contained_target = self_contained_components.is_linker_enabled();
3643+
3644+
let self_contained_linker = self_contained_cli || self_contained_target;
3645+
if self_contained_linker && !sess.opts.cg.link_self_contained.is_linker_disabled() {
3646+
let mut linker_path_exists = false;
3647+
for path in sess.get_tools_search_paths(false) {
3648+
let linker_path = path.join("gcc-ld");
3649+
linker_path_exists |= linker_path.exists();
3650+
cmd.cc_arg({
3651+
let mut arg = OsString::from("-B");
3652+
arg.push(linker_path);
3653+
arg
3654+
});
3655+
}
3656+
if !linker_path_exists {
3657+
sess.dcx().emit_fatal(errors::SelfContainedLinkerMissing);
3658+
}
3659+
}
3660+
3661+
if !sess.target.is_like_wasm {
3662+
cmd.cc_arg("-fuse-ld=lld");
3663+
}
3664+
return ();
3665+
}
3666+
3667+
let mut linker_path_exists = false;
3668+
for path in sess.get_tools_search_paths(false) {
3669+
let linker_path = path.join("wild-gcc-ld");
3670+
linker_path_exists |= linker_path.exists();
3671+
cmd.cc_arg({
3672+
let mut arg = OsString::from("-B");
3673+
arg.push(linker_path);
3674+
arg
3675+
});
3676+
// cmd.cc_arg("-Wl,--no-fork");
3677+
}
3678+
if !linker_path_exists {
3679+
// As a sanity check, we emit an error if none of these paths exist: we want
3680+
// self-contained linking and have no linker.
3681+
sess.dcx().emit_fatal(errors::SelfContainedLinkerMissing);
3682+
}
3683+
}
3684+
36283685
// gold has been deprecated with binutils 2.44
36293686
// and is known to behave incorrectly around Rust programs.
36303687
// There have been reports of being unable to bootstrap with gold:

compiler/rustc_codegen_ssa/src/back/linker.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,16 @@ pub(crate) fn get_linker<'a>(
162162
LinkerFlavor::Bpf => Box::new(BpfLinker { cmd, sess }) as Box<dyn Linker>,
163163
LinkerFlavor::Llbc => Box::new(LlbcLinker { cmd, sess }) as Box<dyn Linker>,
164164
LinkerFlavor::Ptx => Box::new(PtxLinker { cmd, sess }) as Box<dyn Linker>,
165+
LinkerFlavor::Wild => Box::new(GccLinker {
166+
cmd,
167+
sess,
168+
target_cpu,
169+
hinted_static: None,
170+
is_ld: false,
171+
is_gnu: true,
172+
uses_lld: flavor.uses_lld(),
173+
codegen_backend,
174+
}),
165175
}
166176
}
167177

compiler/rustc_session/src/options.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ mod desc {
822822
pub(crate) const parse_link_self_contained: &str = "one of: `y`, `yes`, `on`, `n`, `no`, `off`, or a list of enabled (`+` prefix) and disabled (`-` prefix) \
823823
components: `crto`, `libc`, `unwind`, `linker`, `sanitizers`, `mingw`";
824824
pub(crate) const parse_linker_features: &str =
825-
"a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld`";
825+
"a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld`, `wild`";
826826
pub(crate) const parse_polonius: &str = "either no value or `legacy` (the default), or `next`";
827827
pub(crate) const parse_annotate_moves: &str =
828828
"either a boolean (`yes`, `no`, `on`, `off`, etc.), or a size limit in bytes";

compiler/rustc_target/src/spec/mod.rs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ pub enum LinkerFlavor {
129129
/// Emscripten Compiler Frontend, a wrapper around `WasmLld(Cc::Yes)` that has a different
130130
/// interface and produces some additional JavaScript output.
131131
EmCc,
132+
// TODO: This needs some design on how to proceed
133+
Wild,
132134
// Below: other linker-like tools with unique interfaces for exotic targets.
133135
/// Linker tool for BPF.
134136
Bpf,
@@ -155,6 +157,7 @@ pub enum LinkerFlavorCli {
155157
Bpf,
156158
Ptx,
157159
Llbc,
160+
Wild,
158161

159162
// Legacy stable values
160163
Gcc,
@@ -180,7 +183,8 @@ impl LinkerFlavorCli {
180183
| LinkerFlavorCli::Ld
181184
| LinkerFlavorCli::Lld(..)
182185
| LinkerFlavorCli::Msvc(Lld::No)
183-
| LinkerFlavorCli::Em => false,
186+
| LinkerFlavorCli::Em
187+
| LinkerFlavorCli::Wild => false,
184188
}
185189
}
186190
}
@@ -212,6 +216,7 @@ impl LinkerFlavor {
212216
LinkerFlavorCli::Bpf => LinkerFlavor::Bpf,
213217
LinkerFlavorCli::Llbc => LinkerFlavor::Llbc,
214218
LinkerFlavorCli::Ptx => LinkerFlavor::Ptx,
219+
LinkerFlavorCli::Wild => LinkerFlavor::Wild,
215220

216221
// Below: legacy stable values
217222
LinkerFlavorCli::Gcc => match lld_flavor {
@@ -252,6 +257,7 @@ impl LinkerFlavor {
252257
LinkerFlavor::Bpf => LinkerFlavorCli::Bpf,
253258
LinkerFlavor::Llbc => LinkerFlavorCli::Llbc,
254259
LinkerFlavor::Ptx => LinkerFlavorCli::Ptx,
260+
LinkerFlavor::Wild => LinkerFlavorCli::Wild,
255261
}
256262
}
257263

@@ -267,6 +273,7 @@ impl LinkerFlavor {
267273
LinkerFlavor::Bpf => LinkerFlavorCli::Bpf,
268274
LinkerFlavor::Llbc => LinkerFlavorCli::Llbc,
269275
LinkerFlavor::Ptx => LinkerFlavorCli::Ptx,
276+
LinkerFlavor::Wild => LinkerFlavorCli::Wild,
270277
}
271278
}
272279

@@ -281,6 +288,7 @@ impl LinkerFlavor {
281288
LinkerFlavorCli::EmCc => (Some(Cc::Yes), Some(Lld::Yes)),
282289
LinkerFlavorCli::Bpf | LinkerFlavorCli::Ptx => (None, None),
283290
LinkerFlavorCli::Llbc => (None, None),
291+
LinkerFlavorCli::Wild => (None, None),
284292

285293
// Below: legacy stable values
286294
LinkerFlavorCli::Gcc => (Some(Cc::Yes), None),
@@ -299,6 +307,8 @@ impl LinkerFlavor {
299307

300308
if stem == "llvm-bitcode-linker" {
301309
Ok(Self::Llbc)
310+
} else if stem == "wild" {
311+
Ok(Self::Wild)
302312
} else if stem == "emcc" // GCC/Clang can have an optional target prefix.
303313
|| stem == "gcc"
304314
|| stem.ends_with("-gcc")
@@ -336,7 +346,11 @@ impl LinkerFlavor {
336346
LinkerFlavor::WasmLld(cc) => LinkerFlavor::WasmLld(cc_hint.unwrap_or(cc)),
337347
LinkerFlavor::Unix(cc) => LinkerFlavor::Unix(cc_hint.unwrap_or(cc)),
338348
LinkerFlavor::Msvc(lld) => LinkerFlavor::Msvc(lld_hint.unwrap_or(lld)),
339-
LinkerFlavor::EmCc | LinkerFlavor::Bpf | LinkerFlavor::Llbc | LinkerFlavor::Ptx => self,
349+
LinkerFlavor::EmCc
350+
| LinkerFlavor::Bpf
351+
| LinkerFlavor::Llbc
352+
| LinkerFlavor::Ptx
353+
| LinkerFlavor::Wild => self,
340354
}
341355
}
342356

@@ -364,7 +378,8 @@ impl LinkerFlavor {
364378
| (LinkerFlavor::EmCc, LinkerFlavorCli::EmCc)
365379
| (LinkerFlavor::Bpf, LinkerFlavorCli::Bpf)
366380
| (LinkerFlavor::Llbc, LinkerFlavorCli::Llbc)
367-
| (LinkerFlavor::Ptx, LinkerFlavorCli::Ptx) => return true,
381+
| (LinkerFlavor::Ptx, LinkerFlavorCli::Ptx)
382+
| (LinkerFlavor::Wild, LinkerFlavorCli::Wild) => return true,
368383
// 2. The linker flavor is independent of target and compatible
369384
(LinkerFlavor::Ptx, LinkerFlavorCli::Llbc) => return true,
370385
_ => {}
@@ -390,7 +405,8 @@ impl LinkerFlavor {
390405
| LinkerFlavor::EmCc
391406
| LinkerFlavor::Bpf
392407
| LinkerFlavor::Llbc
393-
| LinkerFlavor::Ptx => LldFlavor::Ld,
408+
| LinkerFlavor::Ptx
409+
| LinkerFlavor::Wild => LldFlavor::Ld,
394410
LinkerFlavor::Darwin(..) => LldFlavor::Ld64,
395411
LinkerFlavor::WasmLld(..) => LldFlavor::Wasm,
396412
LinkerFlavor::Msvc(..) => LldFlavor::Link,
@@ -416,7 +432,8 @@ impl LinkerFlavor {
416432
| LinkerFlavor::Unix(_)
417433
| LinkerFlavor::Bpf
418434
| LinkerFlavor::Llbc
419-
| LinkerFlavor::Ptx => false,
435+
| LinkerFlavor::Ptx
436+
| LinkerFlavor::Wild => false,
420437
}
421438
}
422439

@@ -428,7 +445,8 @@ impl LinkerFlavor {
428445
| LinkerFlavor::Darwin(Cc::Yes, _)
429446
| LinkerFlavor::WasmLld(Cc::Yes)
430447
| LinkerFlavor::Unix(Cc::Yes)
431-
| LinkerFlavor::EmCc => true,
448+
| LinkerFlavor::EmCc
449+
| LinkerFlavor::Wild => true,
432450
LinkerFlavor::Gnu(..)
433451
| LinkerFlavor::Darwin(..)
434452
| LinkerFlavor::WasmLld(_)
@@ -513,6 +531,7 @@ linker_flavor_cli_impls! {
513531
(LinkerFlavorCli::Bpf) "bpf"
514532
(LinkerFlavorCli::Llbc) "llbc"
515533
(LinkerFlavorCli::Ptx) "ptx"
534+
(LinkerFlavorCli::Wild) "wild"
516535

517536
// Legacy stable flavors
518537
(LinkerFlavorCli::Gcc) "gcc"
@@ -2736,6 +2755,7 @@ fn add_link_args_iter(
27362755
assert_eq!(lld, Lld::No);
27372756
insert(LinkerFlavor::Msvc(Lld::Yes));
27382757
}
2758+
LinkerFlavor::Wild => insert(LinkerFlavor::Wild),
27392759
LinkerFlavor::WasmLld(..)
27402760
| LinkerFlavor::Unix(..)
27412761
| LinkerFlavor::EmCc
@@ -3133,6 +3153,7 @@ impl Target {
31333153
| LinkerFlavor::Llbc => {
31343154
check_eq!(flavor, self.linker_flavor, "mixing different linker flavors")
31353155
}
3156+
LinkerFlavor::Wild => todo!(),
31363157
}
31373158

31383159
// Check that link args for cc and non-cc versions of flavors are consistent.

compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ pub(crate) fn target() -> Target {
2121
| SanitizerSet::REALTIME;
2222
base.supports_xray = true;
2323

24+
// When we're asked to use the `rust-lld` linker by default, set the appropriate lld-using
25+
// linker flavor, and self-contained linker component.
26+
if option_env!("CFG_USE_SELF_CONTAINED_LINKER").is_some() {
27+
base.linker_flavor = LinkerFlavor::Gnu(Cc::Yes, Lld::Yes);
28+
base.link_self_contained = crate::spec::LinkSelfContainedDefault::with_linker();
29+
}
30+
31+
base.linker_flavor = LinkerFlavor::Wild;
32+
2433
Target {
2534
llvm_target: "x86_64-unknown-linux-gnu".into(),
2635
metadata: TargetMetadata {

src/bootstrap/src/core/build_steps/compile.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ use serde_derive::Deserialize;
2020
use tracing::span;
2121

2222
use crate::core::build_steps::gcc::{Gcc, GccOutput, GccTargetPair};
23-
use crate::core::build_steps::tool::{RustcPrivateCompilers, SourceType, copy_lld_artifacts};
23+
use crate::core::build_steps::tool::{
24+
RustcPrivateCompilers, SourceType, copy_lld_artifacts, copy_wild_artifacts,
25+
};
2426
use crate::core::build_steps::{dist, llvm};
2527
use crate::core::builder;
2628
use crate::core::builder::{
@@ -2509,6 +2511,15 @@ impl Step for Assemble {
25092511
copy_lld_artifacts(builder, lld_wrapper, target_compiler);
25102512
}
25112513

2514+
if builder.host_target.triple == "x86_64-unknown-linux-gnu" {
2515+
let wild_wrapper =
2516+
builder.ensure(crate::core::build_steps::tool::WildLinker::for_use_by_compiler(
2517+
builder,
2518+
target_compiler,
2519+
));
2520+
copy_wild_artifacts(builder, wild_wrapper, target_compiler);
2521+
}
2522+
25122523
if builder.config.llvm_enabled(target_compiler.host) && builder.config.llvm_tools_enabled {
25132524
debug!(
25142525
"llvm and llvm tools enabled; copying `llvm-objcopy` as `rust-objcopy` to \

src/bootstrap/src/core/build_steps/dist.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,33 @@ impl Step for Rustc {
606606
}
607607
}
608608

609+
if builder.host_target.triple == "x86_64-unknown-linux-gnu" {
610+
let src_dir = builder.sysroot_target_bindir(target_compiler, target);
611+
let rust_wild = exe("rust-wild", target_compiler.host);
612+
builder.copy_link(
613+
&src_dir.join(&rust_wild),
614+
&dst_dir.join(&rust_wild),
615+
FileType::Executable,
616+
);
617+
let self_contained_wild_src_dir = src_dir.join("wild-gcc-ld");
618+
let self_contained_wild_dst_dir = dst_dir.join("wild-gcc-ld");
619+
t!(fs::create_dir(&self_contained_wild_dst_dir));
620+
let wild_name = "wild";
621+
let exe_name = exe(wild_name, target_compiler.host);
622+
builder.copy_link(
623+
&self_contained_wild_src_dir.join(&exe_name),
624+
&self_contained_wild_dst_dir.join(&exe_name),
625+
FileType::Executable,
626+
);
627+
// Pretend Wild is LD so the compiler can pick it up
628+
let exe_name = exe("ld", target_compiler.host);
629+
builder.copy_link(
630+
&self_contained_wild_src_dir.join(&exe_name),
631+
&self_contained_wild_dst_dir.join(&exe_name),
632+
FileType::Executable,
633+
);
634+
}
635+
609636
if builder.config.llvm_enabled(target_compiler.host)
610637
&& builder.config.llvm_tools_enabled
611638
{

0 commit comments

Comments
 (0)