CMakeFile学习笔记之常用CMake命令

2023-05-16

写在前面

本文主要是记录自己学习使用过程中遇到的CMake 指令,在此做一个总结,大部分内容来自与其他博主的总结博客,已在文中标明,如有侵权,请联系删除。

一、add_library 命令

参考链接:
[1] cmake学习笔记之add_library、target_link_libraries和link_directories https://blog.csdn.net/bigdog_1027/article/details/79113342

二、file命令

file(GLOB variable [RELATIVE path] [globbingexpressions]...)

GLOB 会产生一个由所有匹配globbing表达式的文件组成的列表,并将其保存到变量中。Globbing 表达式与正则表达式类似,但更简单。如果指定了RELATIVE 标记,返回的结果将是与指定的路径相对的路径构成的列表。 (通常不推荐使用GLOB命令来从源码树中收集源文件列表。原因是:如果CMakeLists.txt文件没有改变,即便在该源码树中添加或删除文件,产生的构建系统也不会知道何时该要求CMake重新产生构建文件。globbing 表达式包括:

   *.cxx     - match all files with extension cxx
   *.vt?      - match all files with extension vta,...,vtz
   f[3-5].txt - match files f3.txt,f4.txt, f5.txt

参考链接:
[1] CMakeFile命令之file https://blog.csdn.net/fuyajun01/article/details/8880121

三、include 命令

include(CMakeDependentOption) cmake内置,包含cmake_dependent_option方法。include(CheckCXXCompilerFlag) cmake内置,包含CHECK_CXX_COMPILER_FLAG用于检查C++标准支持情况。

参考链接:
[1] CMake 常用命令 https://zhuanlan.zhihu.com/p/258118287

四、Cmake命令之add_subdirectory介绍

命令格式

add_subdirectory (source_dir [binary_dir] [EXCLUDE_FROM_ALL]) #添加一个子目录并构建该子目录。

命令解析

  • source_dir
    必选参数。该参数指定一个子目录,子目录下应该包含CMakeLists.txt文件和代码文件。子目录可以是相对路径也可以是绝对路径,如果是相对路径,则是相对当前目录的一个相对路径。
  • binary_dir
    可选参数。该参数指定一个目录,用于存放输出文件。可以是相对路径也可以是绝对路径,如果是相对路径,则是相对当前输出目录的一个相对路径。如果该参数没有指定,则默认的输出目录使用source_dir。
  • EXCLUDE_FROM_ALL
    可选参数。当指定了该参数,则子目录下的目标不会被父目录下的目标文件包含进去,父目录的CMakeLists.txt不会构建子目录的目标文件,必须在子目录下显式去构建。例外情况:当父目录的目标依赖于子目录的目标,则子目录的目标仍然会被构建出来以满足依赖关系(例如使用了target_link_libraries)。

参考链接:
[1] Cmake命令之add_subdirectory介绍 https://www.jianshu.com/p/07acea4e86a3

五、cmake命令之install介绍

INSTALL指令

安装的需要有两种,一种是从代码编译后直接make install安装,一种是打包时的指定目录安装。
这里需要引入一个新的cmake 指令 INSTALL和一个非常有用的变量CMAKE_INSTALL_PREFIX。
CMAKE_INSTALL_PREFIX变量类似于configure脚本的 –prefix,常见的使用方法看
起来是这个样子:
cmake -DCMAKE_INSTALL_PREFIX=/usr .

INSTALL指令用于定义安装规则,安装的内容可以包括目标二进制、动态库、静态库以及
文件、目录、脚本等。

INSTALL指令包含了各种安装类型,我们需要一个个分开解释

  1. 目标文件的安装:
INSTALL(TARGETS targets...
        [[ARCHIVE|LIBRARY|RUNTIME]
                   [DESTINATION <dir>]
                   [PERMISSIONS permissions...]
                   [CONFIGURATIONS
        [Debug|Release|...]]
                   [COMPONENT <component>]
                   [OPTIONAL]
                ] [...])

参数中的TARGETS后面跟的就是我们通过ADD_EXECUTABLE或者ADD_LIBRARY定义的
目标文件,可能是可执行二进制、动态库、静态库。

目标类型也就相对应的有三种,ARCHIVE特指静态库,LIBRARY特指动态库,RUNTIME
特指可执行目标二进制。

DESTINATION定义了安装的路径,如果路径以/开头,那么指的是绝对路径,这时候
CMAKE_INSTALL_PREFIX其实就无效了。如果你希望使用CMAKE_INSTALL_PREFIX来
定义安装路径,就要写成相对路径,即不要以/开头,那么安装后的路径就是
${CMAKE_INSTALL_PREFIX}/<DESTINATION定义的路径>

举个简单的例子:

INSTALL(TARGETS myrun mylib mystaticlib
       RUNTIME DESTINATION bin
       LIBRARY DESTINATION lib
       ARCHIVE DESTINATION libstatic
)

上面的例子会将:
可执行二进制myrun安装到 ${CMAKE_INSTALL_PREFIX}/bin目录
动态库libmylib安装到 ${CMAKE_INSTALL_PREFIX}/lib目录
静态库libmystaticlib安装到 ${CMAKE_INSTALL_PREFIX}/libstatic目录
特别注意的是你不需要关心TARGETS具体生成的路径,只需要写上TARGETS名称就可以了。

  1. 普通文件的安装
INSTALL(FILES files... DESTINATION <dir>
         [PERMISSIONS permissions...]
         [CONFIGURATIONS [Debug|Release|...]]
         [COMPONENT <component>]
         [RENAME <name>] [OPTIONAL])
可用于安装一般文件,并可以指定访问权限,文件名是此指令所在路径下的相对路径。
如果默认不定义权限PERMISSIONS,安装后的权限为,OWNER_WRITE,OWNER_READ,
GROUP_READ,和WORLD_READ,即644权限。
  1. 非目标文件的可执行程序安装(比如脚本之类)
INSTALL(PROGRAMS files... DESTINATION <dir>
     [PERMISSIONS permissions...]
     [CONFIGURATIONS [Debug|Release|...]]
     [COMPONENT <component>]
     [RENAME <name>] [OPTIONAL])

跟上面的FILES指令使用方法一样,唯一的不同是安装后权限为:
OWNER_EXECUTE, GROUP_EXECUTE, 和WORLD_EXECUTE,即755权限

  1. 目录的安装
INSTALL(DIRECTORY dirs... DESTINATION <dir>
     [FILE_PERMISSIONS permissions...]
     [DIRECTORY_PERMISSIONS permissions...]
     [USE_SOURCE_PERMISSIONS]
     [CONFIGURATIONS [Debug|Release|...]]
     [COMPONENT <component>]
     [[PATTERN <pattern> | REGEX <regex>]
      [EXCLUDE] [PERMISSIONS permissions...]] [...])

这里主要介绍其中的DIRECTORY、PATTERN以及PERMISSIONS参数。
DIRECTORY后面连接的是所在Source目录的相对路径,但务必注意:
abc和abc/有很大的区别。
abc意味着abc这个目录会安装在目标路径下;
abc/意味着abc这个目录的内容会被安装在目标路径下;
如果目录名不以/结尾,那么这个目录将被安装为目标路径下的abc,如果目录名以/结尾,
代表将这个目录中的内容安装到目标路径,但不包括这个目录本身。
PATTERN用于使用正则表达式进行过滤,
PERMISSIONS用于指定PATTERN过滤后的文件权限。

我们来看一个例子:

INSTALL(DIRECTORY icons scripts/ DESTINATION share/myproj
        PATTERN "CVS" EXCLUDE
        PATTERN "scripts/*"
        PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
        GROUP_EXECUTE GROUP_READ)

这条指令的执行结果是:
将icons目录安装到 /share/myproj,将scripts/中的内容安装到
/share/myproj
不包含目录名为CVS的目录,对于scripts/*文件指定权限为 OWNER_EXECUTE
OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ.

  1. 安装时cmake脚本的执行
INSTALL([[SCRIPT <file>] [CODE <code>]] [...])
SCRIPT参数用于在安装时调用cmake脚本文件(也就是<abc>.cmake文件)
CODE参数用于执行CMAKE指令,必须以双引号括起来。比如:
INSTALL(CODE "MESSAGE(\"Sample install message.\")")

转载链接:
[1] CMake总结 - 4 INSTALL https://blog.csdn.net/yangfeng2014/article/details/50638601

六、add_definitions()

将 -D 定义标志添加到源文件的编译中。

add_definitions(-DFOO -DBAR ...)

为当前目录及以下目录中的源文件添加定义到编译器命令行。此命令可用于添加任何标志,但它旨在添加预处理器定义。以 -D/D开头的看起来像预处理器定义的标志会自动添加到COMPILE_DEFINITIONS 当前目录的目录中。具有非平凡值的定义可能会留在标志集中,而不是出于向后兼容性的原因进行转换。

简单来说就是:
之前在程序中需要使用宏定义 #define DEBUG 来实现,那么现在也可以在 CMakeLists.txt 中 add_definitions(-DDEBUG) 实现同样的功能。
在对应的程序源码中,可以这样进行使用:

#ifdef DEBUG
...
#endif

参考链接:
[1] 官方解释: https://cmake.org/cmake/help/v3.0/command/add_definitions.html#command:add_definitions
[2] 古路. CMakeLists中的add_definitions()函数 [EB/OL]. https://blog.csdn.net/fb_941219/article/details/107376017, 2020-07-16/2022-08-07.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CMakeFile学习笔记之常用CMake命令 的相关文章

  • 编译Robust Stereo Visual Inertial Odometry for Fast Autonomous Flight

    宾夕法尼亚大学kumar实验室2018年发布 Robust Stereo Visual Inertial Odometry for Fast Autonomous Flight xff0c 基于MSCKF基础上实现双目视觉惯导里程计 刚好这
  • 公网k8s集群搭建史上超详细的教程!!!

    一 背景 xff1a 1 实验背景 x1f9ea 在学习k8s搭建中 xff0c 网上大部分教程都是用虚拟机做单机集群 xff0c 只有极少数是使用服务器搭建教程 xff1b 但是用云服务器搭建的教程中教程版本都比较老 随着时间的推移 xf
  • 【repo/git小技巧】repo sync时报错“The remote end hung up unexpectedly”解决办法

    像往常一样使用repo init gt repo sync 的形式进行代码仓库下载 xff0c 但每次下载repo sync都不能执行成功 xff0c 问题为 The remote end hung up unexpectedly xff0
  • 在 React 中实现记忆以提高性能小技巧

    React 如何渲染 UI 在详细了解 React 中的 memoization 之前 xff0c 让我们先看看 React 如何使用虚拟 DOM 呈现 UI 常规 DOM 基本上包含一组表示为树的节点 DOM 中的每个节点都是 UI 元素
  • 《Linux内核设计与实现》读书总结

    Linux内核设计与实现 进程管理 进程 xff1a 处于执行器的程序 xff0c 包含代码段 xff0c 打开的文件 xff0c 信号 xff0c 内核内部数据 xff0c 内存地址空间 xff0c 多个线程 xff0c 存放全局变量的数
  • python无报错但是主函数没有执行

    python无报错但是主函数没有执行 是不是遇到过python没有报错 xff0c 但是主函数没有执行 xff0c 完全没有结果的情况 遇到这种情况很有可能就是你没有添加if name 61 61 main 这个东西 xff0c 或者格式不
  • 2018.2.2PHPstrom破解版

    作者 xff1a 聽 雨 来源 xff1a CSDN 原文 xff1a https blog csdn net qq 39439751 article details 82758330 版权声明 xff1a 本文为博主原创文章 xff0c
  • python3中 print不加括号报错!

    python 3和python 2的print是有区别 xff0c python3需要加括号 xff0c 但python2不需要 span class token operator gt gt span span class token o
  • leetcode 772 基本计算器3 双栈解析表达式 单调栈

    此题是比较难的一个题 xff0c 不能简单的用递归来做 假设我们已经能把数字分离出来 xff0c 并且解决了其他无关细节 此时我们要考虑 xff0c 如何处理括号和运算优先级 此题最强的一点是 xff0c 当你看到一个符号时 xff0c 你
  • 自然场景OCR检测(YOLOv3+CRNN)

    自然场景OCR检测 YOLOv3 43 CRNN xff08 中文 43 英文模型 xff09 前言 最近对于自然场景下的OCR比较有兴趣 xff0c 所以总结了一些目前OCR现状 xff0c 并且找了一个自然场景OCR的项目练练手 本人新
  • Tx2刷机及安装Jetpack4.5教程

    描述 xff1a 由于项目需要在工控机上运行目标检测程序 xff0c 所需配置需要包括Cuda OpenCV等软件配置 目前Nvidia已经将cuda opencv等相关用于图像处理 深度学习 计算机视觉所需的软件及文件集成到Jetpack
  • ROS gazebo 模型加载报错

    我的ros装的是ros kinetic desktop full版本 xff0c 所以不用另装gazebo 但是用命令 roscore rosrun gazebo ros gazebo 启动后 xff0c 出现如下错误 xff1a Erro
  • excel对比两边数据去重

    需求 筛选重复数据 xff0c A列是1000条数据 xff0c C列是100条数据 xff0c 删除重复的数据 xff0c 只剩900条 首先 xff0c A列数据要分列 xff0c 因为数据格式不一样 xff0c 会导致后面的问题 xf
  • GVIM的配置/使用

    关于GVIM的配置 使用 以我个人喜好配置 配置文件在用户目录下的 vimrc里 配置完后 xff0c 保存并bash一下即可 一 配置 xff1a 根据自己的喜好配置了一点点 colorscheme darkblue span class
  • 小白科研笔记:简析PointRCNN的基于Bin的误差机制

    1 前言 PointRCNN是一篇做3D目标检测的CVPR2019的文章 目前位居KITTI目标检测榜首的是PV RCNN 这个算法的前身就是PointRCNN 它们的作者都是同一个人 考虑到PV RCNN算法有些复杂 xff0c 于是我想
  • ROS基础:获取全局与局部launch Parameter

    在launch 参数配置中 xff0c 分为有全局参数和局部参数 私有参数 xff0c 两者参数的获取是不同的 xff0c 参数示例如下 xff1a lt launch gt lt 全局参数 gt lt param name 61 34 p
  • Redis分布式锁系列

    1 压力测试出的内存泄漏及解决 xff08 可跳过 xff09 使用jmeter对查询产品分类列表接口进行压力测试 xff0c 出现了堆外内存溢出异常 我们设置的虚拟机堆内存100m xff0c 并不是堆外内存100m 产生堆外内存溢出 x
  • java核心技术卷1基础知识整理

    java核心技术卷1基础知识整理 1 java概述2 java程序设计3 对象与类4 继承5 接口 lambda 表达式与内部类6 并发 1 java概述 1 Java 剔除了 C 43 43 中许多很少使用 难以理解 易混淆的特性 xff
  • 【论文笔记】—目标姿态估计—EPro-PnP—2022-CVPR

    论文介绍 该论文被评为 CVPR 2022 最佳学生论文 将PnP位姿优化问题转变为预测位姿概率密度的问题 对于一个基于PnP的物体位姿估计网络 xff0c 可以通过反向传播位姿的概率密度从而学习物体的2D 3D关联 xff0c 实现稳定的
  • STM32 HAL库串口回调函数配置失效(HAL_UART_RxCpltCallback)

    小编实际操作中 xff0c 用HAL UART RxCpltCallback函数配置接收串口数据 xff0c 在测试过程中用手碰了单片机引脚之后无法再接收到数据 xff0c 终于找到了解决办法 xff0c 就是自己使能接收中断和自己定义中断

随机推荐