@@ -12,7 +12,7 @@ use rustc_metadata::fs::{copy_to_stdout, emit_wrapper_file, METADATA_FILENAME};
1212use rustc_middle:: middle:: debugger_visualizer:: DebuggerVisualizerFile ;
1313use rustc_middle:: middle:: dependency_format:: Linkage ;
1414use rustc_middle:: middle:: exported_symbols:: SymbolExportKind ;
15- use rustc_session:: config:: { self , CFGuard , CrateType , DebugInfo , LdImpl , Strip } ;
15+ use rustc_session:: config:: { self , CFGuard , CrateType , DebugInfo , Strip } ;
1616use rustc_session:: config:: { OutputFilenames , OutputType , PrintRequest , SplitDwarfKind } ;
1717use rustc_session:: cstore:: DllImport ;
1818use rustc_session:: output:: { check_file_is_writeable, invalid_output_for_target, out_filename} ;
@@ -2246,7 +2246,8 @@ fn add_order_independent_options(
22462246 out_filename : & Path ,
22472247 tmpdir : & Path ,
22482248) {
2249- add_gcc_ld_path ( cmd, sess, flavor) ;
2249+ // Take care of the flavors and CLI options requesting the `lld` linker.
2250+ add_lld_args ( cmd, sess, flavor) ;
22502251
22512252 add_apple_sdk ( cmd, sess, flavor) ;
22522253
@@ -2948,55 +2949,66 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result<String, errors::AppleSdkRootErro
29482949 }
29492950}
29502951
2951- fn add_gcc_ld_path ( cmd : & mut dyn Linker , sess : & Session , flavor : LinkerFlavor ) {
2952- if let Some ( ld_impl) = sess. opts . unstable_opts . gcc_ld {
2953- if let LinkerFlavor :: Gnu ( Cc :: Yes , _)
2954- | LinkerFlavor :: Darwin ( Cc :: Yes , _)
2955- | LinkerFlavor :: WasmLld ( Cc :: Yes ) = flavor
2956- {
2957- match ld_impl {
2958- LdImpl :: Lld => {
2959- // Implement the "self-contained" part of -Zgcc-ld
2960- // by adding rustc distribution directories to the tool search path.
2961- for path in sess. get_tools_search_paths ( false ) {
2962- cmd. arg ( {
2963- let mut arg = OsString :: from ( "-B" ) ;
2964- arg. push ( path. join ( "gcc-ld" ) ) ;
2965- arg
2966- } ) ;
2967- }
2968- // Implement the "linker flavor" part of -Zgcc-ld
2969- // by asking cc to use some kind of lld.
2970- cmd. arg ( "-fuse-ld=lld" ) ;
2971-
2972- if !flavor. is_gnu ( ) {
2973- // Tell clang to use a non-default LLD flavor.
2974- // Gcc doesn't understand the target option, but we currently assume
2975- // that gcc is not used for Apple and Wasm targets (#97402).
2976- //
2977- // Note that we don't want to do that by default on macOS: e.g. passing a
2978- // 10.7 target to LLVM works, but not to recent versions of clang/macOS, as
2979- // shown in issue #101653 and the discussion in PR #101792.
2980- //
2981- // It could be required in some cases of cross-compiling with
2982- // `-Zgcc-ld=lld`, but this is generally unspecified, and we don't know
2983- // which specific versions of clang, macOS SDK, host and target OS
2984- // combinations impact us here.
2985- //
2986- // So we do a simple first-approximation until we know more of what the
2987- // Apple targets require (and which would be handled prior to hitting this
2988- // `-Zgcc-ld=lld` codepath anyway), but the expectation is that until then
2989- // this should be manually passed if needed. We specify the target when
2990- // targeting a different linker flavor on macOS, and that's also always
2991- // the case when targeting WASM.
2992- if sess. target . linker_flavor != sess. host . linker_flavor {
2993- cmd. arg ( format ! ( "--target={}" , sess. target. llvm_target) ) ;
2994- }
2995- }
2996- }
2997- }
2998- } else {
2999- sess. emit_fatal ( errors:: OptionGccOnly ) ;
2952+ /// When using the linker flavors opting in to `lld`, or the unstable `-Zgcc-ld=lld` flag, add the
2953+ /// necessary paths and arguments to invoke it:
2954+ /// - when the self-contained linker flag is active: the build of `lld` distributed with rustc,
2955+ /// - or any `lld` available to `cc`.
2956+ fn add_lld_args ( cmd : & mut dyn Linker , sess : & Session , flavor : LinkerFlavor ) {
2957+ let unstable_use_lld = sess. opts . unstable_opts . gcc_ld . is_some ( ) ;
2958+ debug ! ( "add_lld_args requested, flavor: '{flavor:?}', `-Zgcc-ld=lld`: {unstable_use_lld}" ) ;
2959+
2960+ // Sanity check: using the old unstable `-Zgcc-ld=lld` option requires a `cc`-using flavor.
2961+ let flavor_uses_cc = flavor. uses_cc ( ) ;
2962+ if unstable_use_lld && !flavor_uses_cc {
2963+ sess. emit_fatal ( errors:: OptionGccOnly ) ;
2964+ }
2965+
2966+ // If the flavor doesn't use a C/C++ compiler to invoke the linker, or doesn't opt in to `lld`,
2967+ // we don't need to do anything.
2968+ let use_lld = flavor. uses_lld ( ) || unstable_use_lld;
2969+ if !flavor_uses_cc || !use_lld {
2970+ return ;
2971+ }
2972+
2973+ // 1. Implement the "self-contained" part of this feature by adding rustc distribution
2974+ // directories to the tool's search path.
2975+ let self_contained_linker = sess. opts . cg . link_self_contained . linker ( ) || unstable_use_lld;
2976+ if self_contained_linker {
2977+ for path in sess. get_tools_search_paths ( false ) {
2978+ cmd. arg ( {
2979+ let mut arg = OsString :: from ( "-B" ) ;
2980+ arg. push ( path. join ( "gcc-ld" ) ) ;
2981+ arg
2982+ } ) ;
2983+ }
2984+ }
2985+
2986+ // 2. Implement the "linker flavor" part of this feature by asking `cc` to use some kind of
2987+ // `lld` as the linker.
2988+ cmd. arg ( "-fuse-ld=lld" ) ;
2989+
2990+ if !flavor. is_gnu ( ) {
2991+ // Tell clang to use a non-default LLD flavor.
2992+ // Gcc doesn't understand the target option, but we currently assume
2993+ // that gcc is not used for Apple and Wasm targets (#97402).
2994+ //
2995+ // Note that we don't want to do that by default on macOS: e.g. passing a
2996+ // 10.7 target to LLVM works, but not to recent versions of clang/macOS, as
2997+ // shown in issue #101653 and the discussion in PR #101792.
2998+ //
2999+ // It could be required in some cases of cross-compiling with
3000+ // `-Zgcc-ld=lld`, but this is generally unspecified, and we don't know
3001+ // which specific versions of clang, macOS SDK, host and target OS
3002+ // combinations impact us here.
3003+ //
3004+ // So we do a simple first-approximation until we know more of what the
3005+ // Apple targets require (and which would be handled prior to hitting this
3006+ // `-Zgcc-ld=lld` codepath anyway), but the expectation is that until then
3007+ // this should be manually passed if needed. We specify the target when
3008+ // targeting a different linker flavor on macOS, and that's also always
3009+ // the case when targeting WASM.
3010+ if sess. target . linker_flavor != sess. host . linker_flavor {
3011+ cmd. arg ( format ! ( "--target={}" , sess. target. llvm_target) ) ;
30003012 }
30013013 }
30023014}
0 commit comments