Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I remove the dependency on libunwind when cross-compiling Rust programs with the panic_abort option?

I'm specifying the -Cpanic=abort and -Zbuild-std=panic_abort when compiling. Why does the linker still say it needs libunwind to compile a program?

I'm experimenting with various ways to cross-compile Rust programs as small as possible (using the min-sized-rust repo as a reference). Right now I'm trying to compile the powerpc64-unknown-linux-musl target and I'm stuck on trying to remove a dependency on libunwind.

Here's my setup:

# 1. Install the Rust std source code
rustup component add rust-src --toolchain nightly
# 2. Setup a simple rust repo
cargo init testing
cd testing
# 3. Download a musl toolchain
wget https://musl.cc/powerpc64-linux-musl-cross.tgz
tar xzf powerpc64-linux-musl-cross.tgz
# 4. Try to compile the project (options on the command line instead of in files for
# maximum obviousness).
# RUSTFLAGS:
#  -Cpanic=abort - abort immediately on panic
#  -Clink-self-contained=no - don't use rustc's builtin libraries and objects (this
#    is needed because powerpc64-unknown-linux-musl is a tier 3 target)
#  -Clink-arg=--sysroot and -Clink-arg=/path/to/sysroot - pass the option to the linker
#    to specify the sysroot of cross-compilation toolchain
# Cargo options:
#  --config target.<triple>.linker - specify the linker to use
#  -Zbuild-std=std,panic_abort - build the standard library from source. Specify
#    panic_abort to make the abort on panic work
RUSTFLAGS="-Cpanic=abort -Clink-self-contained=no -Clink-arg=--sysroot -Clink-arg=powerpc64-linux-musl-cross/powerpc64-linux-musl/" \
cargo +nightly build \
    --config "target.powerpc64-unknown-linux-musl.linker=\"powerpc64-linux-musl-cross/bin/powerpc64-linux-musl-gcc\"" \
    --target powerpc64-unknown-linux-musl -Zbuild-std=panic_abort,std --release

This fails with the following error:

error: linking with `/home/user/Projects/testing/powerpc64-linux-musl-cross/bin/powerpc64-linux-musl-gcc` failed: exit status: 1

<output snipped>

  = note: /home/user/Projects/testing/powerpc64-linux-musl-cross/bin/../lib/gcc/powerpc64-linux-musl/11.2.1/../../../../powerpc64-linux-musl/bin/ld: cannot find -lunwind
like image 636
irontigran Avatar asked Oct 18 '25 15:10

irontigran


1 Answers

From min-size-rust repository: "Even if panic = "abort" is specified in Cargo.toml, rustc will still include panic strings and formatting code in final binary by default. An unstable panic_immediate_abort feature has been merged into the nightly rustc compiler to address this.

To use this, repeat the instructions above to use build-std, but also pass the following -Z build-std-features=panic_immediate_abort option."

Still, you will get "cannot find -lunwind", because the linker still uses libunwind, even though it's truly unneeded,why! I do not know, maybe it's a bug.(Maybe someone with fair knowledge about linkers can easily solve that.I tried a naive solution which is "cargo .... --verbose", copy , remove "libunwind" then relinking which failed)

I verified that is indeed the missing piece by build from source(--target=x86_64-unknown-linux-musl) AND using an old simple trick which is "touch libunwind.a" in the "self-contained" directory inside a target lib folder.(because the linker would still use it even though it's now truly unneeded, then I gave him a dummy libunwind.a)

In your case, I really tried to build it to your target until I got a headache, but couldn't and stopped, but here is possible solutions:

Giving that you're using "-Z build-std-features=panic_immediate_abort" -If you can custom the linking process, then solve it (until what seems to be a bug is solved) -Create a dummy(empty) libunwind.a where it should be in your toolchain

like image 161
Alyegdry Avatar answered Oct 21 '25 07:10

Alyegdry