From 76f4cefb8a1402efd01d430cb14c8fce61c04b4a Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 29 Nov 2016 15:43:12 -0500 Subject: [PATCH 1/4] x86_64-musl: allow building dylibs with -crt-static --- src/librustc_back/target/linux_musl_base.rs | 2 +- src/librustc_trans/back/link.rs | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/librustc_back/target/linux_musl_base.rs b/src/librustc_back/target/linux_musl_base.rs index 18cca425a32c8..2f40df4dcf18c 100644 --- a/src/librustc_back/target/linux_musl_base.rs +++ b/src/librustc_back/target/linux_musl_base.rs @@ -62,7 +62,7 @@ pub fn opts() -> TargetOptions { // MUSL support doesn't currently include dynamic linking, so there's no // need for dylibs or rpath business. Additionally `-pie` is incompatible // with `-static`, so we can't pass `-pie`. - base.dynamic_linking = false; + base.dynamic_linking = true; base.has_rpath = false; base.position_independent_executables = false; diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 648dc4c24c9a6..43586dfbe9288 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -237,7 +237,16 @@ pub fn default_output_for_target(sess: &Session) -> config::CrateType { /// Checks if target supports crate_type as output pub fn invalid_output_for_target(sess: &Session, crate_type: config::CrateType) -> bool { - match (sess.target.target.options.dynamic_linking, + let requested_features = sess.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"); + let crt_static = if sess.target.target.options.crt_static_default { + !found_negative + } else { + found_positive + }; + + match (sess.target.target.options.dynamic_linking && !crt_static, sess.target.target.options.executables, crate_type) { (false, _, config::CrateTypeCdylib) | (false, _, config::CrateTypeProcMacro) | From f646a18d860d2fa2e0e3ad989eac9b378801700e Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 30 Nov 2016 12:48:37 -0500 Subject: [PATCH 2/4] enable PIE for dynamically linked executables, refactor crt_static logic --- src/librustc/session/mod.rs | 12 ++++++++ src/librustc_back/target/linux_musl_base.rs | 11 ++++--- src/librustc_trans/back/link.rs | 32 +++++++++++---------- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 3d8cfd199615e..bf39723aec24c 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -499,6 +499,18 @@ impl Session { println!("Total time spent computing symbol hashes: {}", duration_to_secs_str(self.perf_stats.symbol_hash_time.get())); } + + /// Checks if the target is going to be statically linked to the C runtime + pub fn target_is_crt_static(&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"); + if self.target.target.options.crt_static_default { + !found_negative + } else { + found_positive + } + } } pub fn build_session(sopts: config::Options, diff --git a/src/librustc_back/target/linux_musl_base.rs b/src/librustc_back/target/linux_musl_base.rs index 2f40df4dcf18c..5d45e1295ad64 100644 --- a/src/librustc_back/target/linux_musl_base.rs +++ b/src/librustc_back/target/linux_musl_base.rs @@ -55,16 +55,19 @@ pub fn opts() -> TargetOptions { // // Each target directory for musl has these object files included in it so // they'll be included from there. + // + // Note that when linking dynamically, these won't be passed to the linker base.pre_link_objects_exe.push("crt1.o".to_string()); base.pre_link_objects_exe.push("crti.o".to_string()); base.post_link_objects.push("crtn.o".to_string()); - // MUSL support doesn't currently include dynamic linking, so there's no - // need for dylibs or rpath business. Additionally `-pie` is incompatible - // with `-static`, so we can't pass `-pie`. + // Dynamically linking to MUSL is opt-in (via the -crt-static target + // feature). The `true`s here are not ultimate and depend on whether one is + // actually linking to MUSL dynamically. base.dynamic_linking = true; base.has_rpath = false; - base.position_independent_executables = false; + // actually only true if linking dynamically + base.position_independent_executables = true; // These targets statically link libc by default base.crt_static_default = true; diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 43586dfbe9288..3c0e63f4edc7c 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -237,16 +237,7 @@ pub fn default_output_for_target(sess: &Session) -> config::CrateType { /// Checks if target supports crate_type as output pub fn invalid_output_for_target(sess: &Session, crate_type: config::CrateType) -> bool { - let requested_features = sess.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"); - let crt_static = if sess.target.target.options.crt_static_default { - !found_negative - } else { - found_positive - }; - - match (sess.target.target.options.dynamic_linking && !crt_static, + match (sess.target.target.options.dynamic_linking && !sess.target_is_crt_static(), sess.target.target.options.executables, crate_type) { (false, _, config::CrateTypeCdylib) | (false, _, config::CrateTypeProcMacro) | @@ -677,6 +668,9 @@ fn link_natively(sess: &Session, let (pname, mut cmd, extra) = get_linker(sess); cmd.env("PATH", command_path(sess, extra)); + let musl = sess.target.target.llvm_target.contains("musl"); + let crt_static = sess.target_is_crt_static(); + let root = sess.target_filesearch(PathKind::Native).get_lib_path(); cmd.args(&sess.target.target.options.pre_link_args); @@ -685,8 +679,12 @@ fn link_natively(sess: &Session, } else { &sess.target.target.options.pre_link_objects_dll }; - for obj in pre_link_objects { - cmd.arg(root.join(obj)); + // When dynamically linking to MUSL we don't need to pass our startup + // objects as those will be provided by the MUSL toolchain + if !musl || crt_static { + for obj in pre_link_objects { + cmd.arg(root.join(obj)); + } } { @@ -695,8 +693,11 @@ fn link_natively(sess: &Session, objects, out_filename, outputs, trans); } cmd.args(&sess.target.target.options.late_link_args); - for obj in &sess.target.target.options.post_link_objects { - cmd.arg(root.join(obj)); + // Same as above + if !musl || crt_static { + for obj in &sess.target.target.options.post_link_objects { + cmd.arg(root.join(obj)); + } } cmd.args(&sess.target.target.options.post_link_args); @@ -822,8 +823,9 @@ fn link_args(cmd: &mut Linker, let mut args = args.iter().chain(more_args.iter()).chain(used_link_args.iter()); let relocation_model = sess.opts.cg.relocation_model.as_ref() .unwrap_or(&empty_str); + let crt_static = sess.target_is_crt_static(); if (t.options.relocation_model == "pic" || *relocation_model == "pic") - && !args.any(|x| *x == "-static") { + && !args.any(|x| *x == "-static") && !crt_static { cmd.position_independent_executable(); } } From 57b323c464559ff450bf2ad501e0d5815b149dd4 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 30 Nov 2016 12:55:52 -0500 Subject: [PATCH 3/4] DRY more --- src/librustc/session/mod.rs | 15 +++++++++++++++ src/librustc_driver/target_features.rs | 26 +------------------------- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index bf39723aec24c..89ab1e5d0aecf 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -503,8 +503,23 @@ impl Session { /// Checks if the target is going to be statically linked to the C runtime pub fn target_is_crt_static(&self) -> bool { let requested_features = self.opts.cg.target_feature.split(','); + let unstable_options = sess.opts.debugging_opts.unstable_options; + let is_nightly = UnstableFeatures::from_environment().is_nightly_build(); let found_negative = requested_features.clone().any(|r| r == "-crt-static"); let found_positive = requested_features.clone().any(|r| r == "+crt-static"); + + // If we switched from the default then that's only allowed on nightly, so + // gate that here. + if (found_positive || found_negative) && (!is_nightly || !unstable_options) { + sess.fatal("specifying the `crt-static` target feature is only allowed \ + on the nightly channel with `-Z unstable-options` passed \ + as well"); + } + + // If the target we're compiling for requests a static crt by default, + // then see if the `-crt-static` feature was passed to disable that. + // Otherwise if we don't have a static crt by default then see if the + // `+crt-static` feature was passed. if self.target.target.options.crt_static_default { !found_negative } else { diff --git a/src/librustc_driver/target_features.rs b/src/librustc_driver/target_features.rs index 876323d599e85..2ffa561fc5b1e 100644 --- a/src/librustc_driver/target_features.rs +++ b/src/librustc_driver/target_features.rs @@ -48,31 +48,7 @@ pub fn add_configuration(cfg: &mut ast::CrateConfig, sess: &Session) { } } - let requested_features = sess.opts.cg.target_feature.split(','); - let unstable_options = sess.opts.debugging_opts.unstable_options; - let is_nightly = UnstableFeatures::from_environment().is_nightly_build(); - let found_negative = requested_features.clone().any(|r| r == "-crt-static"); - let found_positive = requested_features.clone().any(|r| r == "+crt-static"); - - // If the target we're compiling for requests a static crt by default, - // then see if the `-crt-static` feature was passed to disable that. - // Otherwise if we don't have a static crt by default then see if the - // `+crt-static` feature was passed. - let crt_static = if sess.target.target.options.crt_static_default { - !found_negative - } else { - found_positive - }; - - // If we switched from the default then that's only allowed on nightly, so - // gate that here. - if (found_positive || found_negative) && (!is_nightly || !unstable_options) { - sess.fatal("specifying the `crt-static` target feature is only allowed \ - on the nightly channel with `-Z unstable-options` passed \ - as well"); - } - - if crt_static { + if sess.target_is_crt_static() { cfg.insert((tf, Some(Symbol::intern("crt-static")))); } } From a81e2b5fabe2e0f3da38f3f791fb316efd0a154a Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 30 Nov 2016 13:32:03 -0500 Subject: [PATCH 4/4] compilation fixes --- src/librustc/session/mod.rs | 5 +++-- src/librustc_driver/target_features.rs | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 89ab1e5d0aecf..0c7f3c4f6f311 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -35,6 +35,7 @@ use syntax::symbol::Symbol; use syntax::{ast, codemap}; use syntax::feature_gate::AttributeType; use syntax_pos::{Span, MultiSpan}; +use syntax::feature_gate::UnstableFeatures; use rustc_back::PanicStrategy; use rustc_back::target::Target; @@ -503,7 +504,7 @@ impl Session { /// Checks if the target is going to be statically linked to the C runtime pub fn target_is_crt_static(&self) -> bool { let requested_features = self.opts.cg.target_feature.split(','); - let unstable_options = sess.opts.debugging_opts.unstable_options; + let unstable_options = self.opts.debugging_opts.unstable_options; let is_nightly = UnstableFeatures::from_environment().is_nightly_build(); let found_negative = requested_features.clone().any(|r| r == "-crt-static"); let found_positive = requested_features.clone().any(|r| r == "+crt-static"); @@ -511,7 +512,7 @@ impl Session { // If we switched from the default then that's only allowed on nightly, so // gate that here. if (found_positive || found_negative) && (!is_nightly || !unstable_options) { - sess.fatal("specifying the `crt-static` target feature is only allowed \ + self.fatal("specifying the `crt-static` target feature is only allowed \ on the nightly channel with `-Z unstable-options` passed \ as well"); } diff --git a/src/librustc_driver/target_features.rs b/src/librustc_driver/target_features.rs index 2ffa561fc5b1e..80a2fce9ed15e 100644 --- a/src/librustc_driver/target_features.rs +++ b/src/librustc_driver/target_features.rs @@ -12,7 +12,6 @@ use syntax::ast; use llvm::LLVMRustHasFeature; use rustc::session::Session; use rustc_trans::back::write::create_target_machine; -use syntax::feature_gate::UnstableFeatures; use syntax::symbol::Symbol; use libc::c_char;