CMake实战指南 开始1介绍2 创建工程3 最小项目3.1 管理CMake版本3.2 project()命令3.3 构建基础可执行文件3.4 注释3.5 练习 4 构建简单目标4.1 可执行对象4.2 定义链接库4.3 链接目标4.4 链接非目标4.5 旧风格CMake4.6 练习 5 基本的测试和部署5.1 测试5.2 安装5.3 打包5.4 练习 CMake基础6 变量6.1 变量基础6.2 环境基础6.3 缓存变量6.4 作用域块6.5 打印变量值6.6 字串处理6.7 列表6.8 数学6.9 练习 7 控制流7.1 if()命令7.2 循环7.3 练习 8 子目录8.1 add_subdirectory()命令8.2 include()命令8.3 项目相关变量8.4 提前结束8.5 练习 9 函数和宏9.1 基本概念9.2 参数处理9.3 关键参数9.4 返回值9.5 重写命令9.6 函数相关特殊变量9.7 其他调用CMake代码的方式9.8 参数处理中的问题9.9 练习 10属性10.1 通用属性相关命令10.2 全局数据10.3 目录属性10.4 目标属性10.5 源码属性10.6 缓存变量属性10.7 其他属性类型10.8 练习 11 生成器表达式11.1 简单的Boolean逻辑11.2 目标详情11.3 通用信息11.4 路径表达表达式11.5 列表表达式11.6 工具表达式11.7 练习 12 模块12.1 检查模块存在及支持12.2 其他模块12.3 练习 13 策略13.1 策略控制13.2 策略作用域13.3 练习 14 调试和诊断14.1 Log消息14.2 颜色诊断14.3 打印帮助14.4 追踪变量访问14.5 调试生成器表达式14.6 CMake调用性能14.7 丢弃之前结果14.8 交互式调试14.9 练习 15 构建类型15.1 构建类型基本知识15.2 通用错误15.3 定制构建类型15.4 练习 16 编译器和链接器16.1 目标属性16.2 目标属性命令16.3 目标属性上下文16.4 目录属性和命令16.5 消除重复选项16.6 编译器和链接器相关变量16.7 语言相关的编译器标志16.8 编译器选项抽象16.9 练习 深入构建17 语言要求17.1 直接设置语言标准17.2 根据需求设置语言标准17.3 练习 18 高级链接18.1 指定链接目标18.2 定制链接库链接方式18.3 直接链接关系传递18.4 练习 19 目标类型19.1 可执行目标19.2 链接库19.3 导入目标 20 自定义任务20.1 自定义目标20.2 对已存在目标新增构建步骤20.3 文件生成命令20.4 配置时间任务20.5 平台无关命令20.6 合并不同方式20.7 练习 21 文件相关操作21.1 路径管理21.2 复制文件21.3 目录文件读取和写入21.4 文件系统管理21.5 文件全局搜索21.6 文件下载和上传21.7 练习 22 版本信息22.1 项目版本22.2 源码访问版本信息22.3 源码控制提交22.4 练习 23 链接库23.1 构建基础23.2 链接静态库23.3 动态链接库版本23.4 接口兼容性23.5 符号可见性23.6 混合静态库和动态库23.7 练习 24 工具链和交叉编译24.1 工具链文件24.2 目标系统定义24.3 工具选择24.4 系统根目录24.5 编译器检查24.6 示例24.7 安卓系统24.8 练习 25 苹果系统特征25.1 CMake生成器选择25.2 应用程序25.3 框架25.4 可加载程序25.5 构建设置25.6 签名及兼容性25.7 创建及导出打包25.8 通用二进制25.9 链接框架25.10 嵌入框架、插件和扩展25.11 局限性25.12 练习 26 构建性能26.1 工具构建26.2 预编译头26.3 并行构建26.4 优化构建依赖26.5 编译器缓存26.6 调试相关改进26.7 可选链接器26.8 练习 测试和分析27 测试基础27.1 定义和执行简单的测试27.2 测试环境27.3 通过/失败标准和其他结果类型27.4 测试分组和选择27.5 交叉编译和仿真27.6 JUnit输出27.7 练习 28 测试资源和约束28.1 简单的测试依赖28.2 测试夹具28.3 并行执行28.4 简单的资源约束28.5 资源分组28.6 练习 29 构建和测试模式29.1 使用构建和测试模式29.2 用例29.3 可选项29.4 练习 30 测试框架30.1 GoogleTest30.2 Cach230.3 doctest30.4 练习 31 CDash集成31.1 CDash关键概念31.2 Pipelines和Actions执行31.3 CTest配置31.4 测试测量和结果31.5 输出控制31.6 练习 32 静态代码分析32.1 clang-tidy32.2 cppcheck32.3 cpplint32.4 包含你所使用的32.5 关闭某些文件的检查32.6 联合编译存在的潜在问题 33 动态代码分析33.1 Sanitizers33.2 代码覆盖率33.3 练习 部署和依赖34 查找34.1 查找文件和路径34.2 查找路径34.3 查找程序34.4 查找库34.5 查找包34.6 忽略查找路径34.7 调试find_...()调用34.8 练习 35 安装35.1 目录布局35.2 安装项目目录35.3 安装导出目标35.4 安装导入目标35.5 安装文件35.6 自定义安装逻辑35.7 安装依赖35.8 写一个包配置文件35.9 执行安装35.10 练习 36 打包36.1 打包基础36.2 组件36.3 多配置包36.4 练习 37 包生成器37.1 简单的打包37.2 Qt安装框架(IFW)37.3 WIX37.4 NSIS37.5 Inno Setup37.6 GradNDrop37.7 productbuild37.8 RPM37.9 DEB37.10 FreeBSD37.11 Cygwin37.12 NuGet37.13 External37.14 练习 38 外部项目38.1 高层级概括38.2 目录布局38.3 构建步骤38.4 构建步骤管理38.5 其他功能38.6 通用问题38.7 外部数据38.8 练习 39 FetchContent39.1 和外部项目比较39.2 基本使用方法39.3 依赖解决39.4 与find_package()交互39.5 开发者重写39.6 其他关于FetchContent的使用39.7 约束39.8 练习 40 项目可用性40.1 使用相关相关的名字40.2 不要假设顶层的构建40.3 不要硬编码开发者选项40.4 尽可能避免包相关的变量40.5 使用合适的方法获取依赖40.6 练习 41 依赖提供41.1 顶层设置注入点41.2 依赖提供实现41.3 练习 项目组织42 预制条件42.1 高层级结构42.2 配置预制42.3 构建预制42.4 测试预制42.5 打包预制42.6 工作流程预制42.7 练习 43 项目结构43.1 超级构建结构43.2 非超级构建结构43.3 通用的顶层子目录43.4 IDE项目43.5 定义目标43.6 Windows平台相关的问题43.7 清理文件43.8 文件变动时重写运行CMake43.9 项目中注入文件43.10 练习 专题44 使用Qt44.1 项目中使用Qt44.2 建立标准工程44.3 命令和目标名称44.4 定义目标44.5 自动生成44.6 翻译44.7 部署44.8 练习 附录 A:完整编译缓存示例附录B:Sanitizers示例索引 开始 1介绍 跳转 2 创建工程 跳转 3 最小项目 3.1 管理CMake版本 3.2 project()命令 3.3 构建基础可执行文件 3.4 注释 3.5 练习 4 构建简单目标 4.1 可执行对象 4.2 定义链接库 4.3 链接目标 4.4 链接非目标 4.5 旧风格CMake 4.6 练习 5 基本的测试和部署 5.1 测试 5.2 安装 5.3 打包 5.4 练习 CMake基础 6 变量 6.1 变量基础 6.2 环境基础 6.3 缓存变量 6.4 作用域块 6.5 打印变量值 6.6 字串处理 6.7 列表 6.8 数学 6.9 练习 7 控制流 7.1 if()命令 7.2 循环 7.3 练习 8 子目录 8.1 add_subdirectory()命令 8.2 include()命令 8.3 项目相关变量 8.4 提前结束 8.5 练习 9 函数和宏 9.1 基本概念 9.2 参数处理 9.3 关键参数 9.4 返回值 9.5 重写命令 9.6 函数相关特殊变量 9.7 其他调用CMake代码的方式 9.8 参数处理中的问题 9.9 练习 10属性 10.1 通用属性相关命令 10.2 全局数据 10.3 目录属性 10.4 目标属性 10.5 源码属性 10.6 缓存变量属性 10.7 其他属性类型 10.8 练习 11 生成器表达式 11.1 简单的Boolean逻辑 11.2 目标详情 11.3 通用信息 11.4 路径表达表达式 11.5 列表表达式 11.6 工具表达式 11.7 练习 12 模块 12.1 检查模块存在及支持 12.2 其他模块 12.3 练习 13 策略 13.1 策略控制 13.2 策略作用域 13.3 练习 14 调试和诊断 14.1 Log消息 14.2 颜色诊断 14.3 打印帮助 14.4 追踪变量访问 14.5 调试生成器表达式 14.6 CMake调用性能 14.7 丢弃之前结果 14.8 交互式调试 14.9 练习 15 构建类型 15.1 构建类型基本知识 15.2 通用错误 15.3 定制构建类型 15.4 练习 16 编译器和链接器 16.1 目标属性 16.2 目标属性命令 16.3 目标属性上下文 16.4 目录属性和命令 16.5 消除重复选项 16.6 编译器和链接器相关变量 16.7 语言相关的编译器标志 16.8 编译器选项抽象 16.9 练习 深入构建 17 语言要求 17.1 直接设置语言标准 17.2 根据需求设置语言标准 17.3 练习 18 高级链接 18.1 指定链接目标 18.2 定制链接库链接方式 18.3 直接链接关系传递 18.4 练习 19 目标类型 19.1 可执行目标 19.2 链接库 19.3 导入目标 20 自定义任务 20.1 自定义目标 20.2 对已存在目标新增构建步骤 20.3 文件生成命令 20.4 配置时间任务 20.5 平台无关命令 20.6 合并不同方式 20.7 练习 21 文件相关操作 21.1 路径管理 21.2 复制文件 21.3 目录文件读取和写入 21.4 文件系统管理 21.5 文件全局搜索 21.6 文件下载和上传 21.7 练习 22 版本信息 22.1 项目版本 22.2 源码访问版本信息 22.3 源码控制提交 22.4 练习 23 链接库 23.1 构建基础 23.2 链接静态库 23.3 动态链接库版本 23.4 接口兼容性 23.5 符号可见性 23.6 混合静态库和动态库 23.7 练习 24 工具链和交叉编译 24.1 工具链文件 24.2 目标系统定义 24.3 工具选择 24.4 系统根目录 24.5 编译器检查 24.6 示例 24.7 安卓系统 24.8 练习 25 苹果系统特征 25.1 CMake生成器选择 25.2 应用程序 25.3 框架 25.4 可加载程序 25.5 构建设置 25.6 签名及兼容性 25.7 创建及导出打包 25.8 通用二进制 25.9 链接框架 25.10 嵌入框架、插件和扩展 25.11 局限性 25.12 练习 26 构建性能 26.1 工具构建 26.2 预编译头 26.3 并行构建 26.4 优化构建依赖 26.5 编译器缓存 26.6 调试相关改进 26.7 可选链接器 26.8 练习 测试和分析 27 测试基础 27.1 定义和执行简单的测试 27.2 测试环境 27.3 通过/失败标准和其他结果类型 27.4 测试分组和选择 27.5 交叉编译和仿真 27.6 JUnit输出 27.7 练习 28 测试资源和约束 28.1 简单的测试依赖 28.2 测试夹具 28.3 并行执行 28.4 简单的资源约束 28.5 资源分组 28.6 练习 29 构建和测试模式 29.1 使用构建和测试模式 29.2 用例 29.3 可选项 29.4 练习 30 测试框架 30.1 GoogleTest 30.2 Cach2 30.3 doctest 30.4 练习 31 CDash集成 31.1 CDash关键概念 31.2 Pipelines和Actions执行 31.3 CTest配置 31.4 测试测量和结果 31.5 输出控制 31.6 练习 32 静态代码分析 32.1 clang-tidy 32.2 cppcheck 32.3 cpplint 32.4 包含你所使用的 32.5 关闭某些文件的检查 32.6 联合编译存在的潜在问题 33 动态代码分析 33.1 Sanitizers 33.2 代码覆盖率 33.3 练习 部署和依赖 34 查找 34.1 查找文件和路径 34.2 查找路径 34.3 查找程序 34.4 查找库 34.5 查找包 34.6 忽略查找路径 34.7 调试find_…()调用 34.8 练习 35 安装 35.1 目录布局 35.2 安装项目目录 35.3 安装导出目标 35.4 安装导入目标 35.5 安装文件 35.6 自定义安装逻辑 35.7 安装依赖 35.8 写一个包配置文件 35.9 执行安装 35.10 练习 36 打包 36.1 打包基础 36.2 组件 36.3 多配置包 36.4 练习 37 包生成器 37.1 简单的打包 37.2 Qt安装框架(IFW) 37.3 WIX 37.4 NSIS 37.5 Inno Setup 37.6 GradNDrop 37.7 productbuild 37.8 RPM 37.9 DEB 37.10 FreeBSD 37.11 Cygwin 37.12 NuGet 37.13 External 37.14 练习 38 外部项目 38.1 高层级概括 38.2 目录布局 38.3 构建步骤 38.4 构建步骤管理 38.5 其他功能 38.6 通用问题 38.7 外部数据 38.8 练习 39 FetchContent 39.1 和外部项目比较 39.2 基本使用方法 39.3 依赖解决 39.4 与find_package()交互 39.5 开发者重写 39.6 其他关于FetchContent的使用 39.7 约束 39.8 练习 40 项目可用性 40.1 使用相关相关的名字 40.2 不要假设顶层的构建 40.3 不要硬编码开发者选项 40.4 尽可能避免包相关的变量 40.5 使用合适的方法获取依赖 40.6 练习 41 依赖提供 41.1 顶层设置注入点 41.2 依赖提供实现 41.3 练习 项目组织 42 预制条件 42.1 高层级结构 42.2 配置预制 42.3 构建预制 42.4 测试预制 42.5 打包预制 42.6 工作流程预制 42.7 练习 43 项目结构 43.1 超级构建结构 43.2 非超级构建结构 43.3 通用的顶层子目录 43.4 IDE项目 43.5 定义目标 43.6 Windows平台相关的问题 43.7 清理文件 43.8 文件变动时重写运行CMake 43.9 项目中注入文件 43.10 练习 专题 44 使用Qt 44.1 项目中使用Qt 44.2 建立标准工程 44.3 命令和目标名称 44.4 定义目标 44.5 自动生成 44.6 翻译 44.7 部署 44.8 练习 附录 A:完整编译缓存示例 附录B:Sanitizers示例 索引