Error building Rust project for Android (Flutter): arm-linux-androideabi-ranlib not found for OpenSSL compilation
Asked Answered
K

4

8

I'm working on a project that uses Flutter and Rust, and I'm trying to build it for Android. However, I'm facing an error related to arm-linux-androideabi-ranlib not being found. Here's the error message I'm getting:

--- stderr
/home/user/Android/Sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar: warning: creating libcrypto.a
/bin/sh: 1: arm-linux-androideabi-ranlib: not found
/home/user/Android/Sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar: warning: creating libssl.a
/bin/sh: 1: arm-linux-androideabi-ranlib: not found
/bin/sh: 5: arm-linux-androideabi-ranlib: not found
make: *** [Makefile:313: install_dev] Error 127
thread 'main' panicked at '


Error installing OpenSSL:
    Command: cd "/home/user/IdeaProjects/my_project/rust/target/armv7-linux-androideabi/debug/build/openssl-sys-c3d36b893b4843b2/out/openssl-build/build/src" && "make" "install_dev"
    Exit status: exit status: 2

I've checked the NDK directory, and it seems like the required tools are present but not exactly the file arm-linux-androideabi-ranlib. Here's the output of ls for the toolchain directory:

prebuilt/linux-x86_64/bin via 🐍 v2.7.18 took 6s 
❯ pwd
/home/user/Android/Sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/bi
prebuilt/linux-x86_64/bin via 🐍 v2.7.18 
❯ ls
aarch64-linux-android21-clang       i686-linux-android29-clang++
aarch64-linux-android21-clang++     i686-linux-android30-clang
aarch64-linux-android22-clang       i686-linux-android30-clang++
aarch64-linux-android22-clang++     i686-linux-android31-clang
aarch64-linux-android23-clang       i686-linux-android31-clang++
aarch64-linux-android23-clang++     i686-linux-android32-clang
aarch64-linux-android24-clang       i686-linux-android32-clang++
aarch64-linux-android24-clang++     i686-linux-android33-clang
aarch64-linux-android26-clang       i686-linux-android33-clang++
aarch64-linux-android26-clang++     ld
aarch64-linux-android27-clang       ld64.lld
aarch64-linux-android27-clang++     ld.lld
aarch64-linux-android28-clang       lld
aarch64-linux-android28-clang++     lldb
aarch64-linux-android29-clang       lldb-argdumper
aarch64-linux-android29-clang++     lldb.sh
aarch64-linux-android30-clang       lld-link
aarch64-linux-android30-clang++     llvm-addr2line
aarch64-linux-android31-clang       llvm-ar
aarch64-linux-android31-clang++     llvm-as
aarch64-linux-android32-clang       llvm-bolt
aarch64-linux-android32-clang++     llvm-cfi-verify
aarch64-linux-android33-clang       llvm-config
aarch64-linux-android33-clang++     llvm-cov
armv7a-linux-androideabi19-clang    llvm-cxxfilt
armv7a-linux-androideabi19-clang++  llvm-dis
armv7a-linux-androideabi21-clang    llvm-dwarfdump
armv7a-linux-androideabi21-clang++  llvm-dwp
armv7a-linux-androideabi22-clang    llvm-lib
armv7a-linux-androideabi22-clang++  llvm-link
armv7a-linux-androideabi23-clang    llvm-lipo
armv7a-linux-androideabi23-clang++  llvm-modextract
armv7a-linux-androideabi24-clang    llvm-nm
armv7a-linux-androideabi24-clang++  llvm-objcopy
armv7a-linux-androideabi26-clang    llvm-objdump
armv7a-linux-androideabi26-clang++  llvm-profdata
armv7a-linux-androideabi27-clang    llvm-ranlib
armv7a-linux-androideabi27-clang++  llvm-rc
armv7a-linux-androideabi28-clang    llvm-readelf
armv7a-linux-androideabi28-clang++  llvm-readobj
armv7a-linux-androideabi29-clang    llvm-size
armv7a-linux-androideabi29-clang++  llvm-strings
armv7a-linux-androideabi30-clang    llvm-strip
armv7a-linux-androideabi30-clang++  llvm-symbolizer
armv7a-linux-androideabi31-clang    llvm-windres
armv7a-linux-androideabi31-clang++  merge-fdata
armv7a-linux-androideabi32-clang    remote_toolchain_inputs
armv7a-linux-androideabi32-clang++  sancov
armv7a-linux-androideabi33-clang    sanstats
armv7a-linux-androideabi33-clang++  scan-build
bisect_driver.py                    scan-view
clang                               x86_64-linux-android21-clang
clang++                             x86_64-linux-android21-clang++
clang-14                            x86_64-linux-android22-clang
clang-check                         x86_64-linux-android22-clang++
clangd                              x86_64-linux-android23-clang
clang-format                        x86_64-linux-android23-clang++
clang-tidy                          x86_64-linux-android24-clang
dsymutil                            x86_64-linux-android24-clang++
git-clang-format                    x86_64-linux-android26-clang
i686-linux-android19-clang          x86_64-linux-android26-clang++
i686-linux-android19-clang++        x86_64-linux-android27-clang
i686-linux-android21-clang          x86_64-linux-android27-clang++
i686-linux-android21-clang++        x86_64-linux-android28-clang
i686-linux-android22-clang          x86_64-linux-android28-clang++
i686-linux-android22-clang++        x86_64-linux-android29-clang
i686-linux-android23-clang          x86_64-linux-android29-clang++
i686-linux-android23-clang++        x86_64-linux-android30-clang
i686-linux-android24-clang          x86_64-linux-android30-clang++
i686-linux-android24-clang++        x86_64-linux-android31-clang
i686-linux-android26-clang          x86_64-linux-android31-clang++
i686-linux-android26-clang++        x86_64-linux-android32-clang
i686-linux-android27-clang          x86_64-linux-android32-clang++
i686-linux-android27-clang++        x86_64-linux-android33-clang
i686-linux-android28-clang          x86_64-linux-android33-clang++
i686-linux-android28-clang++        yasm
i686-linux-android29-clang

I'm using Flutter 3.7.6, Dart 2.19.3, and cargo-ndk. My gradle.properties file has the ANDROID_NDK variable set to the correct path:

ANDROID_NDK=/home/user/Android/Sdk/ndk/25.2.9519653/

In my build.gradle, I have the following tasks for building the Rust project:

[
        new Tuple2('Debug', ''),
        new Tuple2('Profile', '--release'),
        new Tuple2('Release', '--release')
].each {
    def taskPostfix = it.first
    def profileMode = it.second
    tasks.whenTaskAdded { task ->
        if (task.name == "javaPreCompile$taskPostfix") {
            task.dependsOn "cargoBuild$taskPostfix"
        }
    }
    tasks.register("cargoBuild$taskPostfix", Exec) {
        commandLine 'sh', '-c', """cd ../../rust/my_lib  && \
        ANDROID_NDK_HOME="$ANDROID_NDK" cargo ndk \
            -t armeabi-v7a -t arm64-v8a -t x86 -t x86_64 \
            -o ../android/app/src/main/jniLibs build $profileMode"""
    }
}

And I'm using flutter_rust_bridge version 1.67.0 in my project. Doc related to build.gradle file here.

Rust Cargo.toml:

[lib]
crate-type = ["lib", "staticlib", "cdylib"]

[dependencies]
openssl = { version = "0.10", features = ["vendored"] }

Does anyone have any idea why the build is failing with the "arm-linux-androideabi-ranlib not found" error and how to fix it? Any help would be appreciated. Thanks!

Kittiekittiwake answered 5/4, 2023 at 20:29 Comment(5)
It related du to github.com/fzyzcjy/flutter_rust_bridge/issues/995. I will try with NDK r21e. – Kittiekittiwake
Same error with NDK r21e instead the file arm-linux-androideabi-ranlib exist. – Kittiekittiwake
I'm getting almost the same error, but with aarch64-linux-android-ranlib: not found (probably just due to the build order). – Gradate
@JBis check my answer below, see if it works for you too. – Cadal
try my solution #75944217 – Isabea
C
2

I ran into this similar error, I am running the latest version of Android Studio and have installed NDK using it. It installed everything in $HOME/Android/Sdk. I solved it by:

First you will need to set these env:

export ANDROID_HOME=$HOME/Android/Sdk
export ANDROID_NDK_HOME=$HOME/Android/Sdk/ndk/25.2.9519653

export TOOLCHAIN=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64
export TARGET=aarch64-linux-android
export API=33

export AR=$TOOLCHAIN/bin/llvm-ar
export CC=$TOOLCHAIN/bin/$TARGET$API-clang
export AS=$CC
export CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
export LD=$TOOLCHAIN/bin/ld
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
export STRIP=$TOOLCHAIN/bin/llvm-strip

export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin
export PATH=$PATH:$TOOLCHAIN/bin

After that add the following like to $HOME/.cargo/config (make the config file if it doesn't exist):

[target.aarch64-linux-android]
linker = "/<absolute path to home>/Android/Sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android33-clang"

After that running something like cargo build --target aarch64-linux-android or using ./gradlew build should work.

Cadal answered 3/8, 2023 at 5:41 Comment(0)
H
0

You can configure the path of commands that OpenSSL Android build script uses via environment variables like CC_aarch64-linux-android, RANLIB_aarch64-linux-android, and so on. Here's the PowerShell script I use to configure such variables:

$ANDROID_HOME = "/path/to/Android/sdk";
$ANDROID_SUBDIRS = "emulator", "tools", "tools/bin", "platform-tools";
ForEach ($subdir in $ANDROID_SUBDIRS) {
    ${env:PATH} = "${env:PATH}:${ANDROID_HOME}/$subdir";
}
${env:ANDROID_HOME} = $ANDROID_HOME;
${env:ANDROID_SDK_ROOT} = $ANDROID_HOME;
${env:ANDROID_NDK_ROOT} = "$ANDROID_HOME/ndk/25.2.9519653";

function configureAndroidToolchain {
    # "windows-x86_64" on Windows
    # "darwin-x86_64" on macOS (even with Apple Silicon)
    # "linux-x86_64" on Linux
    $hostTag = "darwin-x86_64";

    # Use the minSdkVersion you use
    $sdkVersion = "29";

    $archs = @{}
    $archs["aarch64-linux-android"] = $null;
    $archs["armv7-linux-androideabi"] = "armv7a-linux-androideabi";
    $archs["x86_64-linux-android"] = $null;
    $archs["i686-linux-android"] = $null;

    $prebuiltDir = "${env:ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/$hostTag/bin";

    foreach ($rustArch in $archs.Keys) {
        $androidArch = $archs[$rustArch];
        if ($androidArch -eq $null) {
            $androidArch = $rustArch;
        }

        Set-Item "env:CC_$rustArch" -Value "$prebuiltDir/$androidArch$sdkVersion-clang";
        Set-Item "env:CXX_$rustArch" -Value "$prebuiltDir/$androidArch$sdkVersion-clang++";
        Set-Item "env:AR_$rustArch" -Value "$prebuiltDir/llvm-ar";
        Set-Item "env:RANLIB_$rustArch" -Value "$prebuiltDir/llvm-ranlib";
        Set-Item "env:CFLAGS_$rustArch" -Value "-D__ANDROID_MIN_SDK_VERSION__=$sdkVersion";
        Set-Item "env:CXXFLAGS_$rustArch" -Value "-D__ANDROID_MIN_SDK_VERSION__=$sdkVersion";
    }
}

configureAndroidToolchain;

After applying these variables, OpenSSL build will complete normally.

Hama answered 18/7, 2023 at 1:36 Comment(0)
E
0

Try to use "openssl-src" version lower or equals to "111.24.0+1.1.1s". I set it manually after each cargo update in Cargo.lock

[[package]]
name = "openssl-src"
version = "111.24.0+1.1.1s"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3498f259dab01178c6228c6b00dcef0ed2a2d5e20d648c017861227773ea4abd"
dependencies = [
 "cc",
]
Ephraim answered 24/8, 2023 at 0:55 Comment(1)
It's almost never a good idea to manually set a version for a dependency. – Meyeroff
I
0

if you use cargo-ndk, you need rebuild cargo-ndk use the same ndk version before your build.

export ANDROID_HOME=/home/user/Android/Sdk
export ANDROID_NDK_HOME=/home/user/Android/Sdk/ndk/25.2.9519653
# eg for mac, must set by OS type
export PATH="$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin:$PATH"
# eg for linux x86_64
export PATH="$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH"


cargo uninstall cargo-ndk
cargo install cargo-ndk

# then you can build:

rustup target add \
    aarch64-linux-android \
    armv7-linux-androideabi \
    x86_64-linux-android \
    i686-linux-android

cd projectPath

cargo ndk \
-t armeabi-v7a -t arm64-v8a -t x86 -t x86_64 \
-o ../android/app/src/main/jniLibs build --release

It took me a lot of genius to find the cause and solve it. I hope my solution can help you.

Isabea answered 23/10, 2023 at 10:47 Comment(0)

© 2022 - 2024 β€” McMap. All rights reserved.