CMake 基础教程
CMake 是一个跨平台的自动化构建系统工具,广泛应用于大型和跨平台的 C++ 项目中。以下是对 CMake 的所有功能和方法的详细解释。
1. CMake 基础功能
1.1 项目定义和配置
cmake_minimum_required(VERSION <version>)
- 该命令用于指定项目所需的最低 CMake 版本。例如,
cmake_minimum_required(VERSION 3.10)
表示要求 CMake 版本至少为 3.10。此命令确保使用的 CMake 版本具有你所需的功能或特性。
- 该命令用于指定项目所需的最低 CMake 版本。例如,
project(<project_name> [<language>...])
- 该命令用于定义项目的名称。你可以指定项目使用的语言(如 CXX 代表 C++,C 代表 C 语言等)。如果没有指定语言,CMake 会默认使用 C 语言。
cmakeproject(MyProject CXX)
set(<variable> <value>)
- 该命令用于设置一个变量的值。例如,
set(SRC_FILES main.cpp)
会将main.cpp
存储在SRC_FILES
变量中,可以在后续命令中使用。 - 也可以设置路径或其他选项。比如:
cmakeset(CMAKE_CXX_STANDARD 11)
这行代码会将 C++ 标准设置为 C++11。
- 该命令用于设置一个变量的值。例如,
1.2 构建目标
add_executable(<name> <source_files>)
- 定义一个可执行目标文件。例如,
add_executable(MyApp main.cpp)
会创建一个名为MyApp
的可执行文件,将main.cpp
作为源文件。
- 定义一个可执行目标文件。例如,
add_library(<name> <source_files>)
- 定义一个库目标,可以是静态库(默认)或共享库(通过
SHARED
选项指定)。例如:
cmakeadd_library(MyLibrary STATIC mylib.cpp)
这会生成一个静态库
MyLibrary.a
,并将mylib.cpp
文件作为源文件。- 定义一个库目标,可以是静态库(默认)或共享库(通过
target_link_libraries(<target> <libraries>)
- 用于为目标链接外部库。比如:
cmaketarget_link_libraries(MyApp MyLibrary)
将
MyApp
与MyLibrary
静态库进行链接。
2. 变量操作和条件判断
2.1 变量操作
set(<variable> <value>)
- 设置一个变量的值,如:
cmakeset(SOURCE_FILES main.cpp utils.cpp)
get_filename_component(<variable> <filename> <option>)
- 从文件路径中提取信息(如文件名、目录、扩展名等)。常见选项包括:
NAME
提取文件名DIRECTORY
提取目录路径EXT
提取文件扩展名
cmakeget_filename_component(DIR_PATH /path/to/file.cpp DIRECTORY)
- 从文件路径中提取信息(如文件名、目录、扩展名等)。常见选项包括:
list(<command> <args>)
- 对列表变量进行操作,如查找、排序、添加或删除元素:
cmakelist(APPEND SRC_FILES newfile.cpp) list(SORT SRC_FILES)
2.2 条件判断
if(<condition>) ... else() ... endif()
- 用于执行条件判断:
cmakeif(WIN32) message(STATUS "This is Windows") elseif(APPLE) message(STATUS "This is macOS") else() message(STATUS "This is Linux") endif()
elseif(<condition>)
- 用于多重条件判断。可与
if
配合使用。
- 用于多重条件判断。可与
else()
- 用于
if
语句的备选代码块。
- 用于
2.3 循环
foreach(<loop_variable> <values>) ... endforeach()
- 用于遍历一个列表的所有元素:
cmakeforeach(file IN LISTS SRC_FILES) message(STATUS "Processing ${file}") endforeach()
3. 查找和使用外部库
3.1 查找外部包
find_package(<package_name> [version] [REQUIRED|OPTIONAL])
- 查找并引入外部依赖包。常用的包有 Boost、OpenCV 等。
REQUIRED
表示包为必需项,若找不到则会抛出错误;OPTIONAL
表示包为可选项。
cmakefind_package(OpenCV REQUIRED)
3.2 目标链接
target_link_libraries(<target> <library>)
- 用于将外部库链接到指定目标。例如:
cmaketarget_link_libraries(MyApp Boost::Boost)
3.3 头文件和源文件
include_directories(<directory>)
- 将头文件目录添加到目标的编译路径中。例如:
cmakeinclude_directories(${CMAKE_SOURCE_DIR}/include)
file(<command> <args>)
- 进行文件操作,如查找文件、读取文件内容等:
cmakefile(GLOB SRC_FILES "*.cpp")
4. 构建选项和配置
4.1 选项和开关
option(<option_name> <description> <initial_value>)
- 设置一个布尔值选项,可以通过命令行或 CMake GUI 来启用或禁用功能。例如:
cmakeoption(USE_OPENMP "Use OpenMP" ON)
4.2 编译选项
add_compile_options(<options>)
- 为所有目标添加编译选项。例如,添加优化选项:
cmakeadd_compile_options(-O2)
target_compile_options(<target> <PRIVATE|PUBLIC> <options>)
- 为指定目标添加编译选项:
cmaketarget_compile_options(MyApp PRIVATE -Wall)
4.3 链接选项
add_link_options(<options>)
- 为所有目标添加链接选项,例如添加链接器优化选项:
cmakeadd_link_options(-O2)
target_link_options(<target> <options>)
- 为指定目标添加链接选项:
cmaketarget_link_options(MyApp PRIVATE -L/path/to/lib)
5. CMake 构建功能
5.1 构建系统生成
cmake ..
- 从构建目录运行 CMake,指定源目录并生成构建文件(如 Makefile)。
cmake --build .
- 使用生成的构建文件进行实际的编译和链接。
5.2 并行构建
cmake --build . -- -jN
- 使用 N 个核心进行并行构建。例如,
-j4
会使用 4 核进行并行构建。
- 使用 N 个核心进行并行构建。例如,
5.3 安装功能
install(TARGETS <target> DESTINATION <path>)
- 安装构建好的目标文件到指定路径:
cmakeinstall(TARGETS MyApp DESTINATION /usr/local/bin)
install(FILES <files> DESTINATION <path>)
- 安装指定的文件(如头文件或配置文件)。
5.4 测试功能
enable_testing()
- 启用测试功能。
add_test(NAME <test_name> COMMAND <test_command>)
- 添加一个测试:
cmakeadd_test(NAME MyTest COMMAND my_test_executable)
ctest
- 执行测试,显示测试结果。
6. 调试和日志
6.1 调试信息
message(<message_type> <message>)
- 打印信息到终端。可以选择不同的消息类型:
STATUS
打印普通信息WARNING
打印警告ERROR
打印错误并停止 CMake 过程
cmakemessage(STATUS "Building ${PROJECT_NAME}")
6.2 日志记录
file(WRITE <filename> <content>)
- 将内容写入指定文件:
cmakefile(WRITE "${CMAKE_BINARY_DIR}/log.txt" "Build started")
7. 高级功能
7.1 生成器表达式
$<...>
- CMake 支持生成器表达式,用于在构建过程中动态生成特定的值。例如:
cmaketarget_compile_definitions(MyApp PRIVATE $<CONFIG:Debug>)
7.2 交叉编译
CMAKE_TOOLCHAIN_FILE
- 用于指定交叉编译工具链配置文件,适用于不同平台或架构的编译过程。
7.3 模块和包管理
include(<module_name>)
- 包含 CMake 模块或脚本,用于扩展 CMake 的功能:
cmakeinclude(CMakeFindPackageHelper)
8. 跨平台支持
8.1 平台检查
if(WIN32)
- 检查当前构建环境是否为 Windows 平台。
if(APPLE)
- 检查当前构建环境是否为 macOS 平台。
if(UNIX)
- 检查当前构建环境是否为 Unix-like 平台(如 Linux)。
8.2 平台特定设置
set(CMAKE_OSX_ARCHITECTURES "x86_64")
- 设置 macOS 的架构。
9. 跨项目集成
9.1 导出配置
export(TARGETS <target> FILE <file>)
- 将构建的目标导出到配置文件,供其他项目使用。
install(EXPORT <export_name> DESTINATION <dir>)
- 导出目标配置,供其他项目通过
find_package
查找和使用。
- 导出目标配置,供其他项目通过
10. CMake 与 IDE 集成
CMake 可以与多种 IDE (如 CLion、Visual Studio、Xcode)集成,自动生成适用于目标平台的工程文件。通过 CMake 配置的项目能够方便地在不同平台上构建。
通过掌握这些命令和功能,CMake 可以帮助开发者更高效地管理项目的构建过程,支持跨平台开发和复杂的依赖关系管理。