-
-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix building on Alpine Linux and musl #644
Comments
To add to that: building Rust static libraries that target musl on a GNU host is straight up broken, and has been since 2018 or so (see this issue, there are a few more but I can't remember their titles/URLs). Basically the issue is that when you do We can alleviate that pain a bit with #524 by compiling the runtime ahead of time, but it's something we'd have to document clearly in case somebody wants to build the runtime from source, on a GNU host, but for a musl target. |
We can now sort of build things for musl as follows:
However, if we run the resulting executable we get this:
To "fix" that we have to build like so:
The resulting executable is then statically linked, and runs just fine. However, I strongly suspect that what this actually does is statically link to GNU libc and not the musl libc, because this works even if you don't have any musl libraries installed. Using
The musl source code in turn has no reference of Unfortunately, what little info I can find points back to the linked Rust issues, so I'm not sure what the solution here is. |
https://github.com/nbdd0121/unwinding seems interesting in that it claims to be a pure-Rust replacement for libgcc_eh & friends. Unfortunately, it requires a nightly version of Rust, and it's not clear when it could be used on a stable version. With that said, it does seem to work if we use
Produces:
It also works if we set the sysroot and use regular clang:
This however will fail if you try to link additional libraries as those won't be located in |
Per rust-lang/rust@ee870d6, it seems progress is being made towards including support for the unwinding crate in Rust itself. This means that at some point in the future, we may not need gcc_s/etc any more, but it's not clear when that would be. |
I've tried various approaches to building the static library such that gcc_eh isn't included, but it seems that no matter what combination of distribution/RUSTFLAGS/etc we use, Rust insists on including the library, and no matter what I try I can't get this to work with |
For #524 there is a sort of workaround: we can build the runtime using a nightly version of Rust using the "unwinding" crate, using this patch: diff --git a/rt/Cargo.toml b/rt/Cargo.toml
index b730832c..9f442973 100644
--- a/rt/Cargo.toml
+++ b/rt/Cargo.toml
@@ -20,6 +20,7 @@ polling = "^2.8"
unicode-segmentation = "^1.8"
backtrace = "^0.3"
rustix = { version = "^0.38.24", features = ["fs", "mm", "param", "process", "net", "std", "time"], default-features = false }
+unwinding = "*"
[dependencies.socket2]
version = "^0.5"
diff --git a/rt/src/lib.rs b/rt/src/lib.rs
index cdc264fb..e5fb0b14 100644
--- a/rt/src/lib.rs
+++ b/rt/src/lib.rs
@@ -3,6 +3,8 @@
#![cfg_attr(feature = "cargo-clippy", allow(clippy::missing_safety_doc))]
#![cfg_attr(feature = "cargo-clippy", allow(clippy::too_many_arguments))]
+extern crate unwinding;
+
pub mod macros;
pub mod arc_without_weak; We'd then build the runtime ahead of time like so:
You can then compile the compiler using stable Rust and use this nightly-built runtime for musl, removing the need for gcc_eh & friends. However, until https://gitlab.com/taricorp/llvm-sys.rs/-/issues/44 is taken care of I'm not sure what happens if you try to build on Alpine for Alpine. This approach also means that we technically still have to depend on libgcc, at least until the unwinding crate is available on stable versions of Rust. |
It seems the use of the "unwinding" crate produces somewhat inconsistent results: when linking using musl-clang, a panic produces a stacktrace. When linking with musl-gcc, no stacktrace is produced. Playing around with the different feature flags doesn't seem to fix this. Based on this, I'm going to abandon the idea of using the "unwinding" crate, as it feels like something that's just too unstable/inconsistent for our usecase at this point. |
To add to the above: The crux of the issue is that unwinding requires certain Linking against libunwind could solve that as it defines these functions, but at least on my platform (Arch Linux) I seemingly can't get it to either dynamically link (it just seemingly ignores it) or statically link (as Arch doesn't ship with static libraries). Thus, I wonder if perhaps the fact that I'm using Arch Linux plays a role here, so I'll see what happens if I link on e.g. Fedora. |
Fedora exhibits the same issues, so this isn't a distribution related issue. |
I sort of made some more (interesting) progress: Rust's musl target bundles a static libunwind library in diff --git a/compiler/src/linker.rs b/compiler/src/linker.rs
index a1ceec8d..f13c9d71 100644
--- a/compiler/src/linker.rs
+++ b/compiler/src/linker.rs
@@ -233,6 +233,7 @@ pub(crate) fn link(
})?;
cmd.arg(&rt_path);
+ cmd.arg("/var/home/yorickpeterse/homes/arch/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained/libunwind.a");
// Include any extra platform specific libraries, such as libm on the
// various Unix platforms. These must come _after_ any object files and Oddly enough, if I link using musl-clang I get a working stack trace for a panic. If instead musl-gcc is used, the trace is missing. |
https://github.com/rust-lang/rust/blob/62d7ed4a6775c4490e493093ca98ef7c215b835b/compiler/rustc_codegen_ssa/src/back/linker.rs#L775 suggests we need to pass |
For musl, what we could do is this: the runtimes we build aren't just gzipped |
I got linking with musl to work, so we can at least build executables that target musl now. Building the compiler on Apline is still broken though, as https://gitlab.com/taricorp/llvm-sys.rs/-/issues/44 hasn't been solved yet. |
Per https://gitlab.com/taricorp/llvm-sys.rs/-/issues/44#note_2095470233, we should soon be able to build on Alpine once more. |
Using musl would allow Inko executables to not depend on glibc, making them more portable. Alpine Linux in turn is commonly used in CI environments.
Support for Alpine Linux is currently blocked by the following issues:
page_size() returns zero under Alpine Linux bytecodealliance/rustix#933Outside of that, it seems to work, but it requires some effort: you have to build the compiler on a non-musl target, then use that to compile Inko to object files. You then have to build the runtime (using
cargo build -p rt
) under Alpine, and manually link things together (again using Alpine) like so:Without the
-static
flag there's still some dynamic linking going on, probably due to Alpine dynamically linking musl by default:You then need the following patch to work around the rustix bug:
Once that's all done, the resulting executable works fine.
Once the mentioned bugs are solved, we'll need to extend the compiler with a proper musl target, as there may be some differences in LLVM between XXX-unknown-linux-musl and XXX-unknown-linux-gnu. We'll also need to adjust the linker flags for Alpine, as many of the current flags aren't needed and cause linker errors.
Related issues
The text was updated successfully, but these errors were encountered: