mirror of
https://gitlab.alpinelinux.org/alpine/aports.git
synced 2025-07-25 20:25:28 +03:00
363 lines
15 KiB
Diff
363 lines
15 KiB
Diff
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
|
|
|