Skip to content

Lazify more work in builtins targets #122703

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 12 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/rustc_target/src/lib.rs
Original file line number Diff line number Diff line change
@@ -12,11 +12,13 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(fn_traits)]
#![feature(iter_intersperse)]
#![feature(let_chains)]
#![feature(min_exhaustive_patterns)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
#![feature(unboxed_closures)]
// tidy-alphabetical-end

use std::path::{Path, PathBuf};
14 changes: 10 additions & 4 deletions compiler/rustc_target/src/spec/base/apple/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::{borrow::Cow, env};

use crate::spec::{add_link_args, add_link_args_iter};
use crate::spec::link_args::LazyLinkArgsState;
use crate::spec::{add_link_args, add_link_args_iter, MaybeLazy};
use crate::spec::{cvs, Cc, DebuginfoKind, FramePointer, LinkArgs, LinkerFlavor, Lld};
use crate::spec::{SplitDebuginfo, StackProbeType, StaticCow, Target, TargetOptions};

@@ -94,7 +95,10 @@ impl TargetAbi {
}
}

fn pre_link_args(os: &'static str, arch: Arch, abi: TargetAbi) -> LinkArgs {
pub(crate) type ApplePreLinkArgs =
(/*os:*/ &'static str, /*arch:*/ Arch, /*abi:*/ TargetAbi);

pub(crate) fn pre_link_args((os, arch, abi): ApplePreLinkArgs) -> LinkArgs {
let platform_name: StaticCow<str> = match abi {
TargetAbi::Normal => os.into(),
TargetAbi::Simulator => format!("{os}-simulator").into(),
@@ -114,7 +118,9 @@ fn pre_link_args(os: &'static str, arch: Arch, abi: TargetAbi) -> LinkArgs {
};
let sdk_version = min_version.clone();

let mut args = TargetOptions::link_args(
let mut args = LinkArgs::new();
add_link_args(
&mut args,
LinkerFlavor::Darwin(Cc::No, Lld::No),
&["-arch", arch.target_name(), "-platform_version"],
);
@@ -151,7 +157,7 @@ pub fn opts(os: &'static str, arch: Arch, abi: TargetAbi) -> TargetOptions {
// macOS has -dead_strip, which doesn't rely on function_sections
function_sections: false,
dynamic_linking: true,
pre_link_args: pre_link_args(os, arch, abi),
pre_link_args: MaybeLazy::lazied(LazyLinkArgsState::Apple((os, arch, abi))),
families: cvs!["unix"],
is_like_osx: true,
// LLVM notes that macOS 10.11+ and iOS 9+ default
8 changes: 5 additions & 3 deletions compiler/rustc_target/src/spec/base/avr_gnu.rs
Original file line number Diff line number Diff line change
@@ -4,8 +4,7 @@ use object::elf;
/// A base target for AVR devices using the GNU toolchain.
///
/// Requires GNU avr-gcc and avr-binutils on the host system.
/// FIXME: Remove the second parameter when const string concatenation is possible.
pub fn target(target_cpu: &'static str, mmcu: &'static str) -> Target {
pub fn target(target_cpu: &'static str) -> Target {
Target {
arch: "avr".into(),
metadata: crate::spec::TargetMetadata {
@@ -24,7 +23,10 @@ pub fn target(target_cpu: &'static str, mmcu: &'static str) -> Target {

linker: Some("avr-gcc".into()),
eh_frame_header: false,
pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[mmcu]),
pre_link_args: TargetOptions::link_args(
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
&["-mmcu=atmega328"],
),
late_link_args: TargetOptions::link_args(
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
&["-lgcc"],
16 changes: 10 additions & 6 deletions compiler/rustc_target/src/spec/base/teeos.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
use crate::spec::{add_link_args, Cc, LinkerFlavor, Lld, PanicStrategy, RelroLevel, TargetOptions};
use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelroLevel, TargetOptions};

pub fn opts() -> TargetOptions {
let lld_args = &["-zmax-page-size=4096", "-znow", "-ztext", "--execute-only"];
let cc_args = &["-Wl,-zmax-page-size=4096", "-Wl,-znow", "-Wl,-ztext", "-mexecute-only"];

let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), lld_args);
add_link_args(&mut pre_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), cc_args);
let pre_link_args = {
const LLD_ARGS: &[&str] = &["-zmax-page-size=4096", "-znow", "-ztext", "--execute-only"];
const CC_ARGS: &[&str] =
&["-Wl,-zmax-page-size=4096", "-Wl,-znow", "-Wl,-ztext", "-mexecute-only"];
TargetOptions::link_args_list(&[
(LinkerFlavor::Gnu(Cc::No, Lld::No), LLD_ARGS),
(LinkerFlavor::Gnu(Cc::Yes, Lld::No), CC_ARGS),
])
};

TargetOptions {
os: "teeos".into(),
5 changes: 3 additions & 2 deletions compiler/rustc_target/src/spec/base/uefi_msvc.rs
Original file line number Diff line number Diff line change
@@ -9,12 +9,13 @@
// the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all
// code runs in the same environment, no process separation is supported.

use crate::spec::{base, LinkerFlavor, Lld, PanicStrategy, StackProbeType, TargetOptions};
use crate::spec::{base, LinkerFlavor, Lld};
use crate::spec::{PanicStrategy, StackProbeType, TargetOptions};

pub fn opts() -> TargetOptions {
let mut base = base::msvc::opts();

base.add_pre_link_args(
base.pre_link_args = TargetOptions::link_args(
LinkerFlavor::Msvc(Lld::No),
&[
// Non-standard subsystems have no default entry-point in PE+ files. We have to define
12 changes: 6 additions & 6 deletions compiler/rustc_target/src/spec/base/wasm.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use crate::spec::{
add_link_args, cvs, Cc, LinkSelfContainedDefault, LinkerFlavor, PanicStrategy, RelocModel,
TargetOptions, TlsModel,
};
use crate::spec::{cvs, Cc, LinkSelfContainedDefault, LinkerFlavor, PanicStrategy};
use crate::spec::{RelocModel, TargetOptions, TlsModel};

pub fn options() -> TargetOptions {
macro_rules! args {
@@ -48,8 +46,10 @@ pub fn options() -> TargetOptions {
};
}

let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::WasmLld(Cc::No), args!(""));
add_link_args(&mut pre_link_args, LinkerFlavor::WasmLld(Cc::Yes), args!("-Wl,"));
let pre_link_args = TargetOptions::link_args_list(&[
(LinkerFlavor::WasmLld(Cc::No), args!("")),
(LinkerFlavor::WasmLld(Cc::Yes), args!("-Wl,")),
]);

TargetOptions {
is_like_wasm: true,
124 changes: 63 additions & 61 deletions compiler/rustc_target/src/spec/base/windows_gnu.rs
Original file line number Diff line number Diff line change
@@ -1,78 +1,80 @@
use crate::spec::crt_objects;
use crate::spec::LinkSelfContainedDefault;
use crate::spec::{add_link_args, crt_objects};
use crate::spec::{cvs, Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions};
use std::borrow::Cow;

pub fn opts() -> TargetOptions {
let mut pre_link_args = TargetOptions::link_args(
LinkerFlavor::Gnu(Cc::No, Lld::No),
&[
// Enable ASLR
"--dynamicbase",
// ASLR will rebase it anyway so leaving that option enabled only leads to confusion
"--disable-auto-image-base",
],
);
add_link_args(
&mut pre_link_args,
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
&[
// Tell GCC to avoid linker plugins, because we are not bundling
// them with Windows installer, and Rust does its own LTO anyways.
"-fno-use-linker-plugin",
"-Wl,--dynamicbase",
"-Wl,--disable-auto-image-base",
],
);
let pre_link_args = TargetOptions::link_args_list(&[
(
LinkerFlavor::Gnu(Cc::No, Lld::No),
&[
// Enable ASLR
"--dynamicbase",
// ASLR will rebase it anyway so leaving that option enabled only leads to confusion
"--disable-auto-image-base",
],
),
(
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
&[
// Tell GCC to avoid linker plugins, because we are not bundling
// them with Windows installer, and Rust does its own LTO anyways.
"-fno-use-linker-plugin",
"-Wl,--dynamicbase",
"-Wl,--disable-auto-image-base",
],
),
]);

// Order of `late_link_args*` was found through trial and error to work with various
// mingw-w64 versions (not tested on the CI). It's expected to change from time to time.
let mingw_libs = &[
"-lmsvcrt",
"-lmingwex",
"-lmingw32",
"-lgcc", // alas, mingw* libraries above depend on libgcc
// mingw's msvcrt is a weird hybrid import library and static library.
// And it seems that the linker fails to use import symbols from msvcrt
// that are required from functions in msvcrt in certain cases. For example
// `_fmode` that is used by an implementation of `__p__fmode` in x86_64.
// The library is purposely listed twice to fix that.
//
// See https://github.com/rust-lang/rust/pull/47483 for some more details.
"-lmsvcrt",
// Math functions missing in MSVCRT (they are present in UCRT) require
// this dependency cycle: `libmingwex.a` -> `libmsvcrt.a` -> `libmingwex.a`.
"-lmingwex",
"-luser32",
"-lkernel32",
];
let mut late_link_args =
TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), mingw_libs);
add_link_args(&mut late_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), mingw_libs);
let late_link_args = {
// Order of `late_link_args*` was found through trial and error to work with various
// mingw-w64 versions (not tested on the CI). It's expected to change from time to time.
const MINGW_LIBS: &[&str] = &[
"-lmsvcrt",
"-lmingwex",
"-lmingw32",
"-lgcc", // alas, mingw* libraries above depend on libgcc
// mingw's msvcrt is a weird hybrid import library and static library.
// And it seems that the linker fails to use import symbols from msvcrt
// that are required from functions in msvcrt in certain cases. For example
// `_fmode` that is used by an implementation of `__p__fmode` in x86_64.
// The library is purposely listed twice to fix that.
//
// See https://github.com/rust-lang/rust/pull/47483 for some more details.
"-lmsvcrt",
// Math functions missing in MSVCRT (they are present in UCRT) require
// this dependency cycle: `libmingwex.a` -> `libmsvcrt.a` -> `libmingwex.a`.
"-lmingwex",
"-luser32",
"-lkernel32",
];
TargetOptions::link_args_list(&[
(LinkerFlavor::Gnu(Cc::No, Lld::No), MINGW_LIBS),
(LinkerFlavor::Gnu(Cc::Yes, Lld::No), MINGW_LIBS),
])
};
// If any of our crates are dynamically linked then we need to use
// the shared libgcc_s-dw2-1.dll. This is required to support
// unwinding across DLL boundaries.
let dynamic_unwind_libs = &["-lgcc_s"];
let mut late_link_args_dynamic =
TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), dynamic_unwind_libs);
add_link_args(
&mut late_link_args_dynamic,
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
dynamic_unwind_libs,
);
let late_link_args_dynamic = {
const DYNAMIC_UNWIND_LIBS: &[&str] = &["-lgcc_s"];
TargetOptions::link_args_list(&[
(LinkerFlavor::Gnu(Cc::No, Lld::No), DYNAMIC_UNWIND_LIBS),
(LinkerFlavor::Gnu(Cc::Yes, Lld::No), DYNAMIC_UNWIND_LIBS),
])
};
// If all of our crates are statically linked then we can get away
// with statically linking the libgcc unwinding code. This allows
// binaries to be redistributed without the libgcc_s-dw2-1.dll
// dependency, but unfortunately break unwinding across DLL
// boundaries when unwinding across FFI boundaries.
let static_unwind_libs = &["-lgcc_eh", "-l:libpthread.a"];
let mut late_link_args_static =
TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), static_unwind_libs);
add_link_args(
&mut late_link_args_static,
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
static_unwind_libs,
);
let late_link_args_static = {
const STATIC_UNWIND_LIBS: &[&str] = &["-lgcc_eh", "-l:libpthread.a"];
TargetOptions::link_args_list(&[
(LinkerFlavor::Gnu(Cc::No, Lld::No), STATIC_UNWIND_LIBS),
(LinkerFlavor::Gnu(Cc::Yes, Lld::No), STATIC_UNWIND_LIBS),
])
};

TargetOptions {
os: "windows".into(),
39 changes: 21 additions & 18 deletions compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
use crate::spec::{add_link_args, base, Cc, LinkArgs, LinkerFlavor, Lld, TargetOptions};
use crate::spec::{base, Cc, LinkerFlavor, Lld, TargetOptions};

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

// FIXME: This should be updated for the exception machinery changes from #67502
// and inherit from `windows_gnu_base`, at least partially.
let mingw_libs = &[
"-lwinstorecompat",
"-lruntimeobject",
"-lsynchronization",
"-lvcruntime140_app",
"-lucrt",
"-lwindowsapp",
"-lmingwex",
"-lmingw32",
];
let mut late_link_args =
TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), mingw_libs);
add_link_args(&mut late_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), mingw_libs);
let late_link_args = {
// FIXME: This should be updated for the exception machinery changes from #67502
// and inherit from `windows_gnu_base`, at least partially.
const MINGW_LIBS: &[&str] = &[
"-lwinstorecompat",
"-lruntimeobject",
"-lsynchronization",
"-lvcruntime140_app",
"-lucrt",
"-lwindowsapp",
"-lmingwex",
"-lmingw32",
];
TargetOptions::link_args_list(&[
(LinkerFlavor::Gnu(Cc::No, Lld::No), MINGW_LIBS),
(LinkerFlavor::Gnu(Cc::Yes, Lld::No), MINGW_LIBS),
])
};
// Reset the flags back to empty until the FIXME above is addressed.
let late_link_args_dynamic = LinkArgs::new();
let late_link_args_static = LinkArgs::new();
let late_link_args_dynamic = Default::default();
let late_link_args_static = Default::default();

TargetOptions {
abi: "uwp".into(),
3 changes: 2 additions & 1 deletion compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs
Original file line number Diff line number Diff line change
@@ -5,7 +5,8 @@ pub fn opts() -> TargetOptions {

opts.abi = "uwp".into();
opts.vendor = "uwp".into();
opts.add_pre_link_args(LinkerFlavor::Msvc(Lld::No), &["/APPCONTAINER", "mincore.lib"]);
opts.pre_link_args =
TargetOptions::link_args(LinkerFlavor::Msvc(Lld::No), &["/APPCONTAINER", "mincore.lib"]);

opts
}
Loading