Skip to content

Commit 289623b

Browse files
committed
Auto merge of #151021 - mati865:wild-experiments, r=<try>
Experiment linking with Wild
2 parents aefa104 + a12e9c3 commit 289623b

File tree

13 files changed

+1584
-10
lines changed

13 files changed

+1584
-10
lines changed

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
@@ -1333,7 +1333,8 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
13331333
LinkerFlavor::Gnu(Cc::Yes, _)
13341334
| LinkerFlavor::Darwin(Cc::Yes, _)
13351335
| LinkerFlavor::WasmLld(Cc::Yes)
1336-
| LinkerFlavor::Unix(Cc::Yes) => {
1336+
| LinkerFlavor::Unix(Cc::Yes)
1337+
| LinkerFlavor::Wild => {
13371338
if cfg!(any(target_os = "solaris", target_os = "illumos")) {
13381339
// On historical Solaris systems, "cc" may have
13391340
// been Sun Studio, which is not flag-compatible
@@ -1373,6 +1374,8 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
13731374
});
13741375
let flavor = sess.target.linker_flavor.with_linker_hints(stem);
13751376
let flavor = adjust_flavor_to_features(flavor, features);
1377+
let linker =
1378+
if flavor == LinkerFlavor::Wild { PathBuf::from("cc") } else { linker };
13761379
Some((linker, flavor))
13771380
}
13781381
(None, None) => None,
@@ -2480,6 +2483,8 @@ fn add_order_independent_options(
24802483
// Take care of the flavors and CLI options requesting the `lld` linker.
24812484
add_lld_args(cmd, sess, flavor, self_contained_components);
24822485

2486+
add_wild_args(cmd, sess, flavor, self_contained_components);
2487+
24832488
add_apple_link_args(cmd, sess, flavor);
24842489

24852490
let apple_sdk_root = add_apple_sdk(cmd, sess, flavor);
@@ -3393,6 +3398,58 @@ fn add_lld_args(
33933398
}
33943399
}
33953400

3401+
fn add_wild_args(
3402+
cmd: &mut dyn Linker,
3403+
sess: &Session,
3404+
flavor: LinkerFlavor,
3405+
self_contained_components: LinkSelfContainedComponents,
3406+
) {
3407+
// Either Wild or LLD to make it work with CI
3408+
if flavor != LinkerFlavor::Wild || std::env::var_os("BUILDING_RUSTC").is_some() {
3409+
let self_contained_cli = sess.opts.cg.link_self_contained.is_linker_enabled();
3410+
let self_contained_target = self_contained_components.is_linker_enabled();
3411+
3412+
let self_contained_linker = self_contained_cli || self_contained_target;
3413+
if self_contained_linker && !sess.opts.cg.link_self_contained.is_linker_disabled() {
3414+
let mut linker_path_exists = false;
3415+
for path in sess.get_tools_search_paths(false) {
3416+
let linker_path = path.join("gcc-ld");
3417+
linker_path_exists |= linker_path.exists();
3418+
cmd.cc_arg({
3419+
let mut arg = OsString::from("-B");
3420+
arg.push(linker_path);
3421+
arg
3422+
});
3423+
}
3424+
if !linker_path_exists {
3425+
sess.dcx().emit_fatal(errors::SelfContainedLinkerMissing);
3426+
}
3427+
}
3428+
3429+
if !sess.target.is_like_wasm {
3430+
cmd.cc_arg("-fuse-ld=lld");
3431+
}
3432+
return ();
3433+
}
3434+
3435+
let mut linker_path_exists = false;
3436+
for path in sess.get_tools_search_paths(false) {
3437+
let linker_path = path.join("wild-gcc-ld");
3438+
linker_path_exists |= linker_path.exists();
3439+
cmd.cc_arg({
3440+
let mut arg = OsString::from("-B");
3441+
arg.push(linker_path);
3442+
arg
3443+
});
3444+
// cmd.cc_arg("-Wl,--no-fork");
3445+
}
3446+
if !linker_path_exists {
3447+
// As a sanity check, we emit an error if none of these paths exist: we want
3448+
// self-contained linking and have no linker.
3449+
sess.dcx().emit_fatal(errors::SelfContainedLinkerMissing);
3450+
}
3451+
}
3452+
33963453
// gold has been deprecated with binutils 2.44
33973454
// and is known to behave incorrectly around Rust programs.
33983455
// 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
@@ -864,7 +864,7 @@ mod desc {
864864
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) \
865865
components: `crto`, `libc`, `unwind`, `linker`, `sanitizers`, `mingw`";
866866
pub(crate) const parse_linker_features: &str =
867-
"a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld`";
867+
"a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld`, `wild`";
868868
pub(crate) const parse_polonius: &str = "either no value or `legacy` (the default), or `next`";
869869
pub(crate) const parse_annotate_moves: &str =
870870
"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
@@ -128,6 +128,8 @@ pub enum LinkerFlavor {
128128
/// Emscripten Compiler Frontend, a wrapper around `WasmLld(Cc::Yes)` that has a different
129129
/// interface and produces some additional JavaScript output.
130130
EmCc,
131+
// TODO: This needs some design on how to proceed
132+
Wild,
131133
// Below: other linker-like tools with unique interfaces for exotic targets.
132134
/// Linker tool for BPF.
133135
Bpf,
@@ -154,6 +156,7 @@ pub enum LinkerFlavorCli {
154156
Bpf,
155157
Ptx,
156158
Llbc,
159+
Wild,
157160

158161
// Legacy stable values
159162
Gcc,
@@ -179,7 +182,8 @@ impl LinkerFlavorCli {
179182
| LinkerFlavorCli::Ld
180183
| LinkerFlavorCli::Lld(..)
181184
| LinkerFlavorCli::Msvc(Lld::No)
182-
| LinkerFlavorCli::Em => false,
185+
| LinkerFlavorCli::Em
186+
| LinkerFlavorCli::Wild => false,
183187
}
184188
}
185189
}
@@ -211,6 +215,7 @@ impl LinkerFlavor {
211215
LinkerFlavorCli::Bpf => LinkerFlavor::Bpf,
212216
LinkerFlavorCli::Llbc => LinkerFlavor::Llbc,
213217
LinkerFlavorCli::Ptx => LinkerFlavor::Ptx,
218+
LinkerFlavorCli::Wild => LinkerFlavor::Wild,
214219

215220
// Below: legacy stable values
216221
LinkerFlavorCli::Gcc => match lld_flavor {
@@ -251,6 +256,7 @@ impl LinkerFlavor {
251256
LinkerFlavor::Bpf => LinkerFlavorCli::Bpf,
252257
LinkerFlavor::Llbc => LinkerFlavorCli::Llbc,
253258
LinkerFlavor::Ptx => LinkerFlavorCli::Ptx,
259+
LinkerFlavor::Wild => LinkerFlavorCli::Wild,
254260
}
255261
}
256262

@@ -266,6 +272,7 @@ impl LinkerFlavor {
266272
LinkerFlavor::Bpf => LinkerFlavorCli::Bpf,
267273
LinkerFlavor::Llbc => LinkerFlavorCli::Llbc,
268274
LinkerFlavor::Ptx => LinkerFlavorCli::Ptx,
275+
LinkerFlavor::Wild => LinkerFlavorCli::Wild,
269276
}
270277
}
271278

@@ -280,6 +287,7 @@ impl LinkerFlavor {
280287
LinkerFlavorCli::EmCc => (Some(Cc::Yes), Some(Lld::Yes)),
281288
LinkerFlavorCli::Bpf | LinkerFlavorCli::Ptx => (None, None),
282289
LinkerFlavorCli::Llbc => (None, None),
290+
LinkerFlavorCli::Wild => (None, None),
283291

284292
// Below: legacy stable values
285293
LinkerFlavorCli::Gcc => (Some(Cc::Yes), None),
@@ -298,6 +306,8 @@ impl LinkerFlavor {
298306

299307
if stem == "llvm-bitcode-linker" {
300308
Ok(Self::Llbc)
309+
} else if stem == "wild" {
310+
Ok(Self::Wild)
301311
} else if stem == "emcc" // GCC/Clang can have an optional target prefix.
302312
|| stem == "gcc"
303313
|| stem.ends_with("-gcc")
@@ -335,7 +345,11 @@ impl LinkerFlavor {
335345
LinkerFlavor::WasmLld(cc) => LinkerFlavor::WasmLld(cc_hint.unwrap_or(cc)),
336346
LinkerFlavor::Unix(cc) => LinkerFlavor::Unix(cc_hint.unwrap_or(cc)),
337347
LinkerFlavor::Msvc(lld) => LinkerFlavor::Msvc(lld_hint.unwrap_or(lld)),
338-
LinkerFlavor::EmCc | LinkerFlavor::Bpf | LinkerFlavor::Llbc | LinkerFlavor::Ptx => self,
348+
LinkerFlavor::EmCc
349+
| LinkerFlavor::Bpf
350+
| LinkerFlavor::Llbc
351+
| LinkerFlavor::Ptx
352+
| LinkerFlavor::Wild => self,
339353
}
340354
}
341355

@@ -363,7 +377,8 @@ impl LinkerFlavor {
363377
| (LinkerFlavor::EmCc, LinkerFlavorCli::EmCc)
364378
| (LinkerFlavor::Bpf, LinkerFlavorCli::Bpf)
365379
| (LinkerFlavor::Llbc, LinkerFlavorCli::Llbc)
366-
| (LinkerFlavor::Ptx, LinkerFlavorCli::Ptx) => return true,
380+
| (LinkerFlavor::Ptx, LinkerFlavorCli::Ptx)
381+
| (LinkerFlavor::Wild, LinkerFlavorCli::Wild) => return true,
367382
// 2. The linker flavor is independent of target and compatible
368383
(LinkerFlavor::Ptx, LinkerFlavorCli::Llbc) => return true,
369384
_ => {}
@@ -389,7 +404,8 @@ impl LinkerFlavor {
389404
| LinkerFlavor::EmCc
390405
| LinkerFlavor::Bpf
391406
| LinkerFlavor::Llbc
392-
| LinkerFlavor::Ptx => LldFlavor::Ld,
407+
| LinkerFlavor::Ptx
408+
| LinkerFlavor::Wild => LldFlavor::Ld,
393409
LinkerFlavor::Darwin(..) => LldFlavor::Ld64,
394410
LinkerFlavor::WasmLld(..) => LldFlavor::Wasm,
395411
LinkerFlavor::Msvc(..) => LldFlavor::Link,
@@ -415,7 +431,8 @@ impl LinkerFlavor {
415431
| LinkerFlavor::Unix(_)
416432
| LinkerFlavor::Bpf
417433
| LinkerFlavor::Llbc
418-
| LinkerFlavor::Ptx => false,
434+
| LinkerFlavor::Ptx
435+
| LinkerFlavor::Wild => false,
419436
}
420437
}
421438

@@ -427,7 +444,8 @@ impl LinkerFlavor {
427444
| LinkerFlavor::Darwin(Cc::Yes, _)
428445
| LinkerFlavor::WasmLld(Cc::Yes)
429446
| LinkerFlavor::Unix(Cc::Yes)
430-
| LinkerFlavor::EmCc => true,
447+
| LinkerFlavor::EmCc
448+
| LinkerFlavor::Wild => true,
431449
LinkerFlavor::Gnu(..)
432450
| LinkerFlavor::Darwin(..)
433451
| LinkerFlavor::WasmLld(_)
@@ -512,6 +530,7 @@ linker_flavor_cli_impls! {
512530
(LinkerFlavorCli::Bpf) "bpf"
513531
(LinkerFlavorCli::Llbc) "llbc"
514532
(LinkerFlavorCli::Ptx) "ptx"
533+
(LinkerFlavorCli::Wild) "wild"
515534

516535
// Legacy stable flavors
517536
(LinkerFlavorCli::Gcc) "gcc"
@@ -2619,6 +2638,7 @@ fn add_link_args_iter(
26192638
assert_eq!(lld, Lld::No);
26202639
insert(LinkerFlavor::Msvc(Lld::Yes));
26212640
}
2641+
LinkerFlavor::Wild => insert(LinkerFlavor::Wild),
26222642
LinkerFlavor::WasmLld(..)
26232643
| LinkerFlavor::Unix(..)
26242644
| LinkerFlavor::EmCc
@@ -3016,6 +3036,7 @@ impl Target {
30163036
| LinkerFlavor::Llbc => {
30173037
check_eq!(flavor, self.linker_flavor, "mixing different linker flavors")
30183038
}
3039+
LinkerFlavor::Wild => todo!(),
30193040
}
30203041

30213042
// 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::{
@@ -2511,6 +2513,15 @@ impl Step for Assemble {
25112513
copy_lld_artifacts(builder, lld_wrapper, target_compiler);
25122514
}
25132515

2516+
if builder.host_target.triple == "x86_64-unknown-linux-gnu" {
2517+
let wild_wrapper =
2518+
builder.ensure(crate::core::build_steps::tool::WildLinker::for_use_by_compiler(
2519+
builder,
2520+
target_compiler,
2521+
));
2522+
copy_wild_artifacts(builder, wild_wrapper, target_compiler);
2523+
}
2524+
25142525
if builder.config.llvm_enabled(target_compiler.host) && builder.config.llvm_tools_enabled {
25152526
debug!(
25162527
"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
@@ -598,6 +598,33 @@ impl Step for Rustc {
598598
}
599599
}
600600

601+
if builder.host_target.triple == "x86_64-unknown-linux-gnu" {
602+
let src_dir = builder.sysroot_target_bindir(target_compiler, target);
603+
let rust_wild = exe("rust-wild", target_compiler.host);
604+
builder.copy_link(
605+
&src_dir.join(&rust_wild),
606+
&dst_dir.join(&rust_wild),
607+
FileType::Executable,
608+
);
609+
let self_contained_wild_src_dir = src_dir.join("wild-gcc-ld");
610+
let self_contained_wild_dst_dir = dst_dir.join("wild-gcc-ld");
611+
t!(fs::create_dir(&self_contained_wild_dst_dir));
612+
let wild_name = "wild";
613+
let exe_name = exe(wild_name, target_compiler.host);
614+
builder.copy_link(
615+
&self_contained_wild_src_dir.join(&exe_name),
616+
&self_contained_wild_dst_dir.join(&exe_name),
617+
FileType::Executable,
618+
);
619+
// Pretend Wild is LD so the compiler can pick it up
620+
let exe_name = exe("ld", target_compiler.host);
621+
builder.copy_link(
622+
&self_contained_wild_src_dir.join(&exe_name),
623+
&self_contained_wild_dst_dir.join(&exe_name),
624+
FileType::Executable,
625+
);
626+
}
627+
601628
if builder.config.llvm_enabled(target_compiler.host)
602629
&& builder.config.llvm_tools_enabled
603630
{

0 commit comments

Comments
 (0)