第一个CMake项目:CMakeLists.txt结构,project()与cmake_minimum_required(),add_executable()

说实话,我见过太多新手一上来就对着CMakeLists.txt发懵。这玩意儿看起来不就是个文本文件吗?怎么那么多讲究?

嗯,它确实就是个文本文件。但它是整个CMake构建系统的灵魂。今天我们就从零开始,把这个文件拆开揉碎了讲清楚。

CMakeLists.txt:项目的"总指挥"

每个CMake项目,根目录下必须有一个CMakeLists.txt。这是硬性规定,没得商量。我刚开始用CMake时,就犯过这种低级错误——把文件命名成cmakelists.txt(少了个大写字母),结果折腾了半小时才发现。

这个文件说白了就是告诉CMake三件事:

  • 你的项目叫什么名字
  • 需要什么版本的CMake
  • 要编译哪些源文件

就这么简单。别把它想得太复杂。

cmake_minimum_required():版本红线

先看这个函数:

cmake_minimum_required(VERSION 3.10)

它的意思很直白——如果用户机器上的CMake版本低于3.10,直接报错退出。为什么要这么干?

我在项目中遇到过一件事:有个同事用了3.5版本的CMake,结果我们项目里用了3.10才支持的IN_LIST操作符。编译到一半报错,排查了整整一个下午。从那以后,我每个项目第一行必写这个。

注意:cmake_minimum_required() 必须写在 project() 之前。这是CMake的语法规定,顺序错了会报错。

版本号怎么选?我个人习惯看项目里用了哪些CMake特性。如果只是简单编译,3.10就够用。如果要用到FetchContenttarget_precompile_headers这些高级功能,至少得3.14以上。

project():给项目一个身份

接下来是project():

project(MyProject VERSION 1.0.0 LANGUAGES CXX)

这个函数干了三件事:

  • 定义了项目名称——MyProject
  • 设置了版本号——1.0.0
  • 指定了编程语言——CXX(就是C++)

你可能会问:版本号有什么用?说实话,小项目确实用不上。但一旦项目大了,需要生成安装包、做版本管理时,PROJECT_VERSION这个变量就派上用场了。我维护的一个开源库,就是靠这个变量自动生成头文件里的版本宏,省了不少事。

小技巧:LANGUAGES参数可以省略。默认会检测C和CXX。如果只写C++,就显式指定CXX,能加快CMake的配置速度。

add_executable():生成可执行文件

最后是核心函数:

add_executable(my_app main.cpp utils.cpp)

第一个参数是目标名称,也就是生成的可执行文件名(Windows下会变成my_app.exe)。后面的参数是源文件列表。

这里有个坑:我曾经把源文件路径写错了,结果CMake没报错,但编译时链接失败。排查了半天才发现是路径问题。所以建议用${CMAKE_CURRENT_SOURCE_DIR}来拼接绝对路径,或者直接用相对路径(相对于CMakeLists.txt所在目录)。

源文件多了怎么办?可以用变量:

set(SOURCES
    main.cpp
    utils.cpp
    network.cpp
    database.cpp
)

add_executable(my_app ${SOURCES})

这样清晰多了。我一般把源文件按模块分组,用不同的变量名管理。

完整的CMakeLists.txt长什么样?

把上面三个拼起来,就是一个最小可用的CMake项目:

cmake_minimum_required(VERSION 3.10)

project(MyFirstProject VERSION 1.0.0 LANGUAGES CXX)

set(SOURCES
    main.cpp
    utils.cpp
)

add_executable(my_app ${SOURCES})

就这几行。你把它放到项目根目录,然后执行:

mkdir build
cd build
cmake ..
make

就能编译出my_app可执行文件。是不是很简单?

本章知识体系

下面这张图帮你理清CMakeLists.txt的核心结构:

CMakeLists.txt 核心结构 CMakeLists.txt cmake_minimum_required 设置最低CMake版本 project 定义项目名称/版本/语言 add_executable 生成可执行文件 VERSION 3.10 MyProject V1.0 CXX my_app main.cpp 三个函数必须按顺序书写:cmake_minimum_required → project → add_executable

避坑指南

最后分享几个我踩过的坑:

  • 文件名大小写:CMakeLists.txt,C和L必须大写。我见过有人写成cmakelists.txt,结果CMake根本找不到。
  • 路径中的空格:项目路径里不要有空格。虽然CMake能处理,但有些编译器会报错。我吃过这个亏,后来所有项目目录都用下划线。
  • 源文件遗漏:add_executable里漏写源文件,编译能过但链接会报"undefined reference"。排查方法:先检查源文件列表是否完整。
  • 版本号写错:cmake_minimum_required(VERSION 3.10) 中间的VERSION不能省略。我见过有人直接写cmake_minimum_required(3.10),结果报错。
核心要点:一个CMakeLists.txt只要包含cmake_minimum_required()、project()、add_executable()这三个函数,就能完成最基本的C++项目构建。先把这三板斧练熟,后面再学高级特性。

好了,这就是第一个CMake项目的全部内容。你可以在自己的机器上试试,写一个最简单的"Hello World"程序,用CMake编译运行。相信我,当你看到终端里输出"Hello World"的那一刻,会很有成就感。


公众号:蓝海资料掘金营,微信deep3321