Skip to content

Commit 982f4ba

Browse files
committed
Move link_args to MaybeLazy - part 1
Replace all the `pre_link_args: TargetOptions::link_args` to `MaybeLazy::lazy(|| TargetOptions::link_args(...))`
1 parent 7753afd commit 982f4ba

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+467
-366
lines changed

compiler/rustc_target/src/spec/base/apple/mod.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{borrow::Cow, env};
22

3-
use crate::spec::{add_link_args, add_link_args_iter};
3+
use crate::spec::{add_link_args, add_link_args_iter, MaybeLazy};
44
use crate::spec::{cvs, Cc, DebuginfoKind, FramePointer, LinkArgs, LinkerFlavor, Lld};
55
use crate::spec::{SplitDebuginfo, StackProbeType, StaticCow, Target, TargetOptions};
66

@@ -90,7 +90,9 @@ impl Arch {
9090
}
9191
}
9292

93-
fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs {
93+
pub fn pre_link_args(os: &'static str, arch: Arch) -> LinkArgs {
94+
let abi = arch.target_abi();
95+
9496
let platform_name: StaticCow<str> = match abi {
9597
"sim" => format!("{os}-simulator").into(),
9698
"macabi" => "mac-catalyst".into(),
@@ -136,7 +138,7 @@ fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs {
136138
args
137139
}
138140

139-
pub fn opts(os: &'static str, arch: Arch) -> TargetOptions {
141+
pub fn opts(os: &'static str, arch: Arch, pre_link_args: MaybeLazy<LinkArgs>) -> TargetOptions {
140142
let abi = arch.target_abi();
141143

142144
TargetOptions {
@@ -149,7 +151,7 @@ pub fn opts(os: &'static str, arch: Arch) -> TargetOptions {
149151
// macOS has -dead_strip, which doesn't rely on function_sections
150152
function_sections: false,
151153
dynamic_linking: true,
152-
pre_link_args: pre_link_args(os, arch, abi),
154+
pre_link_args,
153155
families: cvs!["unix"],
154156
is_like_osx: true,
155157
// LLVM notes that macOS 10.11+ and iOS 9+ default

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

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
use crate::spec::{Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions};
1+
use crate::spec::{Cc, LinkerFlavor, Lld, MaybeLazy, RelocModel, Target, TargetOptions};
22
use object::elf;
33

44
/// A base target for AVR devices using the GNU toolchain.
55
///
66
/// Requires GNU avr-gcc and avr-binutils on the host system.
7-
/// FIXME: Remove the second parameter when const string concatenation is possible.
8-
pub fn target(target_cpu: &'static str, mmcu: &'static str) -> Target {
7+
pub fn target(target_cpu: &'static str) -> Target {
98
Target {
109
arch: "avr".into(),
1110
metadata: crate::spec::TargetMetadata {
@@ -24,11 +23,12 @@ pub fn target(target_cpu: &'static str, mmcu: &'static str) -> Target {
2423

2524
linker: Some("avr-gcc".into()),
2625
eh_frame_header: false,
27-
pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[mmcu]),
28-
late_link_args: TargetOptions::link_args(
29-
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
30-
&["-lgcc"],
31-
),
26+
pre_link_args: MaybeLazy::lazy(|| {
27+
TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-mmcu=atmega328"])
28+
}),
29+
late_link_args: MaybeLazy::lazy(|| {
30+
TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-lgcc"])
31+
}),
3232
max_atomic_width: Some(16),
3333
atomic_cas: false,
3434
relocation_model: RelocModel::Static,

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

+19-17
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, TargetOptions,
2+
crt_objects, cvs, Cc, FramePointer, LinkOutputKind, LinkerFlavor, Lld, MaybeLazy, TargetOptions,
33
};
44

55
pub fn opts() -> TargetOptions {
@@ -8,22 +8,24 @@ pub fn opts() -> TargetOptions {
88
// so we only list them for ld/lld.
99
//
1010
// https://github.com/llvm/llvm-project/blob/db9322b2066c55254e7691efeab863f43bfcc084/clang/lib/Driver/ToolChains/Fuchsia.cpp#L31
11-
let pre_link_args = TargetOptions::link_args(
12-
LinkerFlavor::Gnu(Cc::No, Lld::No),
13-
&[
14-
"--build-id",
15-
"--hash-style=gnu",
16-
"-z",
17-
"max-page-size=4096",
18-
"-z",
19-
"now",
20-
"-z",
21-
"rodynamic",
22-
"-z",
23-
"separate-loadable-segments",
24-
"--pack-dyn-relocs=relr",
25-
],
26-
);
11+
let pre_link_args = MaybeLazy::lazy(|| {
12+
TargetOptions::link_args(
13+
LinkerFlavor::Gnu(Cc::No, Lld::No),
14+
&[
15+
"--build-id",
16+
"--hash-style=gnu",
17+
"-z",
18+
"max-page-size=4096",
19+
"-z",
20+
"now",
21+
"-z",
22+
"rodynamic",
23+
"-z",
24+
"separate-loadable-segments",
25+
"--pack-dyn-relocs=relr",
26+
],
27+
)
28+
});
2729

2830
TargetOptions {
2931
os: "fuchsia".into(),

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

+25-23
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,30 @@
1-
use crate::spec::{cvs, Cc, FramePointer, LinkerFlavor, TargetOptions};
1+
use crate::spec::{cvs, Cc, FramePointer, LinkerFlavor, MaybeLazy, TargetOptions};
22

33
pub fn opts() -> TargetOptions {
4-
let late_link_args = TargetOptions::link_args(
5-
LinkerFlavor::Unix(Cc::Yes),
6-
&[
7-
// The illumos libc contains a stack unwinding implementation, as
8-
// does libgcc_s. The latter implementation includes several
9-
// additional symbols that are not always in base libc. To force
10-
// the consistent use of just one unwinder, we ensure libc appears
11-
// after libgcc_s in the NEEDED list for the resultant binary by
12-
// ignoring any attempts to add it as a dynamic dependency until the
13-
// very end.
14-
// FIXME: This should be replaced by a more complete and generic
15-
// mechanism for controlling the order of library arguments passed
16-
// to the linker.
17-
"-lc",
18-
// LLVM will insert calls to the stack protector functions
19-
// "__stack_chk_fail" and "__stack_chk_guard" into code in native
20-
// object files. Some platforms include these symbols directly in
21-
// libc, but at least historically these have been provided in
22-
// libssp.so on illumos and Solaris systems.
23-
"-lssp",
24-
],
25-
);
4+
let late_link_args = MaybeLazy::lazy(|| {
5+
TargetOptions::link_args(
6+
LinkerFlavor::Unix(Cc::Yes),
7+
&[
8+
// The illumos libc contains a stack unwinding implementation, as
9+
// does libgcc_s. The latter implementation includes several
10+
// additional symbols that are not always in base libc. To force
11+
// the consistent use of just one unwinder, we ensure libc appears
12+
// after libgcc_s in the NEEDED list for the resultant binary by
13+
// ignoring any attempts to add it as a dynamic dependency until the
14+
// very end.
15+
// FIXME: This should be replaced by a more complete and generic
16+
// mechanism for controlling the order of library arguments passed
17+
// to the linker.
18+
"-lc",
19+
// LLVM will insert calls to the stack protector functions
20+
// "__stack_chk_fail" and "__stack_chk_guard" into code in native
21+
// object files. Some platforms include these symbols directly in
22+
// libc, but at least historically these have been provided in
23+
// libssp.so on illumos and Solaris systems.
24+
"-lssp",
25+
],
26+
)
27+
});
2628

2729
TargetOptions {
2830
os: "illumos".into(),

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
use crate::spec::{DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions};
1+
use crate::spec::{DebuginfoKind, LinkerFlavor, Lld, MaybeLazy, SplitDebuginfo, TargetOptions};
22
use std::borrow::Cow;
33

44
pub fn opts() -> TargetOptions {
55
// Suppress the verbose logo and authorship debugging output, which would needlessly
66
// clog any log files.
7-
let pre_link_args = TargetOptions::link_args(LinkerFlavor::Msvc(Lld::No), &["/NOLOGO"]);
7+
let pre_link_args =
8+
MaybeLazy::lazy(|| TargetOptions::link_args(LinkerFlavor::Msvc(Lld::No), &["/NOLOGO"]));
89

910
TargetOptions {
1011
linker_flavor: LinkerFlavor::Msvc(Lld::No),

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

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

35
pub fn opts() -> TargetOptions {
4-
let lld_args = &["-zmax-page-size=4096", "-znow", "-ztext", "--execute-only"];
5-
let cc_args = &["-Wl,-zmax-page-size=4096", "-Wl,-znow", "-Wl,-ztext", "-mexecute-only"];
6-
7-
let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), lld_args);
8-
add_link_args(&mut pre_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), cc_args);
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(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+
});
914

1015
TargetOptions {
1116
os: "teeos".into(),

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

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

66
pub fn options() -> TargetOptions {
@@ -48,8 +48,11 @@ pub fn options() -> TargetOptions {
4848
};
4949
}
5050

51-
let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::WasmLld(Cc::No), args!(""));
52-
add_link_args(&mut pre_link_args, LinkerFlavor::WasmLld(Cc::Yes), args!("-Wl,"));
51+
let pre_link_args = MaybeLazy::lazy(|| {
52+
let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::WasmLld(Cc::No), args!(""));
53+
add_link_args(&mut pre_link_args, LinkerFlavor::WasmLld(Cc::Yes), args!("-Wl,"));
54+
pre_link_args
55+
});
5356

5457
TargetOptions {
5558
is_like_wasm: true,

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

+70-58
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,87 @@
1-
use crate::spec::LinkSelfContainedDefault;
21
use crate::spec::{add_link_args, crt_objects};
32
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 mut pre_link_args = TargetOptions::link_args(
8-
LinkerFlavor::Gnu(Cc::No, Lld::No),
9-
&[
10-
// Enable ASLR
11-
"--dynamicbase",
12-
// ASLR will rebase it anyway so leaving that option enabled only leads to confusion
13-
"--disable-auto-image-base",
14-
],
15-
);
16-
add_link_args(
17-
&mut pre_link_args,
18-
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
19-
&[
20-
// Tell GCC to avoid linker plugins, because we are not bundling
21-
// them with Windows installer, and Rust does its own LTO anyways.
22-
"-fno-use-linker-plugin",
23-
"-Wl,--dynamicbase",
24-
"-Wl,--disable-auto-image-base",
25-
],
26-
);
7+
let pre_link_args = MaybeLazy::lazy(|| {
8+
let mut pre_link_args = TargetOptions::link_args(
9+
LinkerFlavor::Gnu(Cc::No, Lld::No),
10+
&[
11+
// Enable ASLR
12+
"--dynamicbase",
13+
// ASLR will rebase it anyway so leaving that option enabled only leads to confusion
14+
"--disable-auto-image-base",
15+
],
16+
);
17+
add_link_args(
18+
&mut pre_link_args,
19+
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
20+
&[
21+
// Tell GCC to avoid linker plugins, because we are not bundling
22+
// them with Windows installer, and Rust does its own LTO anyways.
23+
"-fno-use-linker-plugin",
24+
"-Wl,--dynamicbase",
25+
"-Wl,--disable-auto-image-base",
26+
],
27+
);
28+
pre_link_args
29+
});
2730

28-
// Order of `late_link_args*` was found through trial and error to work with various
29-
// mingw-w64 versions (not tested on the CI). It's expected to change from time to time.
30-
let mingw_libs = &[
31-
"-lmsvcrt",
32-
"-lmingwex",
33-
"-lmingw32",
34-
"-lgcc", // alas, mingw* libraries above depend on libgcc
35-
// mingw's msvcrt is a weird hybrid import library and static library.
36-
// And it seems that the linker fails to use import symbols from msvcrt
37-
// that are required from functions in msvcrt in certain cases. For example
38-
// `_fmode` that is used by an implementation of `__p__fmode` in x86_64.
39-
// The library is purposely listed twice to fix that.
40-
//
41-
// See https://github.com/rust-lang/rust/pull/47483 for some more details.
42-
"-lmsvcrt",
43-
"-luser32",
44-
"-lkernel32",
45-
];
46-
let mut late_link_args =
47-
TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), mingw_libs);
48-
add_link_args(&mut late_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), mingw_libs);
31+
let late_link_args = MaybeLazy::lazy(|| {
32+
// Order of `late_link_args*` was found through trial and error to work with various
33+
// mingw-w64 versions (not tested on the CI). It's expected to change from time to time.
34+
let mingw_libs = &[
35+
"-lmsvcrt",
36+
"-lmingwex",
37+
"-lmingw32",
38+
"-lgcc", // alas, mingw* libraries above depend on libgcc
39+
// mingw's msvcrt is a weird hybrid import library and static library.
40+
// And it seems that the linker fails to use import symbols from msvcrt
41+
// that are required from functions in msvcrt in certain cases. For example
42+
// `_fmode` that is used by an implementation of `__p__fmode` in x86_64.
43+
// The library is purposely listed twice to fix that.
44+
//
45+
// See https://github.com/rust-lang/rust/pull/47483 for some more details.
46+
"-lmsvcrt",
47+
"-luser32",
48+
"-lkernel32",
49+
];
50+
let mut late_link_args =
51+
TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), mingw_libs);
52+
add_link_args(&mut late_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), mingw_libs);
53+
late_link_args
54+
});
4955
// If any of our crates are dynamically linked then we need to use
5056
// the shared libgcc_s-dw2-1.dll. This is required to support
5157
// unwinding across DLL boundaries.
52-
let dynamic_unwind_libs = &["-lgcc_s"];
53-
let mut late_link_args_dynamic =
54-
TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), dynamic_unwind_libs);
55-
add_link_args(
56-
&mut late_link_args_dynamic,
57-
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
58-
dynamic_unwind_libs,
59-
);
58+
let late_link_args_dynamic = MaybeLazy::lazy(|| {
59+
let dynamic_unwind_libs = &["-lgcc_s"];
60+
let mut late_link_args_dynamic =
61+
TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), dynamic_unwind_libs);
62+
add_link_args(
63+
&mut late_link_args_dynamic,
64+
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
65+
dynamic_unwind_libs,
66+
);
67+
late_link_args_dynamic
68+
});
6069
// If all of our crates are statically linked then we can get away
6170
// with statically linking the libgcc unwinding code. This allows
6271
// binaries to be redistributed without the libgcc_s-dw2-1.dll
6372
// dependency, but unfortunately break unwinding across DLL
6473
// boundaries when unwinding across FFI boundaries.
65-
let static_unwind_libs = &["-lgcc_eh", "-l:libpthread.a"];
66-
let mut late_link_args_static =
67-
TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), static_unwind_libs);
68-
add_link_args(
69-
&mut late_link_args_static,
70-
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
71-
static_unwind_libs,
72-
);
74+
let late_link_args_static = MaybeLazy::lazy(|| {
75+
let static_unwind_libs = &["-lgcc_eh", "-l:libpthread.a"];
76+
let mut late_link_args_static =
77+
TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), static_unwind_libs);
78+
add_link_args(
79+
&mut late_link_args_static,
80+
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
81+
static_unwind_libs,
82+
);
83+
late_link_args_static
84+
});
7385

7486
TargetOptions {
7587
os: "windows".into(),

0 commit comments

Comments
 (0)