问题
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'
回答1:
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.
来源:https://stackoverflow.com/questions/22200621/how-to-compile-and-link-rust-code-into-an-android-apk-packed-application