diff options
Diffstat (limited to 'testing/rust/musl-support-dynamic-linking.patch')
-rw-r--r-- | testing/rust/musl-support-dynamic-linking.patch | 363 |
1 files changed, 363 insertions, 0 deletions
diff --git a/testing/rust/musl-support-dynamic-linking.patch b/testing/rust/musl-support-dynamic-linking.patch new file mode 100644 index 0000000000..7c4e93681b --- /dev/null +++ b/testing/rust/musl-support-dynamic-linking.patch @@ -0,0 +1,363 @@ +From 3abd1f5e2f31b1c95535ef8c3b4bef6ff78b3fa9 Mon Sep 17 00:00:00 2001 +From: Samuel Holland <samuel@sholland.org> +From: Shiz <hi@shiz.me> +Date: Wed, 12 Apr 2017 22:31:06 +0200 +Subject: [PATCH] Support dynamically-linked and/or native musl targets + +These changes allow native compilation on musl-based distributions and the +use of dynamic libraries on linux-musl targets. This is intended to remove +limitations based on past assumptions about musl targets, while +maintaining existing behavior by default. + +Upstream-Issue: https://github.com/rust-lang/rust/pull/40113 +See-Also: https://internals.rust-lang.org/t/refining-cross-platform-crt-static-semantics/5085 + +diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs +index 90fd31ecbd..28520a2c60 100644 +--- a/src/bootstrap/bin/rustc.rs ++++ b/src/bootstrap/bin/rustc.rs +@@ -205,6 +205,17 @@ fn main() { + } + } + } ++ ++ if let Ok(s) = env::var("RUST_CRT_STATIC") { ++ if s == "true" { ++ cmd.arg("-Z").arg("unstable-options"); ++ cmd.arg("-C").arg("target-feature=+crt-static"); ++ } ++ if s == "false" { ++ cmd.arg("-Z").arg("unstable-options"); ++ cmd.arg("-C").arg("target-feature=-crt-static"); ++ } ++ } + } + + if verbose > 1 { +diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs +index 7c35151a6d..c83b6cc24c 100644 +--- a/src/bootstrap/compile.rs ++++ b/src/bootstrap/compile.rs +@@ -94,14 +94,17 @@ pub fn std_link(build: &Build, + t!(fs::create_dir_all(&libdir)); + add_to_sysroot(&out_dir, &libdir); + +- if target.contains("musl") && !target.contains("mips") { ++ if target.contains("musl") { + copy_musl_third_party_objects(build, target, &libdir); + } + } + + /// Copies the crt(1,i,n).o startup objects + /// +-/// Only required for musl targets that statically link to libc ++/// Since musl supports fully static linking, we can cross link for it even ++/// with a glibc-targeting toolchain, given we have the appropriate startup ++/// files. As those shipped with glibc won't work, copy the ones provided by ++/// musl so we have them on linux-gnu hosts. + fn copy_musl_third_party_objects(build: &Build, target: &str, into: &Path) { + for &obj in &["crt1.o", "crti.o", "crtn.o"] { + copy(&build.musl_root(target).unwrap().join("lib").join(obj), &into.join(obj)); +diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs +index 6e077691b3..8d9be38959 100644 +--- a/src/bootstrap/config.rs ++++ b/src/bootstrap/config.rs +@@ -113,6 +113,7 @@ pub struct Target { + pub cc: Option<PathBuf>, + pub cxx: Option<PathBuf>, + pub ndk: Option<PathBuf>, ++ pub crt_static: Option<bool>, + pub musl_root: Option<PathBuf>, + } + +@@ -221,6 +222,7 @@ struct TomlTarget { + cc: Option<String>, + cxx: Option<String>, + android_ndk: Option<String>, ++ crt_static: Option<bool>, + musl_root: Option<String>, + } + +@@ -359,6 +361,7 @@ impl Config { + } + target.cxx = cfg.cxx.clone().map(PathBuf::from); + target.cc = cfg.cc.clone().map(PathBuf::from); ++ target.crt_static = cfg.crt_static.clone(); + target.musl_root = cfg.musl_root.clone().map(PathBuf::from); + + config.target_config.insert(triple.clone(), target); +diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs +index c98dd4751f..e7ee9511d8 100644 +--- a/src/bootstrap/lib.rs ++++ b/src/bootstrap/lib.rs +@@ -500,6 +500,10 @@ impl Build { + .env("RUSTDOC_REAL", self.rustdoc(compiler)) + .env("RUSTC_FLAGS", self.rustc_flags(target).join(" ")); + ++ if let Some(x) = self.crt_static(target) { ++ cargo.env("RUST_CRT_STATIC", x.to_string()); ++ } ++ + // Enable usage of unstable features + cargo.env("RUSTC_BOOTSTRAP", "1"); + self.add_rust_test_threads(&mut cargo); +@@ -883,6 +887,16 @@ impl Build { + return base + } + ++ /// Returns if this target should statically link the C runtime, if specified ++ fn crt_static(&self, target: &str) -> Option<bool> { ++ if target.contains("pc-windows-msvc") { ++ Some(true) ++ } else { ++ self.config.target_config.get(target) ++ .and_then(|t| t.crt_static) ++ } ++ } ++ + /// Returns the "musl root" for this `target`, if defined + fn musl_root(&self, target: &str) -> Option<&Path> { + self.config.target_config.get(target) +diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs +index bc439d6f78..3ee1113516 100644 +--- a/src/bootstrap/sanity.rs ++++ b/src/bootstrap/sanity.rs +@@ -157,8 +157,15 @@ pub fn check(build: &mut Build) { + panic!("the iOS target is only supported on OSX"); + } + +- // Make sure musl-root is valid if specified +- if target.contains("musl") && !target.contains("mips") { ++ // Make sure musl-root is valid ++ if target.contains("musl") { ++ // If this is a native target (host is also musl) and no musl-root is given, ++ // fall back to the system toolchain in /usr before giving up ++ if build.musl_root(target).is_none() && build.config.build == *target { ++ let target = build.config.target_config.entry(target.clone()) ++ .or_insert(Default::default()); ++ target.musl_root = Some("/usr".into()); ++ } + match build.musl_root(target) { + Some(root) => { + if fs::metadata(root.join("lib/libc.a")).is_err() { +diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs +index 36a887e062..1075e4f0cf 100644 +--- a/src/librustc/session/mod.rs ++++ b/src/librustc/session/mod.rs +@@ -34,6 +34,7 @@ use syntax::parse::ParseSess; + use syntax::symbol::Symbol; + use syntax::{ast, codemap}; + use syntax::feature_gate::AttributeType; ++use syntax::feature_gate::UnstableFeatures; + use syntax_pos::{Span, MultiSpan}; + + use rustc_back::PanicStrategy; +@@ -380,6 +381,34 @@ impl Session { + self.opts.debugging_opts.enable_nonzeroing_move_hints + } + ++ pub fn crt_static(&self) -> bool { ++ let requested_features = self.opts.cg.target_feature.split(','); ++ 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"); ++ ++ // 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 self.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) { ++ self.fatal("specifying the `crt-static` target feature is only allowed \ ++ on the nightly channel with `-Z unstable-options` passed \ ++ as well"); ++ } ++ ++ return crt_static; ++ } ++ + pub fn must_not_eliminate_frame_pointers(&self) -> bool { + self.opts.debuginfo != DebugInfoLevel::NoDebugInfo || + !self.target.target.options.eliminate_frame_pointer +diff --git a/src/librustc_back/target/linux_musl_base.rs b/src/librustc_back/target/linux_musl_base.rs +index 18cca425a3..076bbe7193 100644 +--- a/src/librustc_back/target/linux_musl_base.rs ++++ b/src/librustc_back/target/linux_musl_base.rs +@@ -59,14 +59,7 @@ pub fn opts() -> TargetOptions { + 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`. +- base.dynamic_linking = false; +- base.has_rpath = false; +- base.position_independent_executables = false; +- +- // These targets statically link libc by default ++ // Except for on MIPS, these targets statically link libc by default. + base.crt_static_default = true; + + base +diff --git a/src/librustc_back/target/mips_unknown_linux_musl.rs b/src/librustc_back/target/mips_unknown_linux_musl.rs +index e4a6d2a55d..77fcf9770d 100644 +--- a/src/librustc_back/target/mips_unknown_linux_musl.rs ++++ b/src/librustc_back/target/mips_unknown_linux_musl.rs +@@ -25,6 +25,7 @@ pub fn target() -> TargetResult { + features: "+mips32r2,+soft-float".to_string(), + max_atomic_width: Some(32), + ++ crt_static_default: false, + // see #36994 + exe_allocation_crate: "alloc_system".to_string(), + +diff --git a/src/librustc_back/target/mipsel_unknown_linux_musl.rs b/src/librustc_back/target/mipsel_unknown_linux_musl.rs +index 5693bddd04..6339e719e1 100644 +--- a/src/librustc_back/target/mipsel_unknown_linux_musl.rs ++++ b/src/librustc_back/target/mipsel_unknown_linux_musl.rs +@@ -25,6 +25,7 @@ pub fn target() -> TargetResult { + features: "+mips32,+soft-float".to_string(), + max_atomic_width: Some(32), + ++ crt_static_default: false, + // see #36994 + exe_allocation_crate: "alloc_system".to_string(), + +diff --git a/src/librustc_driver/target_features.rs b/src/librustc_driver/target_features.rs +index 124e7aafcc..492ceecaf1 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; + +@@ -49,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.crt_static() { + cfg.insert((tf, Some(Symbol::intern("crt-static")))); + } + } +diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs +index defbb44448..f10c7d5c83 100644 +--- a/src/librustc_trans/back/link.rs ++++ b/src/librustc_trans/back/link.rs +@@ -703,13 +703,15 @@ fn link_natively(sess: &Session, + let root = sess.target_filesearch(PathKind::Native).get_lib_path(); + cmd.args(&sess.target.target.options.pre_link_args); + +- let pre_link_objects = if crate_type == config::CrateTypeExecutable { +- &sess.target.target.options.pre_link_objects_exe +- } else { +- &sess.target.target.options.pre_link_objects_dll +- }; +- for obj in pre_link_objects { +- cmd.arg(root.join(obj)); ++ if sess.crt_static() { ++ let pre_link_objects = if crate_type == config::CrateTypeExecutable { ++ &sess.target.target.options.pre_link_objects_exe ++ } else { ++ &sess.target.target.options.pre_link_objects_dll ++ }; ++ for obj in pre_link_objects { ++ cmd.arg(root.join(obj)); ++ } + } + + { +@@ -718,8 +720,10 @@ 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)); ++ if sess.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); + +diff --git a/src/libstd/build.rs b/src/libstd/build.rs +index 9504194393..dd2008c206 100644 +--- a/src/libstd/build.rs ++++ b/src/libstd/build.rs +@@ -35,7 +35,7 @@ fn main() { + println!("cargo:rustc-link-lib=dl"); + println!("cargo:rustc-link-lib=log"); + println!("cargo:rustc-link-lib=gcc"); +- } else if !target.contains("musl") || target.contains("mips") { ++ } else if !target.contains("musl") { + println!("cargo:rustc-link-lib=dl"); + println!("cargo:rustc-link-lib=rt"); + println!("cargo:rustc-link-lib=pthread"); +diff --git a/src/libunwind/build.rs b/src/libunwind/build.rs +index db41a368a1..b1a86f04ef 100644 +--- a/src/libunwind/build.rs ++++ b/src/libunwind/build.rs +@@ -16,8 +16,8 @@ fn main() { + let target = env::var("TARGET").expect("TARGET was not set"); + + if target.contains("linux") { +- if target.contains("musl") && !target.contains("mips") { +- println!("cargo:rustc-link-lib=static=unwind"); ++ if target.contains("musl") { ++ println!("cargo:rustc-link-lib=unwind"); + } else if !target.contains("android") { + println!("cargo:rustc-link-lib=gcc_s"); + } +diff --git a/src/liblibc/src/unix/mod.rs b/src/liblibc/src/unix/mod.rs +--- a/src/liblibc/src/unix/mod.rs ++++ b/src/liblibc/src/unix/mod.rs +@@ -210,8 +210,7 @@ cfg_if! { + // cargo build, don't pull in anything extra as the libstd dep + // already pulls in all libs. +- } else if #[cfg(any(all(target_env = "musl", not(target_arch = "mips"))))] { ++ } else if #[cfg(target_env = "musl")] { +- #[link(name = "c", kind = "static", cfg(target_feature = "crt-static"))] +- #[link(name = "c", cfg(not(target_feature = "crt-static")))] ++ #[link(name = "c")] + extern {} + } else if #[cfg(target_os = "emscripten")] { + #[link(name = "c")] +-- +2.12.2 + |