aboutsummaryrefslogtreecommitdiffstats
path: root/testing/rust
diff options
context:
space:
mode:
authorJakub Jirutka <jakub@jirutka.cz>2017-04-08 15:08:22 +0200
committerJakub Jirutka <jakub@jirutka.cz>2017-04-09 15:41:28 +0200
commit8c89e1295610fdb35dd125c2f7060e2e74c68527 (patch)
tree6bd5e94c2f58436db3341b9958354acc3a969d2c /testing/rust
parent997883d3a0f8c8c4a12b55f62643a26883d14507 (diff)
downloadaports-8c89e1295610fdb35dd125c2f7060e2e74c68527.tar.bz2
aports-8c89e1295610fdb35dd125c2f7060e2e74c68527.tar.xz
testing/rust: upgrade to 1.16.0 and properly fix dynamic linking
Diffstat (limited to 'testing/rust')
-rw-r--r--testing/rust/APKBUILD148
-rw-r--r--testing/rust/allow-crt-static-on-stable.patch32
-rw-r--r--testing/rust/dont-require-filecheck.patch18
-rw-r--r--testing/rust/fix-linux_musl_base.patch63
-rw-r--r--testing/rust/link-musl-dynamically.patch76
-rw-r--r--testing/rust/llvm-with-ffi.patch13
-rw-r--r--testing/rust/static-pie.patch123
-rw-r--r--testing/rust/support-dynamically-linked-musl.patch384
8 files changed, 682 insertions, 175 deletions
diff --git a/testing/rust/APKBUILD b/testing/rust/APKBUILD
index e7bbe856d9..a2af1143d7 100644
--- a/testing/rust/APKBUILD
+++ b/testing/rust/APKBUILD
@@ -1,39 +1,43 @@
# Contributor: Jakub Jirutka <jakub@jirutka.cz>
+# Contributor: Shiz <hi@shiz.me>
# Maintainer: Jakub Jirutka <jakub@jirutka.cz>
pkgname=rust
-pkgver=1.10.0
-pkgrel=1
+pkgver=1.16.0
+# Git revision of prebuilt cargo to use for bootstrapping.
+_cargo_gitrev=f9e54817e53c7b9845cc7c1ede4c11e4d3e42e36 # 0.17.0
+pkgrel=0
pkgdesc="The Rust Programming Language (compiler)"
url="http://www.rust-lang.org"
arch="x86_64"
-license="ASL-2.0 BSD MIT"
+license="ASL-2.0 BSD ISC MIT"
# gcc is needed at runtime just for linking. Someday rustc might invoke
# the linker directly, and then we'll only need binutils.
# See: https://github.com/rust-lang/rust/issues/11937
depends="$pkgname-stdlib gcc"
-# libffi-dev is needed just because we compile llvm3.7 with LLVM_ENABLE_FFI.
-makedepends="cmake file libffi-dev llvm3.7 llvm3.7-dev llvm3.7-static
+# libffi-dev is needed just because we compile llvm with LLVM_ENABLE_FFI.
+makedepends="cmake file libffi-dev libunwind-dev llvm llvm-dev llvm-static
musl-dev python2 tar zlib-dev"
subpackages="$pkgname-stdlib $pkgname-gdb::noarch $pkgname-lldb::noarch $pkgname-doc"
# XXX: Rust is self-hosted, so you need rustc to build rustc... The problem is
-# that Rust doesn't provide prebuilt rustc for musl yet. Thus I cross-compiled
-# rustc on glibc-based system and uploaded the built tarballs to my server.
-# We're gonna replace them once Rust start providing prebuilt binaries for musl.
+# that Rust doesn't provide prebuilt rustc for musl yet. Thus we use binaries
+# from VoidLinux for now.
# Follow https://github.com/rust-lang/rust/issues/31322.
-# TODO: Implement some support for verifying crates fetched by cargo!
source="https://static.rust-lang.org/dist/rustc-$pkgver-src.tar.gz
- https://alpine.geeknet.cz/distfiles/rustc-$pkgver-x86_64-unknown-linux-musl.tar.gz
- https://alpine.geeknet.cz/distfiles/rust-std-$pkgver-x86_64-unknown-linux-musl.tar.gz
- https://alpine.geeknet.cz/distfiles/cargo-0.11.0-nightly-x86_64-alpine-linux-musl.tar.gz
-
+ https://repo.voidlinux.eu/distfiles/rustc-$pkgver-x86_64-unknown-linux-musl.tar.gz
+ https://repo.voidlinux.eu/distfiles/rust-std-$pkgver-x86_64-unknown-linux-musl.tar.gz
+ cargo-$_cargo_gitrev-x86_64-unknown-linux-musl.tar.gz::https://s3.amazonaws.com/rust-lang-ci/cargo-builds/$_cargo_gitrev/cargo-nightly-x86_64-unknown-linux-musl.tar.gz
dont-require-filecheck.patch
- link-musl-dynamically.patch
+ support-dynamically-linked-musl.patch
+ allow-crt-static-on-stable.patch
+ static-pie.patch
+ fix-linux_musl_base.patch
llvm-with-ffi.patch
move-py-scripts-to-share.patch
"
-options="!check !strip"
-builddir="$srcdir/rustc-$pkgver"
+# TODO: strip gently (see Fedora pkg for inspiration)
+options="!strip !check"
+builddir="$srcdir/rustc-$pkgver-src"
_ctarget="$CARCH-unknown-linux-musl"
_sharedir="usr/share/rust"
@@ -44,6 +48,10 @@ prepare() {
cd "$builddir"
+ # Don't set wrong LD_LIBRARY_PATH, we will rather set it manually when
+ # invoking make.
+ sed -i /LD_LIBRARY_PATH/d src/bootstrap/bootstrap.py
+
# Remove some bundled dependencies.
rm -Rf src/llvm/ src/jemalloc/
@@ -64,50 +72,38 @@ prepare() {
build() {
cd "$builddir"
- export CARGO_HOME="$builddir/.cargo"
-
- # XXX: Cheat Rust build system so we can build rustc using different
- # version of (prebuilt) stable rustc than preconfigured. It's hack-ish,
- # but since we're basically rebuilding rustc with the same version,
- # it's actually safe.
- # Note: --enable-local-rebuild from #33787 didn't work, don't know why.
- local rustc_ver="$("$_stage0dir"/bin/rustc --version | cut -f2 -d ' ')"
- local rustc_key="$(printf "$rustc_ver" | md5sum | cut -c1-8)"
- sed -Ei \
- -e "s/^(rustc):.*/\1: $rustc_ver-1970-01-01/" \
- -e "s/^(rustc_key):.*/\1: $rustc_key/" \
- src/stage0.txt
-
- # Generate config for bootstrap.py to use our prebuilt rustc and cargo
- # for bootstrapping instead of downloading snapshot from internet.
- cat > config.toml <<-EOF
- [build]
- cargo = "$_stage0dir/bin/cargo"
- rustc = "$_stage0dir/bin/rustc"
- EOF
-
# Note: rustc doesn't work well with jemalloc on musl (yet)
./configure \
+ --enable-rustbuild \
--build="$_ctarget" \
--host="$_ctarget" \
+ --target="$_ctarget" \
--prefix="/usr" \
- --enable-rustbuild \
--release-channel="stable" \
+ --enable-local-rust \
+ --local-rust-root="$_stage0dir" \
+ --llvm-root="/usr" \
--musl-root="/usr" \
- --llvm-root="/usr/lib/llvm-3.7" \
+ --enable-vendor \
--disable-docs \
--disable-jemalloc \
--disable-rpath
- # This is really stupid, but rustbuild doesn't provide "install"
- # command yet, so we must create a dist tarball...
- # https://github.com/rust-lang/rust/issues/34675
- make dist VERBOSE=1
+ # Set LD_LIBRARY_PATH, so rustc in stage0 can find correct libs.
+ make \
+ LD_LIBRARY_PATH="$_stage0dir/lib" \
+ RUST_BACKTRACE=1 \
+ RUST_CRT_STATIC="false" \
+ VERBOSE=1
}
check() {
cd "$builddir"
- make check VERBOSE=1
+
+ make check \
+ LD_LIBRARY_PATH="$_stage0dir/lib" \
+ RUST_BACKTRACE=1 \
+ VERBOSE=1
}
# XXX: so libs doesn't have stable ABI, so they should not be registered as
@@ -116,21 +112,30 @@ check() {
package() {
cd "$builddir"
- _install build/dist/rustc-$pkgver-$_ctarget.tar.gz \
- "$pkgdir"/usr
+ make install \
+ LD_LIBRARY_PATH="$_stage0dir/lib" \
+ DESTDIR="$pkgdir"
+
+ cd "$pkgdir"
+
+ # so libs should have executable flag.
+ chmod +x usr/lib/*.so
# Python scripts are noarch, so move them to /usr/share.
# Requires move-py-scripts-to-share.patch to be applied.
- _mv "$pkgdir"/usr/lib/rustlib/etc/*.py "$pkgdir"/$_sharedir/etc/
+ _mv usr/lib/rustlib/etc/*.py $_sharedir/etc/
+ rmdir -p usr/lib/rustlib/etc || true
+
+ # Remove some clutter.
+ cd usr/lib/rustlib
+ rm components install.log manifest-* rust-installer-version uninstall.sh
}
stdlib() {
pkgdesc="The Rust Programming Language (stdlib)"
depends="$pkgname"
- cd "$builddir"
- _install build/dist/rust-std-$pkgver-$_ctarget.tar.gz \
- "$subpkgdir"/usr
+ _mv "$pkgdir"/usr/lib/rustlib "$subpkgdir"/usr/lib/
}
gdb() {
@@ -155,41 +160,20 @@ lldb() {
_mv "$pkgdir"/$_sharedir/etc/lldb_*.py $_sharedir/etc/
}
-_install() {
- local tarfile="$1"
- local dest="$2"
-
- mkdir -p "$dest"
- tar -xz -f "$tarfile" -C "$dest" --strip-components=2 --exclude=manifest.in
-}
-
_mv() {
local dest; for dest; do true; done # get last argument
mkdir -p "$dest"
mv $@
}
-md5sums="a48fef30353fc9daa70b484b690ce5db rustc-1.10.0-src.tar.gz
-7d6278b0898b3c9e05cd3c622d8c7491 rustc-1.10.0-x86_64-unknown-linux-musl.tar.gz
-f5ebd54888bfd8698f629b168691a47b rust-std-1.10.0-x86_64-unknown-linux-musl.tar.gz
-79f81ecfa861f4d97a3b9235e66ba594 cargo-0.11.0-nightly-x86_64-alpine-linux-musl.tar.gz
-c6fc2288df0b746f5317c866800a628b dont-require-filecheck.patch
-4351eff471b20fbcf135fe311e5b0870 link-musl-dynamically.patch
-27f12fb4ce42e18dcf19fd78be4c183e llvm-with-ffi.patch
-9b951149e87a99a1934af4eb7e698902 move-py-scripts-to-share.patch"
-sha256sums="a4015aacf4f6d8a8239253c4da46e7abaa8584f8214d1828d2ff0a8f56176869 rustc-1.10.0-src.tar.gz
-a7d8baacfa2225c923de28ecef2c9550c1d82cef3b90f6a1b8431359da7e7e69 rustc-1.10.0-x86_64-unknown-linux-musl.tar.gz
-335527615fc1a5f53d41c1d8556645bfe0b4f3a39f72ad859b392392066d9239 rust-std-1.10.0-x86_64-unknown-linux-musl.tar.gz
-587172026c0565e839d96b0c1d4c68c000927817398241f96682dca47fa8c3b9 cargo-0.11.0-nightly-x86_64-alpine-linux-musl.tar.gz
-45ffc2e5626ce5e8e7dadecbd7cfdbf4db6bc1bba99dc54376a794011bb3919b dont-require-filecheck.patch
-8aec85b958ab975164d1673b666be0aa88d4b51b5944fa7227024b4942f52ed8 link-musl-dynamically.patch
-a7d533ac9542151234911d4a48815cc53f490b8011f5eab555cbc3a95fbde2b6 llvm-with-ffi.patch
-176dfddeff62f0bac918f742df6041df6ab777d0ddbfd01a73d580180781cbee move-py-scripts-to-share.patch"
-sha512sums="fdef0a4c458ce687ab2921fb879cf6f68ae7ec4d780e407fea80cb751d70d80e621fc37756358d8336383c24646d9e2869215b3591b2240904206df2e58a7e45 rustc-1.10.0-src.tar.gz
-35e94c86a6abc579dcfe875ecc830522ecb8b1a0b96a03054b4020f21b1a2ee1ab2e61782dafbfaa3ce7b5b721f4b15f10e5dfac9c41b6f008152ed8b842ac67 rustc-1.10.0-x86_64-unknown-linux-musl.tar.gz
-f6a89b4a1dc3d620cc1d783f62eb4f2e7a519f6b86b4d87877b854ea86ac740a0c8ea96c4ff11185bfb496861ade286ad08c3ab5e0bcc9592251406d7fb35f8a rust-std-1.10.0-x86_64-unknown-linux-musl.tar.gz
-17838355ff6d87165aa0f61bd01f48c58a426c069bba7c3852d016e1836666bfafe2609c323a0409fc8530ad27fb3ad5989d8cee033633e38b07fefa670597d5 cargo-0.11.0-nightly-x86_64-alpine-linux-musl.tar.gz
-19f390e0d9cd2c23cbad26aa97f51a0978a3ed5170050d5635ee06e5115d8608f55884a61d98003fca91434c9be081bde735ace97f1e251450b70d63c3bffd42 dont-require-filecheck.patch
-9ae2d8d9eff9fb6cf8fe8e902f0b87bc464cd84364734f105230785c4d8dc57ecf6872fc0532e15ac612ef11727e70ef25d08f7b084c4473017989b6c9a4593b link-musl-dynamically.patch
-ab126eea4b960924b4a4d52f73709085a3b742329364db1a3543bcae94e4e6d8f94d30983e5e06069a489678b2d195e7535ff8e66be2c518dc8b2c54cb0c8804 llvm-with-ffi.patch
+sha512sums="096b1b7406be9bc61161bb7cdd2061f2bc2174c161a31f4ed6ceecf7fc379f315fc2f7cb9f6c134ea4f8519c27bf6e5a3f712cf1e56d5785831d8c8374eb0ba5 rustc-1.16.0-src.tar.gz
+e9b10d58ae5b51b09dd31a1dbf7367917bd40a05ecb4ba3e0e7ac229a0352d3ceb77de80f7c0120f553bd7904644da6bf973dbc32850b12dc91f3974846d4164 rustc-1.16.0-x86_64-unknown-linux-musl.tar.gz
+54467213b2824112dec6d5a132ab01d69617a5ccaa9db15e5c8fad55dea5eb31b1b7c9ca07878901d75edd45dc84c726913bf651f3435c480a79703c074b5d90 rust-std-1.16.0-x86_64-unknown-linux-musl.tar.gz
+97698f6b9a1eae6e181dc480599095f0aa5fcf85cdc3dc6b5340a20e1e42f585188c06074c1e35cff4393a78c8502c81d8852fcf7da674e0a7313f88155feb56 cargo-f9e54817e53c7b9845cc7c1ede4c11e4d3e42e36-x86_64-unknown-linux-musl.tar.gz
+2002faf08cca3be702f25618bc17453c5e76644a6ff6b0739b642c2c0f8536ec7f09c98182aff6b2dcc87c77b0929f2f8f732b8242a8f80d94b3824c8cd0d0fe dont-require-filecheck.patch
+a87ffe129debcb9fa958c6d007ffa4a87927890030e0694ee5ab1929ea0c5a48dad86b4e8b71550dcfeda29b644dbb23d8b232bda62439f198a404cf658c68b0 support-dynamically-linked-musl.patch
+57ea7651bc0b0fa5340b9c5de0492ddc8bfaf4f1003298bf27dea57ee562cdd0f3947e091b154388535ce511e001e052f12d48805f7ffece7f04178ad409623f allow-crt-static-on-stable.patch
+541aac679dfdbe5383f884e0493462dd33908308c7b294170b24339d6b9c1e723088c80764125116f24707a67eeeedadceaa9628ca6d2b8c7d0ca9253bf62135 static-pie.patch
+f436fddf7ab70ca5f1424081f5b75450270b200b3d997231323863e11addf76e1d65831a7ca09e3a5b7904ce828766c1f70b08326a175890298f28e5bc8646ef fix-linux_musl_base.patch
+37416e1fa0bc0c8651cd060a645d6245ff7e2082279ab5e13495c5ee412c71915469019cfbec95a0fd9a7fc144475079a3ad16f0eba7a2f5c8dd99e0002f3225 llvm-with-ffi.patch
19cc2725d68db3e359e0e3016028374e5818a97fdba24d0103f7d1706601c8b17c4dd95a3152e64f982f98e95ad3e949acddbea8a39ed0ba8dd4f702acc2704d move-py-scripts-to-share.patch"
diff --git a/testing/rust/allow-crt-static-on-stable.patch b/testing/rust/allow-crt-static-on-stable.patch
new file mode 100644
index 0000000000..c193c0c0ac
--- /dev/null
+++ b/testing/rust/allow-crt-static-on-stable.patch
@@ -0,0 +1,32 @@
+From: Jakub Jirutka <jakub@jirutka.cz>
+Date: Sat, 08 Aug 2016 14:49:00 +0200
+Subject: [PATCH] Allow to use -C target-feature=+crt-static on stable rustc
+
+Rust links system libraries statically on musl by default, but we want to
+link dynamically. At the same time we would like to preserve this behaviour
+for consistency with other distros, to not confuse users.
+
+rustc already provides codegen option to change linking, but currently it's
+allowed only for nightly builds. This patch just removes this check and so
+allows to use it even on stable build.
+
+Build dynamically linked binary with rustc or cargo:
+
+ $ rustc -C target-feature=+crt-static hello_world.rs
+ $ RUSTFLAGS="-C target-feature=+crt-static" cargo build
+
+--- a/src/librustc/session/mod.rs
++++ b/src/librustc/session/mod.rs
+@@ -401,9 +401,9 @@
+ // 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");
++ //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;
diff --git a/testing/rust/dont-require-filecheck.patch b/testing/rust/dont-require-filecheck.patch
index 430cc9320c..6556d82a46 100644
--- a/testing/rust/dont-require-filecheck.patch
+++ b/testing/rust/dont-require-filecheck.patch
@@ -1,19 +1,19 @@
From: Jakub Jirutka <jakub@jirutka.cz>
-Date: Thu, 04 Aug 2016 17:53:00 +0200
+Date: Thu, 06 Apr 2017 12:25:00 +0200
Subject: [PATCH] Do not require FileCheck
---- a/src/bootstrap/build/sanity.rs
-+++ b/src/bootstrap/build/sanity.rs
-@@ -76,12 +76,6 @@
- need_cmd(build.cxx(host).as_ref());
+--- a/src/bootstrap/sanity.rs
++++ b/src/bootstrap/sanity.rs
+@@ -144,12 +144,6 @@
+ }
}
- // Externally configured LLVM requires FileCheck to exist
- let filecheck = build.llvm_filecheck(&build.config.build);
-- if !filecheck.starts_with(&build.out) && !filecheck.exists() {
-- panic!("filecheck executable {:?} does not exist", filecheck);
+- if !filecheck.starts_with(&build.out) && !filecheck.exists() && build.config.codegen_tests {
+- panic!("FileCheck executable {:?} does not exist", filecheck);
- }
-
for target in build.config.target.iter() {
- // Either can't build or don't want to run jemalloc on these targets
- if target.contains("rumprun") ||
+ // Can't compile for iOS unless we're on OSX
+ if target.contains("apple-ios") &&
diff --git a/testing/rust/fix-linux_musl_base.patch b/testing/rust/fix-linux_musl_base.patch
new file mode 100644
index 0000000000..38194290cb
--- /dev/null
+++ b/testing/rust/fix-linux_musl_base.patch
@@ -0,0 +1,63 @@
+From: Jakub Jirutka <jakub@jirutka.cz>
+Date: Sat, 08 Aug 2016 15:06:00 +0200
+Subject: [PATCH] Fix linux_musl_base for native musl host
+
+See https://github.com/rust-lang/rust/pull/40113
+
+--- a/src/librustc_back/target/linux_musl_base.rs
++++ b/src/librustc_back/target/linux_musl_base.rs
+@@ -13,54 +13,14 @@
+ pub fn opts() -> TargetOptions {
+ let mut base = super::linux_base::opts();
+
+- // Make sure that the linker/gcc really don't pull in anything, including
+- // default objects, libs, etc.
+- base.pre_link_args.push("-nostdlib".to_string());
+-
+ // At least when this was tested, the linker would not add the
+ // `GNU_EH_FRAME` program header to executables generated, which is required
+ // when unwinding to locate the unwinding information. I'm not sure why this
+ // argument is *not* necessary for normal builds, but it can't hurt!
+ base.pre_link_args.push("-Wl,--eh-frame-hdr".to_string());
+
+- // There's a whole bunch of circular dependencies when dealing with MUSL
+- // unfortunately. To put this in perspective libc is statically linked to
+- // liblibc and libunwind is statically linked to libstd:
+- //
+- // * libcore depends on `fmod` which is in libc (transitively in liblibc).
+- // liblibc, however, depends on libcore.
+- // * compiler-rt has personality symbols that depend on libunwind, but
+- // libunwind is in libstd which depends on compiler-rt.
+- //
+- // Recall that linkers discard libraries and object files as much as
+- // possible, and with all the static linking and archives flying around with
+- // MUSL the linker is super aggressively stripping out objects. For example
+- // the first case has fmod stripped from liblibc (it's in its own object
+- // file) so it's not there when libcore needs it. In the second example all
+- // the unused symbols from libunwind are stripped (each is in its own object
+- // file in libstd) before we end up linking compiler-rt which depends on
+- // those symbols.
+- //
+- // To deal with these circular dependencies we just force the compiler to
+- // link everything as a group, not stripping anything out until everything
+- // is processed. The linker will still perform a pass to strip out object
+- // files but it won't do so until all objects/archives have been processed.
+- base.pre_link_args.push("-Wl,-(".to_string());
+- base.post_link_args.push("-Wl,-)".to_string());
+-
+- // When generating a statically linked executable there's generally some
+- // small setup needed which is listed in these files. These are provided by
+- // a musl toolchain and are linked by default by the `musl-gcc` script. Note
+- // that `gcc` also does this by default, it just uses some different files.
+- //
+- // Each target directory for musl has these object files included in it so
+- // they'll be included from there.
+- 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());
+-
+ // Except for on MIPS, these targets statically link libc by default.
+ base.crt_static_default = true;
+
+ base
+ }
diff --git a/testing/rust/link-musl-dynamically.patch b/testing/rust/link-musl-dynamically.patch
deleted file mode 100644
index d15eb91ded..0000000000
--- a/testing/rust/link-musl-dynamically.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-From: Jakub Jirutka <jakub@jirutka.cz>
-Date: Thu, 04 Aug 2016 17:53:00 +0200
-Subject: [PATCH] Do not link musl statically
-
-Static linking of rustc on Alpine doesn't work yet.
-
-This patch is ported from
-https://gist.github.com/japaric/52b8816a4c86f5a4699bcc50ebc3e020.
-
---- a/src/bootstrap/build/sanity.rs
-+++ b/src/bootstrap/build/sanity.rs
-@@ -97,26 +91,6 @@
- panic!("the iOS target is only supported on OSX");
- }
-
-- // Make sure musl-root is valid if specified
-- if target.contains("musl") && (target.contains("x86_64") || target.contains("i686")) {
-- match build.config.musl_root {
-- Some(ref root) => {
-- if fs::metadata(root.join("lib/libc.a")).is_err() {
-- panic!("couldn't find libc.a in musl dir: {}",
-- root.join("lib").display());
-- }
-- if fs::metadata(root.join("lib/libunwind.a")).is_err() {
-- panic!("couldn't find libunwind.a in musl dir: {}",
-- root.join("lib").display());
-- }
-- }
-- None => {
-- panic!("when targeting MUSL the build.musl-root option \
-- must be specified in config.toml")
-- }
-- }
-- }
--
- if target.contains("msvc") {
- // There are three builds of cmake on windows: MSVC, MinGW, and
- // Cygwin. The Cygwin build does not have generators for Visual
---- a/src/liblibc/src/unix/mod.rs
-+++ b/src/liblibc/src/unix/mod.rs
-@@ -187,11 +187,6 @@
- } else if #[cfg(all(not(stdbuild), feature = "use_std"))] {
- // 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")),
-- target_env = "musleabi",
-- target_env = "musleabihf"))] {
-- #[link(name = "c", kind = "static")]
-- extern {}
- } else if #[cfg(target_os = "emscripten")] {
- #[link(name = "c")]
- extern {}
---- a/src/librustc_back/target/x86_64_unknown_linux_musl.rs
-+++ b/src/librustc_back/target/x86_64_unknown_linux_musl.rs
-@@ -11,7 +11,7 @@
- use target::Target;
-
- pub fn target() -> Target {
-- let mut base = super::linux_musl_base::opts();
-+ let mut base = super::linux_base::opts();
- base.cpu = "x86-64".to_string();
- base.max_atomic_width = 64;
- base.pre_link_args.push("-m64".to_string());
---- a/src/libunwind/build.rs
-+++ b/src/libunwind/build.rs
-@@ -16,9 +16,7 @@
- let target = env::var("TARGET").unwrap();
-
- if target.contains("linux") {
-- if target.contains("musl") && (target.contains("x86_64") || target.contains("i686")) {
-- println!("cargo:rustc-link-lib=static=unwind");
-- } else if !target.contains("android") {
-+ if !target.contains("android") {
- println!("cargo:rustc-link-lib=gcc_s");
- }
- } else if target.contains("freebsd") {
diff --git a/testing/rust/llvm-with-ffi.patch b/testing/rust/llvm-with-ffi.patch
index 23504eac71..f8c9cdf13a 100644
--- a/testing/rust/llvm-with-ffi.patch
+++ b/testing/rust/llvm-with-ffi.patch
@@ -7,13 +7,10 @@ https://github.com/rust-lang/rust/issues/34486.
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
-@@ -577,6 +577,9 @@
- #[cfg(not(cargobuild))]
- extern {}
-
+@@ -481,3 +481,6 @@
+ mod llvmdeps {
+ include! { env!("CFG_LLVM_LINKAGE_FILE") }
+ }
++
+#[link(name = "ffi")]
+extern {}
-+
- #[linked_from = "rustllvm"] // not quite true but good enough
- extern {
- /* Create and destroy contexts. */
diff --git a/testing/rust/static-pie.patch b/testing/rust/static-pie.patch
new file mode 100644
index 0000000000..adc615f95f
--- /dev/null
+++ b/testing/rust/static-pie.patch
@@ -0,0 +1,123 @@
+From: Shiz <hi@shiz.me>
+Date: Sat, 8 Apr 2017 05:38:00 +0200
+Subject: [PATCH] Add support for static PIE executables
+
+Note that static PIE binaries are reported as dynamically linked by
+the "file" utility:
+
+ $ rustc -C target-feature=+crt-static hello_world.rb
+ $ file hello_world
+ ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically \
+ linked, not stripped, with debug_info
+
+Also ldd reports that it's linked with ldd:
+
+ $ ldd hello_world
+ ldd (0x237fcc81000)
+
+Static PIE binaries are dynamic binaries without a loader or any DT_NEEDED
+entries. The important is that they do not depend on libc or any other system
+library, just like static binaries, but more secure.
+
+ $ readelf -d hello_world
+ Dynamic section at offset 0x2de40 contains 17 entries:
+ Tag Type Name/Value
+ 0x0000000000000010 (SYMBOLIC) 0x0
+ 0x000000000000000c (INIT) 0x17a0
+ 0x000000000000000d (FINI) 0x2003c
+ 0x000000006ffffef5 (GNU_HASH) 0x1c8
+ 0x0000000000000005 (STRTAB) 0x278
+ 0x0000000000000006 (SYMTAB) 0x200
+ 0x000000000000000a (STRSZ) 60 (bytes)
+ 0x000000000000000b (SYMENT) 24 (bytes)
+ 0x0000000000000015 (DEBUG) 0x0
+ 0x0000000000000003 (PLTGOT) 0x22df90
+ 0x0000000000000007 (RELA) 0x2b8
+ 0x0000000000000008 (RELASZ) 5352 (bytes)
+ 0x0000000000000009 (RELAENT) 24 (bytes)
+ 0x0000000000000018 (BIND_NOW)
+ 0x000000006ffffffb (FLAGS_1) Flags: NOW PIE
+ 0x000000006ffffff9 (RELACOUNT) 223
+ 0x0000000000000000 (NULL) 0x0
+
+--- a/src/librustc_back/target/linux_musl_base.rs
++++ b/src/librustc_back/target/linux_musl_base.rs
+@@ -22,5 +22,8 @@
+ // Except for on MIPS, these targets statically link libc by default.
+ base.crt_static_default = true;
+
++ // Static position-independent executables are supported.
++ base.static_position_independent_executables = true;
++
+ base
+ }
+--- a/src/librustc_back/target/mod.rs
++++ b/src/librustc_back/target/mod.rs
+@@ -350,6 +350,8 @@
+ /// the functions in the executable are not randomized and can be used
+ /// during an exploit of a vulnerability in any code.
+ pub position_independent_executables: bool,
++ /// As above, but also support for static position independent executables.
++ pub static_position_independent_executables: bool,
+ /// Format that archives should be emitted in. This affects whether we use
+ /// LLVM to assemble an archive or fall back to the system linker, and
+ /// currently only "gnu" is used to fall into LLVM. Unknown strings cause
+@@ -434,6 +436,7 @@
+ has_rpath: false,
+ no_default_libraries: true,
+ position_independent_executables: false,
++ static_position_independent_executables: false,
+ pre_link_objects_exe: Vec::new(),
+ pre_link_objects_dll: Vec::new(),
+ post_link_objects: Vec::new(),
+--- a/src/librustc_trans/back/link.rs
++++ b/src/librustc_trans/back/link.rs
+@@ -840,6 +840,10 @@
+
+ let used_link_args = sess.cstore.used_link_args();
+
++ if crate_type == config::CrateTypeExecutable && sess.crt_static() {
++ cmd.static_executable();
++ }
++
+ if crate_type == config::CrateTypeExecutable &&
+ t.options.position_independent_executables {
+ let empty_vec = Vec::new();
+@@ -850,7 +854,7 @@
+ let relocation_model = sess.opts.cg.relocation_model.as_ref()
+ .unwrap_or(&empty_str);
+ if (t.options.relocation_model == "pic" || *relocation_model == "pic")
+- && !args.any(|x| *x == "-static") {
++ && (t.options.static_position_independent_executables || !args.any(|x| *x == "-static")) {
+ cmd.position_independent_executable();
+ }
+ }
+--- a/src/librustc_trans/back/linker.rs
++++ b/src/librustc_trans/back/linker.rs
+@@ -82,6 +82,7 @@
+ fn add_object(&mut self, path: &Path);
+ fn gc_sections(&mut self, keep_metadata: bool);
+ fn position_independent_executable(&mut self);
++ fn static_executable(&mut self);
+ fn optimize(&mut self);
+ fn debuginfo(&mut self);
+ fn no_default_libraries(&mut self);
+@@ -116,6 +117,7 @@
+ fn output_filename(&mut self, path: &Path) { self.cmd.arg("-o").arg(path); }
+ fn add_object(&mut self, path: &Path) { self.cmd.arg(path); }
+ fn position_independent_executable(&mut self) { self.cmd.arg("-pie"); }
++ fn static_executable(&mut self) { self.cmd.arg("-static"); }
+ fn args(&mut self, args: &[String]) { self.cmd.args(args); }
+
+ fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
+@@ -359,6 +361,10 @@
+
+ fn position_independent_executable(&mut self) {
+ // noop
++ }
++
++ fn static_executable(&mut self) {
++ self.cmd.arg("-MT");
+ }
+
+ fn no_default_libraries(&mut self) {
diff --git a/testing/rust/support-dynamically-linked-musl.patch b/testing/rust/support-dynamically-linked-musl.patch
new file mode 100644
index 0000000000..69834602cd
--- /dev/null
+++ b/testing/rust/support-dynamically-linked-musl.patch
@@ -0,0 +1,384 @@
+From 3abd1f5e2f31b1c95535ef8c3b4bef6ff78b3fa9 Mon Sep 17 00:00:00 2001
+From: Samuel Holland <samuel@sholland.org>
+Date: Sat, 25 Feb 2017 22:30:15 -0600
+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
+---
+ src/bootstrap/bin/rustc.rs | 11 ++++++++
+ src/bootstrap/compile.rs | 7 ++++--
+ src/bootstrap/config.rs | 3 +++
+ src/bootstrap/lib.rs | 14 +++++++++++
+ src/bootstrap/sanity.rs | 11 ++++++--
+ src/librustc/session/mod.rs | 29 ++++++++++++++++++++++
+ src/librustc_back/target/linux_musl_base.rs | 9 +------
+ .../target/mips_unknown_linux_musl.rs | 1 +
+ .../target/mipsel_unknown_linux_musl.rs | 1 +
+ src/librustc_driver/target_features.rs | 27 +-------------------
+ src/librustc_trans/back/link.rs | 22 +++++++++-------
+ src/libstd/build.rs | 2 +-
+ src/libunwind/build.rs | 4 +--
+ src/libunwind/lib.rs | 6 +++++
+ 14 files changed, 97 insertions(+), 50 deletions(-)
+
+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") {
++ // musl is handled in lib.rs
+ } else if !target.contains("android") {
+ println!("cargo:rustc-link-lib=gcc_s");
+ }
+diff --git a/src/libunwind/lib.rs b/src/libunwind/lib.rs
+index 7fa2ce650f..b78e762f45 100644
+--- a/src/libunwind/lib.rs
++++ b/src/libunwind/lib.rs
+@@ -15,6 +15,7 @@
+ #![deny(warnings)]
+
+ #![feature(cfg_target_vendor)]
++#![feature(link_cfg)]
+ #![feature(staged_api)]
+ #![feature(unwind_attributes)]
+
+@@ -27,3 +28,8 @@ extern crate libc;
+ mod libunwind;
+ #[cfg(not(target_env = "msvc"))]
+ pub use libunwind::*;
++
++#[cfg(target_env = "musl")]
++#[link(name = "unwind", kind = "static", cfg(target_feature = "crt-static"))]
++#[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
++extern {}
+--
+2.12.2
+