目录
[CMake 是什么?](#CMake 是什么?)
[2.file() 用于 文件和目录操作](#2.file() 用于 文件和目录操作)
[1. 查找文件(最常用)](#1. 查找文件(最常用))
[查找 .cpp 文件](#查找 .cpp 文件)
[2. 读取文件](#2. 读取文件)
[3. 写文件](#3. 写文件)
[4. 复制文件](#4. 复制文件)
[5. 创建目录](#5. 创建目录)
[6. 删除文件](#6. 删除文件)
[7. 获取绝对路径](#7. 获取绝对路径)
CMake 是什么?
CMake、Makefile、make 和 gcc 的关系,可以理解成一个编译工程的流水线:
大型项目不喜欢手写 Makefile。
比如 Linux 内核、Qt、OpenCV 这种项目,有很多,手写 Makefile 很痛苦。
src/
include/
lib/
test/
third_party/
简单说:
- gcc:真正负责"编译代码"的工具
- make:负责"按照规则自动执行编译命令"
- Makefile:告诉 make "应该怎么编译"
- CMake:负责"生成 Makefile(或者其他构建系统文件)"
| 命令 | 作用 |
|---|---|
| cmake_minimum_required | 指定CMake版本 |
| project | 定义工程 |
| set | 定义变量 |
| add_executable | 生成程序 |
| add_library | 生成库 |
| target_include_directories | 添加头文件 |
| target_link_libraries | 链接库 |
| target_compile_options | 添加编译参数 |
| target_compile_definitions | 添加宏 |
| file | 文件操作 |
| find_package | 查找第三方库 |
| add_subdirectory | 添加子目录 |
| install | 安装 |
| if | 条件判断 |
1.set()
创建变量、修改变量、保存路径、保存文件列表、设置 CMake 参数等。
基本格式:
set(变量名 值)
例如:
set(NAME hello)
表示:
创建变量 NAME
值为 hello
使用:
message(${NAME})
2.file() 用于 文件和目录操作
- 查找源码文件
- 创建目录
- 复制文件
- 读取/写入文件
- 获取路径等
基本格式:
file(操作 参数...)
1. 查找文件(最常用)
查找 .cpp 文件
file(
GLOB SRC
*.cpp
)
说明:
GLOB → 匹配文件
SRC → 保存结果的变量
*.cpp → 查找规则
使用:
add_executable(
app
${SRC}
)
递归查找
file(
GLOB_RECURSE SRC
src/*.cpp
)
查找:
src/
├── main.cpp
└── lib/test.cpp
都会找到。
2. 读取文件
file(
READ
version.txt
VERSION
)
message(${VERSION})
作用:读取 version.txt 内容保存到变量 VERSION。
3. 写文件
file(
WRITE
test.txt
"hello cmake"
)
生成:
test.txt
内容:
hello cmake
4. 复制文件
file(
COPY
config/ //源目录
DESTINATION //目的地
${CMAKE_BINARY_DIR}
)
//${CMAKE_BINARY_DIR} 是 CMake 固定定义的内置变量名,不是你自己随便起的。
CMake 在运行时会自动创建这些变量,你可以直接使用:
message(${CMAKE_BINARY_DIR})
CMake 会打印当前构建目录。
作用:
config/
|
v
build目录
5. 创建目录
file(
MAKE_DIRECTORY
build/log
)
相当于:
mkdir -p build/log
6. 删除文件
file(
REMOVE
test.txt
)
7. 获取绝对路径
file(
REAL_PATH
./test.txt
PATH
)
message(${PATH})
常用场景
自动添加源码
file(
GLOB SRC
src/*.cpp
)
/*
file(GLOB_RECURSE SRC_User CONFIGURE_DEPENDS ${USR_DIR}/*.c ${USR_DIR}/*.h)
告诉 CMake:以后如果 GLOB 查找出来的文件列表发生变化,自动重新运行 CMake 配置。
它主要用于解决 file(GLOB) 自动查找源码时,新文件加入的问题。
*/
add_executable(
app
${SRC}
)
复制配置文件
file(
COPY
config.ini
DESTINATION
${CMAKE_BINARY_DIR}
)
常用命令总结
| 命令 | 作用 |
|---|---|
file(GLOB) |
查找文件 |
file(GLOB_RECURSE) |
递归查找 |
file(READ) |
读取文件 |
file(WRITE) |
写文件 |
file(COPY) |
复制文件 |
file(MAKE_DIRECTORY) |
创建目录 |
file(REMOVE) |
删除文件 |
file(REAL_PATH) |
获取绝对路径 |
3.add_definitions
add_definitions(-D__ARM_ARCH_PROFILE='M'),等价于: gcc -DNAME=value add_definitions( -D宏名=值 )
add_definitions() 没有目标名,因为它是全局添加编译定义;而 target_compile_definitions() 是针对某个 target 添加定义**。**
现代 CMake 推荐替代:
# 只对指定目标添加宏
target_compile_definitions(
目标名
PRIVATE
宏名
)
1. 目标名(target)
这里的目标就是你之前创建的:add_executable()或者:add_library()生成的东西。
例如:
# 创建一个可执行程序,名字叫 app
add_executable(
app
main.cpp
)
这里:app就是一个 target(目标)。
然后:
target_compile_definitions(
app
PRIVATE
DEBUG
)
意思:给 app 这个目标添加 DEBUG 宏
等价:
gcc main.cpp -DDEBUG
2. PRIVATE 是什么?
PRIVATE 表示:
这个宏只给当前目标使用,不传递给依赖它的其他目标。
例如:
target_compile_definitions(
app
PRIVATE
DEBUG
STM32F10X_HD
)
等价:
gcc -DDEBUG -DSTM32F10X_HD