【问题标题】:Could not link static c library with shared lib in android using Cmake无法使用 Cmake 将静态 c 库与 android 中的共享库链接
【发布时间】:2020-01-20 06:07:01
【问题描述】:

我一直在尝试使用 CMake.txt 将预构建的静态库与共享库链接。

以下是我的 Cmake.txt

add_library( # Specifies the name of the library.
         native-lib

         # Sets the library as a shared library.
         SHARED

         # Provides a relative path to your source file(s).
         src/main/cpp/native-lib.c )


         # Specifies a path to native header files.
        include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include/)
        add_library(my_test_lib STATIC IMPORTED)
        set_target_properties(my_test_lib PROPERTIES IMPORTED_LOCATION  ${CMAKE_SOURCE_DIR}/src/main/jni/libmytestlib.a)
        target_link_libraries(native-lib my_test_lib)

我已将 libmytestlib.a 放在 src/main/jni 位置。

我正在从 native-lib.c(shared lib) 调用 addnumbers() 函数。 函数在静态库中有定义。

每次我构建程序时都会出错

[2/2] Linking C shared library ..\..\..\..\build\intermediates\cmake\debug\obj\x86\libnative-lib.so
FAILED: cmd.exe /C "cd . && C:\Users\Rajeev\AppData\Local\Android\sdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang.exe  --target=i686-none-linux-android --gcc-toolchain=C:/Users/Rajeev/AppData/Local/Android/sdk/ndk-bundle/toolchains/x86-4.9/prebuilt/windows-x86_64 --sysroot=C:/Users/Rajeev/AppData/Local/Android/sdk/ndk-bundle/sysroot -fPIC -isystem 
 C:/Users/Rajeev/AppData/Local/Android/sdk/ndk-bundle/sysroot/usr/include/i686-linux-android -D__ANDROID_API__=18 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -mstackrealign -Wa,--noexecstack -Wformat -Werror=format-security  -O0 -fno-limit-debug-info  -Wl,--exclude-libs,libgcc.a --sysroot C:/Users/Rajeev/AppData/Local/Android/sdk/ndk-bundle/platforms/android-18/arch-x86 -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libnative-lib.so -o ..\..\..\..\build\intermediates\cmake\debug\obj\x86\libnative-lib.so CMakeFiles/native-lib.dir/src/main/cpp/native-lib.c.o  ../../../../src/main/jni/libmytestlib.a -lm && cd ."
 C:/Users/Rajeev/AppData/Local/Android/sdk/ndk-bundle/toolchains/x86-4.9/prebuilt/windows-x86_64/lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin\ld: error: ../../../../src/main/jni/libmytestlib.a(mytestlib.o): incompatible target

D:\Projects\Android_Projects\YegoMotoDriverBikeLoginPassIntg\app\src\main\cpp/native-lib.c:37: error: undefined reference to 'addnumbers'

clang.exe: error: linker command failed with exit code 1 (use -v to see invocation)

 ninja: build stopped: subcommand failed.

为什么每次都会出现不兼容的目标错误。我已经通过stackoverflow搜索但没有解决方案。请指导...

编辑

注意 - 静态库 libmytestlib.a 是在 LINUX 机器上预构建的

【问题讨论】:

  • 您需要使用与您的 Android 二进制文件相同的编译器(和目标架构)来编译 libmytestlib.a。有关交叉编译,请参阅 the manual。如果您告诉我们如何您构建了libmytestlib.a,我们可以向您展示如何交叉编译它。
  • @Botje 我们使用以下命令构建 libmytestlib.a $gcc -m64 -c mytestlib.c -o mytestlib.o $ ar rvs libmytestlib.a mytestlib.o

标签: java android


【解决方案1】:

到目前为止,最简单的解决方案是将构建委托给 CMake:

add_library(my_test_lib STATIC src/main/mytestlib/mytestlib.c)
target_link_libraries(native-lib my_test_lib)

Android 构建系统将负责每个平台调用一次 CMake。

假设你不能这样做,你需要单独手动构建libmytestlib.a for each ANDROID_ABI you intend to support。你至少想要armv7a-linux-androideabiaarch64-linux-android
例如:

mkdir -p src/main/jni/${ANDROID_ABI}
clang -target ${ANDROID_ABI}-android21 -c src/main/mytestlib/mytestlib.c -o src/main/jni/${ANDROID_ABI}/mytestlib.o
${ANDROID_ABI}-ar rvs src/main/jni/${ANDROID_ABI}/libmytestlib.a src/main/jni/${ANDROID_ABI}/mytestlib.o

则对应的CMake sn-p为:

add_library(my_test_lib STATIC IMPORTED)
set_target_properties(my_test_lib PROPERTIES IMPORTED_LOCATION  ${CMAKE_SOURCE_DIR}/src/main/jni/${ANDROID_ABI}/libmytestlib.a)
target_link_libraries(native-lib my_test_lib)

【讨论】:

  • 谢谢,我已经为所有不同的架构 armeabi, arch64-v8a and armeabi-v7a 构建了静态库,它适用于 build.gradle 中设置的对应 ndk 过滤器
  • 我已将这些静态库放在 JNI 文件夹中。现在,如果我在 build.gradle 中设置两个 abi 过滤器,比如 'armeabi' , 'arch64-v8a'。如何将兼容的两个库放在同一个 JNI 文件夹中。
  • 您可以像我一样按平台拆分jni目录并让cmake使用jni/$ANDROID_ABI/libmytestlib.a
猜你喜欢
  • 2013-10-09
  • 2020-04-27
  • 2015-10-08
  • 2018-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多