Skip to content

Instantly share code, notes, and snippets.

@japaric
Last active May 12, 2022 14:29
Show Gist options
  • Save japaric/52b8816a4c86f5a4699bcc50ebc3e020 to your computer and use it in GitHub Desktop.
Save japaric/52b8816a4c86f5a4699bcc50ebc3e020 to your computer and use it in GitHub Desktop.
rustc for x86_64-unknown-linux-musl
# Build an statically linked rustc (with host=x86_64-unknown-linux-musl)
# Last tested on: 9316ae515e2f8f3f497fb4f1559910c1eef2433d
# Usage:
# # patches must be in $(pwd)
# $ ls *.patch
# liblibc.patch rust.patch
#
# $ docker run --rm -it -v $(pwd):/mnt ubuntu:16.04
#
# # inside the docker container
# $ bash /mnt/build.sh
# # FIXMEs
#
# - a rustc built with jemalloc enabled crashes with SIGBUS when compiling anything
#
# # TODOs
#
# - Don't copy crt*.o to stageN
# - Upstream the LLVM patches in `apply_patches()` to rust-lang/llvm
set -ex
host=x86_64-unknown-linux-musl
user=rustbuild
as_user() {
su -c 'bash -c "'"${@}"'"' $user
}
mk_user() {
useradd -m $user
}
install_deps() {
apt-get update
# musl-cross-make
apt-get install -y --no-install-recommends bzip2 ca-certificates curl g++ make patch rsync \
wget xz-utils
# Rust deps
apt-get install -y --no-install-recommends cmake file git python
}
mk_cross_toolchain() {
local td=$(mktemp -d)
local repo=musl-cross-make
local version=0.9.2
pushd $td
curl -L https://github.com/richfelker/$repo/archive/v$version.tar.gz | tar xzf -
cd $repo-$version
TARGET=$host make
cd build-*
TARGET=$host make install
rsync -av output/ /usr/local/
popd
rm -rf $td
pushd /usr/local/bin
ln -s $host-gcc musl-gcc
ln -s $host-g++ musl-g++
popd
}
fetch_rust() {
as_user 'git clone --depth 1 https://github.com/rust-lang/rust ~/rust'
}
apply_patches() {
# TODO upstream these patches to rust-lang/llvm
as_user "
git config --global user.email 'your@example.com'
git config --global user.name 'Your Name'
cd ~/rust
git submodule init
git submodule update src/llvm
cd src/llvm
curl -s http://git.alpinelinux.org/cgit/aports/plain/main/llvm/llvm-0002-Fix-build-with-musl-libc.patch | git am
curl -s http://git.alpinelinux.org/cgit/aports/plain/main/llvm/llvm-0003-Fix-DynamicLibrary-to-build-with-musl-libc.patch | git am
cd ../..
git add src/llvm
git commit -m 'patch llvm to work with musl'
git submodule update src/liblibc
cd src/liblibc
git am /mnt/liblibc.patch
cd ../..
git add src/liblibc
git commit -m 'update liblibc'
git am /mnt/rust.patch
"
}
mk_rustc() {
as_user "
mkdir ~/build
cd ~/build
../rust/configure --enable-rustbuild --disable-jemalloc --enable-llvm-static-stdcpp --host=$host --musl-root=/usr/local/$host
make"
}
main() {
mk_user
install_deps
mk_cross_toolchain
fetch_rust
apply_patches
mk_rustc
}
main
From a3b8f96735be718ad74945ba1988bd59d65b3f59 Mon Sep 17 00:00:00 2001
From: Your Name <your@example.com>
Date: Tue, 26 Jul 2016 03:32:02 +0000
Subject: [PATCH] x86_64-musl: don't link statically
---
src/unix/mod.rs | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/unix/mod.rs b/src/unix/mod.rs
index 214f2cc..49d8a9b 100644
--- a/src/unix/mod.rs
+++ b/src/unix/mod.rs
@@ -199,7 +199,9 @@ cfg_if! {
} 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")),
+ } else if #[cfg(any(all(target_env = "musl",
+ not(target_arch = "mips"),
+ not(target_arch = "x86_64")),
target_env = "musleabi",
target_env = "musleabihf"))] {
#[link(name = "c", kind = "static")]
--
2.7.4
From 09d0b132a2a9603c90d13d04baaf460ccfc6f22f Mon Sep 17 00:00:00 2001
From: Your Name <your@example.com>
Date: Tue, 26 Jul 2016 21:37:48 +0000
Subject: [PATCH] x86_64-musl: don't link statically
---
src/bootstrap/sanity.rs | 2 +-
src/librustc_back/target/x86_64_unknown_linux_musl.rs | 2 +-
src/libunwind/build.rs | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs
index 7c0f09c..0e15438 100644
--- a/src/bootstrap/sanity.rs
+++ b/src/bootstrap/sanity.rs
@@ -100,7 +100,7 @@ pub fn check(build: &mut Build) {
}
// Make sure musl-root is valid if specified
- if target.contains("musl") && (target.contains("x86_64") || target.contains("i686")) {
+ if target.contains("musl") && target.contains("i686") {
match build.config.musl_root {
Some(ref root) => {
if fs::metadata(root.join("lib/libc.a")).is_err() {
diff --git a/src/librustc_back/target/x86_64_unknown_linux_musl.rs b/src/librustc_back/target/x86_64_unknown_linux_musl.rs
index 3301e0e..6bf22a8 100644
--- 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());
diff --git a/src/libunwind/build.rs b/src/libunwind/build.rs
index ebe6fd5..c11e1eb 100644
--- a/src/libunwind/build.rs
+++ b/src/libunwind/build.rs
@@ -16,7 +16,7 @@ fn main() {
let target = env::var("TARGET").unwrap();
if target.contains("linux") {
- if target.contains("musl") && (target.contains("x86_64") || target.contains("i686")) {
+ if target.contains("musl") && target.contains("i686") {
println!("cargo:rustc-link-lib=static=unwind");
} else if !target.contains("android") {
println!("cargo:rustc-link-lib=gcc_s");
--
2.7.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment