4.8 KiB
CMake Target Context Transaction Skill
目标
生成 CMake 工具脚本时,把复杂流程拆成多个可独立调试、可自由组合的 step。
Bash 版里的 ctx 关联数组,在 CMake 版中等价于一个“存储数据的 target”。
每个 step 都必须是一个独立的 add_custom_target()。
核心规则
-
注意写cmake脚本 注意区分 CMAKE_HOST_WIN32 WIN32 的区别 查找系统工具要使用 CMAKE_HOST_WIN32 (WIN32 UNIX APPLE MINGW MSYS CYGWIN ANDROID IOS)
-
写 execute_process 执行查找工具命令 要注意 TIMEOUT 参数 不要无限制等待
-
使用一个 ctx target 存储所有运行状态。
add_custom_target(${ctx_target})
set_property(TARGET ${ctx_target} PROPERTY CTX_XXX "...")
get_property(value TARGET ${ctx_target} PROPERTY CTX_XXX)
-
禁止使用全局变量、CACHE 变量对外传递运行状态。
-
所有返回值都通过
ret_参数返回,且返回值参数写在函数签名前面。
function(step_xxx ret_step_target ctx_target ...)
set(${ret_step_target} "${step_target}" PARENT_SCOPE)
endfunction()
-
CMake 函数的
return()只允许提前结束函数,不用于表达业务状态。 -
使用 fast fail 模式,发现错误直接:
message(FATAL_ERROR "中文错误信息")
禁止带病运行。
- 需要传入 list 时,优先传入 list 变量名,函数内部再取值。
function(step_xxx ret_step_target ctx_target list_var)
set(local_list "${${list_var}}")
endfunction()
- 严禁使用
cmake_parse_arguments()。
严禁使用复杂参数解析。
禁止使用:
cmake_parse_arguments() ARGN ARGV ARGV0 ARGV1
函数参数必须显式、固定、直接声明。
- 日志和注释必须使用中文。
固定 API 模式
init_${整体功能名称}_env
初始化整体功能环境。
function(init_xxx_env ret_ctx_target ctx_target ...)
职责:
- 创建 ctx target。
- 初始化 ctx 属性。
- 创建后续 step 需要的副作用资源。
- 设置统一的
FOLDER属性。 - 返回 ctx target 名称。
step_${功能名称}
创建一个业务步骤。
function(step_xxx ret_step_target ctx_target ...)
职责:
- 读取 ctx target 属性。
- 创建独立的
add_custom_target()。 - step target 必须可单独执行。
- step target 必须设置和 ctx 相同的
FOLDER。 - step target 名称写回 ctx 的
CTX_STEP_TARGETS属性。 - 返回 step target 名称。
clear_${整体功能名称}_env
创建清理步骤。
function(clear_xxx_env ret_clear_target ctx_target ...)
职责:
- 创建一个清理用 custom target。
- 只清理 ctx 中记录过的资源。
- 必须可重复执行。
- 不得误删外部原本存在的资源。
- 设置和 ctx 相同的
FOLDER。 - 返回 clear target 名称。
注意:CMake 配置阶段创建的 target 不能删除,所以 clear 只负责创建“清理 target”。
step 组合规则
step 可以单独执行:
cmake --build build --target xxx_ctx__step_prepare
step 可以通过依赖组合:
add_dependencies(${step_b} ${step_a})
add_dependencies(${step_c} ${step_b})
禁止依赖 target 创建顺序表达执行顺序。
文件拆分
固定拆成三个文件:
base_${整体功能名称}.cmake
function_${整体功能名称}.cmake
test_${整体功能名称}.cmake
包含关系:
test_${整体功能名称}.cmake
include(function_${整体功能名称}.cmake)
function_${整体功能名称}.cmake
include(base_${整体功能名称}.cmake)
base 文件
只放公共工具函数。
function 文件
只放三类函数:
init_${整体功能名称}_env(...)
step_${功能名称}(...)
clear_${整体功能名称}_env(...)
不要添加其他模式。
test 文件
写少量测试主流程函数。
测试函数必须:
* 按 `init -> step -> clear` 模式调用。
* 每个测试函数可独立执行。
* 注释详细。
* 日志中文。
命名规则
ctx target:
${整体功能名称}_ctx
step target:
${ctx_target}__step_${功能名称}
clear target:
${ctx_target}__clear_env
所有相关 target 使用相同的 FOLDER 属性:
set_target_properties(${target}
PROPERTIES
FOLDER "${整体功能名称}"
)
禁止事项
- 禁止使用全局变量传递运行状态。
- 禁止使用 CACHE 变量传递运行状态。
- 禁止使用
cmake_parse_arguments()。 - 禁止依赖 target 创建顺序表达执行顺序。
- 禁止 step 函数偷偷创建主流程 target。
- 禁止 clear 函数删除 ctx 未记录的资源。
- 禁止在 function 文件中添加第四种 API 模式。
- 禁止英文日志和英文注释。