栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

CMake 打包已经存在的动态库生成 target

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

CMake 打包已经存在的动态库生成 target

一. 背景

在 CMakeLists.txt 中,某模块 A 通过 add_subdirectory 引入模块 B ,模块 B 通过 add_subdirectory 引入模块 C。模块 C 里面本身就是一个开源的动态库,比如 libtask。目的想要将 C 模块打包成一个 Target ,以便在 A 模块中中使用方便。

二. 旧版本实现和存在问题

A 模块不直接使用 C 模块,但是 A 模块使用到了 B 模块,B 模块编译依赖 C 模块,就需要导致 A 编译时要通过下面的方式引入 C 模块

  include_directories(${CMAKE_SOURCE_DIR}/thirdparty/B/thirdparty/C/include)
  link_directories(${CMAKE_SOURCE_DIR}/thirdparty/B/thirdparty/C/lib)

该使用方式 A 即为不友好。如果上层存在 M 模块依赖 A 模块,也要通过类似方式用 C,导致使用上极为不友好。

三.解决方案

在 CMake 中有 Target 的概念,尝试单独将 C 打包成一个 Target,这样之后,当 A 依赖 B 时,B 依赖 C,A 不需要直接通过上面相对路径的方式,因为 Target 已经被包进去了。于是在 C 模块中,将所有的已经存在的 so 打包起来:

cmake_minimum_required (VERSION 3.10)

project(libtask)

file(WRITE ${PROJECT_BINARY_DIR}/empty.cpp "")
add_library (${PROJECT_NAME} SHARED ${PROJECT_BINARY_DIR}/empty.cpp)

target_include_directories(${PROJECT_NAME} PUBLIC include)
target_link_libraries(${PROJECT_NAME} PUBLIC
  ${CMAKE_CURRENT_SOURCE_DIR}/lib/libtask-a.so
  ${CMAKE_CURRENT_SOURCE_DIR}/lib/libtask-b.so
)

在 B 模块使用 A 模块时,可以使用下面的方式

xxx
add_subdirectory(thirdparty/libtask)
xxx
target_link_libraries(${PROJECT_NAME} PRIVATE libtask)

其他有问题的方案:
在实现 C 时也可以通过 INTERFACE 的方式打包 C,使用下面的方式:

cmake_minimum_required (VERSION 3.10)

project(libtask)

add_library (${PROJECT_NAME} INTERFACE)

target_include_directories(${PROJECT_NAME} INTERFACE include)
target_link_libraries(${PROJECT_NAME} INTERFACE
  ${CMAKE_CURRENT_SOURCE_DIR}/lib/libtask-a.so
  ${CMAKE_CURRENT_SOURCE_DIR}/lib/libtask-b.so
)

由于想要使用 INTERFACE 的方式打包库文件,此时就就必须使用 INTERFACE 的方式包含头文件和库文件,这样子就导致外部 A 模块无法直接使用 C 的库文件和头文件,还要使用

xxx
add_subdirectory(thirdparty/libtask)
xxx
target_link_libraries(${PROJECT_NAME} PRIVATE libtask)
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/630666.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号