Linking issue with musl and riscv64? (undefined reference to `pow')

Hello,

I'm trying to add riscv64 support to one of my projects. I'm using the latest rust version released last week, 1.93.0, and all cargo packages are up to date.

Here's the project: GitHub - stefansundin/igloo: A small HTTP reverse proxy written in Rust.

To reproduce you can clone it and then run:

docker buildx build --pull --load --progress plain --platform linux/riscv64 -t stefansundin/igloo:riscv .

After waiting for quite a while, you'll get this error:

#13 583.9    Compiling igloo v0.2.0 (/igloo)
#13 967.3 error: linking with `cc` failed: exit status: 1
#13 967.3   |
#13 967.3   = note:  "cc" "<1 object files omitted>" "-Wl,--as-needed" "-Wl,-Bstatic" "/tmp/rustc1KBVpy/{libring-ec5d651bbab4a879,libaws_lc_sys-0a47c029ccd9ac83}.rlib" "<sysroot>/lib/rustlib/riscv64gc-unknown-linux-musl/lib/libcompiler_builtins-*.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lc" "-L" "/tmp/rustc1KBVpy/raw-dylibs" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/igloo/target/riscv64gc-unknown-linux-musl/release-build/build/ring-b908afd8d3553ee5/out" "-L" "/igloo/target/riscv64gc-unknown-linux-musl/release-build/build/aws-lc-sys-6cb2a0d7845a4120/out" "-L" "<sysroot>/lib/rustlib/riscv64gc-unknown-linux-musl/lib" "-o" "/igloo/target/riscv64gc-unknown-linux-musl/release-build/deps/igloo-5de4a821e21ec344" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-Wl,--strip-all" "-nodefaultlibs"
#13 967.3   = note: some arguments are omitted. use `--verbose` to show all linker arguments
#13 967.3   = note: /usr/bin/ld: /igloo/target/riscv64gc-unknown-linux-musl/release-build/deps/igloo-5de4a821e21ec344.igloo.6200c1077e6b69bb-cgu.0.rcgu.o: in function `<aws_smithy_runtime::client::retries::strategy::standard::StandardRetryStrategy as aws_smithy_runtime_api::client::retries::RetryStrategy>::should_attempt_retry':
#13 967.3           igloo.6200c1077e6b69bb-cgu.0:(.text._ZN153_$LT$aws_smithy_runtime..client..retries..strategy..standard..StandardRetryStrategy$u20$as$u20$aws_smithy_runtime_api..client..retries..RetryStrategy$GT$20should_attempt_retry17h32dd69e4fb7e9783E+0x206): undefined reference to `pow'
#13 967.3           /usr/bin/ld: /igloo/target/riscv64gc-unknown-linux-musl/release-build/deps/igloo-5de4a821e21ec344.igloo.6200c1077e6b69bb-cgu.0.rcgu.o: in function `tokio::runtime::scheduler::multi_thread::stats::Stats::end_processing_scheduled_tasks':
#13 967.3           igloo.6200c1077e6b69bb-cgu.0:(.text._ZN5tokio7runtime9scheduler12multi_thread5stats5Stats30end_processing_scheduled_tasks17h52989f7b0b7d398cE+0x64): undefined reference to `pow'
#13 967.3           collect2: error: ld returned 1 exit status
#13 967.3
#13 967.3   = note: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
#13 967.3   = note: use the `-l` flag to specify native libraries to link
#13 967.3   = 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#rustc-link-lib)

I'd like to report this somewhere, my guess is that it would be in this repository: GitHub - rust-lang/compiler-builtins: Rust implementations of compiler-rt and libm

Can someone tell me if that's a good place to report this, or if I should put it somewhere else? I might also have made a silly mistake somewhere in my code, so feel free to check for that too.

I read on Updating Rust's Linux musl targets to 1.2.5 | Rust Blog that "undefined reference to" issues may happen from musl version changes where an outdated libc version is used, but I think I'm on the latest version.

I even tried to make a small rust program that just calls pow but that didn't have this linking problem.

Thank you!

It's probably Rusts f64::powf() which gets linked to C's pow() which is used here.
Can you try to compile an example using f64::powf()?

I tried to make a minimal reproduction using:

fn main() {
    println!("2u64.pow: {}", 2u64.pow(10));
    println!("2f64.powf: {}", 2f64.powf(10.0));
}

But it compiled and ran just fine in docker.

Are you sure that the optimizer isn't computing the pow function at compile time? (I think LLVM can do constant folding with math functions ... I am on mobile and can't check.) What if your reproducer got the exponent from the environment?

Add

ENV RUSTFLAGS="-Ctarget-feature=+crt-static"

Likely other two will need it in future. (They have it as default atm.)

1 Like

You're absolutely right. I started reading the variables from standard input and f64::powf() started showing the same linking problem.

That solved it, thank you!

I found this which I guess is relevant: 1721-crt-static - The Rust RFC Book

Though it doesn't explain why some architectures need it and others don't.