2、第一个CMake项目:创建CMakeLists.txt、cmake_minimum_required、project命令、add_executable、构建与运行
好,咱们直接动手。别管那些花里胡哨的理论,先把第一个CMake项目跑起来。你想想看,学任何东西,第一件事不就是让它「动」起来吗?
我个人习惯,每学一个新工具,先写一个能打印"Hello World"的程序。CMake也不例外。咱们的目标很简单:写一个C++源文件,然后用CMake把它编译成可执行文件。
2.1 项目结构:先搭个架子
首先,你得有个文件夹。我建议你新建一个目录,比如叫 hello_cmake。里面放两个文件:
main.cpp—— 你的C++源代码CMakeLists.txt—— CMake的构建脚本
就这么简单。别搞复杂了,刚开始越简单越好。
main.cpp 的内容,咱们就用最经典的:
#include <iostream>
int main() {
std::cout << "Hello, CMake!" << std::endl;
return 0;
}
嗯,这里要注意:文件名别写错了。我见过有同事把 main.cpp 写成 main.CPP,结果在Linux上编译报错,折腾了半天。大小写敏感,切记。
2.2 CMakeLists.txt:核心中的核心
现在,咱们来写 CMakeLists.txt。这是CMake的灵魂文件。说白了,CMake就是靠这个文件来知道「你要编译什么」、「用什么编译器」、「输出什么」。咱们先写一个最精简的版本:
cmake_minimum_required(VERSION 3.10)
project(HelloCMake)
add_executable(hello main.cpp)
就三行。别嫌少,这三行够用了。咱们一行一行拆开看。
2.2.1 cmake_minimum_required:版本声明
第一行 cmake_minimum_required(VERSION 3.10),意思是「这个项目至少需要CMake 3.10版本」。为什么要有这行?
我在项目中遇到过,有人用了一个很新的CMake特性,比如 target_sources 的某些高级用法,结果同事的机器上CMake版本太老,直接报错。所以,这行就是给你的项目设一个「最低门槛」。我个人习惯,一般设到3.10或3.16,这两个版本比较稳定,覆盖了绝大多数常用功能。
2.2.2 project:项目名称
第二行 project(HelloCMake),就是给你的项目起个名字。这个名字会影响到后面生成的构建目录名、库文件的前缀等等。你可以随便起,但最好有意义。
这里有个小细节:project 命令还可以指定语言,比如 project(HelloCMake CXX) 表示只用C++。不过咱们先不搞那么复杂,默认就好。
2.2.3 add_executable:生成可执行文件
第三行 add_executable(hello main.cpp),意思是「我要生成一个叫 hello 的可执行文件,源文件是 main.cpp」。
你想想看,这就像告诉CMake:「嘿,帮我把这些源文件编译成一个程序,名字就叫hello。」如果有多个源文件,你可以继续往后加,比如 add_executable(hello main.cpp utils.cpp)。不过咱们现在只有一个文件,先这样。
test,那在终端里执行 ./test 时,可能会跟系统的 test 命令混淆。我一般用项目名的小写,比如 hello。
2.3 构建与运行:见证奇迹的时刻
好,文件都写好了。现在咱们来构建。打开终端,进入 hello_cmake 目录,执行以下命令:
mkdir build
cd build
cmake ..
make
或者,如果你用的是Ninja(一个更快的构建工具):
mkdir build
cd build
cmake .. -G Ninja
ninja
我个人推荐用Ninja,编译速度快很多。尤其是大项目,能省不少时间。
执行完 cmake .. 后,你会看到类似这样的输出:
-- The C compiler identification is GNU 11.2.0
-- The CXX compiler identification is GNU 11.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc - works
-- Detecting C compile features
-- Detecting C compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /path/to/hello_cmake/build
看到「Configuring done」和「Generating done」就说明配置成功了。然后 make 或 ninja 会编译你的代码,生成可执行文件。
最后,运行它:
./hello
你应该会看到:
Hello, CMake!
嗯,到这里,你的第一个CMake项目就跑起来了。是不是很简单?
2.4 避坑指南:我踩过的几个坑
我曾经在第一次用CMake时,犯过几个低级错误。分享出来,你别再踩了。
- 忘记创建build目录:直接在源码目录里执行
cmake .和make。这样会把编译产生的临时文件(.o文件、Makefile等)混在源码里,非常乱。记住:永远在build目录里构建。 - CMakeLists.txt 文件名写错:注意大小写。CMake只认
CMakeLists.txt,写成cmakelists.txt或CMakeLists.TXT都不行。 - 源文件路径写错:在
add_executable里,源文件路径是相对于CMakeLists.txt的。如果你把main.cpp放在src子目录下,那就要写成add_executable(hello src/main.cpp)。
2.5 知识体系图:一图看懂本章核心
下面这张图,帮你理清本章的核心逻辑。从源文件到可执行文件,CMake在中间做了什么。
这张图展示了整个流程:你提供 main.cpp 和 CMakeLists.txt,CMake读取脚本后生成构建系统文件(Makefile或Ninja文件),然后构建系统调用编译器,最终生成可执行文件 hello。说白了,CMake就是帮你省去了手写Makefile的麻烦。
2.6 本章小结
咱们这一章,完成了三件事:
- 创建了项目结构:一个
main.cpp和一个CMakeLists.txt - 写了一个三行的CMake脚本:声明版本、项目名、可执行文件
- 用
cmake ..和make成功构建并运行了程序
嗯,别小看这三行。它们是所有CMake项目的基石。后面无论多复杂的项目,核心逻辑都是这三行:告诉CMake「用什么版本」、「项目叫什么」、「要生成什么」。
我个人建议,你现在就动手敲一遍。别复制粘贴,亲手敲一遍,感受一下。遇到问题很正常,对照着上面的避坑指南检查一下。等你看到终端里打出 Hello, CMake! 的那一刻,你就正式入门了。