Skip to content

Commit 39a75e3

Browse files
committed
Auto merge of #58575 - mati865:musl_toolchain, r=<try>
WIP Musl host toolchain Based on #55163 and #57359 Depends on #55566 CC #57439 ### How it works Tested compiler made by `dist` on glibc and musl based distributions and verified binaries it produces: * Ubuntu (glibc) - installed it as a target for host toolchain and observed no regressions for static (default) linking, dynamic linking apparently requires musl build libgcc so I didn't test it. * Alpine (musl) - installed as the host toolchain, by default it links statically (executables are portable and work on glibc distributions) but with `-C target-feature=-crt-static` Rust flag it links dynamically (executables require musl built libraries). ### What's debatable It should be decided whether this toolchain should link dynamically or statically when using it on musl distribution. I believe the distributions would prefer dynamic linking but it'd be misleading because `$ARCH-unknown-linux-musl` target links statically on the other hosts. Another problem is using `RUSTFLAGS='-C target-feature=-crt-static'` for dynamic builds which is really uncomfortable. To address both issues I suggest leaving `$ARCH-unknown-linux-musl` static for both host and cross target and introducing "alias triple" `$ARCH-unknown-linux-dynmusl`. It'd be the same as `$ARCH-unknown-linux-musl` (and use the same libraries to avoid duplication) but it'd link dynamically. <del> ### Why it's still WIP (help wanted) I'm having a hard time getting all tests to pass and I'd appreciate help. Non-verbose error: <details> ``` Testing proc_macro stage1 (x86_64-unknown-linux-musl -> x86_64-unknown-linux-musl) Compiling proc_macro v0.0.0 (/checkout/src/libproc_macro) error[E0463]: can't find crate for `std` error[E0463]: can't find crate for `std` error: aborting due to previous error For more information about this error, try `rustc --explain E0463`. error: aborting due to previous error For more information about this error, try `rustc --explain E0463`. [RUSTC-TIMING] proc_macro test:true 0.529 [RUSTC-TIMING] proc_macro test:false 0.530 error: Could not compile `proc_macro`. warning: build failed, waiting for other jobs to finish... error: Could not compile `proc_macro`. To learn more, run the command again with --verbose. command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "test" "--target" "x86_64-unknown-linux-musl" "-j" "16" "--release" "--locked" "--manifest-path" "/checkout/src/libtest/Cargo.toml" "-p" "proc_macro" "--" expected success, got: exit code: 101 failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test --host x86_64-unknown-linux-musl --target x86_64-unknown-linux-musl ``` </details> Verbose error: <details> ``` Testing proc_macro stage1 (x86_64-unknown-linux-musl -> x86_64-unknown-linux-musl) Compiling proc_macro v0.0.0 (/checkout/src/libproc_macro) Running `/checkout/obj/build/bootstrap/debug/rustc --edition=2018 --crate-name proc_macro src/libproc_macro/lib.rs --color never --crate-type lib --emit=dep-info,link -C opt-level=2 -C metadata=09ddd3ecc930ab63 -C extra-filename=-09ddd3ecc930ab63 --out-dir /checkout/obj/build/x86_64-unknown-linux-musl/stage1-test/x86_64-unknown-linux-musl/release/deps --target x86_64-unknown-linux-musl -L dependency=/checkout/obj/build/x86_64-unknown-linux-musl/stage1-test/x86_64-unknown-linux-musl/release/deps -L dependency=/checkout/obj/build/x86_64-unknown-linux-musl/stage1-test/release/deps -C target-feature=-crt-static` Running `/checkout/obj/build/bootstrap/debug/rustc --edition=2018 --crate-name proc_macro src/libproc_macro/lib.rs --color never --emit=dep-info,link -C opt-level=2 --test -C metadata=a564d363930469c8 -C extra-filename=-a564d363930469c8 --out-dir /checkout/obj/build/x86_64-unknown-linux-musl/stage1-test/x86_64-unknown-linux-musl/release/deps --target x86_64-unknown-linux-musl -L dependency=/checkout/obj/build/x86_64-unknown-linux-musl/stage1-test/x86_64-unknown-linux-musl/release/deps -L dependency=/checkout/obj/build/x86_64-unknown-linux-musl/stage1-test/release/deps -C target-feature=-crt-static` error[E0463]: can't find crate for `std` error[E0463]: can't find crate for `std` error: aborting due to previous error For more information about this error, try `rustc --explain E0463`. error: aborting due to previous error For more information about this error, try `rustc --explain E0463`. [RUSTC-TIMING] proc_macro test:false 0.248 error: Could not compile `proc_macro`. Caused by: process didn't exit successfully: `/checkout/obj/build/bootstrap/debug/rustc --edition=2018 --crate-name proc_macro src/libproc_macro/lib.rs --color never --crate-type lib --emit=dep-info,link -C opt-level=2 -C metadata=09ddd3ecc930ab63 -C extra-filename=-09ddd3ecc930ab63 --out-dir /checkout/obj/build/x86_64-unknown-linux-musl/stage1-test/x86_64-unknown-linux-musl/release/deps --target x86_64-unknown-linux-musl -L dependency=/checkout/obj/build/x86_64-unknown-linux-musl/stage1-test/x86_64-unknown-linux-musl/release/deps -L dependency=/checkout/obj/build/x86_64-unknown-linux-musl/stage1-test/release/deps -C target-feature=-crt-static` (exit code: 1) warning: build failed, waiting for other jobs to finish... [RUSTC-TIMING] proc_macro test:true 0.248 error: Could not compile `proc_macro`. Caused by: process didn't exit successfully: `/checkout/obj/build/bootstrap/debug/rustc --edition=2018 --crate-name proc_macro src/libproc_macro/lib.rs --color never --emit=dep-info,link -C opt-level=2 --test -C metadata=a564d363930469c8 -C extra-filename=-a564d363930469c8 --out-dir /checkout/obj/build/x86_64-unknown-linux-musl/stage1-test/x86_64-unknown-linux-musl/release/deps --target x86_64-unknown-linux-musl -L dependency=/checkout/obj/build/x86_64-unknown-linux-musl/stage1-test/x86_64-unknown-linux-musl/release/deps -L dependency=/checkout/obj/build/x86_64-unknown-linux-musl/stage1-test/release/deps -C target-feature=-crt-static` (exit code: 1) command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "test" "--target" "x86_64-unknown-linux-musl" "-j" "16" "--release" "--locked" "--manifest-path" "/checkout/src/libtest/Cargo.toml" "--verbose" "-p" "proc_macro" "--" expected success, got: exit code: 101 failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test --host x86_64-unknown-linux-musl --target x86_64-unknown-linux-musl ``` </details> Whole tests non-verbose output: [rust-tests.log](https://github.com/rust-lang/rust/files/2879945/rust-tests.log) I think the error is because build system (correctly?) tries to use `obj/build/x86_64-unknown-linux-musl/stage1-test/x86_64-unknown-linux-musl/release/deps` which is empty but `obj/build/x86_64-unknown-linux-gnu/stage1-test/x86_64-unknown-linux-musl/release/deps` contains required libs. </del>
2 parents 88f755f + bba272d commit 39a75e3

File tree

9 files changed

+138
-24
lines changed

9 files changed

+138
-24
lines changed

.travis.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ matrix:
1717
include:
1818
# Images used in testing PR and try-build should be run first.
1919
- env: IMAGE=x86_64-gnu-llvm-6.0 RUST_BACKTRACE=1
20-
if: type = pull_request OR branch = auto
20+
if: branch = auto
2121

2222
- env: IMAGE=dist-x86_64-linux DEPLOY=1
2323
if: branch = try OR branch = auto
@@ -159,7 +159,7 @@ matrix:
159159
- env: IMAGE=dist-x86_64-freebsd DEPLOY=1
160160
if: branch = auto
161161
- env: IMAGE=dist-x86_64-musl DEPLOY=1
162-
if: branch = auto
162+
# if: branch = auto
163163
- env: IMAGE=dist-x86_64-netbsd DEPLOY=1
164164
if: branch = auto
165165
- env: IMAGE=asmjs
@@ -185,7 +185,7 @@ matrix:
185185
- env: IMAGE=x86_64-gnu-distcheck
186186
if: branch = auto
187187
- env: IMAGE=mingw-check
188-
if: type = pull_request OR branch = auto
188+
if: branch = auto
189189

190190
- stage: publish toolstate
191191
if: branch = master AND type = push

src/bootstrap/test.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1636,8 +1636,9 @@ impl Step for Crate {
16361636
// libstd, then what we're actually testing is the libstd produced in
16371637
// stage1. Reflect that here by updating the compiler that we're working
16381638
// with automatically.
1639+
// FIXME(mati865): do similar for the other branch if this is correct
16391640
let compiler = if builder.force_use_stage1(compiler, target) {
1640-
builder.compiler(1, compiler.host)
1641+
builder.compiler(1, builder.config.build)
16411642
} else {
16421643
compiler.clone()
16431644
};
@@ -1802,6 +1803,10 @@ impl Step for CrateRustdoc {
18021803
cargo.arg("--");
18031804
cargo.args(&builder.config.cmd.test_args());
18041805

1806+
if target.contains("musl") {
1807+
cargo.arg("'-Ctarget-feature=-crt-static'");
1808+
}
1809+
18051810
if !builder.config.verbose_tests {
18061811
cargo.arg("--quiet");
18071812
}

src/ci/docker/dist-x86_64-musl/Dockerfile

+16-10
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
44
g++ \
55
make \
66
file \
7+
wget \
78
curl \
89
ca-certificates \
910
python2.7 \
@@ -18,19 +19,17 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
1819

1920
WORKDIR /build/
2021

21-
COPY scripts/musl.sh /build/
22+
COPY scripts/musl-toolchain.sh /build/
2223
# We need to mitigate rust-lang/rust#34978 when compiling musl itself as well
23-
RUN CC=gcc \
24-
CFLAGS="-Wa,-mrelax-relocations=no" \
25-
CXX=g++ \
26-
CXXFLAGS="-Wa,-mrelax-relocations=no" \
27-
bash musl.sh x86_64 && rm -rf /build
24+
# TODO: Check what this issue is and if we can ignore it
25+
26+
RUN bash musl-toolchain.sh x86_64-linux-musl && rm -rf build
2827

2928
COPY scripts/sccache.sh /scripts/
3029
RUN sh /scripts/sccache.sh
3130

3231
ENV RUST_CONFIGURE_ARGS \
33-
--musl-root-x86_64=/musl-x86_64 \
32+
--musl-root-x86_64=/usr/local/x86_64-linux-musl \
3433
--enable-extended \
3534
--disable-docs
3635

@@ -41,6 +40,13 @@ ENV RUST_CONFIGURE_ARGS \
4140
# See: https://github.com/rust-lang/rust/issues/34978
4241
ENV CFLAGS_x86_64_unknown_linux_musl=-Wa,-mrelax-relocations=no
4342

44-
ENV SCRIPT \
45-
python2.7 ../x.py test --target x86_64-unknown-linux-musl && \
46-
python2.7 ../x.py dist --target x86_64-unknown-linux-musl
43+
ENV HOSTS=x86_64-unknown-linux-musl \
44+
CC_x86_64_unknown_linux_musl=x86_64-linux-musl-gcc \
45+
CXX_x86_64_unknown_linux_musl=x86_64-linux-musl-g++
46+
47+
# CARGO_TARGET_ARM_UNKNOWN_LINUX_MUSLEABIHF_LINKER=musl-gcc \
48+
# CARGO_TARGET_ARM_UNKNOWN_LINUX_MUSLEABIHF_RUNNER="qemu-arm -L /musl-arm"
49+
50+
ENV RUSTFLAGS="-C target-feature=-crt-static"
51+
52+
ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
set -ex
2+
3+
hide_output() {
4+
set +x
5+
on_err="
6+
echo ERROR: An error was encountered with the build.
7+
cat /tmp/build.log
8+
exit 1
9+
"
10+
trap "$on_err" ERR
11+
bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
12+
PING_LOOP_PID=$!
13+
$@ &> /tmp/build.log
14+
trap - ERR
15+
kill $PING_LOOP_PID
16+
rm /tmp/build.log
17+
set -x
18+
}
19+
20+
TARGET=$1
21+
#ARCH=$1
22+
#TARGET=linux-musl-$ARCH
23+
ARCH=x86_64
24+
25+
OUTPUT=/usr/local
26+
shift
27+
28+
git clone https://github.com/richfelker/musl-cross-make -b v0.9.7
29+
cd musl-cross-make
30+
31+
hide_output make -j$(nproc) TARGET=$TARGET
32+
hide_output make install TARGET=$TARGET OUTPUT=$OUTPUT
33+
34+
cd -
35+
36+
# Make musl binaries executable
37+
38+
ln -s $OUTPUT/$TARGET/lib/libc.so /lib/ld-musl-$ARCH.so.1
39+
echo $OUTPUT/$TARGET/lib >> /etc/ld-musl-$ARCH.path
40+
41+
42+
export CC=$TARGET-gcc
43+
export CXX=$TARGET-g++
44+
45+
LLVM=70
46+
47+
# may have been downloaded in a previous run
48+
if [ ! -d libunwind-release_$LLVM ]; then
49+
curl -L https://github.com/llvm-mirror/llvm/archive/release_$LLVM.tar.gz | tar xzf -
50+
curl -L https://github.com/llvm-mirror/libunwind/archive/release_$LLVM.tar.gz | tar xzf -
51+
fi
52+
53+
mkdir libunwind-build
54+
cd libunwind-build
55+
cmake ../libunwind-release_$LLVM \
56+
-DLLVM_PATH=/build/llvm-release_$LLVM \
57+
-DLIBUNWIND_ENABLE_SHARED=0 \
58+
-DCMAKE_C_COMPILER=$CC \
59+
-DCMAKE_CXX_COMPILER=$CXX \
60+
-DCMAKE_C_FLAGS="$CFLAGS" \
61+
-DCMAKE_CXX_FLAGS="$CXXFLAGS"
62+
63+
hide_output make -j$(nproc)
64+
cp lib/libunwind.a $OUTPUT/$TARGET/lib
65+
cd - && rm -rf libunwind-build
66+

src/test/run-make-fulldeps/link-cfg/Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
all: $(call DYLIB,return1) $(call DYLIB,return2) $(call NATIVE_STATICLIB,return3)
44
ls $(TMPDIR)
5-
$(RUSTC) --print cfg --target x86_64-unknown-linux-musl | $(CGREP) crt-static
5+
6+
$(BARE_RUSTC) --print cfg --target x86_64-unknown-linux-musl | $(CGREP) crt-static
67

78
$(RUSTC) no-deps.rs --cfg foo
89
$(call RUN,no-deps)

src/test/run-make-fulldeps/linker-output-non-utf8/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ all:
2020
$(RUSTC) library.rs
2121
mkdir $(bad_dir)
2222
mv $(TMPDIR)/liblibrary.a $(bad_dir)
23-
LIBRARY_PATH=$(bad_dir) $(RUSTC) exec.rs 2>&1 | $(CGREP) this_symbol_not_defined
23+
$(RUSTC) -L $(bad_dir) exec.rs 2>&1 | $(CGREP) this_symbol_not_defined

src/test/run-make-fulldeps/reproducible-build/Makefile

+7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
-include ../tools.mk
2+
3+
# ignore-musl
4+
#
5+
# diff:
6+
# -/checkout/obj/build/x86_64-unknown-linux-musl/test/run-make-fulldeps/reproducible-build/reproducible-build/rustcORhwur/libunwind-cfdf9e23c318976b.rlib: 6220632559893696134
7+
# +/checkout/obj/build/x86_64-unknown-linux-musl/test/run-make-fulldeps/reproducible-build/reproducible-build/rustcMaw0kI/libunwind-cfdf9e23c318976b.rlib: 6220632559893696134
8+
29
all: \
310
smoke \
411
debug \

src/test/run-make/rustc-macro-dep-files/Makefile

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
# FIXME(eddyb) provide `HOST_RUSTC` and `TARGET_RUSTC`
44
# instead of hardcoding them everywhere they're needed.
55
all:
6-
$(BARE_RUSTC) foo.rs --out-dir $(TMPDIR)
6+
ifeq ($(IS_MUSL_HOST),1)
7+
$(BARE_RUSTC) $(RUSTFLAGS) -Clinker=$(RUSTC_LINKER) foo.rs --out-dir $(TMPDIR)
8+
else
9+
$(BARE_RUSTC) foo.rs --out-dir $(TMPDIR)
10+
endif
711
$(RUSTC) bar.rs --target $(TARGET) --emit dep-info
812
$(CGREP) -v "proc-macro source" < $(TMPDIR)/bar.d

src/tools/compiletest/src/runtest.rs

+32-7
Original file line numberDiff line numberDiff line change
@@ -1602,18 +1602,15 @@ impl<'test> TestCx<'test> {
16021602
None
16031603
} else if self.config.target.contains("cloudabi")
16041604
|| self.config.target.contains("emscripten")
1605-
|| (self.config.target.contains("musl") && !aux_props.force_host)
16061605
|| self.config.target.contains("wasm32")
16071606
{
16081607
// We primarily compile all auxiliary libraries as dynamic libraries
16091608
// to avoid code size bloat and large binaries as much as possible
16101609
// for the test suite (otherwise including libstd statically in all
16111610
// executables takes up quite a bit of space).
16121611
//
1613-
// For targets like MUSL or Emscripten, however, there is no support for
1614-
// dynamic libraries so we just go back to building a normal library. Note,
1615-
// however, that for MUSL if the library is built with `force_host` then
1616-
// it's ok to be a dylib as the host should always support dylibs.
1612+
// For targets like Emscripten, however, there is no support for
1613+
// dynamic libraries so we just go back to building a normal library.
16171614
Some("lib")
16181615
} else {
16191616
Some("dylib")
@@ -1845,19 +1842,36 @@ impl<'test> TestCx<'test> {
18451842
None => {}
18461843
}
18471844

1845+
// Musl toolchain is build on linux-gnu host
1846+
// but with proper setup it can behave almost* like native linux-musl.
1847+
// One difference is "cc" which will link to glibc; force musl cc.
18481848
if self.props.force_host {
18491849
self.maybe_add_external_args(&mut rustc,
18501850
self.split_maybe_args(&self.config.host_rustcflags));
1851+
if self.config.target.contains("musl") {
1852+
if let Some(ref linker) = self.config.linker {
1853+
rustc.arg(format!("-Clinker={}", linker));
1854+
}
1855+
}
18511856
} else {
18521857
self.maybe_add_external_args(&mut rustc,
18531858
self.split_maybe_args(&self.config.target_rustcflags));
18541859
if !is_rustdoc {
18551860
if let Some(ref linker) = self.config.linker {
18561861
rustc.arg(format!("-Clinker={}", linker));
18571862
}
1863+
} else if self.config.target.contains("musl") {
1864+
if let Some(ref linker) = self.config.linker {
1865+
rustc.arg(format!("--linker={}", linker));
1866+
}
18581867
}
18591868
}
18601869

1870+
// Use dynamic musl for tests because static doesn't allow creating dylibs
1871+
if self.config.target.contains("musl") {
1872+
rustc.arg("-Ctarget-feature=-crt-static");
1873+
}
1874+
18611875
rustc.args(&self.props.compile_flags);
18621876

18631877
rustc
@@ -2641,6 +2655,12 @@ impl<'test> TestCx<'test> {
26412655
// compiler flags set in the test cases:
26422656
cmd.env_remove("RUSTFLAGS");
26432657

2658+
// Use dynamic musl for tests because static doesn't allow creating dylibs
2659+
if self.config.target.contains("musl") {
2660+
cmd.env("RUSTFLAGS", "-Ctarget-feature=-crt-static")
2661+
.env("IS_MUSL_HOST", "1");
2662+
}
2663+
26442664
if self.config.target.contains("msvc") && self.config.cc != "" {
26452665
// We need to pass a path to `lib.exe`, so assume that `cc` is `cl.exe`
26462666
// and that `lib.exe` lives next to it.
@@ -2663,8 +2683,13 @@ impl<'test> TestCx<'test> {
26632683
.env("CC", format!("'{}' {}", self.config.cc, cflags))
26642684
.env("CXX", format!("'{}'", &self.config.cxx));
26652685
} else {
2666-
cmd.env("CC", format!("{} {}", self.config.cc, self.config.cflags))
2667-
.env("CXX", format!("{} {}", self.config.cxx, self.config.cflags))
2686+
let cflags = if self.config.target.contains("musl") {
2687+
self.config.cflags.replace("-static", "")
2688+
} else {
2689+
self.config.cflags.to_string()
2690+
};
2691+
cmd.env("CC", format!("{} {}", self.config.cc, cflags))
2692+
.env("CXX", format!("{} {}", self.config.cxx, cflags))
26682693
.env("AR", &self.config.ar);
26692694

26702695
if self.config.target.contains("windows") {

0 commit comments

Comments
 (0)