CMake 是跨平台构建工具,用于管理项目的编译、链接和安装。以下是常用语法分类整理,结合现代最佳实践:
1. 基础配置
- 版本与项目定义
cmake_minimum_required(VERSION 3.10):指定最低 CMake 版本。project(MyProject [VERSION 1.0] [LANGUAGES CXX]):定义项目名称、版本和语言(如 C++)。set(CMAKE_CXX_STANDARD 17)+set(CMAKE_CXX_STANDARD_REQUIRED ON):全局设置 C++17 标准(推荐目标级配置)。
- 变量操作
set(VAR "value"):定义变量(列表用空格分隔)。unset(VAR):清除变量。list(APPEND VAR item):向列表追加元素。message(STATUS "Building..."):打印信息(支持WARNING/FATAL_ERROR)。
2. 目标管理
- 添加目标
add_executable(app main.cpp):生成可执行文件。add_library(my_lib STATIC src.cpp):生成静态库(SHARED动态库,INTERFACE仅头文件)。add_library(my_lib::core ALIAS my_lib):创建别名目标。
- 依赖与属性
target_include_directories(app PUBLIC include):设置头文件目录(PUBLIC传播到依赖者,PRIVATE仅自身)。target_link_libraries(app PRIVATE my_lib):链接库(PUBLIC传播依赖)。target_compile_options(app PRIVATE -Wall):添加编译选项。target_compile_features(app PUBLIC cxx_std_17):指定 C++ 标准(目标级)。target_compile_definitions(app PRIVATE DEBUG):添加宏定义(如-DDEBUG)。
3. 条件编译与跨平台
- 条件判断
if(UNIX)/if(WIN32):平台判断。if(CMAKE_BUILD_TYPE STREQUAL "Debug"):配置类型判断。option(USE_OPENMP "Enable OpenMP" OFF):定义布尔选项,配合if(USE_OPENMP)使用。
- 跨平台处理
find_package(Threads REQUIRED):查找系统库(如线程库)。- 使用
generator expressions(如$<CONFIG:Debug>)动态配置属性。
4. 依赖管理
- 查找第三方库
find_package(Boost 1.70 REQUIRED COMPONENTS system):查找 Boost 库,指定版本和组件。- 手动查找:
find_file(HEADER my.h PATHS /usr/include)/find_library(LIB my_lib PATHS /usr/lib)。
- 子目录与模块
add_subdirectory(src):递归处理子目录的CMakeLists.txt。include(custom.cmake):包含自定义模块。set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake):自定义查找路径。
5. 安装与打包
- 安装规则
install(TARGETS app my_lib RUNTIME DESTINATION bin LIBRARY DESTINATION lib):安装可执行文件和库。install(DIRECTORY include/ DESTINATION include):安装头文件。install(EXPORT MyProjectTargets FILE MyProjectTargets.cmake DESTINATION lib/cmake):导出配置供其他项目使用。
- 打包配置
set(CPACK_PACKAGE_NAME "MyProject")+include(CPack):生成安装包(支持.deb、.msi等)。
6. 高级用法
- 自定义命令与目标
add_custom_command(OUTPUT generated.cpp COMMAND python gen.py):生成源文件。add_custom_target(doc COMMAND doxygen):添加自定义目标(如文档生成)。
- 配置文件生成
configure_file(config.h.in config.h):替换模板中的变量(如@VERSION@)。
- 变量作用域
- 目录作用域:
CMakeLists.txt中定义的变量仅在当前目录及子目录有效。 - 目标作用域:通过
target_*设置的属性仅影响特定目标。 - 缓存变量:
set(VAR "value" CACHE INTERNAL "")持久化存储。
- 目录作用域:
7. 现代最佳实践
- 避免全局命令:优先使用
target_include_directories替代include_directories,精确控制作用域。 - 模块化结构:采用
add_subdirectory管理子模块,配合target_link_libraries传递依赖。 - 版本控制:使用
find_package自动处理库的版本和依赖冲突。 - 测试集成:
enable_testing()+add_test(NAME test COMMAND test_exe)添加测试。 - 性能优化:
--parallel并行构建,precompile_headers加速编译。
示例:现代 CMake 项目结构
# 顶层 CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(MyApp LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
add_subdirectory(src)
add_subdirectory(tests)
# src/CMakeLists.txt
add_library(my_lib STATIC lib.cpp)
target_include_directories(my_lib PUBLIC include)
target_link_libraries(my_lib PRIVATE fmt::fmt)
# tests/CMakeLists.txt
enable_testing()
add_executable(test_app test.cpp)
target_link_libraries(test_app PRIVATE my_lib)
add_test(NAME test_app COMMAND test_app)
通过以上语法,CMake 可实现跨平台构建、模块化管理及高效依赖解析,是 C++ 项目的首选构建工具。
1705

被折叠的 条评论
为什么被折叠?



