CMake 完整入门教程(一)

1 前言
每一次学习新东西都是很有乐趣的,虽然刚开始会花费时间用来学习,但是实践证明,虽然学习新东西可能会花费一些时间,但是它们带来的好处会远远超过这些花费的时间。学习新东西是值得的,也是很有乐趣的。
网络上 cmake 的教程很多,但是我发现我很难找到一个完整、详细的中文版教程。本文档
中的内容全部收集自网络。详细情况请见附录。
2 CMake 简介
CMake 是一个跨平台的安装 ( 编译 ) 工具,可以用简单的语句来描述所有平台的安装 ( 编译过
) 。他能够输出各种各样的 makefile 或者 project 文件,能测试编译器所支持的 C++
性,类似 UNIX 下的 automake
由于 CMake 易于使用,以及在跨多平台的支持上做得更好, CMake 得到了越来越多的人
的使用。下面的是来自 Google 的趋势图,可以看出 CMake 的应用情况。
2.1 CMakeLists.txt
CMake 靠的是 CMakeLists.txt 文件来生成工程的,事实上, CMakeList.txt 的编写就如使用
make 时编写 Makefile ,只不过,相对来说 CMake 站的高度更高一些,所以虽然还是要编
写一个配置文件,但是 CMakefile 的编写比 makefile 轻松简单很多,而 CMake 最后其实还
是通过生成 makefile 的方式来管理工程的(事实上, CMake 可以生成多种工程文件,甚至
支持 eclipse VC )。
CMakeLists.txt 里面则是具体的指令,用来告诉 CMake 如何生成工程。
2.2 编译和源代码分离
CMake 背后的逻辑思想是编译和源代码分离的原则。
通常 CMakeLists.txt 是和源代码放在一起的。一般每个子目录下都有一个 CMakeLists.txt
于组织该目录下的文件。
而针对具体的平台和配置,我们可以单独创建一个目录,然后在该目录下生成特定平台和
配置的工程文件。这样能够做到具体的工程文件不会和源代码文件混搭在一起。
2.3 CMakeLists.txt 自动继承父目录
子目录的 CMakeLists.txt 自动继承了父目录里的 CMakeLists.txt 所定义的一切宏、变量。这
极大地减少了重复的代码。
3 CMake 安装
要想使用 cmake ,先要安装它。去 www.cmake.org 下载一个最新的 cmake 版本。然后根据
安装说明安装即可。
安装完毕后,打开系统命令行,输入:
cmake --version
如果你看到类似如下的字符串,说明你安装成功了。
cmake version 2.8.12.1
4 CMake 命令行指令
4.1 从命令行生成工程
对于一个已经配置好了 CMakeLists.txt 的项目来说,从命令行生成工程文件是很简单的一
件事情。
下面是从命令行生成一个项目的工程文件的例子语句:
$cmake ..\Source -G "Visual Studio 10"
这条语句将在当前目录下,生成针对 ..\Source 目录的 Visual studio 2010 工程。 ..\Source
必须已经定义了 CMakeLists.txt
常用的 cmake 可以支持的工程类型为:
Visual Studio 10 = Generates Visual Studio 10 (2010) project files.
Visual Studio 11 = Generates Visual Studio 11 (2012) project.
Visual Studio 12 = Generates Visual Studio 12 (2013) project files.
MinGW Makefiles = Generates a make file for use with mingw32-make.
Unix Makefiles = Generates standard UNIX makefiles.
CodeBlocks - MinGW Makefiles = Generates CodeBlocks project files.
CodeBlocks - NMake Makefiles = Generates CodeBlocks project files.
CodeBlocks - Unix Makefiles = Generates CodeBlocks project files.
Eclipse CDT4 - MinGW Makefiles = Generates Eclipse CDT 4.0 project files.
Eclipse CDT4 - NMake Makefiles = Generates Eclipse CDT 4.0 project files.
Eclipse CDT4 - Unix Makefiles = Generates Eclipse CDT 4.0 project files.

4.2 生成 32 位和 64 位工程

对于 Windows MSVC ,我们可以设定 CMake Generator 来确定生成 Win32 还是 Win64 工程
文件,例如:
# 用于生成 Visual Studio 10 Win64 工程文件
$ cmake -G "Visual Studio 10 Win64"
# 用于生成 Visual Studio 10 Win32 工程文件 $ cmake -G "Visual Studio 10"
我们可以通过 CMake –help 来查看当前平台可用的 Generator
对于 UNIX 和类 UNIX 平台,我们可以通过编译器标志(选项)来控制进行 32 位还是 64
构建。
4.3 从命令行定义全局变量
在执行 cmake 指令的时候,可以定义任意多个全局变量。这些全局变量可以直接在
CMakeLists.txt 中被使用。这是一项很方便的功能。例如,如果你希望利用 cmake 生成多
种配置的工程,你可以将工程配置作为一个全局变量,在命令行指定。
在命令行定义全局变量的语法为:
$cmake ..\Source -G "Visual Studio 10" -DCONFIG=Debug -DSSE=True
这条指令定义了两个全局变量: CONFIG SSE ,其值分别是 "Debug" "True"
不要被这两个变量前面的 -D 所迷惑。那只是用来告诉 cmake ,要定义变量了。除此以外没
有任何意义
4.4 构建类型
CMake 为我们提供了四种构建类型:
Debug
Release
MinSizeRel
RelWithDebInfo
如果使用 CMake Windows MSVC 生成 projects/workspaces 那么我们将得到上述的 4 种解
决方案配置。
如果使用 CMake 生成 Makefile 时,我们需要做一些不同的工作。 CMake 中存在一个变
CMAKE_BUILD_TYPE 用于指定构建类型,此变量只用于基于 make 的生成器。我们可以
这样指定构建类型:
$ cmake -DCMAKE_BUILD_TYPE=Debug 这里的 CMAKE_BUILD_TYPE 的值为上述的 4 种构建类型中的一种。
4.5 直译模式
CMake 提供了直译模式,可以执行指定的 script 而不以生成 makefile 为目的 ,后面介绍的
语法特色都可以在直译模式下练习。
$ cmake -P <script-file>
虽然这意味着我们可以将 CMake 拿来当作一般的 scripting language 使用,但 CMake 先天
上就不是为了通用编程语言而设计,所以使用起来未必方便,特别是数学计算方面。
5 CMake 脚本基本语法
5.1 语法简介
CMake 的语法非常单纯,由指令 (command) 和注解所组成,所有的空白、换行、 tab 都没
有特殊作用,仅为语汇元素的区隔。
5.2 注释
凡是由 # 字符开头一直到换行字符间的内容皆会被视为注解,不会有任何作用。
# 这是注释
5.3 指令
5.3.1 基本语法
CMake script 由一连串的指令 (command) 组成,每个指令可有零至多个参数。使用指令的
语法为指令名称加上小括号,括号内可以有零或若干个参数,指令则依照出现在
CMakeLists 当中的顺序执行。
指令是不分大小写的!
cmake 中,所有指令名称大小写都一视同仁,例如 Command COMMAND 皆视为同一
个指令。
例如 message 指令常用来输出讯息:
message(hello)
会输出:
hello
5.3.2 参数的格式
指令的参数通常使用空格、 tab 或者换行来分隔,如:
command(arg1 arg2 arg3 ... argn)
command(
arg1
arg2
arg3
...
argn)
然而,值得注意的是, CMake 也支持用分号 ; 来分隔参数。不过我强烈不建议使用分号来
分隔参数。
5.3.3 在命令行查阅指令说明
输入:
cmake --help-command-list
可以查看到所有的指令列表。要想查阅某个指令的详细使用说明,例如 MESSAGE 指令,
可以在命令行输入:
cmake --help-command message
5.3.4 CMake.org 网站上查阅指令说明
cmake 2.8.12 的指令说明可以在这个地址查阅到:
http://www.cmake.org/cmake/help/v2.8.12/cmake.html
5.4 变量
在撰写 CMakeLists 时可以使用变量储存资料以及作为指令的参数。
5.4.1 变量的特征
CMake 中的变量具有以下特征:
变量严格区分大小写!
CMake 中的变量只有两种类型:字符串,和字符串数组。
变量无需声明即可赋值或者使用。未赋值的变量默认为一个空字符串。
与其他语言编程语言不同的是, CMake 脚本的语法中没有赋值操作。无论是赋
值,还是比较、判断操作,都是通过内置指令来完成的。
变量可以认为都是全局的,哪怕在一个宏中定义的变量,也可以在宏的外面被访问
到。
5.4.2 定义变量
字串和字串数组是 CMake 当中的唯一的两种变量类型。在 CMake 当中我们可以用 set()
令来设定一个变量的值,变量会在第一次使用的时候自动初始化,无须宣告。提取变量值
时通常必须在外面加上 ${} 符号,不过也有少数场合例外。
set(var hello)
message(${var})
会输出
hello
将字串用空白或分号分隔则表示字串数组。
set(foo this is a list)
set(foo this;is;a;list)
上面这两个指令作用完全相同,都是将变量 foo 值指定为一个字串数组,内含 this is
a list 四个字串。
如果在命令中,使用包含了字符串数组的变量作为参数会是怎样的情况呢?例如,下面的
变量:
set(foo a b c)
将其作为参数传入一个指令:
command(${foo}) 这等同于:
command(a b c)
将这个道理应用到其他地方。例如,要想在 foo 数组里面增加一个字符串怎么办呢?只要
foo 变量作为一个参数传递进去就可以了:
set(foo ${foo} d)
执行了该指令后,变量 foo 中则包含了四个字串: a b c d
5.4.3 变量的递归代换
我们知道,要使用一个变量,语法 ${variable} 可以提取出变量所存储的值。变量值的代换
甚至可以递归进行,在撰写复杂的功能时可能很有用。例如:
set(var hello)
set(foo var)
message(${foo})
message(${${foo}})
会输出
var
hello
5.4.4 系统内建全局变量
CMake 预定义了一系列内建变量。请注意,所有的内建变量都是以大写来定义的。
例如: CMAKE_CURRENT_SOURCE_DIR ,指的是当前处理的 CMakeLists.txt 所在的路径。
详细列表见后续章节。
5.4.5 cmake 调用环境变量的方式
使用 $ENV{NAME} 指令就可以调用系统的环境变量了。
比如
MESSAGE(STATUS “HOME dir: $ENV{HOME}”)
设置环境变量的方式是 :
SET(ENV{ 变量名 } )
5.5 字符串操作
5.5.1 不加引号直接使用字符串
CMake 中,指令的参数只有两种可能:
变量
字符串
如果字符串中不包含空格,那么可以不加引号,直接使用。例如:
set(var hello)
message(${var} world)
set 指令中使用了两个参数:第一个参数是字符串 "var" ,作为变量的名字;第二个参数是
字符串 "hello" ,作为变量的值。
message 指令中使用了两个参数:变量 var ,和字符串 "world"
5.5.2 在字符串中展开变量
在字符串中如果用 ${} 将一个变量名包了起来,那么该变量也会被代换。
例如,如果我们执行下面的指令:
set(foo a b c d)
command("${foo}")
则相当于我们执行了 command("a b c d")
5.5.3 使用特殊字符
在字串当中也可以插入空白、换行、分号等字符。例如:
set(a alpha beta gamma)
set(b "alpha beta gamma")
set(c "alpha
beta
gamma"
) message("a = ${a}")
message("b = ${b}")
message("c = ${c}")
其输出为:
a = alpha;beta;gamma
b = alpha beta gamma
c = alpha
bata
gamma
注意:
a 等于一个字串数组,内容为 alpha beta gamma 三个字串
b 等于一个字串,内容为 alpha beta gamma
c 等于一个字串,内容为以换行为分隔的 alpha beta gamma
5.5.4 转义字符串
CMake 大致上相容 C 语言当中的 Escape Sequence ,如 \t \n 等等。如欲表示 CMake 当中的
特殊字符时也可用 \ 标记。
set(bar "alpha beta gamma")
message("\${bar}: ${bar}")
上面的程式码输出
${bar}: alpha beta gamma
5.5.5 字符串连接
我们也可以利用 set 作字串串接:
set(a "alpha beta gamma")
set(b "${a} delta")
set(c ${a} "delta")
b 等于一个字串,内容为 "alpha beta gamma dalta"
c 等于一个字串数组,内容为 alpha beta gamma "dalta" 两个字串
5.6 布尔值
CMake 当中有些字串被赋予了布尔值的意义,大小写差异会被忽略:
以下这些会被视为 FALSE
OFF
FALSE
N
NO
0
"" ( 空字串 )
没被指派值的变量
NOTFOUND
任何结尾是 -NOTFOUND 的字串
以下这些会被视为 TRUE:
ON
TRUE
Y
YE
YES
1
其他不归类为 FALSE 的字串
5.7 数学计算
由于 CMake 当中并没有提供直接的数学运算符,所有的符号组合最终都会形成字串或字串
数组。数学计算必须透过 math 指令解释:
math(EXPR var "1 + 2 * 3")
message("var = ${var}")
输出为
var = 7

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/652297.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【K8S 云原生】K8S的图形化工具——Rancher

目录 一、rancher概述 1、rancher概念 2、rancher和K8S的区别&#xff1a; 二、实验 1、安装部署 2、给集群添加监控&#xff1a; 3、创建命名空间&#xff1a; 4、创建deployment&#xff1a; 5、创建service&#xff1a; 6、创建ingress&#xff1a; 7、创建hpa 8…

基于高精度YOLOv8开发构建公共场景下行人人员姿态估计分析识别系统

姿态估计&#xff08;PoseEstimation&#xff09;在我们前面的相关项目中涉及到的并不多&#xff0c;CV数据场景下主要还是以目标检测、图像识别和分割居多&#xff0c;最近正好项目中在使用YOLO系列最新的模型开发项目&#xff0c;就想着抽时间基于YOLOv8也开发构建实现人体姿…

[UI5 常用控件] 02.Title,Link,Label

文章目录 前言1. Title1.1 结合Panel1.2 结合Table1.3 Title里嵌套Link 2. Link3. Label3.1 普通用法3.2 在Form里使用 前言 本章节记录常用控件Title,Link,Label。 其路径分别是&#xff1a; sap.m.Titlesap.m.Linksap.m.Label 1. Title Title可以结合其他控件一起使用 1.…

总结红包雨项目的所有代码,包括添加图片,分享按钮,红包雨,用户是否有抽奖逻辑判断

整体实现效果: 需要用的图片: html: <body><div id"app"><!-- <div class"share-box"><img src"./share_box.png" alt"share-button"></div> --><!-- img图片 --><div class"gif-…

JVM基础知识汇总篇

☆* o(≧▽≦)o *☆嗨~我是小奥&#x1f379; &#x1f4c4;&#x1f4c4;&#x1f4c4;个人博客&#xff1a;小奥的博客 &#x1f4c4;&#x1f4c4;&#x1f4c4;CSDN&#xff1a;个人CSDN &#x1f4d9;&#x1f4d9;&#x1f4d9;Github&#xff1a;传送门 &#x1f4c5;&a…

翻译: GPT-4 with Vision 升级 Streamlit 应用程序的 7 种方式一

随着 OpenAI 在多模态方面的最新进展&#xff0c;想象一下将这种能力与视觉理解相结合。 现在&#xff0c;您可以在 Streamlit 应用程序中使用 GPT-4 和 Vision&#xff0c;以&#xff1a; 从草图和静态图像构建 Streamlit 应用程序。帮助你优化应用的用户体验&#xff0c;包…

《合成孔径雷达成像算法与实现》Figure5.18

clc clear close all距离向参数 R_eta_c 20e3; % 景中心斜距 Tr 25e-6; % 发射脉冲时宽 Kr 0.25e12; % 距离向调频率 Fr 7.5e6; % 距离向采样率 Nrg 256; % 距离线采样点数 Bw abs(Kr*Tr); …

.NET绿色开源一键自动化下载、安装、激活Office的利器

前言 今天分享一款.NET开源、绿色、安全、无毒的支持一键自动化下载、安装、激活Microsoft Office的利器&#xff1a;LKY_OfficeTools。 工具介绍 一键自动化下载、安装、激活 Microsoft Office 的利器。绿色、开源、安全、无毒。 目前包含的功能&#xff1a; 一键快速下载、…

【机器学习300问】16、逻辑回归模型实现分类的原理?

在上一篇文章中&#xff0c;我初步介绍了什么是逻辑回归模型&#xff0c;从它能解决什么问题开始介绍&#xff0c;并讲到了它长什么样子的。如果有需要的小伙伴可以回顾一下&#xff0c;链接我放在下面啦&#xff1a; 【机器学习300问】15、什么是…

C#,计算几何,二维贝塞尔拟合曲线(Bézier Curve)参数点的计算代码

Pierre Bzier Bzier 算法用于曲线的拟合与插值。 插值是一个或一组函数计算的数值完全经过给定的点。 拟合是一个或一组函数计算的数值尽量路过给定的点。 这里给出 二维 Bzier 曲线拟合的参数点计算代码。 区别于另外一种读音接近的贝塞耳插值算法&#xff08;Bessels int…

【CAD全套教程】第1阶段 CAD软件教程 002+003基础界面设置

002基础界面设置 1.切换界面至AutoCAD经典界面 方式一&#xff1a;任务栏点击后直接选择 方式二&#xff1a;右下角点击齿轮图标&#xff08;切换工作空间&#xff09;后直接选择 界面图 2.AutoCAD常用命令 工具栏右键单击&#xff0c;选择AutoCAD 3.命令提示行 最下方&#xf…

【Docker】实现JMeter分布式压测

一个JMeter实例可能无法产生足够的负载来对你的应用程序进行压力测试。如本网站所示&#xff0c;一个JMeter实例将能够控制许多其他的远程JMeter实例&#xff0c;并对你的应用程序产生更大的负载。JMeter使用Java RMI[远程方法调用]来与分布式网络中的对象进行交互。JMeter主站…

【前端web入门第二天】01 html语法实现列表与表格_合并单元格

html语法实现列表与表格 文章目录: 1.列表 1.1 无序列表1.2 有序列表1.3 定义列表 2.表格 2.1 表格基本结构2.2 表格结构标签2.3 合并单元格 写在最前,第二天学习目标: 列表 表格 表单 元素为嵌套关系 1.列表 作用:布局内容排列整齐的区域。 列表分类:无序列表、有序列表…

数字IC实践项目(8)—CNN加速器(ASIC_Flow;付费项目补充)

数字IC实践项目&#xff08;8&#xff09;—CNN加速器&#xff08;ASIC_Flow&#xff1b;付费项目补充&#xff09; 更新说明项目整体框图神经网络框图File tree 项目简介和学习目的软件环境要求 Area、QOR、Power&Timing报告Area & QORTiming & Power 总结 更新说…

【C++】类与对象(一)

前言 类与对象&#xff08;一&#xff09; 文章目录 一、面向对象和面向过程的对比二、类的引入2.1 C中的结构体2.2 类2.3 类定义方法2.4 修饰限定符2.5 封装2.6 类的实例化2.7 类对象的大小 三、this指针3.1 this 指针的使用 一、面向对象和面向过程的对比 面向过程编程是将程…

GoJS—交互式图表开发的神器(海量案例)

一、GoJS是什么&#xff1a; GoJS是一个用于创建交互式可视化图表和图形的JavaScript库。它提供了丰富的功能和工具&#xff0c;使开发人员能够轻松地构建各种类型的图表&#xff0c;包括流程图、组织结构图、网络拓扑图等。GoJS具有灵活的布局和样式设置&#xff0c;可以通过简…

Python中Numba库装饰器

一、运行速度是Python天生的短板 1.1 编译型语言&#xff1a;C 对于编译型语言&#xff0c;开发完成以后需要将所有的源代码都转换成可执行程序&#xff0c;比如 Windows 下的.exe文件&#xff0c;可执行程序里面包含的就是机器码。只要我们拥有可执行程序&#xff0c;就可以随…

基于STM32的智能手环设计与实现

需要原理图工程&#xff0c;源码&#xff0c;PCB工程的朋友收藏&#xff0c;这篇文章关注我&#xff0c;私我吧&#xff01;&#xff01;&#xff01; 基于STM32的智能手环设计与实现 摘要一、研究背景及意义二、实现功能三、系统方案设计系统方案设计框图3.1 单片机芯片选择3…

[HGAME 2023 week1]easyenc

查壳 IDA打开 字符串打开就发现了明显的标志 int __cdecl main(int argc, const char **argv, const char **envp) {__int64 v3; // rbx__int64 v4; // raxchar v5; // alchar *v6; // rcxint v8[10]; // [rsp20h] [rbp-19h]char v9; // [rsp48h] [rbpFh]__int128 v10[3]; //…

【Java】SpringMVC参数接收(一)

1、接收单个参数 &#xff08;1&#xff09;直接接收参数 RequestMapping("/hello") RestController public class HelloSpring {RequestMapping("/t2")public String t2(String name){return "name" name;} } 当没有传入参数时&#xff0c;返…