CMake是跨平台构建工具通过CMakeLists.txt描述编译规则生成 Makefile/VS工程/Ninja等再调用编译器构建。1. 基础规则1.1主文件CMakeLists.txt根目录必须有大小写敏感。1.2命令格式① 不区分大小写② 参数用空格/换行分隔括号不能丢③ 字符串含空格用双引号包裹如add_executable(QMLTest04 main.cpp) set(CMAKE_PREFIX_PATH D:/Qt/Qt6.11.1/6.11.1/mingw_64) target_link_libraries(QMLTest04 Qt::Core Qt::Gui Qt::Widgets )1.3 注释#注释内容无多行注释只有单行注释。如#MESSAGE(WARNING This is BINARY dir ${QMLTest04_BINARY_DIR})1.4 变量定义/赋值set(变量名 值)取值${变量名}如set(CMAKE_PREFIX_PATH D:/Qt/Qt6.11.1/6.11.1/mingw_64) set(QT_INSTALL_PATH ${CMAKE_PREFIX_PATH})2. 核心命令2.1 最低版本要求cmake_minimum_required(VERSION 4.2)2.2 定义项目2.2.1 设置项目、语言、版本project(QMLTest04) project(MyProject LANGUAGES C CXX VERSION 1.0)2.2.2内置自动变量·${PROJECT_NAME}项目名·${PROJECT_SOURCE_DIR}项目根目录源码根路径·${PROJECT_BINARY_DIR}构建目录编译输出目录MESSAGE( 项目名称: ${PROJECT_NAME}) MESSAGE( 项目根目录: ${PROJECT_SOURCE_DIR}) MESSAGE( 构建目录: ${PROJECT_BINARY_DIR})输出结果项目名称:QMLTest04 项目根目录:E:/C/Demo/QMLTest04 构建目录:E:/C/Demo/QMLTest04/cmake-build-debug2.3 定义变量/列表2.3.1 普通变量set(APP_NAME TestApp) set(VERSION 1.0.0)2.3.2 文件列表多参数列表set(SRCS main.cpp hello.cpp util.c )2.4 生成可执行文件编译源码为exe/可执行程序语法add_executable(输出文件名 源码列表)如#单个源码 add_executable(QMLTest04 main.cpp) #多个源码 add_executable(demo main.cpp test.cpp) #使用变量推荐易维护 add_executable(demo ${SRCS})2.5 生成库文件# 1. 静态库 (.a / .lib) # add_library(库名 STATIC 源码文件) # 2. 动态库 (.so / .dll) # add_library(库名 SHARED 源码文件) set(LIB_SRCS func.cpp) add_library(mylib STATIC ${LIB_SRCS})2.6 链接库给目标可执行文件/库链接依赖库语法target_link_libraries(目标名 库名1 库名2 ...)示例# 可执行文件demo链接静态库mylib target_link_libraries(demo mylib)2.7 头文件搜索路径添加.h/.hpp头文件目录编译时能直接#include xxx.hinclude_directories(头文件目录路径)常用搭配相对路径include_directories(${PROJECT_SOURCE_DIR}/include)现代CMake更推荐target_include_directories作用范围更精准target_include_directories(demo PRIVATE ${PROJECT_SOURCE_DIR}/include)3. 路径与常用内置变量不用手动定义CMake自带${CMAKE_SOURCE_DIR} # 整个工程根目录 ${CMAKE_BINARY_DIR} # 顶层构建目录 ${CMAKE_CURRENT_SOURCE_DIR} # 当前 CMakeLists.txt 所在目录 ${CMAKE_CURRENT_BINARY_DIR} # 当前目录对应的构建目录 # 编译器相关 ${CMAKE_C_COMPILER} # C 编译器 ${CMAKE_CXX_COMPILER} # C 编译器4. 条件判断if语法4.1 基础判断if(条件) 命令... elseif(其他条件) 命令... else() 命令... endif()4.2 常用条件# 判断变量是否存在/非空 if(DEFINED APP_NAME) # 判断操作系统 if(WIN32) message(当前是 Windows) elseif(UNIX) message(当前是 Linux/Mac) endif() # 判断文件/目录是否存在 if(EXISTS ${PROJECT_SOURCE_DIR}/include)4.3 逻辑运算·AND并且·OR或者·NOT取反if(WIN32 AND EXISTS ${PROJECT_SOURCE_DIR}/lib)5. 循环# 遍历文件列表 foreach(file ${SRCS}) message(文件: ${file}) endforeach() # 数字遍历 1~5 foreach(i RANGE 1 5) message(数字: ${i}) endforeach()6. 打印信息message(普通日志) message(STATUS 状态信息) # 标准输出 message(WARNING 警告) message(FATAL_ERROR 致命错误终止编译)