CMake教程 CMake Tutorial(翻译自官方教程)

本文是自己在学习CMake过程中的简单记录。主要内容来自CMake官方教程,有一些自己的理解,也不知道是否正确,请酌情参考。

简介(Introduction)

CMake教程是按步骤进行的学习向导。Cmake涵盖内容多,使用例子学习Cmake各部分是如何工作的,易于理解。

步骤(Steps)

本教程例子的源代码可从CMake官方提供的地址下载。每一步一个文件夹,包括代码,可供学习使用。本教程是分步进行的,每一步都是对上一步的修改完善。

CMake教程步骤1:开始(CMake Tutorial--Step 1: A Basic Starting Point)

如何开始学习CMake?本步骤,介绍CMake的基本语法(syntax)、命令(commands)以及变量(variables)。介绍完基础知识后,会通过三个小练习来创建一个简单的CMake项目(project)。

本步骤的每次练习都会用到一些背景知识。会列出练习的目标,可供参考的资料。编辑文件(Files to Edit)章节下的文件都位于Step1文件夹下,文件中都有步骤(TODO)提示。每个步骤(TODO)表示有一行或两行代码需要修改或增加。步骤(TODO)需要按序号顺序来完成,例如,需先完成步骤1(TODO 1)再完成步骤2(TODO 2)开始(Getting Started)章节下,会给一些提示,帮助读者完成练习。生成运行(Build and Run)章节,则一步一步地生成、测试练习。最后,给出练习的参考答案。
需要注意的是,本教程每步是基于上一步的,例如进行步骤2,需要完成步骤1。

练习1:建立基本的项目(Exercise 1 - Building a Basic Project)

最基本的Cmake项目是由一个单独的源文件生成可执行文件,这样简单的项目,只需要一个由三行命令组成的CMakeList.txt文件。
注意:对于CMake,命令中的字母大写、小写或者大小写都有,CMake都能识别出,但是本教程建议使用小写字母。

每个项目中最顶层的CMakeList.txt,最开始需要的命令是声明所需CMake的最低版本,命令是cmake_minimum_required()(给出的链接,命令的使用帮助,看不太明白)。使用此命令来指定CMake的版本,以确保接下来的CMake函数和设置可以运行。

使用命令project() ,来指定项目名。每个项目都需要此条命令,并且紧跟在cmake_minimum_required()命令之后。此命令还可以指定项目的其他信息如语言、版本号等。

最后,CMake使用命令add_executable() ,来从指定的源文件创建可执行文件。

目标(Goal)

学习如何创建最简单的CMake项目

参考资料(Helpful Resources)

需编辑的文件(Files to Edit)

  • CMakeLists.txt

开始(Getting Started)

在文件夹Help/guide/tutorial/Step1提供了源文件tutorial.cxx,由于计算数值的平方根。本步骤不需要修改此文件。

在此文件夹下,需要修改完成CMakeLists.txt文件,需要完成第一步(TODO 1)第一步TODO 3

练习答案(Soution)

(本节本来在练习的最后,我感觉放在这里,更适合新手学习使用。)

CMakeLists.txt文件第一行需要使用命令cmake_minimum_required()设置CMake的版本:

  • 第一步(TODO 1),在文件CMakeLists.txt中:
    cmake_minimum_required(VERSION 3.10)

下一步使用命令project(),创建项目,并命名:

  • 第二步(TODO 2),在文件CMakeLists.txt中:
    project(Tutorial)

最后一条命令是,add_executable():

  • 第三步(TODO 3),在文件CMakeLists.txt中:
    add_executable(Tutorial tutorial.cxx)

生成运行

完成第一步(TODO 1)第一步TODO 3后,就可以生成运行项目了。首先,运行cmakecmake-gui,配置(configure)项目,然后使用选择的生成工具生成。

例如,在文件夹Help/guide/tutorial(我的是D:\VisualStudioProjects\cmake-3.26.0-rc6-tutorial-source)下,运行命令行,创建生成目录:
mkdir Step1_build

接下来,进入Step1_build文件夹下,运行cmake配置项目、生成本地构建系统:
cd Step1_build
cmake ../Step1

PS D:\VisualStudioProjects\cmake-3.26.0-rc6-tutorial-source> mkdir Step1_build


    目录: D:\VisualStudioProjects\cmake-3.26.0-rc6-tutorial-source


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         3/11/2023   7:00 PM                Step1_build


PS D:\VisualStudioProjects\cmake-3.26.0-rc6-tutorial-source> cd .\Step1_build\
PS D:\VisualStudioProjects\cmake-3.26.0-rc6-tutorial-source\Step1_build> cmake ../Step1
-- Building for: Visual Studio 17 2022
-- The C compiler identification is MSVC 19.35.32215.0
-- The CXX compiler identification is MSVC 19.35.32215.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: D:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.35.32215/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: D:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.35.32215/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (7.1s)
-- Generating done (0.1s)
-- Build files have been written to: D:/VisualStudioProjects/cmake-3.26.0-rc6-tutorial-source/Step1_build
PS D:\VisualStudioProjects\cmake-3.26.0-rc6-tutorial-source\Step1_build>

接下来,调用构建系统完成项目的编译/链接(compile/link):
cmake --buid .

PS D:\VisualStudioProjects\cmake-3.26.0-rc6-tutorial-source\Step1_build> cmake --build .
MSBuild version 17.5.0+6f08c67f3 for .NET Framework

  Checking Build System
  Building Custom Rule D:/VisualStudioProjects/cmake-3.26.0-rc6-tutorial-source/Step1/CMakeLists.txt
  tutorial.cxx
  Tutorial.vcxproj -> D:\VisualStudioProjects\cmake-3.26.0-rc6-tutorial-source\Step1_build\Debug\Tutorial.exe
  Building Custom Rule D:/VisualStudioProjects/cmake-3.26.0-rc6-tutorial-source/Step1/CMakeLists.txt
PS D:\VisualStudioProjects\cmake-3.26.0-rc6-tutorial-source\Step1_build>

最后,进入Debug文件夹下,运行生成的Tutorial程序:

PS D:\VisualStudioProjects\cmake-3.26.0-rc6-tutorial-source\Step1_build> cd .\Debug\
PS D:\VisualStudioProjects\cmake-3.26.0-rc6-tutorial-source\Step1_build\Debug> .\Tutorial.exe 10
The square root of 10 is 3.16228
PS D:\VisualStudioProjects\cmake-3.26.0-rc6-tutorial-source\Step1_build\Debug>

练习2:指定C++标准(Exercise 2 - Specifying the C++ Standard)

CMade有些特殊的变量(variables)或由后台生成,或由项目代码设置对CMAke有特殊用途。这些变量的前缀是CMAKE_。在自己项目中命名变量时避免使用此前缀。其中的两个变量是,CMAKE_CXX_STANDARDCMAKE_CXX_STANDARD_REQUIRED,这两个变量可赋值。这两个变量组合使用,可指定生成项目所需的C++标准。

目标(Goal)

添加要求C++11标准的特性(feature)。

资料(Helpful Resources)

需编辑的文件(Files to Edit)

  • CMakeLists.txt
  • tutorial.cxx

开始(Getting Started)

继续在Step1文件夹下进行编辑。从TODO 4TODO 6
首先,编辑文件tutorial.cxx,增加要求C++11标准的特性。然后,更新CMakelists.txt以要求C++11。

练习答案(Solution)

在文件tutorial.cxx中,使用语句std::stod替换atof,以要求使用C++11标准的特性。

  • TODO 4,在文件tutorial.cxx中:
    const double inputValue = std::stod(argv[1]);

  • TODO 5,删除#include <cstdlib>

在CMake中使用CMAKE_CXX_STANDARD变量来指定使用的C++标准。本教程中,在文件CMakeLists.txt中,设置CMAKE_CXX_STANDARD变量值为11,变量CMAKE_CXX_STANDARD_REQUIRED值为TrueCMAKE_CXX_STANDARD命令要放在add_executable()命令之前。

  • TODO 6,在文件CMakeLists.tx中:
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

生成运行(Build and Run)

由于已经创建了生成目录且以在练习1中运行了CMake,所以可以跳过生成步骤:

cd Step1_build
cmake --build .

测试新生成的Tutorial.exe

Tutorial 4294967296
Tutorial 10
Tutorial

练习3:添加版本号和配置头文件(Exercise 3 - Adding a Version Number and Configured Header File)

有时需要在源代码中使用在CMakelists.txt文件中定义的变量。本练习中,我们打印输出项目版本。

使用配置头文件(configured header file)。在输入文件中定义变量。这些变量语法特殊,类似@VAR@这样。然后,使用命令configure_file(),复制输入文件到输出文件,并且使用CMakelists.txt文件中VAR的值去替换输入文件中的变量值。

虽然可以直接在源码中编辑版本号,但是使用此特性,可以创建单一的版本号源避免存在多个副本。

目标(Goal)

定义、输出项目版本号。

资料

需编辑的文件

  • CMakeLists.txt
  • tutorial.cxx

开始

继续编辑文件夹Step1下的文件,从TODO 7TODO 12。在CMakeLists.txt文件中加入项目版本号,且在此文件中,使用命令configure_file()复制输入文件到输出文件,并且替换输入文件中的变量值。

接下来,创建文件TutorialConfig.h.in(在文件夹Step1下已经有此文件),使用命令configure_file()传入的变量来定义版本号。

最后,更新tutorial.cxx文件以打印出版本号。

练习答案

首先,在CMakeLists.txt文件中,修改命令project()以定义项目名和项目版本号。CMake调用命令project()时,会在后台定义变量Tutorial_VERSION_MAJORTutorial_VERSION_MINOR并赋值。

  • TODO 7,在文件CMakeLists.txt中:
    project(Tutorial VERSION 1.0)

接下来使用configure_file()命令,以把指定的CMake变量值替换输入文件中的值:

  • TODO 8,在文件CMakeLists.txt中:
    configure_file(TutorialConfig.h.in TutorialConfig.h)

配置文件在项目二进制文件目录下写入,因此必须把此目录加入到包含头文件的搜索路径列表中。

注意:此教程中,我们不加区别地使用项目生成目录和项目二进制文件目录,它们指代的路径是一样的,不是指代的bin/目录。

使用命令target_include_directories(),指定可执行文件(executable target)在何处搜索头文件。

  • TODO 9,在文件CMakeLists.txt中:
target_include_directories(Tutorial PUBLIC "${PROJECT_BINARY_DIR}")

TutorialConfig.h.in作为输入来配置头文件,当CMakeLists.txt中的命令configure_file()调用时,文件TutorialConfig.h.中的变量@Tutorial_VERSION_MAJOR@@Tutorial_VERSION_MINOR@的值会被替换成项目中对应的版本号。

  • TODO 10,在文件TutorialConfig.h.in中:
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@

接下来,修改文件tutorial.cxx,来包含配置好的头文件TutorialConfig.h

  • TODO 11,在文件tutorial.cxx中:
#include "TutorialConfig.h"

最后,更新tutorial.cxx,打印程序名和版本号:

  • TODO 12,在文件tutorial.cxx中:
  if (argc < 2) {
    // report version
    std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
              << Tutorial_VERSION_MINOR << std::endl;
    std::cout << "Usage: " << argv[0] << " number" << std::endl;
    return 1;
  }

生成运行

cd Step1_build
cmake --build .

当执行程序不带数字参数时,可打印出版本号:

PS D:\VisualStudioProjects\cmake-3.26.0-rc6-tutorial-source\Step1_build\Debug> .\Tutorial.exe
D:\VisualStudioProjects\cmake-3.26.0-rc6-tutorial-source\Step1_build\Debug\Tutorial.exeVersion 1.0
Usage: D:\VisualStudioProjects\cmake-3.26.0-rc6-tutorial-source\Step1_build\Debug\Tutorial.exe number
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,478评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,825评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,482评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,726评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,633评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,018评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,168评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,320评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,264评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,288评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,995评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,587评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,909评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,284评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,862评论 2 339

推荐阅读更多精彩内容