编译 native_app_glue.c 导致库文件无效

Compiling native_app_glue.c results in an invalid library file

我正在将 C++ 库交叉编译为 Android。我使用 CMake 作为构建生成器,并且使用 NDK 中提供的工具链文件(名为 android.toolchain.cmake)。请注意,我在 Windows.

我想将 android_native_app_glue.c 源代码(同样由 NDK 提供)编译为静态库,以便稍后 link 将其用于我的最终应用程序。在出现错误后,说我缺少符号 ANativeActivity_onCreate,我开始调查。 ANativeActivity_onCreate 是在 android_native_app_glue.c 中定义的函数,所以我查看了使用 nm -o libnative_glue.a 编译的库,看到这个非常令人惊讶:

libnative_glue.a:android_native_app_glue.c.o:0000000000000000 T ANativeActivity_onCreate
libnative_glue.a:android_native_app_glue.c.o:0000000000000000 t android_app_create
libnative_glue.a:android_native_app_glue.c.o:0000000000000000 t android_app_destroy
libnative_glue.a:android_native_app_glue.c.o:0000000000000000 t android_app_entry
libnative_glue.a:android_native_app_glue.c.o:0000000000000000 t android_app_free
...

基本上我的函数是 "there",但大小为零。我假设它们在下一个 link 时被丢弃,因为它们无效 - 查看下一个带有 nm 的工件证实了这一点。

编译该库的 CMake 片段相当简单,但为了完整起见,我将提供它:

add_library(native_glue STATIC "${CMAKE_ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c")

我有两个预定义的 CMake 缓存条目,ANDROID_ABI=arm64-v8aANDROID_PLATFORM=24

什么会导致这个无效的库编译?

linker 试图删除来自非完整静态库的任何未使用的符号,并且 ANativeActivity 不是使用的目录,而是用于重新导出。

您可以 link libnative_app_glue 作为整个存档,或者使用 -u 来防止符号被删除。

-u:

target_link_libraries(mylib -u ANativeActivity_onCreate native_app_glue)

整个档案:

target_link_libraries(mylib -Wl,--whole-archive native_app_glue -Wl,--no-whole-archive)

我还没有用 CMake 实际测试过其中任何一个。虽然已知 ndk-build 等效项可以工作。

您也许还可以使用 object library,这是整个档案的 CMake 风格。

构建 NativeActivity 通常是通过 libnative_app_glue.a 完成的,参见 https://developer.android.com/ndk/samples/sample_na

不幸的是,那里的说明从未针对 CMake 进行更新,因此将 android_native_app_glue.c 文件添加到您的共享库可能更容易。