mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
rustc: Add feature-gated cfg(target_thread_local)
Currently the standard library has some pretty complicated logic to detect whether #[thread_local] should be used or whether it's supported. This is also unfortunately not quite true for OSX where not all versions support the #[thread_local] attribute (only 10.7+ does). Compiling code for OSX 10.6 is typically requested via the MACOSX_DEPLOYMENT_TARGET environment variable (e.g. the linker recognizes this), but the standard library unfortunately does not respect this. This commit updates the compiler to add a `target_thread_local` cfg annotation if the platform being targeted supports the `#[thread_local]` attribute. This is feature gated for now, and it is only true on non-aarch64 Linux and 10.7+ OSX (e.g. what the module already does today). Logic has also been added to parse the deployment target environment variable.
This commit is contained in:
parent
d8cc67fb26
commit
b67b5a8d01
@ -660,6 +660,9 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
|
||||
"windows" | "unix" => ret.push(attr::mk_word_item(fam)),
|
||||
_ => (),
|
||||
}
|
||||
if sess.target.target.options.has_elf_tls {
|
||||
ret.push(attr::mk_word_item(InternedString::new("target_thread_local")));
|
||||
}
|
||||
if sess.opts.debug_assertions {
|
||||
ret.push(attr::mk_word_item(InternedString::new("debug_assertions")));
|
||||
}
|
||||
|
@ -11,7 +11,8 @@
|
||||
use target::Target;
|
||||
|
||||
pub fn target() -> Target {
|
||||
let base = super::linux_base::opts();
|
||||
let mut base = super::linux_base::opts();
|
||||
base.has_elf_tls = false;
|
||||
Target {
|
||||
llvm_target: "aarch64-unknown-linux-gnu".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
|
@ -8,10 +8,30 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::env;
|
||||
|
||||
use target::TargetOptions;
|
||||
use std::default::Default;
|
||||
|
||||
pub fn opts() -> TargetOptions {
|
||||
// ELF TLS is only available in OSX 10.7+. If you try to compile for 10.6
|
||||
// either the linker will complain if it is used or the binary will end up
|
||||
// segfaulting at runtime when run on 10.6. Rust by default supports OSX
|
||||
// 10.7+, but there is a standard environment variable,
|
||||
// MACOSX_DEPLOYMENT_TARGET, which is used to signal targeting older
|
||||
// versions of OSX. For example compiling on 10.10 with
|
||||
// MACOSX_DEPLOYMENT_TARGET set to 10.6 will cause the linker to generate
|
||||
// warnings about the usage of ELF TLS.
|
||||
//
|
||||
// Here we detect what version is being requested, defaulting to 10.7. ELF
|
||||
// TLS is flagged as enabled if it looks to be supported.
|
||||
let deployment_target = env::var("MACOSX_DEPLOYMENT_TARGET").ok();
|
||||
let version = deployment_target.as_ref().and_then(|s| {
|
||||
let mut i = s.splitn(2, ".");
|
||||
i.next().and_then(|a| i.next().map(|b| (a, b)))
|
||||
}).and_then(|(a, b)| {
|
||||
a.parse::<u32>().and_then(|a| b.parse::<u32>().map(|b| (a, b))).ok()
|
||||
}).unwrap_or((10, 7));
|
||||
|
||||
TargetOptions {
|
||||
// OSX has -dead_strip, which doesn't rely on ffunction_sections
|
||||
function_sections: false,
|
||||
@ -25,6 +45,7 @@ pub fn opts() -> TargetOptions {
|
||||
archive_format: "bsd".to_string(),
|
||||
pre_link_args: Vec::new(),
|
||||
exe_allocation_crate: super::maybe_jemalloc(),
|
||||
has_elf_tls: version >= (10, 7),
|
||||
.. Default::default()
|
||||
}
|
||||
}
|
||||
|
@ -88,6 +88,7 @@ pub fn opts(arch: Arch) -> TargetOptions {
|
||||
dynamic_linking: false,
|
||||
executables: true,
|
||||
pre_link_args: pre_link_args(arch),
|
||||
has_elf_tls: false,
|
||||
.. super::apple_base::opts()
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ use target::Target;
|
||||
pub fn target() -> Target {
|
||||
let mut base = super::android_base::opts();
|
||||
base.features = "+v7".to_string();
|
||||
base.has_elf_tls = false;
|
||||
|
||||
Target {
|
||||
llvm_target: "arm-linux-androideabi".to_string(),
|
||||
|
@ -30,6 +30,7 @@ pub fn opts() -> TargetOptions {
|
||||
position_independent_executables: true,
|
||||
archive_format: "gnu".to_string(),
|
||||
exe_allocation_crate: super::maybe_jemalloc(),
|
||||
has_elf_tls: true,
|
||||
.. Default::default()
|
||||
}
|
||||
}
|
||||
|
@ -195,6 +195,10 @@ pub struct TargetOptions {
|
||||
/// Default crate for allocation symbols to link against
|
||||
pub lib_allocation_crate: String,
|
||||
pub exe_allocation_crate: String,
|
||||
|
||||
/// Flag indicating whether ELF TLS (e.g. #[thread_local]) is available for
|
||||
/// this target.
|
||||
pub has_elf_tls: bool,
|
||||
}
|
||||
|
||||
impl Default for TargetOptions {
|
||||
@ -240,6 +244,7 @@ impl Default for TargetOptions {
|
||||
lib_allocation_crate: "alloc_system".to_string(),
|
||||
exe_allocation_crate: "alloc_system".to_string(),
|
||||
allow_asm: true,
|
||||
has_elf_tls: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -236,6 +236,9 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option<u32>, Status
|
||||
|
||||
// allow using type ascription in expressions
|
||||
("type_ascription", "1.6.0", Some(23416), Active),
|
||||
|
||||
// Allows cfg(target_thread_local)
|
||||
("cfg_target_thread_local", "1.7.0", Some(26581), Active),
|
||||
];
|
||||
// (changing above list without updating src/doc/reference.md makes @cmr sad)
|
||||
|
||||
@ -414,6 +417,8 @@ const GATED_CFGS: &'static [(&'static str, &'static str, fn(&Features) -> bool)]
|
||||
// (name in cfg, feature, function to check if the feature is enabled)
|
||||
("target_feature", "cfg_target_feature", cfg_fn!(|x| x.cfg_target_feature)),
|
||||
("target_vendor", "cfg_target_vendor", cfg_fn!(|x| x.cfg_target_vendor)),
|
||||
("target_thread_local", "cfg_target_thread_local",
|
||||
cfg_fn!(|x| x.cfg_target_thread_local)),
|
||||
];
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
@ -541,6 +546,7 @@ pub struct Features {
|
||||
pub type_macros: bool,
|
||||
pub cfg_target_feature: bool,
|
||||
pub cfg_target_vendor: bool,
|
||||
pub cfg_target_thread_local: bool,
|
||||
pub augmented_assignments: bool,
|
||||
pub braced_empty_structs: bool,
|
||||
pub staged_api: bool,
|
||||
@ -575,6 +581,7 @@ impl Features {
|
||||
type_macros: false,
|
||||
cfg_target_feature: false,
|
||||
cfg_target_vendor: false,
|
||||
cfg_target_thread_local: false,
|
||||
augmented_assignments: false,
|
||||
braced_empty_structs: false,
|
||||
staged_api: false,
|
||||
@ -1157,6 +1164,7 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &Handler,
|
||||
type_macros: cx.has_feature("type_macros"),
|
||||
cfg_target_feature: cx.has_feature("cfg_target_feature"),
|
||||
cfg_target_vendor: cx.has_feature("cfg_target_vendor"),
|
||||
cfg_target_thread_local: cx.has_feature("cfg_target_thread_local"),
|
||||
augmented_assignments: cx.has_feature("augmented_assignments"),
|
||||
braced_empty_structs: cx.has_feature("braced_empty_structs"),
|
||||
staged_api: cx.has_feature("staged_api"),
|
||||
|
Loading…
Reference in New Issue
Block a user