【问题标题】:Linking static ".a" libraries to an Android Studio project using Gradle and CMake使用 Gradle 和 CMake 将静态“.a”库链接到 Android Studio 项目
【发布时间】:2020-02-17 20:40:42
【问题描述】:

我需要使用 CMakeLists.txt 将预构建的“.a”静态库链接到 Android Studio 项目。

.a 库是为 armeabi、armeabiv-7a、mips 和 x86 正确构建的(它甚至可以被“objdumped”用于“内容检查”),并且“.h”文件也恰到好处。

我们的目标不是将库源代码与我的 Android Studio 项目原生源代码一起重新编译。

另外,请不要参考使用 NDK + Andoid.mk(仅限 CMakeLists.txt)的解决方案。

由于网络上没有关于此问题的有效示例(包括 Google NDK 文档和 SO),请提供项目文件和/或项目结构所需的所有更改。

我将“.a”文件及其“include”目录保存在本地文件夹中,因此作为对该位置的元引用,请考虑 /lib.a 和 /include。

谢谢。

【问题讨论】:

  • “因为网络上没有关于这个问题的有效示例” - 真的吗?你试过搜索吗?例如。那个问题:stackoverflow.com/questions/39202936/…
  • 我试过了。它不起作用。至少不适用于静态库。我得到的是一条消息,说我在静态库上调用的每个函数都是“未定义的引用”。我通过提供完整路径来强制 C++ 代码包含正确的头文件。所以,我相信静态库毕竟没有被链接。
  • 您使用target_link_libraries 复制库,不是吗?请出示您的代码 (CMakeLists.txt)。

标签: android gradle cmake static linker


【解决方案1】:

经过对该主题的长期研究,这是一个可行的解决方案,但存在一些小问题。

问题 #1:

这应该可以通过将 libxyz.a lib 文件及其 include 目录放在 {AndroidStudioProjects 文件夹}/{项目名称}/app/libs 但是由于某些(仍然未知的)原因,在我的系统上它从来没有那样工作过。

我设法通过将(lib 文件和包含目录)都放在:{AndroidStudioProjects 文件夹}/{项目名称}/app/src/main/cpp/libs(其中必须创建)。

问题 #2:

我遇到了一些 32 位 x 64 位的链接问题,所以在这一点上,我已经放弃了“胖 APK”,只保留了 32 位。

我做了什么

CMakeLists.txt上添加:

add_library(xyz STATIC IMPORTED)
set_target_properties(xyz PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libxyz.a)

并且在 target_link_libraries(到您的共享本机库)上,您必须添加“xyz”引用:

target_link_libraries(
    #the target shared lib:
    native-lib
    #other libs to link go here
    xyz)

额外:

如果您希望能够使用默认的包含目录在您的 C++ 代码中包含 libxyz.a 的标头,如下所示:

#inlcude <xyz.h>

你必须把它添加到CMakeLists.txt

include_directories( ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/include )

仅输出 32 位

build.gradle (Module:app) 上转到“android defaultConfig”块,就在“externalNativeBuild”之前并添加 ndk abiFilters:

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.your.project"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        ndk {
            abiFilters 'armeabi-v7a', 'x86'
        }
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }

请随时改进。

【讨论】:

    【解决方案2】:

    为您的项目创建一个子模块。

    将您的 *.a 文件放在适当的 libs/armAppropriate/nameOfLib.a 中

    在您的 cmakelists.txt 中添加以下行

    set(import-lib-location ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs)
    

    确保这与您的 libs 文件夹的位置相匹配,不要使用绝对路径

    把你的.h文件放到子模块main.cpp.include的include目录中

    将以下内容添加到您的 CmakeLists.txt 文件中

    include_directories(include/) 
    add_library(nameOfLib STATIC IMPORTED )
    set_target_properties(crypto
            PROPERTIES IMPORTED_LOCATION ${import-lib-location}/${ANDROID_ABI}/nameOfLib.a)
    
    
    target_link_libraries( # Specifies the target library.
            your_main_cpp_file
    
            nameOfLib
            )
    

    您的静态库将通过在您的主 cpp 文件中编写的 api 和在此模块中编写的 java/kotlin 代码提供

    在你的主模块的 build.gradle 中写

    api project(path: ':project_that_contains_a_libs')
    

    【讨论】:

      猜你喜欢
      • 2017-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多