diff options
author | Jakub Jirutka <jakub@jirutka.cz> | 2017-05-01 00:43:19 +0200 |
---|---|---|
committer | Jakub Jirutka <jakub@jirutka.cz> | 2017-05-01 00:43:19 +0200 |
commit | 41489596392977197d046ca034685664a3f4afa4 (patch) | |
tree | ef791ac83fd7635db59db40e12beb20a66ada3bd /community/rust | |
parent | abfa07f26ff2837922903586b15e137b67b43219 (diff) | |
download | aports-41489596392977197d046ca034685664a3f4afa4.tar.bz2 aports-41489596392977197d046ca034685664a3f4afa4.tar.xz |
community/rust: move from testing
Diffstat (limited to 'community/rust')
-rw-r--r-- | community/rust/APKBUILD | 212 | ||||
-rw-r--r-- | community/rust/alpine-allow-crt-static.patch | 41 | ||||
-rw-r--r-- | community/rust/alpine-change-rpath-to-rustlib.patch | 37 | ||||
-rw-r--r-- | community/rust/alpine-move-py-scripts-to-share.patch | 22 | ||||
-rw-r--r-- | community/rust/alpine-target.patch | 154 | ||||
-rwxr-xr-x | community/rust/check-rustc | 106 | ||||
-rw-r--r-- | community/rust/llvm-with-ffi.patch | 16 | ||||
-rw-r--r-- | community/rust/minimize-rpath.patch | 102 | ||||
-rw-r--r-- | community/rust/musl-fix-jemalloc.patch | 61 | ||||
-rw-r--r-- | community/rust/musl-fix-linux_musl_base.patch | 63 | ||||
-rw-r--r-- | community/rust/musl-fix-static-linking.patch | 200 | ||||
-rw-r--r-- | community/rust/musl-support-dynamic-linking.patch | 363 | ||||
-rw-r--r-- | community/rust/need-rpath.patch | 62 | ||||
-rw-r--r-- | community/rust/static-pie.patch | 108 |
14 files changed, 1547 insertions, 0 deletions
diff --git a/community/rust/APKBUILD b/community/rust/APKBUILD new file mode 100644 index 0000000000..9179ab50c1 --- /dev/null +++ b/community/rust/APKBUILD @@ -0,0 +1,212 @@ +# Contributor: Jakub Jirutka <jakub@jirutka.cz> +# Contributor: Shiz <hi@shiz.me> +# Maintainer: Jakub Jirutka <jakub@jirutka.cz> +pkgname=rust +pkgver=1.17.0 +# Git revision of prebuilt Cargo to use for bootstrapping, from src/stage0.txt. +_cargo_gitrev=6b05583d71f982bcad049b9fa094c637c062e751 +_llvmver=3.9 +_bootver=1.16.0 +pkgrel=1 +pkgdesc="The Rust Programming Language (compiler)" +url="http://www.rust-lang.org" +arch="x86_64" +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=$pkgver-r$pkgrel gcc llvm-libunwind-dev musl-dev" +# libffi-dev is needed just because we compile llvm with LLVM_ENABLE_FFI. +makedepends="cmake file libffi-dev llvm$_llvmver-dev python2 tar zlib-dev" +subpackages="$pkgname-dbg $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 we use binaries +# from VoidLinux for now. +# Follow https://github.com/rust-lang/rust/issues/31322. +_cbuild="$CARCH-unknown-linux-musl" +source="https://static.rust-lang.org/dist/rustc-$pkgver-src.tar.gz + https://repo.voidlinux.eu/distfiles/rustc-$_bootver-$_cbuild.tar.gz + https://repo.voidlinux.eu/distfiles/rust-std-$_bootver-$_cbuild.tar.gz + cargo-$_cargo_gitrev-$_cbuild.tar.gz::https://s3.amazonaws.com/rust-lang-ci/cargo-builds/$_cargo_gitrev/cargo-nightly-$_cbuild.tar.gz + musl-support-dynamic-linking.patch + musl-fix-static-linking.patch + musl-fix-linux_musl_base.patch + musl-fix-jemalloc.patch + llvm-with-ffi.patch + static-pie.patch + need-rpath.patch + minimize-rpath.patch + alpine-allow-crt-static.patch + alpine-move-py-scripts-to-share.patch + alpine-change-rpath-to-rustlib.patch + alpine-target.patch + check-rustc + " +builddir="$srcdir/rustc-$pkgver-src" + +_rlibdir="usr/lib/rustlib/$CTARGET/lib" +_sharedir="usr/share/rust" +_stage0dir="$srcdir/stage0" + +ldpath="/$_rlibdir" + +prepare() { + default_prepare + + cd "$builddir" + + local stage0_cargo=$(sed -En 's/^cargo:\s*(\S+)$/\1/p' src/stage0.txt) + if [ "$_cargo_gitrev" != "$stage0_cargo" ]; then + error "Update Cargo revision to: $stage0_cargo"; return 1 + fi + + # 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 bundled dependencies. + rm -Rf src/llvm/ src/jemalloc/ + + # Prepare our stage0 for bootstrapping. + mkdir -p "$_stage0dir" + cp -flr "$srcdir"/rustc-*$_cbuild/rustc/* \ + "$srcdir"/rust-std-*$_cbuild/rust-std-*/* \ + "$srcdir"/cargo-*$_cbuild/cargo/* \ + "$_stage0dir"/ + + # Make sure to use the bundled LLVM. + printf '[target.%s]\nllvm_config = "/usr/lib/llvm%s/bin/llvm-config"\n' \ + "$CTARGET" "$_llvmver" > config.toml +} + +build() { + cd "$builddir" + + # jemalloc is disabled, because it increases size of statically linked + # binaries produced by rustc (stripped hello_world 186 kiB vs. 358 kiB) + # for only tiny performance boost (even negative in some tests). + ./configure \ + --build="$_cbuild" \ + --host="$CTARGET" \ + --target="$CTARGET" \ + --prefix="/usr" \ + --release-channel="stable" \ + --enable-local-rust \ + --local-rust-root="$_stage0dir" \ + --llvm-root="/usr/lib/llvm$_llvmver" \ + --musl-root="/usr" \ + --enable-vendor \ + --enable-llvm-link-shared \ + --disable-jemalloc \ + --disable-docs + + # 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() { + "$srcdir"/check-rustc "$builddir/build/$CTARGET/stage2/bin/rustc" + +# XXX: There's some problem with these tests, we will figure it out later. +# cd "$builddir" +# make check \ +# LD_LIBRARY_PATH="$_stage0dir/lib" \ +# RUST_BACKTRACE=1 \ +# RUST_CRT_STATIC="false" \ +# VERBOSE=1 +} + +package() { + cd "$builddir" + + make dist \ + LD_LIBRARY_PATH="$_stage0dir/lib" \ + RUST_BACKTRACE=1 \ + RUST_CRT_STATIC="false" \ + VERBOSE=1 + + local component; for component in rustc rust-std; do + tar -xf "build/dist/$component-$pkgver-$CTARGET.tar.gz" + ./"$component-$pkgver-$CTARGET"/install.sh --destdir="$pkgdir" --prefix=/usr --disable-ldconfig + done + + cd "$pkgdir" + + # These libraries are identical to those under rustlib/. Since we have + # linked rustc/rustdoc against those under rustlib/, we can remove + # them. Read change-rpath-to-rustlib.patch for more info. + rm -r usr/lib/*.so + + # These objects are for static linking with musl on non-musl systems. + rm $_rlibdir/crt*.o + + # Shared objects should have executable flag. + chmod +x $_rlibdir/*.so + + # Python scripts are noarch, so move them to /usr/share. + # Requires move-py-scripts-to-share.patch to be applied. + _mv usr/lib/rustlib/etc/*.py $_sharedir/etc/ + rmdir -p usr/lib/rustlib/etc 2>/dev/null || true + + # Remove some clutter. + cd usr/lib/rustlib + rm components install.log manifest-* rust-installer-version uninstall.sh +} + +stdlib() { + pkgdesc="Standard library for Rust (static rlibs)" + + _mv "$pkgdir"/$_rlibdir/*.rlib "$subpkgdir"/$_rlibdir/ +} + +gdb() { + pkgdesc="GDB pretty printers for Rust" + depends="$pkgname gdb" + + mkdir -p "$subpkgdir" + cd "$subpkgdir" + + _mv "$pkgdir"/usr/bin/rust-gdb usr/bin/ + _mv "$pkgdir"/$_sharedir/etc/gdb_*.py $_sharedir/etc/ +} + +lldb() { + pkgdesc="LLDB pretty printers for Rust" + depends="$pkgname lldb py-lldb" + + mkdir -p "$subpkgdir" + cd "$subpkgdir" + + _mv "$pkgdir"/usr/bin/rust-lldb usr/bin/ + _mv "$pkgdir"/$_sharedir/etc/lldb_*.py $_sharedir/etc/ +} + +_mv() { + local dest; for dest; do true; done # get last argument + mkdir -p "$dest" + mv $@ +} + +sha512sums="781799b29d83b4f0f433814bd818df034526db8e7f88c2df51d3b814eacafe8098d4bbe47ace951e1943325b3267b244007cf04f1f11083645b25aeacd40ebb6 rustc-1.17.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 +0994945aa3faa8106059a746b3a885b1a35bf604b4c1a09a006e1a66135ff94b828102864d1642744b06c60c34a7a3107661dd54413b81ccd7c56653c29e75a5 cargo-6b05583d71f982bcad049b9fa094c637c062e751-x86_64-unknown-linux-musl.tar.gz +b0a8883e4469b60edd150c84486ab950396d757220f97bd271529576614c6c3b49456098507503832c20619d4bd74246dbc99c78116634a68a6df994793e9a94 musl-support-dynamic-linking.patch +292c1cb4f751d830f5f1300d7ef94f573f698ac51e18243d7ff0d5a47bb1729bb2cbe8fb456e7a479213df5e5fbf49e360c9439d0f5ad7126cb72d161c91566a musl-fix-static-linking.patch +f436fddf7ab70ca5f1424081f5b75450270b200b3d997231323863e11addf76e1d65831a7ca09e3a5b7904ce828766c1f70b08326a175890298f28e5bc8646ef musl-fix-linux_musl_base.patch +c913d04ef419b2b6d8e453f72894070f263c9292abf97114a51884d475d03ce5b032053f1676ba9364800b4b35e394f707995058530ad5e4122c60f65ddd3db7 musl-fix-jemalloc.patch +dc6432293bd060d5e3a73f25870867654fae61995dcd919e244a2dc686b6107556deed8c59ca6002182bfeff5ebc1ca2b89c4028ab0fbfb79e65defe47c9b4b0 llvm-with-ffi.patch +5aaf6715b27b8b786740a55b91216d47985fbef3ccb0ef7e6a81696a2823671f8306143f7ecf77e66af91ef1500072524b9b4c7569508922ad5268df6080fda1 static-pie.patch +ff633f2a46c683ad698d1c09c98c06ce9ee9b8d55fa5593cdd485b439ebca3273794d29b5ff32b887be8666f52913a23af6e133c782bd0c4e2c88e306dd3a494 need-rpath.patch +d352614e7c774e181decae210140e789de7fc090327ff371981ad28a11ce51c8c01b27c1101a24bb84d75ed2f706f67868f7dbc52196d4ccdf4ebd2d6d6b6b5e minimize-rpath.patch +b00997c65d1a451fafae8b547893c5cbf03f028d2d70f6971aa670f34c2d6fc82728c740ac4a9909fc1999925ff300e4525cfec745cb9c9521e564eb166872a2 alpine-allow-crt-static.patch +498f4649163974afc4f042c43cd0c15d36784031514201a2962061f288a9336c2bc9749f8d2308b8ce3656f8097b5fc5bef505f61e2a6ed422ef4153f5339d77 alpine-move-py-scripts-to-share.patch +8d6206f8c50856724cf7b4c1854ec82547f040358a1c7d44abeacc27a5c205a963b1fec51e58ec06c68d85bd2f68a9e6e27ebe457f39e8dd043de17758f5063f alpine-change-rpath-to-rustlib.patch +aaf359dbfb8f379bef42647890e99ada4b5326c29f726edb16c51b23a5033b5e00363d2fb6d74a4f11dfbb241b21b22c578e2ec269ecd77a87cf20d3620b29a5 alpine-target.patch +79549055dea81379c890b495c82456ab497a9179ec6702c59e11d0748bc668f47fc3d6a69c27a0545bb87c01318631dffc69260bf2d4badc75f53cbf7fad7528 check-rustc" diff --git a/community/rust/alpine-allow-crt-static.patch b/community/rust/alpine-allow-crt-static.patch new file mode 100644 index 0000000000..5e81671f60 --- /dev/null +++ b/community/rust/alpine-allow-crt-static.patch @@ -0,0 +1,41 @@ +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 want to allow users to optionally +use static linking. + +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 staticaly 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; +--- a/src/test/compile-fail/crt-static-gated.rs ++++ b/src/test/compile-fail/crt-static-gated.rs +@@ -10,5 +10,6 @@ + + // compile-flags:-C target-feature=+crt-static + // error-pattern: specifying the `crt-static` target feature is only allowed ++// ignore-test we just want this feature and no one will stop us! + + fn main() {} diff --git a/community/rust/alpine-change-rpath-to-rustlib.patch b/community/rust/alpine-change-rpath-to-rustlib.patch new file mode 100644 index 0000000000..4be0f9d0a6 --- /dev/null +++ b/community/rust/alpine-change-rpath-to-rustlib.patch @@ -0,0 +1,37 @@ +From: Jakub Jirutka <jakub@jirutka.cz> +Date: Sat, 08 Aug 2016 19:56:00 +0200 +Subject: [PATCH] Change rpath for rustc/rustdoc to rustlib/$TARGET/lib + +Rust installs two identical sets of *.so libraries into /usr/lib and +/usr/lib/rustlib/$TARGET/lib. The former comes with the rustc component, +/usr/bin/rustc and /usr/bin/rustdoc are linked against them. The latter +comes with rust-std and are used for binaries dynamically linked against +Rust libraries (usually compiler plugins, like clippy). + +These *.so libraries don't keep stable ABI, so it's better to treat +them as private. Such libraries should not be exposed at standard paths +like /usr/lib, but use rpath. + +This patch changes rpath for binaries of the rustc component to +`$ORIGIN/../lib/rustlib/$TARGET/lib`. Duplicate libraries will be still +installed into /usr/lib, but we can simply remove them when packaging. + +Related upstream issues: + +* https://github.com/rust-lang/rust/issues/37971 +* https://github.com/rust-lang-nursery/rustup.rs/issues/837 + +--- a/src/bootstrap/bin/rustc.rs ++++ b/src/bootstrap/bin/rustc.rs +@@ -189,9 +189,9 @@ + if stage != "0" { + cmd.arg("-Z").arg("osx-rpath-install-name"); + } +- Some("-Wl,-rpath,@loader_path/../lib") ++ Some("-Wl,-rpath,@loader_path/../lib".to_string()) + } else if !target.contains("windows") { +- Some("-Wl,-rpath,$ORIGIN/../lib") ++ Some(format!("-Wl,-rpath,$ORIGIN/../lib/rustlib/{}/lib", target)) + } else { + None + }; diff --git a/community/rust/alpine-move-py-scripts-to-share.patch b/community/rust/alpine-move-py-scripts-to-share.patch new file mode 100644 index 0000000000..dcab4abd81 --- /dev/null +++ b/community/rust/alpine-move-py-scripts-to-share.patch @@ -0,0 +1,22 @@ +--- a/src/etc/rust-gdb ++++ b/src/etc/rust-gdb +@@ -14,7 +14,7 @@ + + # Find out where the pretty printer Python module is + RUSTC_SYSROOT=`rustc --print=sysroot` +-GDB_PYTHON_MODULE_DIRECTORY="$RUSTC_SYSROOT/lib/rustlib/etc" ++GDB_PYTHON_MODULE_DIRECTORY="$RUSTC_SYSROOT/share/rust/etc" + + # Run GDB with the additional arguments that load the pretty printers + PYTHONPATH="$PYTHONPATH:$GDB_PYTHON_MODULE_DIRECTORY" gdb \ +--- a/src/etc/rust-lldb ++++ b/src/etc/rust-lldb +@@ -33,7 +33,7 @@ + RUSTC_SYSROOT=`rustc --print sysroot` + + # Write the LLDB script to the tempfile +-echo "command script import \"$RUSTC_SYSROOT/lib/rustlib/etc/lldb_rust_formatters.py\"" >> $TMPFILE ++echo "command script import \"$RUSTC_SYSROOT/share/rust/etc/lldb_rust_formatters.py\"" >> $TMPFILE + echo "type summary add --no-value --python-function lldb_rust_formatters.print_val -x \".*\" --category Rust" >> $TMPFILE + echo "type category enable Rust" >> $TMPFILE + diff --git a/community/rust/alpine-target.patch b/community/rust/alpine-target.patch new file mode 100644 index 0000000000..e013a6bc2e --- /dev/null +++ b/community/rust/alpine-target.patch @@ -0,0 +1,154 @@ +From: Shiz <hi@shiz.me> +Date: Thu, 20 Aug 2017 01:52:36 +0200 +Subject: [PATCH] Add Alpine targets + +This adds `$arch-alpine-linux-musl` targets to Rust to encode our toolchain +and distribution-specific quirks instead of polluting the main musl target of +`$arch-unknown-linux-musl`. + +--- /dev/null ++++ b/src/librustc_back/target/i586_alpine_linux_musl.rs +@@ -0,0 +1,32 @@ ++// Copyright 2017 The Rust Project Developers. See the COPYRIGHT ++// file at the top-level directory of this distribution and at ++// http://rust-lang.org/COPYRIGHT. ++// ++// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or ++// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license ++// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your ++// option. This file may not be copied, modified, or distributed ++// except according to those terms. ++ ++use target::{Target, TargetResult}; ++ ++pub fn target() -> TargetResult { ++ let mut base = super::linux_musl_base::opts(); ++ base.cpu = "pentium4".to_string(); ++ base.max_atomic_width = Some(64); ++ base.crt_static_default = false; ++ base.static_position_independent_executables = true; ++ base.need_rpath = true; ++ ++ Ok(Target { ++ llvm_target: "i586-alpine-linux-musl".to_string(), ++ target_endian: "little".to_string(), ++ target_pointer_width: "32".to_string(), ++ data_layout: "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128".to_string(), ++ arch: "x86".to_string(), ++ target_os: "linux".to_string(), ++ target_env: "musl".to_string(), ++ target_vendor: "alpine".to_string(), ++ options: base, ++ }) ++} +--- a/src/librustc_back/target/mod.rs ++++ b/src/librustc_back/target/mod.rs +@@ -214,6 +214,9 @@ + ("thumbv7m-none-eabi", thumbv7m_none_eabi), + ("thumbv7em-none-eabi", thumbv7em_none_eabi), + ("thumbv7em-none-eabihf", thumbv7em_none_eabihf), ++ ++ ("i586-alpine-linux-musl", i586_alpine_linux_musl), ++ ("x86_64-alpine-linux-musl", x86_64_alpine_linux_musl), + } + + /// Everything `rustc` knows about how to compile for a specific target. +--- /dev/null ++++ b/src/librustc_back/target/x86_64_alpine_linux_musl.rs +@@ -0,0 +1,32 @@ ++// Copyright 2017 The Rust Project Developers. See the COPYRIGHT ++// file at the top-level directory of this distribution and at ++// http://rust-lang.org/COPYRIGHT. ++// ++// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or ++// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license ++// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your ++// option. This file may not be copied, modified, or distributed ++// except according to those terms. ++ ++use target::{Target, TargetResult}; ++ ++pub fn target() -> TargetResult { ++ let mut base = super::linux_musl_base::opts(); ++ base.cpu = "x86-64".to_string(); ++ base.max_atomic_width = Some(64); ++ base.crt_static_default = false; ++ base.static_position_independent_executables = true; ++ base.need_rpath = true; ++ ++ Ok(Target { ++ llvm_target: "x86_64-alpine-linux-musl".to_string(), ++ target_endian: "little".to_string(), ++ target_pointer_width: "64".to_string(), ++ data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), ++ arch: "x86_64".to_string(), ++ target_os: "linux".to_string(), ++ target_env: "musl".to_string(), ++ target_vendor: "alpine".to_string(), ++ options: base, ++ }) ++} +--- /dev/null ++++ b/mk/cfg/i586-alpine-linux-musl.mk +@@ -0,0 +1,29 @@ ++# i586-alpine-linux-musl configuration ++CC_i586-alpine-linux-musl=$(CC) ++CXX_i586-alpine-linux-musl=$(CXX) ++CPP_i586-alpine-linux-musl=$(CPP) ++AR_i586-alpine-linux-musl=$(AR) ++CFG_INSTALL_ONLY_RLIB_i586-alpine-linux-musl = 0 ++CFG_LIB_NAME_i586-alpine-linux-musl=lib$(1).so ++CFG_STATIC_LIB_NAME_i586-alpine-linux-musl=lib$(1).a ++CFG_LIB_GLOB_i586-alpine-linux-musl=lib$(1)-*.so ++CFG_JEMALLOC_CFLAGS_i586-alpine-linux-musl := ++CFG_GCCISH_CFLAGS_i586-alpine-linux-musl := -g -fPIC ++CFG_GCCISH_CXXFLAGS_i586-alpine-linux-musl := ++CFG_GCCISH_LINK_FLAGS_i586-alpine-linux-musl := ++CFG_GCCISH_DEF_FLAG_i586-alpine-linux-musl := ++CFG_LLC_FLAGS_i586-alpine-linux-musl := ++CFG_INSTALL_NAME_i586-alpine-linux-musl = ++CFG_EXE_SUFFIX_i586-alpine-linux-musl = ++CFG_WINDOWSY_i586-alpine-linux-musl := ++CFG_UNIXY_i586-alpine-linux-musl := 1 ++CFG_LDPATH_i586-alpine-linux-musl := ++CFG_RUN_i586-alpine-linux-musl=$(2) ++CFG_RUN_TARG_i586-alpine-linux-musl=$(call CFG_RUN_i586-alpine-linux-musl,,$(2)) ++CFG_GNU_TRIPLE_i586-alpine-linux-musl := i586-alpine-linux-musl ++CFG_THIRD_PARTY_OBJECTS_i586-alpine-linux-musl := ++CFG_INSTALLED_OBJECTS_i586-alpine-linux-musl := ++ ++NATIVE_DEPS_libc_T_i586-alpine-linux-musl += libc.a ++NATIVE_DEPS_std_T_i586-alpine-linux-musl += ++NATIVE_DEPS_unwind_T_i586-alpine-linux-musl += libunwind.a +--- /dev/null ++++ b/mk/cfg/x86_64-alpine-linux-musl.mk +@@ -0,0 +1,29 @@ ++# x86_64-alpine-linux-musl configuration ++CC_x86_64-alpine-linux-musl=$(CC) ++CXX_x86_64-alpine-linux-musl=$(CXX) ++CPP_x86_64-alpine-linux-musl=$(CPP) ++AR_x86_64-alpine-linux-musl=$(AR) ++CFG_INSTALL_ONLY_RLIB_x86_64-alpine-linux-musl = 0 ++CFG_LIB_NAME_x86_64-alpine-linux-musl=lib$(1).so ++CFG_STATIC_LIB_NAME_x86_64-alpine-linux-musl=lib$(1).a ++CFG_LIB_GLOB_x86_64-alpine-linux-musl=lib$(1)-*.so ++CFG_JEMALLOC_CFLAGS_x86_64-alpine-linux-musl := ++CFG_GCCISH_CFLAGS_x86_64-alpine-linux-musl := -g -fPIC ++CFG_GCCISH_CXXFLAGS_x86_64-alpine-linux-musl := ++CFG_GCCISH_LINK_FLAGS_x86_64-alpine-linux-musl := ++CFG_GCCISH_DEF_FLAG_x86_64-alpine-linux-musl := ++CFG_LLC_FLAGS_x86_64-alpine-linux-musl := ++CFG_INSTALL_NAME_x86_64-alpine-linux-musl = ++CFG_EXE_SUFFIX_x86_64-alpine-linux-musl = ++CFG_WINDOWSY_x86_64-alpine-linux-musl := ++CFG_UNIXY_x86_64-alpine-linux-musl := 1 ++CFG_LDPATH_x86_64-alpine-linux-musl := ++CFG_RUN_x86_64-alpine-linux-musl=$(2) ++CFG_RUN_TARG_x86_64-alpine-linux-musl=$(call CFG_RUN_x86_64-alpine-linux-musl,,$(2)) ++CFG_GNU_TRIPLE_x86_64-alpine-linux-musl := x86_64-alpine-linux-musl ++CFG_THIRD_PARTY_OBJECTS_x86_64-alpine-linux-musl := ++CFG_INSTALLED_OBJECTS_x86_64-alpine-linux-musl := ++ ++NATIVE_DEPS_libc_T_x86_64-alpine-linux-musl += libc.a ++NATIVE_DEPS_std_T_x86_64-alpine-linux-musl += ++NATIVE_DEPS_unwind_T_x86_64-alpine-linux-musl += libunwind.a diff --git a/community/rust/check-rustc b/community/rust/check-rustc new file mode 100755 index 0000000000..2e96a45f60 --- /dev/null +++ b/community/rust/check-rustc @@ -0,0 +1,106 @@ +#!/bin/sh +# vim: set ts=4: +set -eu + +RUSTC="$1" +TMPDIR="$(pwd)/.tmp-${0##*/}-$RANDOM" +failed=0 + + +_rustc() { + printf '\n$ rustc %s\n' "$*" + "$RUSTC" "$@" +} + +die() { + printf '\033[1;31mERROR:\033[0m %s\n' "$1" >&2 # bold red + exit 1 +} + +fail() { + printf '\033[1;31mFAIL:\033[0m %s\n' "$1" >&2 # bold red + failed=$(( failed + 1 )) +} + +assert_dynamic() { + readelf -l "$1" | grep -Fqw INTERP \ + && readelf -d "$1" | grep -Fqw NEEDED || { + fail "$1 is not a dynamic executable!" + readelf -ld "$1" + } +} + +assert_ok() { + "$1" || fail "$1 exited with status $?" +} + +assert_panic() { + local status=0 + "$1" || status=$? && [ "$status" = 101 ] \ + || fail "$1 exited with status $status, but expected 101" +} + +assert_pie() { + readelf -d "$1" | grep -Fw FLAGS_1 | grep -Fqw PIE || { + fail "$1 is not a PIE executable!" + readelf -d "$1" + } +} + +assert_static() { + test -f "$1" \ + && ! readelf -l "$1" | grep -Fqw INTERP \ + && ! readelf -d "$1" | grep -Fqw NEEDED || { + fail "$1 is not a static executable!" + readelf -ld "$1" + } +} + + +#-------------------- M a i n -------------------- + +test -d "$TMPDIR" && die "$TMPDIR already exists!" +mkdir -p "$TMPDIR" +trap "rm -R '$TMPDIR'" EXIT + +cd "$TMPDIR" + +cat >> hello_world.rs <<-EOF + fn main() { + println!("Hello, world!"); + } +EOF + +_rustc hello_world.rs +assert_ok ./hello_world +assert_dynamic hello_world +assert_pie hello_world +rm -f hello_world + +_rustc -C target-feature=-crt-static hello_world.rs +assert_ok ./hello_world +assert_dynamic hello_world +assert_pie hello_world +rm -f hello_world + +_rustc -C target-feature=+crt-static hello_world.rs +assert_ok ./hello_world +assert_static hello_world +assert_pie hello_world +rm -f hello_world + + +cat >> panic.rs <<-EOF + fn main() { + panic!("This should panic"); + } +EOF + +_rustc -C target-feature=-crt-static panic.rs +assert_panic ./panic + +_rustc -C target-feature=+crt-static panic.rs +assert_panic ./panic + + +[ "$failed" -eq 0 ] || die "$failed assertion(s) has failed" diff --git a/community/rust/llvm-with-ffi.patch b/community/rust/llvm-with-ffi.patch new file mode 100644 index 0000000000..42b0895e75 --- /dev/null +++ b/community/rust/llvm-with-ffi.patch @@ -0,0 +1,16 @@ +From: Jakub Jirutka <jakub@jirutka.cz> +Date: Thu, 04 Aug 2016 17:53:00 +0200 +Subject: [PATCH] Workaround for external LLVM built with LLVM_ENABLE_FFI + +Workaround for problem with LLVM_ENABLE_FFI described in +https://github.com/rust-lang/rust/issues/34486. + +--- a/src/librustc_llvm/lib.rs ++++ b/src/librustc_llvm/lib.rs +@@ -432,3 +432,6 @@ + mod llvmdeps { + include! { env!("CFG_LLVM_LINKAGE_FILE") } + } ++ ++#[link(name = "ffi")] ++extern {} diff --git a/community/rust/minimize-rpath.patch b/community/rust/minimize-rpath.patch new file mode 100644 index 0000000000..1fc0e1b722 --- /dev/null +++ b/community/rust/minimize-rpath.patch @@ -0,0 +1,102 @@ +From: Shiz <hi@shiz.me> +Date: Thu, 20 Aug 2017 01:44:12 +0200 +Subject: [PATCH] Minimize generated RPATH in end products + +By default, RPATH generation adds both the install prefix and the generated +relative path to the install prefix. This is unnecessary, so we add the install +prefix to a list of absolute paths to omit in the relative path generation, +and skip it there. + +--- a/src/librustc_trans/back/rpath.rs ++++ b/src/librustc_trans/back/rpath.rs +@@ -69,14 +69,15 @@ + debug!(" {:?}", libpath.display()); + } + ++ // The backup rpath is the global library location. ++ // We also omit this path from the relative rpaths. ++ let fallback_rpaths = vec![get_install_prefix_rpath(config)]; ++ + // Use relative paths to the libraries. Binaries can be moved + // as long as they maintain the relative relationship to the + // crates they depend on. +- let rel_rpaths = get_rpaths_relative_to_output(config, libs); ++ let rel_rpaths = get_rpaths_relative_to_output(config, libs, &fallback_rpaths); + +- // And a final backup rpath to the global library location. +- let fallback_rpaths = vec![get_install_prefix_rpath(config)]; +- + fn log_rpaths(desc: &str, rpaths: &[String]) { + debug!("{} rpaths:", desc); + for rpath in rpaths { +@@ -96,11 +97,13 @@ + } + + fn get_rpaths_relative_to_output(config: &mut RPathConfig, +- libs: &[PathBuf]) -> Vec<String> { +- libs.iter().map(|a| get_rpath_relative_to_output(config, a)).collect() ++ libs: &[PathBuf], ++ omit: &Vec<String>) -> Vec<String> { ++ libs.iter().filter_map(|a| get_rpath_relative_to_output(config, a, omit)).collect() + } + +-fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String { ++fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path, ++ omit: &Vec<String>) -> Option<String> { + // Mac doesn't appear to support $ORIGIN + let prefix = if config.is_like_osx { + "@loader_path" +@@ -114,11 +117,18 @@ + let mut output = cwd.join(&config.out_filename); + output.pop(); + let output = fs::canonicalize(&output).unwrap_or(output); +- let relative = path_relative_from(&lib, &output) +- .expect(&format!("couldn't create relative path from {:?} to {:?}", output, lib)); ++ + // FIXME (#9639): This needs to handle non-utf8 paths +- format!("{}/{}", prefix, +- relative.to_str().expect("non-utf8 component in path")) ++ let libpath = lib.to_str().expect("non-utf8 component in path").to_string(); ++ if omit.contains(&libpath) { ++ None ++ } else { ++ let relative = path_relative_from(&lib, &output) ++ .expect(&format!("couldn't create relative path from {:?} to {:?}", output, lib)); ++ // FIXME (#9639): This needs to handle non-utf8 paths ++ Some(format!("{}/{}", prefix, ++ relative.to_str().expect("non-utf8 component in path"))) ++ } + } + + // This routine is adapted from the *old* Path's `path_relative_from` +@@ -239,6 +249,7 @@ + #[test] + fn test_rpath_relative() { + if cfg!(target_os = "macos") { ++ let omit = Vec::new(); + let config = &mut RPathConfig { + used_crates: Vec::new(), + has_rpath: true, +@@ -248,9 +259,11 @@ + get_install_prefix_lib_path: &mut || panic!(), + }; + let res = get_rpath_relative_to_output(config, +- Path::new("lib/libstd.so")); ++ Path::new("lib/libstd.so"), ++ &omit); + assert_eq!(res, "@loader_path/../lib"); + } else { ++ let omit = Vec::new(); + let config = &mut RPathConfig { + used_crates: Vec::new(), + out_filename: PathBuf::from("bin/rustc"), +@@ -260,7 +273,8 @@ + linker_is_gnu: true, + }; + let res = get_rpath_relative_to_output(config, +- Path::new("lib/libstd.so")); ++ Path::new("lib/libstd.so"), ++ &omit); + assert_eq!(res, "$ORIGIN/../lib"); + } + } diff --git a/community/rust/musl-fix-jemalloc.patch b/community/rust/musl-fix-jemalloc.patch new file mode 100644 index 0000000000..345398a301 --- /dev/null +++ b/community/rust/musl-fix-jemalloc.patch @@ -0,0 +1,61 @@ +From 536011d929ecbd1170baf34e09580e567c971f95 Mon Sep 17 00:00:00 2001 +From: Shiz <hi@shiz.me> +Date: Sat, 8 Apr 2017 20:36:00 +0200 +Subject: [PATCH] Fix jemalloc support for musl + +Just like DragonFlyBSD, using the same symbols as the system allocator will +result in a segmentation fault at runtime due to allocator mismatches. +As such, prefix the jemalloc symbols instead. + +Upstream-Issue: https://github.com/rust-lang/rust/pull/41168 +--- + src/liballoc_jemalloc/build.rs | 2 +- + src/liballoc_jemalloc/lib.rs | 10 +++++----- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/liballoc_jemalloc/build.rs b/src/liballoc_jemalloc/build.rs +index ae040a2..f3a0eeb 100644 +--- a/src/liballoc_jemalloc/build.rs ++++ b/src/liballoc_jemalloc/build.rs +@@ -138,7 +138,7 @@ fn main() { + // should be good to go! + cmd.arg("--with-jemalloc-prefix=je_"); + cmd.arg("--disable-tls"); +- } else if target.contains("dragonfly") { ++ } else if target.contains("dragonfly") || target.contains("musl") { + cmd.arg("--with-jemalloc-prefix=je_"); + } + +diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs +index a7a67ef..83cc1ef 100644 +--- a/src/liballoc_jemalloc/lib.rs ++++ b/src/liballoc_jemalloc/lib.rs +@@ -51,23 +51,23 @@ mod imp { + // request it as unprefixing cause segfaults (mismatches in allocators). + extern "C" { + #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", +- target_os = "dragonfly", target_os = "windows"), ++ target_os = "dragonfly", target_os = "windows", target_env = "musl"), + link_name = "je_mallocx")] + fn mallocx(size: size_t, flags: c_int) -> *mut c_void; + #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", +- target_os = "dragonfly", target_os = "windows"), ++ target_os = "dragonfly", target_os = "windows", target_env = "musl"), + link_name = "je_rallocx")] + fn rallocx(ptr: *mut c_void, size: size_t, flags: c_int) -> *mut c_void; + #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", +- target_os = "dragonfly", target_os = "windows"), ++ target_os = "dragonfly", target_os = "windows", target_env = "musl"), + link_name = "je_xallocx")] + fn xallocx(ptr: *mut c_void, size: size_t, extra: size_t, flags: c_int) -> size_t; + #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", +- target_os = "dragonfly", target_os = "windows"), ++ target_os = "dragonfly", target_os = "windows", target_env = "musl"), + link_name = "je_sdallocx")] + fn sdallocx(ptr: *mut c_void, size: size_t, flags: c_int); + #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", +- target_os = "dragonfly", target_os = "windows"), ++ target_os = "dragonfly", target_os = "windows", target_env = "musl"), + link_name = "je_nallocx")] + fn nallocx(size: size_t, flags: c_int) -> size_t; + } diff --git a/community/rust/musl-fix-linux_musl_base.patch b/community/rust/musl-fix-linux_musl_base.patch new file mode 100644 index 0000000000..38194290cb --- /dev/null +++ b/community/rust/musl-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/community/rust/musl-fix-static-linking.patch b/community/rust/musl-fix-static-linking.patch new file mode 100644 index 0000000000..85de05e542 --- /dev/null +++ b/community/rust/musl-fix-static-linking.patch @@ -0,0 +1,200 @@ +From: Shiz <hi@shiz.me> +Date: Fri, 21 Apr 2017 01:04:46 +0200 +Subject: [PATCH] Support fully static linking on *nix targets + +This patch adds support for full static linking on *nix targets. + +It adds `Session::fully_static()` to determine whether full static linking +should be utilised. By default, this is the case if the target is not +MSVC-like and the `crt-static` target feature is requested, as for *nix +targets this implies a fully static result. In the future, a target feature +or other compile option could perhaps be added to have the invoker decide +this more flexibly at run-time. + +It also adds the proper linker argument for static result objects to `Linker` +and implements them for `GnuLinker` and `MsvcLinker`. Additionally, when +statically linking, all the objects are linked in a group (-Wl,-( and -Wl,-) +on GNU-compatible linkers) to resolve dependency and order issues that may +normally arise. For `MsvcLinker`, this is a no-op as it already exhibits +this behavior by default. + +Finally, if no linking preference is given for native libraries +(`NativeLibraryKind::NativeUnknown`), they are linked statically if full +static linking is requested, instead of dynamically as before. + +--- a/src/librustc/session/mod.rs ++++ b/src/librustc/session/mod.rs +@@ -409,6 +409,11 @@ + return crt_static; + } + ++ pub fn fully_static(&self) -> bool { ++ // TODO: figure out better semantics for this, possibly a target option? ++ return self.crt_static() && !self.target.target.options.is_like_msvc ++ } ++ + pub fn must_not_eliminate_frame_pointers(&self) -> bool { + self.opts.debuginfo != DebugInfoLevel::NoDebugInfo || + !self.target.target.options.eliminate_frame_pointer +--- a/src/librustc_trans/back/link.rs ++++ b/src/librustc_trans/back/link.rs +@@ -239,8 +239,8 @@ + /// Checks if target supports crate_type as output + pub fn invalid_output_for_target(sess: &Session, + crate_type: config::CrateType) -> bool { +- match (sess.target.target.options.dynamic_linking, +- sess.target.target.options.executables, crate_type) { ++ let dynamic_linking = sess.target.target.options.dynamic_linking && !sess.fully_static(); ++ match (dynamic_linking, sess.target.target.options.executables, crate_type) { + (false, _, config::CrateTypeCdylib) | + (false, _, config::CrateTypeProcMacro) | + (false, _, config::CrateTypeDylib) => true, +@@ -840,6 +840,10 @@ + + let used_link_args = sess.cstore.used_link_args(); + ++ if crate_type == config::CrateTypeExecutable && sess.fully_static() { ++ cmd.static_executable(); ++ } ++ + if crate_type == config::CrateTypeExecutable && + t.options.position_independent_executables { + let empty_vec = Vec::new(); +@@ -870,15 +870,8 @@ + cmd.no_default_libraries(); + } + +- // Take careful note of the ordering of the arguments we pass to the linker +- // here. Linkers will assume that things on the left depend on things to the +- // right. Things on the right cannot depend on things on the left. This is +- // all formally implemented in terms of resolving symbols (libs on the right +- // resolve unknown symbols of libs on the left, but not vice versa). ++ // We have organized the arguments we pass to the linker as such: + // +- // For this reason, we have organized the arguments we pass to the linker as +- // such: +- // + // 1. The local object that LLVM just generated + // 2. Local native libraries + // 3. Upstream rust libraries +--- a/src/librustc_trans/back/link.rs ++++ b/src/librustc_trans/back/link.rs +@@ -951,17 +951,12 @@ + // list can't depend on items higher up in the list. For example nothing can + // depend on what we just generated (e.g. that'd be a circular dependency). + // Upstream rust libraries are not allowed to depend on our local native +- // libraries as that would violate the structure of the DAG, in that +- // scenario they are required to link to them as well in a shared fashion. +- // +- // Note that upstream rust libraries may contain native dependencies as +- // well, but they also can't depend on what we just started to add to the +- // link line. And finally upstream native libraries can't depend on anything +- // in this DAG so far because they're only dylibs and dylibs can only depend +- // on other dylibs (e.g. other native deps). ++ // libraries as that would violate the structure of the DAG. ++ cmd.start_group(); + add_local_native_libraries(cmd, sess); + add_upstream_rust_crates(cmd, sess, crate_type, tmpdir); + add_upstream_native_libraries(cmd, sess, crate_type); ++ cmd.end_group(); + + // # Telling the linker what we're doing + +@@ -983,11 +983,14 @@ + cmd.link_whole_staticlib(&l.name.as_str(), &search_path); + } + +- cmd.hint_dynamic(); ++ let fully_static = sess.fully_static(); ++ if !fully_static { ++ cmd.hint_dynamic(); ++ } + + for lib in others { + match lib.kind { +- NativeLibraryKind::NativeUnknown => cmd.link_dylib(&lib.name.as_str()), ++ NativeLibraryKind::NativeUnknown => if fully_static { cmd.link_staticlib(&lib.name.as_str()) } else { cmd.link_dylib(&lib.name.as_str()) }, + NativeLibraryKind::NativeFramework => cmd.link_framework(&lib.name.as_str()), + NativeLibraryKind::NativeStatic => bug!(), + } +--- 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); +@@ -93,6 +93,8 @@ + fn no_whole_archives(&mut self); + fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType); + fn subsystem(&mut self, subsystem: &str); ++ fn start_group(&mut self); ++ fn end_group(&mut self); + } + + pub struct GnuLinker<'a> { +@@ -116,6 +117,9 @@ + 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 start_group(&mut self) { self.cmd.arg("-Wl,-("); } ++ fn end_group(&mut self) { self.cmd.arg("-Wl,-)"); } + 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) { +@@ -484,6 +488,14 @@ + if subsystem == "windows" { + self.cmd.arg("/ENTRY:mainCRTStartup"); + } ++ } ++ ++ fn start_group(&mut self) { ++ // Not needed ++ } ++ ++ fn end_group(&mut self) { ++ // Not needed + } + } + +@@ -562,6 +562,10 @@ + // noop + } + ++ fn static_executable(&mut self) { ++ // noop ++ } ++ + fn args(&mut self, args: &[String]) { + self.cmd.args(args); + } +@@ -657,6 +661,14 @@ + + fn subsystem(&mut self, _subsystem: &str) { + // noop ++ } ++ ++ fn start_group(&mut self) { ++ self.cmd.arg("-Wl,-("); ++ } ++ ++ fn end_group(&mut self) { ++ self.cmd.arg("-Wl,-)"); + } + } + diff --git a/community/rust/musl-support-dynamic-linking.patch b/community/rust/musl-support-dynamic-linking.patch new file mode 100644 index 0000000000..7c4e93681b --- /dev/null +++ b/community/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 + diff --git a/community/rust/need-rpath.patch b/community/rust/need-rpath.patch new file mode 100644 index 0000000000..b345d27d92 --- /dev/null +++ b/community/rust/need-rpath.patch @@ -0,0 +1,62 @@ +From: Shiz <hi@shiz.me> +Date: Thu, 20 Aug 2017 01:48:22 +0200 +Subject: [PATCH] Add need_rpath target option to force RPATH generation + +This adds a `need_rpath` option to the target options in order to implicitly +have the equivalent of `-C rpath` specified by default for final products +(executables and dynamic libraries), so that RPATHs are always added. + +We have to skip this step in the bootstrap phase as it does its own manual +RPATH additions, but unfortunately there's no clean way to detect this. +As such, we have to resort to checking the `RUSTC_BOOTSTRAP` variable. +Hacky hacky! + +--- a/src/librustc_back/target/mod.rs ++++ b/src/librustc_back/target/mod.rs +@@ -341,6 +341,8 @@ + pub allows_weak_linkage: bool, + /// Whether the linker support rpaths or not. Defaults to false. + pub has_rpath: bool, ++ /// Whether to force rpath support on by default. Defaults to false. ++ pub need_rpath: bool, + /// Whether to disable linking to the default libraries, typically corresponds + /// to `-nodefaultlibs`. Defaults to true. + pub no_default_libraries: bool, +@@ -434,6 +436,7 @@ + linker_is_gnu: false, + allows_weak_linkage: true, + has_rpath: false, ++ need_rpath: false, + no_default_libraries: true, + position_independent_executables: false, + static_position_independent_executables: false, +@@ -616,6 +616,7 @@ + key!(linker_is_gnu, bool); + key!(allows_weak_linkage, bool); + key!(has_rpath, bool); ++ key!(need_rpath, bool); + key!(no_default_libraries, bool); + key!(position_independent_executables, bool); + key!(static_position_independent_executables, bool); +@@ -781,6 +782,7 @@ + target_option_val!(linker_is_gnu); + target_option_val!(allows_weak_linkage); + target_option_val!(has_rpath); ++ target_option_val!(need_rpath); + target_option_val!(no_default_libraries); + target_option_val!(position_independent_executables); + target_option_val!(static_position_independent_executables); +--- a/src/librustc_trans/back/link.rs ++++ b/src/librustc_trans/back/link.rs +@@ -901,7 +901,10 @@ + // FIXME (#2397): At some point we want to rpath our guesses as to + // where extern libraries might live, based on the + // addl_lib_search_paths +- if sess.opts.cg.rpath { ++ // XXX: hacky hacky ++ let bootstrap = env::var("RUSTC_BOOTSTRAP").is_ok(); ++ if !bootstrap && !sess.fully_static() && ++ (sess.opts.cg.rpath || sess.target.target.options.need_rpath) { + let sysroot = sess.sysroot(); + let target_triple = &sess.opts.target_triple; + let mut get_install_prefix_lib_path = || { diff --git a/community/rust/static-pie.patch b/community/rust/static-pie.patch new file mode 100644 index 0000000000..4c4e4b77c1 --- /dev/null +++ b/community/rust/static-pie.patch @@ -0,0 +1,108 @@ +From: Shiz <hi@shiz.me> +Date: Tue, 11 Apr 2017 04:37:00 +0200 +Subject: [PATCH] Add support for static PIE executables + +Note that static PIE binaries are reported as dynamically linked by file(1): + + $ 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 + +In addition, ldd(1) reports that it's linked with ldd, as it can't find any +dependencies except itself loaded into the process: + + $ 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 +@@ -914,13 +914,9 @@ + + if crate_type == config::CrateTypeExecutable && + t.options.position_independent_executables { +- let empty_vec = Vec::new(); +- let args = sess.opts.cg.link_args.as_ref().unwrap_or(&empty_vec); +- let more_args = &sess.opts.cg.link_arg; +- let mut args = args.iter().chain(more_args.iter()).chain(used_link_args.iter()); +- ++ let static_pie = t.options.static_position_independent_executables; + if get_reloc_model(sess) == llvm::RelocMode::PIC +- && !args.any(|x| *x == "-static") { ++ && (!sess.fully_static() || static_pie) { + cmd.position_independent_executable(); + } + } +--- a/src/librustc_back/target/mod.rs ++++ b/src/librustc_back/target/mod.rs +@@ -612,6 +612,7 @@ + key!(has_rpath, bool); + key!(no_default_libraries, bool); + key!(position_independent_executables, bool); ++ key!(static_position_independent_executables, bool); + key!(archive_format); + key!(allow_asm, bool); + key!(custom_unwind_resume, bool); +@@ -776,6 +777,7 @@ + target_option_val!(has_rpath); + target_option_val!(no_default_libraries); + target_option_val!(position_independent_executables); ++ target_option_val!(static_position_independent_executables); + target_option_val!(archive_format); + target_option_val!(allow_asm); + target_option_val!(custom_unwind_resume); |