# CMake Target Context Transaction Skill

## 目标

生成 CMake 工具脚本时，把复杂流程拆成多个可独立调试、可自由组合的 step。

Bash 版里的 `ctx` 关联数组，在 CMake 版中等价于一个“存储数据的 target”。

每个 step 都必须是一个独立的 `add_custom_target()`。

---

## 核心规则
0. 注意写cmake脚本 注意区分 CMAKE_HOST_WIN32   WIN32 的区别 查找系统工具要使用 CMAKE_HOST_WIN32  （WIN32 UNIX APPLE MINGW MSYS CYGWIN ANDROID IOS）
0. 写 execute_process 执行查找工具命令  要注意 TIMEOUT 参数 不要无限制等待

1. 使用一个 ctx target 存储所有运行状态。

```cmake
add_custom_target(${ctx_target})
set_property(TARGET ${ctx_target} PROPERTY CTX_XXX "...")
get_property(value TARGET ${ctx_target} PROPERTY CTX_XXX)
```

2. 禁止使用全局变量、CACHE 变量对外传递运行状态。

3. 所有返回值都通过 `ret_` 参数返回，且返回值参数写在函数签名前面。

```cmake
function(step_xxx ret_step_target ctx_target ...)
    set(${ret_step_target} "${step_target}" PARENT_SCOPE)
endfunction()
```

4. CMake 函数的 `return()` 只允许提前结束函数，不用于表达业务状态。

5. 使用 fast fail 模式，发现错误直接：

```cmake
message(FATAL_ERROR "中文错误信息")
```

禁止带病运行。

6. 需要传入 list 时，优先传入 list 变量名，函数内部再取值。

```cmake
function(step_xxx ret_step_target ctx_target list_var)
    set(local_list "${${list_var}}")
endfunction()
```

7. 严禁使用 `cmake_parse_arguments()`。

严禁使用复杂参数解析。

禁止使用：

cmake_parse_arguments()
ARGN
ARGV
ARGV0
ARGV1

函数参数必须显式、固定、直接声明。



8. 日志和注释必须使用中文。

---

## 固定 API 模式

### init_${整体功能名称}_env

初始化整体功能环境。

```cmake
function(init_xxx_env ret_ctx_target ctx_target ...)
```

职责：

* 创建 ctx target。
* 初始化 ctx 属性。
* 创建后续 step 需要的副作用资源。
* 设置统一的 `FOLDER` 属性。
* 返回 ctx target 名称。

---

### step_${功能名称}

创建一个业务步骤。

```cmake
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

创建清理步骤。

```cmake
function(clear_xxx_env ret_clear_target ctx_target ...)
```

职责：

* 创建一个清理用 custom target。
* 只清理 ctx 中记录过的资源。
* 必须可重复执行。
* 不得误删外部原本存在的资源。
* 设置和 ctx 相同的 `FOLDER`。
* 返回 clear target 名称。

注意：CMake 配置阶段创建的 target 不能删除，所以 clear 只负责创建“清理 target”。

---

## step 组合规则

step 可以单独执行：

```bash
cmake --build build --target xxx_ctx__step_prepare
```

step 可以通过依赖组合：

```cmake
add_dependencies(${step_b} ${step_a})
add_dependencies(${step_c} ${step_b})
```

禁止依赖 target 创建顺序表达执行顺序。

---

## 文件拆分

固定拆成三个文件：

```text
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：

```text
${整体功能名称}_ctx
```

step target：

```text
${ctx_target}__step_${功能名称}
```

clear target：

```text
${ctx_target}__clear_env
```

所有相关 target 使用相同的 `FOLDER` 属性：

```cmake
set_target_properties(${target}
    PROPERTIES
        FOLDER "${整体功能名称}"
)
```

---

## 禁止事项

* 禁止使用全局变量传递运行状态。
* 禁止使用 CACHE 变量传递运行状态。
* 禁止使用 `cmake_parse_arguments()`。
* 禁止依赖 target 创建顺序表达执行顺序。
* 禁止 step 函数偷偷创建主流程 target。
* 禁止 clear 函数删除 ctx 未记录的资源。
* 禁止在 function 文件中添加第四种 API 模式。
* 禁止英文日志和英文注释。
