@@ -42,9 +42,11 @@ use crate::core::config::toml::install::Install;
4242use crate :: core:: config:: toml:: llvm:: Llvm ;
4343use crate :: core:: config:: toml:: rust:: {
4444 BootstrapOverrideLld , Rust , RustOptimize , check_incompatible_options_for_ci_rustc,
45- default_lld_opt_in_targets, parse_codegen_backends,
45+ parse_codegen_backends,
46+ } ;
47+ use crate :: core:: config:: toml:: target:: {
48+ DefaultLinuxLinkerOverride , Target , TomlTarget , default_linux_linker_overrides,
4649} ;
47- use crate :: core:: config:: toml:: target:: { Target , TomlTarget } ;
4850use crate :: core:: config:: {
4951 CompilerBuiltins , DebuginfoLevel , DryRun , GccCiMode , LlvmLibunwind , Merge , ReplaceOpt ,
5052 RustcLto , SplitDebuginfo , StringOrBool , threads_from_config,
@@ -829,6 +831,11 @@ impl Config {
829831 . to_owned ( ) ;
830832 }
831833
834+ let mut lld_enabled = rust_lld_enabled. unwrap_or ( false ) ;
835+
836+ // Linux targets for which the user explicitly overrode the used linker
837+ let mut targets_with_user_linker_override = HashSet :: new ( ) ;
838+
832839 if let Some ( t) = toml. target {
833840 for ( triple, cfg) in t {
834841 let TomlTarget {
@@ -837,6 +844,7 @@ impl Config {
837844 ar : target_ar,
838845 ranlib : target_ranlib,
839846 default_linker : target_default_linker,
847+ default_linker_linux : target_default_linker_linux_override,
840848 linker : target_linker,
841849 split_debuginfo : target_split_debuginfo,
842850 llvm_config : target_llvm_config,
@@ -860,6 +868,33 @@ impl Config {
860868
861869 let mut target = Target :: from_triple ( & triple) ;
862870
871+ if target_default_linker_linux_override. is_some ( ) {
872+ targets_with_user_linker_override. insert ( triple. clone ( ) ) ;
873+ }
874+
875+ let default_linker_linux_override = match target_default_linker_linux_override {
876+ Some ( DefaultLinuxLinkerOverride :: SelfContainedLldCc ) => {
877+ if rust_default_linker. is_some ( ) {
878+ panic ! (
879+ "cannot set both `default-linker` and `default-linker-linux` for target `{triple}`"
880+ ) ;
881+ }
882+ if !triple. contains ( "linux-gnu" ) {
883+ panic ! (
884+ "`default-linker-linux` can only be set for Linux GNU targets, not for `{triple}`"
885+ ) ;
886+ }
887+ if !lld_enabled {
888+ panic ! (
889+ "Trying to override the default Linux linker for `{triple}` to be self-contained LLD, but LLD is not being built. Enable it with rust.lld = true."
890+ ) ;
891+ }
892+ DefaultLinuxLinkerOverride :: SelfContainedLldCc
893+ }
894+ Some ( DefaultLinuxLinkerOverride :: Off ) => DefaultLinuxLinkerOverride :: Off ,
895+ None => DefaultLinuxLinkerOverride :: default ( ) ,
896+ } ;
897+
863898 if let Some ( ref s) = target_llvm_config {
864899 if download_rustc_commit. is_some ( ) && triple == * host_target. triple {
865900 panic ! (
@@ -893,6 +928,7 @@ impl Config {
893928 target. linker = target_linker. map ( PathBuf :: from) ;
894929 target. crt_static = target_crt_static;
895930 target. default_linker = target_default_linker;
931+ target. default_linker_linux_override = default_linker_linux_override;
896932 target. musl_root = target_musl_root. map ( PathBuf :: from) ;
897933 target. musl_libdir = target_musl_libdir. map ( PathBuf :: from) ;
898934 target. wasi_root = target_wasi_root. map ( PathBuf :: from) ;
@@ -918,6 +954,38 @@ impl Config {
918954 }
919955 }
920956
957+ for ( target, linker_override) in default_linux_linker_overrides ( ) {
958+ // If the user overrode the default Linux linker, do not apply bootstrap defaults
959+ if targets_with_user_linker_override. contains ( & target) {
960+ continue ;
961+ }
962+ let default_linux_linker_override = match linker_override {
963+ DefaultLinuxLinkerOverride :: Off => continue ,
964+ DefaultLinuxLinkerOverride :: SelfContainedLldCc => {
965+ // If we automatically default to the self-contained LLD linker,
966+ // we also need to handle the rust.lld option.
967+ match rust_lld_enabled {
968+ // If LLD was not enabled explicitly, we enable it
969+ None => {
970+ lld_enabled = true ;
971+ Some ( DefaultLinuxLinkerOverride :: SelfContainedLldCc )
972+ }
973+ // If it was enabled already, we don't need to do anything
974+ Some ( true ) => Some ( DefaultLinuxLinkerOverride :: SelfContainedLldCc ) ,
975+ // If it was explicitly disabled, we do not apply the
976+ // linker override
977+ Some ( false ) => None ,
978+ }
979+ }
980+ } ;
981+ if let Some ( linker_override) = default_linux_linker_override {
982+ target_config
983+ . entry ( TargetSelection :: from_user ( & target) )
984+ . or_default ( )
985+ . default_linker_linux_override = linker_override;
986+ }
987+ }
988+
921989 let llvm_from_ci = parse_download_ci_llvm (
922990 & dwn_ctx,
923991 & rust_info,
@@ -926,28 +994,6 @@ impl Config {
926994 llvm_assertions,
927995 ) ;
928996
929- // We make `x86_64-unknown-linux-gnu` use the self-contained linker by default, so we will
930- // build our internal lld and use it as the default linker, by setting the `rust.lld` config
931- // to true by default:
932- // - on the `x86_64-unknown-linux-gnu` target
933- // - when building our in-tree llvm (i.e. the target has not set an `llvm-config`), so that
934- // we're also able to build the corresponding lld
935- // - or when using an external llvm that's downloaded from CI, which also contains our prebuilt
936- // lld
937- // - otherwise, we'd be using an external llvm, and lld would not necessarily available and
938- // thus, disabled
939- // - similarly, lld will not be built nor used by default when explicitly asked not to, e.g.
940- // when the config sets `rust.lld = false`
941- let lld_enabled = if default_lld_opt_in_targets ( ) . contains ( & host_target. triple . to_string ( ) )
942- && hosts == [ host_target]
943- {
944- let no_llvm_config =
945- target_config. get ( & host_target) . is_none_or ( |config| config. llvm_config . is_none ( ) ) ;
946- rust_lld_enabled. unwrap_or ( llvm_from_ci || no_llvm_config)
947- } else {
948- rust_lld_enabled. unwrap_or ( false )
949- } ;
950-
951997 if llvm_from_ci {
952998 let warn = |option : & str | {
953999 println ! (
0 commit comments