详解CMakeLists.txt
在前一篇文章 esp32 初识 cmake 构建工具 中,已经用”hellow world”程序介绍了cmake最基本的用法,今天详细讲解CMakeLists.txt
文件。
CMakeLists.txt
CMakeLists.txt文件是CMake构建工具的核心配置文件。它包含了构建项目所需的一系列指令和参数,CMake会根据这些信息生成相应的构建文件。CMakeLists.txt文件通常位于项目的顶层目录,并可在子目录中包含其他的CMakeLists.txt文件以组织复杂项目的构建过程。
CMakeLists.txt文件包含以下几类指令:
- 项目设置:定义项目名称、版本、目标平台等信息
- 指定源文件和头文件:指定项目中要编译的源文件和头文件
- 添加子目录:将子目录加入构建过程,子目录中可以包含其它的CMakeLists.txt文件
- 设置编译器和链接器选项:例如,指定编译标志、链接库等
- 添加可执行文件和库:指定要生成的可执行文件、静态库或动态库
- 添加依赖和链接库:指定项目需要的外部库和头文件路径
以下是一个简单的C语言项目的CMakeLists.txt文件示例:
1 | # 设置CMake的最低版本要求 |
这个示例中,我们创建了一个基于C语言的名为”MyProject”的项目,设置了C11标准,并添加了一个名为”MyLibrary”的静态库。我们还指定了源文件、头文件以及库的依赖关系。
CMakeLists.txt文件包含以下几种主要语法:
注释:以
#
开头的行表示注释。示例:
1
# 这是一条注释
变量:使用
set()
函数设置变量值,通过${}
使用变量值。示例:
1
2set(SOURCE_FILES main.cpp)
add_executable(my_app ${SOURCE_FILES})条件控制:使用
if()
,elseif()
,else()
和endif()
来进行条件控制。示例:
1
2
3
4
5
6
7
8
9if(WIN32)
set(PLATFORM "Windows")
elseif(APPLE)
set(PLATFORM "macOS")
elseif(UNIX)
set(PLATFORM "Linux")
else()
message(FATAL_ERROR "Unsupported platform")
endif()循环:使用
foreach()
相关语法进行循环。示例:
1
2
3
4set(SOURCE_FILES main.cpp file1.cpp file2.cpp)
foreach(file ${SOURCE_FILES})
message("source file: ${file}")
endforeach()函数和宏:使用
function()
和endfunction()
定义函数,使用macro()
和endmacro()
定义宏。示例:
1
2
3
4
5
6
7
8
9
10
11
12
13function(print_files files)
foreach(file ${files})
message("file: ${file}")
endforeach()
endfunction()
macro(my_macro arg1 arg2)
message("arg1 is ${arg1}, arg2 is ${arg2}")
endmacro()
set(SOURCE_FILES main.cpp file1.cpp file2.cpp)
print_files(${SOURCE_FILES})
my_macro("Hello" "World")
示例
下面用一段示例来综合下上面的语法:
1 | # 设置CMake最低版本要求 |
这是一个基本的CMakeLists.txt文件,主要包含以下内容:
- 设置CMake的最低版本要求为3.0。
- 创建一个名为hello_world的项目。
- 设定C++11标准。
- 检测当前平台类型(Windows、macOS或Linux),并将其存储在变量PLATFORM中。
- 定义一个名为print_files的函数,用于打印文件列表。
- 定义一个名为my_macro的宏,用于打印平台和处理器信息。
- 设置一个文件列表,并使用print_files函数打印出来。
- 调用my_macro宏,打印平台和处理器信息。
- 添加一个名为hello_world的可执行文件,其源代码为main.cpp。
运行结果:
1 | esp-test\hello\build via △ v3.24.3 |
虽然基本语法并不复杂,但组合使用也是变化繁多,再加上还有各种内置变量,实际大型项目中的CMakeLists.txt
可能非常复杂,需要持续认真学习和积累。好在cmake语法相对简单,比较接近自然语言,所以实际读起来还是很容易理解的。