I'm attempting to build a shared library for android, however I haven't found a single definitive source saying exactly what I need to do. I've been piecing together a build script but... it's not going well. What I'm trying to do is ultimately rather simple - I have 2 static libraries (opus and speexdsp). I import both of these into rust and then build a shared library with rust (which exports exactly the symbols I need from opus and speexdsp, slightly modified to suit my needs).
I have this working for windows and linux, but unfortunately I know next to nothing about building native code for Android! So far I have:
# Build opus
cd $OPUS
echo "APP_ABI := armeabi-v7a, x86" > Application.mk
cd $NDK
./ndk-build -C $OPUS NDK_PROJECT_PATH=. NDK_APPLICATION_MK=Application.mk APP_BUILD_SCRIPT=Android.mk
I do this for both opus and speexdsp, this produces me the static inputs to rust. My rust file (which works on windows and linux, so I'm fairly confident this isn't wrong) looks a bit like this:
extern "C" {
pub fn opus_encoder_create(Fs: i32, channels: i32, application: i32, error: *mut i32) -> *mut OpusEncoder;
}
#[no_mangle]
pub extern "C" fn do_stuff(samplingRate: i32, channels: i32, application: i32, error: mut i32) -> *mut ::OpusEncoder {
unsafe {
return ::opus_encoder_create(samplingRate, channels, application, error);
}
}
Finally I invoke cargo on this rust project. This is the bit that's going wrong. My script for this bit:
python $NDK/build/tools/make_standalone_toolchain.py --arch x86 --api 18 --install-dir x86_TOOLCHAIN
export ANDROID_NDK=$NDK
export ANDROID_SDK=$SDK
export ANDROID_TOOLCHAIN=x86_TOOLCHAIN
export PATH=$PATH:$ANDROID_TOOLCHAIN/bin
cargo clean
ANDROID_HOME=$ANDROID_SDK NDK_HOME=$ANDROID_NDK NDK_STANDALONE=$ANDROID_TOOLCHAIN cargo build --target=i686-linux-android
This is largely based on this guide from the servo wiki. This dies completely with a massive linker error:
error: linking with `cc` failed: exit code: 1
note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-Wl,--allow-multiple-definition" "-L" "/home/martin/.multirust/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib" "/home/martin/Desktop/DissonanceNative/target/i686-linux-android/debug/DissonanceNative.0.o" "-o" "/home/martin/Desktop/DissonanceNative/target/i686-linux-android/debug/libDissonanceNative.so" "/home/martin/Desktop/DissonanceNative/target/i686-linux-android/debug/DissonanceNative.metadata.o" "-nodefaultlibs" "-L" "/home/martin/Desktop/DissonanceNative/target/i686-linux-android/debug" "-L" "/home/martin/Desktop/DissonanceNative/target/i686-linux-android/debug/deps" "-L" "/home/martin/Desktop/DissonanceNative/links/android/x86" "-L" "/home/martin/.multirust/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib" "-Wl,-Bstatic" "-Wl,--whole-archive" "-l" "opus" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "-l" "speexdsp" "-Wl,--no-whole-archive" "-Wl,-Bdynamic" "-Wl,--whole-archive" "/tmp/rustc.fV3f6epx1dY2/libstd-39b92f95.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.fV3f6epx1dY2/libpanic_unwind-39b92f95.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.fV3f6epx1dY2/libunwind-39b92f95.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.fV3f6epx1dY2/librand-39b92f95.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.fV3f6epx1dY2/libcollections-39b92f95.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.fV3f6epx1dY2/librustc_unicode-39b92f95.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.fV3f6epx1dY2/liballoc-39b92f95.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.fV3f6epx1dY2/liballoc_system-39b92f95.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.fV3f6epx1dY2/liblibc-39b92f95.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.fV3f6epx1dY2/libcore-39b92f95.rlib" "-Wl,--no-whole-archive" "-l" "dl" "-l" "log" "-l" "gcc" "-l" "gcc" "-l" "c" "-l" "m" "-shared" "-l" "compiler-rt"
note: /usr/bin/ld: skipping incompatible /home/martin/Desktop/DissonanceNative/links/android/x86/libopus.a when searching for -lopus
/usr/bin/ld: cannot find -lopus
/usr/bin/ld: skipping incompatible /home/martin/Desktop/DissonanceNative/links/android/x86/libspeexdsp.a when searching for -lspeexdsp
/usr/bin/ld: cannot find -lspeexdsp
/usr/bin/ld: cannot find -llog
collect2: error: ld returned 1 exit status
Notably, this completely skipped over the opus and speexdsp inputs because they're incompatible.
Does anyone have any advice or suggestions? Even just a single guide which walks through all the steps would be extremely helpful!