2014-07-23 11:56:36 -07:00
|
|
|
//! [Flexible target specification.](https://github.com/rust-lang/rfcs/pull/131)
|
|
|
|
//!
|
|
|
|
//! Rust targets a wide variety of usecases, and in the interest of flexibility,
|
|
|
|
//! allows new target triples to be defined in configuration files. Most users
|
|
|
|
//! will not need to care about these, but this is invaluable when porting Rust
|
|
|
|
//! to a new platform, and allows for an unprecedented level of control over how
|
|
|
|
//! the compiler works.
|
|
|
|
//!
|
|
|
|
//! # Using custom targets
|
|
|
|
//!
|
|
|
|
//! A target triple, as passed via `rustc --target=TRIPLE`, will first be
|
|
|
|
//! compared against the list of built-in targets. This is to ease distributing
|
|
|
|
//! rustc (no need for configuration files) and also to hold these built-in
|
|
|
|
//! targets as immutable and sacred. If `TRIPLE` is not one of the built-in
|
|
|
|
//! targets, rustc will check if a file named `TRIPLE` exists. If it does, it
|
|
|
|
//! will be loaded as the target configuration. If the file does not exist,
|
|
|
|
//! rustc will search each directory in the environment variable
|
|
|
|
//! `RUST_TARGET_PATH` for a file named `TRIPLE.json`. The first one found will
|
|
|
|
//! be loaded. If no file is found in any of those directories, a fatal error
|
2016-04-09 09:39:22 -05:00
|
|
|
//! will be given.
|
2014-07-23 11:56:36 -07:00
|
|
|
//!
|
|
|
|
//! Projects defining their own targets should use
|
|
|
|
//! `--target=path/to/my-awesome-platform.json` instead of adding to
|
|
|
|
//! `RUST_TARGET_PATH`.
|
|
|
|
//!
|
|
|
|
//! # Defining a new target
|
|
|
|
//!
|
|
|
|
//! Targets are defined using [JSON](http://json.org/). The `Target` struct in
|
|
|
|
//! this module defines the format the JSON file should take, though each
|
|
|
|
//! underscore in the field names should be replaced with a hyphen (`-`) in the
|
|
|
|
//! JSON file. Some fields are required in every target specification, such as
|
2016-04-18 15:38:45 +03:00
|
|
|
//! `llvm-target`, `target-endian`, `target-pointer-width`, `data-layout`,
|
|
|
|
//! `arch`, and `os`. In general, options passed to rustc with `-C` override
|
|
|
|
//! the target's settings, though `target-feature` and `link-args` will *add*
|
|
|
|
//! to the list specified by the target, rather than replace.
|
2014-07-23 11:56:36 -07:00
|
|
|
|
2021-01-05 01:01:29 +00:00
|
|
|
use crate::abi::Endian;
|
2019-12-22 17:42:04 -05:00
|
|
|
use crate::spec::abi::{lookup as lookup_abi, Abi};
|
2020-04-29 20:47:07 +03:00
|
|
|
use crate::spec::crt_objects::{CrtObjects, CrtObjectsFallback};
|
2021-02-07 23:47:03 +02:00
|
|
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
2019-07-23 18:50:47 +03:00
|
|
|
use rustc_serialize::json::{Json, ToJson};
|
2020-07-25 19:02:49 +01:00
|
|
|
use rustc_span::symbol::{sym, Symbol};
|
2016-04-07 22:29:01 -05:00
|
|
|
use std::collections::BTreeMap;
|
2021-01-09 16:54:20 +02:00
|
|
|
use std::convert::TryFrom;
|
2020-11-08 14:27:51 +03:00
|
|
|
use std::ops::{Deref, DerefMut};
|
2018-03-14 15:27:06 +01:00
|
|
|
use std::path::{Path, PathBuf};
|
2017-12-08 17:07:47 +02:00
|
|
|
use std::str::FromStr;
|
2019-12-22 17:42:04 -05:00
|
|
|
use std::{fmt, io};
|
2014-07-23 11:56:36 -07:00
|
|
|
|
2019-11-09 23:32:17 +01:00
|
|
|
use rustc_macros::HashStable_Generic;
|
|
|
|
|
2018-04-25 19:30:39 +03:00
|
|
|
pub mod abi;
|
2020-04-29 20:47:07 +03:00
|
|
|
pub mod crt_objects;
|
|
|
|
|
2015-04-29 10:53:01 -07:00
|
|
|
mod android_base;
|
2014-07-23 11:56:36 -07:00
|
|
|
mod apple_base;
|
2020-02-14 16:05:45 -08:00
|
|
|
mod apple_sdk_base;
|
2016-10-24 11:04:04 +02:00
|
|
|
mod arm_base;
|
2020-07-26 23:58:37 +12:00
|
|
|
mod avr_gnu_base;
|
2015-04-29 10:53:01 -07:00
|
|
|
mod dragonfly_base;
|
|
|
|
mod freebsd_base;
|
2019-12-22 17:42:04 -05:00
|
|
|
mod fuchsia_base;
|
2016-09-25 16:55:40 -05:00
|
|
|
mod haiku_base;
|
2018-07-30 15:50:51 +02:00
|
|
|
mod hermit_base;
|
2019-11-24 21:05:32 +01:00
|
|
|
mod hermit_kernel_base;
|
2020-04-13 23:37:22 +00:00
|
|
|
mod illumos_base;
|
2019-12-22 17:42:04 -05:00
|
|
|
mod l4re_base;
|
2015-04-29 10:53:01 -07:00
|
|
|
mod linux_base;
|
2020-11-10 23:32:58 +03:00
|
|
|
mod linux_gnu_base;
|
2019-08-31 15:13:16 -04:00
|
|
|
mod linux_kernel_base;
|
2016-05-01 17:41:28 -04:00
|
|
|
mod linux_musl_base;
|
2020-10-08 21:47:22 +03:00
|
|
|
mod linux_uclibc_base;
|
2020-04-11 17:30:09 +03:00
|
|
|
mod msvc_base;
|
2015-06-30 20:37:11 -07:00
|
|
|
mod netbsd_base;
|
2019-12-22 17:42:04 -05:00
|
|
|
mod openbsd_base;
|
|
|
|
mod redox_base;
|
|
|
|
mod riscv_base;
|
2016-01-28 14:02:31 +03:00
|
|
|
mod solaris_base;
|
2019-12-22 17:42:04 -05:00
|
|
|
mod thumb_base;
|
2020-04-11 16:04:18 +03:00
|
|
|
mod uefi_msvc_base;
|
2019-12-22 17:42:04 -05:00
|
|
|
mod vxworks_base;
|
|
|
|
mod wasm32_base;
|
2020-04-11 16:04:18 +03:00
|
|
|
mod windows_gnu_base;
|
2015-05-08 14:44:17 -07:00
|
|
|
mod windows_msvc_base;
|
2020-04-11 16:04:18 +03:00
|
|
|
mod windows_uwp_gnu_base;
|
2019-07-31 15:00:34 +07:00
|
|
|
mod windows_uwp_msvc_base;
|
2014-07-23 11:56:36 -07:00
|
|
|
|
2019-10-20 15:54:53 +11:00
|
|
|
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
2017-12-08 17:07:47 +02:00
|
|
|
pub enum LinkerFlavor {
|
|
|
|
Em,
|
|
|
|
Gcc,
|
|
|
|
Ld,
|
|
|
|
Msvc,
|
|
|
|
Lld(LldFlavor),
|
2019-01-19 21:59:34 +01:00
|
|
|
PtxLinker,
|
2017-12-08 17:07:47 +02:00
|
|
|
}
|
|
|
|
|
2019-10-20 15:54:53 +11:00
|
|
|
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
2017-12-08 17:07:47 +02:00
|
|
|
pub enum LldFlavor {
|
|
|
|
Wasm,
|
|
|
|
Ld64,
|
|
|
|
Ld,
|
|
|
|
Link,
|
|
|
|
}
|
|
|
|
|
2018-08-18 20:16:04 +02:00
|
|
|
impl LldFlavor {
|
|
|
|
fn from_str(s: &str) -> Option<Self> {
|
|
|
|
Some(match s {
|
|
|
|
"darwin" => LldFlavor::Ld64,
|
|
|
|
"gnu" => LldFlavor::Ld,
|
|
|
|
"link" => LldFlavor::Link,
|
|
|
|
"wasm" => LldFlavor::Wasm,
|
|
|
|
_ => return None,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ToJson for LldFlavor {
|
|
|
|
fn to_json(&self) -> Json {
|
|
|
|
match *self {
|
|
|
|
LldFlavor::Ld64 => "darwin",
|
|
|
|
LldFlavor::Ld => "gnu",
|
|
|
|
LldFlavor::Link => "link",
|
|
|
|
LldFlavor::Wasm => "wasm",
|
2019-12-22 17:42:04 -05:00
|
|
|
}
|
|
|
|
.to_json()
|
2018-08-18 20:16:04 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-08 17:07:47 +02:00
|
|
|
impl ToJson for LinkerFlavor {
|
|
|
|
fn to_json(&self) -> Json {
|
|
|
|
self.desc().to_json()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
macro_rules! flavor_mappings {
|
|
|
|
($((($($flavor:tt)*), $string:expr),)*) => (
|
|
|
|
impl LinkerFlavor {
|
|
|
|
pub const fn one_of() -> &'static str {
|
2019-05-29 20:05:43 +02:00
|
|
|
concat!("one of: ", $($string, " ",)*)
|
2017-12-08 17:07:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn from_str(s: &str) -> Option<Self> {
|
|
|
|
Some(match s {
|
2019-05-29 20:05:43 +02:00
|
|
|
$($string => $($flavor)*,)*
|
2017-12-08 17:07:47 +02:00
|
|
|
_ => return None,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn desc(&self) -> &str {
|
|
|
|
match *self {
|
2019-05-29 20:05:43 +02:00
|
|
|
$($($flavor)* => $string,)*
|
2017-12-08 17:07:47 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
flavor_mappings! {
|
|
|
|
((LinkerFlavor::Em), "em"),
|
|
|
|
((LinkerFlavor::Gcc), "gcc"),
|
|
|
|
((LinkerFlavor::Ld), "ld"),
|
|
|
|
((LinkerFlavor::Msvc), "msvc"),
|
2019-01-19 21:59:34 +01:00
|
|
|
((LinkerFlavor::PtxLinker), "ptx-linker"),
|
2017-12-08 17:07:47 +02:00
|
|
|
((LinkerFlavor::Lld(LldFlavor::Wasm)), "wasm-ld"),
|
|
|
|
((LinkerFlavor::Lld(LldFlavor::Ld64)), "ld64.lld"),
|
|
|
|
((LinkerFlavor::Lld(LldFlavor::Ld)), "ld.lld"),
|
|
|
|
((LinkerFlavor::Lld(LldFlavor::Link)), "lld-link"),
|
|
|
|
}
|
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable, HashStable_Generic)]
|
2017-12-08 17:07:47 +02:00
|
|
|
pub enum PanicStrategy {
|
|
|
|
Unwind,
|
|
|
|
Abort,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl PanicStrategy {
|
|
|
|
pub fn desc(&self) -> &str {
|
|
|
|
match *self {
|
|
|
|
PanicStrategy::Unwind => "unwind",
|
|
|
|
PanicStrategy::Abort => "abort",
|
|
|
|
}
|
|
|
|
}
|
2020-07-25 19:02:49 +01:00
|
|
|
|
|
|
|
pub fn desc_symbol(&self) -> Symbol {
|
|
|
|
match *self {
|
|
|
|
PanicStrategy::Unwind => sym::unwind,
|
|
|
|
PanicStrategy::Abort => sym::abort,
|
|
|
|
}
|
|
|
|
}
|
2017-12-08 17:07:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ToJson for PanicStrategy {
|
|
|
|
fn to_json(&self) -> Json {
|
|
|
|
match *self {
|
|
|
|
PanicStrategy::Abort => "abort".to_json(),
|
|
|
|
PanicStrategy::Unwind => "unwind".to_json(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable)]
|
2017-12-08 17:07:47 +02:00
|
|
|
pub enum RelroLevel {
|
|
|
|
Full,
|
|
|
|
Partial,
|
|
|
|
Off,
|
|
|
|
None,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl RelroLevel {
|
|
|
|
pub fn desc(&self) -> &str {
|
|
|
|
match *self {
|
|
|
|
RelroLevel::Full => "full",
|
|
|
|
RelroLevel::Partial => "partial",
|
|
|
|
RelroLevel::Off => "off",
|
|
|
|
RelroLevel::None => "none",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FromStr for RelroLevel {
|
|
|
|
type Err = ();
|
|
|
|
|
|
|
|
fn from_str(s: &str) -> Result<RelroLevel, ()> {
|
|
|
|
match s {
|
|
|
|
"full" => Ok(RelroLevel::Full),
|
|
|
|
"partial" => Ok(RelroLevel::Partial),
|
|
|
|
"off" => Ok(RelroLevel::Off),
|
|
|
|
"none" => Ok(RelroLevel::None),
|
|
|
|
_ => Err(()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ToJson for RelroLevel {
|
|
|
|
fn to_json(&self) -> Json {
|
|
|
|
match *self {
|
|
|
|
RelroLevel::Full => "full".to_json(),
|
|
|
|
RelroLevel::Partial => "partial".to_json(),
|
|
|
|
RelroLevel::Off => "off".to_json(),
|
|
|
|
RelroLevel::None => "None".to_json(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable)]
|
2018-12-31 10:58:13 -08:00
|
|
|
pub enum MergeFunctions {
|
|
|
|
Disabled,
|
|
|
|
Trampolines,
|
2019-12-22 17:42:04 -05:00
|
|
|
Aliases,
|
2018-12-31 10:58:13 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl MergeFunctions {
|
|
|
|
pub fn desc(&self) -> &str {
|
|
|
|
match *self {
|
|
|
|
MergeFunctions::Disabled => "disabled",
|
|
|
|
MergeFunctions::Trampolines => "trampolines",
|
|
|
|
MergeFunctions::Aliases => "aliases",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FromStr for MergeFunctions {
|
|
|
|
type Err = ();
|
|
|
|
|
|
|
|
fn from_str(s: &str) -> Result<MergeFunctions, ()> {
|
|
|
|
match s {
|
|
|
|
"disabled" => Ok(MergeFunctions::Disabled),
|
|
|
|
"trampolines" => Ok(MergeFunctions::Trampolines),
|
|
|
|
"aliases" => Ok(MergeFunctions::Aliases),
|
|
|
|
_ => Err(()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ToJson for MergeFunctions {
|
|
|
|
fn to_json(&self) -> Json {
|
|
|
|
match *self {
|
|
|
|
MergeFunctions::Disabled => "disabled".to_json(),
|
|
|
|
MergeFunctions::Trampolines => "trampolines".to_json(),
|
|
|
|
MergeFunctions::Aliases => "aliases".to_json(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-23 00:46:45 +03:00
|
|
|
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
|
|
|
|
pub enum RelocModel {
|
|
|
|
Static,
|
|
|
|
Pic,
|
|
|
|
DynamicNoPic,
|
|
|
|
Ropi,
|
|
|
|
Rwpi,
|
|
|
|
RopiRwpi,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FromStr for RelocModel {
|
|
|
|
type Err = ();
|
|
|
|
|
|
|
|
fn from_str(s: &str) -> Result<RelocModel, ()> {
|
|
|
|
Ok(match s {
|
|
|
|
"static" => RelocModel::Static,
|
|
|
|
"pic" => RelocModel::Pic,
|
|
|
|
"dynamic-no-pic" => RelocModel::DynamicNoPic,
|
|
|
|
"ropi" => RelocModel::Ropi,
|
|
|
|
"rwpi" => RelocModel::Rwpi,
|
|
|
|
"ropi-rwpi" => RelocModel::RopiRwpi,
|
|
|
|
_ => return Err(()),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ToJson for RelocModel {
|
|
|
|
fn to_json(&self) -> Json {
|
|
|
|
match *self {
|
|
|
|
RelocModel::Static => "static",
|
|
|
|
RelocModel::Pic => "pic",
|
|
|
|
RelocModel::DynamicNoPic => "dynamic-no-pic",
|
|
|
|
RelocModel::Ropi => "ropi",
|
|
|
|
RelocModel::Rwpi => "rwpi",
|
|
|
|
RelocModel::RopiRwpi => "ropi-rwpi",
|
|
|
|
}
|
|
|
|
.to_json()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-07 03:34:27 +03:00
|
|
|
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
|
|
|
|
pub enum CodeModel {
|
|
|
|
Tiny,
|
|
|
|
Small,
|
|
|
|
Kernel,
|
|
|
|
Medium,
|
|
|
|
Large,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FromStr for CodeModel {
|
|
|
|
type Err = ();
|
|
|
|
|
|
|
|
fn from_str(s: &str) -> Result<CodeModel, ()> {
|
|
|
|
Ok(match s {
|
2020-05-20 23:09:19 +03:00
|
|
|
"tiny" => CodeModel::Tiny,
|
2020-05-07 03:34:27 +03:00
|
|
|
"small" => CodeModel::Small,
|
|
|
|
"kernel" => CodeModel::Kernel,
|
|
|
|
"medium" => CodeModel::Medium,
|
|
|
|
"large" => CodeModel::Large,
|
|
|
|
_ => return Err(()),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ToJson for CodeModel {
|
|
|
|
fn to_json(&self) -> Json {
|
|
|
|
match *self {
|
|
|
|
CodeModel::Tiny => "tiny",
|
|
|
|
CodeModel::Small => "small",
|
|
|
|
CodeModel::Kernel => "kernel",
|
|
|
|
CodeModel::Medium => "medium",
|
|
|
|
CodeModel::Large => "large",
|
|
|
|
}
|
|
|
|
.to_json()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-25 21:45:21 +03:00
|
|
|
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
|
|
|
|
pub enum TlsModel {
|
|
|
|
GeneralDynamic,
|
|
|
|
LocalDynamic,
|
|
|
|
InitialExec,
|
|
|
|
LocalExec,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FromStr for TlsModel {
|
|
|
|
type Err = ();
|
|
|
|
|
|
|
|
fn from_str(s: &str) -> Result<TlsModel, ()> {
|
|
|
|
Ok(match s {
|
|
|
|
// Note the difference "general" vs "global" difference. The model name is "general",
|
|
|
|
// but the user-facing option name is "global" for consistency with other compilers.
|
|
|
|
"global-dynamic" => TlsModel::GeneralDynamic,
|
|
|
|
"local-dynamic" => TlsModel::LocalDynamic,
|
|
|
|
"initial-exec" => TlsModel::InitialExec,
|
|
|
|
"local-exec" => TlsModel::LocalExec,
|
|
|
|
_ => return Err(()),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ToJson for TlsModel {
|
|
|
|
fn to_json(&self) -> Json {
|
|
|
|
match *self {
|
|
|
|
TlsModel::GeneralDynamic => "global-dynamic",
|
|
|
|
TlsModel::LocalDynamic => "local-dynamic",
|
|
|
|
TlsModel::InitialExec => "initial-exec",
|
|
|
|
TlsModel::LocalExec => "local-exec",
|
|
|
|
}
|
|
|
|
.to_json()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-29 20:47:07 +03:00
|
|
|
/// Everything is flattened to a single enum to make the json encoding/decoding less annoying.
|
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
|
|
|
|
pub enum LinkOutputKind {
|
|
|
|
/// Dynamically linked non position-independent executable.
|
|
|
|
DynamicNoPicExe,
|
|
|
|
/// Dynamically linked position-independent executable.
|
|
|
|
DynamicPicExe,
|
|
|
|
/// Statically linked non position-independent executable.
|
|
|
|
StaticNoPicExe,
|
|
|
|
/// Statically linked position-independent executable.
|
|
|
|
StaticPicExe,
|
|
|
|
/// Regular dynamic library ("dynamically linked").
|
|
|
|
DynamicDylib,
|
|
|
|
/// Dynamic library with bundled libc ("statically linked").
|
|
|
|
StaticDylib,
|
2020-12-12 21:38:23 -06:00
|
|
|
/// WASI module with a lifetime past the _initialize entry point
|
|
|
|
WasiReactorExe,
|
2020-04-29 20:47:07 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
impl LinkOutputKind {
|
|
|
|
fn as_str(&self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
LinkOutputKind::DynamicNoPicExe => "dynamic-nopic-exe",
|
|
|
|
LinkOutputKind::DynamicPicExe => "dynamic-pic-exe",
|
|
|
|
LinkOutputKind::StaticNoPicExe => "static-nopic-exe",
|
|
|
|
LinkOutputKind::StaticPicExe => "static-pic-exe",
|
|
|
|
LinkOutputKind::DynamicDylib => "dynamic-dylib",
|
|
|
|
LinkOutputKind::StaticDylib => "static-dylib",
|
2020-12-12 21:38:23 -06:00
|
|
|
LinkOutputKind::WasiReactorExe => "wasi-reactor-exe",
|
2020-04-29 20:47:07 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(super) fn from_str(s: &str) -> Option<LinkOutputKind> {
|
|
|
|
Some(match s {
|
|
|
|
"dynamic-nopic-exe" => LinkOutputKind::DynamicNoPicExe,
|
|
|
|
"dynamic-pic-exe" => LinkOutputKind::DynamicPicExe,
|
|
|
|
"static-nopic-exe" => LinkOutputKind::StaticNoPicExe,
|
|
|
|
"static-pic-exe" => LinkOutputKind::StaticPicExe,
|
|
|
|
"dynamic-dylib" => LinkOutputKind::DynamicDylib,
|
|
|
|
"static-dylib" => LinkOutputKind::StaticDylib,
|
2020-12-12 21:38:23 -06:00
|
|
|
"wasi-reactor-exe" => LinkOutputKind::WasiReactorExe,
|
2020-04-29 20:47:07 +03:00
|
|
|
_ => return None,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for LinkOutputKind {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
f.write_str(self.as_str())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
2017-02-21 14:47:15 -05:00
|
|
|
pub type LinkArgs = BTreeMap<LinkerFlavor, Vec<String>>;
|
2016-07-24 11:47:39 -05:00
|
|
|
|
2020-11-30 08:39:08 -08:00
|
|
|
#[derive(Clone, Copy, Hash, Debug, PartialEq, Eq)]
|
|
|
|
pub enum SplitDebuginfo {
|
|
|
|
/// Split debug-information is disabled, meaning that on supported platforms
|
|
|
|
/// you can find all debug information in the executable itself. This is
|
|
|
|
/// only supported for ELF effectively.
|
|
|
|
///
|
|
|
|
/// * Windows - not supported
|
|
|
|
/// * macOS - don't run `dsymutil`
|
|
|
|
/// * ELF - `.dwarf_*` sections
|
|
|
|
Off,
|
|
|
|
|
|
|
|
/// Split debug-information can be found in a "packed" location separate
|
|
|
|
/// from the final artifact. This is supported on all platforms.
|
|
|
|
///
|
|
|
|
/// * Windows - `*.pdb`
|
|
|
|
/// * macOS - `*.dSYM` (run `dsymutil`)
|
|
|
|
/// * ELF - `*.dwp` (run `rust-llvm-dwp`)
|
|
|
|
Packed,
|
|
|
|
|
|
|
|
/// Split debug-information can be found in individual object files on the
|
|
|
|
/// filesystem. The main executable may point to the object files.
|
|
|
|
///
|
|
|
|
/// * Windows - not supported
|
|
|
|
/// * macOS - supported, scattered object files
|
|
|
|
/// * ELF - supported, scattered `*.dwo` files
|
|
|
|
Unpacked,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SplitDebuginfo {
|
|
|
|
fn as_str(&self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
SplitDebuginfo::Off => "off",
|
|
|
|
SplitDebuginfo::Packed => "packed",
|
|
|
|
SplitDebuginfo::Unpacked => "unpacked",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FromStr for SplitDebuginfo {
|
|
|
|
type Err = ();
|
|
|
|
|
|
|
|
fn from_str(s: &str) -> Result<SplitDebuginfo, ()> {
|
|
|
|
Ok(match s {
|
|
|
|
"off" => SplitDebuginfo::Off,
|
|
|
|
"unpacked" => SplitDebuginfo::Unpacked,
|
|
|
|
"packed" => SplitDebuginfo::Packed,
|
|
|
|
_ => return Err(()),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ToJson for SplitDebuginfo {
|
|
|
|
fn to_json(&self) -> Json {
|
|
|
|
self.as_str().to_json()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for SplitDebuginfo {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
f.write_str(self.as_str())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-09 16:54:20 +02:00
|
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
|
|
pub enum StackProbeType {
|
|
|
|
/// Don't emit any stack probes.
|
|
|
|
None,
|
|
|
|
/// It is harmless to use this option even on targets that do not have backend support for
|
|
|
|
/// stack probes as the failure mode is the same as if no stack-probe option was specified in
|
|
|
|
/// the first place.
|
|
|
|
Inline,
|
|
|
|
/// Call `__rust_probestack` whenever stack needs to be probed.
|
|
|
|
Call,
|
|
|
|
/// Use inline option for LLVM versions later than specified in `min_llvm_version_for_inline`
|
|
|
|
/// and call `__rust_probestack` otherwise.
|
|
|
|
InlineOrCall { min_llvm_version_for_inline: (u32, u32, u32) },
|
|
|
|
}
|
|
|
|
|
|
|
|
impl StackProbeType {
|
|
|
|
fn from_json(json: &Json) -> Result<Self, String> {
|
|
|
|
let object = json.as_object().ok_or_else(|| "expected a JSON object")?;
|
|
|
|
let kind = object
|
|
|
|
.get("kind")
|
|
|
|
.and_then(|o| o.as_string())
|
|
|
|
.ok_or_else(|| "expected `kind` to be a string")?;
|
|
|
|
match kind {
|
|
|
|
"none" => Ok(StackProbeType::None),
|
|
|
|
"inline" => Ok(StackProbeType::Inline),
|
|
|
|
"call" => Ok(StackProbeType::Call),
|
|
|
|
"inline-or-call" => {
|
|
|
|
let min_version = object
|
|
|
|
.get("min-llvm-version-for-inline")
|
|
|
|
.and_then(|o| o.as_array())
|
|
|
|
.ok_or_else(|| "expected `min-llvm-version-for-inline` to be an array")?;
|
|
|
|
let mut iter = min_version.into_iter().map(|v| {
|
|
|
|
let int = v.as_u64().ok_or_else(
|
|
|
|
|| "expected `min-llvm-version-for-inline` values to be integers",
|
|
|
|
)?;
|
|
|
|
u32::try_from(int)
|
|
|
|
.map_err(|_| "`min-llvm-version-for-inline` values don't convert to u32")
|
|
|
|
});
|
|
|
|
let min_llvm_version_for_inline = (
|
|
|
|
iter.next().unwrap_or(Ok(11))?,
|
|
|
|
iter.next().unwrap_or(Ok(0))?,
|
|
|
|
iter.next().unwrap_or(Ok(0))?,
|
|
|
|
);
|
|
|
|
Ok(StackProbeType::InlineOrCall { min_llvm_version_for_inline })
|
|
|
|
}
|
|
|
|
_ => Err(String::from(
|
2021-02-11 20:33:16 +01:00
|
|
|
"`kind` expected to be one of `none`, `inline`, `call` or `inline-or-call`",
|
2021-01-09 16:54:20 +02:00
|
|
|
)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ToJson for StackProbeType {
|
|
|
|
fn to_json(&self) -> Json {
|
|
|
|
Json::Object(match self {
|
|
|
|
StackProbeType::None => {
|
|
|
|
vec![(String::from("kind"), "none".to_json())].into_iter().collect()
|
|
|
|
}
|
|
|
|
StackProbeType::Inline => {
|
|
|
|
vec![(String::from("kind"), "inline".to_json())].into_iter().collect()
|
|
|
|
}
|
|
|
|
StackProbeType::Call => {
|
|
|
|
vec![(String::from("kind"), "call".to_json())].into_iter().collect()
|
|
|
|
}
|
|
|
|
StackProbeType::InlineOrCall { min_llvm_version_for_inline } => vec![
|
|
|
|
(String::from("kind"), "inline-or-call".to_json()),
|
|
|
|
(
|
|
|
|
String::from("min-llvm-version-for-inline"),
|
|
|
|
min_llvm_version_for_inline.to_json(),
|
|
|
|
),
|
|
|
|
]
|
|
|
|
.into_iter()
|
|
|
|
.collect(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-07 23:47:03 +02:00
|
|
|
bitflags::bitflags! {
|
|
|
|
#[derive(Default, Encodable, Decodable)]
|
|
|
|
pub struct SanitizerSet: u8 {
|
|
|
|
const ADDRESS = 1 << 0;
|
|
|
|
const LEAK = 1 << 1;
|
|
|
|
const MEMORY = 1 << 2;
|
|
|
|
const THREAD = 1 << 3;
|
|
|
|
const HWADDRESS = 1 << 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Formats a sanitizer set as a comma separated list of sanitizers' names.
|
|
|
|
impl fmt::Display for SanitizerSet {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
let mut first = true;
|
|
|
|
for s in *self {
|
|
|
|
let name = match s {
|
|
|
|
SanitizerSet::ADDRESS => "address",
|
|
|
|
SanitizerSet::LEAK => "leak",
|
|
|
|
SanitizerSet::MEMORY => "memory",
|
|
|
|
SanitizerSet::THREAD => "thread",
|
|
|
|
SanitizerSet::HWADDRESS => "hwaddress",
|
|
|
|
_ => panic!("unrecognized sanitizer {:?}", s),
|
|
|
|
};
|
|
|
|
if !first {
|
2021-02-08 00:49:00 +02:00
|
|
|
f.write_str(", ")?;
|
2021-02-07 23:47:03 +02:00
|
|
|
}
|
|
|
|
f.write_str(name)?;
|
|
|
|
first = false;
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IntoIterator for SanitizerSet {
|
|
|
|
type Item = SanitizerSet;
|
|
|
|
type IntoIter = std::vec::IntoIter<SanitizerSet>;
|
|
|
|
|
|
|
|
fn into_iter(self) -> Self::IntoIter {
|
|
|
|
[SanitizerSet::ADDRESS, SanitizerSet::LEAK, SanitizerSet::MEMORY, SanitizerSet::THREAD, SanitizerSet::HWADDRESS]
|
|
|
|
.iter()
|
|
|
|
.copied()
|
|
|
|
.filter(|&s| self.contains(s))
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
.into_iter()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<CTX> HashStable<CTX> for SanitizerSet {
|
|
|
|
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
|
|
|
|
self.bits().hash_stable(ctx, hasher);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! supported_targets {
|
|
|
|
( $(($( $triple:literal, )+ $module:ident ),)+ ) => {
|
|
|
|
$(mod $module;)+
|
|
|
|
|
|
|
|
/// List of supported targets
|
|
|
|
pub const TARGETS: &[&str] = &[$($($triple),+),+];
|
|
|
|
|
|
|
|
fn load_builtin(target: &str) -> Option<Target> {
|
|
|
|
let mut t = match target {
|
|
|
|
$( $($triple)|+ => $module::target(), )+
|
|
|
|
_ => return None,
|
|
|
|
};
|
|
|
|
t.is_builtin = true;
|
|
|
|
debug!("got builtin target: {:?}", t);
|
|
|
|
Some(t)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
mod tests_impl;
|
|
|
|
|
|
|
|
// Cannot put this into a separate file without duplication, make an exception.
|
|
|
|
$(
|
|
|
|
#[test] // `#[test]`
|
|
|
|
fn $module() {
|
|
|
|
tests_impl::test_target(super::$module::target());
|
|
|
|
}
|
|
|
|
)+
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-02-12 10:11:58 -05:00
|
|
|
supported_targets! {
|
|
|
|
("x86_64-unknown-linux-gnu", x86_64_unknown_linux_gnu),
|
2017-10-11 16:15:42 -03:00
|
|
|
("x86_64-unknown-linux-gnux32", x86_64_unknown_linux_gnux32),
|
2016-02-12 10:11:58 -05:00
|
|
|
("i686-unknown-linux-gnu", i686_unknown_linux_gnu),
|
2016-02-13 17:03:00 +01:00
|
|
|
("i586-unknown-linux-gnu", i586_unknown_linux_gnu),
|
2016-02-12 10:11:58 -05:00
|
|
|
("mips-unknown-linux-gnu", mips_unknown_linux_gnu),
|
2016-08-26 17:06:13 -05:00
|
|
|
("mips64-unknown-linux-gnuabi64", mips64_unknown_linux_gnuabi64),
|
|
|
|
("mips64el-unknown-linux-gnuabi64", mips64el_unknown_linux_gnuabi64),
|
2019-03-05 23:28:15 +08:00
|
|
|
("mipsisa32r6-unknown-linux-gnu", mipsisa32r6_unknown_linux_gnu),
|
|
|
|
("mipsisa32r6el-unknown-linux-gnu", mipsisa32r6el_unknown_linux_gnu),
|
|
|
|
("mipsisa64r6-unknown-linux-gnuabi64", mipsisa64r6_unknown_linux_gnuabi64),
|
|
|
|
("mipsisa64r6el-unknown-linux-gnuabi64", mipsisa64r6el_unknown_linux_gnuabi64),
|
2016-02-12 10:11:58 -05:00
|
|
|
("mipsel-unknown-linux-gnu", mipsel_unknown_linux_gnu),
|
|
|
|
("powerpc-unknown-linux-gnu", powerpc_unknown_linux_gnu),
|
2018-02-23 22:18:40 +01:00
|
|
|
("powerpc-unknown-linux-gnuspe", powerpc_unknown_linux_gnuspe),
|
2018-09-10 01:35:35 +00:00
|
|
|
("powerpc-unknown-linux-musl", powerpc_unknown_linux_musl),
|
2016-02-12 10:11:58 -05:00
|
|
|
("powerpc64-unknown-linux-gnu", powerpc64_unknown_linux_gnu),
|
2018-08-07 21:59:15 -05:00
|
|
|
("powerpc64-unknown-linux-musl", powerpc64_unknown_linux_musl),
|
2016-02-12 10:11:58 -05:00
|
|
|
("powerpc64le-unknown-linux-gnu", powerpc64le_unknown_linux_gnu),
|
2018-06-18 16:28:01 +00:00
|
|
|
("powerpc64le-unknown-linux-musl", powerpc64le_unknown_linux_musl),
|
2016-08-26 21:05:16 -05:00
|
|
|
("s390x-unknown-linux-gnu", s390x_unknown_linux_gnu),
|
2021-02-16 00:46:14 +00:00
|
|
|
("s390x-unknown-linux-musl", s390x_unknown_linux_musl),
|
2018-02-17 15:48:05 +01:00
|
|
|
("sparc-unknown-linux-gnu", sparc_unknown_linux_gnu),
|
2018-01-04 14:55:04 -02:00
|
|
|
("sparc64-unknown-linux-gnu", sparc64_unknown_linux_gnu),
|
2016-02-12 10:11:58 -05:00
|
|
|
("arm-unknown-linux-gnueabi", arm_unknown_linux_gnueabi),
|
|
|
|
("arm-unknown-linux-gnueabihf", arm_unknown_linux_gnueabihf),
|
2016-04-27 18:02:31 -07:00
|
|
|
("arm-unknown-linux-musleabi", arm_unknown_linux_musleabi),
|
|
|
|
("arm-unknown-linux-musleabihf", arm_unknown_linux_musleabihf),
|
2017-12-26 13:05:03 -02:00
|
|
|
("armv4t-unknown-linux-gnueabi", armv4t_unknown_linux_gnueabi),
|
2016-11-06 13:06:01 +01:00
|
|
|
("armv5te-unknown-linux-gnueabi", armv5te_unknown_linux_gnueabi),
|
2018-05-04 08:47:24 +02:00
|
|
|
("armv5te-unknown-linux-musleabi", armv5te_unknown_linux_musleabi),
|
2020-11-30 09:47:09 +01:00
|
|
|
("armv5te-unknown-linux-uclibceabi", armv5te_unknown_linux_uclibceabi),
|
2019-07-29 18:28:36 +03:00
|
|
|
("armv7-unknown-linux-gnueabi", armv7_unknown_linux_gnueabi),
|
2016-02-12 10:11:58 -05:00
|
|
|
("armv7-unknown-linux-gnueabihf", armv7_unknown_linux_gnueabihf),
|
2018-06-04 11:44:30 +03:00
|
|
|
("thumbv7neon-unknown-linux-gnueabihf", thumbv7neon_unknown_linux_gnueabihf),
|
2019-11-04 21:48:22 -06:00
|
|
|
("thumbv7neon-unknown-linux-musleabihf", thumbv7neon_unknown_linux_musleabihf),
|
2019-07-29 18:28:36 +03:00
|
|
|
("armv7-unknown-linux-musleabi", armv7_unknown_linux_musleabi),
|
2016-04-27 18:02:31 -07:00
|
|
|
("armv7-unknown-linux-musleabihf", armv7_unknown_linux_musleabihf),
|
2016-02-12 10:11:58 -05:00
|
|
|
("aarch64-unknown-linux-gnu", aarch64_unknown_linux_gnu),
|
2017-09-05 16:55:25 +00:00
|
|
|
("aarch64-unknown-linux-musl", aarch64_unknown_linux_musl),
|
2016-02-12 10:11:58 -05:00
|
|
|
("x86_64-unknown-linux-musl", x86_64_unknown_linux_musl),
|
|
|
|
("i686-unknown-linux-musl", i686_unknown_linux_musl),
|
2018-01-04 14:55:04 -02:00
|
|
|
("i586-unknown-linux-musl", i586_unknown_linux_musl),
|
2016-02-12 10:11:58 -05:00
|
|
|
("mips-unknown-linux-musl", mips_unknown_linux_musl),
|
|
|
|
("mipsel-unknown-linux-musl", mipsel_unknown_linux_musl),
|
2019-07-28 11:46:47 +08:00
|
|
|
("mips64-unknown-linux-muslabi64", mips64_unknown_linux_muslabi64),
|
|
|
|
("mips64el-unknown-linux-muslabi64", mips64el_unknown_linux_muslabi64),
|
2018-08-10 12:01:18 -05:00
|
|
|
("hexagon-unknown-linux-musl", hexagon_unknown_linux_musl),
|
2018-01-04 14:55:04 -02:00
|
|
|
|
2016-08-16 17:07:55 -05:00
|
|
|
("mips-unknown-linux-uclibc", mips_unknown_linux_uclibc),
|
|
|
|
("mipsel-unknown-linux-uclibc", mipsel_unknown_linux_uclibc),
|
2016-02-12 10:11:58 -05:00
|
|
|
|
|
|
|
("i686-linux-android", i686_linux_android),
|
2017-04-20 14:02:42 -03:00
|
|
|
("x86_64-linux-android", x86_64_linux_android),
|
2016-02-12 10:11:58 -05:00
|
|
|
("arm-linux-androideabi", arm_linux_androideabi),
|
2016-05-05 01:08:14 +03:00
|
|
|
("armv7-linux-androideabi", armv7_linux_androideabi),
|
2018-06-04 11:44:30 +03:00
|
|
|
("thumbv7neon-linux-androideabi", thumbv7neon_linux_androideabi),
|
2016-02-12 10:11:58 -05:00
|
|
|
("aarch64-linux-android", aarch64_linux_android),
|
|
|
|
|
2020-10-11 18:01:32 -04:00
|
|
|
("x86_64-unknown-none-linuxkernel", x86_64_unknown_none_linuxkernel),
|
2019-08-31 15:13:16 -04:00
|
|
|
|
2017-01-25 21:09:18 +01:00
|
|
|
("aarch64-unknown-freebsd", aarch64_unknown_freebsd),
|
2019-02-02 16:41:38 +01:00
|
|
|
("armv6-unknown-freebsd", armv6_unknown_freebsd),
|
|
|
|
("armv7-unknown-freebsd", armv7_unknown_freebsd),
|
2016-02-12 10:11:58 -05:00
|
|
|
("i686-unknown-freebsd", i686_unknown_freebsd),
|
2019-01-21 18:50:54 +01:00
|
|
|
("powerpc64-unknown-freebsd", powerpc64_unknown_freebsd),
|
2016-02-12 10:11:58 -05:00
|
|
|
("x86_64-unknown-freebsd", x86_64_unknown_freebsd),
|
|
|
|
|
|
|
|
("x86_64-unknown-dragonfly", x86_64_unknown_dragonfly),
|
|
|
|
|
2018-05-12 09:45:35 +02:00
|
|
|
("aarch64-unknown-openbsd", aarch64_unknown_openbsd),
|
2016-11-29 18:49:09 +01:00
|
|
|
("i686-unknown-openbsd", i686_unknown_openbsd),
|
2019-08-15 15:34:23 +02:00
|
|
|
("sparc64-unknown-openbsd", sparc64_unknown_openbsd),
|
2016-02-12 10:11:58 -05:00
|
|
|
("x86_64-unknown-openbsd", x86_64_unknown_openbsd),
|
2021-03-03 21:17:17 +01:00
|
|
|
("powerpc-unknown-openbsd", powerpc_unknown_openbsd),
|
2016-11-29 18:49:09 +01:00
|
|
|
|
2018-08-04 16:53:52 -05:00
|
|
|
("aarch64-unknown-netbsd", aarch64_unknown_netbsd),
|
2018-05-18 09:26:53 -05:00
|
|
|
("armv6-unknown-netbsd-eabihf", armv6_unknown_netbsd_eabihf),
|
2018-05-18 09:26:53 -05:00
|
|
|
("armv7-unknown-netbsd-eabihf", armv7_unknown_netbsd_eabihf),
|
2017-02-06 08:49:16 -06:00
|
|
|
("i686-unknown-netbsd", i686_unknown_netbsd),
|
2018-02-16 14:29:24 -06:00
|
|
|
("powerpc-unknown-netbsd", powerpc_unknown_netbsd),
|
2016-12-03 08:53:13 -06:00
|
|
|
("sparc64-unknown-netbsd", sparc64_unknown_netbsd),
|
2016-02-12 10:11:58 -05:00
|
|
|
("x86_64-unknown-netbsd", x86_64_unknown_netbsd),
|
|
|
|
|
2016-09-30 13:17:22 -05:00
|
|
|
("i686-unknown-haiku", i686_unknown_haiku),
|
|
|
|
("x86_64-unknown-haiku", x86_64_unknown_haiku),
|
2016-09-24 23:38:56 -05:00
|
|
|
|
2020-07-11 14:50:03 -04:00
|
|
|
("aarch64-apple-darwin", aarch64_apple_darwin),
|
2016-02-12 10:11:58 -05:00
|
|
|
("x86_64-apple-darwin", x86_64_apple_darwin),
|
|
|
|
("i686-apple-darwin", i686_apple_darwin),
|
|
|
|
|
2018-07-26 17:57:20 -07:00
|
|
|
("aarch64-fuchsia", aarch64_fuchsia),
|
|
|
|
("x86_64-fuchsia", x86_64_fuchsia),
|
2016-10-18 13:43:18 -07:00
|
|
|
|
2020-07-26 23:58:37 +12:00
|
|
|
("avr-unknown-gnu-atmega328", avr_unknown_gnu_atmega328),
|
2016-05-06 09:32:10 -04:00
|
|
|
|
2017-08-03 10:37:11 +02:00
|
|
|
("x86_64-unknown-l4re-uclibc", x86_64_unknown_l4re_uclibc),
|
|
|
|
|
2019-04-07 08:39:54 -06:00
|
|
|
("aarch64-unknown-redox", aarch64_unknown_redox),
|
2016-12-12 19:53:51 -07:00
|
|
|
("x86_64-unknown-redox", x86_64_unknown_redox),
|
|
|
|
|
2016-02-12 10:11:58 -05:00
|
|
|
("i386-apple-ios", i386_apple_ios),
|
|
|
|
("x86_64-apple-ios", x86_64_apple_ios),
|
|
|
|
("aarch64-apple-ios", aarch64_apple_ios),
|
|
|
|
("armv7-apple-ios", armv7_apple_ios),
|
|
|
|
("armv7s-apple-ios", armv7s_apple_ios),
|
2019-08-11 20:31:01 +02:00
|
|
|
("x86_64-apple-ios-macabi", x86_64_apple_ios_macabi),
|
2020-10-03 14:46:58 +02:00
|
|
|
("aarch64-apple-ios-macabi", aarch64_apple_ios_macabi),
|
2021-02-04 09:26:02 -05:00
|
|
|
("aarch64-apple-ios-sim", aarch64_apple_ios_sim),
|
2020-01-10 18:48:37 -08:00
|
|
|
("aarch64-apple-tvos", aarch64_apple_tvos),
|
|
|
|
("x86_64-apple-tvos", x86_64_apple_tvos),
|
2016-02-12 10:11:58 -05:00
|
|
|
|
2018-08-24 19:32:49 +02:00
|
|
|
("armebv7r-none-eabi", armebv7r_none_eabi),
|
2018-05-16 21:58:26 +02:00
|
|
|
("armebv7r-none-eabihf", armebv7r_none_eabihf),
|
2018-08-24 19:16:20 +02:00
|
|
|
("armv7r-none-eabi", armv7r_none_eabi),
|
2018-08-24 19:32:49 +02:00
|
|
|
("armv7r-none-eabihf", armv7r_none_eabihf),
|
2018-05-16 21:58:26 +02:00
|
|
|
|
2021-02-16 15:02:04 +01:00
|
|
|
("x86_64-pc-solaris", x86_64_pc_solaris),
|
|
|
|
("x86_64-sun-solaris", x86_64_sun_solaris),
|
2017-02-16 21:19:43 -08:00
|
|
|
("sparcv9-sun-solaris", sparcv9_sun_solaris),
|
2016-02-12 10:11:58 -05:00
|
|
|
|
2020-04-13 23:37:22 +00:00
|
|
|
("x86_64-unknown-illumos", x86_64_unknown_illumos),
|
|
|
|
|
2016-02-12 10:11:58 -05:00
|
|
|
("x86_64-pc-windows-gnu", x86_64_pc_windows_gnu),
|
|
|
|
("i686-pc-windows-gnu", i686_pc_windows_gnu),
|
2019-05-27 17:18:14 +02:00
|
|
|
("i686-uwp-windows-gnu", i686_uwp_windows_gnu),
|
|
|
|
("x86_64-uwp-windows-gnu", x86_64_uwp_windows_gnu),
|
2016-02-12 10:11:58 -05:00
|
|
|
|
2018-07-16 16:38:56 -07:00
|
|
|
("aarch64-pc-windows-msvc", aarch64_pc_windows_msvc),
|
2019-07-31 15:00:34 +07:00
|
|
|
("aarch64-uwp-windows-msvc", aarch64_uwp_windows_msvc),
|
2016-02-12 10:11:58 -05:00
|
|
|
("x86_64-pc-windows-msvc", x86_64_pc_windows_msvc),
|
2019-07-31 15:00:34 +07:00
|
|
|
("x86_64-uwp-windows-msvc", x86_64_uwp_windows_msvc),
|
2016-02-12 10:11:58 -05:00
|
|
|
("i686-pc-windows-msvc", i686_pc_windows_msvc),
|
2019-07-31 15:00:34 +07:00
|
|
|
("i686-uwp-windows-msvc", i686_uwp_windows_msvc),
|
2016-03-03 17:23:00 -08:00
|
|
|
("i586-pc-windows-msvc", i586_pc_windows_msvc),
|
2018-06-26 09:44:19 -07:00
|
|
|
("thumbv7a-pc-windows-msvc", thumbv7a_pc_windows_msvc),
|
2020-05-12 16:33:41 +08:00
|
|
|
("thumbv7a-uwp-windows-msvc", thumbv7a_uwp_windows_msvc),
|
2016-02-12 10:11:58 -05:00
|
|
|
|
2016-09-06 00:41:50 +00:00
|
|
|
("asmjs-unknown-emscripten", asmjs_unknown_emscripten),
|
2016-09-15 20:46:04 -05:00
|
|
|
("wasm32-unknown-emscripten", wasm32_unknown_emscripten),
|
2017-10-22 20:01:00 -07:00
|
|
|
("wasm32-unknown-unknown", wasm32_unknown_unknown),
|
2019-04-30 19:37:25 -07:00
|
|
|
("wasm32-wasi", wasm32_wasi),
|
2016-09-15 20:46:04 -05:00
|
|
|
|
|
|
|
("thumbv6m-none-eabi", thumbv6m_none_eabi),
|
|
|
|
("thumbv7m-none-eabi", thumbv7m_none_eabi),
|
|
|
|
("thumbv7em-none-eabi", thumbv7em_none_eabi),
|
|
|
|
("thumbv7em-none-eabihf", thumbv7em_none_eabihf),
|
2018-10-19 04:51:02 +00:00
|
|
|
("thumbv8m.base-none-eabi", thumbv8m_base_none_eabi),
|
2018-11-13 15:00:51 +00:00
|
|
|
("thumbv8m.main-none-eabi", thumbv8m_main_none_eabi),
|
|
|
|
("thumbv8m.main-none-eabihf", thumbv8m_main_none_eabihf),
|
2017-07-06 15:15:44 -05:00
|
|
|
|
2020-01-15 16:39:08 +01:00
|
|
|
("armv7a-none-eabi", armv7a_none_eabi),
|
|
|
|
("armv7a-none-eabihf", armv7a_none_eabihf),
|
|
|
|
|
2017-07-06 15:15:44 -05:00
|
|
|
("msp430-none-elf", msp430_none_elf),
|
2017-12-22 09:37:02 +01:00
|
|
|
|
2018-07-30 15:50:51 +02:00
|
|
|
("aarch64-unknown-hermit", aarch64_unknown_hermit),
|
|
|
|
("x86_64-unknown-hermit", x86_64_unknown_hermit),
|
2020-10-11 18:01:32 -04:00
|
|
|
|
|
|
|
("x86_64-unknown-none-hermitkernel", x86_64_unknown_none_hermitkernel),
|
2018-07-26 14:01:24 +02:00
|
|
|
|
2019-07-18 18:37:23 +03:00
|
|
|
("riscv32i-unknown-none-elf", riscv32i_unknown_none_elf),
|
2018-08-30 14:19:48 +02:00
|
|
|
("riscv32imc-unknown-none-elf", riscv32imc_unknown_none_elf),
|
2018-07-26 14:01:24 +02:00
|
|
|
("riscv32imac-unknown-none-elf", riscv32imac_unknown_none_elf),
|
2020-07-07 13:35:55 -07:00
|
|
|
("riscv32gc-unknown-linux-gnu", riscv32gc_unknown_linux_gnu),
|
2021-02-16 16:18:53 -08:00
|
|
|
("riscv32gc-unknown-linux-musl", riscv32gc_unknown_linux_musl),
|
2019-02-12 19:05:41 +03:00
|
|
|
("riscv64imac-unknown-none-elf", riscv64imac_unknown_none_elf),
|
2019-02-12 19:15:00 +03:00
|
|
|
("riscv64gc-unknown-none-elf", riscv64gc_unknown_none_elf),
|
2019-11-23 14:15:27 +07:00
|
|
|
("riscv64gc-unknown-linux-gnu", riscv64gc_unknown_linux_gnu),
|
2021-02-16 16:18:53 -08:00
|
|
|
("riscv64gc-unknown-linux-musl", riscv64gc_unknown_linux_musl),
|
2018-08-09 22:04:55 +02:00
|
|
|
|
|
|
|
("aarch64-unknown-none", aarch64_unknown_none),
|
2019-09-18 15:38:02 +02:00
|
|
|
("aarch64-unknown-none-softfloat", aarch64_unknown_none_softfloat),
|
2018-11-19 15:05:28 +05:30
|
|
|
|
|
|
|
("x86_64-fortanix-unknown-sgx", x86_64_fortanix_unknown_sgx),
|
Add x86_64-unknown-uefi target
This adds a new rustc target-configuration called 'x86_64-unknown_uefi'.
Furthermore, it adds a UEFI base-configuration to be used with other
targets supported by UEFI (e.g., i386, armv7hl, aarch64, itanium, ...).
UEFI systems provide a very basic operating-system environment, meant
to unify how systems are booted. It is tailored for simplicity and fast
setup, as it is only meant to bootstrap other systems. For instance, it
copies most of the ABI from Microsoft Windows, rather than inventing
anything on its own. Furthermore, any complex CPU features are
disabled. Only one CPU is allowed to be up, no interrupts other than
the timer-interrupt are allowed, no process-separation is performed,
page-tables are identity-mapped, ...
Nevertheless, UEFI has an application model. Its main purpose is to
allow operating-system vendors to write small UEFI applications that
load their kernel and terminate the UEFI system. However, many other
UEFI applications have emerged in the past, including network-boot,
debug-consoles, and more.
This UEFI target allows to compile rust code natively as UEFI
applications. No standard library support is added, but libcore can be
used out-of-the-box if a panic-handler is provided. Furthermore,
liballoc works as well, if a `GlobalAlloc` handler is provided. Both
have been tested with this target-configuration.
Note that full libstd support is unlikely to happen. While UEFI does
have standardized interfaces for networking and alike, none of these
are mandatory and they are unlikely to be shipped in common consumer
firmwares. Furthermore, several features like process-separation are
not available (or only in very limited fashion). Those parts of libstd
would have to be masked.
2018-12-13 10:08:20 +01:00
|
|
|
|
|
|
|
("x86_64-unknown-uefi", x86_64_unknown_uefi),
|
Add i686-unknown-uefi target
This adds a new rustc target-configuration called 'i686-unknown_uefi'.
This is similar to existing x86_64-unknown_uefi target.
The i686-unknown-uefi target can be used to build Intel Architecture
32bit UEFI application. The ABI defined in UEFI environment (aka IA32)
is similar to cdecl.
We choose i686-unknown-uefi-gnu instead of i686-unknown-uefi to avoid
the intrinsics generated by LLVM. The detail of root-cause and solution
analysis is added as comment in the code.
For x86_64-unknown-uefi, we cannot use -gnu, because the ABI between
MSVC and GNU is totally different, and UEFI chooses ABI similar to MSVC.
For i686-unknown-uefi, the UEFI chooses cdecl ABI, which is same as
MSVC and GNU. According to LLVM code, the only differences between MSVC
and GNU are fmodf(f32), longjmp() and TLS, which have no impact to UEFI.
As such, using i686-unknown-uefi-gnu is the simplest way to pass the build.
Adding the undefined symbols, such as _aulldiv() to rust compiler-builtins
is out of scope. But it may be considered later.
The scope of this patch is limited to support target-configuration.
No standard library support is added in this patch. Such work can be
done in future enhancement.
Cc: Josh Triplett <josh.triplett@intel.com>
Reviewed-by: Josh Triplett <josh.triplett@intel.com>
2019-08-29 11:44:37 +08:00
|
|
|
("i686-unknown-uefi", i686_unknown_uefi),
|
2019-01-19 21:59:34 +01:00
|
|
|
|
|
|
|
("nvptx64-nvidia-cuda", nvptx64_nvidia_cuda),
|
2019-07-15 23:57:53 -07:00
|
|
|
|
|
|
|
("i686-wrs-vxworks", i686_wrs_vxworks),
|
2019-08-12 10:46:57 -07:00
|
|
|
("x86_64-wrs-vxworks", x86_64_wrs_vxworks),
|
|
|
|
("armv7-wrs-vxworks-eabihf", armv7_wrs_vxworks_eabihf),
|
2019-07-15 23:57:53 -07:00
|
|
|
("aarch64-wrs-vxworks", aarch64_wrs_vxworks),
|
|
|
|
("powerpc-wrs-vxworks", powerpc_wrs_vxworks),
|
|
|
|
("powerpc-wrs-vxworks-spe", powerpc_wrs_vxworks_spe),
|
|
|
|
("powerpc64-wrs-vxworks", powerpc64_wrs_vxworks),
|
2020-05-09 15:41:49 -04:00
|
|
|
|
|
|
|
("mipsel-sony-psp", mipsel_sony_psp),
|
2020-11-02 19:11:24 +01:00
|
|
|
("mipsel-unknown-none", mipsel_unknown_none),
|
2020-07-17 18:59:24 -06:00
|
|
|
("thumbv4t-none-eabi", thumbv4t_none_eabi),
|
2021-01-20 17:13:49 +00:00
|
|
|
|
|
|
|
("aarch64_be-unknown-linux-gnu", aarch64_be_unknown_linux_gnu),
|
|
|
|
("aarch64-unknown-linux-gnu_ilp32", aarch64_unknown_linux_gnu_ilp32),
|
|
|
|
("aarch64_be-unknown-linux-gnu_ilp32", aarch64_be_unknown_linux_gnu_ilp32),
|
2016-02-12 10:11:58 -05:00
|
|
|
}
|
|
|
|
|
2014-07-23 11:56:36 -07:00
|
|
|
/// Everything `rustc` knows about how to compile for a specific target.
|
|
|
|
///
|
|
|
|
/// Every field here must be specified, and has no default value.
|
2016-07-23 07:22:58 -05:00
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
2014-07-23 11:56:36 -07:00
|
|
|
pub struct Target {
|
|
|
|
/// Target triple to pass to LLVM.
|
|
|
|
pub llvm_target: String,
|
2020-10-14 18:22:10 +02:00
|
|
|
/// Number of bits in a pointer. Influences the `target_pointer_width` `cfg` variable.
|
|
|
|
pub pointer_width: u32,
|
2019-07-01 17:31:52 -04:00
|
|
|
/// Architecture to use for ABI considerations. Valid options include: "x86",
|
|
|
|
/// "x86_64", "arm", "aarch64", "mips", "powerpc", "powerpc64", and others.
|
2014-07-23 11:56:36 -07:00
|
|
|
pub arch: String,
|
2016-04-18 15:38:45 +03:00
|
|
|
/// [Data layout](http://llvm.org/docs/LangRef.html#data-layout) to pass to LLVM.
|
|
|
|
pub data_layout: String,
|
2014-07-23 11:56:36 -07:00
|
|
|
/// Optional settings with defaults.
|
|
|
|
pub options: TargetOptions,
|
|
|
|
}
|
|
|
|
|
2018-11-03 22:57:53 +02:00
|
|
|
pub trait HasTargetSpec {
|
2018-04-18 16:01:26 +03:00
|
|
|
fn target_spec(&self) -> &Target;
|
|
|
|
}
|
|
|
|
|
2018-11-03 22:57:53 +02:00
|
|
|
impl HasTargetSpec for Target {
|
2018-04-18 16:01:26 +03:00
|
|
|
fn target_spec(&self) -> &Target {
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-23 11:56:36 -07:00
|
|
|
/// Optional aspects of a target specification.
|
|
|
|
///
|
|
|
|
/// This has an implementation of `Default`, see each field for what the default is. In general,
|
|
|
|
/// these try to take "minimal defaults" that don't assume anything about the runtime they run in.
|
2020-11-08 14:27:51 +03:00
|
|
|
///
|
|
|
|
/// `TargetOptions` as a separate structure is mostly an implementation detail of `Target`
|
|
|
|
/// construction, all its fields logically belong to `Target` and available from `Target`
|
|
|
|
/// through `Deref` impls.
|
2016-07-23 07:22:58 -05:00
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
2014-07-23 11:56:36 -07:00
|
|
|
pub struct TargetOptions {
|
2016-04-18 15:38:45 +03:00
|
|
|
/// Whether the target is built-in or loaded from a custom target specification.
|
|
|
|
pub is_builtin: bool,
|
|
|
|
|
2021-01-05 01:01:29 +00:00
|
|
|
/// Used as the `target_endian` `cfg` variable. Defaults to little endian.
|
|
|
|
pub endian: Endian,
|
2020-10-08 19:57:41 +03:00
|
|
|
/// Width of c_int type. Defaults to "32".
|
2020-11-08 14:57:55 +03:00
|
|
|
pub c_int_width: String,
|
2020-11-11 20:40:51 +03:00
|
|
|
/// OS name to use for conditional compilation (`target_os`). Defaults to "none".
|
2020-11-11 20:10:15 +03:00
|
|
|
/// "none" implies a bare metal target without `std` library.
|
|
|
|
/// A couple of targets having `std` also use "unknown" as an `os` value,
|
|
|
|
/// but they are exceptions.
|
2020-11-08 14:57:55 +03:00
|
|
|
pub os: String,
|
2020-11-11 20:40:51 +03:00
|
|
|
/// Environment name to use for conditional compilation (`target_env`). Defaults to "".
|
2020-11-08 14:57:55 +03:00
|
|
|
pub env: String,
|
2020-11-11 20:40:51 +03:00
|
|
|
/// Vendor name to use for conditional compilation (`target_vendor`). Defaults to "unknown".
|
2020-11-08 14:57:55 +03:00
|
|
|
pub vendor: String,
|
2020-10-08 22:22:28 +03:00
|
|
|
/// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed
|
|
|
|
/// on the command line. Defaults to `LinkerFlavor::Gcc`.
|
|
|
|
pub linker_flavor: LinkerFlavor,
|
2020-10-08 19:36:11 +03:00
|
|
|
|
2018-02-10 12:09:25 -08:00
|
|
|
/// Linker to invoke
|
|
|
|
pub linker: Option<String>,
|
2015-10-18 14:32:50 -07:00
|
|
|
|
2020-04-11 02:52:34 +03:00
|
|
|
/// LLD flavor used if `lld` (or `rust-lld`) is specified as a linker
|
|
|
|
/// without clarifying its flavor in any way.
|
2018-08-18 16:31:36 +02:00
|
|
|
pub lld_flavor: LldFlavor,
|
|
|
|
|
2018-04-29 11:17:54 +02:00
|
|
|
/// Linker arguments that are passed *before* any user-defined libraries.
|
2020-05-30 17:03:50 +03:00
|
|
|
pub pre_link_args: LinkArgs,
|
2020-04-29 20:47:07 +03:00
|
|
|
/// Objects to link before and after all other object code.
|
|
|
|
pub pre_link_objects: CrtObjects,
|
|
|
|
pub post_link_objects: CrtObjects,
|
|
|
|
/// Same as `(pre|post)_link_objects`, but when we fail to pull the objects with help of the
|
|
|
|
/// target's native gcc and fall back to the "self-contained" mode and pull them manually.
|
|
|
|
/// See `crt_objects.rs` for some more detailed documentation.
|
|
|
|
pub pre_link_objects_fallback: CrtObjects,
|
|
|
|
pub post_link_objects_fallback: CrtObjects,
|
|
|
|
/// Which logic to use to determine whether to fall back to the "self-contained" mode or not.
|
|
|
|
pub crt_objects_fallback: Option<CrtObjectsFallback>,
|
|
|
|
|
2015-10-18 14:32:50 -07:00
|
|
|
/// Linker arguments that are unconditionally passed after any
|
2020-04-29 20:47:07 +03:00
|
|
|
/// user-defined but before post-link objects. Standard platform
|
2015-10-18 14:32:50 -07:00
|
|
|
/// libraries that should be always be linked to, usually go here.
|
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
2017-02-21 14:47:15 -05:00
|
|
|
pub late_link_args: LinkArgs,
|
2020-03-03 20:41:37 +00:00
|
|
|
/// Linker arguments used in addition to `late_link_args` if at least one
|
|
|
|
/// Rust dependency is dynamically linked.
|
|
|
|
pub late_link_args_dynamic: LinkArgs,
|
|
|
|
/// Linker arguments used in addition to `late_link_args` if aall Rust
|
|
|
|
/// dependencies are statically linked.
|
|
|
|
pub late_link_args_static: LinkArgs,
|
2015-04-21 18:00:16 -07:00
|
|
|
/// Linker arguments that are unconditionally passed *after* any
|
|
|
|
/// user-defined libraries.
|
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
2017-02-21 14:47:15 -05:00
|
|
|
pub post_link_args: LinkArgs,
|
2020-05-10 17:39:57 -04:00
|
|
|
/// Optional link script applied to `dylib` and `executable` crate types.
|
|
|
|
/// This is a string containing the script, not a path. Can only be applied
|
|
|
|
/// to linkers where `linker_is_gnu` is true.
|
|
|
|
pub link_script: Option<String>,
|
2015-10-18 14:32:50 -07:00
|
|
|
|
2019-09-12 13:47:17 +03:00
|
|
|
/// Environment variables to be set for the linker invocation.
|
2017-06-22 15:16:54 -07:00
|
|
|
pub link_env: Vec<(String, String)>,
|
2019-09-12 13:47:17 +03:00
|
|
|
/// Environment variables to be removed for the linker invocation.
|
|
|
|
pub link_env_remove: Vec<String>,
|
2017-06-22 15:16:54 -07:00
|
|
|
|
2016-12-18 22:25:46 -05:00
|
|
|
/// Extra arguments to pass to the external assembler (when used)
|
|
|
|
pub asm_args: Vec<String>,
|
|
|
|
|
2015-04-21 18:00:16 -07:00
|
|
|
/// Default CPU to pass to LLVM. Corresponds to `llc -mcpu=$cpu`. Defaults
|
2016-05-05 14:23:43 +02:00
|
|
|
/// to "generic".
|
2014-07-23 11:56:36 -07:00
|
|
|
pub cpu: String,
|
2015-04-21 18:00:16 -07:00
|
|
|
/// Default target features to pass to LLVM. These features will *always* be
|
|
|
|
/// passed, and cannot be disabled even via `-C`. Corresponds to `llc
|
|
|
|
/// -mattr=$features`.
|
2014-07-23 11:56:36 -07:00
|
|
|
pub features: String,
|
|
|
|
/// Whether dynamic linking is available on this target. Defaults to false.
|
|
|
|
pub dynamic_linking: bool,
|
2017-10-22 20:01:00 -07:00
|
|
|
/// If dynamic linking is available, whether only cdylibs are supported.
|
|
|
|
pub only_cdylib: bool,
|
2014-07-23 11:56:36 -07:00
|
|
|
/// Whether executables are available on this target. iOS, for example, only allows static
|
|
|
|
/// libraries. Defaults to false.
|
|
|
|
pub executables: bool,
|
|
|
|
/// Relocation model to use in object file. Corresponds to `llc
|
2020-04-23 00:46:45 +03:00
|
|
|
/// -relocation-model=$relocation_model`. Defaults to `Pic`.
|
|
|
|
pub relocation_model: RelocModel,
|
2018-01-22 17:01:36 -08:00
|
|
|
/// Code model to use. Corresponds to `llc -code-model=$code_model`.
|
2020-05-07 03:34:27 +03:00
|
|
|
/// Defaults to `None` which means "inherited from the base LLVM target".
|
|
|
|
pub code_model: Option<CodeModel>,
|
2017-10-31 17:45:19 +00:00
|
|
|
/// TLS model to use. Options are "global-dynamic" (default), "local-dynamic", "initial-exec"
|
|
|
|
/// and "local-exec". This is similar to the -ftls-model option in GCC/Clang.
|
2020-04-25 21:45:21 +03:00
|
|
|
pub tls_model: TlsModel,
|
2014-07-23 11:56:36 -07:00
|
|
|
/// Do not emit code that uses the "red zone", if the ABI has one. Defaults to false.
|
|
|
|
pub disable_redzone: bool,
|
|
|
|
/// Eliminate frame pointers from stack frames if possible. Defaults to true.
|
|
|
|
pub eliminate_frame_pointer: bool,
|
|
|
|
/// Emit each function in its own section. Defaults to true.
|
|
|
|
pub function_sections: bool,
|
|
|
|
/// String to prepend to the name of every dynamic library. Defaults to "lib".
|
|
|
|
pub dll_prefix: String,
|
|
|
|
/// String to append to the name of every dynamic library. Defaults to ".so".
|
|
|
|
pub dll_suffix: String,
|
|
|
|
/// String to append to the name of every executable.
|
|
|
|
pub exe_suffix: String,
|
|
|
|
/// String to prepend to the name of every static library. Defaults to "lib".
|
|
|
|
pub staticlib_prefix: String,
|
|
|
|
/// String to append to the name of every static library. Defaults to ".a".
|
|
|
|
pub staticlib_suffix: String,
|
2015-10-08 22:08:07 -04:00
|
|
|
/// OS family to use for conditional compilation. Valid options: "unix", "windows".
|
2020-11-08 14:57:55 +03:00
|
|
|
pub os_family: Option<String>,
|
2018-02-26 10:20:14 -08:00
|
|
|
/// Whether the target toolchain's ABI supports returning small structs as an integer.
|
|
|
|
pub abi_return_struct_as_int: bool,
|
2017-03-12 14:13:35 -04:00
|
|
|
/// Whether the target toolchain is like macOS's. Only useful for compiling against iOS/macOS,
|
|
|
|
/// in particular running dsymutil and some other stuff like `-dead_strip`. Defaults to false.
|
2014-07-23 11:56:36 -07:00
|
|
|
pub is_like_osx: bool,
|
2016-01-21 19:30:22 +03:00
|
|
|
/// Whether the target toolchain is like Solaris's.
|
|
|
|
/// Only useful for compiling against Illumos/Solaris,
|
|
|
|
/// as they have a different set of linker flags. Defaults to false.
|
2016-01-28 14:02:31 +03:00
|
|
|
pub is_like_solaris: bool,
|
2020-11-12 00:54:23 +03:00
|
|
|
/// Whether the target is like Windows.
|
|
|
|
/// This is a combination of several more specific properties represented as a single flag:
|
|
|
|
/// - The target uses a Windows ABI,
|
|
|
|
/// - uses PE/COFF as a format for object code,
|
|
|
|
/// - uses Windows-style dllexport/dllimport for shared libraries,
|
|
|
|
/// - uses import libraries and .def files for symbol exports,
|
|
|
|
/// - executables support setting a subsystem.
|
2014-07-23 11:56:36 -07:00
|
|
|
pub is_like_windows: bool,
|
2020-11-12 00:54:23 +03:00
|
|
|
/// Whether the target is like MSVC.
|
|
|
|
/// This is a combination of several more specific properties represented as a single flag:
|
|
|
|
/// - The target has all the properties from `is_like_windows`
|
|
|
|
/// (for in-tree targets "is_like_msvc ⇒ is_like_windows" is ensured by a unit test),
|
|
|
|
/// - has some MSVC-specific Windows ABI properties,
|
|
|
|
/// - uses a link.exe-like linker,
|
|
|
|
/// - uses CodeView/PDB for debuginfo and natvis for its visualization,
|
|
|
|
/// - uses SEH-based unwinding,
|
|
|
|
/// - supports control flow guard mechanism.
|
2015-03-04 22:58:59 +00:00
|
|
|
pub is_like_msvc: bool,
|
2017-01-19 22:31:57 +03:00
|
|
|
/// Whether the target toolchain is like Emscripten's. Only useful for compiling with
|
|
|
|
/// Emscripten toolchain.
|
|
|
|
/// Defaults to false.
|
|
|
|
pub is_like_emscripten: bool,
|
2018-11-22 00:59:37 -08:00
|
|
|
/// Whether the target toolchain is like Fuchsia's.
|
|
|
|
pub is_like_fuchsia: bool,
|
2020-10-09 15:08:18 -04:00
|
|
|
/// Version of DWARF to use if not using the default.
|
|
|
|
/// Useful because some platforms (osx, bsd) only want up to DWARF2.
|
|
|
|
pub dwarf_version: Option<u32>,
|
2014-07-23 11:56:36 -07:00
|
|
|
/// Whether the linker support GNU-like arguments such as -O. Defaults to false.
|
|
|
|
pub linker_is_gnu: bool,
|
2016-07-13 17:03:02 -04:00
|
|
|
/// The MinGW toolchain has a known issue that prevents it from correctly
|
2017-12-31 17:17:01 +01:00
|
|
|
/// handling COFF object files with more than 2<sup>15</sup> sections. Since each weak
|
2016-07-13 17:03:02 -04:00
|
|
|
/// symbol needs its own COMDAT section, weak linkage implies a large
|
|
|
|
/// number sections that easily exceeds the given limit for larger
|
|
|
|
/// codebases. Consequently we want a way to disallow weak linkage on some
|
|
|
|
/// platforms.
|
|
|
|
pub allows_weak_linkage: bool,
|
2014-07-23 11:56:36 -07:00
|
|
|
/// Whether the linker support rpaths or not. Defaults to false.
|
|
|
|
pub has_rpath: bool,
|
2015-09-21 19:02:46 +02:00
|
|
|
/// Whether to disable linking to the default libraries, typically corresponds
|
|
|
|
/// to `-nodefaultlibs`. Defaults to true.
|
|
|
|
pub no_default_libraries: bool,
|
2015-05-11 14:41:27 -07:00
|
|
|
/// Dynamically linked executables can be compiled as position independent
|
|
|
|
/// if the default relocation model of position independent code is not
|
|
|
|
/// changed. This is a requirement to take advantage of ASLR, as otherwise
|
|
|
|
/// the functions in the executable are not randomized and can be used
|
|
|
|
/// during an exploit of a vulnerability in any code.
|
2014-11-06 00:17:56 -05:00
|
|
|
pub position_independent_executables: bool,
|
2020-05-02 01:59:35 +03:00
|
|
|
/// Executables that are both statically linked and position-independent are supported.
|
|
|
|
pub static_position_independent_executables: bool,
|
2018-09-26 19:19:55 +03:00
|
|
|
/// Determines if the target always requires using the PLT for indirect
|
|
|
|
/// library calls or not. This controls the default value of the `-Z plt` flag.
|
|
|
|
pub needs_plt: bool,
|
2017-07-14 22:01:37 +02:00
|
|
|
/// Either partial, full, or off. Full RELRO makes the dynamic linker
|
|
|
|
/// resolve all symbols at startup and marks the GOT read-only before
|
|
|
|
/// starting the program, preventing overwriting the GOT.
|
|
|
|
pub relro_level: RelroLevel,
|
trans: Use LLVM's writeArchive to modify archives
We have previously always relied upon an external tool, `ar`, to modify archives
that the compiler produces (staticlibs, rlibs, etc). This approach, however, has
a number of downsides:
* Spawning a process is relatively expensive for small compilations
* Encoding arguments across process boundaries often incurs unnecessary overhead
or lossiness. For example `ar` has a tough time dealing with files that have
the same name in archives, and the compiler copies many files around to ensure
they can be passed to `ar` in a reasonable fashion.
* Most `ar` programs found do **not** have the ability to target arbitrary
platforms, so this is an extra tool which needs to be found/specified when
cross compiling.
The LLVM project has had a tool called `llvm-ar` for quite some time now, but it
wasn't available in the standard LLVM libraries (it was just a standalone
program). Recently, however, in LLVM 3.7, this functionality has been moved to a
library and is now accessible by consumers of LLVM via the `writeArchive`
function.
This commit migrates our archive bindings to no longer invoke `ar` by default
but instead make a library call to LLVM to do various operations. This solves
all of the downsides listed above:
* Archive management is now much faster, for example creating a "hello world"
staticlib is now 6x faster (50ms => 8ms). Linking dynamic libraries also
recently started requiring modification of rlibs, and linking a hello world
dynamic library is now 2x faster.
* The compiler is now one step closer to "hassle free" cross compilation because
no external tool is needed for managing archives, LLVM does the right thing!
This commit does not remove support for calling a system `ar` utility currently.
We will continue to maintain compatibility with LLVM 3.5 and 3.6 looking forward
(so the system LLVM can be used wherever possible), and in these cases we must
shell out to a system utility. All nightly builds of Rust, however, will stop
needing a system `ar`.
2015-07-09 00:14:20 -07:00
|
|
|
/// Format that archives should be emitted in. This affects whether we use
|
|
|
|
/// LLVM to assemble an archive or fall back to the system linker, and
|
|
|
|
/// currently only "gnu" is used to fall into LLVM. Unknown strings cause
|
|
|
|
/// the system linker to be used.
|
|
|
|
pub archive_format: String,
|
2015-08-20 17:47:21 -05:00
|
|
|
/// Is asm!() allowed? Defaults to true.
|
|
|
|
pub allow_asm: bool,
|
2019-10-17 16:09:32 -07:00
|
|
|
/// Whether the runtime startup code requires the `main` function be passed
|
|
|
|
/// `argc` and `argv` values.
|
|
|
|
pub main_needs_argc_argv: bool,
|
2015-06-25 10:07:01 -07:00
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Flag indicating whether ELF TLS (e.g., #[thread_local]) is available for
|
2015-12-10 12:21:55 -08:00
|
|
|
/// this target.
|
|
|
|
pub has_elf_tls: bool,
|
2015-11-27 19:44:33 +00:00
|
|
|
// This is mainly for easy compatibility with emscripten.
|
|
|
|
// If we give emcc .o files that are actually .bc files it
|
|
|
|
// will 'just work'.
|
|
|
|
pub obj_is_bitcode: bool,
|
2020-05-07 12:26:18 +10:00
|
|
|
/// Whether the target requires that emitted object code includes bitcode.
|
|
|
|
pub forces_embed_bitcode: bool,
|
2020-05-07 15:34:31 +10:00
|
|
|
/// Content of the LLVM cmdline section associated with embedded bitcode.
|
|
|
|
pub bitcode_llvm_cmdline: String,
|
2016-04-15 20:16:19 +01:00
|
|
|
|
2016-08-15 09:46:44 +00:00
|
|
|
/// Don't use this field; instead use the `.min_atomic_width()` method.
|
|
|
|
pub min_atomic_width: Option<u64>,
|
|
|
|
|
2016-10-03 23:45:40 -05:00
|
|
|
/// Don't use this field; instead use the `.max_atomic_width()` method.
|
|
|
|
pub max_atomic_width: Option<u64>,
|
2016-09-27 21:26:08 -05:00
|
|
|
|
2018-06-30 14:56:08 -05:00
|
|
|
/// Whether the target supports atomic CAS operations natively
|
|
|
|
pub atomic_cas: bool,
|
|
|
|
|
2016-09-27 21:26:08 -05:00
|
|
|
/// Panic strategy: "unwind" or "abort"
|
|
|
|
pub panic_strategy: PanicStrategy,
|
2016-10-24 11:04:04 +02:00
|
|
|
|
2020-07-08 09:36:52 -04:00
|
|
|
/// A list of ABIs unsupported by the current target. Note that generic ABIs
|
|
|
|
/// are considered to be supported on all platforms and cannot be marked
|
|
|
|
/// unsupported.
|
|
|
|
pub unsupported_abis: Vec<Abi>,
|
rustc: Implement #[link(cfg(..))] and crt-static
This commit is an implementation of [RFC 1721] which adds a new target feature
to the compiler, `crt-static`, which can be used to select how the C runtime for
a target is linked. Most targets dynamically linke the C runtime by default with
the notable exception of some of the musl targets.
[RFC 1721]: https://github.com/rust-lang/rfcs/blob/master/text/1721-crt-static.md
This commit first adds the new target-feature, `crt-static`. If enabled, then
the `cfg(target_feature = "crt-static")` will be available. Targets like musl
will have this enabled by default. This feature can be controlled through the
standard target-feature interface, `-C target-feature=+crt-static` or
`-C target-feature=-crt-static`.
Next this adds an gated and unstable `#[link(cfg(..))]` feature to enable the
`crt-static` semantics we want with libc. The exact behavior of this attribute
is a little squishy, but it's intended to be a forever-unstable
implementation detail of the liblibc crate.
Specifically the `#[link(cfg(..))]` annotation means that the `#[link]`
directive is only active in a compilation unit if that `cfg` value is satisfied.
For example when compiling an rlib, these directives are just encoded and
ignored for dylibs, and all staticlibs are continued to be put into the rlib as
usual. When placing that rlib into a staticlib, executable, or dylib, however,
the `cfg` is evaluated *as if it were defined in the final artifact* and the
library is decided to be linked or not.
Essentially, what'll happen is:
* On MSVC with `-C target-feature=-crt-static`, the `msvcrt.lib` library will be
linked to.
* On MSVC with `-C target-feature=+crt-static`, the `libcmt.lib` library will be
linked to.
* On musl with `-C target-feature=-crt-static`, the object files in liblibc.rlib
are removed and `-lc` is passed instead.
* On musl with `-C target-feature=+crt-static`, the object files in liblibc.rlib
are used and `-lc` is not passed.
This commit does **not** include an update to the liblibc module to implement
these changes. I plan to do that just after the 1.14.0 beta release is cut to
ensure we get ample time to test this feature.
cc #37406
2016-10-31 16:40:13 -07:00
|
|
|
|
2017-08-22 16:24:29 -05:00
|
|
|
/// Whether or not linking dylibs to a static CRT is allowed.
|
|
|
|
pub crt_static_allows_dylibs: bool,
|
rustc: Implement #[link(cfg(..))] and crt-static
This commit is an implementation of [RFC 1721] which adds a new target feature
to the compiler, `crt-static`, which can be used to select how the C runtime for
a target is linked. Most targets dynamically linke the C runtime by default with
the notable exception of some of the musl targets.
[RFC 1721]: https://github.com/rust-lang/rfcs/blob/master/text/1721-crt-static.md
This commit first adds the new target-feature, `crt-static`. If enabled, then
the `cfg(target_feature = "crt-static")` will be available. Targets like musl
will have this enabled by default. This feature can be controlled through the
standard target-feature interface, `-C target-feature=+crt-static` or
`-C target-feature=-crt-static`.
Next this adds an gated and unstable `#[link(cfg(..))]` feature to enable the
`crt-static` semantics we want with libc. The exact behavior of this attribute
is a little squishy, but it's intended to be a forever-unstable
implementation detail of the liblibc crate.
Specifically the `#[link(cfg(..))]` annotation means that the `#[link]`
directive is only active in a compilation unit if that `cfg` value is satisfied.
For example when compiling an rlib, these directives are just encoded and
ignored for dylibs, and all staticlibs are continued to be put into the rlib as
usual. When placing that rlib into a staticlib, executable, or dylib, however,
the `cfg` is evaluated *as if it were defined in the final artifact* and the
library is decided to be linked or not.
Essentially, what'll happen is:
* On MSVC with `-C target-feature=-crt-static`, the `msvcrt.lib` library will be
linked to.
* On MSVC with `-C target-feature=+crt-static`, the `libcmt.lib` library will be
linked to.
* On musl with `-C target-feature=-crt-static`, the object files in liblibc.rlib
are removed and `-lc` is passed instead.
* On musl with `-C target-feature=+crt-static`, the object files in liblibc.rlib
are used and `-lc` is not passed.
This commit does **not** include an update to the liblibc module to implement
these changes. I plan to do that just after the 1.14.0 beta release is cut to
ensure we get ample time to test this feature.
cc #37406
2016-10-31 16:40:13 -07:00
|
|
|
/// Whether or not the CRT is statically linked by default.
|
|
|
|
pub crt_static_default: bool,
|
2017-08-22 16:24:29 -05:00
|
|
|
/// Whether or not crt-static is respected by the compiler (or is a no-op).
|
|
|
|
pub crt_static_respected: bool,
|
2017-06-21 12:08:18 -07:00
|
|
|
|
2021-01-09 16:54:20 +02:00
|
|
|
/// The implementation of stack probes to use.
|
|
|
|
pub stack_probes: StackProbeType,
|
2017-09-08 14:49:51 -07:00
|
|
|
|
|
|
|
/// The minimum alignment for global symbols.
|
|
|
|
pub min_global_align: Option<u64>,
|
2017-10-04 14:38:52 -07:00
|
|
|
|
|
|
|
/// Default number of codegen units to use in debug mode
|
|
|
|
pub default_codegen_units: Option<u64>,
|
2017-11-11 07:08:00 -08:00
|
|
|
|
|
|
|
/// Whether to generate trap instructions in places where optimization would
|
|
|
|
/// otherwise produce control flow that falls through into unrelated memory.
|
|
|
|
pub trap_unreachable: bool,
|
2017-10-22 20:01:00 -07:00
|
|
|
|
|
|
|
/// This target requires everything to be compiled with LTO to emit a final
|
|
|
|
/// executable, aka there is no native linker for this target.
|
|
|
|
pub requires_lto: bool,
|
|
|
|
|
|
|
|
/// This target has no support for threads.
|
|
|
|
pub singlethread: bool,
|
|
|
|
|
|
|
|
/// Whether library functions call lowering/optimization is disabled in LLVM
|
|
|
|
/// for this target unconditionally.
|
|
|
|
pub no_builtins: bool,
|
2017-12-03 21:53:48 -08:00
|
|
|
|
2018-01-30 11:54:07 -08:00
|
|
|
/// The default visibility for symbols in this target should be "hidden"
|
|
|
|
/// rather than "default"
|
|
|
|
pub default_hidden_visibility: bool,
|
2018-03-09 07:25:54 -08:00
|
|
|
|
2018-04-06 15:40:43 +02:00
|
|
|
/// Whether a .debug_gdb_scripts section will be added to the output object file
|
|
|
|
pub emit_debug_gdb_scripts: bool,
|
2018-04-19 15:17:34 -07:00
|
|
|
|
|
|
|
/// Whether or not to unconditionally `uwtable` attributes on functions,
|
|
|
|
/// typically because the platform needs to unwind for things like stack
|
|
|
|
/// unwinders.
|
|
|
|
pub requires_uwtable: bool,
|
2018-10-12 17:04:31 -07:00
|
|
|
|
2021-03-23 02:38:30 +08:00
|
|
|
/// Whether or not to emit `uwtable` attributes on functions if `-C force-unwind-tables`
|
|
|
|
/// is not specified and `uwtable` is not required on this target.
|
|
|
|
pub default_uwtable: bool,
|
|
|
|
|
2018-10-12 17:04:31 -07:00
|
|
|
/// Whether or not SIMD types are passed by reference in the Rust ABI,
|
|
|
|
/// typically required if a target can be compiled with a mixed set of
|
|
|
|
/// target features. This is `true` by default, and `false` for targets like
|
|
|
|
/// wasm32 where the whole program either has simd or not.
|
|
|
|
pub simd_types_indirect: bool,
|
2018-11-19 15:04:28 +05:30
|
|
|
|
2019-04-14 19:05:21 +02:00
|
|
|
/// Pass a list of symbol which should be exported in the dylib to the linker.
|
|
|
|
pub limit_rdylib_exports: bool,
|
|
|
|
|
2018-11-19 15:04:28 +05:30
|
|
|
/// If set, have the linker export exactly these symbols, instead of using
|
|
|
|
/// the usual logic to figure this out from the crate itself.
|
2018-12-31 10:58:13 -08:00
|
|
|
pub override_export_symbols: Option<Vec<String>>,
|
|
|
|
|
|
|
|
/// Determines how or whether the MergeFunctions LLVM pass should run for
|
|
|
|
/// this target. Either "disabled", "trampolines", or "aliases".
|
|
|
|
/// The MergeFunctions pass is generally useful, but some targets may need
|
|
|
|
/// to opt out. The default is "aliases".
|
|
|
|
///
|
2020-10-14 17:35:43 +02:00
|
|
|
/// Workaround for: <https://github.com/rust-lang/rust/issues/57356>
|
2019-03-30 18:50:19 +09:00
|
|
|
pub merge_functions: MergeFunctions,
|
|
|
|
|
|
|
|
/// Use platform dependent mcount function
|
2020-11-08 14:57:55 +03:00
|
|
|
pub mcount: String,
|
2019-10-29 21:12:05 -07:00
|
|
|
|
|
|
|
/// LLVM ABI name, corresponds to the '-mabi' parameter available in multilib C compilers
|
|
|
|
pub llvm_abiname: String,
|
2019-12-02 17:52:45 +05:30
|
|
|
|
|
|
|
/// Whether or not RelaxElfRelocation flag will be passed to the linker
|
|
|
|
pub relax_elf_relocations: bool,
|
2020-01-09 16:40:40 +01:00
|
|
|
|
|
|
|
/// Additional arguments to pass to LLVM, similar to the `-C llvm-args` codegen option.
|
|
|
|
pub llvm_args: Vec<String>,
|
2020-04-16 19:40:11 -07:00
|
|
|
|
|
|
|
/// Whether to use legacy .ctors initialization hooks rather than .init_array. Defaults
|
|
|
|
/// to false (uses .init_array).
|
|
|
|
pub use_ctors_section: bool,
|
2020-07-22 15:49:04 +03:00
|
|
|
|
|
|
|
/// Whether the linker is instructed to add a `GNU_EH_FRAME` ELF header
|
|
|
|
/// used to locate unwinding information is passed
|
|
|
|
/// (only has effect if the linker is `ld`-like).
|
|
|
|
pub eh_frame_header: bool,
|
2020-10-08 23:23:27 +01:00
|
|
|
|
|
|
|
/// Is true if the target is an ARM architecture using thumb v1 which allows for
|
|
|
|
/// thumb and arm interworking.
|
|
|
|
pub has_thumb_interworking: bool,
|
2020-11-30 08:39:08 -08:00
|
|
|
|
|
|
|
/// How to handle split debug information, if at all. Specifying `None` has
|
|
|
|
/// target-specific meaning.
|
|
|
|
pub split_debuginfo: SplitDebuginfo,
|
2021-02-08 00:49:00 +02:00
|
|
|
|
|
|
|
/// The sanitizers supported by this target
|
|
|
|
///
|
|
|
|
/// Note that the support here is at a codegen level. If the machine code with sanitizer
|
|
|
|
/// enabled can generated on this target, but the necessary supporting libraries are not
|
|
|
|
/// distributed with the target, the sanitizer should still appear in this list for the target.
|
|
|
|
pub supported_sanitizers: SanitizerSet,
|
2014-07-23 11:56:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for TargetOptions {
|
2019-02-08 14:53:55 +01:00
|
|
|
/// Creates a set of "sane defaults" for any target. This is still
|
2015-05-11 14:41:27 -07:00
|
|
|
/// incomplete, and if used for compilation, will certainly not work.
|
2014-07-23 11:56:36 -07:00
|
|
|
fn default() -> TargetOptions {
|
|
|
|
TargetOptions {
|
2016-04-18 15:38:45 +03:00
|
|
|
is_builtin: false,
|
2021-01-05 01:01:29 +00:00
|
|
|
endian: Endian::Little,
|
2020-11-08 14:57:55 +03:00
|
|
|
c_int_width: "32".to_string(),
|
|
|
|
os: "none".to_string(),
|
|
|
|
env: String::new(),
|
|
|
|
vendor: "unknown".to_string(),
|
2020-10-08 22:22:28 +03:00
|
|
|
linker_flavor: LinkerFlavor::Gcc,
|
2018-02-10 12:09:25 -08:00
|
|
|
linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.to_string()),
|
2018-08-18 16:31:36 +02:00
|
|
|
lld_flavor: LldFlavor::Ld,
|
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
2017-02-21 14:47:15 -05:00
|
|
|
pre_link_args: LinkArgs::new(),
|
|
|
|
post_link_args: LinkArgs::new(),
|
2020-05-10 17:39:57 -04:00
|
|
|
link_script: None,
|
2016-12-18 22:25:46 -05:00
|
|
|
asm_args: Vec::new(),
|
2014-07-23 11:56:36 -07:00
|
|
|
cpu: "generic".to_string(),
|
2018-08-23 10:14:52 +02:00
|
|
|
features: String::new(),
|
2014-07-23 11:56:36 -07:00
|
|
|
dynamic_linking: false,
|
2017-10-22 20:01:00 -07:00
|
|
|
only_cdylib: false,
|
2014-07-23 11:56:36 -07:00
|
|
|
executables: false,
|
2020-04-23 00:46:45 +03:00
|
|
|
relocation_model: RelocModel::Pic,
|
2018-01-22 17:01:36 -08:00
|
|
|
code_model: None,
|
2020-04-25 21:45:21 +03:00
|
|
|
tls_model: TlsModel::GeneralDynamic,
|
2014-07-23 11:56:36 -07:00
|
|
|
disable_redzone: false,
|
|
|
|
eliminate_frame_pointer: true,
|
|
|
|
function_sections: true,
|
|
|
|
dll_prefix: "lib".to_string(),
|
|
|
|
dll_suffix: ".so".to_string(),
|
2018-08-23 10:14:52 +02:00
|
|
|
exe_suffix: String::new(),
|
2014-07-23 11:56:36 -07:00
|
|
|
staticlib_prefix: "lib".to_string(),
|
|
|
|
staticlib_suffix: ".a".to_string(),
|
2020-11-08 14:57:55 +03:00
|
|
|
os_family: None,
|
2018-02-26 10:20:14 -08:00
|
|
|
abi_return_struct_as_int: false,
|
2014-07-23 11:56:36 -07:00
|
|
|
is_like_osx: false,
|
2016-01-28 14:02:31 +03:00
|
|
|
is_like_solaris: false,
|
2014-07-23 11:56:36 -07:00
|
|
|
is_like_windows: false,
|
2017-01-19 22:31:57 +03:00
|
|
|
is_like_emscripten: false,
|
2015-03-04 22:58:59 +00:00
|
|
|
is_like_msvc: false,
|
2018-11-22 00:59:37 -08:00
|
|
|
is_like_fuchsia: false,
|
2020-10-09 15:08:18 -04:00
|
|
|
dwarf_version: None,
|
2014-07-23 11:56:36 -07:00
|
|
|
linker_is_gnu: false,
|
2016-07-13 17:03:02 -04:00
|
|
|
allows_weak_linkage: true,
|
2014-07-23 11:56:36 -07:00
|
|
|
has_rpath: false,
|
2015-09-21 19:02:46 +02:00
|
|
|
no_default_libraries: true,
|
2014-11-06 00:17:56 -05:00
|
|
|
position_independent_executables: false,
|
2020-05-02 01:59:35 +03:00
|
|
|
static_position_independent_executables: false,
|
2018-09-26 19:19:55 +03:00
|
|
|
needs_plt: false,
|
2018-03-09 14:53:15 +01:00
|
|
|
relro_level: RelroLevel::None,
|
2020-04-29 20:47:07 +03:00
|
|
|
pre_link_objects: Default::default(),
|
|
|
|
post_link_objects: Default::default(),
|
|
|
|
pre_link_objects_fallback: Default::default(),
|
|
|
|
post_link_objects_fallback: Default::default(),
|
|
|
|
crt_objects_fallback: None,
|
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
2017-02-21 14:47:15 -05:00
|
|
|
late_link_args: LinkArgs::new(),
|
2020-03-03 20:41:37 +00:00
|
|
|
late_link_args_dynamic: LinkArgs::new(),
|
|
|
|
late_link_args_static: LinkArgs::new(),
|
2017-06-22 15:16:54 -07:00
|
|
|
link_env: Vec::new(),
|
2019-09-12 13:47:17 +03:00
|
|
|
link_env_remove: Vec::new(),
|
2016-02-08 10:27:03 -08:00
|
|
|
archive_format: "gnu".to_string(),
|
2019-10-17 16:09:32 -07:00
|
|
|
main_needs_argc_argv: true,
|
2015-08-20 17:47:21 -05:00
|
|
|
allow_asm: true,
|
2015-12-10 12:21:55 -08:00
|
|
|
has_elf_tls: false,
|
2015-11-27 19:44:33 +00:00
|
|
|
obj_is_bitcode: false,
|
2020-05-07 12:26:18 +10:00
|
|
|
forces_embed_bitcode: false,
|
2020-05-07 15:34:31 +10:00
|
|
|
bitcode_llvm_cmdline: String::new(),
|
2016-08-15 09:46:44 +00:00
|
|
|
min_atomic_width: None,
|
2016-10-03 23:45:40 -05:00
|
|
|
max_atomic_width: None,
|
2018-06-30 14:56:08 -05:00
|
|
|
atomic_cas: true,
|
2016-09-27 21:26:08 -05:00
|
|
|
panic_strategy: PanicStrategy::Unwind,
|
2020-07-08 09:36:52 -04:00
|
|
|
unsupported_abis: vec![],
|
2017-08-22 16:24:29 -05:00
|
|
|
crt_static_allows_dylibs: false,
|
rustc: Implement #[link(cfg(..))] and crt-static
This commit is an implementation of [RFC 1721] which adds a new target feature
to the compiler, `crt-static`, which can be used to select how the C runtime for
a target is linked. Most targets dynamically linke the C runtime by default with
the notable exception of some of the musl targets.
[RFC 1721]: https://github.com/rust-lang/rfcs/blob/master/text/1721-crt-static.md
This commit first adds the new target-feature, `crt-static`. If enabled, then
the `cfg(target_feature = "crt-static")` will be available. Targets like musl
will have this enabled by default. This feature can be controlled through the
standard target-feature interface, `-C target-feature=+crt-static` or
`-C target-feature=-crt-static`.
Next this adds an gated and unstable `#[link(cfg(..))]` feature to enable the
`crt-static` semantics we want with libc. The exact behavior of this attribute
is a little squishy, but it's intended to be a forever-unstable
implementation detail of the liblibc crate.
Specifically the `#[link(cfg(..))]` annotation means that the `#[link]`
directive is only active in a compilation unit if that `cfg` value is satisfied.
For example when compiling an rlib, these directives are just encoded and
ignored for dylibs, and all staticlibs are continued to be put into the rlib as
usual. When placing that rlib into a staticlib, executable, or dylib, however,
the `cfg` is evaluated *as if it were defined in the final artifact* and the
library is decided to be linked or not.
Essentially, what'll happen is:
* On MSVC with `-C target-feature=-crt-static`, the `msvcrt.lib` library will be
linked to.
* On MSVC with `-C target-feature=+crt-static`, the `libcmt.lib` library will be
linked to.
* On musl with `-C target-feature=-crt-static`, the object files in liblibc.rlib
are removed and `-lc` is passed instead.
* On musl with `-C target-feature=+crt-static`, the object files in liblibc.rlib
are used and `-lc` is not passed.
This commit does **not** include an update to the liblibc module to implement
these changes. I plan to do that just after the 1.14.0 beta release is cut to
ensure we get ample time to test this feature.
cc #37406
2016-10-31 16:40:13 -07:00
|
|
|
crt_static_default: false,
|
2017-08-22 16:24:29 -05:00
|
|
|
crt_static_respected: false,
|
2021-01-09 16:54:20 +02:00
|
|
|
stack_probes: StackProbeType::None,
|
2017-09-08 14:49:51 -07:00
|
|
|
min_global_align: None,
|
2017-10-04 14:38:52 -07:00
|
|
|
default_codegen_units: None,
|
2017-11-11 07:08:00 -08:00
|
|
|
trap_unreachable: true,
|
2017-10-22 20:01:00 -07:00
|
|
|
requires_lto: false,
|
|
|
|
singlethread: false,
|
|
|
|
no_builtins: false,
|
2018-01-30 11:54:07 -08:00
|
|
|
default_hidden_visibility: false,
|
2018-04-06 15:40:43 +02:00
|
|
|
emit_debug_gdb_scripts: true,
|
2018-04-19 15:17:34 -07:00
|
|
|
requires_uwtable: false,
|
2021-03-23 02:38:30 +08:00
|
|
|
default_uwtable: false,
|
2018-10-12 17:04:31 -07:00
|
|
|
simd_types_indirect: true,
|
2019-04-14 19:05:21 +02:00
|
|
|
limit_rdylib_exports: true,
|
2018-11-19 15:04:28 +05:30
|
|
|
override_export_symbols: None,
|
2018-12-31 10:58:13 -08:00
|
|
|
merge_functions: MergeFunctions::Aliases,
|
2020-11-08 14:57:55 +03:00
|
|
|
mcount: "mcount".to_string(),
|
2019-10-29 21:12:05 -07:00
|
|
|
llvm_abiname: "".to_string(),
|
2019-12-02 17:52:45 +05:30
|
|
|
relax_elf_relocations: false,
|
2020-01-09 16:40:40 +01:00
|
|
|
llvm_args: vec![],
|
2020-04-16 19:40:11 -07:00
|
|
|
use_ctors_section: false,
|
2020-07-22 15:49:04 +03:00
|
|
|
eh_frame_header: true,
|
2020-10-08 23:23:27 +01:00
|
|
|
has_thumb_interworking: false,
|
2020-11-30 08:39:08 -08:00
|
|
|
split_debuginfo: SplitDebuginfo::Off,
|
2021-02-08 00:49:00 +02:00
|
|
|
supported_sanitizers: SanitizerSet::empty(),
|
2014-07-23 11:56:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-08 19:36:11 +03:00
|
|
|
/// `TargetOptions` being a separate type is basically an implementation detail of `Target` that is
|
|
|
|
/// used for providing defaults. Perhaps there's a way to merge `TargetOptions` into `Target` so
|
|
|
|
/// this `Deref` implementation is no longer necessary.
|
|
|
|
impl Deref for Target {
|
|
|
|
type Target = TargetOptions;
|
|
|
|
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
&self.options
|
|
|
|
}
|
|
|
|
}
|
2020-11-08 14:27:51 +03:00
|
|
|
impl DerefMut for Target {
|
|
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
|
|
&mut self.options
|
|
|
|
}
|
|
|
|
}
|
2020-10-08 19:36:11 +03:00
|
|
|
|
2014-07-23 11:56:36 -07:00
|
|
|
impl Target {
|
2018-09-25 16:37:31 -04:00
|
|
|
/// Given a function ABI, turn it into the correct ABI for this target.
|
2016-02-05 13:13:36 +01:00
|
|
|
pub fn adjust_abi(&self, abi: Abi) -> Abi {
|
2014-07-23 11:56:36 -07:00
|
|
|
match abi {
|
rustc_target: add "unwind" payloads to `Abi`
### Overview
This commit begins the implementation work for RFC 2945. For more
information, see the rendered RFC [1] and tracking issue [2].
A boolean `unwind` payload is added to the `C`, `System`, `Stdcall`,
and `Thiscall` variants, marking whether unwinding across FFI
boundaries is acceptable. The cases where each of these variants'
`unwind` member is true correspond with the `C-unwind`,
`system-unwind`, `stdcall-unwind`, and `thiscall-unwind` ABI strings
introduced in RFC 2945 [3].
### Feature Gate and Unstable Book
This commit adds a `c_unwind` feature gate for the new ABI strings.
Tests for this feature gate are included in `src/test/ui/c-unwind/`,
which ensure that this feature gate works correctly for each of the
new ABIs.
A new language features entry in the unstable book is added as well.
### Further Work To Be Done
This commit does not proceed to implement the new unwinding ABIs,
and is intentionally scoped specifically to *defining* the ABIs and
their feature flag.
### One Note on Test Churn
This will lead to some test churn, in re-blessing hash tests, as the
deleted comment in `src/librustc_target/spec/abi.rs` mentioned,
because we can no longer guarantee the ordering of the `Abi`
variants.
While this is a downside, this decision was made bearing in mind
that RFC 2945 states the following, in the "Other `unwind` Strings"
section [3]:
> More unwind variants of existing ABI strings may be introduced,
> with the same semantics, without an additional RFC.
Adding a new variant for each of these cases, rather than specifying
a payload for a given ABI, would quickly become untenable, and make
working with the `Abi` enum prone to mistakes.
This approach encodes the unwinding information *into* a given ABI,
to account for the future possibility of other `-unwind` ABI
strings.
### Ignore Directives
`ignore-*` directives are used in two of our `*-unwind` ABI test
cases.
Specifically, the `stdcall-unwind` and `thiscall-unwind` test cases
ignore architectures that do not support `stdcall` and
`thiscall`, respectively.
These directives are cribbed from
`src/test/ui/c-variadic/variadic-ffi-1.rs` for `stdcall`, and
`src/test/ui/extern/extern-thiscall.rs` for `thiscall`.
This would otherwise fail on some targets, see:
https://github.com/rust-lang-ci/rust/commit/fcf697f90206e9c87b39d494f94ab35d976bfc60
### Footnotes
[1]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md
[2]: https://github.com/rust-lang/rust/issues/74990
[3]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md#other-unwind-abi-strings
2020-08-27 11:49:18 -04:00
|
|
|
Abi::System { unwind } => {
|
2020-11-08 14:27:51 +03:00
|
|
|
if self.is_like_windows && self.arch == "x86" {
|
rustc_target: add "unwind" payloads to `Abi`
### Overview
This commit begins the implementation work for RFC 2945. For more
information, see the rendered RFC [1] and tracking issue [2].
A boolean `unwind` payload is added to the `C`, `System`, `Stdcall`,
and `Thiscall` variants, marking whether unwinding across FFI
boundaries is acceptable. The cases where each of these variants'
`unwind` member is true correspond with the `C-unwind`,
`system-unwind`, `stdcall-unwind`, and `thiscall-unwind` ABI strings
introduced in RFC 2945 [3].
### Feature Gate and Unstable Book
This commit adds a `c_unwind` feature gate for the new ABI strings.
Tests for this feature gate are included in `src/test/ui/c-unwind/`,
which ensure that this feature gate works correctly for each of the
new ABIs.
A new language features entry in the unstable book is added as well.
### Further Work To Be Done
This commit does not proceed to implement the new unwinding ABIs,
and is intentionally scoped specifically to *defining* the ABIs and
their feature flag.
### One Note on Test Churn
This will lead to some test churn, in re-blessing hash tests, as the
deleted comment in `src/librustc_target/spec/abi.rs` mentioned,
because we can no longer guarantee the ordering of the `Abi`
variants.
While this is a downside, this decision was made bearing in mind
that RFC 2945 states the following, in the "Other `unwind` Strings"
section [3]:
> More unwind variants of existing ABI strings may be introduced,
> with the same semantics, without an additional RFC.
Adding a new variant for each of these cases, rather than specifying
a payload for a given ABI, would quickly become untenable, and make
working with the `Abi` enum prone to mistakes.
This approach encodes the unwinding information *into* a given ABI,
to account for the future possibility of other `-unwind` ABI
strings.
### Ignore Directives
`ignore-*` directives are used in two of our `*-unwind` ABI test
cases.
Specifically, the `stdcall-unwind` and `thiscall-unwind` test cases
ignore architectures that do not support `stdcall` and
`thiscall`, respectively.
These directives are cribbed from
`src/test/ui/c-variadic/variadic-ffi-1.rs` for `stdcall`, and
`src/test/ui/extern/extern-thiscall.rs` for `thiscall`.
This would otherwise fail on some targets, see:
https://github.com/rust-lang-ci/rust/commit/fcf697f90206e9c87b39d494f94ab35d976bfc60
### Footnotes
[1]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md
[2]: https://github.com/rust-lang/rust/issues/74990
[3]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md#other-unwind-abi-strings
2020-08-27 11:49:18 -04:00
|
|
|
Abi::Stdcall { unwind }
|
2014-07-23 11:56:36 -07:00
|
|
|
} else {
|
rustc_target: add "unwind" payloads to `Abi`
### Overview
This commit begins the implementation work for RFC 2945. For more
information, see the rendered RFC [1] and tracking issue [2].
A boolean `unwind` payload is added to the `C`, `System`, `Stdcall`,
and `Thiscall` variants, marking whether unwinding across FFI
boundaries is acceptable. The cases where each of these variants'
`unwind` member is true correspond with the `C-unwind`,
`system-unwind`, `stdcall-unwind`, and `thiscall-unwind` ABI strings
introduced in RFC 2945 [3].
### Feature Gate and Unstable Book
This commit adds a `c_unwind` feature gate for the new ABI strings.
Tests for this feature gate are included in `src/test/ui/c-unwind/`,
which ensure that this feature gate works correctly for each of the
new ABIs.
A new language features entry in the unstable book is added as well.
### Further Work To Be Done
This commit does not proceed to implement the new unwinding ABIs,
and is intentionally scoped specifically to *defining* the ABIs and
their feature flag.
### One Note on Test Churn
This will lead to some test churn, in re-blessing hash tests, as the
deleted comment in `src/librustc_target/spec/abi.rs` mentioned,
because we can no longer guarantee the ordering of the `Abi`
variants.
While this is a downside, this decision was made bearing in mind
that RFC 2945 states the following, in the "Other `unwind` Strings"
section [3]:
> More unwind variants of existing ABI strings may be introduced,
> with the same semantics, without an additional RFC.
Adding a new variant for each of these cases, rather than specifying
a payload for a given ABI, would quickly become untenable, and make
working with the `Abi` enum prone to mistakes.
This approach encodes the unwinding information *into* a given ABI,
to account for the future possibility of other `-unwind` ABI
strings.
### Ignore Directives
`ignore-*` directives are used in two of our `*-unwind` ABI test
cases.
Specifically, the `stdcall-unwind` and `thiscall-unwind` test cases
ignore architectures that do not support `stdcall` and
`thiscall`, respectively.
These directives are cribbed from
`src/test/ui/c-variadic/variadic-ffi-1.rs` for `stdcall`, and
`src/test/ui/extern/extern-thiscall.rs` for `thiscall`.
This would otherwise fail on some targets, see:
https://github.com/rust-lang-ci/rust/commit/fcf697f90206e9c87b39d494f94ab35d976bfc60
### Footnotes
[1]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md
[2]: https://github.com/rust-lang/rust/issues/74990
[3]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md#other-unwind-abi-strings
2020-08-27 11:49:18 -04:00
|
|
|
Abi::C { unwind }
|
2014-07-23 11:56:36 -07:00
|
|
|
}
|
2019-12-22 17:42:04 -05:00
|
|
|
}
|
2018-09-25 16:37:31 -04:00
|
|
|
// These ABI kinds are ignored on non-x86 Windows targets.
|
|
|
|
// See https://docs.microsoft.com/en-us/cpp/cpp/argument-passing-and-naming-conventions
|
|
|
|
// and the individual pages for __stdcall et al.
|
rustc_target: add "unwind" payloads to `Abi`
### Overview
This commit begins the implementation work for RFC 2945. For more
information, see the rendered RFC [1] and tracking issue [2].
A boolean `unwind` payload is added to the `C`, `System`, `Stdcall`,
and `Thiscall` variants, marking whether unwinding across FFI
boundaries is acceptable. The cases where each of these variants'
`unwind` member is true correspond with the `C-unwind`,
`system-unwind`, `stdcall-unwind`, and `thiscall-unwind` ABI strings
introduced in RFC 2945 [3].
### Feature Gate and Unstable Book
This commit adds a `c_unwind` feature gate for the new ABI strings.
Tests for this feature gate are included in `src/test/ui/c-unwind/`,
which ensure that this feature gate works correctly for each of the
new ABIs.
A new language features entry in the unstable book is added as well.
### Further Work To Be Done
This commit does not proceed to implement the new unwinding ABIs,
and is intentionally scoped specifically to *defining* the ABIs and
their feature flag.
### One Note on Test Churn
This will lead to some test churn, in re-blessing hash tests, as the
deleted comment in `src/librustc_target/spec/abi.rs` mentioned,
because we can no longer guarantee the ordering of the `Abi`
variants.
While this is a downside, this decision was made bearing in mind
that RFC 2945 states the following, in the "Other `unwind` Strings"
section [3]:
> More unwind variants of existing ABI strings may be introduced,
> with the same semantics, without an additional RFC.
Adding a new variant for each of these cases, rather than specifying
a payload for a given ABI, would quickly become untenable, and make
working with the `Abi` enum prone to mistakes.
This approach encodes the unwinding information *into* a given ABI,
to account for the future possibility of other `-unwind` ABI
strings.
### Ignore Directives
`ignore-*` directives are used in two of our `*-unwind` ABI test
cases.
Specifically, the `stdcall-unwind` and `thiscall-unwind` test cases
ignore architectures that do not support `stdcall` and
`thiscall`, respectively.
These directives are cribbed from
`src/test/ui/c-variadic/variadic-ffi-1.rs` for `stdcall`, and
`src/test/ui/extern/extern-thiscall.rs` for `thiscall`.
This would otherwise fail on some targets, see:
https://github.com/rust-lang-ci/rust/commit/fcf697f90206e9c87b39d494f94ab35d976bfc60
### Footnotes
[1]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md
[2]: https://github.com/rust-lang/rust/issues/74990
[3]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md#other-unwind-abi-strings
2020-08-27 11:49:18 -04:00
|
|
|
Abi::Stdcall { unwind } | Abi::Thiscall { unwind } => {
|
|
|
|
if self.is_like_windows && self.arch != "x86" { Abi::C { unwind } } else { abi }
|
|
|
|
}
|
|
|
|
Abi::Fastcall | Abi::Vectorcall => {
|
|
|
|
if self.is_like_windows && self.arch != "x86" {
|
|
|
|
Abi::C { unwind: false }
|
|
|
|
} else {
|
|
|
|
abi
|
|
|
|
}
|
2019-12-22 17:42:04 -05:00
|
|
|
}
|
2019-10-24 15:29:29 +00:00
|
|
|
Abi::EfiApi => {
|
2019-10-25 14:50:51 +00:00
|
|
|
if self.arch == "x86_64" {
|
2019-10-24 15:29:29 +00:00
|
|
|
Abi::Win64
|
|
|
|
} else {
|
rustc_target: add "unwind" payloads to `Abi`
### Overview
This commit begins the implementation work for RFC 2945. For more
information, see the rendered RFC [1] and tracking issue [2].
A boolean `unwind` payload is added to the `C`, `System`, `Stdcall`,
and `Thiscall` variants, marking whether unwinding across FFI
boundaries is acceptable. The cases where each of these variants'
`unwind` member is true correspond with the `C-unwind`,
`system-unwind`, `stdcall-unwind`, and `thiscall-unwind` ABI strings
introduced in RFC 2945 [3].
### Feature Gate and Unstable Book
This commit adds a `c_unwind` feature gate for the new ABI strings.
Tests for this feature gate are included in `src/test/ui/c-unwind/`,
which ensure that this feature gate works correctly for each of the
new ABIs.
A new language features entry in the unstable book is added as well.
### Further Work To Be Done
This commit does not proceed to implement the new unwinding ABIs,
and is intentionally scoped specifically to *defining* the ABIs and
their feature flag.
### One Note on Test Churn
This will lead to some test churn, in re-blessing hash tests, as the
deleted comment in `src/librustc_target/spec/abi.rs` mentioned,
because we can no longer guarantee the ordering of the `Abi`
variants.
While this is a downside, this decision was made bearing in mind
that RFC 2945 states the following, in the "Other `unwind` Strings"
section [3]:
> More unwind variants of existing ABI strings may be introduced,
> with the same semantics, without an additional RFC.
Adding a new variant for each of these cases, rather than specifying
a payload for a given ABI, would quickly become untenable, and make
working with the `Abi` enum prone to mistakes.
This approach encodes the unwinding information *into* a given ABI,
to account for the future possibility of other `-unwind` ABI
strings.
### Ignore Directives
`ignore-*` directives are used in two of our `*-unwind` ABI test
cases.
Specifically, the `stdcall-unwind` and `thiscall-unwind` test cases
ignore architectures that do not support `stdcall` and
`thiscall`, respectively.
These directives are cribbed from
`src/test/ui/c-variadic/variadic-ffi-1.rs` for `stdcall`, and
`src/test/ui/extern/extern-thiscall.rs` for `thiscall`.
This would otherwise fail on some targets, see:
https://github.com/rust-lang-ci/rust/commit/fcf697f90206e9c87b39d494f94ab35d976bfc60
### Footnotes
[1]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md
[2]: https://github.com/rust-lang/rust/issues/74990
[3]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md#other-unwind-abi-strings
2020-08-27 11:49:18 -04:00
|
|
|
Abi::C { unwind: false }
|
2019-10-24 15:29:29 +00:00
|
|
|
}
|
2019-12-22 17:42:04 -05:00
|
|
|
}
|
|
|
|
abi => abi,
|
2014-07-23 11:56:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-15 09:46:44 +00:00
|
|
|
/// Minimum integer size in bits that this target can perform atomic
|
|
|
|
/// operations on.
|
|
|
|
pub fn min_atomic_width(&self) -> u64 {
|
2020-11-08 14:27:51 +03:00
|
|
|
self.min_atomic_width.unwrap_or(8)
|
2016-08-15 09:46:44 +00:00
|
|
|
}
|
|
|
|
|
2016-10-03 23:45:40 -05:00
|
|
|
/// Maximum integer size in bits that this target can perform atomic
|
|
|
|
/// operations on.
|
|
|
|
pub fn max_atomic_width(&self) -> u64 {
|
2020-11-08 14:27:51 +03:00
|
|
|
self.max_atomic_width.unwrap_or_else(|| self.pointer_width.into())
|
2016-10-03 23:45:40 -05:00
|
|
|
}
|
|
|
|
|
2016-10-24 11:04:04 +02:00
|
|
|
pub fn is_abi_supported(&self, abi: Abi) -> bool {
|
2020-11-08 14:27:51 +03:00
|
|
|
abi.generic() || !self.unsupported_abis.contains(&abi)
|
2016-10-24 11:04:04 +02:00
|
|
|
}
|
|
|
|
|
2019-02-08 14:53:55 +01:00
|
|
|
/// Loads a target descriptor from a JSON object.
|
2020-10-05 15:37:55 +03:00
|
|
|
pub fn from_json(obj: Json) -> Result<Target, String> {
|
2016-04-07 22:29:01 -05:00
|
|
|
// While ugly, this code must remain this way to retain
|
|
|
|
// compatibility with existing JSON fields and the internal
|
|
|
|
// expected naming of the Target and TargetOptions structs.
|
|
|
|
// To ensure compatibility is retained, the built-in targets
|
|
|
|
// are round-tripped through this code to catch cases where
|
|
|
|
// the JSON parser is not updated to match the structs.
|
2014-07-23 11:56:36 -07:00
|
|
|
|
2015-02-01 12:44:15 -05:00
|
|
|
let get_req_field = |name: &str| {
|
2018-08-10 13:13:50 +02:00
|
|
|
obj.find(name)
|
2019-12-22 17:42:04 -05:00
|
|
|
.map(|s| s.as_string())
|
|
|
|
.and_then(|os| os.map(|s| s.to_string()))
|
|
|
|
.ok_or_else(|| format!("Field {} in target specification is required", name))
|
2014-07-23 11:56:36 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
let mut base = Target {
|
2016-08-27 07:48:39 -07:00
|
|
|
llvm_target: get_req_field("llvm-target")?,
|
2020-10-14 18:22:10 +02:00
|
|
|
pointer_width: get_req_field("target-pointer-width")?
|
|
|
|
.parse::<u32>()
|
|
|
|
.map_err(|_| "target-pointer-width must be an integer".to_string())?,
|
2016-08-27 07:48:39 -07:00
|
|
|
data_layout: get_req_field("data-layout")?,
|
|
|
|
arch: get_req_field("arch")?,
|
2014-07-23 11:56:36 -07:00
|
|
|
options: Default::default(),
|
|
|
|
};
|
|
|
|
|
2015-01-02 14:44:21 -08:00
|
|
|
macro_rules! key {
|
2014-07-23 11:56:36 -07:00
|
|
|
($key_name:ident) => ( {
|
|
|
|
let name = (stringify!($key_name)).replace("_", "-");
|
2020-04-24 13:58:41 -07:00
|
|
|
if let Some(s) = obj.find(&name).and_then(Json::as_string) {
|
2020-11-08 14:27:51 +03:00
|
|
|
base.$key_name = s.to_string();
|
2020-04-24 13:58:41 -07:00
|
|
|
}
|
2014-07-23 11:56:36 -07:00
|
|
|
} );
|
2020-10-08 20:54:45 +03:00
|
|
|
($key_name:ident = $json_name:expr) => ( {
|
|
|
|
let name = $json_name;
|
|
|
|
if let Some(s) = obj.find(&name).and_then(Json::as_string) {
|
2020-11-08 14:27:51 +03:00
|
|
|
base.$key_name = s.to_string();
|
2020-10-08 20:54:45 +03:00
|
|
|
}
|
|
|
|
} );
|
2014-07-23 11:56:36 -07:00
|
|
|
($key_name:ident, bool) => ( {
|
|
|
|
let name = (stringify!($key_name)).replace("_", "-");
|
2020-04-24 13:58:41 -07:00
|
|
|
if let Some(s) = obj.find(&name).and_then(Json::as_boolean) {
|
2020-11-08 14:27:51 +03:00
|
|
|
base.$key_name = s;
|
2020-04-24 13:58:41 -07:00
|
|
|
}
|
2014-07-23 11:56:36 -07:00
|
|
|
} );
|
2020-10-09 15:08:18 -04:00
|
|
|
($key_name:ident, Option<u32>) => ( {
|
|
|
|
let name = (stringify!($key_name)).replace("_", "-");
|
|
|
|
if let Some(s) = obj.find(&name).and_then(Json::as_u64) {
|
|
|
|
if s < 1 || s > 5 {
|
|
|
|
return Err("Not a valid DWARF version number".to_string());
|
|
|
|
}
|
2020-11-08 14:27:51 +03:00
|
|
|
base.$key_name = Some(s as u32);
|
2020-10-09 15:08:18 -04:00
|
|
|
}
|
|
|
|
} );
|
2016-10-03 23:45:40 -05:00
|
|
|
($key_name:ident, Option<u64>) => ( {
|
2016-04-15 20:16:19 +01:00
|
|
|
let name = (stringify!($key_name)).replace("_", "-");
|
2020-04-24 13:58:41 -07:00
|
|
|
if let Some(s) = obj.find(&name).and_then(Json::as_u64) {
|
2020-11-08 14:27:51 +03:00
|
|
|
base.$key_name = Some(s);
|
2020-04-24 13:58:41 -07:00
|
|
|
}
|
2016-04-15 20:16:19 +01:00
|
|
|
} );
|
2018-12-31 10:58:13 -08:00
|
|
|
($key_name:ident, MergeFunctions) => ( {
|
|
|
|
let name = (stringify!($key_name)).replace("_", "-");
|
|
|
|
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
|
|
|
|
match s.parse::<MergeFunctions>() {
|
2020-11-08 14:27:51 +03:00
|
|
|
Ok(mergefunc) => base.$key_name = mergefunc,
|
2018-12-31 10:58:13 -08:00
|
|
|
_ => return Some(Err(format!("'{}' is not a valid value for \
|
|
|
|
merge-functions. Use 'disabled', \
|
|
|
|
'trampolines', or 'aliases'.",
|
|
|
|
s))),
|
|
|
|
}
|
|
|
|
Some(Ok(()))
|
|
|
|
})).unwrap_or(Ok(()))
|
|
|
|
} );
|
2020-04-23 00:46:45 +03:00
|
|
|
($key_name:ident, RelocModel) => ( {
|
|
|
|
let name = (stringify!($key_name)).replace("_", "-");
|
|
|
|
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
|
|
|
|
match s.parse::<RelocModel>() {
|
2020-11-08 14:27:51 +03:00
|
|
|
Ok(relocation_model) => base.$key_name = relocation_model,
|
2020-04-23 00:46:45 +03:00
|
|
|
_ => return Some(Err(format!("'{}' is not a valid relocation model. \
|
|
|
|
Run `rustc --print relocation-models` to \
|
|
|
|
see the list of supported values.", s))),
|
|
|
|
}
|
|
|
|
Some(Ok(()))
|
|
|
|
})).unwrap_or(Ok(()))
|
|
|
|
} );
|
2020-05-07 03:34:27 +03:00
|
|
|
($key_name:ident, CodeModel) => ( {
|
|
|
|
let name = (stringify!($key_name)).replace("_", "-");
|
|
|
|
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
|
|
|
|
match s.parse::<CodeModel>() {
|
2020-11-08 14:27:51 +03:00
|
|
|
Ok(code_model) => base.$key_name = Some(code_model),
|
2020-05-07 03:34:27 +03:00
|
|
|
_ => return Some(Err(format!("'{}' is not a valid code model. \
|
|
|
|
Run `rustc --print code-models` to \
|
|
|
|
see the list of supported values.", s))),
|
|
|
|
}
|
|
|
|
Some(Ok(()))
|
|
|
|
})).unwrap_or(Ok(()))
|
|
|
|
} );
|
2020-04-25 21:45:21 +03:00
|
|
|
($key_name:ident, TlsModel) => ( {
|
|
|
|
let name = (stringify!($key_name)).replace("_", "-");
|
|
|
|
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
|
|
|
|
match s.parse::<TlsModel>() {
|
2020-11-08 14:27:51 +03:00
|
|
|
Ok(tls_model) => base.$key_name = tls_model,
|
2020-04-25 21:45:21 +03:00
|
|
|
_ => return Some(Err(format!("'{}' is not a valid TLS model. \
|
|
|
|
Run `rustc --print tls-models` to \
|
|
|
|
see the list of supported values.", s))),
|
|
|
|
}
|
|
|
|
Some(Ok(()))
|
|
|
|
})).unwrap_or(Ok(()))
|
|
|
|
} );
|
2016-09-27 21:26:08 -05:00
|
|
|
($key_name:ident, PanicStrategy) => ( {
|
|
|
|
let name = (stringify!($key_name)).replace("_", "-");
|
|
|
|
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
|
|
|
|
match s {
|
2020-11-08 14:27:51 +03:00
|
|
|
"unwind" => base.$key_name = PanicStrategy::Unwind,
|
|
|
|
"abort" => base.$key_name = PanicStrategy::Abort,
|
2016-09-27 21:26:08 -05:00
|
|
|
_ => return Some(Err(format!("'{}' is not a valid value for \
|
|
|
|
panic-strategy. Use 'unwind' or 'abort'.",
|
|
|
|
s))),
|
|
|
|
}
|
|
|
|
Some(Ok(()))
|
|
|
|
})).unwrap_or(Ok(()))
|
|
|
|
} );
|
2017-07-14 22:01:37 +02:00
|
|
|
($key_name:ident, RelroLevel) => ( {
|
|
|
|
let name = (stringify!($key_name)).replace("_", "-");
|
|
|
|
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
|
2017-07-18 01:27:55 +02:00
|
|
|
match s.parse::<RelroLevel>() {
|
2020-11-08 14:27:51 +03:00
|
|
|
Ok(level) => base.$key_name = level,
|
2017-07-14 22:01:37 +02:00
|
|
|
_ => return Some(Err(format!("'{}' is not a valid value for \
|
|
|
|
relro-level. Use 'full', 'partial, or 'off'.",
|
|
|
|
s))),
|
|
|
|
}
|
|
|
|
Some(Ok(()))
|
|
|
|
})).unwrap_or(Ok(()))
|
|
|
|
} );
|
2020-11-30 08:39:08 -08:00
|
|
|
($key_name:ident, SplitDebuginfo) => ( {
|
|
|
|
let name = (stringify!($key_name)).replace("_", "-");
|
|
|
|
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
|
|
|
|
match s.parse::<SplitDebuginfo>() {
|
|
|
|
Ok(level) => base.$key_name = level,
|
|
|
|
_ => return Some(Err(format!("'{}' is not a valid value for \
|
|
|
|
split-debuginfo. Use 'off' or 'dsymutil'.",
|
|
|
|
s))),
|
|
|
|
}
|
|
|
|
Some(Ok(()))
|
|
|
|
})).unwrap_or(Ok(()))
|
|
|
|
} );
|
2014-07-23 11:56:36 -07:00
|
|
|
($key_name:ident, list) => ( {
|
|
|
|
let name = (stringify!($key_name)).replace("_", "-");
|
2020-04-24 13:58:41 -07:00
|
|
|
if let Some(v) = obj.find(&name).and_then(Json::as_array) {
|
2020-11-08 14:27:51 +03:00
|
|
|
base.$key_name = v.iter()
|
2020-04-24 13:58:41 -07:00
|
|
|
.map(|a| a.as_string().unwrap().to_string())
|
|
|
|
.collect();
|
|
|
|
}
|
2014-07-23 11:56:36 -07:00
|
|
|
} );
|
2018-11-19 15:04:28 +05:30
|
|
|
($key_name:ident, opt_list) => ( {
|
|
|
|
let name = (stringify!($key_name)).replace("_", "-");
|
2020-04-24 13:58:41 -07:00
|
|
|
if let Some(v) = obj.find(&name).and_then(Json::as_array) {
|
2020-11-08 14:27:51 +03:00
|
|
|
base.$key_name = Some(v.iter()
|
2020-04-24 13:58:41 -07:00
|
|
|
.map(|a| a.as_string().unwrap().to_string())
|
|
|
|
.collect());
|
|
|
|
}
|
2018-11-19 15:04:28 +05:30
|
|
|
} );
|
2015-09-07 00:35:57 -05:00
|
|
|
($key_name:ident, optional) => ( {
|
|
|
|
let name = (stringify!($key_name)).replace("_", "-");
|
|
|
|
if let Some(o) = obj.find(&name[..]) {
|
2020-11-08 14:27:51 +03:00
|
|
|
base.$key_name = o
|
2015-09-07 00:35:57 -05:00
|
|
|
.as_string()
|
|
|
|
.map(|s| s.to_string() );
|
|
|
|
}
|
|
|
|
} );
|
2020-11-08 14:57:55 +03:00
|
|
|
($key_name:ident = $json_name:expr, optional) => ( {
|
|
|
|
let name = $json_name;
|
2021-02-16 00:30:06 +01:00
|
|
|
if let Some(o) = obj.find(name) {
|
2020-11-08 14:57:55 +03:00
|
|
|
base.$key_name = o
|
2015-09-07 00:35:57 -05:00
|
|
|
.as_string()
|
|
|
|
.map(|s| s.to_string() );
|
|
|
|
}
|
|
|
|
} );
|
2018-08-18 20:16:04 +02:00
|
|
|
($key_name:ident, LldFlavor) => ( {
|
|
|
|
let name = (stringify!($key_name)).replace("_", "-");
|
|
|
|
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
|
|
|
|
if let Some(flavor) = LldFlavor::from_str(&s) {
|
2020-11-08 14:27:51 +03:00
|
|
|
base.$key_name = flavor;
|
2018-08-18 20:16:04 +02:00
|
|
|
} else {
|
|
|
|
return Some(Err(format!(
|
|
|
|
"'{}' is not a valid value for lld-flavor. \
|
|
|
|
Use 'darwin', 'gnu', 'link' or 'wasm.",
|
|
|
|
s)))
|
|
|
|
}
|
|
|
|
Some(Ok(()))
|
|
|
|
})).unwrap_or(Ok(()))
|
|
|
|
} );
|
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
2017-02-21 14:47:15 -05:00
|
|
|
($key_name:ident, LinkerFlavor) => ( {
|
|
|
|
let name = (stringify!($key_name)).replace("_", "-");
|
2020-10-08 22:22:28 +03:00
|
|
|
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
|
|
|
|
match LinkerFlavor::from_str(s) {
|
2020-11-08 14:27:51 +03:00
|
|
|
Some(linker_flavor) => base.$key_name = linker_flavor,
|
2020-10-08 22:22:28 +03:00
|
|
|
_ => return Some(Err(format!("'{}' is not a valid value for linker-flavor. \
|
|
|
|
Use {}", s, LinkerFlavor::one_of()))),
|
|
|
|
}
|
|
|
|
Some(Ok(()))
|
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
2017-02-21 14:47:15 -05:00
|
|
|
})).unwrap_or(Ok(()))
|
|
|
|
} );
|
2021-01-09 16:54:20 +02:00
|
|
|
($key_name:ident, StackProbeType) => ( {
|
|
|
|
let name = (stringify!($key_name)).replace("_", "-");
|
|
|
|
obj.find(&name[..]).and_then(|o| match StackProbeType::from_json(o) {
|
|
|
|
Ok(v) => {
|
|
|
|
base.$key_name = v;
|
|
|
|
Some(Ok(()))
|
|
|
|
},
|
|
|
|
Err(s) => Some(Err(
|
|
|
|
format!("`{:?}` is not a valid value for `{}`: {}", o, name, s)
|
|
|
|
)),
|
|
|
|
}).unwrap_or(Ok(()))
|
|
|
|
} );
|
2020-04-29 20:47:07 +03:00
|
|
|
($key_name:ident, crt_objects_fallback) => ( {
|
|
|
|
let name = (stringify!($key_name)).replace("_", "-");
|
|
|
|
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
|
|
|
|
match s.parse::<CrtObjectsFallback>() {
|
2020-11-08 14:27:51 +03:00
|
|
|
Ok(fallback) => base.$key_name = Some(fallback),
|
2020-04-29 20:47:07 +03:00
|
|
|
_ => return Some(Err(format!("'{}' is not a valid CRT objects fallback. \
|
|
|
|
Use 'musl', 'mingw' or 'wasm'", s))),
|
|
|
|
}
|
|
|
|
Some(Ok(()))
|
|
|
|
})).unwrap_or(Ok(()))
|
|
|
|
} );
|
|
|
|
($key_name:ident, link_objects) => ( {
|
|
|
|
let name = (stringify!($key_name)).replace("_", "-");
|
|
|
|
if let Some(val) = obj.find(&name[..]) {
|
|
|
|
let obj = val.as_object().ok_or_else(|| format!("{}: expected a \
|
|
|
|
JSON object with fields per CRT object kind.", name))?;
|
|
|
|
let mut args = CrtObjects::new();
|
|
|
|
for (k, v) in obj {
|
|
|
|
let kind = LinkOutputKind::from_str(&k).ok_or_else(|| {
|
|
|
|
format!("{}: '{}' is not a valid value for CRT object kind. \
|
|
|
|
Use '(dynamic,static)-(nopic,pic)-exe' or \
|
2020-12-12 21:38:23 -06:00
|
|
|
'(dynamic,static)-dylib' or 'wasi-reactor-exe'", name, k)
|
2020-04-29 20:47:07 +03:00
|
|
|
})?;
|
|
|
|
|
|
|
|
let v = v.as_array().ok_or_else(||
|
|
|
|
format!("{}.{}: expected a JSON array", name, k)
|
|
|
|
)?.iter().enumerate()
|
|
|
|
.map(|(i,s)| {
|
|
|
|
let s = s.as_string().ok_or_else(||
|
|
|
|
format!("{}.{}[{}]: expected a JSON string", name, k, i))?;
|
|
|
|
Ok(s.to_owned())
|
|
|
|
})
|
|
|
|
.collect::<Result<Vec<_>, String>>()?;
|
|
|
|
|
|
|
|
args.insert(kind, v);
|
|
|
|
}
|
2020-11-08 14:27:51 +03:00
|
|
|
base.$key_name = args;
|
2020-04-29 20:47:07 +03:00
|
|
|
}
|
|
|
|
} );
|
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
2017-02-21 14:47:15 -05:00
|
|
|
($key_name:ident, link_args) => ( {
|
|
|
|
let name = (stringify!($key_name)).replace("_", "-");
|
2018-07-13 10:14:16 -07:00
|
|
|
if let Some(val) = obj.find(&name[..]) {
|
|
|
|
let obj = val.as_object().ok_or_else(|| format!("{}: expected a \
|
|
|
|
JSON object with fields per linker-flavor.", name))?;
|
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
2017-02-21 14:47:15 -05:00
|
|
|
let mut args = LinkArgs::new();
|
|
|
|
for (k, v) in obj {
|
2018-07-13 10:14:16 -07:00
|
|
|
let flavor = LinkerFlavor::from_str(&k).ok_or_else(|| {
|
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
2017-02-21 14:47:15 -05:00
|
|
|
format!("{}: '{}' is not a valid value for linker-flavor. \
|
|
|
|
Use 'em', 'gcc', 'ld' or 'msvc'", name, k)
|
|
|
|
})?;
|
|
|
|
|
2018-07-13 10:14:16 -07:00
|
|
|
let v = v.as_array().ok_or_else(||
|
|
|
|
format!("{}.{}: expected a JSON array", name, k)
|
|
|
|
)?.iter().enumerate()
|
|
|
|
.map(|(i,s)| {
|
|
|
|
let s = s.as_string().ok_or_else(||
|
|
|
|
format!("{}.{}[{}]: expected a JSON string", name, k, i))?;
|
|
|
|
Ok(s.to_owned())
|
|
|
|
})
|
|
|
|
.collect::<Result<Vec<_>, String>>()?;
|
|
|
|
|
|
|
|
args.insert(flavor, v);
|
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
2017-02-21 14:47:15 -05:00
|
|
|
}
|
2020-11-08 14:27:51 +03:00
|
|
|
base.$key_name = args;
|
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
2017-02-21 14:47:15 -05:00
|
|
|
}
|
|
|
|
} );
|
2017-06-23 17:26:39 -07:00
|
|
|
($key_name:ident, env) => ( {
|
|
|
|
let name = (stringify!($key_name)).replace("_", "-");
|
|
|
|
if let Some(a) = obj.find(&name[..]).and_then(|o| o.as_array()) {
|
|
|
|
for o in a {
|
|
|
|
if let Some(s) = o.as_string() {
|
|
|
|
let p = s.split('=').collect::<Vec<_>>();
|
|
|
|
if p.len() == 2 {
|
|
|
|
let k = p[0].to_string();
|
|
|
|
let v = p[1].to_string();
|
2020-11-08 14:27:51 +03:00
|
|
|
base.$key_name.push((k, v));
|
2017-06-23 17:26:39 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} );
|
2015-01-02 14:44:21 -08:00
|
|
|
}
|
2014-07-23 11:56:36 -07:00
|
|
|
|
2021-01-05 01:01:29 +00:00
|
|
|
if let Some(s) = obj.find("target-endian").and_then(Json::as_string) {
|
|
|
|
base.endian = s.parse()?;
|
|
|
|
}
|
2016-04-15 09:13:28 -05:00
|
|
|
key!(is_builtin, bool);
|
2020-11-12 19:16:59 +03:00
|
|
|
key!(c_int_width = "target-c-int-width");
|
2020-11-08 14:57:55 +03:00
|
|
|
key!(os);
|
|
|
|
key!(env);
|
|
|
|
key!(vendor);
|
2020-10-08 22:22:28 +03:00
|
|
|
key!(linker_flavor, LinkerFlavor)?;
|
2018-02-10 12:09:25 -08:00
|
|
|
key!(linker, optional);
|
2018-12-01 15:48:55 -06:00
|
|
|
key!(lld_flavor, LldFlavor)?;
|
2020-04-29 20:47:07 +03:00
|
|
|
key!(pre_link_objects, link_objects);
|
|
|
|
key!(post_link_objects, link_objects);
|
|
|
|
key!(pre_link_objects_fallback, link_objects);
|
|
|
|
key!(post_link_objects_fallback, link_objects);
|
|
|
|
key!(crt_objects_fallback, crt_objects_fallback)?;
|
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
2017-02-21 14:47:15 -05:00
|
|
|
key!(pre_link_args, link_args);
|
|
|
|
key!(late_link_args, link_args);
|
2020-03-03 20:41:37 +00:00
|
|
|
key!(late_link_args_dynamic, link_args);
|
|
|
|
key!(late_link_args_static, link_args);
|
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
2017-02-21 14:47:15 -05:00
|
|
|
key!(post_link_args, link_args);
|
2020-05-10 17:39:57 -04:00
|
|
|
key!(link_script, optional);
|
2017-06-23 17:26:39 -07:00
|
|
|
key!(link_env, env);
|
2019-09-12 13:47:17 +03:00
|
|
|
key!(link_env_remove, list);
|
2016-12-18 22:25:46 -05:00
|
|
|
key!(asm_args, list);
|
2016-04-15 09:13:28 -05:00
|
|
|
key!(cpu);
|
|
|
|
key!(features);
|
|
|
|
key!(dynamic_linking, bool);
|
2017-10-22 20:01:00 -07:00
|
|
|
key!(only_cdylib, bool);
|
2016-04-15 09:13:28 -05:00
|
|
|
key!(executables, bool);
|
2020-04-23 00:46:45 +03:00
|
|
|
key!(relocation_model, RelocModel)?;
|
2020-05-07 03:34:27 +03:00
|
|
|
key!(code_model, CodeModel)?;
|
2020-04-25 21:45:21 +03:00
|
|
|
key!(tls_model, TlsModel)?;
|
2016-04-15 09:13:28 -05:00
|
|
|
key!(disable_redzone, bool);
|
|
|
|
key!(eliminate_frame_pointer, bool);
|
|
|
|
key!(function_sections, bool);
|
2014-07-23 11:56:36 -07:00
|
|
|
key!(dll_prefix);
|
|
|
|
key!(dll_suffix);
|
|
|
|
key!(exe_suffix);
|
|
|
|
key!(staticlib_prefix);
|
|
|
|
key!(staticlib_suffix);
|
2020-11-12 19:16:59 +03:00
|
|
|
key!(os_family = "target-family", optional);
|
2018-02-26 10:20:14 -08:00
|
|
|
key!(abi_return_struct_as_int, bool);
|
2014-07-23 11:56:36 -07:00
|
|
|
key!(is_like_osx, bool);
|
2016-04-15 09:13:28 -05:00
|
|
|
key!(is_like_solaris, bool);
|
2014-07-23 11:56:36 -07:00
|
|
|
key!(is_like_windows, bool);
|
2016-04-08 11:24:19 +03:00
|
|
|
key!(is_like_msvc, bool);
|
2017-01-20 21:18:51 +03:00
|
|
|
key!(is_like_emscripten, bool);
|
2018-11-22 00:59:37 -08:00
|
|
|
key!(is_like_fuchsia, bool);
|
2020-10-09 15:08:18 -04:00
|
|
|
key!(dwarf_version, Option<u32>);
|
2014-07-23 11:56:36 -07:00
|
|
|
key!(linker_is_gnu, bool);
|
2016-07-13 17:03:02 -04:00
|
|
|
key!(allows_weak_linkage, bool);
|
2014-07-23 11:56:36 -07:00
|
|
|
key!(has_rpath, bool);
|
2015-09-21 19:02:46 +02:00
|
|
|
key!(no_default_libraries, bool);
|
2016-04-15 09:13:28 -05:00
|
|
|
key!(position_independent_executables, bool);
|
2020-05-02 01:59:35 +03:00
|
|
|
key!(static_position_independent_executables, bool);
|
2018-09-26 19:19:55 +03:00
|
|
|
key!(needs_plt, bool);
|
2018-12-01 15:48:55 -06:00
|
|
|
key!(relro_level, RelroLevel)?;
|
2015-11-18 01:14:15 +01:00
|
|
|
key!(archive_format);
|
2015-08-20 17:47:21 -05:00
|
|
|
key!(allow_asm, bool);
|
2019-10-17 16:09:32 -07:00
|
|
|
key!(main_needs_argc_argv, bool);
|
2016-04-15 09:13:28 -05:00
|
|
|
key!(has_elf_tls, bool);
|
|
|
|
key!(obj_is_bitcode, bool);
|
2020-05-07 12:26:18 +10:00
|
|
|
key!(forces_embed_bitcode, bool);
|
2020-05-07 15:34:31 +10:00
|
|
|
key!(bitcode_llvm_cmdline);
|
2016-10-03 23:45:40 -05:00
|
|
|
key!(max_atomic_width, Option<u64>);
|
2016-08-15 09:46:44 +00:00
|
|
|
key!(min_atomic_width, Option<u64>);
|
2018-06-30 14:56:08 -05:00
|
|
|
key!(atomic_cas, bool);
|
2018-12-01 15:48:55 -06:00
|
|
|
key!(panic_strategy, PanicStrategy)?;
|
2017-08-22 16:24:29 -05:00
|
|
|
key!(crt_static_allows_dylibs, bool);
|
rustc: Implement #[link(cfg(..))] and crt-static
This commit is an implementation of [RFC 1721] which adds a new target feature
to the compiler, `crt-static`, which can be used to select how the C runtime for
a target is linked. Most targets dynamically linke the C runtime by default with
the notable exception of some of the musl targets.
[RFC 1721]: https://github.com/rust-lang/rfcs/blob/master/text/1721-crt-static.md
This commit first adds the new target-feature, `crt-static`. If enabled, then
the `cfg(target_feature = "crt-static")` will be available. Targets like musl
will have this enabled by default. This feature can be controlled through the
standard target-feature interface, `-C target-feature=+crt-static` or
`-C target-feature=-crt-static`.
Next this adds an gated and unstable `#[link(cfg(..))]` feature to enable the
`crt-static` semantics we want with libc. The exact behavior of this attribute
is a little squishy, but it's intended to be a forever-unstable
implementation detail of the liblibc crate.
Specifically the `#[link(cfg(..))]` annotation means that the `#[link]`
directive is only active in a compilation unit if that `cfg` value is satisfied.
For example when compiling an rlib, these directives are just encoded and
ignored for dylibs, and all staticlibs are continued to be put into the rlib as
usual. When placing that rlib into a staticlib, executable, or dylib, however,
the `cfg` is evaluated *as if it were defined in the final artifact* and the
library is decided to be linked or not.
Essentially, what'll happen is:
* On MSVC with `-C target-feature=-crt-static`, the `msvcrt.lib` library will be
linked to.
* On MSVC with `-C target-feature=+crt-static`, the `libcmt.lib` library will be
linked to.
* On musl with `-C target-feature=-crt-static`, the object files in liblibc.rlib
are removed and `-lc` is passed instead.
* On musl with `-C target-feature=+crt-static`, the object files in liblibc.rlib
are used and `-lc` is not passed.
This commit does **not** include an update to the liblibc module to implement
these changes. I plan to do that just after the 1.14.0 beta release is cut to
ensure we get ample time to test this feature.
cc #37406
2016-10-31 16:40:13 -07:00
|
|
|
key!(crt_static_default, bool);
|
2017-08-22 16:24:29 -05:00
|
|
|
key!(crt_static_respected, bool);
|
2021-01-09 16:54:20 +02:00
|
|
|
key!(stack_probes, StackProbeType)?;
|
2017-09-08 14:49:51 -07:00
|
|
|
key!(min_global_align, Option<u64>);
|
2017-10-04 14:38:52 -07:00
|
|
|
key!(default_codegen_units, Option<u64>);
|
2017-11-11 07:08:00 -08:00
|
|
|
key!(trap_unreachable, bool);
|
2017-10-22 20:01:00 -07:00
|
|
|
key!(requires_lto, bool);
|
|
|
|
key!(singlethread, bool);
|
|
|
|
key!(no_builtins, bool);
|
2018-01-30 11:54:07 -08:00
|
|
|
key!(default_hidden_visibility, bool);
|
2018-04-06 15:40:43 +02:00
|
|
|
key!(emit_debug_gdb_scripts, bool);
|
2018-04-19 15:17:34 -07:00
|
|
|
key!(requires_uwtable, bool);
|
2021-03-23 02:38:30 +08:00
|
|
|
key!(default_uwtable, bool);
|
2018-10-12 17:04:31 -07:00
|
|
|
key!(simd_types_indirect, bool);
|
2019-04-14 19:05:21 +02:00
|
|
|
key!(limit_rdylib_exports, bool);
|
2018-11-19 15:04:28 +05:30
|
|
|
key!(override_export_symbols, opt_list);
|
2018-12-31 10:58:13 -08:00
|
|
|
key!(merge_functions, MergeFunctions)?;
|
2020-11-12 19:16:59 +03:00
|
|
|
key!(mcount = "target-mcount");
|
2019-10-29 21:12:05 -07:00
|
|
|
key!(llvm_abiname);
|
2019-12-02 17:52:45 +05:30
|
|
|
key!(relax_elf_relocations, bool);
|
2020-01-09 16:40:40 +01:00
|
|
|
key!(llvm_args, list);
|
2020-04-16 19:40:11 -07:00
|
|
|
key!(use_ctors_section, bool);
|
2020-07-22 15:49:04 +03:00
|
|
|
key!(eh_frame_header, bool);
|
2020-10-08 23:23:27 +01:00
|
|
|
key!(has_thumb_interworking, bool);
|
2020-11-30 08:39:08 -08:00
|
|
|
key!(split_debuginfo, SplitDebuginfo)?;
|
2014-07-23 11:56:36 -07:00
|
|
|
|
2020-07-08 09:36:52 -04:00
|
|
|
// NB: The old name is deprecated, but support for it is retained for
|
|
|
|
// compatibility.
|
|
|
|
for name in ["abi-blacklist", "unsupported-abis"].iter() {
|
|
|
|
if let Some(array) = obj.find(name).and_then(Json::as_array) {
|
|
|
|
for name in array.iter().filter_map(|abi| abi.as_string()) {
|
|
|
|
match lookup_abi(name) {
|
|
|
|
Some(abi) => {
|
|
|
|
if abi.generic() {
|
|
|
|
return Err(format!(
|
|
|
|
"The ABI \"{}\" is considered to be supported on all \
|
|
|
|
targets and cannot be marked unsupported",
|
|
|
|
abi
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
2020-11-08 14:27:51 +03:00
|
|
|
base.unsupported_abis.push(abi)
|
2020-07-08 09:36:52 -04:00
|
|
|
}
|
|
|
|
None => {
|
2019-12-22 17:42:04 -05:00
|
|
|
return Err(format!(
|
2020-07-08 09:36:52 -04:00
|
|
|
"Unknown ABI \"{}\" in target specification",
|
|
|
|
name
|
2019-12-22 17:42:04 -05:00
|
|
|
));
|
2016-10-24 11:04:04 +02:00
|
|
|
}
|
2019-12-22 17:42:04 -05:00
|
|
|
}
|
2016-10-24 11:04:04 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-24 11:47:39 -05:00
|
|
|
Ok(base)
|
2014-07-23 11:56:36 -07:00
|
|
|
}
|
|
|
|
|
2015-02-26 21:00:43 -08:00
|
|
|
/// Search RUST_TARGET_PATH for a JSON file specifying the given target
|
|
|
|
/// triple. Note that it could also just be a bare filename already, so also
|
|
|
|
/// check for that. If one of the hardcoded targets we know about, just
|
|
|
|
/// return it directly.
|
2014-07-23 11:56:36 -07:00
|
|
|
///
|
2015-02-26 21:00:43 -08:00
|
|
|
/// The error string could come from any of the APIs called, including
|
|
|
|
/// filesystem access and JSON decoding.
|
2018-03-14 15:27:06 +01:00
|
|
|
pub fn search(target_triple: &TargetTriple) -> Result<Target, String> {
|
2019-12-22 17:42:04 -05:00
|
|
|
use rustc_serialize::json;
|
2015-01-27 12:20:58 -08:00
|
|
|
use std::env;
|
2018-01-10 08:58:39 -08:00
|
|
|
use std::fs;
|
2014-07-23 11:56:36 -07:00
|
|
|
|
|
|
|
fn load_file(path: &Path) -> Result<Target, String> {
|
2018-01-10 08:58:39 -08:00
|
|
|
let contents = fs::read(path).map_err(|e| e.to_string())?;
|
2019-12-22 17:42:04 -05:00
|
|
|
let obj = json::from_reader(&mut &contents[..]).map_err(|e| e.to_string())?;
|
2016-07-24 11:47:39 -05:00
|
|
|
Target::from_json(obj)
|
2014-07-23 11:56:36 -07:00
|
|
|
}
|
|
|
|
|
2018-08-09 15:42:43 +02:00
|
|
|
match *target_triple {
|
|
|
|
TargetTriple::TargetTriple(ref target_triple) => {
|
2020-10-05 16:24:04 +03:00
|
|
|
// check if triple is in list of built-in targets
|
|
|
|
if let Some(t) = load_builtin(target_triple) {
|
|
|
|
return Ok(t);
|
2018-03-14 15:27:06 +01:00
|
|
|
}
|
2014-07-23 11:56:36 -07:00
|
|
|
|
2018-03-14 15:27:06 +01:00
|
|
|
// search for a file named `target_triple`.json in RUST_TARGET_PATH
|
|
|
|
let path = {
|
|
|
|
let mut target = target_triple.to_string();
|
|
|
|
target.push_str(".json");
|
|
|
|
PathBuf::from(target)
|
|
|
|
};
|
2014-07-23 11:56:36 -07:00
|
|
|
|
2018-08-09 15:42:43 +02:00
|
|
|
let target_path = env::var_os("RUST_TARGET_PATH").unwrap_or_default();
|
2014-07-23 11:56:36 -07:00
|
|
|
|
2018-03-14 15:27:06 +01:00
|
|
|
// FIXME 16351: add a sane default search path?
|
2014-07-23 11:56:36 -07:00
|
|
|
|
2018-03-14 15:27:06 +01:00
|
|
|
for dir in env::split_paths(&target_path) {
|
2019-12-22 17:42:04 -05:00
|
|
|
let p = dir.join(&path);
|
2018-03-14 15:27:06 +01:00
|
|
|
if p.is_file() {
|
|
|
|
return load_file(&p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(format!("Could not find specification for target {:?}", target_triple))
|
|
|
|
}
|
2018-08-09 15:42:43 +02:00
|
|
|
TargetTriple::TargetPath(ref target_path) => {
|
2018-03-14 15:27:06 +01:00
|
|
|
if target_path.is_file() {
|
|
|
|
return load_file(&target_path);
|
|
|
|
}
|
|
|
|
Err(format!("Target path {:?} is not a valid file", target_path))
|
2014-07-23 11:56:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-06-25 10:07:01 -07:00
|
|
|
|
2016-04-07 22:29:01 -05:00
|
|
|
impl ToJson for Target {
|
|
|
|
fn to_json(&self) -> Json {
|
|
|
|
let mut d = BTreeMap::new();
|
|
|
|
let default: TargetOptions = Default::default();
|
|
|
|
|
|
|
|
macro_rules! target_val {
|
2019-12-22 17:42:04 -05:00
|
|
|
($attr:ident) => {{
|
2016-04-07 22:29:01 -05:00
|
|
|
let name = (stringify!($attr)).replace("_", "-");
|
2018-10-26 03:11:11 +09:00
|
|
|
d.insert(name, self.$attr.to_json());
|
2019-12-22 17:42:04 -05:00
|
|
|
}};
|
|
|
|
($attr:ident, $key_name:expr) => {{
|
2016-04-07 22:29:01 -05:00
|
|
|
let name = $key_name;
|
|
|
|
d.insert(name.to_string(), self.$attr.to_json());
|
2019-12-22 17:42:04 -05:00
|
|
|
}};
|
2016-04-07 22:29:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! target_option_val {
|
2019-12-22 17:42:04 -05:00
|
|
|
($attr:ident) => {{
|
2016-04-07 22:29:01 -05:00
|
|
|
let name = (stringify!($attr)).replace("_", "-");
|
2020-11-08 14:27:51 +03:00
|
|
|
if default.$attr != self.$attr {
|
|
|
|
d.insert(name, self.$attr.to_json());
|
2016-04-07 22:29:01 -05:00
|
|
|
}
|
2019-12-22 17:42:04 -05:00
|
|
|
}};
|
|
|
|
($attr:ident, $key_name:expr) => {{
|
2016-04-07 22:29:01 -05:00
|
|
|
let name = $key_name;
|
2020-11-08 14:27:51 +03:00
|
|
|
if default.$attr != self.$attr {
|
|
|
|
d.insert(name.to_string(), self.$attr.to_json());
|
2016-04-07 22:29:01 -05:00
|
|
|
}
|
2019-12-22 17:42:04 -05:00
|
|
|
}};
|
|
|
|
(link_args - $attr:ident) => {{
|
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
2017-02-21 14:47:15 -05:00
|
|
|
let name = (stringify!($attr)).replace("_", "-");
|
2020-11-08 14:27:51 +03:00
|
|
|
if default.$attr != self.$attr {
|
2019-12-22 17:42:04 -05:00
|
|
|
let obj = self
|
|
|
|
.$attr
|
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
2017-02-21 14:47:15 -05:00
|
|
|
.iter()
|
|
|
|
.map(|(k, v)| (k.desc().to_owned(), v.clone()))
|
|
|
|
.collect::<BTreeMap<_, _>>();
|
2018-10-26 03:11:11 +09:00
|
|
|
d.insert(name, obj.to_json());
|
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
2017-02-21 14:47:15 -05:00
|
|
|
}
|
2019-12-22 17:42:04 -05:00
|
|
|
}};
|
|
|
|
(env - $attr:ident) => {{
|
2017-06-23 17:26:39 -07:00
|
|
|
let name = (stringify!($attr)).replace("_", "-");
|
2020-11-08 14:27:51 +03:00
|
|
|
if default.$attr != self.$attr {
|
2019-12-22 17:42:04 -05:00
|
|
|
let obj = self
|
|
|
|
.$attr
|
2017-06-23 17:26:39 -07:00
|
|
|
.iter()
|
|
|
|
.map(|&(ref k, ref v)| k.clone() + "=" + &v)
|
|
|
|
.collect::<Vec<_>>();
|
2018-10-26 03:11:11 +09:00
|
|
|
d.insert(name, obj.to_json());
|
2017-06-23 17:26:39 -07:00
|
|
|
}
|
2019-12-22 17:42:04 -05:00
|
|
|
}};
|
2016-04-07 22:29:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
target_val!(llvm_target);
|
2020-10-15 11:44:00 +02:00
|
|
|
d.insert("target-pointer-width".to_string(), self.pointer_width.to_string().to_json());
|
2016-04-07 22:29:01 -05:00
|
|
|
target_val!(arch);
|
|
|
|
target_val!(data_layout);
|
|
|
|
|
2020-10-08 21:47:22 +03:00
|
|
|
target_option_val!(is_builtin);
|
2020-11-12 19:16:59 +03:00
|
|
|
target_option_val!(endian, "target-endian");
|
|
|
|
target_option_val!(c_int_width, "target-c-int-width");
|
2020-11-08 14:57:55 +03:00
|
|
|
target_option_val!(os);
|
|
|
|
target_option_val!(env);
|
|
|
|
target_option_val!(vendor);
|
2020-10-08 22:22:28 +03:00
|
|
|
target_option_val!(linker_flavor);
|
2016-04-07 22:29:01 -05:00
|
|
|
target_option_val!(linker);
|
2018-08-18 20:16:04 +02:00
|
|
|
target_option_val!(lld_flavor);
|
2020-04-29 20:47:07 +03:00
|
|
|
target_option_val!(pre_link_objects);
|
|
|
|
target_option_val!(post_link_objects);
|
|
|
|
target_option_val!(pre_link_objects_fallback);
|
|
|
|
target_option_val!(post_link_objects_fallback);
|
|
|
|
target_option_val!(crt_objects_fallback);
|
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
2017-02-21 14:47:15 -05:00
|
|
|
target_option_val!(link_args - pre_link_args);
|
|
|
|
target_option_val!(link_args - late_link_args);
|
2020-03-03 20:41:37 +00:00
|
|
|
target_option_val!(link_args - late_link_args_dynamic);
|
|
|
|
target_option_val!(link_args - late_link_args_static);
|
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
2017-02-21 14:47:15 -05:00
|
|
|
target_option_val!(link_args - post_link_args);
|
2020-05-10 17:39:57 -04:00
|
|
|
target_option_val!(link_script);
|
2017-06-23 17:26:39 -07:00
|
|
|
target_option_val!(env - link_env);
|
2019-09-12 13:47:17 +03:00
|
|
|
target_option_val!(link_env_remove);
|
2016-12-18 22:25:46 -05:00
|
|
|
target_option_val!(asm_args);
|
2016-04-07 22:29:01 -05:00
|
|
|
target_option_val!(cpu);
|
|
|
|
target_option_val!(features);
|
|
|
|
target_option_val!(dynamic_linking);
|
2017-10-22 20:01:00 -07:00
|
|
|
target_option_val!(only_cdylib);
|
2016-04-07 22:29:01 -05:00
|
|
|
target_option_val!(executables);
|
|
|
|
target_option_val!(relocation_model);
|
|
|
|
target_option_val!(code_model);
|
2017-10-31 17:45:19 +00:00
|
|
|
target_option_val!(tls_model);
|
2016-04-07 22:29:01 -05:00
|
|
|
target_option_val!(disable_redzone);
|
|
|
|
target_option_val!(eliminate_frame_pointer);
|
|
|
|
target_option_val!(function_sections);
|
|
|
|
target_option_val!(dll_prefix);
|
|
|
|
target_option_val!(dll_suffix);
|
|
|
|
target_option_val!(exe_suffix);
|
|
|
|
target_option_val!(staticlib_prefix);
|
|
|
|
target_option_val!(staticlib_suffix);
|
2020-11-12 19:16:59 +03:00
|
|
|
target_option_val!(os_family, "target-family");
|
2018-02-26 10:20:14 -08:00
|
|
|
target_option_val!(abi_return_struct_as_int);
|
2016-04-07 22:29:01 -05:00
|
|
|
target_option_val!(is_like_osx);
|
|
|
|
target_option_val!(is_like_solaris);
|
|
|
|
target_option_val!(is_like_windows);
|
|
|
|
target_option_val!(is_like_msvc);
|
2017-01-20 21:18:51 +03:00
|
|
|
target_option_val!(is_like_emscripten);
|
2018-11-22 00:59:37 -08:00
|
|
|
target_option_val!(is_like_fuchsia);
|
2020-10-09 15:08:18 -04:00
|
|
|
target_option_val!(dwarf_version);
|
2016-04-07 22:29:01 -05:00
|
|
|
target_option_val!(linker_is_gnu);
|
2016-07-13 17:03:02 -04:00
|
|
|
target_option_val!(allows_weak_linkage);
|
2016-04-07 22:29:01 -05:00
|
|
|
target_option_val!(has_rpath);
|
|
|
|
target_option_val!(no_default_libraries);
|
|
|
|
target_option_val!(position_independent_executables);
|
2020-05-02 01:59:35 +03:00
|
|
|
target_option_val!(static_position_independent_executables);
|
2018-09-26 19:19:55 +03:00
|
|
|
target_option_val!(needs_plt);
|
2017-07-14 22:01:37 +02:00
|
|
|
target_option_val!(relro_level);
|
2016-04-07 22:29:01 -05:00
|
|
|
target_option_val!(archive_format);
|
|
|
|
target_option_val!(allow_asm);
|
2019-10-17 16:09:32 -07:00
|
|
|
target_option_val!(main_needs_argc_argv);
|
2016-04-07 22:29:01 -05:00
|
|
|
target_option_val!(has_elf_tls);
|
|
|
|
target_option_val!(obj_is_bitcode);
|
2020-05-07 12:26:18 +10:00
|
|
|
target_option_val!(forces_embed_bitcode);
|
2020-05-07 15:34:31 +10:00
|
|
|
target_option_val!(bitcode_llvm_cmdline);
|
2016-08-15 09:46:44 +00:00
|
|
|
target_option_val!(min_atomic_width);
|
2016-04-07 22:29:01 -05:00
|
|
|
target_option_val!(max_atomic_width);
|
2018-06-30 14:56:08 -05:00
|
|
|
target_option_val!(atomic_cas);
|
2016-09-27 21:26:08 -05:00
|
|
|
target_option_val!(panic_strategy);
|
2017-08-22 16:24:29 -05:00
|
|
|
target_option_val!(crt_static_allows_dylibs);
|
rustc: Implement #[link(cfg(..))] and crt-static
This commit is an implementation of [RFC 1721] which adds a new target feature
to the compiler, `crt-static`, which can be used to select how the C runtime for
a target is linked. Most targets dynamically linke the C runtime by default with
the notable exception of some of the musl targets.
[RFC 1721]: https://github.com/rust-lang/rfcs/blob/master/text/1721-crt-static.md
This commit first adds the new target-feature, `crt-static`. If enabled, then
the `cfg(target_feature = "crt-static")` will be available. Targets like musl
will have this enabled by default. This feature can be controlled through the
standard target-feature interface, `-C target-feature=+crt-static` or
`-C target-feature=-crt-static`.
Next this adds an gated and unstable `#[link(cfg(..))]` feature to enable the
`crt-static` semantics we want with libc. The exact behavior of this attribute
is a little squishy, but it's intended to be a forever-unstable
implementation detail of the liblibc crate.
Specifically the `#[link(cfg(..))]` annotation means that the `#[link]`
directive is only active in a compilation unit if that `cfg` value is satisfied.
For example when compiling an rlib, these directives are just encoded and
ignored for dylibs, and all staticlibs are continued to be put into the rlib as
usual. When placing that rlib into a staticlib, executable, or dylib, however,
the `cfg` is evaluated *as if it were defined in the final artifact* and the
library is decided to be linked or not.
Essentially, what'll happen is:
* On MSVC with `-C target-feature=-crt-static`, the `msvcrt.lib` library will be
linked to.
* On MSVC with `-C target-feature=+crt-static`, the `libcmt.lib` library will be
linked to.
* On musl with `-C target-feature=-crt-static`, the object files in liblibc.rlib
are removed and `-lc` is passed instead.
* On musl with `-C target-feature=+crt-static`, the object files in liblibc.rlib
are used and `-lc` is not passed.
This commit does **not** include an update to the liblibc module to implement
these changes. I plan to do that just after the 1.14.0 beta release is cut to
ensure we get ample time to test this feature.
cc #37406
2016-10-31 16:40:13 -07:00
|
|
|
target_option_val!(crt_static_default);
|
2017-08-22 16:24:29 -05:00
|
|
|
target_option_val!(crt_static_respected);
|
2017-06-21 12:08:18 -07:00
|
|
|
target_option_val!(stack_probes);
|
2017-09-08 14:49:51 -07:00
|
|
|
target_option_val!(min_global_align);
|
2017-10-04 14:38:52 -07:00
|
|
|
target_option_val!(default_codegen_units);
|
2017-11-11 07:08:00 -08:00
|
|
|
target_option_val!(trap_unreachable);
|
2017-10-22 20:01:00 -07:00
|
|
|
target_option_val!(requires_lto);
|
|
|
|
target_option_val!(singlethread);
|
|
|
|
target_option_val!(no_builtins);
|
2018-01-30 11:54:07 -08:00
|
|
|
target_option_val!(default_hidden_visibility);
|
2018-04-06 15:40:43 +02:00
|
|
|
target_option_val!(emit_debug_gdb_scripts);
|
2018-04-19 15:17:34 -07:00
|
|
|
target_option_val!(requires_uwtable);
|
2021-03-23 02:38:30 +08:00
|
|
|
target_option_val!(default_uwtable);
|
2018-10-12 17:04:31 -07:00
|
|
|
target_option_val!(simd_types_indirect);
|
2019-04-14 19:05:21 +02:00
|
|
|
target_option_val!(limit_rdylib_exports);
|
2018-11-19 15:04:28 +05:30
|
|
|
target_option_val!(override_export_symbols);
|
2018-12-31 10:58:13 -08:00
|
|
|
target_option_val!(merge_functions);
|
2020-11-12 19:16:59 +03:00
|
|
|
target_option_val!(mcount, "target-mcount");
|
2019-10-29 21:12:05 -07:00
|
|
|
target_option_val!(llvm_abiname);
|
2019-12-02 17:52:45 +05:30
|
|
|
target_option_val!(relax_elf_relocations);
|
2020-01-09 16:40:40 +01:00
|
|
|
target_option_val!(llvm_args);
|
2020-04-16 19:40:11 -07:00
|
|
|
target_option_val!(use_ctors_section);
|
2020-07-22 15:49:04 +03:00
|
|
|
target_option_val!(eh_frame_header);
|
2020-10-08 23:23:27 +01:00
|
|
|
target_option_val!(has_thumb_interworking);
|
2020-11-30 08:39:08 -08:00
|
|
|
target_option_val!(split_debuginfo);
|
2016-04-07 22:29:01 -05:00
|
|
|
|
2020-11-08 14:27:51 +03:00
|
|
|
if default.unsupported_abis != self.unsupported_abis {
|
2019-12-22 17:42:04 -05:00
|
|
|
d.insert(
|
2020-07-08 09:36:52 -04:00
|
|
|
"unsupported-abis".to_string(),
|
2020-11-08 14:27:51 +03:00
|
|
|
self.unsupported_abis
|
2019-12-22 17:42:04 -05:00
|
|
|
.iter()
|
|
|
|
.map(|&name| Abi::name(name).to_json())
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
.to_json(),
|
|
|
|
);
|
2016-10-24 11:04:04 +02:00
|
|
|
}
|
|
|
|
|
2016-04-07 22:29:01 -05:00
|
|
|
Json::Object(d)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-14 15:27:06 +01:00
|
|
|
/// Either a target triple string or a path to a JSON file.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(PartialEq, Clone, Debug, Hash, Encodable, Decodable)]
|
2018-03-14 15:27:06 +01:00
|
|
|
pub enum TargetTriple {
|
|
|
|
TargetTriple(String),
|
|
|
|
TargetPath(PathBuf),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TargetTriple {
|
2018-03-24 20:14:59 +01:00
|
|
|
/// Creates a target triple from the passed target triple string.
|
2018-03-14 15:27:06 +01:00
|
|
|
pub fn from_triple(triple: &str) -> Self {
|
|
|
|
TargetTriple::TargetTriple(triple.to_string())
|
|
|
|
}
|
|
|
|
|
2018-03-24 20:14:59 +01:00
|
|
|
/// Creates a target triple from the passed target path.
|
|
|
|
pub fn from_path(path: &Path) -> Result<Self, io::Error> {
|
|
|
|
let canonicalized_path = path.canonicalize()?;
|
|
|
|
Ok(TargetTriple::TargetPath(canonicalized_path))
|
|
|
|
}
|
|
|
|
|
2018-03-14 15:27:06 +01:00
|
|
|
/// Returns a string triple for this target.
|
|
|
|
///
|
|
|
|
/// If this target is a path, the file name (without extension) is returned.
|
|
|
|
pub fn triple(&self) -> &str {
|
2018-08-09 15:42:43 +02:00
|
|
|
match *self {
|
|
|
|
TargetTriple::TargetTriple(ref triple) => triple,
|
2019-12-22 17:42:04 -05:00
|
|
|
TargetTriple::TargetPath(ref path) => path
|
|
|
|
.file_stem()
|
|
|
|
.expect("target path must not be empty")
|
|
|
|
.to_str()
|
|
|
|
.expect("target path must be valid unicode"),
|
2018-03-14 15:27:06 +01:00
|
|
|
}
|
|
|
|
}
|
2018-03-26 19:01:26 +02:00
|
|
|
|
|
|
|
/// Returns an extended string triple for this target.
|
|
|
|
///
|
|
|
|
/// If this target is a path, a hash of the path is appended to the triple returned
|
|
|
|
/// by `triple()`.
|
|
|
|
pub fn debug_triple(&self) -> String {
|
|
|
|
use std::collections::hash_map::DefaultHasher;
|
2019-12-22 17:42:04 -05:00
|
|
|
use std::hash::{Hash, Hasher};
|
2018-03-26 19:01:26 +02:00
|
|
|
|
|
|
|
let triple = self.triple();
|
2018-08-09 15:42:43 +02:00
|
|
|
if let TargetTriple::TargetPath(ref path) = *self {
|
2018-03-26 19:01:26 +02:00
|
|
|
let mut hasher = DefaultHasher::new();
|
|
|
|
path.hash(&mut hasher);
|
|
|
|
let hash = hasher.finish();
|
|
|
|
format!("{}-{}", triple, hash)
|
|
|
|
} else {
|
|
|
|
triple.to_owned()
|
|
|
|
}
|
|
|
|
}
|
2018-03-14 15:27:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for TargetTriple {
|
2019-02-08 21:00:07 +09:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2018-03-26 19:01:26 +02:00
|
|
|
write!(f, "{}", self.debug_triple())
|
2018-03-14 15:27:06 +01:00
|
|
|
}
|
|
|
|
}
|