android-rs-glue
android-rs-glue copied to clipboard
Building a native library
How can I use a native library I've built for Android? More specifically, I'd like to build rust-sdl2
, however it seems cargo-apk
cannot find the built SDL2 libraries.
In theory this should work as in any non-Android platform: http://doc.crates.io/build-script.html#overriding-build-scripts
I'm trying to build a ggez based app, which uses SDL2
.
= note: /usr/local/android-ndk-r15b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/ld: error: cannot find -lSDL2
collect2: error: ld returned 1 exit status
Error while executing gcc
What steps should I do to fix that problem? Should I create an updated docker image, which will install SDL2
before running cargo apk build
?
UPD. I installed into docker image libsdl2-dev libsdl2-2.0
and it didn't help, I'm getting the same error.
I installed into docker image libsdl2-dev libsdl2-2.0 and it didn't help
That's because these packages contain a libsdl2 that targets your current platform, while you need a libsdl2 that targets Android.
Could you please point me to the docs on how I can do it?
If I have libSDL2.so
built for android, where should I place it so ld
could find it?
See the docs here: http://doc.crates.io/build-script.html#overriding-build-scripts
Put a .cargo/config
file somewhere (or in your HOME), and put something like this inside:
[target.arm-linux-androideabi.SDL2] # refers to this line: https://github.com/Rust-SDL2/rust-sdl2/blob/master/sdl2-sys/Cargo.toml#L11
rustc-link-search = ["/some/path"]
rustc-link-lib = ["SDL2"] # name of the file, with `lib` and `.so` removed
Ok, I did a custom build.rs
.
cargo apk build
produced the apk, and I installed it to the device with adb
.
But app crashes with
java.lang.UnsatisfiedLinkError: dlopen failed: "/data/app/rust.bomber-2/lib/arm/libSDL2.so" has unexpected e_machine: 3
That means that libSDL2.so
is not compiled for the right architecture (ARM vs x86, I guess)
There are 4 libs like so
.
├── arm64-v8a
│ └── libSDL2.so
├── armeabi-v7a
│ └── libSDL2.so
├── x86
│ └── libSDL2.so
└── x86_64
└── libSDL2.so
build.rs
looks like this:
println!("cargo:rustc-flags=-L sdl2/arm64-v8a",);
println!("cargo:rustc-flags=-L sdl2/armeabi",);
println!("cargo:rustc-flags=-L sdl2/armeabi-v7a",);
println!("cargo:rustc-flags=-L sdl2/x86",);
Is is possible that cargo apk
uses wrong lib?
arm64-v8a/libSDL2.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=678e6ed427ba01e71cc6e675ac376b713c387dd7, with debug_info, not stripped
armeabi-v7a/libSDL2.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=0b70b55f875a58a784cbe1ecd8837a2fb7e3550a, with debug_info, not stripped
x86_64/libSDL2.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=07c38370c2ed4f9c712bcbab0c579801989f8730, with debug_info, not stripped
x86/libSDL2.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, BuildID[sha1]=b7e7fd5aac2e0459b609f2b16a650adec042da5f, with debug_info, not stripped
Well, try using only one to see if it works.
I linked arm64-v8a/libSDL2.so
statically, and the next error :) is
java.lang.IllegalArgumentException: Requested window android.view.ViewRootImpl$W@b091df3 does not exist
Hm, probably it's not related. But it still crashes.
Now I'm trying to build exactly one target.
In Cargo.toml
:
[package.metadata.android]
build_targets = [ "aarch64-linux-android" ]
then cargo apk build
gives
Compiling android_native_app_glue.c
/usr/local/android-ndk-r15b/sources/android/native_app_glue/android_native_app_glue.c:18:17: fatal error: jni.h: No such file or directory
#include <jni.h>
^
compilation terminated.
error: process didn't exit successfully: `/usr/local/android-ndk-r15b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc /usr/local/android-ndk-r15b/sources/android/native_app_glue/android_native_app_glue.c -c -o /root/src/target/android-artifacts/aarch64-linux-android/android_native_app_glue.o --sysroot /usr/local/android-ndk-r15b/platforms/android-18/arch-arm64` (exit code: 1)
ok, I finally did it.
android_version = 21
did the trick
Got the same jni.h not found trying to compile current example:
~ cargo apk build
Compiling android_native_app_glue.c
/home/marcos.cabral/Android/Sdk/ndk/android-ndk-r18b/sources/android/native_app_glue/android_native_app_glue.c:18:10: fatal error:
'jni.h' file not found
#include <jni.h>
^~~~~~~
1 error generated.
error: process didn't exit successfully: `/home/marcos.cabral/Android/Sdk/ndk/android-ndk-r18b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc /home/marcos.cabral/Android/Sdk/ndk/android-ndk-r18b/sources/android/native_app_glue/android_native_app_glue.c -c -o /home/marcos.cabral/_w/android-rs-glue/examples/advanced/target/android-artifacts/armv7-linux-androideabi/android_native_app_glue.o --sysroot /home/marcos.cabral/Android/Sdk/ndk/android-ndk-r18b/platforms/android-29/arch-arm` (exit code: 1)
searching for jni.h found that it is present at:
Sdk/ndk-bundle/sysroot/usr/include/jni.h
Sdk/ndk/android-ndk-r18b/sysroot/usr/include/jni.h
Sdk/ndk/20.0.5594570/sysroot/usr/include/jni.h
Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/jni.h
Sdk/ndk/20.0.5594570/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/jni.h
So, for me it looks like cargo apk is pointing to the wrong sysroot
What am I missing ?
Can you try things with the master version of cargo-apk? The build process has changed substantially. The current version isn't available on crates.io yet. Waiting for #221 to be resolved. The current master shouldn't have that issue. However, there is a known issue when linking to c++. The issue is discussed and has a workaround in #245.
Thanks, building example basic and advanced works with master, looking forward to build something with a gui like conrod. If there is any project / example doing it already, could you please point me the url ?
I am unaware of any examples that use a GUI.