From 3c0803667816f03f894c5cd44391a1f677c48672 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 25 Apr 2022 19:16:54 +0200 Subject: [PATCH 01/12] add dedicated `-C linker-flavor` structures --- compiler/rustc_session/src/config.rs | 56 ++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 55307b9cebb70..64b6e107f0c1d 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -199,6 +199,62 @@ impl LinkerPluginLto { } } +/// The possible values `-C linker-flavor` can take: either one of the well-known linker flavors, or +/// an enrichment to one of them, for example representing additional arguments to its principal +/// linker flavor. +/// +/// This a surface enum for the CLI syntax, so that target specs don't have to deal with the +/// specifics of the CLI: they will always use the well-known principal linker flavor via the +/// `to_flavor` method, and never the enrichment variants. +/// +/// Currently used to represent finer-grained uses of `gcc`, to improve ease-of-use for wrapping a +/// given linker like `lld`, `gold` or `mold`. +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub enum LinkerFlavorCli { + /// When the CLI option is one of the well-known linker-flavors that don't need special + /// handling. + WellKnown(LinkerFlavor), + + /// Enrichments to the `LinkerFlavor::Gcc` flavor, to specify the linker via `-fuse-ld` + Gcc { use_ld: String }, +} + +impl LinkerFlavorCli { + /// Returns the principal linker flavor that this CLI option represents. + pub fn to_flavor(&self) -> LinkerFlavor { + match *self { + LinkerFlavorCli::WellKnown(flavor) => flavor, + LinkerFlavorCli::Gcc { .. } => LinkerFlavor::Gcc, + } + } +} + +/// Parses a `-C linker-flavor` option +impl FromStr for LinkerFlavorCli { + type Err = (); + + fn from_str(s: &str) -> Result { + // If the value is one of the existing flavor mappings, return that. + if let Some(flavor) = LinkerFlavor::from_str(s) { + return Ok(LinkerFlavorCli::WellKnown(flavor)); + } + + // Otherwise, it should be the enrichments to the gcc/cc flavor: wrapping a given linker + // separated by a colon like `gcc:lld`. + let parts: Vec<_> = s.split("gcc:").collect(); + if parts.len() != 2 { + return Err(()); + } + + let wrapped_linker = parts[1]; + if !wrapped_linker.is_empty() { + Ok(LinkerFlavorCli::Gcc { use_ld: wrapped_linker.to_string() }) + } else { + Err(()) + } + } +} + /// The different settings that can be enabled via the `-Z location-detail` flag. #[derive(Clone, PartialEq, Hash, Debug)] pub struct LocationDetail { From 8ef3d5bed803b93ba3a467119f68d5d4809f23ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 25 Apr 2022 19:26:23 +0200 Subject: [PATCH 02/12] add tests for `LinkerFlavorCli` options parsing --- compiler/rustc_session/src/lib.rs | 3 ++ compiler/rustc_session/src/tests.rs | 55 +++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 compiler/rustc_session/src/tests.rs diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 44cf504864254..0f727750d4815 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -34,6 +34,9 @@ pub mod output; pub use getopts; +#[cfg(test)] +mod tests; + /// Requirements for a `StableHashingContext` to be used in this crate. /// This is a hack to allow using the `HashStable_Generic` derive macro /// instead of implementing everything in `rustc_middle`. diff --git a/compiler/rustc_session/src/tests.rs b/compiler/rustc_session/src/tests.rs new file mode 100644 index 0000000000000..ab15d7393de9c --- /dev/null +++ b/compiler/rustc_session/src/tests.rs @@ -0,0 +1,55 @@ +use std::str::FromStr; + +use crate::config::*; +use rustc_target::spec::{LinkerFlavor, LldFlavor}; + +/// When adding enrichments to `-C linker-flavor`, we want to ensure the existing `rustc_target` +/// `LinkerFlavor`s are still supported as-is: they are option values that can be used on +/// stable. +#[test] +pub fn parse_well_known_linker_flavor() { + // All `LinkerFlavor`s are wrapped as a whole, so there's no particular need to be + // exhaustive here. + assert_eq!(LinkerFlavorCli::from_str("gcc"), Ok(LinkerFlavorCli::WellKnown(LinkerFlavor::Gcc))); + assert_eq!( + LinkerFlavorCli::from_str("msvc"), + Ok(LinkerFlavorCli::WellKnown(LinkerFlavor::Msvc)) + ); + assert_eq!( + LinkerFlavorCli::from_str("bpf-linker"), + Ok(LinkerFlavorCli::WellKnown(LinkerFlavor::BpfLinker)) + ); + assert_eq!( + LinkerFlavorCli::from_str("lld-link"), + Ok(LinkerFlavorCli::WellKnown(LinkerFlavor::Lld(LldFlavor::Link))) + ); + assert_eq!( + LinkerFlavorCli::from_str("ld64.lld"), + Ok(LinkerFlavorCli::WellKnown(LinkerFlavor::Lld(LldFlavor::Ld64))) + ); + + // While other invalid values for well-known flavors are already errors + assert_eq!(LinkerFlavorCli::from_str("unknown_linker"), Err(())); +} + +/// Enrichments can currently allow for the `gcc` flavor to specify for a given linker to be +/// used, much like you'd use `-fuse-ld` as a link arg. When using `-C +/// linker-flavor=gcc:$linker`, the `$linker` will be passed directly to `cc`. +#[test] +pub fn parse_gcc_enrichment_linker_flavor() { + assert_eq!( + LinkerFlavorCli::from_str("gcc:lld"), + Ok(LinkerFlavorCli::Gcc { use_ld: "lld".to_string() }) + ); + assert_eq!( + LinkerFlavorCli::from_str("gcc:gold"), + Ok(LinkerFlavorCli::Gcc { use_ld: "gold".to_string() }) + ); + + // No linker actually mentioned + assert_eq!(LinkerFlavorCli::from_str("gcc:"), Err(())); + + // Only one `gcc:` separator allowed + assert_eq!(LinkerFlavorCli::from_str("gcc:gcc:"), Err(())); + assert_eq!(LinkerFlavorCli::from_str("gcc:gcc:linker"), Err(())); +} From cc5ac27df7c09148a64ede862d636df9bd4631b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 25 Apr 2022 20:15:53 +0200 Subject: [PATCH 03/12] use `LinkerFlavorCli` for `-C linker-flavor` --- compiler/rustc_codegen_ssa/src/back/link.rs | 12 ++++++++---- compiler/rustc_interface/src/tests.rs | 3 ++- compiler/rustc_session/src/config.rs | 2 +- compiler/rustc_session/src/options.rs | 12 +++++++----- compiler/rustc_target/src/spec/mod.rs | 4 ++++ 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 878a670cba3ef..b61b5996784d4 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1130,7 +1130,7 @@ pub fn ignored_for_lto(sess: &Session, info: &CrateInfo, cnum: CrateNum) -> bool && (info.compiler_builtins == Some(cnum) || info.is_no_builtins.contains(&cnum)) } -// This functions tries to determine the appropriate linker (and corresponding LinkerFlavor) to use +/// This function tries to determine the appropriate linker (and corresponding LinkerFlavor) to use pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { fn infer_from( sess: &Session, @@ -1203,9 +1203,13 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { } } - // linker and linker flavor specified via command line have precedence over what the target - // specification specifies - if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), sess.opts.cg.linker_flavor) { + // Lower the potential `-C linker-flavor` CLI flag to its principal linker-flavor + let linker_flavor = + sess.opts.cg.linker_flavor.as_ref().map(|surface_flavor| surface_flavor.to_flavor()); + + // The `-C linker` and `-C linker-flavor` CLI flags have higher priority than what the target + // specification declares. + if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), linker_flavor) { return ret; } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index d07e17f679251..e7dd70f40627b 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -3,6 +3,7 @@ use crate::interface::parse_cfgspecs; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig}; use rustc_session::config::InstrumentCoverage; +use rustc_session::config::LinkerFlavorCli; use rustc_session::config::Strip; use rustc_session::config::{build_configuration, build_session_options, to_crate_config}; use rustc_session::config::{ @@ -551,7 +552,7 @@ fn test_codegen_options_tracking_hash() { untracked!(link_args, vec![String::from("abc"), String::from("def")]); untracked!(link_self_contained, Some(true)); untracked!(linker, Some(PathBuf::from("linker"))); - untracked!(linker_flavor, Some(LinkerFlavor::Gcc)); + untracked!(linker_flavor, Some(LinkerFlavorCli::WellKnown(LinkerFlavor::Gcc))); untracked!(no_stack_check, true); untracked!(remark, Passes::Some(vec![String::from("pass1"), String::from("pass2")])); untracked!(rpath, true); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 64b6e107f0c1d..a26c241bfc3f1 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2432,7 +2432,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { } } - if cg.linker_flavor == Some(LinkerFlavor::L4Bender) + if cg.linker_flavor == Some(LinkerFlavorCli::WellKnown(LinkerFlavor::L4Bender)) && !nightly_options::is_unstable_enabled(matches) { early_error( diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 1b583417ca089..62ffeff5e90a0 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -5,7 +5,7 @@ use crate::lint; use crate::search_paths::SearchPath; use crate::utils::NativeLib; use rustc_errors::LanguageIdentifier; -use rustc_target::spec::{CodeModel, LinkerFlavor, MergeFunctions, PanicStrategy, SanitizerSet}; +use rustc_target::spec::{CodeModel, MergeFunctions, PanicStrategy, SanitizerSet}; use rustc_target::spec::{ RelocModel, RelroLevel, SplitDebuginfo, StackProtector, TargetTriple, TlsModel, }; @@ -383,7 +383,9 @@ mod desc { "either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`"; pub const parse_cfprotection: &str = "`none`|`no`|`n` (default), `branch`, `return`, or `full`|`yes`|`y` (equivalent to `branch` and `return`)"; pub const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`"; - pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavor::one_of(); + pub const parse_linker_flavor: &str = "one of: `em`, `gcc`, `l4-bender`, `ld`, `msvc`, \ + `ptx-linker`, `bpf-linker`, `wasm-ld`, `ld64.lld`, `ld.lld`, `lld-link`, \ + or a `gcc:`-prefixed linker to use with the gcc flavor, like `gcc:lld` or `gcc:gold,`"; pub const parse_optimization_fuel: &str = "crate=integer"; pub const parse_mir_spanview: &str = "`statement` (default), `terminator`, or `block`"; pub const parse_instrument_coverage: &str = @@ -760,8 +762,8 @@ mod parse { true } - pub(crate) fn parse_linker_flavor(slot: &mut Option, v: Option<&str>) -> bool { - match v.and_then(LinkerFlavor::from_str) { + pub(crate) fn parse_linker_flavor(slot: &mut Option, v: Option<&str>) -> bool { + match v.and_then(|s| LinkerFlavorCli::from_str(s).ok()) { Some(lf) => *slot = Some(lf), _ => return false, } @@ -1120,7 +1122,7 @@ options! { on C toolchain installed in the system"), linker: Option = (None, parse_opt_pathbuf, [UNTRACKED], "system linker to link outputs with"), - linker_flavor: Option = (None, parse_linker_flavor, [UNTRACKED], + linker_flavor: Option = (None, parse_linker_flavor, [UNTRACKED], "linker flavor"), linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled, parse_linker_plugin_lto, [TRACKED], diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index f7abeafd38f10..4ae57e7627a88 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -165,6 +165,10 @@ macro_rules! flavor_mappings { ) } +// Note: until string concatenation can be done in const contexts, remember to update the +// `parse_linker_flavor` error message in rustc_session/src/options.rs whenever adding a new allowed +// value here, since it also mentions enriched CLI-allowed values like `gcc:lld` that are then +// lowered to these target specs `LinkerFlavor`s. flavor_mappings! { ((LinkerFlavor::Em), "em"), ((LinkerFlavor::Gcc), "gcc"), From 045cb0aacdaa64bb4e60f6fc9676289678003daf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 25 Apr 2022 20:26:21 +0200 Subject: [PATCH 04/12] implement linker-flavor enrichments for MCP --- compiler/rustc_codegen_ssa/src/back/link.rs | 132 ++++++++++++++++---- compiler/rustc_session/src/options.rs | 2 +- 2 files changed, 109 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index b61b5996784d4..fe891b498c027 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -9,7 +9,7 @@ use rustc_hir::def_id::CrateNum; use rustc_metadata::fs::{emit_metadata, METADATA_FILENAME}; use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::middle::exported_symbols::SymbolExportKind; -use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Strip}; +use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, LinkerFlavorCli, Strip}; use rustc_session::config::{OutputFilenames, OutputType, PrintRequest, SplitDwarfKind}; use rustc_session::cstore::DllImport; use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename}; @@ -17,7 +17,7 @@ use rustc_session::search_paths::PathKind; use rustc_session::utils::NativeLibKind; /// For all the linkers we support, and information they might /// need out of the shared crate context before we get rid of it. -use rustc_session::{filesearch, Session}; +use rustc_session::{config::InstrumentCoverage, filesearch, Session}; use rustc_span::symbol::Symbol; use rustc_span::DebuggerVisualizerFile; use rustc_target::spec::crt_objects::{CrtObjects, CrtObjectsFallback}; @@ -2016,7 +2016,7 @@ fn add_order_independent_options( out_filename: &Path, tmpdir: &Path, ) { - add_gcc_ld_path(cmd, sess, flavor); + handle_cli_linker_flavors(cmd, sess, flavor, crt_objects_fallback); add_apple_sdk(cmd, sess, flavor); @@ -2694,29 +2694,113 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result { } } -fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { - if let Some(ld_impl) = sess.opts.unstable_opts.gcc_ld { - if let LinkerFlavor::Gcc = flavor { - match ld_impl { - LdImpl::Lld => { - let tools_path = sess.get_tools_search_paths(false); - let gcc_ld_dir = tools_path - .into_iter() - .map(|p| p.join("gcc-ld")) - .find(|p| { - p.join(if sess.host.is_like_windows { "ld.exe" } else { "ld" }).exists() - }) - .unwrap_or_else(|| sess.fatal("rust-lld (as ld) not found")); - cmd.arg({ - let mut arg = OsString::from("-B"); - arg.push(gcc_ld_dir); - arg - }); - cmd.arg(format!("-Wl,-rustc-lld-flavor={}", sess.target.lld_flavor.as_str())); - } +/// This takes care of the various possible enrichments to the linking that can be requested on the +/// CLI (and emitting errors and warnings when applicable): +/// - shortcuts to `-fuse-ld` with the `gcc` flavor +/// - the unstable `-Zgcc-ld=lld` flag to use `rust-lld`, stabilized as the following item +fn handle_cli_linker_flavors( + cmd: &mut dyn Linker, + sess: &Session, + flavor: LinkerFlavor, + crt_objects_fallback: bool, +) { + let unstable_gcc_lld = sess.opts.unstable_opts.gcc_ld == Some(LdImpl::Lld); + if unstable_gcc_lld { + // Sanity check: ensure `gcc` is the currently selected flavor. + if LinkerFlavor::Gcc != flavor { + sess.fatal("`-Zgcc-ld` is used even though the linker flavor is not `gcc`"); + } + } + + let cg = &sess.opts.cg; + + // The `-C linker-flavor` CLI flag can optionally enrich linker-flavors. Check whether that's + // applicable, and emit errors if sanity checks fail. There's currently only one enrichment: + // adding an argument to the `cc` invocation to use the `use_ld` given linker. + let use_ld = match &cg.linker_flavor { + Some(LinkerFlavorCli::Gcc { use_ld }) => { + // Ensure `gcc` is the currently selected flavor. Error out cleanly, as `-Zgcc-ld` does + // if that happens, but this should be unreachable. + if LinkerFlavor::Gcc != flavor { + sess.fatal( + "`-Clinker-flavor=gcc:*` flag is used even though the \ + linker flavor is not `gcc`", + ); + } + + use_ld + } + + // Note: exhaustive match arm here, to avoid fallthroughs if new linker-flavor enrichments + // are added in the future. + Some(LinkerFlavorCli::WellKnown(_)) | None => { + if unstable_gcc_lld { + "lld" + } else { + // We're not in a situation needing enrichments. + return; } + } + }; + + // From now on in this function, we handle the `gcc` linker-flavor enrichment. + + // Except for `lld`, the given linker executable will be passed straight to `-fuse-ld`. + if use_ld == "lld" { + // Start by checking if we're in the context of a known issue that users might hit when + // using `lld`: + // + // 1. when requesting self-contained CRT linking (or on a target that does it + // automatically), and coverage/profile generation: point at #79555 "Coverage is not + // generated when using rust-lld as linker" + let instrument_coverage = cg.instrument_coverage.is_some() + && cg.instrument_coverage != Some(InstrumentCoverage::Off); + let generate_profile = cg.profile_generate.enabled(); + if crt_objects_fallback && (instrument_coverage || generate_profile) { + sess.warn( + "Using `lld`, self-contained linking, and coverage or profile generation has known \ + issues. See issue #79555 for more details, at \ + https://github.com/rust-lang/rust/issues/79555", + ); + } + + // 2. Maybe point at https://github.com/flamegraph-rs/flamegraph/pull/157 or the + // corresponding rust/LLVM issue when/if it's tracked, depending on whether we use the + // workaround argument `--no-rosegment` by default when invoking `lld`. + // + // 3. If in the future, other linker flavors and targets are eligible to a `rust-lld` + // enrichment, maybe also point at target-specific issues like: + // - MSVC + ThinLTO blocker https://github.com/rust-lang/rust/issues/81408 + // - the "lld on MSVC" tracking issue https://github.com/rust-lang/rust/issues/71520 + // containing a list of blocking issues + + // Now, handle `rust-lld`. If the `-Zgcc-ld=lld` flag was provided, we use `rust-lld`, the + // rustup-distributed version of `lld` (when applicable, i.e. not in distro-builds) by: + // - checking the `lld-wrapper`s exist in the sysroot + // - adding their folder as a search path, or requesting to use a wrapper directly + if unstable_gcc_lld { + // A `gcc-ld` folder (containing the `lld-wrapper`s that will run `rust-lld`) is present in + // the sysroot's target-specific tool binaries folder. + let tools_path = sess.get_tools_search_paths(false); + let gcc_ld_dir = tools_path + .into_iter() + .map(|p| p.join("gcc-ld")) + .find(|p| p.join(if sess.host.is_like_windows { "ld.exe" } else { "ld" }).exists()) + .unwrap_or_else(|| sess.fatal("rust-lld (as ld) not found")); + + cmd.arg({ + let mut arg = OsString::from("-B"); + arg.push(gcc_ld_dir); + arg + }); + cmd.arg(format!("-Wl,-rustc-lld-flavor={}", sess.target.lld_flavor.as_str())); } else { - sess.fatal("option `-Z gcc-ld` is used even though linker flavor is not gcc"); + // We were asked to use `lld` but not `rust-lld`. + cmd.arg("-fuse-ld=lld"); } + } else { + // Otherwise, we were just asked to use a linker executable, and it's expected that `cc` + // will find it on the $PATH. + cmd.arg(format!("-fuse-ld={}", use_ld)); } } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 62ffeff5e90a0..95d18e591febd 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1618,7 +1618,7 @@ pub enum WasiExecModel { Reactor, } -#[derive(Clone, Copy, Hash)] +#[derive(Clone, Copy, Hash, PartialEq)] pub enum LdImpl { Lld, } From 8d8081418f605a6b5865d300be573071b9c2af8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 25 Apr 2022 20:27:31 +0200 Subject: [PATCH 05/12] add sanity check about `-Zgcc-ld` and `-Clinker-flavor=gcc:*` --- compiler/rustc_session/src/config.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index a26c241bfc3f1..7f3fcf9a84156 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2442,6 +2442,18 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { ); } + // Until the unstable flag is removed, ensure `-Zgcc-ld=lld` and `-Clinker-flavor=gcc:lld` have + // a matching linker choice. + if let Some(LinkerFlavorCli::Gcc { use_ld }) = &cg.linker_flavor { + if use_ld != "lld" && unstable_opts.gcc_ld == Some(LdImpl::Lld) { + early_error( + error_format, + "`-Zgcc-ld=lld` and `-Clinker-flavor` differ in their \ + linker choice. The latter should be `-Clinker-flavor=gcc:lld`", + ); + } + } + let prints = collect_print_requests(&mut cg, &mut unstable_opts, matches, error_format); let cg = cg; From 877fa6b8172ed114984f7b4148bf2f698ff850d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Tue, 26 Apr 2022 23:45:23 +0200 Subject: [PATCH 06/12] require `-Z unstable-options` to use the new linker-flavor flag values only the stable values for `-Clinker-flavor` can be used on stable until we have more feedback on the interface --- compiler/rustc_session/src/config.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 7f3fcf9a84156..2af3fda09abda 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2442,9 +2442,19 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { ); } - // Until the unstable flag is removed, ensure `-Zgcc-ld=lld` and `-Clinker-flavor=gcc:lld` have - // a matching linker choice. if let Some(LinkerFlavorCli::Gcc { use_ld }) = &cg.linker_flavor { + // For testing purposes, until we have more feedback about these options: ensure `-Z + // unstable-options` is enabled when using the `gcc` linker flavor enrichments. + if !unstable_opts.unstable_options { + early_error( + error_format, + "the `gcc:*` linker flavor is unstable, the `-Z unstable-options` \ + flag must also be passed to use it", + ); + } + + // Until the unstable flag is removed, ensure `-Zgcc-ld=lld` and `-Clinker-flavor=gcc:lld` + // have a matching linker choice. if use_ld != "lld" && unstable_opts.gcc_ld == Some(LdImpl::Lld) { early_error( error_format, From 6e0bff9df14ddad5bddce496bc3e77ef65873d32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Wed, 27 Apr 2022 19:18:23 +0200 Subject: [PATCH 07/12] test warning about known issue 79555 with lld --- src/test/ui/linkers/mentions_issue_79555.rs | 11 +++++++++++ src/test/ui/linkers/mentions_issue_79555.stderr | 4 ++++ 2 files changed, 15 insertions(+) create mode 100644 src/test/ui/linkers/mentions_issue_79555.rs create mode 100644 src/test/ui/linkers/mentions_issue_79555.stderr diff --git a/src/test/ui/linkers/mentions_issue_79555.rs b/src/test/ui/linkers/mentions_issue_79555.rs new file mode 100644 index 0000000000000..aaefaca0c4cba --- /dev/null +++ b/src/test/ui/linkers/mentions_issue_79555.rs @@ -0,0 +1,11 @@ +// build-pass +// needs-profiler-support +// needs-rust-lld +// compile-flags: -C linker-flavor=gcc:lld -Z unstable-options -Clink-self-contained=y -Cinstrument-coverage + +// Test ensuring that a warning referencing lld known issue 79555 is emitted when: +// - we're asking to use lld, via the enriched gcc linker-flavor +// - the CRT object linking is on +// - either coverage or generating a profile is requested + +fn main() {} diff --git a/src/test/ui/linkers/mentions_issue_79555.stderr b/src/test/ui/linkers/mentions_issue_79555.stderr new file mode 100644 index 0000000000000..8a42d67708b97 --- /dev/null +++ b/src/test/ui/linkers/mentions_issue_79555.stderr @@ -0,0 +1,4 @@ +warning: Using `lld`, self-contained linking, and coverage or profile generation has known issues. See issue #79555 for more details, at https://github.com/rust-lang/rust/issues/79555 + +warning: 1 warning emitted + From d337f07e0013cd051ddee5c3836c7f1a7705a06f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Wed, 27 Apr 2022 19:23:22 +0200 Subject: [PATCH 08/12] test unstable values of `-C linker-flavor=gcc` --- src/test/ui/linkers/unstable_linker_flavor.lld.stderr | 2 ++ src/test/ui/linkers/unstable_linker_flavor.other.stderr | 2 ++ src/test/ui/linkers/unstable_linker_flavor.rs | 9 +++++++++ 3 files changed, 13 insertions(+) create mode 100644 src/test/ui/linkers/unstable_linker_flavor.lld.stderr create mode 100644 src/test/ui/linkers/unstable_linker_flavor.other.stderr create mode 100644 src/test/ui/linkers/unstable_linker_flavor.rs diff --git a/src/test/ui/linkers/unstable_linker_flavor.lld.stderr b/src/test/ui/linkers/unstable_linker_flavor.lld.stderr new file mode 100644 index 0000000000000..056d7e18238ff --- /dev/null +++ b/src/test/ui/linkers/unstable_linker_flavor.lld.stderr @@ -0,0 +1,2 @@ +error: the `gcc:*` linker flavor is unstable, the `-Z unstable-options` flag must also be passed to use it + diff --git a/src/test/ui/linkers/unstable_linker_flavor.other.stderr b/src/test/ui/linkers/unstable_linker_flavor.other.stderr new file mode 100644 index 0000000000000..056d7e18238ff --- /dev/null +++ b/src/test/ui/linkers/unstable_linker_flavor.other.stderr @@ -0,0 +1,2 @@ +error: the `gcc:*` linker flavor is unstable, the `-Z unstable-options` flag must also be passed to use it + diff --git a/src/test/ui/linkers/unstable_linker_flavor.rs b/src/test/ui/linkers/unstable_linker_flavor.rs new file mode 100644 index 0000000000000..096d4785b69f9 --- /dev/null +++ b/src/test/ui/linkers/unstable_linker_flavor.rs @@ -0,0 +1,9 @@ +// check-fail +// revisions: lld other +// [lld] compile-flags: -C linker-flavor=gcc:lld +// [other] compile-flags: -C linker-flavor=gcc:other + +// Test ensuring that the unstable `gcc:*` values of the stable `-C linker-flavor` flag require +// using `-Z unstable options` + +fn main() {} From 6d2e060dca50fbdc5f6dd83a7df5f654a0ec6488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Wed, 27 Apr 2022 19:27:33 +0200 Subject: [PATCH 09/12] add test ensuring `-Zgcc-ld=$linker` and `-Clinker-flavor=gcc:$linker` match currently only "lld" is usable in this context --- src/test/ui/linkers/gcc_ld_mismatch.rs | 7 +++++++ src/test/ui/linkers/gcc_ld_mismatch.stderr | 2 ++ 2 files changed, 9 insertions(+) create mode 100644 src/test/ui/linkers/gcc_ld_mismatch.rs create mode 100644 src/test/ui/linkers/gcc_ld_mismatch.stderr diff --git a/src/test/ui/linkers/gcc_ld_mismatch.rs b/src/test/ui/linkers/gcc_ld_mismatch.rs new file mode 100644 index 0000000000000..397bf16b9ff51 --- /dev/null +++ b/src/test/ui/linkers/gcc_ld_mismatch.rs @@ -0,0 +1,7 @@ +// check-fail +// compile-flags: -Zgcc-ld=lld -Clinker-flavor=gcc:not_lld -Zunstable-options + +// Test ensuring that until the unstable flag is removed (if ever), if both the linker-flavor and +// `gcc-ld` flags are used, they ask for the same linker. + +fn main() {} diff --git a/src/test/ui/linkers/gcc_ld_mismatch.stderr b/src/test/ui/linkers/gcc_ld_mismatch.stderr new file mode 100644 index 0000000000000..9e5c6eb0f6a73 --- /dev/null +++ b/src/test/ui/linkers/gcc_ld_mismatch.stderr @@ -0,0 +1,2 @@ +error: `-Zgcc-ld=lld` and `-Clinker-flavor` differ in their linker choice. The latter should be `-Clinker-flavor=gcc:lld` + From aebc133622e88c69ef3cf2dd2308a67be0d9bf2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Wed, 27 Apr 2022 20:25:51 +0200 Subject: [PATCH 10/12] add run-make test for `-C linker-flavor=gcc:*` ensures that the wrapped linker is indeed passed straight to cc --- src/test/run-make/gcc-linker-flavor/Makefile | 9 +++++++++ src/test/run-make/gcc-linker-flavor/empty.rs | 4 ++++ 2 files changed, 13 insertions(+) create mode 100644 src/test/run-make/gcc-linker-flavor/Makefile create mode 100644 src/test/run-make/gcc-linker-flavor/empty.rs diff --git a/src/test/run-make/gcc-linker-flavor/Makefile b/src/test/run-make/gcc-linker-flavor/Makefile new file mode 100644 index 0000000000000..09b8b28e8263e --- /dev/null +++ b/src/test/run-make/gcc-linker-flavor/Makefile @@ -0,0 +1,9 @@ +# only-linux + +# Ensure that the enriched `gcc` linker-flavor passes the requested linker to `cc` + +-include ../../run-make-fulldeps/tools.mk +RUSTC_FLAGS = -C linker-flavor=gcc:my_wrapped_linker -Z unstable-options --print link-args + +all: + $(RUSTC) $(RUSTC_FLAGS) empty.rs | $(CGREP) "fuse-ld=my_wrapped_linker" diff --git a/src/test/run-make/gcc-linker-flavor/empty.rs b/src/test/run-make/gcc-linker-flavor/empty.rs new file mode 100644 index 0000000000000..d227f726a44b2 --- /dev/null +++ b/src/test/run-make/gcc-linker-flavor/empty.rs @@ -0,0 +1,4 @@ +// Test ensuring that the enriched `gcc` linker flavor requesting an arbitrary linker (`-C +// linker-flavor=gcc:$linker`) is passed to `cc` as `-fuse-ld` + +fn main() {} From a4c8128c057ee8fa83274ccd5bcdb087a5aaf987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 8 May 2022 19:03:24 +0200 Subject: [PATCH 11/12] make an impossible case a `bug!` --- compiler/rustc_codegen_ssa/src/back/link.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index fe891b498c027..0e33a580c889d 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2719,10 +2719,15 @@ fn handle_cli_linker_flavors( // adding an argument to the `cc` invocation to use the `use_ld` given linker. let use_ld = match &cg.linker_flavor { Some(LinkerFlavorCli::Gcc { use_ld }) => { - // Ensure `gcc` is the currently selected flavor. Error out cleanly, as `-Zgcc-ld` does - // if that happens, but this should be unreachable. + // Ensure `gcc` is the currently selected flavor. + // + // This should be the case as long as this piece of code stays downstream from the CLI + // linker-flavor lowering, and the actual `LinkerFlavor` is not changed or overriden by + // the time the order-independent options are added to the command args. + // + // If that changes by mistake (or intentionally) in the future, we panic. if LinkerFlavor::Gcc != flavor { - sess.fatal( + bug!( "`-Clinker-flavor=gcc:*` flag is used even though the \ linker flavor is not `gcc`", ); From 08395edc4b51acdb0c893369b3b19f0317bb8329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 25 Jul 2022 16:48:46 +0200 Subject: [PATCH 12/12] remove freeform component from `LinkerFlavorCli` --- compiler/rustc_codegen_ssa/src/back/link.rs | 136 +++++++++--------- compiler/rustc_session/src/config.rs | 32 ++--- compiler/rustc_session/src/options.rs | 5 +- compiler/rustc_session/src/tests.rs | 14 +- src/test/run-make/gcc-linker-flavor/Makefile | 4 +- src/test/run-make/gcc-linker-flavor/empty.rs | 4 +- src/test/ui/linkers/gcc_ld_mismatch.rs | 4 +- src/test/ui/linkers/gcc_ld_mismatch.stderr | 4 +- .../linkers/unstable_linker_flavor.lld.stderr | 2 - .../unstable_linker_flavor.other.stderr | 2 - src/test/ui/linkers/unstable_linker_flavor.rs | 6 +- .../ui/linkers/unstable_linker_flavor.stderr | 2 + 12 files changed, 93 insertions(+), 122 deletions(-) delete mode 100644 src/test/ui/linkers/unstable_linker_flavor.lld.stderr delete mode 100644 src/test/ui/linkers/unstable_linker_flavor.other.stderr create mode 100644 src/test/ui/linkers/unstable_linker_flavor.stderr diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 0e33a580c889d..15c5a6abc7cdd 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2696,8 +2696,9 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result { /// This takes care of the various possible enrichments to the linking that can be requested on the /// CLI (and emitting errors and warnings when applicable): -/// - shortcuts to `-fuse-ld` with the `gcc` flavor -/// - the unstable `-Zgcc-ld=lld` flag to use `rust-lld`, stabilized as the following item +/// - the unstable `-Zgcc-ld=lld` flag to use `rust-lld` +/// - the shortcut to `-fuse-ld=lld` with the `gcc` flavor, to eventually use `rust-lld` when +/// `-Clink-self-contained=linker` is introduced. fn handle_cli_linker_flavors( cmd: &mut dyn Linker, sess: &Session, @@ -2705,19 +2706,18 @@ fn handle_cli_linker_flavors( crt_objects_fallback: bool, ) { let unstable_gcc_lld = sess.opts.unstable_opts.gcc_ld == Some(LdImpl::Lld); - if unstable_gcc_lld { - // Sanity check: ensure `gcc` is the currently selected flavor. - if LinkerFlavor::Gcc != flavor { - sess.fatal("`-Zgcc-ld` is used even though the linker flavor is not `gcc`"); - } + + // Sanity check: ensure `gcc` is the currently selected flavor. + if unstable_gcc_lld && LinkerFlavor::Gcc != flavor { + sess.fatal("`-Zgcc-ld` is used even though the linker flavor is not `gcc`"); } let cg = &sess.opts.cg; // The `-C linker-flavor` CLI flag can optionally enrich linker-flavors. Check whether that's // applicable, and emit errors if sanity checks fail. There's currently only one enrichment: - // adding an argument to the `cc` invocation to use the `use_ld` given linker. - let use_ld = match &cg.linker_flavor { + // adding an argument to the `cc` invocation to use `lld`. + match &cg.linker_flavor { Some(LinkerFlavorCli::Gcc { use_ld }) => { // Ensure `gcc` is the currently selected flavor. // @@ -2733,79 +2733,71 @@ fn handle_cli_linker_flavors( ); } - use_ld + if *use_ld != LdImpl::Lld { + // We're not in a situation needing enrichments. + return; + } } - // Note: exhaustive match arm here, to avoid fallthroughs if new linker-flavor enrichments - // are added in the future. Some(LinkerFlavorCli::WellKnown(_)) | None => { - if unstable_gcc_lld { - "lld" - } else { + if !unstable_gcc_lld { // We're not in a situation needing enrichments. return; } } - }; + } - // From now on in this function, we handle the `gcc` linker-flavor enrichment. + // From now on in this function, we handle the `gcc` linker-flavor enrichment to use `lld`. - // Except for `lld`, the given linker executable will be passed straight to `-fuse-ld`. - if use_ld == "lld" { - // Start by checking if we're in the context of a known issue that users might hit when - // using `lld`: - // - // 1. when requesting self-contained CRT linking (or on a target that does it - // automatically), and coverage/profile generation: point at #79555 "Coverage is not - // generated when using rust-lld as linker" - let instrument_coverage = cg.instrument_coverage.is_some() - && cg.instrument_coverage != Some(InstrumentCoverage::Off); - let generate_profile = cg.profile_generate.enabled(); - if crt_objects_fallback && (instrument_coverage || generate_profile) { - sess.warn( - "Using `lld`, self-contained linking, and coverage or profile generation has known \ - issues. See issue #79555 for more details, at \ - https://github.com/rust-lang/rust/issues/79555", - ); - } + // Start by checking if we're in the context of a known issue that users might hit when + // using `lld`: + // + // 1. when requesting self-contained CRT linking (or on a target that does it + // automatically), and coverage/profile generation: point at #79555 "Coverage is not + // generated when using rust-lld as linker" + let instrument_coverage = + cg.instrument_coverage.is_some() && cg.instrument_coverage != Some(InstrumentCoverage::Off); + let generate_profile = cg.profile_generate.enabled(); + if crt_objects_fallback && (instrument_coverage || generate_profile) { + sess.warn( + "Using `lld`, self-contained linking, and coverage or profile generation has known \ + issues. See issue #79555 for more details, at \ + https://github.com/rust-lang/rust/issues/79555", + ); + } - // 2. Maybe point at https://github.com/flamegraph-rs/flamegraph/pull/157 or the - // corresponding rust/LLVM issue when/if it's tracked, depending on whether we use the - // workaround argument `--no-rosegment` by default when invoking `lld`. - // - // 3. If in the future, other linker flavors and targets are eligible to a `rust-lld` - // enrichment, maybe also point at target-specific issues like: - // - MSVC + ThinLTO blocker https://github.com/rust-lang/rust/issues/81408 - // - the "lld on MSVC" tracking issue https://github.com/rust-lang/rust/issues/71520 - // containing a list of blocking issues - - // Now, handle `rust-lld`. If the `-Zgcc-ld=lld` flag was provided, we use `rust-lld`, the - // rustup-distributed version of `lld` (when applicable, i.e. not in distro-builds) by: - // - checking the `lld-wrapper`s exist in the sysroot - // - adding their folder as a search path, or requesting to use a wrapper directly - if unstable_gcc_lld { - // A `gcc-ld` folder (containing the `lld-wrapper`s that will run `rust-lld`) is present in - // the sysroot's target-specific tool binaries folder. - let tools_path = sess.get_tools_search_paths(false); - let gcc_ld_dir = tools_path - .into_iter() - .map(|p| p.join("gcc-ld")) - .find(|p| p.join(if sess.host.is_like_windows { "ld.exe" } else { "ld" }).exists()) - .unwrap_or_else(|| sess.fatal("rust-lld (as ld) not found")); - - cmd.arg({ - let mut arg = OsString::from("-B"); - arg.push(gcc_ld_dir); - arg - }); - cmd.arg(format!("-Wl,-rustc-lld-flavor={}", sess.target.lld_flavor.as_str())); - } else { - // We were asked to use `lld` but not `rust-lld`. - cmd.arg("-fuse-ld=lld"); - } + // 2. Maybe point at https://github.com/flamegraph-rs/flamegraph/pull/157 or the + // corresponding rust/LLVM issue when/if it's tracked, depending on whether we use the + // workaround argument `--no-rosegment` by default when invoking `lld`. + // + // 3. If in the future, other linker flavors and targets are eligible to a `rust-lld` + // enrichment, maybe also point at target-specific issues like: + // - MSVC + ThinLTO blocker https://github.com/rust-lang/rust/issues/81408 + // - the "lld on MSVC" tracking issue https://github.com/rust-lang/rust/issues/71520 + // containing a list of blocking issues + + // Now, handle `rust-lld`. If the `-Zgcc-ld=lld` flag was provided, we use `rust-lld`, the + // rustup-distributed version of `lld` (when applicable, i.e. not in distro-builds) by: + // - checking the `lld-wrapper`s exist in the sysroot + // - adding their folder as a search path, or requesting to use a wrapper directly + if unstable_gcc_lld { + // A `gcc-ld` folder (containing the `lld-wrapper`s that will run `rust-lld`) is present in + // the sysroot's target-specific tool binaries folder. + let tools_path = sess.get_tools_search_paths(false); + let gcc_ld_dir = tools_path + .into_iter() + .map(|p| p.join("gcc-ld")) + .find(|p| p.join(if sess.host.is_like_windows { "ld.exe" } else { "ld" }).exists()) + .unwrap_or_else(|| sess.fatal("rust-lld (as ld) not found")); + + cmd.arg({ + let mut arg = OsString::from("-B"); + arg.push(gcc_ld_dir); + arg + }); + cmd.arg(format!("-Wl,-rustc-lld-flavor={}", sess.target.lld_flavor.as_str())); } else { - // Otherwise, we were just asked to use a linker executable, and it's expected that `cc` - // will find it on the $PATH. - cmd.arg(format!("-fuse-ld={}", use_ld)); + // Otherwise, we were asked to use `lld` but not `rust-lld`. + cmd.arg("-fuse-ld=lld"); } } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 2af3fda09abda..ec87f10d012d2 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -208,15 +208,15 @@ impl LinkerPluginLto { /// `to_flavor` method, and never the enrichment variants. /// /// Currently used to represent finer-grained uses of `gcc`, to improve ease-of-use for wrapping a -/// given linker like `lld`, `gold` or `mold`. -#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +/// given linker (currently: only `lld`). +#[derive(Clone, Debug, PartialEq)] pub enum LinkerFlavorCli { /// When the CLI option is one of the well-known linker-flavors that don't need special /// handling. WellKnown(LinkerFlavor), - /// Enrichments to the `LinkerFlavor::Gcc` flavor, to specify the linker via `-fuse-ld` - Gcc { use_ld: String }, + /// Enrichments to the `LinkerFlavor::Gcc` flavor, to specify the linker via `-fuse-ld`. + Gcc { use_ld: LdImpl }, } impl LinkerFlavorCli { @@ -241,17 +241,11 @@ impl FromStr for LinkerFlavorCli { // Otherwise, it should be the enrichments to the gcc/cc flavor: wrapping a given linker // separated by a colon like `gcc:lld`. - let parts: Vec<_> = s.split("gcc:").collect(); - if parts.len() != 2 { + if s != "gcc:lld" { return Err(()); } - let wrapped_linker = parts[1]; - if !wrapped_linker.is_empty() { - Ok(LinkerFlavorCli::Gcc { use_ld: wrapped_linker.to_string() }) - } else { - Err(()) - } + Ok(LinkerFlavorCli::Gcc { use_ld: LdImpl::Lld }) } } @@ -2442,26 +2436,16 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { ); } - if let Some(LinkerFlavorCli::Gcc { use_ld }) = &cg.linker_flavor { + if let Some(LinkerFlavorCli::Gcc { .. }) = &cg.linker_flavor { // For testing purposes, until we have more feedback about these options: ensure `-Z // unstable-options` is enabled when using the `gcc` linker flavor enrichments. if !unstable_opts.unstable_options { early_error( error_format, - "the `gcc:*` linker flavor is unstable, the `-Z unstable-options` \ + "the `gcc:lld` linker flavor is unstable, the `-Z unstable-options` \ flag must also be passed to use it", ); } - - // Until the unstable flag is removed, ensure `-Zgcc-ld=lld` and `-Clinker-flavor=gcc:lld` - // have a matching linker choice. - if use_ld != "lld" && unstable_opts.gcc_ld == Some(LdImpl::Lld) { - early_error( - error_format, - "`-Zgcc-ld=lld` and `-Clinker-flavor` differ in their \ - linker choice. The latter should be `-Clinker-flavor=gcc:lld`", - ); - } } let prints = collect_print_requests(&mut cg, &mut unstable_opts, matches, error_format); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 95d18e591febd..5cd8f4d6ff2fc 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -384,8 +384,7 @@ mod desc { pub const parse_cfprotection: &str = "`none`|`no`|`n` (default), `branch`, `return`, or `full`|`yes`|`y` (equivalent to `branch` and `return`)"; pub const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`"; pub const parse_linker_flavor: &str = "one of: `em`, `gcc`, `l4-bender`, `ld`, `msvc`, \ - `ptx-linker`, `bpf-linker`, `wasm-ld`, `ld64.lld`, `ld.lld`, `lld-link`, \ - or a `gcc:`-prefixed linker to use with the gcc flavor, like `gcc:lld` or `gcc:gold,`"; + `ptx-linker`, `bpf-linker`, `wasm-ld`, `ld64.lld`, `ld.lld`, `lld-link`, or `gcc:lld`"; pub const parse_optimization_fuel: &str = "crate=integer"; pub const parse_mir_spanview: &str = "`statement` (default), `terminator`, or `block`"; pub const parse_instrument_coverage: &str = @@ -1618,7 +1617,7 @@ pub enum WasiExecModel { Reactor, } -#[derive(Clone, Copy, Hash, PartialEq)] +#[derive(Clone, Copy, Hash, PartialEq, Debug)] pub enum LdImpl { Lld, } diff --git a/compiler/rustc_session/src/tests.rs b/compiler/rustc_session/src/tests.rs index ab15d7393de9c..9f9eef99fe3ba 100644 --- a/compiler/rustc_session/src/tests.rs +++ b/compiler/rustc_session/src/tests.rs @@ -32,20 +32,18 @@ pub fn parse_well_known_linker_flavor() { assert_eq!(LinkerFlavorCli::from_str("unknown_linker"), Err(())); } -/// Enrichments can currently allow for the `gcc` flavor to specify for a given linker to be -/// used, much like you'd use `-fuse-ld` as a link arg. When using `-C -/// linker-flavor=gcc:$linker`, the `$linker` will be passed directly to `cc`. +/// Enrichments can currently allow the `gcc` flavor to use `lld`, much like you'd use `-fuse-ld` as +/// a link arg. #[test] pub fn parse_gcc_enrichment_linker_flavor() { assert_eq!( LinkerFlavorCli::from_str("gcc:lld"), - Ok(LinkerFlavorCli::Gcc { use_ld: "lld".to_string() }) - ); - assert_eq!( - LinkerFlavorCli::from_str("gcc:gold"), - Ok(LinkerFlavorCli::Gcc { use_ld: "gold".to_string() }) + Ok(LinkerFlavorCli::Gcc { use_ld: LdImpl::Lld }) ); + // Only `gcc:lld` is supported for now + assert_eq!(LinkerFlavorCli::from_str("gcc:gold"), Err(())); + // No linker actually mentioned assert_eq!(LinkerFlavorCli::from_str("gcc:"), Err(())); diff --git a/src/test/run-make/gcc-linker-flavor/Makefile b/src/test/run-make/gcc-linker-flavor/Makefile index 09b8b28e8263e..585220a758e44 100644 --- a/src/test/run-make/gcc-linker-flavor/Makefile +++ b/src/test/run-make/gcc-linker-flavor/Makefile @@ -3,7 +3,7 @@ # Ensure that the enriched `gcc` linker-flavor passes the requested linker to `cc` -include ../../run-make-fulldeps/tools.mk -RUSTC_FLAGS = -C linker-flavor=gcc:my_wrapped_linker -Z unstable-options --print link-args +RUSTC_FLAGS = -C linker-flavor=gcc:lld -Z unstable-options --print link-args all: - $(RUSTC) $(RUSTC_FLAGS) empty.rs | $(CGREP) "fuse-ld=my_wrapped_linker" + $(RUSTC) $(RUSTC_FLAGS) empty.rs | $(CGREP) "fuse-ld=lld" diff --git a/src/test/run-make/gcc-linker-flavor/empty.rs b/src/test/run-make/gcc-linker-flavor/empty.rs index d227f726a44b2..4f6be7710134f 100644 --- a/src/test/run-make/gcc-linker-flavor/empty.rs +++ b/src/test/run-make/gcc-linker-flavor/empty.rs @@ -1,4 +1,4 @@ -// Test ensuring that the enriched `gcc` linker flavor requesting an arbitrary linker (`-C -// linker-flavor=gcc:$linker`) is passed to `cc` as `-fuse-ld` +// Test ensuring that the enriched `gcc` linker flavor requesting `lld` (`-C +// linker-flavor=gcc:lld`) is passed to `cc` as `-fuse-ld=lld` fn main() {} diff --git a/src/test/ui/linkers/gcc_ld_mismatch.rs b/src/test/ui/linkers/gcc_ld_mismatch.rs index 397bf16b9ff51..2628bcb05f533 100644 --- a/src/test/ui/linkers/gcc_ld_mismatch.rs +++ b/src/test/ui/linkers/gcc_ld_mismatch.rs @@ -1,5 +1,5 @@ -// check-fail -// compile-flags: -Zgcc-ld=lld -Clinker-flavor=gcc:not_lld -Zunstable-options +// build-fail +// compile-flags: -Zgcc-ld=lld -Clinker-flavor=em -Zunstable-options // Test ensuring that until the unstable flag is removed (if ever), if both the linker-flavor and // `gcc-ld` flags are used, they ask for the same linker. diff --git a/src/test/ui/linkers/gcc_ld_mismatch.stderr b/src/test/ui/linkers/gcc_ld_mismatch.stderr index 9e5c6eb0f6a73..c6ef47773556c 100644 --- a/src/test/ui/linkers/gcc_ld_mismatch.stderr +++ b/src/test/ui/linkers/gcc_ld_mismatch.stderr @@ -1,2 +1,4 @@ -error: `-Zgcc-ld=lld` and `-Clinker-flavor` differ in their linker choice. The latter should be `-Clinker-flavor=gcc:lld` +error: `-Zgcc-ld` is used even though the linker flavor is not `gcc` + +error: aborting due to previous error diff --git a/src/test/ui/linkers/unstable_linker_flavor.lld.stderr b/src/test/ui/linkers/unstable_linker_flavor.lld.stderr deleted file mode 100644 index 056d7e18238ff..0000000000000 --- a/src/test/ui/linkers/unstable_linker_flavor.lld.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: the `gcc:*` linker flavor is unstable, the `-Z unstable-options` flag must also be passed to use it - diff --git a/src/test/ui/linkers/unstable_linker_flavor.other.stderr b/src/test/ui/linkers/unstable_linker_flavor.other.stderr deleted file mode 100644 index 056d7e18238ff..0000000000000 --- a/src/test/ui/linkers/unstable_linker_flavor.other.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: the `gcc:*` linker flavor is unstable, the `-Z unstable-options` flag must also be passed to use it - diff --git a/src/test/ui/linkers/unstable_linker_flavor.rs b/src/test/ui/linkers/unstable_linker_flavor.rs index 096d4785b69f9..b0d3f2d261875 100644 --- a/src/test/ui/linkers/unstable_linker_flavor.rs +++ b/src/test/ui/linkers/unstable_linker_flavor.rs @@ -1,9 +1,7 @@ // check-fail -// revisions: lld other -// [lld] compile-flags: -C linker-flavor=gcc:lld -// [other] compile-flags: -C linker-flavor=gcc:other +// compile-flags: -C linker-flavor=gcc:lld -// Test ensuring that the unstable `gcc:*` values of the stable `-C linker-flavor` flag require +// Test ensuring that the unstable `gcc:lld` value of the stable `-C linker-flavor` flag requires // using `-Z unstable options` fn main() {} diff --git a/src/test/ui/linkers/unstable_linker_flavor.stderr b/src/test/ui/linkers/unstable_linker_flavor.stderr new file mode 100644 index 0000000000000..2826b8446697d --- /dev/null +++ b/src/test/ui/linkers/unstable_linker_flavor.stderr @@ -0,0 +1,2 @@ +error: the `gcc:lld` linker flavor is unstable, the `-Z unstable-options` flag must also be passed to use it +