Skip to content
This repository was archived by the owner on Jul 3, 2020. It is now read-only.

Building a native library #135

Open
torkleyy opened this issue Apr 26, 2017 · 19 comments
Open

Building a native library #135

torkleyy opened this issue Apr 26, 2017 · 19 comments

Comments

@torkleyy
Copy link

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.

@tomaka
Copy link
Contributor

tomaka commented Apr 26, 2017

In theory this should work as in any non-Android platform: http://doc.crates.io/build-script.html#overriding-build-scripts

@TatriX
Copy link

TatriX commented Oct 5, 2017

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.

@tomaka
Copy link
Contributor

tomaka commented Oct 5, 2017

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.

@TatriX
Copy link

TatriX commented Oct 5, 2017

Could you please point me to the docs on how I can do it?

@TatriX
Copy link

TatriX commented Oct 9, 2017

If I have libSDL2.so built for android, where should I place it so ld could find it?

@tomaka
Copy link
Contributor

tomaka commented Oct 9, 2017

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

@TatriX
Copy link

TatriX commented Oct 9, 2017

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

@tomaka
Copy link
Contributor

tomaka commented Oct 9, 2017

That means that libSDL2.so is not compiled for the right architecture (ARM vs x86, I guess)

@TatriX
Copy link

TatriX commented Oct 9, 2017

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?

@TatriX
Copy link

TatriX commented Oct 9, 2017

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

@tomaka
Copy link
Contributor

tomaka commented Oct 9, 2017

Well, try using only one to see if it works.

@TatriX
Copy link

TatriX commented Oct 9, 2017

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

@TatriX
Copy link

TatriX commented Oct 9, 2017

Hm, probably it's not related. But it still crashes.

@TatriX
Copy link

TatriX commented Oct 9, 2017

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)

@TatriX
Copy link

TatriX commented Oct 9, 2017

ok, I finally did it.
android_version = 21 did the trick

@mmacedoeu
Copy link

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 ?

@philip-alldredge
Copy link
Contributor

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.

@mmacedoeu
Copy link

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 ?

@philip-alldredge
Copy link
Contributor

I am unaware of any examples that use a GUI.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants