Auto merge of #40113 - smaeul:native-musl, r=alexcrichton
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. A minor related bugfix is included.
This commit is contained in:
commit
a3f0ee9a7b
20 changed files with 133 additions and 48 deletions
|
@ -292,6 +292,12 @@
|
||||||
# build native code.
|
# build native code.
|
||||||
#android-ndk = "/path/to/ndk"
|
#android-ndk = "/path/to/ndk"
|
||||||
|
|
||||||
|
# Force static or dynamic linkage of the standard library for this target. If
|
||||||
|
# this target is a host for rustc, this will also affect the linkage of the
|
||||||
|
# compiler itself. This is useful for building rustc on targets that normally
|
||||||
|
# only use static libraries. If unset, the target's default linkage is used.
|
||||||
|
#crt-static = false
|
||||||
|
|
||||||
# The root location of the MUSL installation directory. The library directory
|
# The root location of the MUSL installation directory. The library directory
|
||||||
# will also need to contain libunwind.a for an unwinding implementation. Note
|
# will also need to contain libunwind.a for an unwinding implementation. Note
|
||||||
# that this option only makes sense for MUSL targets that produce statically
|
# that this option only makes sense for MUSL targets that produce statically
|
||||||
|
|
|
@ -237,9 +237,13 @@ fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if target.contains("pc-windows-msvc") {
|
if let Ok(s) = env::var("RUSTC_CRT_STATIC") {
|
||||||
cmd.arg("-Z").arg("unstable-options");
|
if s == "true" {
|
||||||
cmd.arg("-C").arg("target-feature=+crt-static");
|
cmd.arg("-C").arg("target-feature=+crt-static");
|
||||||
|
}
|
||||||
|
if s == "false" {
|
||||||
|
cmd.arg("-C").arg("target-feature=-crt-static");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force all crates compiled by this compiler to (a) be unstable and (b)
|
// Force all crates compiled by this compiler to (a) be unstable and (b)
|
||||||
|
|
|
@ -503,6 +503,10 @@ impl<'a> Builder<'a> {
|
||||||
cargo.env("RUSTC_METADATA_SUFFIX", "rustc");
|
cargo.env("RUSTC_METADATA_SUFFIX", "rustc");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(x) = self.crt_static(target) {
|
||||||
|
cargo.env("RUSTC_CRT_STATIC", x.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
// Enable usage of unstable features
|
// Enable usage of unstable features
|
||||||
cargo.env("RUSTC_BOOTSTRAP", "1");
|
cargo.env("RUSTC_BOOTSTRAP", "1");
|
||||||
self.add_rust_test_threads(&mut cargo);
|
self.add_rust_test_threads(&mut cargo);
|
||||||
|
|
|
@ -77,6 +77,14 @@ impl Step for Std {
|
||||||
target,
|
target,
|
||||||
});
|
});
|
||||||
println!("Uplifting stage1 std ({} -> {})", from.host, target);
|
println!("Uplifting stage1 std ({} -> {})", from.host, target);
|
||||||
|
|
||||||
|
// Even if we're not building std this stage, the new sysroot must
|
||||||
|
// still contain the musl startup objects.
|
||||||
|
if target.contains("musl") && !target.contains("mips") {
|
||||||
|
let libdir = builder.sysroot_libdir(compiler, target);
|
||||||
|
copy_musl_third_party_objects(build, target, &libdir);
|
||||||
|
}
|
||||||
|
|
||||||
builder.ensure(StdLink {
|
builder.ensure(StdLink {
|
||||||
compiler: from,
|
compiler: from,
|
||||||
target_compiler: compiler,
|
target_compiler: compiler,
|
||||||
|
@ -89,6 +97,11 @@ impl Step for Std {
|
||||||
println!("Building stage{} std artifacts ({} -> {})", compiler.stage,
|
println!("Building stage{} std artifacts ({} -> {})", compiler.stage,
|
||||||
&compiler.host, target);
|
&compiler.host, target);
|
||||||
|
|
||||||
|
if target.contains("musl") && !target.contains("mips") {
|
||||||
|
let libdir = builder.sysroot_libdir(compiler, target);
|
||||||
|
copy_musl_third_party_objects(build, target, &libdir);
|
||||||
|
}
|
||||||
|
|
||||||
let out_dir = build.cargo_out(compiler, Mode::Libstd, target);
|
let out_dir = build.cargo_out(compiler, Mode::Libstd, target);
|
||||||
build.clear_if_dirty(&out_dir, &builder.rustc(compiler));
|
build.clear_if_dirty(&out_dir, &builder.rustc(compiler));
|
||||||
let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "build");
|
let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "build");
|
||||||
|
@ -105,6 +118,20 @@ impl Step for Std {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Copies the crt(1,i,n).o startup objects
|
||||||
|
///
|
||||||
|
/// 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: Interned<String>,
|
||||||
|
into: &Path) {
|
||||||
|
for &obj in &["crt1.o", "crti.o", "crtn.o"] {
|
||||||
|
copy(&build.musl_root(target).unwrap().join("lib").join(obj), &into.join(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Configure cargo to compile the standard library, adding appropriate env vars
|
/// Configure cargo to compile the standard library, adding appropriate env vars
|
||||||
/// and such.
|
/// and such.
|
||||||
pub fn std_cargo(build: &Build,
|
pub fn std_cargo(build: &Build,
|
||||||
|
@ -189,10 +216,6 @@ impl Step for StdLink {
|
||||||
let libdir = builder.sysroot_libdir(target_compiler, target);
|
let libdir = builder.sysroot_libdir(target_compiler, target);
|
||||||
add_to_sysroot(&libdir, &libstd_stamp(build, compiler, target));
|
add_to_sysroot(&libdir, &libstd_stamp(build, compiler, target));
|
||||||
|
|
||||||
if target.contains("musl") && !target.contains("mips") {
|
|
||||||
copy_musl_third_party_objects(build, target, &libdir);
|
|
||||||
}
|
|
||||||
|
|
||||||
if build.config.sanitizers && compiler.stage != 0 && target == "x86_64-apple-darwin" {
|
if build.config.sanitizers && compiler.stage != 0 && target == "x86_64-apple-darwin" {
|
||||||
// The sanitizers are only built in stage1 or above, so the dylibs will
|
// The sanitizers are only built in stage1 or above, so the dylibs will
|
||||||
// be missing in stage0 and causes panic. See the `std()` function above
|
// be missing in stage0 and causes panic. See the `std()` function above
|
||||||
|
@ -208,15 +231,6 @@ impl Step for StdLink {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Copies the crt(1,i,n).o startup objects
|
|
||||||
///
|
|
||||||
/// Only required for musl targets that statically link to libc
|
|
||||||
fn copy_musl_third_party_objects(build: &Build, target: Interned<String>, into: &Path) {
|
|
||||||
for &obj in &["crt1.o", "crti.o", "crtn.o"] {
|
|
||||||
copy(&build.musl_root(target).unwrap().join("lib").join(obj), &into.join(obj));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn copy_apple_sanitizer_dylibs(native_dir: &Path, platform: &str, into: &Path) {
|
fn copy_apple_sanitizer_dylibs(native_dir: &Path, platform: &str, into: &Path) {
|
||||||
for &sanitizer in &["asan", "tsan"] {
|
for &sanitizer in &["asan", "tsan"] {
|
||||||
let filename = format!("libclang_rt.{}_{}_dynamic.dylib", sanitizer, platform);
|
let filename = format!("libclang_rt.{}_{}_dynamic.dylib", sanitizer, platform);
|
||||||
|
|
|
@ -143,6 +143,7 @@ pub struct Target {
|
||||||
pub cc: Option<PathBuf>,
|
pub cc: Option<PathBuf>,
|
||||||
pub cxx: Option<PathBuf>,
|
pub cxx: Option<PathBuf>,
|
||||||
pub ndk: Option<PathBuf>,
|
pub ndk: Option<PathBuf>,
|
||||||
|
pub crt_static: Option<bool>,
|
||||||
pub musl_root: Option<PathBuf>,
|
pub musl_root: Option<PathBuf>,
|
||||||
pub qemu_rootfs: Option<PathBuf>,
|
pub qemu_rootfs: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
@ -275,6 +276,7 @@ struct TomlTarget {
|
||||||
cc: Option<String>,
|
cc: Option<String>,
|
||||||
cxx: Option<String>,
|
cxx: Option<String>,
|
||||||
android_ndk: Option<String>,
|
android_ndk: Option<String>,
|
||||||
|
crt_static: Option<bool>,
|
||||||
musl_root: Option<String>,
|
musl_root: Option<String>,
|
||||||
qemu_rootfs: Option<String>,
|
qemu_rootfs: Option<String>,
|
||||||
}
|
}
|
||||||
|
@ -446,6 +448,7 @@ impl Config {
|
||||||
}
|
}
|
||||||
target.cxx = cfg.cxx.clone().map(PathBuf::from);
|
target.cxx = cfg.cxx.clone().map(PathBuf::from);
|
||||||
target.cc = cfg.cc.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);
|
target.musl_root = cfg.musl_root.clone().map(PathBuf::from);
|
||||||
target.qemu_rootfs = cfg.qemu_rootfs.clone().map(PathBuf::from);
|
target.qemu_rootfs = cfg.qemu_rootfs.clone().map(PathBuf::from);
|
||||||
|
|
||||||
|
|
|
@ -656,6 +656,16 @@ impl Build {
|
||||||
base
|
base
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns if this target should statically link the C runtime, if specified
|
||||||
|
fn crt_static(&self, target: Interned<String>) -> 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
|
/// Returns the "musl root" for this `target`, if defined
|
||||||
fn musl_root(&self, target: Interned<String>) -> Option<&Path> {
|
fn musl_root(&self, target: Interned<String>) -> Option<&Path> {
|
||||||
self.config.target_config.get(&target)
|
self.config.target_config.get(&target)
|
||||||
|
|
|
@ -151,8 +151,15 @@ pub fn check(build: &mut Build) {
|
||||||
panic!("the iOS target is only supported on macOS");
|
panic!("the iOS target is only supported on macOS");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure musl-root is valid if specified
|
// Make sure musl-root is valid
|
||||||
if target.contains("musl") && !target.contains("mips") {
|
if target.contains("musl") && !target.contains("mips") {
|
||||||
|
// 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) {
|
match build.musl_root(*target) {
|
||||||
Some(root) => {
|
Some(root) => {
|
||||||
if fs::metadata(root.join("lib/libc.a")).is_err() {
|
if fs::metadata(root.join("lib/libc.a")).is_err() {
|
||||||
|
|
|
@ -429,6 +429,31 @@ impl Session {
|
||||||
.unwrap_or(self.opts.debug_assertions)
|
.unwrap_or(self.opts.debug_assertions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn crt_static(&self) -> bool {
|
||||||
|
// If the target does not opt in to crt-static support, use its default.
|
||||||
|
if self.target.target.options.crt_static_respected {
|
||||||
|
self.crt_static_feature()
|
||||||
|
} else {
|
||||||
|
self.target.target.options.crt_static_default
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn crt_static_feature(&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 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 {
|
||||||
|
found_positive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn must_not_eliminate_frame_pointers(&self) -> bool {
|
pub fn must_not_eliminate_frame_pointers(&self) -> bool {
|
||||||
self.opts.debuginfo != DebugInfoLevel::NoDebugInfo ||
|
self.opts.debuginfo != DebugInfoLevel::NoDebugInfo ||
|
||||||
!self.target.target.options.eliminate_frame_pointer
|
!self.target.target.options.eliminate_frame_pointer
|
||||||
|
|
|
@ -60,15 +60,10 @@ pub fn opts() -> TargetOptions {
|
||||||
base.pre_link_objects_exe.push("crti.o".to_string());
|
base.pre_link_objects_exe.push("crti.o".to_string());
|
||||||
base.post_link_objects.push("crtn.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
|
// These targets statically link libc by default
|
||||||
base.crt_static_default = true;
|
base.crt_static_default = true;
|
||||||
|
// These targets allow the user to choose between static and dynamic linking.
|
||||||
|
base.crt_static_respected = true;
|
||||||
|
|
||||||
base
|
base
|
||||||
}
|
}
|
||||||
|
|
|
@ -416,8 +416,12 @@ pub struct TargetOptions {
|
||||||
/// ABIs are considered to be supported on all platforms and cannot be blacklisted.
|
/// ABIs are considered to be supported on all platforms and cannot be blacklisted.
|
||||||
pub abi_blacklist: Vec<Abi>,
|
pub abi_blacklist: Vec<Abi>,
|
||||||
|
|
||||||
|
/// 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.
|
/// Whether or not the CRT is statically linked by default.
|
||||||
pub crt_static_default: bool,
|
pub crt_static_default: bool,
|
||||||
|
/// Whether or not crt-static is respected by the compiler (or is a no-op).
|
||||||
|
pub crt_static_respected: bool,
|
||||||
|
|
||||||
/// Whether or not stack probes (__rust_probestack) are enabled
|
/// Whether or not stack probes (__rust_probestack) are enabled
|
||||||
pub stack_probes: bool,
|
pub stack_probes: bool,
|
||||||
|
@ -478,7 +482,9 @@ impl Default for TargetOptions {
|
||||||
max_atomic_width: None,
|
max_atomic_width: None,
|
||||||
panic_strategy: PanicStrategy::Unwind,
|
panic_strategy: PanicStrategy::Unwind,
|
||||||
abi_blacklist: vec![],
|
abi_blacklist: vec![],
|
||||||
|
crt_static_allows_dylibs: false,
|
||||||
crt_static_default: false,
|
crt_static_default: false,
|
||||||
|
crt_static_respected: false,
|
||||||
stack_probes: false,
|
stack_probes: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -714,7 +720,9 @@ impl Target {
|
||||||
key!(max_atomic_width, Option<u64>);
|
key!(max_atomic_width, Option<u64>);
|
||||||
key!(min_atomic_width, Option<u64>);
|
key!(min_atomic_width, Option<u64>);
|
||||||
try!(key!(panic_strategy, PanicStrategy));
|
try!(key!(panic_strategy, PanicStrategy));
|
||||||
|
key!(crt_static_allows_dylibs, bool);
|
||||||
key!(crt_static_default, bool);
|
key!(crt_static_default, bool);
|
||||||
|
key!(crt_static_respected, bool);
|
||||||
key!(stack_probes, bool);
|
key!(stack_probes, bool);
|
||||||
|
|
||||||
if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
|
if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
|
||||||
|
@ -902,7 +910,9 @@ impl ToJson for Target {
|
||||||
target_option_val!(min_atomic_width);
|
target_option_val!(min_atomic_width);
|
||||||
target_option_val!(max_atomic_width);
|
target_option_val!(max_atomic_width);
|
||||||
target_option_val!(panic_strategy);
|
target_option_val!(panic_strategy);
|
||||||
|
target_option_val!(crt_static_allows_dylibs);
|
||||||
target_option_val!(crt_static_default);
|
target_option_val!(crt_static_default);
|
||||||
|
target_option_val!(crt_static_respected);
|
||||||
target_option_val!(stack_probes);
|
target_option_val!(stack_probes);
|
||||||
|
|
||||||
if default.abi_blacklist != self.options.abi_blacklist {
|
if default.abi_blacklist != self.options.abi_blacklist {
|
||||||
|
|
|
@ -63,6 +63,8 @@ pub fn opts() -> TargetOptions {
|
||||||
is_like_windows: true,
|
is_like_windows: true,
|
||||||
is_like_msvc: true,
|
is_like_msvc: true,
|
||||||
pre_link_args: args,
|
pre_link_args: args,
|
||||||
|
crt_static_allows_dylibs: true,
|
||||||
|
crt_static_respected: true,
|
||||||
|
|
||||||
.. Default::default()
|
.. Default::default()
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,21 +25,7 @@ pub fn add_configuration(cfg: &mut ast::CrateConfig, sess: &Session) {
|
||||||
cfg.insert((tf, Some(feat)));
|
cfg.insert((tf, Some(feat)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let requested_features = sess.opts.cg.target_feature.split(',');
|
if sess.crt_static_feature() {
|
||||||
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 crt_static {
|
|
||||||
cfg.insert((tf, Some(Symbol::intern("crt-static"))));
|
cfg.insert((tf, Some(Symbol::intern("crt-static"))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -902,7 +902,7 @@ fn link_args(cmd: &mut Linker,
|
||||||
let mut args = args.iter().chain(more_args.iter()).chain(used_link_args.iter());
|
let mut args = args.iter().chain(more_args.iter()).chain(used_link_args.iter());
|
||||||
|
|
||||||
if get_reloc_model(sess) == llvm::RelocMode::PIC
|
if get_reloc_model(sess) == llvm::RelocMode::PIC
|
||||||
&& !args.any(|x| *x == "-static") {
|
&& !sess.crt_static() && !args.any(|x| *x == "-static") {
|
||||||
cmd.position_independent_executable();
|
cmd.position_independent_executable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -966,11 +966,13 @@ fn link_args(cmd: &mut Linker,
|
||||||
add_upstream_rust_crates(cmd, sess, crate_type, tmpdir);
|
add_upstream_rust_crates(cmd, sess, crate_type, tmpdir);
|
||||||
add_upstream_native_libraries(cmd, sess, crate_type);
|
add_upstream_native_libraries(cmd, sess, crate_type);
|
||||||
|
|
||||||
// # Telling the linker what we're doing
|
// Tell the linker what we're doing.
|
||||||
|
|
||||||
if crate_type != config::CrateTypeExecutable {
|
if crate_type != config::CrateTypeExecutable {
|
||||||
cmd.build_dylib(out_filename);
|
cmd.build_dylib(out_filename);
|
||||||
}
|
}
|
||||||
|
if crate_type == config::CrateTypeExecutable && sess.crt_static() {
|
||||||
|
cmd.build_static_executable();
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME (#2397): At some point we want to rpath our guesses as to
|
// FIXME (#2397): At some point we want to rpath our guesses as to
|
||||||
// where extern libraries might live, based on the
|
// where extern libraries might live, based on the
|
||||||
|
|
|
@ -110,6 +110,7 @@ pub trait Linker {
|
||||||
fn debuginfo(&mut self);
|
fn debuginfo(&mut self);
|
||||||
fn no_default_libraries(&mut self);
|
fn no_default_libraries(&mut self);
|
||||||
fn build_dylib(&mut self, out_filename: &Path);
|
fn build_dylib(&mut self, out_filename: &Path);
|
||||||
|
fn build_static_executable(&mut self);
|
||||||
fn args(&mut self, args: &[String]);
|
fn args(&mut self, args: &[String]);
|
||||||
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType);
|
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType);
|
||||||
fn subsystem(&mut self, subsystem: &str);
|
fn subsystem(&mut self, subsystem: &str);
|
||||||
|
@ -179,6 +180,7 @@ impl<'a> Linker for GccLinker<'a> {
|
||||||
fn position_independent_executable(&mut self) { self.cmd.arg("-pie"); }
|
fn position_independent_executable(&mut self) { self.cmd.arg("-pie"); }
|
||||||
fn partial_relro(&mut self) { self.linker_arg("-z,relro"); }
|
fn partial_relro(&mut self) { self.linker_arg("-z,relro"); }
|
||||||
fn full_relro(&mut self) { self.linker_arg("-z,relro,-z,now"); }
|
fn full_relro(&mut self) { self.linker_arg("-z,relro,-z,now"); }
|
||||||
|
fn build_static_executable(&mut self) { self.cmd.arg("-static"); }
|
||||||
fn args(&mut self, args: &[String]) { self.cmd.args(args); }
|
fn args(&mut self, args: &[String]) { self.cmd.args(args); }
|
||||||
|
|
||||||
fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
|
fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
|
||||||
|
@ -396,6 +398,10 @@ impl<'a> Linker for MsvcLinker<'a> {
|
||||||
self.cmd.arg(arg);
|
self.cmd.arg(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_static_executable(&mut self) {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
|
||||||
fn gc_sections(&mut self, _keep_metadata: bool) {
|
fn gc_sections(&mut self, _keep_metadata: bool) {
|
||||||
// MSVC's ICF (Identical COMDAT Folding) link optimization is
|
// MSVC's ICF (Identical COMDAT Folding) link optimization is
|
||||||
// slow for Rust and thus we disable it by default when not in
|
// slow for Rust and thus we disable it by default when not in
|
||||||
|
@ -683,6 +689,10 @@ impl<'a> Linker for EmLinker<'a> {
|
||||||
bug!("building dynamic library is unsupported on Emscripten")
|
bug!("building dynamic library is unsupported on Emscripten")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_static_executable(&mut self) {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
|
||||||
fn export_symbols(&mut self, _tmpdir: &Path, crate_type: CrateType) {
|
fn export_symbols(&mut self, _tmpdir: &Path, crate_type: CrateType) {
|
||||||
let symbols = &self.info.exports[&crate_type];
|
let symbols = &self.info.exports[&crate_type];
|
||||||
|
|
||||||
|
|
|
@ -123,8 +123,11 @@ pub fn invalid_output_for_target(sess: &Session,
|
||||||
match (sess.target.target.options.dynamic_linking,
|
match (sess.target.target.options.dynamic_linking,
|
||||||
sess.target.target.options.executables, crate_type) {
|
sess.target.target.options.executables, crate_type) {
|
||||||
(false, _, config::CrateTypeCdylib) |
|
(false, _, config::CrateTypeCdylib) |
|
||||||
(false, _, config::CrateTypeProcMacro) |
|
(false, _, config::CrateTypeDylib) |
|
||||||
(false, _, config::CrateTypeDylib) => true,
|
(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, config::CrateTypeExecutable) => true,
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ fn main() {
|
||||||
println!("cargo:rustc-link-lib=dl");
|
println!("cargo:rustc-link-lib=dl");
|
||||||
println!("cargo:rustc-link-lib=log");
|
println!("cargo:rustc-link-lib=log");
|
||||||
println!("cargo:rustc-link-lib=gcc");
|
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=dl");
|
||||||
println!("cargo:rustc-link-lib=rt");
|
println!("cargo:rustc-link-lib=rt");
|
||||||
println!("cargo:rustc-link-lib=pthread");
|
println!("cargo:rustc-link-lib=pthread");
|
||||||
|
|
|
@ -16,7 +16,7 @@ fn main() {
|
||||||
|
|
||||||
if target.contains("linux") {
|
if target.contains("linux") {
|
||||||
if target.contains("musl") && !target.contains("mips") {
|
if target.contains("musl") && !target.contains("mips") {
|
||||||
println!("cargo:rustc-link-lib=static=unwind");
|
// musl is handled in lib.rs
|
||||||
} else if !target.contains("android") {
|
} else if !target.contains("android") {
|
||||||
println!("cargo:rustc-link-lib=gcc_s");
|
println!("cargo:rustc-link-lib=gcc_s");
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#![deny(warnings)]
|
#![deny(warnings)]
|
||||||
|
|
||||||
#![feature(cfg_target_vendor)]
|
#![feature(cfg_target_vendor)]
|
||||||
|
#![feature(link_cfg)]
|
||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![feature(unwind_attributes)]
|
#![feature(unwind_attributes)]
|
||||||
#![feature(static_nobundle)]
|
#![feature(static_nobundle)]
|
||||||
|
@ -28,3 +29,8 @@ extern crate libc;
|
||||||
mod libunwind;
|
mod libunwind;
|
||||||
#[cfg(not(target_env = "msvc"))]
|
#[cfg(not(target_env = "msvc"))]
|
||||||
pub use libunwind::*;
|
pub use libunwind::*;
|
||||||
|
|
||||||
|
#[cfg(target_env = "musl")]
|
||||||
|
#[link(name = "unwind", kind = "static-nobundle", cfg(target_feature = "crt-static"))]
|
||||||
|
#[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
|
||||||
|
extern {}
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
// aux-build:issue-13560-1.rs
|
// aux-build:issue-13560-1.rs
|
||||||
// aux-build:issue-13560-2.rs
|
// aux-build:issue-13560-2.rs
|
||||||
// aux-build:issue-13560-3.rs
|
// aux-build:issue-13560-3.rs
|
||||||
// ignore-musl
|
|
||||||
|
|
||||||
// Regression test for issue #13560, the test itself is all in the dependent
|
// Regression test for issue #13560, the test itself is all in the dependent
|
||||||
// libraries. The fail which previously failed to compile is the one numbered 3.
|
// libraries. The fail which previously failed to compile is the one numbered 3.
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
// aux-build:linkage-visibility.rs
|
// aux-build:linkage-visibility.rs
|
||||||
// ignore-android: FIXME(#10356)
|
// ignore-android: FIXME(#10356)
|
||||||
// ignore-windows: std::dynamic_lib does not work on Windows well
|
// ignore-windows: std::dynamic_lib does not work on Windows well
|
||||||
// ignore-musl
|
|
||||||
// ignore-emscripten no dynamic linking
|
// ignore-emscripten no dynamic linking
|
||||||
|
|
||||||
extern crate linkage_visibility as foo;
|
extern crate linkage_visibility as foo;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue