当前位置: 首页 > news >正文

NDK CMake工程中引入其他C++三方库

在Android NDK CMake工程中引入其他C++三方库时,有以下几种常见的依赖方式:

1. 源码依赖

如果三方库的源代码包含在你的项目目录中,并且它有自己的CMake配置,可以使用add_subdirectory将三方库的构建过程集成到你的项目中。

示例:

假设三方库的源代码位于third_party/SomeLibrary目录下。

# CMakeLists.txt# 添加三方库的构建
add_subdirectory(third_party/SomeLibrary)# 添加可执行文件目标
add_library(native-lib SHARED native-lib.cpp)# 将三方库链接到目标
target_link_libraries(native-lib PRIVATE SomeLibrary)

2. 预编译库依赖

如果三方库已经预先编译成.so.a文件,可以使用add_librarytarget_link_libraries来引入这些预编译库。
适用场景:第三方库已提供针对 Android 的预编译动态库(.so)和头文件。

示例:

假设三方库的预编译.so文件位于libs/${ANDROID_ABI}/libSomeLibrary.so

# CMakeLists.txt# 添加预编译库
add_library(SomeLibrary SHARED IMPORTED)
set_target_properties(SomeLibrary PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libSomeLibrary.so)# 添加可执行文件目标
add_library(native-lib SHARED native-lib.cpp)# 将预编译库链接到目标
target_link_libraries(native-lib PRIVATE SomeLibrary)
方式 1:预编译动态库(.so

步骤

  1. 放置文件

    • .so 文件按 ABI 分类放入 src/main/jniLibs/abi/ 目录(如 armeabi-v7a/libmylib.so)。
    • 将头文件放入 src/main/cpp/include/ 目录。
  2. 配置 CMakeLists.txt

    # 设置头文件路径
    include_directories(src/main/cpp/include)# 导入动态库(以 openssl 为例)
    add_library(openssl SHARED IMPORTED)
    set_target_properties(openssl PROPERTIESIMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libssl.so
    )# 添加自己的目标(如共享库)
    add_library(native-lib SHAREDsrc/main/cpp/native-lib.cpp
    )# 链接第三方库和系统库(如 log)
    target_link_libraries(native-libopenssllog  # Android 系统日志库
    )
    

方式 2:预编译静态库(.a

步骤

  1. 放置文件

    • .a 文件放入 src/main/jniLibs/abi/ 目录。
    • 头文件放入 src/main/cpp/include/
  2. 配置 CMakeLists.txt

    # 导入静态库(如 libpng)
    add_library(png STATIC IMPORTED)
    set_target_properties(png PROPERTIESIMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libpng.a
    )# 链接静态库
    target_link_libraries(native-libpnglog
    )
    

3. 使用FetchContent模块(CMake 3.11+)

如果三方库可以从远程位置(如Git仓库)获取,可以使用FetchContent模块在构建过程中自动下载和构建三方库。

示例:

假设三方库的Git地址为https://github.com/someuser/SomeLibrary.git

# CMakeLists.txt# 启用FetchContent模块
include(FetchContent)# 下载并构建三方库
FetchContent_Declare(SomeLibraryGIT_REPOSITORY https://github.com/someuser/SomeLibrary.gitGIT_TAG        main
)
FetchContent_MakeAvailable(SomeLibrary)# 添加可执行文件目标
add_library(native-lib SHARED native-lib.cpp)# 将三方库链接到目标
target_link_libraries(native-lib PRIVATE SomeLibrary)

4. 手动指定源文件

如果三方库的源代码是一个简单的库,没有复杂的构建系统,可以直接将源文件添加到你的CMake工程中。

示例:

假设三方库的源文件位于third_party/SomeLibrary/src目录下,头文件位于third_party/SomeLibrary/include目录下。

# CMakeLists.txt# 添加三方库的源文件
add_library(SomeLibrary STATIC)
target_sources(SomeLibrary PRIVATEthird_party/SomeLibrary/src/file1.cppthird_party/SomeLibrary/src/file2.cpp
)
target_include_directories(SomeLibrary PRIVATEthird_party/SomeLibrary/include
)# 添加可执行文件目标
add_library(native-lib SHARED native-lib.cpp)# 将三方库链接到目标
target_link_libraries(native-lib PRIVATE SomeLibrary)

步骤

  1. 将源码放入项目目录

    • 将第三方库的源码放在 thirdparty/ 目录下(如 thirdparty/openssl)。
  2. 配置 CMakeLists.txt

    # 将第三方库的源码目录加入子目录编译
    add_subdirectory(${CMAKE_SOURCE_DIR}/thirdparty/openssl)# 添加自己的目标
    add_library(native-lib SHARED src/main/cpp/native-lib.cpp)# 链接编译后的库
    target_link_libraries(native-libopenssl  # 假设第三方库生成的库名为 openssllog
    )
    

5. 使用include_directories指定头文件路径

如果需要引入三方库的头文件,可以使用include_directories指定头文件路径。

示例:

假设三方库的头文件位于third_party/SomeLibrary/include目录下。

# CMakeLists.txt# 指定头文件路径
include_directories(third_party/SomeLibrary/include)# 添加可执行文件目标
add_library(native-lib SHARED native-lib.cpp)# 如果是预编译库,还需要指定库文件路径并链接
# add_library(SomeLibrary SHARED IMPORTED)
# set_target_properties(SomeLibrary PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libSomeLibrary.so)
# target_link_libraries(native-lib PRIVATE SomeLibrary)

方式 4:系统库查找(find_package

步骤

  1. 确保库已安装

    • 第三方库需在系统中安装(如通过 NDK 或包管理器安装)。
  2. 配置 CMakeLists.txt

    # 查找已安装的 OpenCV 库
    find_package(OpenCV REQUIRED)# 添加目标并链接
    add_library(native-lib SHARED src/main/cpp/native-lib.cpp)
    target_include_directories(native-lib PRIVATE ${OpenCV_INCLUDE_DIRS})
    target_link_libraries(native-lib ${OpenCV_LIBS} log)
    

方式 5:自动下载编译(ExternalProject_Add

步骤

  1. 配置 CMakeLists.txt
    # 下载并编译第三方库(如 gtest)
    include(ExternalProject)
    ExternalProject_Add(gtestGIT_REPOSITORY https://github.com/google/googletest.gitCMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/gtest
    )# 添加目标并链接
    add_library(gtest-lib INTERFACE)
    target_include_directories(gtest-lib INTERFACE${CMAKE_BINARY_DIR}/gtest/include
    )
    target_link_libraries(gtest-lib INTERFACE${CMAKE_BINARY_DIR}/gtest/lib/libgtest.a
    )# 使用 gtest
    add_executable(my_test test.cpp)
    target_link_libraries(my_test gtest-lib)
    

关键配置说明

  1. 头文件路径

    include_directories(  # 传统方式src/main/cpp/includethirdparty/include
    )# 推荐使用 target_include_directories
    target_include_directories(native-lib PRIVATE${CMAKE_SOURCE_DIR}/src/main/cpp/include
    )
    
  2. 动态库路径的动态化

    • 使用 ${ANDROID_ABI} 变量自动适配不同 ABI:
      set(LIB_DIR ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI})
      set_target_properties(png PROPERTIESIMPORTED_LOCATION ${LIB_DIR}/libpng.so
      )
      
  3. 依赖传递性

    • 如果第三方库依赖其他库(如 libcrypto.so),需逐层导入:
      add_library(crypto SHARED IMPORTED)
      set_target_properties(crypto PROPERTIESIMPORTED_LOCATION ${LIB_DIR}/libcrypto.so
      )
      target_link_libraries(openssl PRIVATE crypto)  # openssl 依赖 crypto
      

总结:依赖方式对比

  • 源码依赖:适用于三方库的源代码已经包含在项目目录中,并且有CMake配置。
  • 预编译库依赖:适用于三方库已经预先编译成.so.a文件。
  • FetchContent:适用于从远程位置获取并自动构建三方库。
  • 手动指定源文件:适用于简单的三方库,直接将源文件添加到工程中。
  • include_directories:适用于需要引入三方库的头文件。
    | 方式 | 是否需要源码 | 适用场景 | 优点 | 缺点 |
    |------------------------|--------------|-----------------------------------|-------------------------------|-------------------------------|
    | 预编译动态库(.so) | 不需要 | 第三方提供预编译动态库 | 快速集成,无需编译 | 需确保 ABI 兼容性 |
    | 预编译静态库(.a) | 不需要 | 第三方提供静态库 | 静态链接,无依赖传递问题 | 文件体积较大 |
    | 源码编译(add_subdirectory) | 需要 | 需自定义编译或库未提供预编译文件 | 灵活配置,支持修改源码 | 需处理交叉编译及依赖 |
    | 系统库(find_package) | 不需要 | 系统已安装且提供 CMake 配置文件 | 自动化配置,简洁 | 依赖系统环境 |
    | 自动下载(ExternalProject) | 需要 | 需自动管理源码下载和编译 | 自动化流程,便于版本控制 | 构建时间较长 |

通过以上方法,可以根据第三方库的提供形式和项目需求,灵活选择最合适的依赖方式。


http://www.mrgr.cn/news/96189.html

相关文章:

  • Redis和三大消息队列
  • STM32F103_LL库+寄存器学习笔记09 - DMA串口接收与DMA串口发送,串口接收空闲中断
  • VxKex无法通过快捷方式启动程序
  • gogs私服搭建
  • ZeroMQ介绍及如何交叉编译在嵌入式Linux下使用
  • ESP32-CAM在PlatformIO IDE里实现OTA的几个小TIPS
  • 骨密度以及骨密度测量,测量方案,意义;提高;实现方案
  • jmeter 镜像构建
  • C语言学习关键笔记
  • 数据结构C语言练习(顺序表)
  • 论文阅读笔记:Denoising Diffusion Implicit Models
  • nara wpe去混响学习笔记
  • 力扣刷题第一遍
  • Microi吾码界面设计引擎之基础组件用法大全【内置组件篇·中】
  • Leetcode算法方法总结
  • 生成器的应用 async与await实现
  • 【leetcode hot 100 347】前 K 个高频元素
  • centos8上实现lvs集群负载均衡nat模式
  • mysql--主从复制--部署
  • 循环神经网络(RNN)