Introduce temporary target feature crt_static_respected

This feature allows targets to opt in to full support of the crt-static
feature. Currently, crt-static is allowed on all targets, even those
that really can't or really shouldn't support it. This works because it
is very loose in the specification of its effects. Changing the behavior
of crt-static to be more strict in how it chooses libraries and links
executables would likely cause compilation to fail on these platforms.

To avoid breaking existing uses of crt-static, whitelist targets that
support the new, stricter behavior. For all other targets, this changes
crt-static from being "mostly a no-op" to "explicitly a no-op".
This commit is contained in:
Samuel Holland 2017-08-22 16:24:29 -05:00
parent 3cb987862f
commit beb8abe9a5
5 changed files with 18 additions and 1 deletions

View file

@ -430,6 +430,15 @@ impl Session {
}
pub fn crt_static(&self) -> bool {
// If the target does not opt in to crt-static support, use its default.
if self.target.target.options.crt_static_respected {
self.crt_static_feature()
} else {
self.target.target.options.crt_static_default
}
}
pub fn crt_static_feature(&self) -> bool {
let requested_features = self.opts.cg.target_feature.split(',');
let found_negative = requested_features.clone().any(|r| r == "-crt-static");
let found_positive = requested_features.clone().any(|r| r == "+crt-static");

View file

@ -69,6 +69,8 @@ pub fn opts() -> TargetOptions {
// These targets statically link libc by default
base.crt_static_default = true;
// These targets allow the user to choose between static and dynamic linking.
base.crt_static_respected = true;
base
}

View file

@ -418,6 +418,8 @@ pub struct TargetOptions {
/// Whether or not the CRT is statically linked by default.
pub crt_static_default: bool,
/// Whether or not crt-static is respected by the compiler (or is a no-op).
pub crt_static_respected: bool,
/// Whether or not stack probes (__rust_probestack) are enabled
pub stack_probes: bool,
@ -479,6 +481,7 @@ impl Default for TargetOptions {
panic_strategy: PanicStrategy::Unwind,
abi_blacklist: vec![],
crt_static_default: false,
crt_static_respected: false,
stack_probes: false,
}
}
@ -715,6 +718,7 @@ impl Target {
key!(min_atomic_width, Option<u64>);
try!(key!(panic_strategy, PanicStrategy));
key!(crt_static_default, bool);
key!(crt_static_respected, bool);
key!(stack_probes, bool);
if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
@ -903,6 +907,7 @@ impl ToJson for Target {
target_option_val!(max_atomic_width);
target_option_val!(panic_strategy);
target_option_val!(crt_static_default);
target_option_val!(crt_static_respected);
target_option_val!(stack_probes);
if default.abi_blacklist != self.options.abi_blacklist {

View file

@ -63,6 +63,7 @@ pub fn opts() -> TargetOptions {
is_like_windows: true,
is_like_msvc: true,
pre_link_args: args,
crt_static_respected: true,
.. Default::default()
}

View file

@ -25,7 +25,7 @@ pub fn add_configuration(cfg: &mut ast::CrateConfig, sess: &Session) {
cfg.insert((tf, Some(feat)));
}
if sess.crt_static() {
if sess.crt_static_feature() {
cfg.insert((tf, Some(Symbol::intern("crt-static"))));
}
}