CMAKE 分为Configure Generate Build三个阶段
essential
cmake生成项目构建树(Generate a Project Buildsystem)
cmake -S <path-to-source> -B <path-to-build> -G <generator-name>
e.g. cmake -S ./project -B ./build -G "Unix Makefiles"
cmake -S <path-to-source> -B <path-to-build> -G <generator-name> -C <path-to-cache-variables-scripts>
e.g. cmake -S ./project -B ./build -G "Unix Makefiles" -C "./cacheV.txt"
cmake -S <path-to-source> -B <path-to-build> -G <generator-name> -D <var>[:<type>]=<value>
e.g. cmake -S ./project -B ./build -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Release
其中cacheV.txt的内容是
set(CMAKE_CXX_COMPILER /usr/bin/g++)
set(CMAKE_BUILD_TYPE Release)
-S CMakeLists.txt所在目录,源码目录 -B 构建树的生成目录 -G 指定生成器(可以用cmake --help查看当前系统支持的生成器) -C 包含预填缓冲变量的脚本(比如C C++编译器路径,构建类型)??(为什么有时候起作用有时候没作用?加载不了cacheV.txt? 但是在Presets中能够设置CMAKE_CXX_COMPILER 设置不了CMAKE_BUILD_TYPE 但是可以在生成命令中设置CMAKE_BUILD_TYPE??)(事实证明) -D 设置缓冲变量 -L[A][H] 列出缓存变量(CMake在生成的时候打印出缓存变量) --system-information <file> 输出关于系统的多项信息 --log-level=<level> 指定日志级别 ERROR WARNING NOTICE STATUS(default) VERBOSE DEBUG TRACE --log-context 让message命令能够输出上下文 --trace 输出每个命令的文件名称和代码行号和参数 更详细的生成信息 --preset=<preset> 指定预设的工作流
--list-presets 预置的选项 查看CMakePresets.json中的预设的CMake的生成、构建等设置 能够设置整个cmake的工作流的选项
在命令行中-D以及Preset变量和环境变量的优先级见下图:
图自ModernCMakeC++
?? 问题 -U 移除CMAKE CACHE中的匹配项 -T 指定工具集 -A 指定平台
cmake通过项目构建树构建项目
cmake --build <build-tree-dir> [<options>] [-- <build-tool-options>]
e.g. cmake --build ./build (构建树的路径和生成阶段-B后的路径相同)
-j 并行构建(环境变量 CMAKE_BUILD_PARALLEL_LEVEL 未验证) cmake --build ./build --parallel 8 cmake --build ./build -- -j 8 cmake --build ./build -j 8
-t --target 选择构建目标
cmake --build ./build --target <target1> -t <target2> ...
cmake --build ./build --target <target1> <target2> <target3> ...
有一个内置的构建目标clean,执行cmake --build ./build --target clean时,会清除以前构建的目标
e.g. cmake --build ./build --target clean
--clean-first 在构建目标之前先清除历史构建目标。 e.g. cmake --build ./build --target main --clean-first
-v --verbose 查看详细的构建输出信息(对应的缓存变量CMAKE_VERBOSE_MAKEFILE)
??问题 多配置生成器选项 同时构建Debug和Release支持的生成器包括Ninja Multi-Config Xcode Visual Studio --config <cfg> 在生成构建树的时候,使用-G指定"Ninja Multi-Config"等,然后在构建的时候使用--config Debug等。(问题是cfg是一个配置文件还是只能一次选Debug,空格分隔多个type不对)
cmake安装项目
cmake --install <dir> [options]
e.g. cmake --instal ./build 同样是指定构建树的目录
--config 多配置生成器 e.g. cmake --install ./build --config Debug 安装的时候可执行目标在Debug或者Release的目录下,和单配置生成器的目录不同,如果用了多生成器,安装的时候也需要
--prefix 安装目录的选项
cmake --install <dir> --prefix <prefix>
e.g. cmake --install ./build --prefix /home/usr 安装路径为/home/usr/DESTINATION CMakeLists.txt中的内容
??问题
--component 安装单个组件
cmake --install ./build --component <comp>
e.g. 具体用法?
--default-directory-permissions <permissions> 其中u=rwx, g=rx, o=rx
cmake --install ./build --default-directory-permissions
e.g. 具体用法
运行脚本
cmake [{-D <var>=<value>}...] -P <cmake-script-file> [-- <unparsed-options>...]
可以通过-D给变量传值也可以通过--后给脚本传值 脚本模式不会执行配置或者生成构建树,不影响缓存。
e.g. 具体用法?
运行命令行 执行一些平台无关的命令,可以通过cmake -E 查询支持的命令
cmake -E <command> [<options>]
e.g. 具体用法?
CTest
用法 在./build构建目录中使用
ctest
会自动化测试
CPack
为不同的平台创建:压缩包、可执行安装程序、安装向导、NuGet包、macOS包、DMG包、rpm等。
ccmake cmake-gui-qt
CMakeCache.txt 包含External cache entries和Internal cache entries其中External是用户可以修改的
包配置文件命名规则 <PackageName>-config.cmake <PackageName>Config.cmake,指定package的版本的时候,cmake会通过<Config>Version.cmake文件进行版本检查 cmake有一个包的注册表
CMakePresets.json和CMakeUserPresets.json 能够明确缓存变量、生成器、构建树路径等内容。且可以继承。// 最后我们会给一个cmake官方的CMakePresets.json例子以及一个补充例子
官方例子:cmake-presets(7) — CMake 3.29.0 Documentation
CMakePresets.json的结构通常如下:
{ "version": 1, "cmakeMinimumRequired": {"major":3,"minor":19,"patch":3}, "configurePresets": [], }
其中configurePresets数组的每个元素的结构如下: { "name": "my-preset", "displayName":"Custmo Preset", "description": "Ninja", "binaryDir": "", "cacheVariables": { "CMAKE_CXX_COMPILER": "/usr/bin/g++", "CMAKE_TOOLCHAIN_FILE": "/home/godzilla/softwares/vcpkg/scripts/buildsystems/vcpkg.cmake" } }
支持的字段包括 "name" 机器友好的 唯一的表示configure的名称 "Hidden" 布尔值 true或者false 是否隐藏当前preset configure 在 cmake --list-presets命令中不可见 "displayName" 一个可选的字符串,提供人类友好的名称 "Inherits" 继承的preset configure "Vendor" ???供应商的值? "Generator" 指定生成器的类型 "toolset" 可能是WSL? architecture ??? "binaryDir" 构建树的路径 通常是${sourceDir}/cmake-build-debug "cacheVariables" 预设缓存变量的 "environment" 用来设置环境变量 添加路径等
宏识别和展开 {sourceParentDir} 项目根目录的父目录 最高级CMkaeLists.txt所在的目录的上一级目录 /home/usr {presetName} 预设的名字 {dollar} 美元符号 penv{<varaibel-name>} 父环境的变量宏 $venodr{<macro-name>} 供应商自己的宏
cmake脚本
script.cmake内容如下
cmake_minimum_required(VERSION 3.20.0)
message("hellocmake")
file(WRITE Hello.txt "I am writing to a file")
然后执行 cmake -P ./script.cmake即可 脚本的内建变量包括 CMAKE_BINARY_DIR CMAKE_SOURCE_DIR CMAKE_CURRENT_BINARY_DIR CMAKE_CURRENT_SOURCE_DIR
cmake模块
cmake可以通过inclde(<MODULE>)引入模块使用扩展功能
cmake_minimum_required(VERSION 3.20.0)
project(project)
include(module1)
module1_api(module1_api1_args)
众多模块中比较常用的一个就是find_package()用以查找第三方依赖。