Auto merge of #77386 - joshtriplett:static-glibc, r=petrochenkov

Support static linking with glibc and target-feature=+crt-static

With this change, it's possible to build on a linux-gnu target and pass
RUSTFLAGS='-C target-feature=+crt-static' or the equivalent via a
`.cargo/config.toml` file, and get a statically linked executable.

Update to libc 0.2.78, which adds support for static linking with glibc.

Add `crt_static_respected` to the `linux_base` target spec.

Update `android_base` and `linux_musl_base` accordingly. Avoid enabling
crt_static_respected on Android platforms, since that hasn't been
tested.

Closes https://github.com/rust-lang/rust/issues/65447.
This commit is contained in:
bors 2020-10-06 21:11:04 +00:00
commit 98edd1fbf8
9 changed files with 17 additions and 32 deletions

View File

@ -1660,9 +1660,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.77"
version = "0.2.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235"
checksum = "2448f6066e80e3bfc792e9c98bf705b4b0fc6e8ef5b43e5889aff0eaa9c58743"
dependencies = [
"rustc-std-workspace-core",
]

View File

@ -12,5 +12,6 @@ pub fn opts() -> TargetOptions {
base.position_independent_executables = true;
base.has_elf_tls = false;
base.requires_uwtable = true;
base.crt_static_respected = false;
base
}

View File

@ -28,6 +28,7 @@ pub fn opts() -> TargetOptions {
position_independent_executables: true,
relro_level: RelroLevel::Full,
has_elf_tls: true,
crt_static_respected: true,
..Default::default()
}
}

View File

@ -10,8 +10,6 @@ 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

@ -16,7 +16,7 @@ cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] }
panic_unwind = { path = "../panic_unwind", optional = true }
panic_abort = { path = "../panic_abort" }
core = { path = "../core" }
libc = { version = "0.2.77", default-features = false, features = ['rustc-dep-of-std'] }
libc = { version = "0.2.79", default-features = false, features = ['rustc-dep-of-std'] }
compiler_builtins = { version = "0.1.35" }
profiler_builtins = { path = "../profiler_builtins", optional = true }
unwind = { path = "../unwind" }

View File

@ -461,15 +461,7 @@ impl ExitStatus {
}
fn exited(&self) -> bool {
// On Linux-like OSes this function is safe, on others it is not. See
// libc issue: https://github.com/rust-lang/libc/issues/1888.
#[cfg_attr(
any(target_os = "linux", target_os = "android", target_os = "emscripten"),
allow(unused_unsafe)
)]
unsafe {
libc::WIFEXITED(self.0)
}
libc::WIFEXITED(self.0)
}
pub fn success(&self) -> bool {
@ -477,23 +469,11 @@ impl ExitStatus {
}
pub fn code(&self) -> Option<i32> {
// On Linux-like OSes this function is safe, on others it is not. See
// libc issue: https://github.com/rust-lang/libc/issues/1888.
#[cfg_attr(
any(target_os = "linux", target_os = "android", target_os = "emscripten"),
allow(unused_unsafe)
)]
if self.exited() { Some(unsafe { libc::WEXITSTATUS(self.0) }) } else { None }
if self.exited() { Some(libc::WEXITSTATUS(self.0)) } else { None }
}
pub fn signal(&self) -> Option<i32> {
// On Linux-like OSes this function is safe, on others it is not. See
// libc issue: https://github.com/rust-lang/libc/issues/1888.
#[cfg_attr(
any(target_os = "linux", target_os = "android", target_os = "emscripten"),
allow(unused_unsafe)
)]
if !self.exited() { Some(unsafe { libc::WTERMSIG(self.0) }) } else { None }
if !self.exited() { Some(libc::WTERMSIG(self.0)) } else { None }
}
}

View File

@ -14,7 +14,7 @@ doc = false
[dependencies]
core = { path = "../core" }
libc = { version = "0.2.51", features = ['rustc-dep-of-std'], default-features = false }
libc = { version = "0.2.79", features = ['rustc-dep-of-std'], default-features = false }
compiler_builtins = "0.1.0"
cfg-if = "0.1.8"

View File

@ -12,11 +12,9 @@ fn main() {
} else if target.contains("x86_64-fortanix-unknown-sgx") {
llvm_libunwind::compile();
} else if target.contains("linux") {
// linking for Linux is handled in lib.rs
if target.contains("musl") {
// linking for musl is handled in lib.rs
llvm_libunwind::compile();
} else if !target.contains("android") {
println!("cargo:rustc-link-lib=gcc_s");
}
} else if target.contains("freebsd") {
println!("cargo:rustc-link-lib=gcc_s");

View File

@ -42,6 +42,13 @@ cfg_if::cfg_if! {
#[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
extern "C" {}
// When building with crt-static, we get `gcc_eh` from the `libc` crate, since
// glibc needs it, and needs it listed later on the linker command line. We
// don't want to duplicate it here.
#[cfg(all(target_os = "linux", target_env = "gnu", not(feature = "llvm-libunwind")))]
#[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
extern "C" {}
#[cfg(target_os = "redox")]
#[link(name = "gcc_eh", kind = "static-nobundle", cfg(target_feature = "crt-static"))]
#[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]