【问题标题】:Compiling native_app_glue.c results in an invalid library file编译 native_app_glue.c 导致库文件无效
【发布时间】:2019-12-03 00:31:21
【问题描述】:

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

我想将 android_native_app_glue.c 源代码(也由 NDK 提供)编译为静态库,以便稍后将其链接到我的最终应用程序。在出现错误后,说我缺少符号 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
...

基本上我的函数是“那里”,但大小为零。我假设它们在下一个链接中被丢弃,因为它们无效 - 用nm 查看下一个工件证实了这一点。

用于编译库的 CMake sn-p 相当简单,但为了完整起见,我将提供它:

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

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

【问题讨论】:

  • 对于 Android 应用程序,您必须提供一个共享库。您会发现不使用静态库来构建这个共享库会更容易,而是将所有相关源添加到共享库中。
  • @AlexCohn 我知道,最终产品是一个共享库,但它缺少ANativeActivity_onCreate。这就是为什么我开始研究从这个胶水 C 源文件编译的静态库,发现所有符号都是“无效的”。如果我不分多个步骤执行此操作,您认为会有所不同吗?
  • 构建 NativeActivity 通常是通过libnative_app_glue.a 完成的,参见developer.android.com/ndk/samples/sample_na。但是那里的说明从未针对 CMake 进行更新,因此将 android_native_app_glue.c 文件添加到您的共享库中可能会更容易。
  • @AlexCohn 所以...直接编译到目标确实有效。我不知道为什么。我会进一步调查。如果您愿意,请将其作为答案,我会接受它,如果我找出导致此行为的原因,可能会添加其他信息。

标签: android c++ cmake android-ndk


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    链接器尝试修剪来自非完整静态库的任何未使用的符号,并且ANativeActivity 不是使用目录,而是用于重新导出。

    您可以将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 风格。

    【讨论】:

    • target_link_libraries(mylib -u ANativeActivity_onCreate native_app_glue) 不起作用,因为 native_app_glue 库已经包含这些函数的无效条目(请参阅我的原始帖子,nm 输出)。此外,由于某种原因,我所有的链接器标志都通过ar 传递,它无法识别这些标志中的任何一个。
    猜你喜欢
    • 2021-11-16
    • 2020-02-15
    • 2020-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-06
    • 2015-11-09
    • 1970-01-01
    相关资源
    最近更新 更多