和Ai一起学习CMake
现在人工智能爆火,ChatGPT、new bing等层出不穷。我们借助Ai来学习一下CMake。下面是我与Ai的问答,这个学习主要是通过Ai来学习,但是防止Ai乱说话,我会结合自身的知识和实际操作给出相应的补充。
我的环境如下:
- 操作系统:Windows11
- CMake版本:3.25
- 默认生成器:Visual Studio 17 2022
- 默认编译器:MSVC
- 终端:Powershell
- 编辑器:nvim、notepad–、vscode
如果你的环境和我的不一样,那么出现的问题可能就会不一样,要学会自己修改。关于编辑器,前期建议不要使用vscode,因为vscode会有提示,前期应该是打基础的时候,自己手动打命令这样才能熟练,当你开始觉得已经熟悉了CMake的命令语法,就可以使用vscode,这样可以提高效率,每个人的掌握的速度不一样,因人而异。
CMake的介绍
CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。CMake能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。CMake不直接编译软件,而是结合原生构建系统来构建软件。
CMake的产生可以追溯到20世纪90年代,当时开发人员使用的构建工具很有限,需要为不同的平台编写不同的Makefile,这极大地增加了软件开发的难度和复杂性。为了解决这个问题,Bill Hoffman于2000年创建了CMake项目,并开源发布,以便于更多的人使用和贡献。
CMake使用平台无关的配置文件来控制软件编译过程,并生成可在您选择的编译器环境中使用项目文件,比如可以生成vs项目文件或者makefile。
下载与安装CMake
下载直接到CMake官网下载即可,就不过多细说。当下载完CMake之后会得到一个压缩包,我们安装CMake其实就是去解压这个压缩包。解压之后可以得到下面的内容:
其中D:\mySoft\cmake
是我的cmake的安装根目录,bin
目录中就是包含了CMake的cmake.exe
等可执行文件,然后也包含了带图形界面的cmake工具。doc
目录就是存放文档的,man
就是存放手册的。然后还有一个share
文件夹,里面也存放了一些东西。我们无需关心除了bin
以外的文件夹,这些文件夹就相当于对CMake的一些相关的概念和使用手册一样。我们主要关心的是bin
目录。点开bin
目录可以看到下面的内容:
其中,cmake.exe
就是我们经常会使用到的cmake
命令,它是重头戏。然后还有一个cmake-gui.exe
,这个就是图形化的cmake,它的特点就是直观和易用,但是并不是我们学习CMake的主要部分。然后还有一个ctest.exe
这个是用来测试的,然后还有另外的两个可执行程序。我们只使用CMake的命令行部分,也只学习构建编译的部分,其他的相关内容可以去CMake的官网学习。
配置CMake环境
前面知识介绍了CMake的一些组成。因为CMake相当于是Windows的第三方软件,Windows操作系统并不认识CMake,这就意味着,我们不可以全局地访问CMake,也就不能直接使用CMake,所以我们需要把CMake配置到环境变量中。
我以我当前CMake的安装路径为例。我把D:\mySoft\cmake\bin
配置到系统环境变量path
中。具体操作如下:
win键->输入“环境”->打开->环境变量->系统变量->path->新建->粘贴(D:\mySoft\cmake\bin
)->一路点击确定关掉所有窗口。
这个过程很类似其他软件的环境变量的配置,例如Java的JAVA_HOME
和CLASSPATH
的配置,还有像MinGW
的配置,还有MySQL
的配置。练多了就会了,然后有时候可能会出现冲突的,则需要点击上面最后一张图中的上移
或下移
操作即可。
配置好了之后在终端输入cmake --version
查看一下cmake的版本号,如果出现下面的输出则说明CMake的配置已经完成了,如果不是,则是没有配置好,请重新检查一下步骤。
PS D:\> cmake --version
cmake version 3.25.0-rc1
CMake suite maintained and supported by Kitware (kitware.com/cmake).
因为版本不同而输出的结果不一样那也无伤大雅,只要不少说找不到命令就行。
我与Ai的问答
在学习CMake之前,我们先制定一下学习计划,以便我们是有目标地学习,而不是盲目的学习。毕竟有目标的学习我们会知道要学什么,我们也会学比较实用的,而不是学了不用。
学习计划
结合最新的人工智能来一起学习是最快的,效率翻倍。但是需要有经验的人来引导Ai,要不然会被Ai带入死胡同。所以由我来带领大家一起来和Ai学习CMake,我的作用就是引导和纠正。我这里使用的Ai是new bing.
我:
我需要的是学习CMake的学习计划,请你帮我制定一个CMake的学习计划。
new bing:
好的,以下是一个简单的CMake学习计划:
- 学习CMake的基本语法和命令,包括CMakeLists.txt文件的编写方法。
- 学习如何使用CMake编译一个简单的程序,例如Hello World。
- 学习如何使用CMake编译一个包含多个源文件的程序。
- 学习如何使用CMake编译一个包含头文件和库文件的程序。
- 学习如何使用CMake编译一个跨平台的程序。
- 学习如何使用CMake安装一个项目。
- 学习如何使用CMake编译一个包含测试的程序。
你可以参考以下链接来学习CMake:
希望这些信息能帮到你!
源: 与必应的对话, 2023/4/30
(1) cmake学习总结(一) - 知乎 - 知乎专栏. https://zhuanlan.zhihu.com/p/150869814.
(2) CMake简明教程(中文版) - 知乎 - 知乎专栏. https://zhuanlan.zhihu.com/p/492932151.
(3) cmake使用详细教程(日常使用这一篇就足够了) - CSDN博客. https://blog.csdn.net/iuu77/article/details/129229361.
补充:上面是new bing给出的回答。它告诉了我们CMake的学习计划,我们等下将结合它的学习计划对点学习CMake。并且new bing给出了学习CMake的参考链接,这些链接都是前人写好了的,可以拿来参考。最后一块是new bing的搜索链接。
学习计划的第一点:CMake的基本语法和命令
先来了解一下CMake的一些基本的语法和命令。CMake的语法规则是从上往下执行的。特别是后面学习到的命令是一定要有顺序要求的,例如CMake命令中带target
命令要放到带add
命令的后面,这应该很明显。因为只有先生成了target
才能对target
做其他操作,即先增加目标,然后才对目标做其他操作。如果想在cmake构建项目的时候打印输出一些信息就可以使用message
命令(后面会提到用法)。set
命令一般只有两个参数,其含义就是把后面的值赋值给前面的值。前面的值一般都是CMake内置的变量,或者是我们自己自定义的变量,所以set
命令更像是我们学习编程语言中的赋值操作一样,只是这个set
是CMake的语法而已。
接下来有请new bing.
我:
好,那么开始学习CMake。先从你给的计划中的第一个开始吧。CMake的基本语法和命令有哪些,写CMake时有什么要求,文件应该怎么样命名,CMake的源文件和C++的源文件的位置关系是什么,请你使用精炼的语言回答。
new bing:
CMake的基本语法和命令十分简单,具有以下要点:
- CMake由指令(command)和注释组成,空白、换行、tab仅作为语素分隔符。
- 注释以井号——“#”开头,至行尾结束。
- 指令后加小括号,用于传入参数,指令按照从上至下顺序进行解析。
- CMakeLists.txt文件是CMake的构建脚本,用于描述如何构建一个项目。
- CMakeLists.txt文件应该放在项目的根目录下。
- CMakeLists.txt文件中应该包含project指令,用于定义项目名称和版本号。
- CMakeLists.txt文件中应该包含add_executable或add_library指令,用于定义可执行文件或库文件。
- CMakeLists.txt文件中应该包含target_link_libraries指令,用于链接库文件。
希望这些信息能帮到你!
补充:
- CMake中没有多行注释,但是可以使用多个单行注释来实现多行注释的效果,CMake的注释是以
#
号开头。 - CMake要求工程主目录和所有存放源代码子目录下都要编写 CMakeLists.txt 文件,源文件必须命名为
CMakeLists.txt
。 target_link_libraries
命令应该放在add_executable
之后,用于指明连接进来的库。官方推荐使用这个接口,而不推荐使用link_libraries
,因为link_libraries
需要放到add_executable
之前。
学习计划二:CMake的简单模板
上一小节只是了解了CMake的一些基本的命令和基本的语法规则,那么从这一小节开始,我们就开始使用CMake去构建我们的C++项目,那么我们先来一个最简单的CMake的模板。就是基本写CMake都要有的命令,就类似学C语言是的main
函数一样。
我:
请你给出一个简单的
CMakeLists.txt
的模板。new bing:
下面是一个简单的
CMakeLists.txt
模板,你可以根据自己的需要进行修改:# 设置CMake的最小版本 cmake_minimum_required(VERSION 3.0) # 设置项目的名称,这里的名称是 my_project project(my_project) # 设置C++的标准版本为C++11 set(CMAKE_CXX_STANDARD 11) # 生成可执行文件my_project.exe 其中main.cpp是依赖的C++源文件 add_executable(my_project main.cpp)
希望这个回答能够帮到你!
我们利用这个模板来简单创建一个项目。
在文件加demo
下有一个简单的main.cpp
文件,内容如下:
#include <iostream>
using namespace std;
int main() {
cout << "Hello, CMake" << endl;
return 0;
}
创建一个CMakeLists.txt
文件,内容如下:
# 设置CMake的最小版本
cmake_minimum_required(VERSION 3.10)
# 设置项目的名称,这里的名称是 my_project
project(demo)
# 设置C++的标准版本为C++11
set(CMAKE_CXX_STANDARD 11)
# 生成可执行文件my_project.exe 其中main.cpp是依赖的C++源文件
add_executable(demo main.cpp)
查看当前项目目录:
PS D:\myCoding\Terminal\C++\demo> ls
Directory: D:\myCoding\Terminal\C++\demo
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2023/4/30 星期日 15:30 313 CMakeLists.txt
-a--- 2023/4/30 星期日 15:29 106 main.cpp
我这里是Windows
平台下的PowerShell
。
构建项目
然后现在我们去构建项目。问一下new bing.
我:
我现在在demo文件夹下已经创建并编辑好了
main.cpp
、CMakeLists.txt
,请问我应该怎么去构建这个项目。new bing:
你可以使用以下命令来构建你的项目:
mkdir build cd build cmake .. make
其中,
mkdir build
用于创建一个名为build
的文件夹,cd build
用于进入这个文件夹,cmake ..
用于在这个文件夹下生成Makefile,make
用于编译并生成可执行文件。希望这个回答能够帮到你!
源: 与必应的对话, 2023/4/30
(1) CMake. https://cmake.org/.
(2) Running CMake | CMake. https://cmake.org/runningcmake/.
(3) CMake Tutorial | CMake. https://cmake.org/cmake-tutorial/.
那么我们现在就使用new bing提示我们的答案去构建项目。
当我已经创建好一个build
文件夹之后,并进入了文件夹build
,然后执行cmake ..
,终端输出的结果如下:
PS D:\myCoding\Terminal\C++\demo\build> cmake ..
-- Building for: Visual Studio 17 2022
-- Selecting Windows SDK version 10.0.22000.0 to target Windows 10.0.22621.
-- The C compiler identification is MSVC 19.35.32217.1
-- The CXX compiler identification is MSVC 19.35.32217.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/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: C:/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
-- Generating done
-- Build files have been written to: D:/myCoding/Terminal/C++/demo/build
从结果中可以看到,默认使用的生成器是Visual Studio 17 2022
。因为我这里是Windows
平台。但是new bing给我的cmake命令确实基于Mingw
的,自然不可以使用make
命令(包括mingw32-make
也不行)。那我就继续问new bing。
我:
如果我采用的生成器是Windows平台下的
Visual Studio 17 2022
,请问我应该怎么通过cmake来构建并运行C++项目,我在PowerShell终端,我不使用IDE。new bing:
你好,你可以在PowerShell终端中使用cmake构建C++项目。你需要先安装cmake和Visual Studio,然后在PowerShell中运行以下命令:
mkdir build cd build cmake .. cmake --build .
这将创建一个名为“build”的文件夹,然后将您的源代码放入其中。接下来,您需要在PowerShell中导航到该文件夹并运行上述命令。这将生成您的可执行文件。
补充:这里的cmake --build .
命令是cmake提供的通用的命令,不管使用的是什么生成器都是可以的,而如果使用make
命令那必须采用的生成器是GCC
的make
才行,如是在Windows平台下则使用对应的mingw32-make
命令,但是这样做的话就不够通用,因为如果使用不同的生成器来构建项目就要单独去记住对应的生成的命令,太麻烦了,所以使用cmake提供的通用的命令即可。
我:
可不可以解释一下
cmake --build .
的意思。new bing:
cmake --build .
是CMake的一个命令,用于构建项目。它会在当前目录下查找CMakeLists.txt文件,然后根据其中的指令生成构建系统。这个命令会自动调用构建系统的生成器,如make或ninja等,来编译和链接项目。如果你想指定编译器、编译选项、链接选项等,可以在cmake --build .
后面加上相应的参数。例如,如果你想使用Release模式编译项目,可以使用cmake --build . --config Release
命令。
那我们就采用cmake --build .
命令去生成项目的可执行文件。
PS D:\myCoding\Terminal\C++\demo\build> cmake --build .
MSBuild version 17.5.1+f6fdcf537 for .NET Framework
Checking Build System
Building Custom Rule D:/myCoding/Terminal/C++/demo/CMakeLists.txt
main.cpp
demo.vcxproj -> D:\myCoding\Terminal\C++\demo\build\Debug\demo.exe
Building Custom Rule D:/myCoding/Terminal/C++/demo/CMakeLists.txt
那么从终端的打印信息可以看到,确实生成了对应的demo.exe
文件。我们进入对应的目录去运行它。
PS D:\myCoding\Terminal\C++\demo\build> cd D:\myCoding\Terminal\C++\demo\build\Debug
PS D:\myCoding\Terminal\C++\demo\build\Debug> .\demo.exe
Hello, CMake
结果成功输出了Hello, CMake
.
切换生成器
我们上面构建项目的时候采用的是Windows平台下默认的Visual Studio
,那可不可以切换成Mingw
的生成器呢。
我:
我当前的操作系统是Windows,它默认使用的生成器是
Visual Studio
,如果我想切换到Mingw
,那么我的cmake命令应该如何写?new bing:
如果你想在Windows上使用Mingw作为编译器,可以在运行
cmake
命令时指定生成器为MinGW Makefiles
。例如,你可以使用以下命令来生成Makefile并编译项目:cmake -G "MinGW Makefiles" -DCMAKE_C_COMPILER=gcc.exe -DCMAKE_CXX_COMPILER=g++.exe .. cmake --build .
其中,
-DCMAKE_C_COMPILER=gcc.exe
和-DCMAKE_CXX_COMPILER=g++.exe
分别指定了C和C++编译器为gcc和g++。如果你的Mingw安装在非默认路径下,还需要指定Mingw的安装路径。
其中,如果你不知道-G
后面的字符串应该写什么的话,你可以直接输入cmake -G
回车,这样就可以看到你的操作系统支持的生成器,并且知道它们的名字和使用说明。
例如我的操作系统支持的生成器如下所示:
PS D:\> cmake -G
CMake Error: No generator specified for -G
Generators
* Visual Studio 17 2022 = Generates Visual Studio 2022 project files.
Use -A option to specify architecture.
Visual Studio 16 2019 = Generates Visual Studio 2019 project files.
Use -A option to specify architecture.
Visual Studio 15 2017 [arch] = Generates Visual Studio 2017 project files.
Optional [arch] can be "Win64" or "ARM".
Visual Studio 14 2015 [arch] = Generates Visual Studio 2015 project files.
Optional [arch] can be "Win64" or "ARM".
Visual Studio 12 2013 [arch] = Generates Visual Studio 2013 project files.
Optional [arch] can be "Win64" or "ARM".
Visual Studio 11 2012 [arch] = Deprecated. Generates Visual Studio 2012
project files. Optional [arch] can be
"Win64" or "ARM".
Visual Studio 9 2008 [arch] = Generates Visual Studio 2008 project files.
Optional [arch] can be "Win64" or "IA64".
Borland Makefiles = Generates Borland makefiles.
NMake Makefiles = Generates NMake makefiles.
NMake Makefiles JOM = Generates JOM makefiles.
MSYS Makefiles = Generates MSYS makefiles.
MinGW Makefiles = Generates a make file for use with
mingw32-make.
Green Hills MULTI = Generates Green Hills MULTI files
(experimental, work-in-progress).
Unix Makefiles = Generates standard UNIX makefiles.
Ninja = Generates build.ninja files.
Ninja Multi-Config = Generates build-<Config>.ninja files.
Watcom WMake = Generates Watcom WMake makefiles.
CodeBlocks - MinGW Makefiles = Generates CodeBlocks project files.
CodeBlocks - NMake Makefiles = Generates CodeBlocks project files.
CodeBlocks - NMake Makefiles JOM
= Generates CodeBlocks project files.
CodeBlocks - Ninja = Generates CodeBlocks project files.
CodeBlocks - Unix Makefiles = Generates CodeBlocks project files.
CodeLite - MinGW Makefiles = Generates CodeLite project files.
CodeLite - NMake Makefiles = Generates CodeLite project files.
CodeLite - Ninja = Generates CodeLite project files.
CodeLite - Unix Makefiles = Generates CodeLite project files.
Eclipse CDT4 - NMake Makefiles
= Generates Eclipse CDT 4.0 project files.
Eclipse CDT4 - MinGW Makefiles
= Generates Eclipse CDT 4.0 project files.
Eclipse CDT4 - Ninja = Generates Eclipse CDT 4.0 project files.
Eclipse CDT4 - Unix Makefiles= Generates Eclipse CDT 4.0 project files.
Kate - MinGW Makefiles = Generates Kate project files.
Kate - NMake Makefiles = Generates Kate project files.
Kate - Ninja = Generates Kate project files.
Kate - Unix Makefiles = Generates Kate project files.
Sublime Text 2 - MinGW Makefiles
= Generates Sublime Text 2 project files.
Sublime Text 2 - NMake Makefiles
= Generates Sublime Text 2 project files.
Sublime Text 2 - Ninja = Generates Sublime Text 2 project files.
Sublime Text 2 - Unix Makefiles
= Generates Sublime Text 2 project files.
其中生成器前面带有*
号的表示默认的生成器,例如我这里默认的生成器是Visual Studio 17 2022
.
那么我的电脑上是装有MinGW
的,那么我切换到MinGW来试试看。我们把demo
文件夹复制一份,然后清空build
目录下的所有内容。
PS D:\myCoding\Terminal\C++> cp demo/* demo2/
PS D:\myCoding\Terminal\C++> cd .\demo2\
PS D:\myCoding\Terminal\C++\demo2> rm build/*
PS D:\myCoding\Terminal\C++