Skip to content

Commit 9f6c856

Browse files
committed
Make TargetOptions::link_args stateful lazy - part 2
by adding `TargetOptions::link_args_list` to handle multi link args
1 parent 7f55449 commit 9f6c856

15 files changed

+119
-170
lines changed

compiler/rustc_target/src/spec/base/fuchsia.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::spec::{
2-
crt_objects, cvs, Cc, FramePointer, LinkOutputKind, LinkerFlavor, Lld, MaybeLazy, TargetOptions,
2+
crt_objects, cvs, Cc, FramePointer, LinkOutputKind, LinkerFlavor, Lld, TargetOptions,
33
};
44

55
pub fn opts() -> TargetOptions {

compiler/rustc_target/src/spec/base/teeos.rs

+10-11
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
1-
use crate::spec::{
2-
add_link_args, Cc, LinkerFlavor, Lld, MaybeLazy, PanicStrategy, RelroLevel, TargetOptions,
3-
};
1+
use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelroLevel, TargetOptions};
42

53
pub fn opts() -> TargetOptions {
6-
let pre_link_args = MaybeLazy::lazy(|| {
7-
let lld_args = &["-zmax-page-size=4096", "-znow", "-ztext", "--execute-only"];
8-
let cc_args = &["-Wl,-zmax-page-size=4096", "-Wl,-znow", "-Wl,-ztext", "-mexecute-only"];
9-
let mut pre_link_args =
10-
TargetOptions::link_args_base(LinkerFlavor::Gnu(Cc::No, Lld::No), lld_args);
11-
add_link_args(&mut pre_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), cc_args);
12-
pre_link_args
13-
});
4+
let pre_link_args = {
5+
const LLD_ARGS: &[&str] = &["-zmax-page-size=4096", "-znow", "-ztext", "--execute-only"];
6+
const CC_ARGS: &[&str] =
7+
&["-Wl,-zmax-page-size=4096", "-Wl,-znow", "-Wl,-ztext", "-mexecute-only"];
8+
TargetOptions::link_args_list(&[
9+
(LinkerFlavor::Gnu(Cc::No, Lld::No), LLD_ARGS),
10+
(LinkerFlavor::Gnu(Cc::Yes, Lld::No), CC_ARGS),
11+
])
12+
};
1413

1514
TargetOptions {
1615
os: "teeos".into(),

compiler/rustc_target/src/spec/base/wasm.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
use crate::spec::{
2-
add_link_args, cvs, Cc, LinkSelfContainedDefault, LinkerFlavor, MaybeLazy, PanicStrategy,
3-
RelocModel, TargetOptions, TlsModel,
4-
};
1+
use crate::spec::{cvs, Cc, LinkSelfContainedDefault, LinkerFlavor, PanicStrategy};
2+
use crate::spec::{RelocModel, TargetOptions, TlsModel};
53

64
pub fn options() -> TargetOptions {
75
macro_rules! args {
@@ -48,12 +46,10 @@ pub fn options() -> TargetOptions {
4846
};
4947
}
5048

51-
let pre_link_args = MaybeLazy::lazy(|| {
52-
let mut pre_link_args =
53-
TargetOptions::link_args_base(LinkerFlavor::WasmLld(Cc::No), args!(""));
54-
add_link_args(&mut pre_link_args, LinkerFlavor::WasmLld(Cc::Yes), args!("-Wl,"));
55-
pre_link_args
56-
});
49+
let pre_link_args = TargetOptions::link_args_list(&[
50+
(LinkerFlavor::WasmLld(Cc::No), args!("")),
51+
(LinkerFlavor::WasmLld(Cc::Yes), args!("-Wl,")),
52+
]);
5753

5854
TargetOptions {
5955
is_like_wasm: true,

compiler/rustc_target/src/spec/base/windows_gnu.rs

+29-39
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
1-
use crate::spec::{add_link_args, crt_objects};
1+
use crate::spec::crt_objects;
2+
use crate::spec::LinkSelfContainedDefault;
23
use crate::spec::{cvs, Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions};
3-
use crate::spec::{LinkSelfContainedDefault, MaybeLazy};
44
use std::borrow::Cow;
55

66
pub fn opts() -> TargetOptions {
7-
let pre_link_args = MaybeLazy::lazy(|| {
8-
let mut pre_link_args = TargetOptions::link_args_base(
7+
let pre_link_args = TargetOptions::link_args_list(&[
8+
(
99
LinkerFlavor::Gnu(Cc::No, Lld::No),
1010
&[
1111
// Enable ASLR
1212
"--dynamicbase",
1313
// ASLR will rebase it anyway so leaving that option enabled only leads to confusion
1414
"--disable-auto-image-base",
1515
],
16-
);
17-
add_link_args(
18-
&mut pre_link_args,
16+
),
17+
(
1918
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
2019
&[
2120
// Tell GCC to avoid linker plugins, because we are not bundling
@@ -24,14 +23,13 @@ pub fn opts() -> TargetOptions {
2423
"-Wl,--dynamicbase",
2524
"-Wl,--disable-auto-image-base",
2625
],
27-
);
28-
pre_link_args
29-
});
26+
),
27+
]);
3028

31-
let late_link_args = MaybeLazy::lazy(|| {
29+
let late_link_args = {
3230
// Order of `late_link_args*` was found through trial and error to work with various
3331
// mingw-w64 versions (not tested on the CI). It's expected to change from time to time.
34-
let mingw_libs = &[
32+
const MINGW_LIBS: &[&str] = &[
3533
"-lmsvcrt",
3634
"-lmingwex",
3735
"-lmingw32",
@@ -50,41 +48,33 @@ pub fn opts() -> TargetOptions {
5048
"-luser32",
5149
"-lkernel32",
5250
];
53-
let mut late_link_args =
54-
TargetOptions::link_args_base(LinkerFlavor::Gnu(Cc::No, Lld::No), mingw_libs);
55-
add_link_args(&mut late_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), mingw_libs);
56-
late_link_args
57-
});
51+
TargetOptions::link_args_list(&[
52+
(LinkerFlavor::Gnu(Cc::No, Lld::No), MINGW_LIBS),
53+
(LinkerFlavor::Gnu(Cc::Yes, Lld::No), MINGW_LIBS),
54+
])
55+
};
5856
// If any of our crates are dynamically linked then we need to use
5957
// the shared libgcc_s-dw2-1.dll. This is required to support
6058
// unwinding across DLL boundaries.
61-
let late_link_args_dynamic = MaybeLazy::lazy(|| {
62-
let dynamic_unwind_libs = &["-lgcc_s"];
63-
let mut late_link_args_dynamic =
64-
TargetOptions::link_args_base(LinkerFlavor::Gnu(Cc::No, Lld::No), dynamic_unwind_libs);
65-
add_link_args(
66-
&mut late_link_args_dynamic,
67-
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
68-
dynamic_unwind_libs,
69-
);
70-
late_link_args_dynamic
71-
});
59+
let late_link_args_dynamic = {
60+
const DYNAMIC_UNWIND_LIBS: &[&str] = &["-lgcc_s"];
61+
TargetOptions::link_args_list(&[
62+
(LinkerFlavor::Gnu(Cc::No, Lld::No), DYNAMIC_UNWIND_LIBS),
63+
(LinkerFlavor::Gnu(Cc::Yes, Lld::No), DYNAMIC_UNWIND_LIBS),
64+
])
65+
};
7266
// If all of our crates are statically linked then we can get away
7367
// with statically linking the libgcc unwinding code. This allows
7468
// binaries to be redistributed without the libgcc_s-dw2-1.dll
7569
// dependency, but unfortunately break unwinding across DLL
7670
// boundaries when unwinding across FFI boundaries.
77-
let late_link_args_static = MaybeLazy::lazy(|| {
78-
let static_unwind_libs = &["-lgcc_eh", "-l:libpthread.a"];
79-
let mut late_link_args_static =
80-
TargetOptions::link_args_base(LinkerFlavor::Gnu(Cc::No, Lld::No), static_unwind_libs);
81-
add_link_args(
82-
&mut late_link_args_static,
83-
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
84-
static_unwind_libs,
85-
);
86-
late_link_args_static
87-
});
71+
let late_link_args_static = {
72+
const STATIC_UNWIND_LIBS: &[&str] = &["-lgcc_eh", "-l:libpthread.a"];
73+
TargetOptions::link_args_list(&[
74+
(LinkerFlavor::Gnu(Cc::No, Lld::No), STATIC_UNWIND_LIBS),
75+
(LinkerFlavor::Gnu(Cc::Yes, Lld::No), STATIC_UNWIND_LIBS),
76+
])
77+
};
8878

8979
TargetOptions {
9080
os: "windows".into(),

compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
use crate::spec::{add_link_args, base, Cc, LinkArgs, LinkerFlavor, Lld, MaybeLazy, TargetOptions};
1+
use crate::spec::{base, Cc, LinkerFlavor, Lld, TargetOptions};
22

33
pub fn opts() -> TargetOptions {
44
let base = base::windows_gnu::opts();
55

6-
let late_link_args = MaybeLazy::lazy(|| {
6+
let late_link_args = {
77
// FIXME: This should be updated for the exception machinery changes from #67502
88
// and inherit from `windows_gnu_base`, at least partially.
9-
let mingw_libs = &[
9+
const MINGW_LIBS: &[&str] = &[
1010
"-lwinstorecompat",
1111
"-lruntimeobject",
1212
"-lsynchronization",
@@ -16,14 +16,14 @@ pub fn opts() -> TargetOptions {
1616
"-lmingwex",
1717
"-lmingw32",
1818
];
19-
let mut late_link_args =
20-
TargetOptions::link_args_base(LinkerFlavor::Gnu(Cc::No, Lld::No), mingw_libs);
21-
add_link_args(&mut late_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), mingw_libs);
22-
late_link_args
23-
});
19+
TargetOptions::link_args_list(&[
20+
(LinkerFlavor::Gnu(Cc::No, Lld::No), MINGW_LIBS),
21+
(LinkerFlavor::Gnu(Cc::Yes, Lld::No), MINGW_LIBS),
22+
])
23+
};
2424
// Reset the flags back to empty until the FIXME above is addressed.
25-
let late_link_args_dynamic = MaybeLazy::lazy(LinkArgs::new);
26-
let late_link_args_static = MaybeLazy::lazy(LinkArgs::new);
25+
let late_link_args_dynamic = Default::default();
26+
let late_link_args_static = Default::default();
2727

2828
TargetOptions {
2929
abi: "uwp".into(),
+16-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! Linker arguments
22
3+
use crate::spec::add_link_args;
34
use crate::spec::{LinkerFlavor, LinkerFlavorCli};
4-
use crate::spec::{MaybeLazy, TargetOptions};
5-
use crate::spec::StaticCow;
5+
use crate::spec::{MaybeLazy, StaticCow};
66

77
use std::collections::BTreeMap;
88

@@ -12,15 +12,26 @@ pub type LinkArgsCli = BTreeMap<LinkerFlavorCli, Vec<StaticCow<str>>>;
1212
pub type LazyLinkArgs = MaybeLazy<LinkArgs, LazyLinkArgsState>;
1313

1414
pub(super) enum LazyLinkArgsState {
15-
Simple(LinkerFlavor, &'static [&'static str])
15+
Simple(LinkerFlavor, &'static [&'static str]),
16+
List(&'static [(LinkerFlavor, &'static [&'static str])]),
1617
}
1718

1819
impl FnOnce<()> for LazyLinkArgsState {
1920
type Output = LinkArgs;
2021
extern "rust-call" fn call_once(self, _args: ()) -> Self::Output {
2122
match self {
22-
LazyLinkArgsState::Simple(flavor, args) =>
23-
TargetOptions::link_args_base(flavor, args),
23+
LazyLinkArgsState::Simple(flavor, args) => {
24+
let mut link_args = LinkArgs::new();
25+
add_link_args(&mut link_args, flavor, args);
26+
link_args
27+
}
28+
LazyLinkArgsState::List(l) => {
29+
let mut link_args = LinkArgs::new();
30+
for (flavor, args) in l {
31+
add_link_args(&mut link_args, *flavor, args)
32+
}
33+
link_args
34+
}
2435
}
2536
}
2637
}

compiler/rustc_target/src/spec/mod.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -2394,10 +2394,8 @@ impl TargetOptions {
23942394
MaybeLazy::lazied(link_args::LazyLinkArgsState::Simple(flavor, args))
23952395
}
23962396

2397-
fn link_args_base(flavor: LinkerFlavor, args: &[&'static str]) -> LinkArgs {
2398-
let mut link_args = LinkArgs::new();
2399-
add_link_args(&mut link_args, flavor, args);
2400-
link_args
2397+
fn link_args_list(list: &'static [(LinkerFlavor, &'static [&'static str])]) -> LazyLinkArgs {
2398+
MaybeLazy::lazied(link_args::LazyLinkArgsState::List(list))
24012399
}
24022400

24032401
fn update_from_cli(&mut self) {

compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs

+6-14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use crate::spec::{add_link_args, base, Cc, FramePointer};
2-
use crate::spec::{LinkerFlavor, Lld, MaybeLazy, Target, TargetOptions};
1+
use crate::spec::{base, Cc, FramePointer};
2+
use crate::spec::{LinkerFlavor, Lld, Target, TargetOptions};
33

44
pub fn target() -> Target {
55
let mut base = base::windows_gnu::opts();
@@ -10,18 +10,10 @@ pub fn target() -> Target {
1010

1111
// Mark all dynamic libraries and executables as compatible with the larger 4GiB address
1212
// space available to x86 Windows binaries on x86_64.
13-
base.pre_link_args = MaybeLazy::lazy(|| {
14-
let mut pre_link_args = TargetOptions::link_args_base(
15-
LinkerFlavor::Gnu(Cc::No, Lld::No),
16-
&["-m", "i386pe", "--large-address-aware"],
17-
);
18-
add_link_args(
19-
&mut pre_link_args,
20-
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
21-
&["-Wl,--large-address-aware"],
22-
);
23-
pre_link_args
24-
});
13+
base.pre_link_args = TargetOptions::link_args_list(&[
14+
(LinkerFlavor::Gnu(Cc::No, Lld::No), &["-m", "i386pe", "--large-address-aware"]),
15+
(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-Wl,--large-address-aware"]),
16+
]);
2517

2618
Target {
2719
llvm_target: "i686-pc-windows-gnu".into(),

compiler/rustc_target/src/spec/targets/i686_uwp_windows_gnu.rs

+6-14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use crate::spec::{add_link_args, base, Cc, FramePointer};
2-
use crate::spec::{LinkerFlavor, Lld, MaybeLazy, Target, TargetOptions};
1+
use crate::spec::{base, Cc, FramePointer};
2+
use crate::spec::{LinkerFlavor, Lld, Target, TargetOptions};
33

44
pub fn target() -> Target {
55
let mut base = base::windows_uwp_gnu::opts();
@@ -9,18 +9,10 @@ pub fn target() -> Target {
99

1010
// Mark all dynamic libraries and executables as compatible with the larger 4GiB address
1111
// space available to x86 Windows binaries on x86_64.
12-
base.pre_link_args = MaybeLazy::lazy(|| {
13-
let mut pre_link_args = TargetOptions::link_args_base(
14-
LinkerFlavor::Gnu(Cc::No, Lld::No),
15-
&["-m", "i386pe", "--large-address-aware"],
16-
);
17-
add_link_args(
18-
&mut pre_link_args,
19-
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
20-
&["-Wl,--large-address-aware"],
21-
);
22-
pre_link_args
23-
});
12+
base.pre_link_args = TargetOptions::link_args_list(&[
13+
(LinkerFlavor::Gnu(Cc::No, Lld::No), &["-m", "i386pe", "--large-address-aware"]),
14+
(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-Wl,--large-address-aware"]),
15+
]);
2416

2517
Target {
2618
llvm_target: "i686-pc-windows-gnu".into(),

compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
use crate::spec::{
2-
base, cvs, LinkArgs, LinkerFlavor, MaybeLazy, PanicStrategy, RelocModel, Target, TargetOptions,
3-
};
1+
use crate::spec::{base, cvs, LinkerFlavor, PanicStrategy};
2+
use crate::spec::{RelocModel, Target, TargetOptions};
43

54
pub fn target() -> Target {
65
// Reset flags for non-Em flavors back to empty to satisfy sanity checking tests.
7-
let pre_link_args = MaybeLazy::lazy(LinkArgs::new);
6+
let pre_link_args = Default::default();
87
let post_link_args = TargetOptions::link_args(LinkerFlavor::EmCc, &["-sABORTING_MALLOC=0"]);
98

109
let opts = TargetOptions {

compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs

+7-11
Original file line numberDiff line numberDiff line change
@@ -9,35 +9,31 @@
99
//!
1010
//! This target is more or less managed by the Rust and WebAssembly Working
1111
//! Group nowadays at <https://github.com/rustwasm>.
12-
13-
use crate::spec::add_link_args;
14-
use crate::spec::{base, Cc, LinkerFlavor, MaybeLazy, Target, TargetOptions};
12+
use crate::spec::{base, Cc, LinkerFlavor, Target, TargetOptions};
1513

1614
pub fn target() -> Target {
1715
let mut options = base::wasm::options();
1816
options.os = "unknown".into();
1917

20-
options.pre_link_args = MaybeLazy::lazy(|| {
21-
let mut pre_link_args = TargetOptions::link_args_base(
18+
options.pre_link_args = TargetOptions::link_args_list(&[
19+
(
2220
LinkerFlavor::WasmLld(Cc::No),
2321
&[
2422
// For now this target just never has an entry symbol no matter the output
2523
// type, so unconditionally pass this.
2624
"--no-entry",
2725
],
28-
);
29-
add_link_args(
30-
&mut pre_link_args,
26+
),
27+
(
3128
LinkerFlavor::WasmLld(Cc::Yes),
3229
&[
3330
// Make sure clang uses LLD as its linker and is configured appropriately
3431
// otherwise
3532
"--target=wasm32-unknown-unknown",
3633
"-Wl,--no-entry",
3734
],
38-
);
39-
pre_link_args
40-
});
35+
),
36+
]);
4137

4238
Target {
4339
llvm_target: "wasm32-unknown-unknown".into(),

0 commit comments

Comments
 (0)