Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to cross compile for Android #5

Closed
sn99 opened this issue Aug 10, 2023 · 7 comments
Closed

Unable to cross compile for Android #5

sn99 opened this issue Aug 10, 2023 · 7 comments

Comments

@sn99
Copy link

sn99 commented Aug 10, 2023

Running cargo build --target aarch64-linux-android --verbose gives

cargo  build --target aarch64-linux-android --verbose
       Fresh autocfg v1.1.0
       Fresh cc v1.0.79
       Fresh pkg-config v0.3.27
       Fresh bytemuck v1.13.1
       Fresh num-traits v0.2.16
       Fresh safe_arch v0.7.1
       Fresh rawpointer v0.2.1
       Fresh cfg-if v1.0.0
       Fresh static_assertions v1.1.0
       Fresh bitflags v1.3.2
       Fresh scopeguard v1.2.0
       Fresh libc v0.2.147
       Fresh approx v0.5.1
       Fresh num-integer v0.1.45
       Fresh num-complex v0.4.3
       Fresh wide v0.7.11
       Fresh paste v1.0.14
   Compiling hidapi v2.4.1
       Fresh matrixmultiply v0.3.7
       Fresh bitflags v2.0.2
       Fresh tinyjson v2.5.1
       Fresh byteorder v1.4.3
     Running `/home/sn99/Downloads/ar-drivers-rs-master/target/debug/build/hidapi-244def70a3e3da47/build-script-build`
       Fresh nix v0.26.2
   Compiling simba v0.8.1
       Fresh typenum v1.16.0
       Fresh num-rational v0.4.1
   Compiling libusb1-sys v0.6.4
   Compiling rusb v0.9.2
     Running `/home/sn99/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rustc --crate-name simba --edition=2018 /home/sn99/.cargo/registry/src/index.crates.io-6f17d22bba15001f/simba-0.8.1/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=80 --crate-type lib --emit=dep-info,metadata,link -C embed-bitcode=no -C debuginfo=2 --cfg 'feature="std"' --cfg 'feature="wide"' -C metadata=47ec6e6ace1412ee -C extra-filename=-47ec6e6ace1412ee --out-dir /home/sn99/Downloads/ar-drivers-rs-master/target/aarch64-linux-android/debug/deps --target aarch64-linux-android -C linker=/home/sn99/Android/Sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android33-clang -L dependency=/home/sn99/Downloads/ar-drivers-rs-master/target/aarch64-linux-android/debug/deps -L dependency=/home/sn99/Downloads/ar-drivers-rs-master/target/debug/deps --extern approx=/home/sn99/Downloads/ar-drivers-rs-master/target/aarch64-linux-android/debug/deps/libapprox-ef5258c943a15217.rmeta --extern num_complex=/home/sn99/Downloads/ar-drivers-rs-master/target/aarch64-linux-android/debug/deps/libnum_complex-2675a163087bd6a6.rmeta --extern num_traits=/home/sn99/Downloads/ar-drivers-rs-master/target/aarch64-linux-android/debug/deps/libnum_traits-6407d669dc13bf7f.rmeta --extern paste=/home/sn99/Downloads/ar-drivers-rs-master/target/debug/deps/libpaste-b8a4ca751342c3a9.so --extern wide=/home/sn99/Downloads/ar-drivers-rs-master/target/aarch64-linux-android/debug/deps/libwide-1c39544f96c044a6.rmeta --cap-lints allow`
   Compiling serialport v4.2.2
     Running `/home/sn99/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rustc --crate-name libusb1_sys --edition=2018 /home/sn99/.cargo/registry/src/index.crates.io-6f17d22bba15001f/libusb1-sys-0.6.4/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=80 --crate-type lib --emit=dep-info,metadata,link -C embed-bitcode=no -C debuginfo=2 -C metadata=201450028b344926 -C extra-filename=-201450028b344926 --out-dir /home/sn99/Downloads/ar-drivers-rs-master/target/aarch64-linux-android/debug/deps --target aarch64-linux-android -C linker=/home/sn99/Android/Sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android33-clang -L dependency=/home/sn99/Downloads/ar-drivers-rs-master/target/aarch64-linux-android/debug/deps -L dependency=/home/sn99/Downloads/ar-drivers-rs-master/target/debug/deps --extern libc=/home/sn99/Downloads/ar-drivers-rs-master/target/aarch64-linux-android/debug/deps/liblibc-ee138b075719b2ac.rmeta --cap-lints allow -L native=/home/sn99/Downloads/ar-drivers-rs-master/target/aarch64-linux-android/debug/build/libusb1-sys-45fa8d6d74cfaa9d/out -l static=usb-vendored`
     Running `/home/sn99/Downloads/ar-drivers-rs-master/target/debug/build/rusb-081683cded2a227a/build-script-build`
     Running `/home/sn99/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rustc --crate-name serialport --edition=2018 /home/sn99/.cargo/registry/src/index.crates.io-6f17d22bba15001f/serialport-4.2.2/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=80 --crate-type lib --emit=dep-info,metadata,link -C embed-bitcode=no -C debuginfo=2 --cfg 'feature="default"' --cfg 'feature="libudev"' -C metadata=61d56f0899571aa3 -C extra-filename=-61d56f0899571aa3 --out-dir /home/sn99/Downloads/ar-drivers-rs-master/target/aarch64-linux-android/debug/deps --target aarch64-linux-android -C linker=/home/sn99/Android/Sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android33-clang -L dependency=/home/sn99/Downloads/ar-drivers-rs-master/target/aarch64-linux-android/debug/deps -L dependency=/home/sn99/Downloads/ar-drivers-rs-master/target/debug/deps --extern bitflags=/home/sn99/Downloads/ar-drivers-rs-master/target/aarch64-linux-android/debug/deps/libbitflags-24e29694f72f86d5.rmeta --extern cfg_if=/home/sn99/Downloads/ar-drivers-rs-master/target/aarch64-linux-android/debug/deps/libcfg_if-931c0cdcdfd6cc3b.rmeta --extern nix=/home/sn99/Downloads/ar-drivers-rs-master/target/aarch64-linux-android/debug/deps/libnix-90801f53a5fdd38b.rmeta --extern scopeguard=/home/sn99/Downloads/ar-drivers-rs-master/target/aarch64-linux-android/debug/deps/libscopeguard-8d68803e22ce5110.rmeta --cap-lints allow`
error: failed to run custom build command for `hidapi v2.4.1`

Caused by:
  process didn't exit successfully: `/home/sn99/Downloads/ar-drivers-rs-master/target/debug/build/hidapi-244def70a3e3da47/build-script-build` (exit status: 101)
  --- stdout
  cargo:rerun-if-changed=etc/hidapi/linux/hid.c
  cargo:rerun-if-env-changed=LIBUSB_1.0_NO_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_aarch64-linux-android
  cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_aarch64_linux_android
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_ALLOW_CROSS
  cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS
  cargo:rerun-if-env-changed=PKG_CONFIG_aarch64-linux-android
  cargo:rerun-if-env-changed=PKG_CONFIG_aarch64_linux_android
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_aarch64-linux-android
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_aarch64_linux_android
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_SYSROOT_DIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR

  --- stderr
  thread 'main' panicked at 'Unable to find libusb-1.0: "pkg-config has not been configured to support cross-compilation.\n\nInstall a sysroot for the target platform and configure it via\nPKG_CONFIG_SYSROOT_DIR and PKG_CONFIG_PATH, or install a\ncross-compiling wrapper for pkg-config and set it via\nPKG_CONFIG environment variable."', /home/sn99/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hidapi-2.4.1/build.rs:72:60
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
warning: build failed, waiting for other jobs to finish...

I went through this ruabmbua/hidapi-rs#122 issue too, to find any hints but alas.

My env looks something like this:

export ANDROID_HOME=$HOME/Android/Sdk
export ANDROID_NDK_HOME=/home/sn99/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

And .cargo/config looks like this:

[target.aarch64-linux-android]
linker = "/home/sn99/Android/Sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android33-clang"
@badicsalex
Copy link
Owner

Heh, I was never actually solved this properly.

First off, you need to cross-compile a libusb.so (it's just cd libusb/android; $ANDROID_NDK_HOME/ndk-build libs/armeabi-v7a/libusb1.0.so APP_ABI=armeabi-v7a APP_PLATFORM=android-$API)

Then I use a file called fake-pk-config.sh with these contents:

if [[ "$1" == "--libs" && "$2" == "--cflags" ]]; then
    case "$3" in
        "libusb-1.0")
            echo "-I$BASE_DIR/libusb/libusb -L$BASE_DIR/libusb/android/libs/armeabi-v7a -lusb1.0"
            ;;

        *)
            echo "Unsupported lib" >&2
            exit 1
            ;;
    esac
elif [[ "$1" == "--modversion" ]]; then
    case "$2" in
        "libusb-1.0")
            echo "1.0.26"
            ;;

        *)
            echo "Unsupported lib" >&2
            exit 1
            ;;
    esac
else
    echo "Unsupported args." >&2
    exit 1
fi

And export PKG_CONFIG="$BASE_DIR/fake-pkg-config.sh". You could probably make the actual pkg-config work properly (with the PKG_CONFIG* env vars and creating a libusb.pc file), but I never really cared :P

An alternative would be properly implementing https://github.com/badicsalex/tiny-linux-usb and then using that instead of both rusb and hidapi. I did try it with the nreal air driver, and it can be made to work on Android, but it'd take at least a week of real work.

@badicsalex
Copy link
Owner

OK, just writing this down made me so ashamed that I got rid of fake-pkg-config.sh. Now my build-android.sh looks like this (libusb is added to the git repo as a submodule):

set -e

SCRIPT="$(readlink -f "$0")"
export BASE_DIR="$(dirname "$SCRIPT")"

export ANDROID_NDK="/opt/android_sdk/ndk/25.2.9519653/"
export TOOLCHAIN="$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64"
export TARGET="armv7a-linux-androideabi"
export API="29"
export ANDROID_PLATFORM=android-$API
export ANDROID_NATIVE_API_LEVEL=$API
export ANDROID_ARM_NEON=TRUE
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 PKG_CONFIG_PATH="$BASE_DIR/libusb_install/lib/pkgconfig"
export PKG_CONFIG_ALLOW_CROSS=1
export CFLAGS="-march=armv7-a -mfpu=neon"

if [[ ! -f "$BASE_DIR/libusb_install/lib/libusb-1.0.so" ]]; then (
    echo
    echo " == BUILDING LIBUSB == "
    echo
    cd libusb
    ./bootstrap.sh
    ./configure \
        --host armv7a-linux-androideabi \
        --prefix=$BASE_DIR/libusb_install \
        --enable-udev=false \
        --enable-system-log
    make -j
    make install
) fi

cargo build --target armv7-linux-androideabi --release --lib

@badicsalex
Copy link
Owner

You could probably set the prefix of your libusb ./configure call to the sysroot of your ndk, install it there, and use PKG_CONFIG_SYSROOT_DIR instead. But I'm uncomfortable putting additional files into that sysroot.

@sn99
Copy link
Author

sn99 commented Aug 11, 2023

Thanks for you help @badicsalex I was able to reproduce your steps, here is my build-android.sh:

#!/bin/bash

set -e

SCRIPT="$(readlink -f "$0")"
export BASE_DIR="$(dirname "$SCRIPT")"

# export ANDROID_NDK="/home/sn99/Android/Sdk/ndk/25.2.9519653/"
export TOOLCHAIN="$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64"
export TARGET="aarch64-linux-android"
export API="33"
export ANDROID_PLATFORM=android-$API
export ANDROID_NATIVE_API_LEVEL=$API
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 PKG_CONFIG_PATH="$BASE_DIR/libusb_install/lib/pkgconfig"
export PKG_CONFIG_ALLOW_CROSS=1
export CFLAGS="-march=armv8-a"

if [[ ! -f "$BASE_DIR/libusb_install/lib/libusb-1.0.so" ]]; then
    (
    echo
    echo " == BUILDING LIBUSB == "
    echo
    cd libusb
    ./bootstrap.sh
    ./configure \
        --host $TARGET \
        --prefix=$BASE_DIR/libusb_install \
        --enable-udev=false \
        --enable-system-log
    make -j
    make install
    )
fi

cargo build --target $TARGET --release --lib

And .cargo/config looks like this:

[target.aarch64-linux-android]
linker = "/home/sn99/Android/Sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android33-clang++"

@sn99 sn99 closed this as completed Aug 11, 2023
@sn99 sn99 reopened this Aug 25, 2023
@sn99
Copy link
Author

sn99 commented Aug 25, 2023

@badicsalex Sorry for disturbing you again but now I am getting a runtime error (it builds though):

08-25 16:30:06.569 27157 27157 E AndroidRuntime: FATAL EXCEPTION: main
08-25 16:30:06.569 27157 27157 E AndroidRuntime: Process: tech.subcom.shepherd, PID: 27157
08-25 16:30:06.569 27157 27157 E AndroidRuntime: java.lang.UnsatisfiedLinkError: dlopen failed: library "libusb-1.0.so" not found: needed by /data/app/~~NGFfCGYaHQB3DLarljH9Cw==/tech.subcom.shepherd-aUWkQ82xuUhS6yuCPl5-fg==/base.apk!/lib/arm64-v8a/libshepherd_android_rust.so in namespace classloader-namespace
08-25 16:30:06.569 27157 27157 E AndroidRuntime: 	at java.lang.Runtime.loadLibrary0(Runtime.java:1087)
08-25 16:30:06.569 27157 27157 E AndroidRuntime: 	at java.lang.Runtime.loadLibrary0(Runtime.java:1008)
08-25 16:30:06.569 27157 27157 E AndroidRuntime: 	at java.lang.System.loadLibrary(System.java:1664)
08-25 16:30:06.569 27157 27157 E AndroidRuntime: 	at tech.subcom.shepherd.ShepherdService.<clinit>(ShepherdService.java:16)
08-25 16:30:06.569 27157 27157 E AndroidRuntime: 	at java.lang.Class.newInstance(Native Method)
08-25 16:30:06.569 27157 27157 E AndroidRuntime: 	at android.app.AppComponentFactory.instantiateService(AppComponentFactory.java:129)
08-25 16:30:06.569 27157 27157 E AndroidRuntime: 	at androidx.core.app.CoreComponentFactory.instantiateService(CoreComponentFactory.java:75)
08-25 16:30:06.569 27157 27157 E AndroidRuntime: 	at android.app.ActivityThread.handleCreateService(ActivityThread.java:4523)
08-25 16:30:06.569 27157 27157 E AndroidRuntime: 	at android.app.ActivityThread.access$100(ActivityThread.java:287)
08-25 16:30:06.569 27157 27157 E AndroidRuntime: 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2189)
08-25 16:30:06.569 27157 27157 E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:106)
08-25 16:30:06.569 27157 27157 E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:255)
08-25 16:30:06.569 27157 27157 E AndroidRuntime: 	at android.app.ActivityThread.main(ActivityThread.java:8212)
08-25 16:30:06.569 27157 27157 E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
08-25 16:30:06.569 27157 27157 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:632)
08-25 16:30:06.569 27157 27157 E AndroidRuntime: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1049)

@badicsalex
Copy link
Owner

You have to put the built libusb-1.0.so file into your jniLibs directory, right next to the rust .so.

@sn99
Copy link
Author

sn99 commented Aug 28, 2023

Ahhh, thanks again, I got it working by placing libusb_install/lib/ -> app/src/main/jniLibs/arm64-v8a.

@sn99 sn99 closed this as completed Aug 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants