为了将我们的库文件更方便地提供给他人使用,cmake 提供了一种方式,通过查找 .cmake 文件,将库导入项目中。

本节学习的内容,就是将我们的库导出一个 xxx.cmake 文件,以及 在项目中导入

本专栏的实践代码全部放在 github 上,欢迎 star !!!

如有问题,欢迎留言、或加群【392784757】交流

xxxConfig.cmake 文件是一个 CMake 配置文件用于在项目中查找和使用某个库。目的是方便在其 CMake 构建系统中找到并正确配置该库。

cmake_minimum_required(VERSION 3.20)

project(export_my_package)

file(WRITE include/slib.h "void slib();")
file(WRITE slib.cpp [=[ #include <iostream>
#include "slib.h"
void slib()
{
std::cout<<"in slib func\n" <<std::endl;
}
]=]) add_library(slib STATIC slib.cpp)
# 导出头文件; file glob 加入所有 头文件
set_target_properties(slib PROPERTIES PUBLIC_HEADER include/slib.h)

设置 头文件include路径,这里的设置有两个层面

如果仅这样设置

target_include_directories(slib PUBLIC include) # PUBLIC 第三方调用时 也可以导入头文件

会在构建时报错

#[[
Target "slib" INTERFACE_INCLUDE_DIRECTORIES property contains path: "E:/my-github-repos/learn-cmake-together/ref_course/506export_my_package/include" which is prefixed in the source directory. ]]

提示 INTERFACE_INCLUDE_DIRECTORIES 包含了一个源目录路径。这个路径是绝对路径,而不是相对于安装目录的相对路径。当你尝试导出或安装这个目标时,绝对路径可能会导致错误,因为在安装后的环境中,这个路径可能不存在。

因此我们需要对这个include 路径进行 分别设置,一个是 构建时,一个是导出时【也就是他人使用时 用到的路径】

通过 生成表达式 我们可以根据 是在哪个行为 进而设置路径

# 路径被两次引用 1 编译slib 库时 2 export 写入config时
target_include_directories(slib PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> # 仅在编译时有效
$<INSTALL_INTERFACE:include> # 只在install 时有值 绝对路径/include
)

安装导出

在安装过程中,通过添加EXPORT 这一指令,将我们的库配置文件导出

install(TARGETS slib
EXPORT slib # 导出
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
PUBLIC_HEADER DESTINATION include
) install(EXPORT slib FILE slibConfig.cmake DESTINATION config)

导出文件的默认名称

# Config.cmake

# slibConfig.cmake

构建指令

cmake -B build -S .
cmake --build build
cmake --install build --prefix=out # --config=Debug # windows下需要添加--congig

执行后,结构如下



在config 目录下,有库对应的 xxx.cmake 文件,也就是我们后续导入库 需要找到的文件

导入

cmake_minimum_required(VERSION 3.20)
project(find_my_package) file(WRITE main.cpp [=[ #include "slib.h"
#include <iostream> using namespace std;
int main()
{
cout<<"in main"<<endl;
slib();
return 0;
}
]=])
find_package(slib) message("slib_found = ${slib_FOUND}")
if(slib_FOUND)
message("find slib success!")
endif() add_executable(main main.cpp) target_link_libraries(main slib) get_target_property(inc slib INTERFACE_INCLUDE_DIRECTORIES)
message("INTERFACE_INCLUDE_DIRECTORIES = ${inc}")

执行后提示 找不到

CMake Warning at CMakeLists.txt:21 (find_package):
By not providing "Findslib.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "slib", but
CMake did not find one. Could not find a package configuration file provided by "slib" with any of
the following names: slibConfig.cmake
slib-config.cmake Add the installation prefix of "slib" to CMAKE_PREFIX_PATH or set
"slib_DIR" to a directory containing one of the above files. If "slib"
provides a separate development package or SDK, be sure it has been
installed.

通过提示,我们看到添加slib路径的方法

  1. 添加 slib 安装路径 到 CMAKE_PREFIX_PATH
  2. 设置 slib_DIR 变量 包含 xxx.cmake 路径
set(slib_DIR "替换包含 slibConfig.cmake 所在的路径")

然后重新构建,执行

导入成功

版本问题

相关的库可以设置版本,设定相应的限制,只导入指定要求的版本,这样也需要在导出配置时,进行一定的设置

version 的变量值 可以预先设定 + -Dversion 传入的方式实现

install(EXPORT slib FILE slibConfig.cmake DESTINATION config/slib-${version})
# <packagename>Config.cmake
# slibConfig.cmake # 写入版本信息 slibConfigVersion.cmake
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
${CMAKE_INSTALL_PREFIX}/config/slib-${version}/slibConfigVersion.cmake
VERSION ${version}
COMPATIBILITY SameMajorVersion #版本兼容问题 cmake.org.cn
)

【CMake系列】07-export与find的更多相关文章

  1. Java 集合系列 07 List总结(LinkedList, ArrayList等使用场景和性能分析)

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  2. JavaScript进阶系列07,鼠标事件

    鼠标事件有Keydown, Keyup, Keypress,但Keypress与Keydown和Keyup不同,如果按ctrl, shift, caps lock......等修饰键,不会触发Keyp ...

  3. 委托、Lambda表达式、事件系列07,使用EventHandler委托

    谈到事件注册,EventHandler是最常用的. EventHandler是一个委托,接收2个形参.sender是指事件的发起者,e代表事件参数. □ 使用EventHandler实现猜拳游戏 使用 ...

  4. 线程系列07,使用lock语句块或Interlocked类型方法保证自增变量的数据同步

    假设多个线程共享一个静态变量,如果让每个线程都执行相同的方法每次让静态变量自增1,这样的做法线程安全吗?能保证自增变量数据同步吗?本篇体验使用lock语句块和Interlocked类型方法保证自增变量 ...

  5. C#程序集系列07,篡改程序集

    以下几个方面用来区分不同的程序集:○ 程序集名称:Name○ 程序集版本:Version○ 程序集公匙: Public Token○ 程序集文化:Culture 如果没有很严格地按照上面的几个方面来创 ...

  6. CMake命令之export

    CMake中与export()相关的命令 (注:红色字体是标题,粉色是需要特别需要注意的地方) 总的来说,export()命令想要做的事情可以用一句话概括:Export targets from th ...

  7. Hibernate 系列 07 - Hibernate中Java对象的三种状态

    引导目录: Hibernate 系列教程 目录 1. Java对象的三种状态 当应用通过调用Hibernate API与框架发生交互时,需要从持久化的角度关注应用对象的生命周期. 持久化声明周期是Hi ...

  8. Java 集合系列07之 Stack详细介绍(源码解析)和使用示例

    概要 学完Vector了之后,接下来我们开始学习Stack.Stack很简单,它继承于Vector.学习方式还是和之前一样,先对Stack有个整体认识,然后再学习它的源码:最后再通过实例来学会使用它. ...

  9. Android Studio 单刷《第一行代码》系列 07 —— Broadcast 广播

    前情提要(Previously) 本系列将使用 Android Studio 将<第一行代码>(书中讲解案例使用Eclipse)刷一遍,旨在为想入坑 Android 开发,并选择 Andr ...

  10. 1. CMake 系列 - 从零构建动态库和静态库

    目录 1. 文件目录结构 2. 库文件源代码 3. 编译生成库文件 1. 文件目录结构 首先创建如下目录结构: └── lib ├── build # ├── CMakeLists.txt └── s ...

随机推荐

  1. ABC199E

    考虑状压. 设计状态 \(dp_{i,j}\) 表示考虑 \(i\) 个数,每个数的使用情况的二进制压缩表示为 \(j\) 的情况下的方案数. 然后去正常转移. 唯一特殊的是将限制放在点上,假若这个点 ...

  2. python3 模型日记

    说明 作为一种 python 框架模型的记录吧,用于个人总结,不定时更新. 正文 1. 主进程退出后,子进程也跟着退出 之前遇到过一种情况,用 flet 写了一个页面,然后又同时开了一个 tcp se ...

  3. 如何在 Windows 使用 Podman Desktop 取代 Docker Desktop

    Podman Desktop 是 Docker Desktop 的免费替代品,是本地开发使用的另一个绝佳选择.它提供了类似的功能集,同时保持完全开源,让您避免使用 Docker 产品的许可问题.在本文 ...

  4. 树莓派4B-PCA9685驱动舵机

    前言 不知道你们有没有遇到过这么一种情况,直接用树莓派的引脚输出PWM控制舵机,舵机是会出现抖动的.就算代码进行一定的时延迟优化还是会有影响的. 现在我们可以使用PCA9685这个模块去驱动舵机. P ...

  5. TIOBE 7月编程排行榜出炉!Python再次出圈

    又到了周三,本周有过半了,大家好呀 ~~ 每月的TIOBE编程排行榜都是技术社区关注的焦点,作为编程语言流行度的晴雨表,它反映了行业趋势和 技术走向.2024年7月的榜单揭晓了一个重要变化:Pytho ...

  6. [oeasy]python021_赛博宝剑铭文大赏_宝剑上的铭文_特殊符号和宝物

    继续运行 回忆上次内容 上次修改了 程序 将 石中剑 变成了 红色 爱之大剑       添加图片注释,不超过 140 字(可选)   可以 让宝剑 具有 更多 铭文符号 和 颜色 吗?   铭文 亚 ...

  7. OI-Wiki 学习笔记

    算法基础 \(\text{Update: 2024 - 07 - 22}\) 复杂度 定义 衡量一个算法的快慢,一定要考虑数据规模的大小. 一般来说,数据规模越大,算法的用时就越长. 而在算法竞赛中, ...

  8. hbuilderx打正式包所需的私钥证书的创建方法

    现在使用uniapp作为底层框架来开发app应用已经成为了很多公司的事实标准,而uniapp的开发工具hbuilderx云打包的时候,需要私钥证书和证书profile文件. 而且还需要将打包好的ipa ...

  9. Zabbix 5.0 LTS 配置企业微信(Webhook)自动发送告警信息

    依据前面文章<Zabbix 5.0 LTS URL 健康监测>环境,实现企业微信(Webhook)自动发送告警信息. 一.创建企业微信机器人 先在自己的企业微信群里创建一个机器人,并获取其 ...

  10. P1973 [NOI2011] NOI 嘉年华

    思路: 先将时间进行离散化,设总时间为 \(cnt\),然后考虑求出 \(W(l,r)\),即在时间段 \([l,r]\) 内的所有节目,可以 \(n^2\) 前缀和,也可以 \(n^3\) 暴力. ...