Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to compile and link rust code into an android apk packed application

I'm trying to add Rust code to an android NDK sample (native-activity); Whenever I link Rust code (compiled as a .a) into the .so , it fails to run.

I went on information from here to get an android aware rust compiler and 'standalone toolchain' https://github.com/mozilla/rust/wiki/Doc-building-for-android

Someone was suggesting on the Rust IRC channel that I need to mention 'thumb' somewhere; is there an option to pass to rustc, or did I have to build it all differently in the first place?

I've certainly been able to call rust & c from eachother on desktop builds.

Is there a sample where someone has rust code working in a .apk; it would have to be simple.. its very hard to decipher makefiles for complex projects. (I think it would be very hard to figure this out from reading Servo source)

I've verified this process generates a useable package without adding rust; it only fails to run if I link unstripped rust code - even if it isn't reached (even though the linking doesn't tell me anything is wrong). If i remove the call to 'rusty_android()', it works. If i move the call to rusty_android to a point that isn't reached, it still doesn't work. I can verify with 'nm' that 'rusty_android' is in the .so ... unmangled.

This is my current build process: its taken from the android native-activity sample; i've added a rust source file with a single extern functin returning a value, and tried to debug print that from the samples' C main

ANDROID_CXX  = /opt/ndk_standalone/bin/arm-linux-androideabi-gcc

android:
    $(ANDROID_CXX) -I/home/ME/android-ndk-r9b/sources/android/native_app_glue -c jni/main.c  -o obj/local/armeabi/objs/native-activity/main.o
    rustc --target=arm-linux-androideabi hello_android.rs -C android-cross-path=/opt/ndk_standalone --crate-type=staticlib -o rusty_android.a
    $(ANDROID_CXX) -shared -o libs/armeabi/libnative-activity.so obj/local/armeabi/objs/native-activity/main.o obj/local/armeabi/libandroid_native_app_glue.a another.o rusty_android.a -llog -landroid -lEGL -lGLESv1_CM
   ant debug
   adb install -r bin/NativeActivity-debug.apk
   adb shell am start -n com.example.native_activity/android.app.NativeActivity




hello_android.rs:-

use std::libc;
#[no_mangle]
pub extern fn   rusty_android()->libc::c_int {
99 as libc::c_int
}

in main.c, inserted in android_main(..):-
    { extern int rusty_android(); LOGI("****rust says %d****", rusty_android()); }

The suspicion that something to specificy 'thumb' might be needed arose from comparing LLVM IR and asm sources, but it seems strange that it would be an additional option required over and above 'arm-linux-androideabi'

like image 761
centaurian_slug Avatar asked Mar 05 '14 14:03

centaurian_slug


1 Answers

Since I posted this, someone helped out and i've got this makefile that works..

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := rust-prebuilt
LOCAL_SRC_FILES := librusty_android.a

include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)

LOCAL_MODULE    := native-activity
LOCAL_SRC_FILES := main.c

LOCAL_LDLIBS    := -llog -landroid -lEGL -lGLESv1_CM 
LOCAL_STATIC_LIBRARIES +=  android_native_app_glue rust-prebuilt

include $(BUILD_SHARED_LIBRARY)

$(call import-module,android/native_app_glue)

So using this, one can link a prebuilt rust static library in the ndk samples' own link process.

So what is it doing behind the scenes, librusty_android-> rust-prebuilt .. does it just have different linker options I missed ? is it converting the libray somehow, or signing it ?

I can obviously make a single makefile to compile my rust code then call this as a final step but it would still be nice to simplify this out and find out why it works.

like image 197
centaurian_slug Avatar answered Sep 21 '22 17:09

centaurian_slug