From 12ceed013cdbd5d431a6908d49b2b6cb6fe1d032 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Tue, 22 Aug 2017 16:24:29 -0500 Subject: [PATCH] Introduce target feature crt_static_allows_dylibs Most UNIX-like platforms do not allow shared libraries to statically link their own libc, as libc expects to have consistent process-global state. On those platforms, when we do not have a shared libc available, we must not attempt to link dylibs or cdylibs. On Windows, however, it is expected to statically link the CRT into dynamic libraries. This feature is only relevant for targets that support both fully-static and fully-dynamic linkage, such as musl on Linux. --- src/librustc_back/target/mod.rs | 5 +++++ src/librustc_back/target/windows_msvc_base.rs | 1 + src/librustc_trans_utils/link.rs | 7 +++++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index 0ff633ffe377..130e1b695dbd 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -416,6 +416,8 @@ pub struct TargetOptions { /// ABIs are considered to be supported on all platforms and cannot be blacklisted. pub abi_blacklist: Vec, + /// Whether or not linking dylibs to a static CRT is allowed. + pub crt_static_allows_dylibs: bool, /// 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). @@ -480,6 +482,7 @@ impl Default for TargetOptions { max_atomic_width: None, panic_strategy: PanicStrategy::Unwind, abi_blacklist: vec![], + crt_static_allows_dylibs: false, crt_static_default: false, crt_static_respected: false, stack_probes: false, @@ -717,6 +720,7 @@ impl Target { key!(max_atomic_width, Option); key!(min_atomic_width, Option); try!(key!(panic_strategy, PanicStrategy)); + key!(crt_static_allows_dylibs, bool); key!(crt_static_default, bool); key!(crt_static_respected, bool); key!(stack_probes, bool); @@ -906,6 +910,7 @@ impl ToJson for Target { target_option_val!(min_atomic_width); target_option_val!(max_atomic_width); target_option_val!(panic_strategy); + target_option_val!(crt_static_allows_dylibs); target_option_val!(crt_static_default); target_option_val!(crt_static_respected); target_option_val!(stack_probes); diff --git a/src/librustc_back/target/windows_msvc_base.rs b/src/librustc_back/target/windows_msvc_base.rs index f44a9b44426d..42a4e6f5f118 100644 --- a/src/librustc_back/target/windows_msvc_base.rs +++ b/src/librustc_back/target/windows_msvc_base.rs @@ -63,6 +63,7 @@ pub fn opts() -> TargetOptions { is_like_windows: true, is_like_msvc: true, pre_link_args: args, + crt_static_allows_dylibs: true, crt_static_respected: true, .. Default::default() diff --git a/src/librustc_trans_utils/link.rs b/src/librustc_trans_utils/link.rs index 264158f0de9e..aa8637fabe85 100644 --- a/src/librustc_trans_utils/link.rs +++ b/src/librustc_trans_utils/link.rs @@ -123,8 +123,11 @@ pub fn invalid_output_for_target(sess: &Session, match (sess.target.target.options.dynamic_linking, sess.target.target.options.executables, crate_type) { (false, _, config::CrateTypeCdylib) | - (false, _, config::CrateTypeProcMacro) | - (false, _, config::CrateTypeDylib) => true, + (false, _, config::CrateTypeDylib) | + (false, _, config::CrateTypeProcMacro) => true, + (true, _, config::CrateTypeCdylib) | + (true, _, config::CrateTypeDylib) => sess.crt_static() && + !sess.target.target.options.crt_static_allows_dylibs, (_, false, config::CrateTypeExecutable) => true, _ => false }