跳转至
  • dsp_algo/modules/CMakeLists.txt(全新 · 顶层 modules/ 子目录聚合)
  • dsp_algo/modules/source/CMakeLists.txt(全新 · per-module STATIC)
  • dsp_algo/modules/sink/CMakeLists.txt(全新)
  • dsp_algo/modules/eq/CMakeLists.txt(全新)
  • dsp_algo/modules/dynamics/CMakeLists.txt(全新 · 若存在)
  • dsp_algo/modules/gain/CMakeLists.txt(全新 · 若存在)
  • dsp_algo/modules/<其他>/CMakeLists.txt(每 module 一份)
  • dsp_algo/CMakeLists.txt(改 · 顶层 add_subdirectory(modules) + DSPAlgo/DSPAlgoStatic 链接 per-module STATIC lib)
  • dsp_algo/tests/cmake_refactor/*(全新 · CMake 配置测试 + P/Invoke 回归) worktree: d:/work/25_claude/workspace/AlgoDepartment/04_development_branch_cmake_refactor/ branch: feature/cmake-per-module-phase1 occupies: [P6.K-modules-cmake(写), P6.K-toplevel-cmake(写), P6.K-tests(写)] adr: docs/08-implementation/40-aios/ADR/ADR-AIOS-09-plugin-architecture.md ref_section: §2.4 DSP 端 lib 打包机制 + §4.1 fork 2 + §3.2 负面后果"CMake 大重构" derived_from: ADR-AIOS-09 created: 2026-05-30 last_modified: 2026-05-30 12:14 dispatched_at: 2026-05-30 12:14 estimated: 3.0d unblocks:
  • P6.UA9-plugin-registry-static(plugin_registry_static.c 需 per-module STATIC 列表)
  • P6.UA9-cmake-per-module-refactor-phase2(thirdparty/ 子目录扩展需要本任务的 modules/ 拆分基础) related_zombie:
  • P5.U-meter-tap-multi-tool--48cf0ba(同 ClaudeB 模式参考) related_dispatched:
  • P6.UA9-plugin-abi-v1-design(同 P6 · 文件正交:plugin/ vs modules/CMakeLists.txt · 可并行 · 不强等其 zombie)
  • P5.UA9-plugin-registry-service(后端 · 文件完全正交)
  • P1.UA9-module-library-from-registry(前端 · 文件完全正交)

P6.UA9-cmake-per-module-refactor-phase1 · CMake per-module STATIC 拆分(ADR-AIOS-09 §2.4 fork)

Worker:TBD(用户分配 · isolation: 🚀 task · 独立 worktree + branch feature/cmake-per-module-phase1)· 部门:DSP (dsp_algo) 预计:3.0d · 优先级:P1(ADR-09 fork 3/7 前置)· 状态:dispatched 隔离:🚀 任务隔离(CMake 大重构 · 风险高 · 独立 worktree 防止破坏 xistudio)


🔍 触发与解锁链

触发 状态 影响
ADR-AIOS-09 accepted v1.1 ✅ 2026-05-30 09:18 8 fork 启动 · 用户拍板派首批 4 fork
.clinerules v1.4 §任务隔离类型分配准则 本 fork 标 isolation: task(CMake 重构破坏现有构建风险)
ADR §3.2 负面后果"CMake 大重构" ✅ 永久 缓解措施:分 Phase 拆 · Phase 1 仅 builtin 拆分(本任务)· Phase 2 第三方接入(fork 7)
与 P6.UA9-plugin-abi-v1-design 文件正交 plugin/ vs modules/CMakeLists.txt · 可并行 · 不强等 fork 1 zombie

→ 跨栈独立(纯 CMake + C 重构) · 不修改 contract-v1.0 · 不破坏现有 P/Invoke 接口(DSPAlgo SHARED 输出符号 100% 保持)。


任务定义(基于 ADR-AIOS-09 §2.4)

按 ADR-09 §2.4 DSP 端 lib 打包机制 · 把现有单 CMakeLists 拆分为: 1. dsp_algo/modules/CMakeLists.txt(顶层 modules/ 聚合 · 调用所有 per-module add_subdirectory) 2. dsp_algo/modules/<module-name>/CMakeLists.txt(每 module 独立 STATIC 库) 3. 顶层 dsp_algo/CMakeLists.txt 修改: - DSPAlgo SHARED target 改为 target_link_libraries 所有 per-module STATIC(替代现有 OBJECT 编译方式) - DSPAlgoStatic STATIC target 同样链接所有 per-module STATIC 4. CMake 配置测试 + P/Invoke 回归测试(确保 DSPAlgo.dll 导出符号未变 · C# 端 DllImport 零修改)

关键铁律(ADR §2.6): - builtin module 仍编译进主 DSPAlgo.dll(§2.6 #4 防御性 · 保证 host 最小可用集) - 不破坏现有 P/Invoke(§3.2 缓解 · 现有 C# 端零修改是验收硬标准) - DSPAlgoStatic 仍可编译(嵌入式固件用 · 不引入运行时加载)


完整 prompt(直接复制粘贴 worker 终端)

[U-thread]   P6.UA9-cmake-per-module-refactor-phase1(alias: P6.U-cmake-per-module-refactor-phase1)
[部门]       DSP (dsp_algo) · 推荐 skill: dsp-mixer-realtime-validation
[Worker CWD] d:/work/25_claude/workspace/AlgoDepartment/04_development_branch_cmake_refactor/(独立 worktree · 由用户配置 git worktree add)
[Branch]     feature/cmake-per-module-phase1(独立 branch · 任务隔离)
[Occupies]   P6.K-modules-cmake(写 · modules/ 子目录所有 CMakeLists) + P6.K-toplevel-cmake(写 · 顶层 dsp_algo/CMakeLists.txt 改造) + P6.K-tests(写 · CMake 配置测试 + P/Invoke 回归)
[隔离]       🚀 任务隔离(.clinerules v1.4 §任务隔离类型分配准则)· 独立 worktree + branch · 落地后走 PR 合并 xistudio
[优先级]     P1 · 3.0d · ADR-09 fork 3/7 前置 · 不破坏现有 P/Invoke(C# 端零修改)是硬标准
[ADR]        d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/ADR/ADR-AIOS-09-plugin-architecture.md(必读 §2.4 DSP 端 lib 打包机制 + §2.6 边界铁律 #4 + §3.2 负面后果"CMake 大重构" + §4.1 fork 2)
[业务行为契约引用] ADR-AIOS-09 §2.4 完整 CMake 重构方案(ADR line 248-293 给出代码示例)
[参考文档](绝对路径)
  - d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/ADR/ADR-AIOS-09-plugin-architecture.md(主 ADR · §2.4 必读 · 含 CMake 代码 line 248-293)
  - d:/work/25_claude/workspace/AlgoDepartment/04_development/dsp_algo/CMakeLists.txt(现有顶层 CMake · 全文必读 · 看 add_library SHARED/STATIC 双 target 现状)
  - d:/work/25_claude/workspace/AlgoDepartment/04_development/dsp_algo/modules/(列目录 · 看现有 module 全部子目录)
  - d:/work/25_claude/workspace/AlgoDepartment/04_development/dsp_algo/dll/dspalgo_dll.c(facade · 必须保留所有 __declspec(dllexport) 符号)
  - d:/work/25_claude/workspace/AlgoDepartment/04_development/backend_csharp/Interop/DspManifestInterop.cs(C# DllImport · 看哪些 C 函数被引用 · 这些不能被 CMake 重构破坏)
  - 上游 ADR:d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/ADR/ADR-AIOS-04-xiforge-architecture.md(§2.1.2 module UID · per-module CMake target 命名沿用)
  - contract-v1.0(已 frozen · 不改):d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/contracts/protocol-v1.md

【背景】
ADR-AIOS-09 accepted v1.1 · 议题 ⑥ 动态加载架构 · §2.4 DSP 端 lib 打包机制要求把现有单 CMakeLists 拆为 per-module STATIC + 顶层聚合。

🚨 **真值核查**(ADR §1.3):
- 当前 dsp_algo/CMakeLists.txt **单一根**(无子目录 CMake)
- 2 个 add_library target:DSPAlgo SHARED(L85)+ DSPAlgoStatic STATIC(L125)
- modules/source/sink/eq/... 全部源码 OBJECT 编译进单 dll
- 没有 per-module STATIC lib 拆分

**Phase 1 目标**(本任务范围):
- ✅ 拆分 builtin module(source / sink / eq / 其他存在的)为独立 STATIC lib
- ✅ 顶层 DSPAlgo SHARED + DSPAlgoStatic STATIC 改为 target_link_libraries(... <每个 per-module STATIC>)
- ✅ DSPAlgo.dll 导出符号 100% 保持(C# P/Invoke 零修改)
- ✅ DSPAlgoStatic 仍可编译(嵌入式固件用)
- ❌ 不实施 thirdparty/ 子目录(留 fork 7 phase2)
- ❌ 不实施 plugin_registry_static.c(留 fork 3)
- ❌ 不实施 plugin_loader_pc(留 fork 4)

**ADR §2.6 边界铁律**:
- #4 builtin module 仍编译进主 dll(本任务严守 · 不允许把 builtin 拆出可单独删除)

**P/Invoke 兼容铁律**(本任务硬验收):
- DSPAlgo.dll 导出符号清单不变(__declspec(dllexport) 函数名 + 签名)
- C# 端 DspManifestInterop.cs / 其他 DllImport 调用零修改
- 现有单测 + 集成测试全过(基线后端 147/0 不破)

【执行步骤】

Step 1 · git worktree 配置(用户预先做 · worker 接到 prompt 时已就位)
- 用户 cd d:/work/25_claude/workspace/AlgoDepartment/04_development/
- 用户 git worktree add ../04_development_branch_cmake_refactor feature/cmake-per-module-phase1
- 用户配置 worker cwd 到 04_development_branch_cmake_refactor/

Step 2 · read 已有基础(只读 · 必做)
- read ADR-AIOS-09 §2.4 全文(line 248-293 含完整 CMake 代码示例)+ §2.6 边界铁律 + §3.2 负面后果
- read dsp_algo/CMakeLists.txt 全文(看 SHARED/STATIC 双 target 现状 · sources 列表 · target_compile_definitions / target_include_directories)
- ls dsp_algo/modules/ 列出所有 module 子目录(source / sink / eq / dynamics / gain / 其他)
- read dsp_algo/modules/<每个>/(看每个 module 的源文件 + 头文件)
- read dsp_algo/dll/dspalgo_dll.c(看 facade 导出符号清单 · 这些符号必须保留)
- read backend_csharp/Interop/DspManifestInterop.cs(看 C# 端引用了哪些 C 函数)
- ⚠️ 不 read 任何 plugin/ 子目录(fork 1 拥有)

Step 3 · 起草 dsp_algo/modules/<module-name>/CMakeLists.txt(每 module 一份)
- 模板(对每个 module · 替换 <module-name>):
  ```cmake
  # dsp_algo/modules/source/CMakeLists.txt
  add_library(xisound-module-source STATIC
      source_module.c
      source_module_factory.c       # 若存在
      source_param_table.c          # 若存在
      # ... 该 module 的所有 .c 源文件
  )
  target_include_directories(xisound-module-source PUBLIC include)
  target_compile_definitions(xisound-module-source PRIVATE XISOUND_BUILTIN_PLUGIN=1)
  target_link_libraries(xisound-module-source PUBLIC xisound-plugin-abi)  # 若 fork 1 已合并 · 否则 PRIVATE 注释掉
  ```
- target 命名规范:`xisound-module-<lowercase-name>`(对齐 ADR §2.4 line 261)
- 把现有单 CMakeLists 中该 module 对应的 sources 字段抽出来 · 一字不漏迁移
- target_include_directories PUBLIC 暴露 include · 让顶层和其他 module 可引用
- ⚠️ 严禁修改任何 .c / .h 文件内容(本任务仅 CMake 重构)

Step 4 · 起草 dsp_algo/modules/CMakeLists.txt(顶层 modules/ 聚合)
- 模板:
  ```cmake
  # dsp_algo/modules/CMakeLists.txt
  add_subdirectory(source)
  add_subdirectory(sink)
  add_subdirectory(eq)
  add_subdirectory(dynamics)        # 若存在
  add_subdirectory(gain)            # 若存在
  # ... 所有 builtin module
  ```
- 不创建 modules/ INTERFACE / OBJECT 库(每 module 独立 STATIC)
- 顺序按字母排或按依赖顺序(若 module 间有 link 依赖)

Step 5 · 改造顶层 dsp_algo/CMakeLists.txt
- 在合适位置(L80 附近 · DSPAlgo target 之前)加 add_subdirectory(modules)
- DSPAlgo SHARED target(L85)改造:
  ```cmake
  # 旧(OBJECT 编译):
  add_library(DSPAlgo SHARED
      dll/dspalgo_dll.c
      modules/source/source_module.c   # OBJECT 编译
      modules/sink/sink_module.c
      # ... 大量 .c 文件直接列在这里
  )

  # 新(STATIC 链接):
  add_library(DSPAlgo SHARED
      dll/dspalgo_dll.c                # 仅保留 facade
      framework/dsp_engine.c           # 若存在
  )
  target_link_libraries(DSPAlgo PRIVATE
      xisound-module-source
      xisound-module-sink
      xisound-module-eq
      # ... 所有 per-module STATIC
  )
  ```
- DSPAlgoStatic STATIC target(L125)同样改造(把现有源码列表换成 target_link_libraries)
- ⚠️ 必须保留 WINDOWS_EXPORT_ALL_SYMBOLS / __declspec(dllexport) 行为 · 否则 P/Invoke 全断
- 若 fork 1(plugin_abi.h)已合并 · 加 target_link_libraries(... xisound-plugin-abi);若未合并 · 用注释 TODO 标记 · 等 fork 1 zombie 后补

Step 6 · 起草 dsp_algo/tests/cmake_refactor/* (CMake 配置测试 + P/Invoke 回归)
- test_export_symbols.ps1(或 .sh):
  ```
  # 用 dumpbin /exports DSPAlgo.dll(Windows)或 nm -D DSPAlgo.so(Linux)
  # 抓取所有 __declspec(dllexport) 符号
  # 对比基线(基线在 build/ 之外预存一份 expected_exports.txt)
  # 任何 missing / extra 即 fail
  ```
- 把当前 main xistudio 分支 build 出的 DSPAlgo.dll 导出符号 dumpbin 一次 · 保存 expected_exports.txt 作基线
- 本任务 build 后再次 dumpbin · 对比 · 必须 100% 一致
- test_per_module_target.cmake:CMake 配置阶段验证每个 xisound-module-<name> target 存在
- test_p_invoke_smoke.cs(C# · 可选):简单调用 DspManifestInterop.GetCurrentVersion 等 · 验证 dll 加载 + 符号可达

Step 7 · build + 测试 + 回归
- cd dsp_algo
- cmake -B build -DCMAKE_BUILD_TYPE=Release
- cmake --build build --target DSPAlgo DSPAlgoStatic
- ✓ 零错误零警告(若有警告必须解释 · 不允许 silently 接受)
- powershell -File tests/cmake_refactor/test_export_symbols.ps1 → 必须 PASS(导出符号 100% 一致)
- 切回主仓 backend_csharp(主 worktree · xistudio)· 用本任务 build 出的 DSPAlgo.dll 替换 · 跑后端测试:
  - cd ../04_development/backend_csharp
  - dotnet test → 基线 147/0 必须保持(P/Invoke 零修改)
- 若 backend_csharp 测试有任何 fail · 必须修(可能是符号缺失 / 签名变 / 路径错)
- 跑前端 e2e(若有用 dll 的)→ 验证

Step 8 · Commit + push(到 feature/cmake-per-module-phase1 branch)
- git status / git add dsp_algo/modules/ dsp_algo/CMakeLists.txt dsp_algo/tests/cmake_refactor/
- git commit -m "..."(见下)
- git push origin feature/cmake-per-module-phase1
- ⚠️ 不 merge 到 xistudio · 等用户走 PR 合并

【验收】

形式合规:
- cmake --build → ✓ 零错误零警告
- DSPAlgo.dll + DSPAlgoStatic.lib 都成功生成
- 导出符号对比 expected_exports.txt → 100% 一致(test_export_symbols.ps1 PASS)
- backend_csharp dotnet test → 147/0 全过(P/Invoke 零回归)
- N+2 文件落地(N = module 数 · 每 module 1 个 CMakeLists + 顶层 modules/CMakeLists.txt + 顶层 dsp_algo/CMakeLists.txt 改 + tests/cmake_refactor/*)

业务行为契约自查清单(ADR §2.4 + §2.6):
- [ ] ① 每 module 独立 STATIC lib(target 名 xisound-module-<name>)
- [ ] ② DSPAlgo SHARED 改为 target_link_libraries 链接所有 per-module STATIC
- [ ] ③ DSPAlgoStatic STATIC 同样改造(嵌入式固件可编译)
- [ ] ④ DSPAlgo.dll 导出符号 100% 保持(P/Invoke 零回归)
- [ ] ⑤ ADR §2.6 #4 验证:builtin module 仍编译进主 dll(没有"可单独删除"的 plugin · 全部静态链入)
- [ ] ⑥ 任何 .c / .h 文件零修改(本任务仅 CMake 重构 · 源码不动)
- [ ] ⑦ XISOUND_BUILTIN_PLUGIN=1 macro 设置在每个 per-module STATIC(便于 fork 3 plugin_registry_static 识别)
- [ ] ⑧ 若 fork 1 zombie · 链接 xisound-plugin-abi(fork 1 INTERFACE 库);否则 TODO 标记

【commit】
subject:`feat(P6.UA9-cmake-per-module-refactor-phase1): per-module STATIC lib split + toplevel link · ADR-09 §2.4 phase1 · P/Invoke zero regression`

trailer(必须精确):
[step=8/8] [pid=P6] [uid=UA9-cmake-per-module-refactor-phase1] [occupies=P6.K-modules-cmake+P6.K-toplevel-cmake+P6.K-tests]
[files=dsp_algo/modules/CMakeLists.txt, dsp_algo/modules/**/CMakeLists.txt, dsp_algo/CMakeLists.txt, dsp_algo/tests/cmake_refactor/**]
[isolation] task(独立 worktree 04_development_branch_cmake_refactor · branch feature/cmake-per-module-phase1 · 落盘后走 PR 合并)
[p-invoke-regression] DSPAlgo.dll exports 100% identical · backend_csharp 147/0 unchanged
[derived_from] ADR-AIOS-09 §2.4 fork 2

【禁止】
1. ❌ **不许在 xistudio 主分支直接 commit**(任务隔离 🚀 task · 必须独立 worktree + branch)
2. ❌ **不许修改任何 .c / .h 源码**(本任务仅 CMake 重构 · 源码动了 ABI 风险)
3. ❌ **不许改变 DSPAlgo.dll 导出符号**(P/Invoke 兼容铁律 · 任何 missing/extra 符号即 fail)
4. ❌ **不许动 plugin/ 子目录**(留 fork 1 P6.UA9-plugin-abi-v1-design)
5. ❌ **不许实施 thirdparty/ 子目录**(留 fork 7 phase2)
6. ❌ **不许实施 plugin_registry_static.c**(留 fork 3)
7. ❌ **不许实施 plugin_loader_pc**(留 fork 4)
8. ❌ **不许动 backend_csharp/ 或 frontend_vue3/ 任何文件**(P5/P1 fork 拥有)
9. ❌ **不许把 builtin module 拆成可单独删除的 plugin**(ADR §2.6 #4 · builtin 仍编译进主 dll)
10. ❌ **不许跳验收**(cmake build / 导出符号对比 / backend_csharp 147/0 任一红必须修到全绿)
11. ❌ **不许省略三元组 trailer**(含 [isolation] + [p-invoke-regression] 特殊标记)
12. ❌ **不许自改本 prompt 文件**

解锁链(本任务 zombie 后)

  • fork 3 P6.UA9-plugin-registry-static 解锁(plugin_registry_static.c 需 per-module STATIC 列表 · 本任务 CMake 拆分提供基础)
  • fork 7 P6.UA9-cmake-per-module-refactor-phase2 解锁(thirdparty/ 子目录扩展继承本任务 modules/ 结构)
  • ✅ ADR-09 §2.4 DSP 端 lib 打包机制基础就位 · 后续 builtin module 维护单独可测试 / 复用 / 维护
  • ✅ 给嵌入式 DSP 固件(SHARC / Hexagon)提供 per-module STATIC 库基础(每个 module 可独立链接到固件总包)

风险评估

风险 缓解
⚠️ DSPAlgo.dll 导出符号意外丢失(__declspec(dllexport)) step 7 强制 dumpbin 对比 expected_exports.txt · 100% 一致才允许 push
⚠️ backend_csharp dotnet test 因 P/Invoke 失败 step 7 强制跑 backend_csharp 全测试 · 147/0 是硬验收
⚠️ CMake target 链接顺序循环依赖 per-module 间假设无相互依赖(若有 · 加 PUBLIC link · 让 CMake 自动解析)
⚠️ DSPAlgoStatic 嵌入式工具链编译失败 step 7 验证 DSPAlgoStatic 也能 build · 若工具链不支持 STATIC link 多个 STATIC · 需调研
⚠️ 与 fork 1 plugin_abi.h 集成时机冲突 fork 1 INTERFACE 库不强依赖 · 若 fork 1 zombie 在前 · 直接链接;否则 TODO 注释
⚠️ 第三方 module(若混在 modules/ 下)被误拆 step 2 严格列目录 · 若发现 thirdparty 痕迹 · 留给 fork 7 不动
⚠️ worktree 配置错误 step 1 强制用户预配置

历史

时间 事件 hash
2026-05-30 12:14 dispatched · ADR-09 4 fork 首批派发(B 方向 · fork 2 与 fork 1 文件正交并行)· UID v1.4 命名 P6.UA9 · isolation: task 独立 worktree