Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ members = [
"src/tools/unicode-table-generator",
"src/tools/unstable-book-gen",
"src/tools/wasm-component-ld",
# "src/tools/wild-linker",
"src/tools/x",
# tidy-alphabetical-end
]
Expand All @@ -53,6 +54,7 @@ exclude = [
"build",
"compiler/rustc_codegen_cranelift",
"compiler/rustc_codegen_gcc",
"src/tools/wild-linker",
"src/bootstrap",
"tests/rustdoc-gui",
# HACK(eddyb) This hardcodes the fact that our CI uses `/checkout/obj`.
Expand Down Expand Up @@ -92,4 +94,3 @@ codegen-units = 1
# If you want to use a crate with local modifications, you can set a path or git dependency here.
# For git dependencies, also add your source to ALLOWED_SOURCES in src/tools/tidy/src/extdeps.rs.
#[patch.crates-io]

60 changes: 59 additions & 1 deletion compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1326,7 +1326,8 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
LinkerFlavor::Gnu(Cc::Yes, _)
| LinkerFlavor::Darwin(Cc::Yes, _)
| LinkerFlavor::WasmLld(Cc::Yes)
| LinkerFlavor::Unix(Cc::Yes) => {
| LinkerFlavor::Unix(Cc::Yes)
| LinkerFlavor::Wild => {
if cfg!(any(target_os = "solaris", target_os = "illumos")) {
// On historical Solaris systems, "cc" may have
// been Sun Studio, which is not flag-compatible
Expand Down Expand Up @@ -1366,6 +1367,8 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
});
let flavor = sess.target.linker_flavor.with_linker_hints(stem);
let flavor = adjust_flavor_to_features(flavor, features);
let linker =
if flavor == LinkerFlavor::Wild { PathBuf::from("cc") } else { linker };
Some((linker, flavor))
}
(None, None) => None,
Expand Down Expand Up @@ -2482,6 +2485,8 @@ fn add_order_independent_options(
// Take care of the flavors and CLI options requesting the `lld` linker.
add_lld_args(cmd, sess, flavor, self_contained_components);

add_wild_args(cmd, sess, flavor, self_contained_components);

add_apple_link_args(cmd, sess, flavor);

let apple_sdk_root = add_apple_sdk(cmd, sess, flavor);
Expand Down Expand Up @@ -3403,6 +3408,59 @@ fn add_lld_args(
}
}

fn add_wild_args(
cmd: &mut dyn Linker,
sess: &Session,
flavor: LinkerFlavor,
self_contained_components: LinkSelfContainedComponents,
) {
// Either Wild or LLD to make it work with CI
if flavor != LinkerFlavor::Wild || std::env::var_os("BUILDING_RUSTC").is_some() {
let self_contained_cli = sess.opts.cg.link_self_contained.is_linker_enabled();
let self_contained_target = self_contained_components.is_linker_enabled();

let self_contained_linker = self_contained_cli || self_contained_target;
if self_contained_linker && !sess.opts.cg.link_self_contained.is_linker_disabled() {
let mut linker_path_exists = false;
for path in sess.get_tools_search_paths(false) {
let linker_path = path.join("gcc-ld");
linker_path_exists |= linker_path.exists();
cmd.cc_arg({
let mut arg = OsString::from("-B");
arg.push(linker_path);
arg
});
}
if !linker_path_exists {
sess.dcx().emit_fatal(errors::SelfContainedLinkerMissing);
}
}

if !sess.target.is_like_wasm {
cmd.cc_arg("-fuse-ld=lld");
}
return ();
}

let mut linker_path_exists = false;
for path in sess.get_tools_search_paths(false) {
let linker_path = path.join("wild-gcc-ld");
linker_path_exists |= linker_path.exists();
cmd.cc_arg({
let mut arg = OsString::from("-B");
arg.push(linker_path);
arg
});
cmd.cc_arg("-Wl,--threads=8");
// cmd.cc_arg("-Wl,--no-fork");
}
if !linker_path_exists {
// As a sanity check, we emit an error if none of these paths exist: we want
// self-contained linking and have no linker.
sess.dcx().emit_fatal(errors::SelfContainedLinkerMissing);
}
}

// gold has been deprecated with binutils 2.44
// and is known to behave incorrectly around Rust programs.
// There have been reports of being unable to bootstrap with gold:
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,15 @@ pub(crate) fn get_linker<'a>(
LinkerFlavor::Bpf => Box::new(BpfLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::Llbc => Box::new(LlbcLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::Ptx => Box::new(PtxLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::Wild => Box::new(GccLinker {
cmd,
sess,
target_cpu,
hinted_static: None,
is_ld: false,
is_gnu: true,
uses_lld: flavor.uses_lld(),
}),
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,7 @@ mod desc {
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) \
components: `crto`, `libc`, `unwind`, `linker`, `sanitizers`, `mingw`";
pub(crate) const parse_linker_features: &str =
"a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld`";
"a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld`, `wild`";
pub(crate) const parse_polonius: &str = "either no value or `legacy` (the default), or `next`";
pub(crate) const parse_stack_protector: &str =
"one of (`none` (default), `basic`, `strong`, or `all`)";
Expand Down
31 changes: 26 additions & 5 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@
/// Emscripten Compiler Frontend, a wrapper around `WasmLld(Cc::Yes)` that has a different
/// interface and produces some additional JavaScript output.
EmCc,
// TODO: This needs some design on how to proceed
Wild,

Check failure on line 131 in compiler/rustc_target/src/spec/mod.rs

View workflow job for this annotation

GitHub Actions / PR - tidy

TODO is used for tasks that should be done before merging a PR; If you want to leave a message in the codebase use FIXME

Check failure on line 131 in compiler/rustc_target/src/spec/mod.rs

View workflow job for this annotation

GitHub Actions / PR - aarch64-gnu-llvm-19-2

TODO is used for tasks that should be done before merging a PR; If you want to leave a message in the codebase use FIXME
// Below: other linker-like tools with unique interfaces for exotic targets.
/// Linker tool for BPF.
Bpf,
Expand All @@ -153,6 +155,7 @@
Bpf,
Ptx,
Llbc,
Wild,

// Legacy stable values
Gcc,
Expand All @@ -178,7 +181,8 @@
| LinkerFlavorCli::Ld
| LinkerFlavorCli::Lld(..)
| LinkerFlavorCli::Msvc(Lld::No)
| LinkerFlavorCli::Em => false,
| LinkerFlavorCli::Em
| LinkerFlavorCli::Wild => false,
}
}
}
Expand Down Expand Up @@ -245,6 +249,7 @@
LinkerFlavorCli::Bpf => LinkerFlavor::Bpf,
LinkerFlavorCli::Llbc => LinkerFlavor::Llbc,
LinkerFlavorCli::Ptx => LinkerFlavor::Ptx,
LinkerFlavorCli::Wild => LinkerFlavor::Wild,

// Below: legacy stable values
LinkerFlavorCli::Gcc => match lld_flavor {
Expand Down Expand Up @@ -285,6 +290,7 @@
LinkerFlavor::Bpf => LinkerFlavorCli::Bpf,
LinkerFlavor::Llbc => LinkerFlavorCli::Llbc,
LinkerFlavor::Ptx => LinkerFlavorCli::Ptx,
LinkerFlavor::Wild => LinkerFlavorCli::Wild,
}
}

Expand All @@ -300,6 +306,7 @@
LinkerFlavor::Bpf => LinkerFlavorCli::Bpf,
LinkerFlavor::Llbc => LinkerFlavorCli::Llbc,
LinkerFlavor::Ptx => LinkerFlavorCli::Ptx,
LinkerFlavor::Wild => LinkerFlavorCli::Wild,
}
}

Expand All @@ -314,6 +321,7 @@
LinkerFlavorCli::EmCc => (Some(Cc::Yes), Some(Lld::Yes)),
LinkerFlavorCli::Bpf | LinkerFlavorCli::Ptx => (None, None),
LinkerFlavorCli::Llbc => (None, None),
LinkerFlavorCli::Wild => (None, None),

// Below: legacy stable values
LinkerFlavorCli::Gcc => (Some(Cc::Yes), None),
Expand All @@ -332,6 +340,8 @@

if stem == "llvm-bitcode-linker" {
Ok(Self::Llbc)
} else if stem == "wild" {
Ok(Self::Wild)
} else if stem == "emcc" // GCC/Clang can have an optional target prefix.
|| stem == "gcc"
|| stem.ends_with("-gcc")
Expand Down Expand Up @@ -369,7 +379,11 @@
LinkerFlavor::WasmLld(cc) => LinkerFlavor::WasmLld(cc_hint.unwrap_or(cc)),
LinkerFlavor::Unix(cc) => LinkerFlavor::Unix(cc_hint.unwrap_or(cc)),
LinkerFlavor::Msvc(lld) => LinkerFlavor::Msvc(lld_hint.unwrap_or(lld)),
LinkerFlavor::EmCc | LinkerFlavor::Bpf | LinkerFlavor::Llbc | LinkerFlavor::Ptx => self,
LinkerFlavor::EmCc
| LinkerFlavor::Bpf
| LinkerFlavor::Llbc
| LinkerFlavor::Ptx
| LinkerFlavor::Wild => self,
}
}

Expand Down Expand Up @@ -397,7 +411,8 @@
| (LinkerFlavor::EmCc, LinkerFlavorCli::EmCc)
| (LinkerFlavor::Bpf, LinkerFlavorCli::Bpf)
| (LinkerFlavor::Llbc, LinkerFlavorCli::Llbc)
| (LinkerFlavor::Ptx, LinkerFlavorCli::Ptx) => return true,
| (LinkerFlavor::Ptx, LinkerFlavorCli::Ptx)
| (LinkerFlavor::Wild, LinkerFlavorCli::Wild) => return true,
// 2. The linker flavor is independent of target and compatible
(LinkerFlavor::Ptx, LinkerFlavorCli::Llbc) => return true,
_ => {}
Expand Down Expand Up @@ -427,6 +442,7 @@
LinkerFlavor::Darwin(..) => LldFlavor::Ld64,
LinkerFlavor::WasmLld(..) => LldFlavor::Wasm,
LinkerFlavor::Msvc(..) => LldFlavor::Link,
LinkerFlavor::Wild => todo!(),
}
}

Expand All @@ -449,7 +465,8 @@
| LinkerFlavor::Unix(_)
| LinkerFlavor::Bpf
| LinkerFlavor::Llbc
| LinkerFlavor::Ptx => false,
| LinkerFlavor::Ptx
| LinkerFlavor::Wild => false,
}
}

Expand All @@ -461,7 +478,8 @@
| LinkerFlavor::Darwin(Cc::Yes, _)
| LinkerFlavor::WasmLld(Cc::Yes)
| LinkerFlavor::Unix(Cc::Yes)
| LinkerFlavor::EmCc => true,
| LinkerFlavor::EmCc
| LinkerFlavor::Wild => true,
LinkerFlavor::Gnu(..)
| LinkerFlavor::Darwin(..)
| LinkerFlavor::WasmLld(_)
Expand Down Expand Up @@ -546,6 +564,7 @@
(LinkerFlavorCli::Bpf) "bpf"
(LinkerFlavorCli::Llbc) "llbc"
(LinkerFlavorCli::Ptx) "ptx"
(LinkerFlavorCli::Wild) "wild"

// Legacy stable flavors
(LinkerFlavorCli::Gcc) "gcc"
Expand Down Expand Up @@ -2847,6 +2866,7 @@
assert_eq!(lld, Lld::No);
insert(LinkerFlavor::Msvc(Lld::Yes));
}
LinkerFlavor::Wild => insert(LinkerFlavor::Wild),
LinkerFlavor::WasmLld(..)
| LinkerFlavor::Unix(..)
| LinkerFlavor::EmCc
Expand Down Expand Up @@ -3237,6 +3257,7 @@
| LinkerFlavor::Llbc => {
check_eq!(flavor, self.linker_flavor, "mixing different linker flavors")
}
LinkerFlavor::Wild => todo!(),
}

// Check that link args for cc and non-cc versions of flavors are consistent.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ pub(crate) fn target() -> Target {
base.link_self_contained = crate::spec::LinkSelfContainedDefault::with_linker();
}

base.linker_flavor = LinkerFlavor::Wild;

Target {
llvm_target: "x86_64-unknown-linux-gnu".into(),
metadata: TargetMetadata {
Expand Down
13 changes: 12 additions & 1 deletion src/bootstrap/src/core/build_steps/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ use serde_derive::Deserialize;
use tracing::span;

use crate::core::build_steps::gcc::{Gcc, GccOutput, add_cg_gcc_cargo_flags};
use crate::core::build_steps::tool::{RustcPrivateCompilers, SourceType, copy_lld_artifacts};
use crate::core::build_steps::tool::{
RustcPrivateCompilers, SourceType, copy_lld_artifacts, copy_wild_artifacts,
};
use crate::core::build_steps::{dist, llvm};
use crate::core::builder;
use crate::core::builder::{
Expand Down Expand Up @@ -2315,6 +2317,15 @@ impl Step for Assemble {
copy_lld_artifacts(builder, lld_wrapper, target_compiler);
}

if builder.host_target.triple == "x86_64-unknown-linux-gnu" {
let wild_wrapper =
builder.ensure(crate::core::build_steps::tool::WildLinker::for_use_by_compiler(
builder,
target_compiler,
));
copy_wild_artifacts(builder, wild_wrapper, target_compiler);
}

if builder.config.llvm_enabled(target_compiler.host) && builder.config.llvm_tools_enabled {
debug!(
"llvm and llvm tools enabled; copying `llvm-objcopy` as `rust-objcopy` to \
Expand Down
27 changes: 27 additions & 0 deletions src/bootstrap/src/core/build_steps/dist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,33 @@ impl Step for Rustc {
}
}

if builder.host_target.triple == "x86_64-unknown-linux-gnu" {
let src_dir = builder.sysroot_target_bindir(target_compiler, target);
let rust_wild = exe("rust-wild", target_compiler.host);
builder.copy_link(
&src_dir.join(&rust_wild),
&dst_dir.join(&rust_wild),
FileType::Executable,
);
let self_contained_wild_src_dir = src_dir.join("wild-gcc-ld");
let self_contained_wild_dst_dir = dst_dir.join("wild-gcc-ld");
t!(fs::create_dir(&self_contained_wild_dst_dir));
let wild_name = "wild";
let exe_name = exe(wild_name, target_compiler.host);
builder.copy_link(
&self_contained_wild_src_dir.join(&exe_name),
&self_contained_wild_dst_dir.join(&exe_name),
FileType::Executable,
);
// Pretend Wild is LD so the compiler can pick it up
let exe_name = exe("ld", target_compiler.host);
builder.copy_link(
&self_contained_wild_src_dir.join(&exe_name),
&self_contained_wild_dst_dir.join(&exe_name),
FileType::Executable,
);
}

if builder.config.llvm_enabled(target_compiler.host)
&& builder.config.llvm_tools_enabled
{
Expand Down
Loading
Loading