Skip to content

Commit b2eec46

Browse files
committed
Auto merge of #151021 - mati865:wild-experiments, r=<try>
Experiment linking with Wild
2 parents 88f7399 + 5256472 commit b2eec46

14 files changed

Lines changed: 1587 additions & 10 deletions

File tree

Cargo.toml

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

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1831,7 +1831,8 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
18311831
LinkerFlavor::Gnu(Cc::Yes, _)
18321832
| LinkerFlavor::Darwin(Cc::Yes, _)
18331833
| LinkerFlavor::WasmLld(Cc::Yes)
1834-
| LinkerFlavor::Unix(Cc::Yes) => {
1834+
| LinkerFlavor::Unix(Cc::Yes)
1835+
| LinkerFlavor::Wild => {
18351836
if cfg!(any(target_os = "solaris", target_os = "illumos")) {
18361837
// On historical Solaris systems, "cc" may have
18371838
// been Sun Studio, which is not flag-compatible
@@ -1870,6 +1871,8 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
18701871
});
18711872
let flavor = sess.target.linker_flavor.with_linker_hints(stem);
18721873
let flavor = adjust_flavor_to_features(flavor, features);
1874+
let linker =
1875+
if flavor == LinkerFlavor::Wild { PathBuf::from("cc") } else { linker };
18731876
Some((linker, flavor))
18741877
}
18751878
(None, None) => None,
@@ -3215,6 +3218,8 @@ fn add_order_independent_options(
32153218
// Take care of the flavors and CLI options requesting the `lld` linker.
32163219
add_lld_args(cmd, sess, flavor, self_contained_components);
32173220

3221+
add_wild_args(cmd, sess, flavor, self_contained_components);
3222+
32183223
add_apple_link_args(cmd, sess, flavor);
32193224

32203225
let apple_sdk_root = add_apple_sdk(cmd, sess, flavor);
@@ -4146,6 +4151,58 @@ fn add_lld_args(
41464151
}
41474152
}
41484153

4154+
fn add_wild_args(
4155+
cmd: &mut dyn Linker,
4156+
sess: &Session,
4157+
flavor: LinkerFlavor,
4158+
self_contained_components: LinkSelfContainedComponents,
4159+
) {
4160+
// Either Wild or LLD to make it work with CI
4161+
if flavor != LinkerFlavor::Wild || std::env::var_os("BUILDING_RUSTC").is_some() {
4162+
let self_contained_cli = sess.opts.cg.link_self_contained.is_linker_enabled();
4163+
let self_contained_target = self_contained_components.is_linker_enabled();
4164+
4165+
let self_contained_linker = self_contained_cli || self_contained_target;
4166+
if self_contained_linker && !sess.opts.cg.link_self_contained.is_linker_disabled() {
4167+
let mut linker_path_exists = false;
4168+
for path in sess.get_tools_search_paths(false) {
4169+
let linker_path = path.join("gcc-ld");
4170+
linker_path_exists |= linker_path.exists();
4171+
cmd.cc_arg({
4172+
let mut arg = OsString::from("-B");
4173+
arg.push(linker_path);
4174+
arg
4175+
});
4176+
}
4177+
if !linker_path_exists {
4178+
sess.dcx().emit_fatal(diagnostics::SelfContainedLinkerMissing);
4179+
}
4180+
}
4181+
4182+
if !sess.target.is_like_wasm {
4183+
cmd.cc_arg("-fuse-ld=lld");
4184+
}
4185+
return ();
4186+
}
4187+
4188+
let mut linker_path_exists = false;
4189+
for path in sess.get_tools_search_paths(false) {
4190+
let linker_path = path.join("wild-gcc-ld");
4191+
linker_path_exists |= linker_path.exists();
4192+
cmd.cc_arg({
4193+
let mut arg = OsString::from("-B");
4194+
arg.push(linker_path);
4195+
arg
4196+
});
4197+
// cmd.cc_arg("-Wl,--no-fork");
4198+
}
4199+
if !linker_path_exists {
4200+
// As a sanity check, we emit an error if none of these paths exist: we want
4201+
// self-contained linking and have no linker.
4202+
sess.dcx().emit_fatal(diagnostics::SelfContainedLinkerMissing);
4203+
}
4204+
}
4205+
41494206
// gold has been deprecated with binutils 2.44
41504207
// and is known to behave incorrectly around Rust programs.
41514208
// 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
@@ -161,6 +161,16 @@ pub(crate) fn get_linker<'a>(
161161
LinkerFlavor::EmCc => Box::new(EmLinker { cmd, sess }) as Box<dyn Linker>,
162162
LinkerFlavor::Bpf => Box::new(BpfLinker { cmd, sess }) as Box<dyn Linker>,
163163
LinkerFlavor::Llbc => Box::new(LlbcLinker { cmd, sess }) as Box<dyn Linker>,
164+
LinkerFlavor::Wild => Box::new(GccLinker {
165+
cmd,
166+
sess,
167+
target_cpu,
168+
hinted_static: None,
169+
is_ld: false,
170+
is_gnu: true,
171+
uses_lld: flavor.uses_lld(),
172+
codegen_backend,
173+
}),
164174
}
165175
}
166176

compiler/rustc_session/src/options.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,7 @@ mod desc {
890890
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) \
891891
components: `crto`, `libc`, `unwind`, `linker`, `sanitizers`, `mingw`";
892892
pub(crate) const parse_linker_features: &str =
893-
"a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld`";
893+
"a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld`, `wild`";
894894
pub(crate) const parse_polonius: &str =
895895
"either no value or one of `legacy` (the default), `off`, or `next`";
896896
pub(crate) const parse_annotate_moves: &str =

compiler/rustc_target/src/spec/mod.rs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ pub enum LinkerFlavor {
130130
/// Emscripten Compiler Frontend, a wrapper around `WasmLld(Cc::Yes)` that has a different
131131
/// interface and produces some additional JavaScript output.
132132
EmCc,
133+
// TODO: This needs some design on how to proceed
134+
Wild,
133135
// Below: other linker-like tools with unique interfaces for exotic targets.
134136
/// Linker tool for BPF.
135137
Bpf,
@@ -153,6 +155,7 @@ pub enum LinkerFlavorCli {
153155
EmCc,
154156
Bpf,
155157
Llbc,
158+
Wild,
156159

157160
// Legacy stable values
158161
Gcc,
@@ -177,7 +180,8 @@ impl LinkerFlavorCli {
177180
| LinkerFlavorCli::Ld
178181
| LinkerFlavorCli::Lld(..)
179182
| LinkerFlavorCli::Msvc(Lld::No)
180-
| LinkerFlavorCli::Em => false,
183+
| LinkerFlavorCli::Em
184+
| LinkerFlavorCli::Wild => false,
181185
}
182186
}
183187
}
@@ -208,6 +212,7 @@ impl LinkerFlavor {
208212
LinkerFlavorCli::EmCc => LinkerFlavor::EmCc,
209213
LinkerFlavorCli::Bpf => LinkerFlavor::Bpf,
210214
LinkerFlavorCli::Llbc => LinkerFlavor::Llbc,
215+
LinkerFlavorCli::Wild => LinkerFlavor::Wild,
211216

212217
// Below: legacy stable values
213218
LinkerFlavorCli::Gcc => match lld_flavor {
@@ -247,6 +252,7 @@ impl LinkerFlavor {
247252
LinkerFlavor::EmCc => LinkerFlavorCli::Em,
248253
LinkerFlavor::Bpf => LinkerFlavorCli::Bpf,
249254
LinkerFlavor::Llbc => LinkerFlavorCli::Llbc,
255+
LinkerFlavor::Wild => LinkerFlavorCli::Wild,
250256
}
251257
}
252258

@@ -261,6 +267,7 @@ impl LinkerFlavor {
261267
LinkerFlavor::EmCc => LinkerFlavorCli::EmCc,
262268
LinkerFlavor::Bpf => LinkerFlavorCli::Bpf,
263269
LinkerFlavor::Llbc => LinkerFlavorCli::Llbc,
270+
LinkerFlavor::Wild => LinkerFlavorCli::Wild,
264271
}
265272
}
266273

@@ -275,6 +282,7 @@ impl LinkerFlavor {
275282
LinkerFlavorCli::EmCc => (Some(Cc::Yes), Some(Lld::Yes)),
276283
LinkerFlavorCli::Bpf => (None, None),
277284
LinkerFlavorCli::Llbc => (None, None),
285+
LinkerFlavorCli::Wild => (None, None),
278286

279287
// Below: legacy stable values
280288
LinkerFlavorCli::Gcc => (Some(Cc::Yes), None),
@@ -293,6 +301,8 @@ impl LinkerFlavor {
293301

294302
if stem == "llvm-bitcode-linker" {
295303
Ok(Self::Llbc)
304+
} else if stem == "wild" {
305+
Ok(Self::Wild)
296306
} else if stem == "emcc" // GCC/Clang can have an optional target prefix.
297307
|| stem == "gcc"
298308
|| stem.ends_with("-gcc")
@@ -330,7 +340,9 @@ impl LinkerFlavor {
330340
LinkerFlavor::WasmLld(cc) => LinkerFlavor::WasmLld(cc_hint.unwrap_or(cc)),
331341
LinkerFlavor::Unix(cc) => LinkerFlavor::Unix(cc_hint.unwrap_or(cc)),
332342
LinkerFlavor::Msvc(lld) => LinkerFlavor::Msvc(lld_hint.unwrap_or(lld)),
333-
LinkerFlavor::EmCc | LinkerFlavor::Bpf | LinkerFlavor::Llbc => self,
343+
LinkerFlavor::EmCc | LinkerFlavor::Bpf | LinkerFlavor::Llbc | LinkerFlavor::Wild => {
344+
self
345+
}
334346
}
335347
}
336348

@@ -357,7 +369,8 @@ impl LinkerFlavor {
357369
| (LinkerFlavor::Msvc(..), LinkerFlavorCli::Msvc(..))
358370
| (LinkerFlavor::EmCc, LinkerFlavorCli::EmCc)
359371
| (LinkerFlavor::Bpf, LinkerFlavorCli::Bpf)
360-
| (LinkerFlavor::Llbc, LinkerFlavorCli::Llbc) => return true,
372+
| (LinkerFlavor::Llbc, LinkerFlavorCli::Llbc)
373+
| (LinkerFlavor::Wild, LinkerFlavorCli::Wild) => return true,
361374
_ => {}
362375
}
363376

@@ -380,7 +393,8 @@ impl LinkerFlavor {
380393
| LinkerFlavor::Unix(..)
381394
| LinkerFlavor::EmCc
382395
| LinkerFlavor::Bpf
383-
| LinkerFlavor::Llbc => LldFlavor::Ld,
396+
| LinkerFlavor::Llbc
397+
| LinkerFlavor::Wild => LldFlavor::Ld,
384398
LinkerFlavor::Darwin(..) => LldFlavor::Ld64,
385399
LinkerFlavor::WasmLld(..) => LldFlavor::Wasm,
386400
LinkerFlavor::Msvc(..) => LldFlavor::Link,
@@ -405,7 +419,8 @@ impl LinkerFlavor {
405419
| LinkerFlavor::Msvc(_)
406420
| LinkerFlavor::Unix(_)
407421
| LinkerFlavor::Bpf
408-
| LinkerFlavor::Llbc => false,
422+
| LinkerFlavor::Llbc
423+
| LinkerFlavor::Wild => false,
409424
}
410425
}
411426

@@ -417,7 +432,8 @@ impl LinkerFlavor {
417432
| LinkerFlavor::Darwin(Cc::Yes, _)
418433
| LinkerFlavor::WasmLld(Cc::Yes)
419434
| LinkerFlavor::Unix(Cc::Yes)
420-
| LinkerFlavor::EmCc => true,
435+
| LinkerFlavor::EmCc
436+
| LinkerFlavor::Wild => true,
421437
LinkerFlavor::Gnu(..)
422438
| LinkerFlavor::Darwin(..)
423439
| LinkerFlavor::WasmLld(_)
@@ -500,6 +516,7 @@ linker_flavor_cli_impls! {
500516
(LinkerFlavorCli::EmCc) "em-cc"
501517
(LinkerFlavorCli::Bpf) "bpf"
502518
(LinkerFlavorCli::Llbc) "llbc"
519+
(LinkerFlavorCli::Wild) "wild"
503520

504521
// Legacy stable flavors
505522
(LinkerFlavorCli::Gcc) "gcc"
@@ -2762,6 +2779,7 @@ fn add_link_args_iter(
27622779
assert_eq!(lld, Lld::No);
27632780
insert(LinkerFlavor::Msvc(Lld::Yes));
27642781
}
2782+
LinkerFlavor::Wild => insert(LinkerFlavor::Wild),
27652783
LinkerFlavor::WasmLld(..)
27662784
| LinkerFlavor::Unix(..)
27672785
| LinkerFlavor::EmCc
@@ -3157,6 +3175,7 @@ impl Target {
31573175
LinkerFlavor::EmCc | LinkerFlavor::Bpf | LinkerFlavor::Llbc => {
31583176
check_eq!(flavor, self.linker_flavor, "mixing different linker flavors")
31593177
}
3178+
LinkerFlavor::Wild => todo!(),
31603179
}
31613180

31623181
// 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
@@ -22,6 +22,15 @@ pub(crate) fn target() -> Target {
2222
base.supports_fentry = true;
2323
base.supports_xray = true;
2424

25+
// When we're asked to use the `rust-lld` linker by default, set the appropriate lld-using
26+
// linker flavor, and self-contained linker component.
27+
if option_env!("CFG_USE_SELF_CONTAINED_LINKER").is_some() {
28+
base.linker_flavor = LinkerFlavor::Gnu(Cc::Yes, Lld::Yes);
29+
base.link_self_contained = crate::spec::LinkSelfContainedDefault::with_linker();
30+
}
31+
32+
base.linker_flavor = LinkerFlavor::Wild;
33+
2534
Target {
2635
llvm_target: "x86_64-unknown-linux-gnu".into(),
2736
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
self, Builder, Cargo, CommandLineStep, Kind, RunConfig, ShouldRun, Step, StepMetadata,
@@ -2485,6 +2487,15 @@ impl CommandLineStep for Assemble {
24852487
copy_lld_artifacts(builder, lld_wrapper, target_compiler);
24862488
}
24872489

2490+
if builder.host_target.triple == "x86_64-unknown-linux-gnu" {
2491+
let wild_wrapper =
2492+
builder.ensure(crate::core::build_steps::tool::WildLinker::for_use_by_compiler(
2493+
builder,
2494+
target_compiler,
2495+
));
2496+
copy_wild_artifacts(builder, wild_wrapper, target_compiler);
2497+
}
2498+
24882499
if builder.config.llvm_enabled(target_compiler.host) && builder.config.llvm_tools_enabled {
24892500
debug!(
24902501
"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
@@ -608,6 +608,33 @@ impl CommandLineStep for Rustc {
608608
}
609609
}
610610

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

0 commit comments

Comments
 (0)