CMake 安装动态库并生成 XxxConfig.cmake 文件

文章目录

  • CMake 安装动态库并生成 XxxConfig.cmake 文件
    • 引言
    • 展示
    • 简单解释CMakeLists.txt
      • set_target_properties
      • target_include_directories
      • configure_package_config_file
      • write_basic_package_version_file
      • install
        • TARGETS
        • FILES|PROGRAMS
        • EXPORT

引言

之前说了一下《使用 CMake 生成动态库/静态库》,既然写了动态库,那肯定是要提供给别人调用的,我们就来看看要怎么调用

写过 cmake 的都应该知道,cmake 通过 find_package 去找动态库,find_package 会去调用 XxxConfig.cmake 或 xxx-config.cmake 或 FindXxx.cmake 文件去找动态库,上述文件出现的顺序就是调用的优先级,前两个文件一般是库作者提供的,后一个主要用于库作者没提供前两个文件的时候我们自己编写一个给 find_package 调用。

展示

直接上 CMakeLists.txt

cmake_minimum_required(VERSION 3.16)project(FooLibrary VERSION 1.0.0)set(CMAKE_CXX_STANDARD 11)add_library(${PROJECT_NAME} SHARED library.cpp)# 这个使用了生成器表达式,其他项目引入包的时候就可以同时引入头文件包含路径
target_include_directories(${PROJECT_NAME} INTERFACE$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>$<INSTALL_INTERFACE:include>)set(CONFIG_FILE_PATH share/cmake/${PROJECT_NAME})include(GNUInstallDirs)include(CMakePackageConfigHelpers)configure_package_config_file(FooLibraryConfig.cmake.in${CMAKE_BINARY_DIR}/FooLibraryConfig.cmakeINSTALL_DESTINATION ${CONFIG_FILE_PATH}PATH_VARS CMAKE_INSTALL_INCLUDEDIR)write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmakeVERSION ${CMAKE_PROJECT_VERSION}COMPATIBILITY SameMajorVersion)install(TARGETS ${PROJECT_NAME}EXPORT ${PROJECT_NAME}Targets)install(EXPORT ${PROJECT_NAME}TargetsDESTINATION ${CONFIG_FILE_PATH})install(FILES${CMAKE_BINARY_DIR}/FooLibraryConfig.cmake${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmakeDESTINATION ${CONFIG_FILE_PATH})

FooLibraryConfig.cmake.in

@PACKAGE_INIT@include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")

FooLibraryConfig.cmake.in

下面这几句主要是为了设置 <PackageName>_NCLUDE_DIR <PackageName>_NCLUDES <PackageName>_LIBRARY <PackageName>_LIBRARIES <PackageName>_LIBS 等变量,但是这些变量 CMake 没有要求且各个库提供的都不一样,所以也可以不设置。

@PACKAGE_INIT@include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")get_target_property(@PROJECT_NAME@_LIBRARY @PROJECT_NAME@ LOCATION)
set_and_check(@PROJECT_NAME@_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@")

然后就可以使用了

find_package(FooLibrary)
target_link_libraries(${PROJECT_NAME} FooLibrary)

简单解释CMakeLists.txt

set_target_properties

https://cmake.org/cmake/help/latest/command/set_target_properties.html

set_target_properties(target1 target2 ...PROPERTIES prop1 value1prop2 value2 ...)

安装的时候会将 PUBLIC_HEADER 后面指定的头文件安装到指定的路径,默认为 include

target_include_directories

https://cmake.org/cmake/help/latest/command/target_include_directories.html

target_include_directories(<target> [SYSTEM] [AFTER|BEFORE]<INTERFACE|PUBLIC|PRIVATE> [items1...][<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])

上面的写法是可重定位的,PRIVATEPUBLIC 会设置 targe t的 INCLUDE_DIRECTORIES 属性;PUBLICINTERFACE 会设置给 target 的 INTERFACE_INCLUDE_DIRECTORIES 属性;里面有的那两个参数叫做什么生成表达式,也不知这个翻译对不对,官网传送门cmake-generator-expressions

configure_package_config_file

https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html

configure_package_config_file(<input> <output>INSTALL_DESTINATION <path>[PATH_VARS <var1> <var2> ... <varN>][NO_SET_AND_CHECK_MACRO][NO_CHECK_REQUIRED_COMPONENTS_MACRO][INSTALL_PREFIX <path>])

与 configure_file 差不多,但是这个用来写 cmake config 文件会好很多,INSTALL_DESTINATION config文件将要安装的位置,PATH_VARS 指定的变量,可以在 Config.cmake.in 文件中类似这样 @PACKAGE_VAR1@ 引用,这种用法可重定位,而不是硬编码

write_basic_package_version_file

https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html

write_basic_package_version_file(<filename>[VERSION <major.minor.patch>]COMPATIBILITY <AnyNewerVersion|SameMajorVersion|SameMinorVersion|ExactVersion>[ARCH_INDEPENDENT] )

VERSION 不指定的话就用 PROJECT_VERSION,都没有指定的话就会报错;COMPATIBILITY 版本兼容,有好几个选项,具体看官网

install

https://cmake.org/cmake/help/latest/command/install.html

install(TARGETS <target>... [...])
install({FILES | PROGRAMS} <file>... [...])
install(DIRECTORY <dir>... [...])
install(SCRIPT <file> [...])
install(CODE <code> [...])
install(EXPORT <export-name> [...])

TARGETS

install(TARGETS targets... [EXPORT <export-name>][[ARCHIVE|LIBRARY|RUNTIME|OBJECTS|FRAMEWORK|BUNDLE|PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE][DESTINATION <dir>][PERMISSIONS permissions...][CONFIGURATIONS [Debug|Release|...]][COMPONENT <component>][NAMELINK_COMPONENT <component>][OPTIONAL] [EXCLUDE_FROM_ALL][NAMELINK_ONLY|NAMELINK_SKIP]] [...][INCLUDES DESTINATION [<dir> ...]])

FILES|PROGRAMS

install(<FILES|PROGRAMS> files...TYPE <type> | DESTINATION <dir>[PERMISSIONS permissions...][CONFIGURATIONS [Debug|Release|...]][COMPONENT <component>][RENAME <name>] [OPTIONAL] [EXCLUDE_FROM_ALL])

TYPE 取值以及默认路径; GNUInstallDirs Variable 需要 include(GNUInstallDirs)

TYPE Argumen GNUInstallDirs Variable Built-In Default
BIN ${CMAKE_INSTALL_BINDIR} bin
SBIN ${CMAKE_INSTALL_SBINDIR} sbin
LIB ${CMAKE_INSTALL_LIBDIR} lib
INCLUDE ${CMAKE_INSTALL_INCLUDEDIR} include
SYSCONF ${CMAKE_INSTALL_SYSCONFDIR} etc
SHAREDSTATE ${CMAKE_INSTALL_SHARESTATEDIR} com
LOCALSTATE ${CMAKE_INSTALL_LOCALSTATEDIR} var
RUNSTATE ${CMAKE_INSTALL_RUNSTATEDIR} <LOCALSTATE dir>/run
DATA ${CMAKE_INSTALL_DATADIR} <DATAROOT dir>
INFO ${CMAKE_INSTALL_INFODIR} <DATAROOT dir>/info
LOCALE ${CMAKE_INSTALL_LOCALEDIR} <DATAROOT dir>/locale
MAN ${CMAKE_INSTALL_MANDIR} <DATAROOT dir>/man
DOC ${CMAKE_INSTALL_DOCDIR} <DATAROOT dir>/doc

如果不指定 PERMISSIONSFILES 默认权限为 OWNER_WRITE, OWNER_READ, GROUP_READ, WORLD_READPROGRAMS 额外还有 OWNER_EXECUTE, GROUP_EXECUTE, WORLD_EXECUTE 权限

EXPORT

需要 install TARGETS 的时候 EXPORT 才行

install(EXPORT <export-name> DESTINATION <dir>[NAMESPACE <namespace>] [[FILE <name>.cmake]|[PERMISSIONS permissions...][CONFIGURATIONS [Debug|Release|...]][EXPORT_LINK_INTERFACE_LIBRARIES][COMPONENT <component>][EXCLUDE_FROM_ALL])

由于个人水平有限,文中若有不合理或不正确的地方欢迎指出改正

若文中个人文章链接打不开,请在站内寻找同名文章

文章可能更新不及时,请以个人博客处文章为准

006 - CMake 安装动态库并生成 XxxConfig.cmake 文件相关推荐

  1. C++中.lib静态库、.dll动态库的生成及调用1

    一.前言 1.动态链接库(dll)与静态链接库(lib): 动态链接库(dll)是一个可以被其他应用程序共享的程序模块,其中封装了一些可以被共享的例程和资源.在链接步骤中,连接器将从库文件取得所需的代 ...

  2. 【Android NDK 开发】Android Studio 使用 CMake 导入动态库 ( 构建脚本路径配置 | 指定动态库查找路径 | 链接动态库 )

    文章目录 I . CMake 引入动态库与静态库区别 II . Android Studio 中 CMake 引入动态库流程 III . 指定动态库查找路径 IV . 链接函数库 V . 完整代码示例 ...

  3. 【Android NDK 开发】Android.mk 配置动态库 ( Android Studio 配置动态库 | 动态库加载版本限制 | 本章仅做参考推荐使用 CMake 配置动态库 )

    文章目录 I . Android Studio 中使用 Android.mk 配置动态库 总结 II . 第三方动态库来源 III . 配置 Android.mk 构建脚本路径 IV . 预编译 第三 ...

  4. C++中.lib静态库、.dll动态库的生成及调用2

    关于动.静态库的介绍及静态库的生成及调用参见:C++中.lib静态库..dll动态库的生成及调用<1>,本文主要介绍基于VS2015平台的动态库dll的生成及调用方法. 一.动态库的生成 ...

  5. linux中动态链接库用扩展名,Linux操作系统下动态库的生成及链接方法是什么?...

    Linux下动态库文件的扩展名为".so"(Shared Object).按照约定,所有动态库文件名的形式是libname.so(可能在名字中加入版本号).这样,线程函数库被称作l ...

  6. Linux 静态库和动态库的生成及使用

    1.分文件编程 分模块的编程思想:假设一个项目需要用到网络.超声波.电机,程序不是都杂糅在同一个文件,而是将网络.超声波.电机需要调用的函数写在不同文件里,在主文件中直接调用即可. 好处: a.功能责 ...

  7. NDK01-打包静态库 动态库在mk和cmake环境配置使用

    动态库和静态库 动态库: libxxx.so 运行的时候,才会去加载,加载一次就在内存中存在副本,其他地方使用就都是公用的.使用场景就是 高德百度sdk对外开房 静态库: libxxx.a 编译期把静 ...

  8. 库文件:静态库与动态库的生成和使用

    0.引言 当进行C语言的编写时,想要查看标准库的某个函数是怎样实现的,比如 stdio.h 里的 printf 函数,跳转后只能看见函数声明,而无法跳转到函数的定义处,为什么无法查看函数的定义,这就涉 ...

  9. c# 利用动态库DllImport(kernel32)读写ini文件(提供Dmo下载)

    c# 利用动态库DllImport("kernel32")读写ini文件 自从读了设计模式,真的会改变一个程序员的习惯.我觉得嘛,经验也可以从一个人的习惯看得出来,看他的代码编写习 ...

最新文章

  1. 图之典—可视化图表的词典
  2. 添加gitignore文件后使其生效
  3. Django之Xadmin
  4. SharePoint 2010 大中小架构的部署
  5. 25岁程序员 VS 35岁程序员,太真实!
  6. 重定义 不同的基类型_镍及铁镍基耐蚀合金高温合金哈氏合金镍基合金之第一篇概述...
  7. Linux-Ubuntu安装 MySQL
  8. 数据库健康状况监视_监视数据库运行状况和行为:哪些指标重要?
  9. python库怎么绘画_[雪峰磁针石博客]python绘图作业:使用pygame库画房子
  10. 【渝粤题库】陕西师范大学500901 基础物理专题(力、热) 作业(专升本)
  11. 各种数据集汇总——转载而来
  12. 创建一个HashMap 集合,存储省份下的城市,key是为省份 value 是为该省份下的城市
  13. 阿里云文字转语音接口
  14. 预演:使用 TensorFlow 进行深度学习
  15. React生命周期详解
  16. Refresh PDB
  17. JAVA基础——对象与引用概念(转载)
  18. Blender图解教程:手把手教你独立游戏开发必备的极简式贴图法
  19. 人工智能基础——什么是人工智能
  20. Linux select函数的使用

热门文章

  1. IDEA spring之p命名空间注入
  2. Praat脚本-013 | 无需标注自动切除音频首尾静音段
  3. 项目实战 | Excel导出(一)——导出方式
  4. Unity3D组件 | Excel导出
  5. 24行代码简单实现qq空间自动点赞
  6. 祝愿大家新年快乐,祝愿祖国繁荣昌盛
  7. 在生词本查单词的译文
  8. 有了ERP,工厂有必要再部署一套WMS仓储管理系统吗
  9. 来自LinuxAid的2004年9月盘点
  10. 解决移动硬盘符不见的问题