2、第一个CMake项目:创建CMakeLists.txt、cmake_minimum_required、project命令、add_executable、编译与运行第一个程序
好,咱们正式开始动手了。
上一章我们聊了CMake是什么、能干什么。这一章,直接上手写代码。你想想看,学任何工具,最爽的不就是看到“Hello World”跑起来的那一刻吗?
我个人习惯,学一个新东西,先搭一个最小的可运行项目。哪怕它再简单,只要能跑通,后面的信心就来了。CMake也不例外。
2.1 项目结构:先搭个架子
我们先创建一个文件夹,名字就叫 hello_cmake。里面放两个文件:
main.cpp—— 我们的C++源代码CMakeLists.txt—— CMake的构建脚本
就这么简单。别一上来就搞什么src、include、lib的目录结构,那是后面的事。第一个项目,越简单越好。
main.cpp 的内容:
#include <iostream>
int main() {
std::cout << "Hello, CMake!" << std::endl;
return 0;
}
这段代码没什么好解释的,就是打印一句话。重点是旁边的 CMakeLists.txt。
2.2 CMakeLists.txt:项目的“总指挥”
CMakeLists.txt 是CMake的核心。CMake读的就是这个文件。它告诉CMake:你的项目叫什么、用什么语言、最低支持哪个版本的CMake、要生成什么目标。
我们的第一个CMakeLists.txt长这样:
cmake_minimum_required(VERSION 3.10)
project(HelloCMake)
add_executable(hello main.cpp)
三行,搞定。咱们一行一行拆开看。
2.2.1 cmake_minimum_required:定个“最低门槛”
这一行指定了CMake的最低版本。比如 VERSION 3.10,意思是:如果用户机器上的CMake版本低于3.10,就报错退出。
为什么要加这个?
因为不同版本的CMake,语法和功能有差异。有些新特性在老版本里不支持。如果不指定,别人用老版本CMake跑你的项目,可能编译到一半报一些莫名其妙的错误。
VERSION 3.30,那用户必须装3.30以上才能用。我建议写一个你实际测试过的、比较通用的版本。比如3.10或3.16,大多数Linux发行版都自带。
我曾经在一个项目里,同事把版本号写成了3.20,结果客户的CI环境里装的是3.15,整个构建流程直接卡住。后来我改成了3.10,问题解决。嗯,这里要注意,版本号不是越高越好,兼容性才是第一位的。
2.2.2 project:给项目起个名
project(HelloCMake) 这一行,定义了项目名称。这个名字会影响到后面生成的一些变量,比如 PROJECT_NAME、PROJECT_SOURCE_DIR 等。
语法很简单:
project(<项目名> [语言列表])
比如你想指定项目用C++和C:
project(HelloCMake CXX C)
如果不写语言列表,默认就是C和C++都支持。我个人习惯,纯C++项目就写 CXX,明确一点。
2.2.3 add_executable:生成可执行文件
这一行是核心:
add_executable(hello main.cpp)
它的意思是:用 main.cpp 这个源文件,编译生成一个叫 hello 的可执行文件。
语法:
add_executable(<目标名> <源文件列表>)
目标名就是最终生成的可执行文件的名字。在Windows上会生成 hello.exe,在Linux/macOS上生成 hello。
如果有多个源文件,可以这样写:
add_executable(hello main.cpp utils.cpp helper.cpp)
当然,项目大了之后,我们不会这样一个个列文件,而是用 file(GLOB) 或 aux_source_directory 来自动收集。但第一个项目,手动列出来最清晰。
2.3 编译与运行:见证奇迹
好,文件都准备好了。现在我们来编译。
CMake的构建分为两步:
- 配置(Configure):CMake读取CMakeLists.txt,生成构建系统文件(比如Makefile或Visual Studio工程)。
- 构建(Build):用生成的构建系统去编译代码。
我们推荐使用“外部构建”(out-of-source build),也就是在项目根目录外单独建一个 build 文件夹,所有生成的文件都放在里面。这样不会污染源代码目录。
操作步骤:
# 1. 进入项目根目录
cd hello_cmake
# 2. 创建build目录并进入
mkdir build && cd build
# 3. 配置:告诉CMake源码在哪
cmake ..
# 4. 构建:编译代码
cmake --build .
# 5. 运行
./hello
如果你看到终端输出:
Hello, CMake!
恭喜你,第一个CMake项目跑通了!
cmake -G 指定生成器。比如 cmake -G "Visual Studio 17 2022" ..。但初学者先用默认的就好。
2.4 知识体系图:这一章我们学了什么
下面这张图,帮你理清这一章的核心逻辑:
2.5 避坑指南:我踩过的几个坑
第一个项目虽然简单,但有些细节不注意,还是会卡住。我分享几个亲身经历:
- 路径问题:
cmake ..中的..是相对于当前目录(build)的上级目录。如果你在项目根目录直接执行cmake .,那就是内部构建,生成的文件会混在源码里。我个人强烈建议用外部构建。 - 大小写敏感:CMake命令不区分大小写,但变量名区分。比如
CMAKE_CXX_STANDARD和cmake_cxx_standard不是一回事。建议命令用小写,变量用大写。 - 源文件路径:
add_executable里的源文件路径,是相对于CMakeLists.txt所在目录的。如果你把源文件放在src子目录,就要写成add_executable(hello src/main.cpp)。 - 重新配置:如果你修改了CMakeLists.txt,记得重新执行
cmake ..来重新配置。只执行cmake --build .不会重新读取CMakeLists.txt。
核心要点回顾:
cmake_minimum_required指定CMake最低版本,保证兼容性。project定义项目名称,影响后续变量。add_executable用源文件生成可执行文件。- 使用外部构建(build目录),保持源码干净。
- 两步走:先
cmake ..配置,再cmake --build .构建。
好了,第一个项目就到这里。你现在可以自己动手试试,把 main.cpp 里的输出改一改,重新编译运行,感受一下CMake的工作流。说白了,就是这三行命令、三个CMake指令,后面所有复杂的东西,都是在这个基础上长出来的。
公众号:蓝海资料掘金营,微信 deep3321