Skip to content

Commit 9b9bee4

Browse files
committed
Employ clang linker flavor for supporting cross-linking automatically
1 parent 76fbc12 commit 9b9bee4

File tree

6 files changed

+38
-56
lines changed

6 files changed

+38
-56
lines changed

Diff for: compiler/rustc_codegen_ssa/src/back/link.rs

+4-25
Original file line numberDiff line numberDiff line change
@@ -2284,6 +2284,10 @@ fn add_order_independent_options(
22842284
out_filename: &Path,
22852285
tmpdir: &Path,
22862286
) {
2287+
if flavor.uses_clang() && sess.target.linker_flavor != sess.host.linker_flavor {
2288+
cmd.arg(format!("--target={}", sess.target.llvm_target));
2289+
}
2290+
22872291
// Take care of the flavors and CLI options requesting the `lld` linker.
22882292
add_lld_args(cmd, sess, flavor, self_contained_components);
22892293

@@ -3053,29 +3057,4 @@ fn add_lld_args(
30533057
// 2. Implement the "linker flavor" part of this feature by asking `cc` to use some kind of
30543058
// `lld` as the linker.
30553059
cmd.arg("-fuse-ld=lld");
3056-
3057-
if !flavor.is_gnu() {
3058-
// Tell clang to use a non-default LLD flavor.
3059-
// Gcc doesn't understand the target option, but we currently assume
3060-
// that gcc is not used for Apple and Wasm targets (#97402).
3061-
//
3062-
// Note that we don't want to do that by default on macOS: e.g. passing a
3063-
// 10.7 target to LLVM works, but not to recent versions of clang/macOS, as
3064-
// shown in issue #101653 and the discussion in PR #101792.
3065-
//
3066-
// It could be required in some cases of cross-compiling with
3067-
// LLD, but this is generally unspecified, and we don't know
3068-
// which specific versions of clang, macOS SDK, host and target OS
3069-
// combinations impact us here.
3070-
//
3071-
// So we do a simple first-approximation until we know more of what the
3072-
// Apple targets require (and which would be handled prior to hitting this
3073-
// LLD codepath anyway), but the expectation is that until then
3074-
// this should be manually passed if needed. We specify the target when
3075-
// targeting a different linker flavor on macOS, and that's also always
3076-
// the case when targeting WASM.
3077-
if sess.target.linker_flavor != sess.host.linker_flavor {
3078-
cmd.arg(format!("--target={}", sess.target.llvm_target));
3079-
}
3080-
}
30813060
}

Diff for: compiler/rustc_target/src/spec/mod.rs

+30-5
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ use rustc_fs_util::try_canonicalize;
4343
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
4444
use rustc_span::symbol::{kw, sym, Symbol};
4545
use serde_json::Value;
46+
use std::assert_matches::assert_matches;
4647
use std::borrow::Cow;
4748
use std::collections::BTreeMap;
4849
use std::hash::{Hash, Hasher};
@@ -437,6 +438,17 @@ impl LinkerFlavor {
437438
| LinkerFlavor::Ptx => false,
438439
}
439440
}
441+
442+
pub fn uses_clang(self) -> bool {
443+
match self {
444+
LinkerFlavor::Gnu(Cc::Clang, _)
445+
| LinkerFlavor::Darwin(Cc::Clang, _)
446+
| LinkerFlavor::WasmLld(Cc::Clang)
447+
| LinkerFlavor::Unix(Cc::Clang)
448+
| LinkerFlavor::EmCc => true,
449+
_ => false,
450+
}
451+
}
440452
}
441453

442454
macro_rules! linker_flavor_cli_impls {
@@ -2185,21 +2197,34 @@ fn add_link_args_iter(
21852197
match flavor {
21862198
LinkerFlavor::Gnu(cc, lld) => {
21872199
assert_eq!(lld, Lld::No);
2200+
assert_matches!(cc, Cc::No | Cc::Yes);
21882201
insert(LinkerFlavor::Gnu(cc, Lld::Yes));
2202+
if cc == Cc::Yes {
2203+
insert(LinkerFlavor::Gnu(Cc::Clang, Lld::No));
2204+
insert(LinkerFlavor::Gnu(Cc::Clang, Lld::Yes));
2205+
}
21892206
}
21902207
LinkerFlavor::Darwin(cc, lld) => {
21912208
assert_eq!(lld, Lld::No);
2209+
assert_matches!(cc, Cc::No | Cc::Yes);
21922210
insert(LinkerFlavor::Darwin(cc, Lld::Yes));
2211+
if cc == Cc::Yes {
2212+
insert(LinkerFlavor::Darwin(Cc::Clang, Lld::No));
2213+
insert(LinkerFlavor::Darwin(Cc::Clang, Lld::Yes));
2214+
}
21932215
}
21942216
LinkerFlavor::Msvc(lld) => {
21952217
assert_eq!(lld, Lld::No);
21962218
insert(LinkerFlavor::Msvc(Lld::Yes));
21972219
}
2198-
LinkerFlavor::WasmLld(..)
2199-
| LinkerFlavor::Unix(..)
2200-
| LinkerFlavor::EmCc
2201-
| LinkerFlavor::Bpf
2202-
| LinkerFlavor::Ptx => {}
2220+
LinkerFlavor::WasmLld(cc) | LinkerFlavor::Unix(cc) => {
2221+
assert_matches!(cc, Cc::No | Cc::Yes);
2222+
if cc == Cc::Yes {
2223+
insert(LinkerFlavor::Gnu(Cc::Clang, Lld::No));
2224+
insert(LinkerFlavor::Gnu(Cc::Clang, Lld::Yes));
2225+
}
2226+
}
2227+
LinkerFlavor::EmCc | LinkerFlavor::Bpf | LinkerFlavor::Ptx => {}
22032228
}
22042229
}
22052230

Diff for: compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,7 @@ pub fn target() -> Target {
3535
"--no-entry",
3636
],
3737
);
38-
options.add_pre_link_args(
39-
LinkerFlavor::WasmLld(Cc::Yes),
40-
&[
41-
// Make sure clang uses LLD as its linker and is configured appropriately
42-
// otherwise
43-
"--target=wasm32-unknown-unknown",
44-
"-Wl,--no-entry",
45-
],
46-
);
38+
options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::Yes), &["-Wl,--no-entry"]);
4739

4840
Target {
4941
llvm_target: "wasm32-unknown-unknown".into(),

Diff for: compiler/rustc_target/src/spec/targets/wasm32_wasi.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,12 @@
7474
7575
use crate::spec::crt_objects;
7676
use crate::spec::LinkSelfContainedDefault;
77-
use crate::spec::{base, Cc, LinkerFlavor, Target};
77+
use crate::spec::{base, Target};
7878

7979
pub fn target() -> Target {
8080
let mut options = base::wasm::options();
8181

8282
options.os = "wasi".into();
83-
options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::Yes), &["--target=wasm32-wasi"]);
8483

8584
options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained();
8685
options.post_link_objects_self_contained = crt_objects::post_wasi_self_contained();

Diff for: compiler/rustc_target/src/spec/targets/wasm32_wasi_preview1_threads.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,7 @@ pub fn target() -> Target {
8585
);
8686
options.add_pre_link_args(
8787
LinkerFlavor::WasmLld(Cc::Yes),
88-
&[
89-
"--target=wasm32-wasi-threads",
90-
"-Wl,--import-memory",
91-
"-Wl,--export-memory,",
92-
"-Wl,--shared-memory",
93-
],
88+
&["-Wl,--import-memory", "-Wl,--export-memory,", "-Wl,--shared-memory"],
9489
);
9590

9691
options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained();

Diff for: compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,7 @@ pub fn target() -> Target {
2222
"-mwasm64",
2323
],
2424
);
25-
options.add_pre_link_args(
26-
LinkerFlavor::WasmLld(Cc::Yes),
27-
&[
28-
// Make sure clang uses LLD as its linker and is configured appropriately
29-
// otherwise
30-
"--target=wasm64-unknown-unknown",
31-
"-Wl,--no-entry",
32-
],
33-
);
25+
options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::Yes), &["-Wl,--no-entry"]);
3426

3527
// Any engine that implements wasm64 will surely implement the rest of these
3628
// features since they were all merged into the official spec by the time

0 commit comments

Comments
 (0)