rust-mobile/ndk

Android NDK r23 beta 3 and up do not include `libgcc` anymore

MarijnS95 opened this issue · 12 comments

A heads-up to anyone upgrading beyond NDK r23 beta 2:

error: linking with `~/Android/Sdk/ndk/23.0.7272597/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android30-clang` failed: exit status: 1
  |
  = note: "~/Android/Sdk/ndk/23.0.7272597/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android30-clang" "-Wl,--allow-multiple-definition" "-Wl,--eh-frame-hdr" "-Wl,-znoexecstack" "-Wl,--as-needed" "-L" "~/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/aarch64-linux-android/lib" ... "-Wl,--gc-sections" "-shared" "-Wl,-zrelro" "-Wl,-znow" "-nodefaultlibs" "-L" "android-ndk-rs/target/aarch64-linux-android/debug/deps" "-L" "android-ndk-rs/target/debug/deps" "-L" "~/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/aarch64-linux-android/lib" "-Wl,-Bstatic" ... "-Wl,-Bdynamic" "-landroid" "-ldl" "-llog" "-lgcc" "-lc" "-lm"
  = note: ld: error: unable to find library -lgcc
          clang-12: error: linker command failed with exit code 1 (use -v to see invocation)


error: aborting due to previous error

error: could not compile `ndk-examples`

r23 beta 2 is still working fine as per #137.

GCC Is being completely removed from the NDK, but unfortunately something deep down in Rust depends on gcc. This also happens on a project without dependencies built with cargo b --target aarch64-linux-android.

The possible cause for these is:
https://github.com/rust-lang/rust/blob/9a3214e9be41a5d50ae6ba9bb8422dcc2cb10473/library/std/src/sys/unix/mod.rs#L210-L214
I'll see whether Rust really needs to link against libgcc and if that can otherwise be replaced with libclang_rt.builtins as per https://github.com/android/ndk/wiki/Changelog-r23#changes / android/ndk#1231, without breaking existing builds.

It looks like this has been fixed with rust-lang/rust#85806 🥳

Unfortunately it has not reached nightly yet, will close this when it is confirmed fixed.

Please don't download or use undocumented rar files from random people on the internet.

Aforementioned Rust PR unfortunately doesn't fix it as the older NDK installed on the CI seems to add -lgcc back to the linker flags (rust-lang/rust#85806 (comment)). This can be solved by using nightly and building std locally by setting -Zbuild-std, but it's also something we can fix from android-ndk-rs by providing a libgcc.a linker script that requests linking with libunwind instead: termux/termux-packages#7339 (comment)

We can do this by either:

  • Providing libgcc.a on one of the existing linker paths, such as target/<triple>/debug/deps - but this requires a cargo clean or removing the file if the user switches to a different (older) NDK;
  • Set RUSTFLAGS with -C linker-args=-L... when calling cargo build, but this is mutually exclusive with the other ways of configuring rustflags;
  • Switch to cargo rustc and pass -- -L/the/path to a custom location where we write libgcc.a.

We'd only want to do this if the NDK is >= r23 as to not break r22. The first option won't remove the linker script from the path again which likely has adverse effects.

@MarijnS95 what? i'm just offering the temporary solution, there's no stupid scams or viruses inside that .rar file.

"Switch to cargo rustc and pass -- -L/the/path to a custom location where we write libgcc.a" exactly, that's. just take "libgcc.a" for every arch, anyway mine's taken from NDK-r21d, working fine so far.

We'll write libgcc.a which includes exactly INPUT(-lunwind) as reviewable text. Not some binary that has been copied from hopefully an earlier NDK. Your repository doesn't even document where the files originate from.

@MarijnS95 just take them yourself from the earlier NDK (r21d), if you don't have any, download from official google repo and if there's not available, just extract from .rar file above. i swear there's no virus at all.

It looks like this was fixed in rust-lang/rust@965997b and so using a Rust nightly more recent than ~Jun 2021 should work.

@jfgoog please see rust-lang/rust#85806 (comment) and other replies below.

Supposedly Rust's std/toolchain is built with an older NDK that includes a linker statement for libgcc regardless of that patch. Feel free to try it out for yourself on a recent Rust release or nightly, too.

Cool! Glad to see progress on this, and sorry for the drive-by comment.

@jfgoog no worries, I thought I had mentioned that that Rust patch unfortunately hasn't fixed it, hence the need for a workaround. Now that that's in I'll make a new release today or tomorrow, stay tuned!

@ar37-rs that's exactly what someone who is sending a virus would say (i'm just kidding, thanks man 😂 )