【问题标题】:how to compile and link rust code into an android apk packed application如何将 rust 代码编译并链接到 android apk 打包应用程序中
【发布时间】:2014-04-07 16:19:35
【问题描述】:

我正在尝试将 Rust 代码添加到 android NDK 示例(本机活动); 每当我将 Rust 代码(编译为 .a)链接到 .so 时,它都无法运行。

我从这里开始获取信息,以获得一个支持 android 的 rust 编译器和“独立工具链” https://github.com/mozilla/rust/wiki/Doc-building-for-android

有人在 Rust IRC 频道上建议我需要在某处提及“拇指”; 是否有传递给 rustc 的选项,还是我必须首先以不同的方式构建它?

我当然能够在桌面版本上互相调用 rust & c。

是否有示例表明某人在 .apk 中使用了 rust 代码;它必须很简单。要破译复杂项目的makefile非常困难。 (我认为通过阅读伺服源很难弄清楚这一点)

我已验证此过程会生成一个可用的包不会添加 rust;只有在我 link 未剥离的 rust 代码时,它才会运行失败——即使它没有达到(即使链接没有告诉我任何错误)。 如果我删除对“rusty_android()”的调用,它就可以工作。如果我将对 rusty_android 的调用移动到未达到的点,它仍然不起作用。我可以用 'nm' 验证 'rusty_android' 是否在 .so ... 中。

这是我当前的构建过程:它取自 android native-activity 示例;我添加了一个带有单个 extern 函数返回值的 rust 源文件,并尝试从示例的 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()); }

在比较 LLVM IR 和 asm 源时可能需要特定“thumb”的东西的怀疑,但奇怪的是它会是除了“arm-linux-androideabi”之外需要的额外选项

【问题讨论】:

  • 尚未尝试使用 Android 的 NativeActivity 进行任何操作,但我有一个正在运行的 Android Studio NDK 项目,该项目构建并链接到预先构建的 rust 共享库,并使用 C++ shim 进行 Java 之间的接口和锈。我刚刚用这些更改更新了Rust Wiki,如果你仍然需要,我不介意分享这个项目......

标签: android android-ndk arm rust thumb


【解决方案1】:

自从我发布此内容后,有人提供了帮助,我得到了这个有效的 makefile..

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)

因此,使用它,可以在 ndk 示例自己的链接过程中链接预构建的 rust 静态库。

那么它在幕后做了什么,librusty_android-> rust-prebuilt .. 它只是有我错过的不同链接器选项吗?它是以某种方式转换库,还是签名?

我显然可以制作一个单独的 makefile 来编译我的 rust 代码,然后将其作为最后一步调用,但简化它并找出 为什么它可以工作仍然会很好。

【讨论】:

  • 我正在尝试关注这个和github.com/rust-lang/rust/wiki/Doc-building-for-android,但我遇到了错误:b SharedLibrary : libnative-activity.so /home/skligys/Work/Android/android-ndk-r9d/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: jni/librust_android.a(r-compiler-rt-gcc_personality_v0.o): in function __gcc_personality_v0:/home/skligys/Temp/Rust/rust/src/compiler-rt/lib/builtins/gcc_personality_v0.c:206: error: undefined reference to '_Unwind_GetIP'
  • 我的问题与@SkirmantasKligys 完全相同。您是否以某种方式解决了这个问题?
  • @Bastian:我的第一个解决方法是从 Android NDK(定义 _Unwind_GetGR、_Unwind_SetGR、_Unwind_GetIP、_Unwind_SetIP)获取 unwind.c 并将其链接。我的第二个解决方法是切换到github.com/tomaka/android-rs-glue,开箱即用效果很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-05
  • 2011-06-03
  • 1970-01-01
  • 1970-01-01
  • 2013-02-21
  • 1970-01-01
  • 2017-01-27
相关资源
最近更新 更多