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

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)

更多相关:

  • 1 模块简介在python中常见的模块有三种,在python解释器中的内置模块,第三方模块和自定义模块。模块的有使用python编写的文件,有已被编译为共享库或DLL的C或C++扩展,也有使用C编写连接到python解释器的内置模块和把一些列模块组织起来的文件(文件包)。python使用模块内置模块,第三方模块以及内置模块,是pyth...

  • 简介 OpenCV是一个C++库,用于实时处理计算机视觉方面的问题,涵盖了很多计算机视觉领域的模块。  OpenCV有两个Python接口,老版本的cv模块使用OpenCV内置的数据类型,新版本的cv2模块使用NumPy数组。 对于新版本的模块,可以通过下面方式导入: import cv2 而老版本的模块则通过下面方式导入: i...

  • 一、python中的模块 有过C语言编程经验的朋友都知道在C语言中如果要引用sqrt函数,必须用语句#include 引入math.h这个头文件,否则是无法正常进行调用的。 那么在Python中,如果要引用一些其他的函数,该怎么处理呢? 在Python中有一个概念叫做模块(module),这个和C语言中的头文件以及Ja...

  •  对于一些大型的项目来说,将项目的各个模块理清并进行管理,便于后续项目的维护,使用maven管理是很方便的,它可以很好的构建模块来设计项目的整体结构,对一些小型的项目不建议使用 1、新建父maven模块(idea版本为2017.2) 选择maven类型 点击next,填写GroupId和AtifactId 点击next 确认工...

  • nan 是not a number ,inf是无穷大 numpy.nan_to_num(x): 使用0代替数组x中的nan元素,使用有限的数字代替inf元素...

  • 简介 Simple Reference  基础CUDA示例,适用于初学者, 反映了运用CUDA和CUDA runtime APIs的一些基本概念.Utilities Reference  演示如何查询设备能力和衡量GPU/CPU 带宽的实例程序。Graphics Reference  图形化示例展现的是 CUDA, OpenGL,...

  • 在做开发的过程中难免需要给内核及下载的一些源码打补丁,所以我们先学习下Linux下使用如如何使用diff制作补丁以及如何使用patch打补丁。...

  • 我在调研ATS 4.2.3挂载SSD的过程中,遇到很多坑,特此详细记录我摸索的主要过程,以便大家以后避免之。 基本思路可以完全照搬参考文献[2][3] 下面的安装假定是以root用户身份进行的,Linux服务器已经安装好系统,磁盘已经做好分区。 首先需要认识我们的Linux服务器的硬件配置和软件情况 硬件配置: DELL...

  • 该博文整理一些在使用stl编程过程中遇到的小经验: 1.在多线程环境下面打印调试,如何使用cout及时刷新到屏幕上? 在C中我们经常这样使用: printf("Hello World "); fflush(stdout); 如果使用stl,我们可以这样使用: cout << "Hello World" << endl <...

  • 方法/步骤 1、新建一个project,或者如果已经有project的话,那就直接新建一个module.注意选择Java library,然后下一步 2、输入module的一些信息。点击finish 3、在左侧找到build.gradle,双击打开,参照图中修改一下配置 4、编写java代码测试下 转载于:https://...