Failing to Build Statically-Linked Rust Binaries
Please note that I found a solution using Nix.
I’ve written before about how I build small, self-contained binaries for Rust
programs. I was unable to repeat the process for a different
project. The first hurdle was a missing ceil
function:
= note: /usr/bin/ld: /app/target/x86_64-unknown-linux-musl/release/deps/libnum_cpus-9b0d9afaf0a074d3.rlib(num_cpus-9b0d9afaf0a074d3.num_cpus.564d9279-cgu.0.rcgu.o): in function `num_cpus::linux::init_cgroups': num_cpus.564d9279-cgu.0:(.text._ZN8num_cpus5linux12init_cgroups17h5c54b6f76c5096b4E+0x997): undefined reference to `ceil' collect2: error: ld returned 1 exit status = help: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified = note: use the `-l` flag to specify native libraries to link = note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)
This seems to be caused by a missing maths library. The normal solution appears to be adding -lm
to link libmath, but I couldn’t find an equivalent on Alpine Linux. I have to admit, I don’t
understand why it’s required when the only relevant line my search turned up seems to use Rust’s
ceil
.
I tried building a non-static binary on Alpine Linux and running it in a distroless image. Oddly enough, even though the build was being run in Docker with the same code and steps, it succeeded on my machine but not in the GitHub workflow. The many errors were musl-related:
Compiling foo-feeds v0.1.0 (/app) error[E0463]: can't find crate for `std` | = note: the `x86_64-unknown-linux-musl` target may not be installed = help: consider downloading the target with `rustup target add x86_64-unknown-linux-musl` error[E0463]: can't find crate for `std` which `atom_syndication` depends on --> src/feed.rs:1:5
I was building with the muslrust image, which has the relevant
target installed, so I was certain that wasn’t the issue. I ultimately settled for building a
dynamically-linked binary using the Debian variant of the Rust image and running it in Debian as
well. I also had to omit target-cpu=native
.