为了将我们的库文件更方便地提供给他人使用,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. MYSQL中怎么查询LONGBLOB类型数据的大小

    在MySQL中,LONGBLOB 是一种二进制大对象(BLOB)数据类型,用于存储大量的二进制数据.但是,LONGBLOB 数据类型本身并不直接存储数据的大小(长度).它存储的是二进制数据的实际内容. ...

  2. 【JavaScript】聊聊js中关于this的指向

    前言 最近在看回JavaScript的面试题,this 指向问题是入坑前端必须了解的知识点,现在迎来了ES6+的时代,因为箭头函数的出现,所以感觉有必要对 this 问题梳理一下,所以刚好总结一下Ja ...

  3. Canavs在文字上绘制删除线/中划线

    效果图: 思路: 绘制文字 绘制高度为1px的长方形,并用黑色填充 长方形的宽度为文字的长度 具体代码: let canvas = document.getElementById('canvas'); ...

  4. Spark3学习【基于Java】2. Spark-Sql核心概念

    SparkSession 从Spark2开始,Spark-SQL引入了SparkSession这个核心类,它是处理DataSet等结构数据的入口.在2.0之前,使用的是spark-core里的Spar ...

  5. Docker 总体架构图解

    Docker 的总体架构 Docker 是一个 C/S 模式的架构,后端是一个松耦合架构,模块各司其职. 下图是它的总体架构图: 1. 用户使用 Docker Client 与 Docker Daem ...

  6. css 手稿

    CSS 网页的布局和外观的显示样式 没有一张图解决不了的事:https://www.processon.com/mindmap/5e368a8be4b0d27af184e118 选择器 * 通配符选择 ...

  7. MyBatis xml文件头

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC & ...

  8. 基于 Impala 的高性能数仓建设实践之虚拟数仓

    导读:本文主要介绍网易数帆 NDH 在 Impala 上实现的虚拟数仓特性,包括资源分组.水平扩展.混合分组和分时复用等功能,可以灵活配置集群资源.均衡节点负载.提高查询并发,并充分利用节点资源. 接 ...

  9. centos7安装pcntl扩展

    查看PHP扩展加载的目录php -i | grep extension_dir Centos下使用yum安装php默认是都不带pcntl扩展,需要安装扩展需要下载安装包,编译安装. 首先查看你的服务器 ...

  10. 解码 xsync 的 map 实现

    解码 xsync 的 map 实现 最近在寻找 Go 的并发 map 库的时候,翻到一个 github 宝藏库,xsync (https://github.com/puzpuzpuz/xsync) . ...