一、基本语法结构
1. 注释
2. 基本命令格式
1
| command_name(arg1 arg2 ...)
|
注意:CMake 不区分大小写,但推荐统一使用小写(现代 CMake 风格)。
二、变量操作
定义与引用变量
1 2 3 4 5 6 7 8 9 10 11 12
| set(MY_VAR "Hello") set(NUMBERS 1 2 3 4) set(FLAG ON)
message("Value: ${MY_VAR}")
list(APPEND NUMBERS 5) list(LENGTH NUMBERS len) list(GET NUMBERS 0 first)
|
变量作用域
1 2 3 4 5 6 7 8
| set(LOCAL_VAR "local")
set(CACHE_VAR "default" CACHE STRING "描述信息")
set(ENV{PATH} "$ENV{PATH}:/new/path")
|
三、核心构建命令
项目与版本
1 2 3 4 5
| cmake_minimum_required(VERSION 3.15) project(MyProject VERSION 1.0.0 DESCRIPTION "项目描述" LANGUAGES CXX)
|
生成可执行文件
1 2 3 4
| add_executable(app_name main.cpp utils.cpp )
|
生成库
1 2 3 4 5 6 7 8 9 10 11
| add_library(my_static STATIC src.cpp)
add_library(my_shared SHARED src.cpp)
add_library(my_objects OBJECT src1.cpp src2.cpp)
add_library(my_header INTERFACE)
|
链接库
1 2 3 4 5 6 7 8 9 10 11
| target_link_libraries(app_name PRIVATE my_lib PUBLIC dep_lib INTERFACE header_lib )
target_include_directories(app_name PRIVATE include/) target_compile_definitions(app_name PRIVATE DEBUG=1) target_compile_options(app_name PRIVATE -Wall -Wextra)
|
四、条件与循环
条件判断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| if(CONDITION) elseif(OTHER_CONDITION) else() endif()
if(EXISTS "${CMAKE_SOURCE_DIR}/file.txt") if(IS_DIRECTORY "${CMAKE_SOURCE_DIR}/dir") if(VARIABLE) if(NOT VARIABLE) if(VAR1 AND VAR2) if(VAR1 OR VAR2) if(VAR STREQUAL "string") if(VERSION_GREATER ${VER1} ${VER2})
|
循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| set(items a b c) foreach(item IN LISTS items) message("Item: ${item}") endforeach()
foreach(i RANGE 1 10) message("i = ${i}") endforeach()
set(i 0) while(i LESS 10) math(EXPR i "${i} + 1") message("i = ${i}") endwhile()
|
五、函数与宏
定义函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| function(my_function arg1 arg2) message("First arg: ${arg1}") message("All args: ${ARGV}") set(result "computed" PARENT_SCOPE) endfunction()
my_function(1 2 3) message("Result: ${result}")
|
定义宏
1 2 3 4
| macro(my_macro arg) message("Arg: ${arg}") endmacro()
|
区别:function 创建新作用域,macro 直接文本替换(类似 C 预处理器)。
六、模块与包含
包含其他 CMake 文件
1 2 3 4 5 6 7 8 9 10
| include(FindPackageHandleStandardArgs) include(ExternalProject)
include(${CMAKE_SOURCE_DIR}/cmake/utils.cmake)
add_subdirectory(src) add_subdirectory(extern/lib EXCLUDE_FROM_ALL)
|
查找包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| find_package(Boost 1.70 REQUIRED COMPONENTS system thread) find_package(OpenCV REQUIRED)
if(Boost_FOUND) target_link_libraries(my_target PRIVATE Boost::system) endif()
find_library(MATH_LIB m) find_path(OPENSSL_INCLUDE_DIR openssl/ssl.h)
find_program(PYTHON_EXECUTABLE python3)
|
七、现代 CMake 最佳实践(重要!)
目标导向设计(Target-based)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| include_directories(include) add_definitions(-DDEBUG) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
add_library(my_lib src.cpp) target_include_directories(my_lib PUBLIC $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include> ) target_compile_features(my_lib PUBLIC cxx_std_17) target_compile_definitions(my_lib PRIVATE DEBUG=1)
|
生成器表达式(Generator Expressions)
1 2 3 4 5 6 7 8 9 10
| target_compile_definitions(app PRIVATE $<$<CONFIG:Debug>:DEBUG_MODE> $<$<PLATFORM_ID:Windows>:WIN32_LEAN> $<$<CXX_COMPILER_ID:GNU,Clang>:GNU_COMPAT> )
target_link_libraries(app PRIVATE $<$<BOOL:${USE_OPENSSL}>:OpenSSL::SSL> )
|
安装与导出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| install(TARGETS my_lib EXPORT my_lib-targets LIBRARY DESTINATION lib ARCHIVE DESTINATION lib RUNTIME DESTINATION bin INCLUDES DESTINATION include )
install(DIRECTORY include/ DESTINATION include)
install(EXPORT my_lib-targets FILE my_lib-targets.cmake NAMESPACE my_lib:: DESTINATION lib/cmake/my_lib )
|
八、实用示例:完整 CMakeLists.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| cmake_minimum_required(VERSION 3.15) project(Calculator VERSION 1.0.0 LANGUAGES CXX)
option(BUILD_TESTS "Build unit tests" ON) option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF)
add_library(math_lib src/add.cpp src/subtract.cpp ) target_include_directories(math_lib PUBLIC $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include> )
add_executable(calc app/main.cpp) target_link_libraries(calc PRIVATE math_lib)
if(BUILD_TESTS) enable_testing() add_subdirectory(tests) endif()
install(TARGETS calc math_lib RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib ) install(DIRECTORY include/ DESTINATION include)
|
九、常用变量速查
| 变量 |
含义 |
CMAKE_SOURCE_DIR |
源码根目录 |
CMAKE_BINARY_DIR |
构建根目录 |
CMAKE_CURRENT_SOURCE_DIR |
当前 CMakeLists.txt 所在目录 |
CMAKE_CURRENT_BINARY_DIR |
当前构建目录 |
PROJECT_NAME |
项目名称 |
PROJECT_VERSION |
项目版本 |
CMAKE_BUILD_TYPE |
构建类型 (Debug/Release/RelWithDebInfo/MinSizeRel) |
CMAKE_CXX_COMPILER |
C++ 编译器 |
CMAKE_INSTALL_PREFIX |
安装前缀(默认 /usr/local 或 C:\Program Files) |
CMake 3.0+ 引入了现代 CMake 理念,核心思想是以目标(Target)为中心,通过 target_ 系列命令精确控制构建属性,避免全局设置带来的副作用。这是目前最推荐的写法。