Skip to content

Latest commit

 

History

History
1103 lines (840 loc) · 73.4 KB

File metadata and controls

1103 lines (840 loc) · 73.4 KB

Changelog

本文件追踪 mcpp-community/mcpp 公开仓的版本演进。 格式参考 Keep a Changelog

[0.0.101] — 2026-07-20

#253:feature 模型两缺口收口——per-feature per-glob flags + per-OS features 语义锁定,解锁 compat.opencv dnn off-linux 腿并消除 feature-off 构建的死 glob 告警。设计见 .agents/docs/2026-07-20-issue-253-feature-flags-and-per-os-features-design.md

新增

  • features.<name>.flags(#253):feature 级 per-glob 编译旗标,与 [build].flags 共用同一 entry 文法(glob 必填 + cflags/cxxflags/asmflags/defines),xpkg 与 mcpp.toml 双文法一数据模型(共享解析 helper)。激活时折入既有 globFlags 单一漏斗(scanner 匹配/per-TU 落旗标/死 glob 告警/fingerprint 四个下游零改动),追加在 base 规则之后、feature 按名序,"last flag wins" 使 feature 规则可覆盖 base;折入点在 includeDevDeps 门外(0.0.94 双路径不变量)。私有 per-TU、不传播(与接口开关 defines 的语义分界)。feature off 时规则不存在 → opencv mlas 一类"结构性必死 glob"的告警自然消失;feature on 而 glob 空仍告警,且文案点名归属 feature(features.<f>.flags glob '...' matched no source file)。TOML 侧 [[features.<name>.flags]] AOT 拼写同步进 #227 封闭文法 allowlist(features.*.flags 通配段)。
  • per-OS features 语义锁定(#253):mcpp.<os> 段的文本拼接 additive overlay 本就覆盖 features 键——同名 feature 逐子键 append(中性段在前、OS 段在后),per-OS 段可注册 OS-only feature;现以单测(逐 OS osOverride)+ e2e 锁死并写入文档,配合 features.<f>.flags 构成 opencv dnn 的 common/delta 形态(中性段放跨平台公共载荷,per-OS 段放 mlas x86 / NEON 差集与其旗标)。

修复

  • 依赖包 per-glob flags 此前不入 per-package fingerprint:canonical_package_build_metadata 只序列化 cflags/cxxflags/ldflags/genfiles,globFlags 靠"descriptor 随版本冻结"间接成立;feature 折入使该向量随构建变化,现与根侧同款全量有序序列化(globflags:/gc:/gxx:/gas:/gd:)。

备注

  • e2e 新增 146(feature flags 四象限 + 死 glob 告警消除/点名 + 私有不传播对照)/147(per-OS features 端到端,宿主段生效、非宿主段投毒不可见);单测新增 xpkg/TOML 解析与 per-OS 合并锁定。host/target 轴缺陷(per-OS 拼接键=宿主常量,交叉编译选段错误)另开 issue 跟踪,不入本版。

[0.0.100] — 2026-07-19

大型源码直编包(ffmpeg/opencv 级,数千 TU)全平台化批次:#247/#248/#249 平台三修 + 增量构建修复 + build.mcpp 指令面补全(P1)。设计见 .agents/docs/2026-07-19-large-source-pkg-platform-fixes-and-buildmcpp-generation-design.md

修复

  • windows driver-style 链接命令行溢出(#247):gnu 方言(g++/clang++ 作链接驱动——windows 托管 clang-MSVC 即此)的 cxx_link/cxx_archive/cxx_shared 此前内联 $in,数千对象直接溢出 CreateProcess 32 KiB 上限。现 windows 上 driver-style 也走 response file;两方言分支收敛为单一 link_rule 发射器(msvc 规则文本逐字节不变),POSIX 保持内联零变化。配套:ninja 节点名统一 generic_string() 正斜杠——rsp 内容按 GNU 文法分词,反斜杠是转义符(obj\cli.o 会被吃成 objcli.o)。
  • macOS dep/root build.mcpp 收不到 G3 契约环境(#248,launcher-unify):非 Linux 的 capture_exec 走 shell 字符串拼接,ENV… cd <cwd> && bin 里 env 只绑给 cd(全仓唯一 env+cwd 双非空调用点恰是 build.mcpp)。现 macOS 与 Linux 同走 posix_spawn 直启路径(child-only env + addchdir_np,environ_NSGetEnviron() portable-correct),顺带消掉 macOS 的 shell quoting/注入面。windows shell 回退补 cd /d(跨盘符)。
  • generated_files 每次构建无条件重写毁增量:materialize 此前不比内容直接写,mtime 抖动令 ninja 把 include 该头的全部 TU 判脏——冻结快照包(config.h × 数千 TU)每次 build 都全量重编。现内容逐字节相同即跳写(变更检测本就由指纹负责)。
  • xpkg feature 表未知子键(如 features.X.include_dirs)此前静默吞掉,现进 xpkgUnknownKeys 走统一告警面。

新增

  • [build] include_dirs_after-idirafter(#249):排在工具链系统目录之后搜索的 include 目录(descriptor/xpkg 与 mcpp.toml 双文法、* tarball 根 glob、沿 Public/Interface 边传播且不升级为 -I)。治大小写不敏感 macOS 上依赖源根 VERSION 顶替 libc++ <version> 一类系统头遮蔽;-isystem 不解此症(仍先于默认系统目录)。方言降级单点收敛:cl.exe → 末尾 /I,NASM 单元 → 普通 -I(NASM 会把 -idirafter<p> 误吞成 -i dirafter<p>)。附带统一主工程 include 路径的 glob 展开(此前与 dep 路径两套推导)。
  • build.mcpp 指令面补全(P1,0.0.100+):mcpp:source=(选既有 payload 源入编译集,generated= 的"绝对路径灰色用法"正名)、mcpp:include-dir= / mcpp:include-dir-after=(私有 include,Cargo 纪律不进公共接口;typed 通道享方言降级);typed import mcpp; 同步 source()/include_dir()/include_dir_after()。契约环境拆分 MCPP_TARGET_OS/ARCH/ENV(免手撕三元组)。root build.mcpp 后移至依赖解析之后,与 dep 一样拿到 MCPP_DEP_<NAME>_DIR;指令落通道收敛为 root/dep 共享的单一 fold(防"同一决策两处推导")。顺修:root build.mcpp 变更此前被整库 fast-path 吞掉不触发重跑。
  • mcpp xpkg parse --all-os:按 xpm 声明的平台集逐 OS 校验 per-OS 段(构建路径只 splice 宿主段,windows 段的 typo 在 linux CI 上原本不可见);mcpp-index CI 可单 runner lint 多平台描述符。

备注

  • e2e 新增 141–145(-idirafter 语义/增量跳写/source= /include-dir/root dep-dirs);linux 全量 e2e 134 过(3 项为既知环境性失败)。macOS/windows 断面由平台 CI 与 mcpp-index spike 复现件(PR#89/90/91)收口。

[0.0.99] — 2026-07-19

#230–#243 批次收尾:#243 feature 转发落地(0.0.98 只出了设计)+ #238 根因修复随 xlings 0.4.67 vendored 入包 + #230 windows build.mcpp 次生面补齐。设计见 .agents/docs/2026-07-19-v0.0.99-feature-forwarding-238-230-design.md

新增

  • feature 依赖 feature 转发 dep/feat(#243,Cargo 平价):[features] 里含 / 的 token(或表格形专用 forward = ["dep/feat"] 键)表示"本包该 feature 激活时,顺带打开依赖 depfeat feature"——一个 feature 既能本地拉源、又能开依赖的重档 feature,解阻塞模块包的可选模块接口(opencv-m 的 import opencv.dnn;:dnn 一档同时拉 dnn.cppm 源集并把 compat.opencvfeatures=["dnn"] 参与构建,而非对所有消费者全量 +309 TU)。收敛为一数据模型 featureForwards 两文法(TOML 与 xpkg 描述符共享唯一切分点 split_feature_forward_token);转发注入 0.0.98 既有的 aggregatedRequest 依赖边漏斗(在子依赖 push 进 worklist 前把转发 feature 并入其请求集),一处注入同时覆盖解析(mergeActiveFeatureDeps 拉被转发 feature 的条件依赖)与激活(边图 union → apply() 发宏/源集)两个消费点;沿 BFS 前向边天然传递(root→mid→leaf)。与 #242 default-features = false 加性组合(转发进显式请求集、不受默认门控影响),mcpp build/mcpp test 双路径一致。转发到未声明依赖 strict 报错 / 非 strict 告警;转发未声明的依赖 feature 复用既有 "does not declare requested feature" 门。单测 3 例、e2e 128(含双路径)。

修复

  • ≥2 项目级 index_repo 时 install_packages 静默失败(#238,根因修复上游落地):vendored xlings 由 0.4.62 升至 0.4.67,携 openxlings/xlings#374 的多仓安装修复(fix(xim): surface multi-repo install failures + best-effort catalog,commit cf9b60d5)。此前 workspace 根级 [indices] 继承(#224)× default 重定向(R6)组合会给每个成员播下 ≥2 个 index_repos,任一未缓存包安装裸 exit 1 无 error 事件;0.0.98 已在 mcpp 侧把它变成可操作诊断,0.0.99 随 bundle 带上真正的解析修复。发布/交叉构建/e2e 三处 workflow pin 同步 0.4.67。
  • windows 下依赖/成员 build.mcpp 产物名缺 .exe 无法执行(#230 次生面):build.mcpp 编出的宿主程序此前恒名 build.mcpp.bin;windows 的 capture_exec 走 cmd.exe,.bin 不在 PATHEXT 故无法按名启动 PE。现按平台取后缀(windows=build.mcpp.exe,其余保持 .bin,is_windows 为 constexpr,非 windows 字节不变)。此面在 0.0.96 的 scanner symlink-逃逸崩溃(df985df,裸 127 的真凶)修复后才会被 workspace 的 build-mcpp 成员在 windows 走到。

备注

  • #230 主因(scanner glob 顺 .mcpp/.xlings symlink 逃逸进 vendored 索引、CJK 文件名触发 MSVC 窄串转换抛异常→__fastfail→裸 127)已于 0.0.96 根治并在 0.0.98/0.0.99 在库;src/main.cpp 顶层 catch 兜底(未捕获异常→exit 70,不再裸 127)。0.0.99 补齐 build.mcpp 次生面后,mcpp-index 的 workspace(windows)CI 从临时钉回的 0.0.94 升到 0.0.99 复验全绿即关闭。

[0.0.98] — 2026-07-19

#230–#243 批次(单 PR 统一发布,逐 commit):#233 对象路径消歧的两个后续缺口(#239/#240,解阻塞 mcpplibs #79 opencv 收录)+ #237/#241/#242 根因级实现 + #238 mcpp 侧诊断(根因在 openxlings/xlings#374)+ #243 设计。总账 + 架构评估见 .agents/docs/2026-07-19-issues-230-243-batch-ledger-and-architecture-assessment.md;各设计文档见 .agents/docs/2026-07-19-*

新增

  • MCPP_DEP_<NAME>_DIR build.mcpp 契约(#241):包的 build.mcpp 现可经 mcpp::dep_dir("<name>") 拿到依赖的安装目录(verdir/payload 根),不必再逆向 store 布局(实例:compat.opencv 的 unifont feature 读数据资产包 compat.opencv-unifont 的字体 blob)。用权威的 consumer→dep 边图注入,覆盖 feature 激活的依赖;canonical + short 双发(dep_dir("compat.zlib")/dep_dir("zlib") 皆可)、同款 sanitize、碰撞守卫、自动进 rerun hash。作用域为依赖侧 build.mcpp(root 工程 build.mcpp 早于依赖解析运行,列为后续项)。
  • 消费端 default-features = false(#242):依赖 spec 支持关闭该依赖的默认 feature 集({ default-features = false, features = ["x"] }),Cargo 平价。根因收敛在 feature_closure 的单一 seedDefault 门:关闭时不 seed 该依赖 [features].default,仅显式请求 + implies 激活;root 包/工程 build.mcpp 仍默认 seed。(挡住 compat.ffmpeg 裁剪档形态。)

修复

  • 消歧后链接输入未跟随改名,依赖与消费者同名源即挂(#240):当依赖包与消费者存在同名源(近乎必现——双方都有 src/main.cpp,如 OpenCV 自带的 sample main.cpp × 消费者的入口)时,#233 已把被扫描的消费者 main 编到 obj/<pkg>/src/main.o,但链接步骤仍引用消歧前的扁平 obj/main.oninja: error: 'obj/main.o' … missing and no known rule。现将对象路径分配收敛为单一来源:被 glob 进来的入口复用其编译边已消歧的对象;未被 glob 的入口也纳入同一碰撞普查后消歧——链接输入与编译边永不背离。常见单二进制工程(main 唯一)仍为扁平 obj/main.o,字节不变。
  • 绝对/越根路径源的消歧对象逃逸出 obj/(#239):依赖 build.mcpp 写进 OUT_DIR(target/.build-mcpp/deps/<name>@<ver>/out/,在包根之外)的生成源,其 relPath 携带 ..,#233 曾原样拼进 obj/<pkg>/../… 致对象路径爬出构建树(甚至在 CWD 镜像整棵绝对路径树);且路径里的 @ 会被 ninja 单引号包裹,连带压垮 #235 的 "$out.d" depfile 重定向。现消歧前缀逐分量净化:去绝对根、. 丢弃、..__up、非可移植字符(如 @)→_——对象永远向下且 shell 安全;逐分量单射,保住 #233 的唯一性(L1b 断言兜底残余)。
  • xpkg 描述符 mcpp 段未知键 build 时静默忽略(#237):dependencies 误写(正确键 deps)等未知键此前只有 mcpp xpkg parse 报,build 路径静默丢弃致依赖消失无诊断。现描述符被采纳为依赖时按键响亮告警并给 did-you-mean(封闭词表别名 + Levenshtein 回退);沿用 0.0.97 封闭文法先例,告警而非硬错以保前向兼容。
  • feature 请求集收敛到依赖边图(#242 传递边 + #241 命名;架构评估头号优化):此前 feature 请求集在解析(mergeActiveFeatureDeps,读 per-edge spec)与激活(apply(),只扫 root 直接依赖)两处独立推导且对传递边不自洽——传递依赖的请求 feature 与其消费者的 default-features = false 被静默丢弃(激活仍 seed 该依赖默认 feature,定义其宏/保留默认门控源,而解析已跳过)。现 DependencyEdge 携带 per-edge requestedFeatures + defaultFeatures,新 aggregatedRequest 对某依赖包所有入边做 union/OR(Cargo 菱形语义),激活与依赖 build.mcpp 共享之;直接依赖行为不变,顺带补掉长期的传递 feature 未传播缺口。e2e 127。
  • 多 index repo 下 install_packages 失败无诊断(#238,根因在 xlings):裸 fetch failed (exit 1) 现重建为可操作诊断——点名目标、已配置 index repos 清单、≥2 仓的已知 xlings 解析缺口提示、保留子进程输出、MCPP_VERBOSE=1 看原始调用。仅诊断改进;多仓解析的根因修复须落在 openxlings/xlings(已开 openxlings/xlings#374)。

设计(未实现,后续 PR)

  • #243 feature 依赖转发(dep/feat):核实条件依赖半边已存在([feature-deps]/xpkg features.x.deps),真正缺口是转发;设计见 .agents/docs/2026-07-19-issue-243-feature-forwarding-design.md,收敛为单一 per-package 请求 feature 漏斗(顺带补 prepare.cppm:2653 传递性缺口),与 #242 opt-out 加性组合。

备注

  • #230(windows workspace exit 127)已于 0.0.96 修复,待 mcpp-index windows CI pin ≥0.0.98 复验后关闭。

[0.0.97] — 2026-07-18

架构级修复批次(单 PR,逐簇 commit):ffmpeg-m/opencv-m 全源码直编暴露的第二层缺口 + workspace 测试基建语法空洞。

新增

  • [[build.flags]] 数组表写法(#227):[build].flags 现同时接受 TOML 标准数组表 [[build.flags]] 与内联表数组两种等价写法(声明顺序=应用顺序不变),长 per-glob flags 条目不再挤单行。纯解析层扩展(自研 TOML parser 补全 array-of-tables);并加清单层 closed-grammar 守卫——非白名单段落误写 [[x]](如 [[dependencies]] 手滑)现硬报错而非静默丢数据。
  • glob 花括号交替 {a,b}(#228):sources/flags glob 支持 libavcodec/{aac,bsf,hevc}/** 笛卡尔展开(嵌套/多组均可),vendored 大库 per-glob 声明不再重复。
  • 默认命名空间索引重定向(R6):[indices] default = { path = "..." }(亦接受空引号键 "")可把默认命名空间(namespace = "" 的模块包)指向本地 checkout,补上此前只能重定向具名命名空间的语法空洞——使 index 仓能以 mcpp test --workspace 声明式验证 imgui/ffmpeg/opencv 等模块包,替代逐包 smoke shell。(url 形式的默认命名空间重定向暂不支持,解析期显式报错而非静默失效。)
  • mcpp run -p <member>:run 命令支持选择 workspace 成员并运行其二进制(与 build/test-p 对齐)。

修复

  • 源发现全树遍历致 mcpp run 前慢 + 缓存复用(#225):glob 遍历改从字面前缀起(src/**src/ 起走,不再从项目根扫全树),并排除 .git/target/git 子模块边界;mcpp run 复用 mcpp build 已解析的缓存,不再每次重扫大子模块(此前含大 compat/ 子模块时每次 ~9.5s)。
  • 相对 include 族 flag 未按项目根重写 + 含空格值未转义(#226 #234):-iquote/-isystem/-idirafter/-iprefix/-L 现与 -I 一样按项目根绝对化(joined 与 separated 两拼写);defines = ["T=long long"] 等含空格值发射时 shell 引号保护,不再被拆成孤立参数。含 [build] include_dirs 在 MSVC 方言下的相对路径绝对化亦一并修正。
  • 对象路径按父目录名折叠致同名源冲突(#233):不同目录同名源(a/src/util.cpp vs b/src/util.cpp,OpenCV/LLVM 式 modules/<mod>/src/* 布局)对象路径改按碰撞时镜像源相对路径消歧 + 构建后唯一性断言;非碰撞项路径字节不变。
  • 模块 purview 内文本 #include 改动不触发重编(#235):编译边补 depfile 追踪(过滤 GCC -fmodules 注入的反向规则以规避 ninja inputs may not also have inputs),purview/GMF/普通头改动均正确触发重编——顺带根治此前非 MSVC 下普通头改动也不重编的潜伏问题。
  • 依赖包 cfg 条件 sources 被消费时不展开(#229):path/git 依赖的 [target.'cfg(...)'.build].sources 现与 root/version-dep 同样按已解析 target 求值(mcpp buildmcpp test 双路径),不再 undefined reference(与 #218 同类,收敛为统一 per-package 求值)。
  • nasm 冷环境惰性自举时序(#232):nasm 供给改走工具链同款同步门 Fetcher::resolve_xpkg_path("xim:nasm@3.02", autoInstall=true)(索引刷新前置 + 硬报错 + payload 校验),不再先判死后台补装;config 自举错误不再被 if(cfg) 门吞成误导性的 "no usable nasm"。
  • workspace 根配置无法一次声明全员可用(#224):[workspace.dependencies] 的 path 依赖可被成员经 .workspace = true 继承;根 [indices] 的相对 pathworkspace 根解析(而非消费成员目录),成员不再需重复声明各自 ../ 相对路径。

备注

  • #230(windows workspace 崩溃)已于 0.0.96 修复。#215(cppfly Clang 反射行)待上游 Clang 落地 P2996,不排期。

[0.0.96] — 2026-07-18

修复

  • [windows] mcpp test --workspace 静默崩溃(裸 exit 127,实为 0xC0000409) (#230,修复 #231)。三层根因:
    1. 0.0.95 扫描器的 glob walk 新增 follow_directory_symlink,而项目本地 .mcpp/.xlings/data/<index> 是指回索引根的符号链接 → walk 逃逸出成员 目录、扫遍整个索引 checkout(CI 里含 vendored xim-pkgindex);
    2. path_matches_globgeneric_string() 拼窄串,MSVC 在非 CJK ANSI 代码页 (runner ACP=1252)下遇到中文文件名 bug-report---问题反馈.mdstd::system_error;
    3. 异常逃出 main 未捕获 → std::terminate__fastfail(0xC0000409), git-bash 显示为无任何输出的 exit 127。
    • 修复:expand_glob/expand_dir_glob 按名剪枝 .mcpp 目录(mcpp 自身 元数据目录永远不是源码目录,从源头切断符号链接逃逸,顺带避免每个成员把 整个索引树白走一遍);path_matches_glob 对无法窄化的文件名按"不匹配" 跳过而不是摧毁构建;main() 增加最后防线 catch,逃逸异常打印真实错误并 以 70 退出,不再静默 fastfail。
    • 取证:runner 开 WER 全内存 dump,崩溃栈+被转换字符串逐帧还原(记录见 mcpplibs/mcpp-index debug/mcpp230-windows-repro 分支及 #230)。
    • 回归测试:tests/e2e/113_scanner_mcpp_dir_prune.sh(.mcpp 符号链接逃逸 必须被剪枝;CJK 文件名不得致命)。linux 行为对照:0.0.95 会顺着该符号链接 把项目外源码编进来(链接期 duplicate main),修复后构建干净。

[0.0.95] — 2026-07-17

  • 见 GitHub Release v0.0.95:声明式清单能力(features.sources / generated_files / cfg 条件 sources / per-glob flags,#223)、汇编源一等公民(.S/.s/.asm 进 sources,NASM 按目标推导 -f,#220)、build.mcpp 补全(环境契约 + cross 下 运行 + 依赖包执行,#222)。 已知问题:#230(本版 windows workspace 崩溃,0.0.96 修复)、#232(冷环境 xim:nasm 自举产出空载荷,待修)。

[0.0.94] — 2026-07-15

修复

  • 依赖包被激活 feature 的 sourcesmcpp test 下不编译prepare_build() 把 feature 源集解析(drop + add)整段门在 !includeDevDeps,而 mcpp testincludeDevDeps = true → 激活 feature 的 sources 从不被加回构建图。 descriptor 若把某个 glob 写在 features 下(xpkg 的 features.X.sources 只落进 featureSources、从不进 base sources),该包在 mcpp build 下正常、 在 mcpp test 下必然链接失败(undefined reference)。
    • 命中面:compat.cjsonutils(cJSONUtils_*)、compat.eigeneigen_blas(dgemm_)、compat.spdlogcompiled
    • eigen_blasdgemm_ 一直被记为「把 feature 编出的依赖目标链进 test 二进制是 follow-up」——定性是错的:不是链接问题,是源集解析问题。
    • 修复:drop 仍只在 build 模式做(mcpp test 需要保留完整源面,让 dev-dep 轨的 per-test main 检测看得见 gtest_main.cc 并逐 test 剪枝——见 tests/e2e/79_gtest_regular_dep_feature_main.sh);add 改为两模式都做, 并去重,使 gtest 那种 base/feature 双列的 glob 不会进两次。
    • 回归测试:tests/e2e/100_feature_sources_test_mode.sh(cjson utilsmcpp test 下必须编译并链接;mcpp build 仍正常;不请求 feature 时 gated 源仍被排除)。

[0.0.93] — 2026-07-15

变更(命名统一,全部旧拼写永久兼容)

  • 工具链 × 目标 命名统一 —— 二轴身份模型。toolchain = family@version (family 只剩 gcc | llvm | msvc),target = mcpp 自有三段 triple arch-os[-env](Zig 式砍 vendor)。变体(gnu/musl/msvc)进 triple env 段, "cross"/"musl"/"mingw" 不再是工具链名字——mingw-cross 16.1.0 的本体是 gcc@16.1.0 → x86_64-windows-gnu,交叉只是 host≠target 的关系。业界对照 (rustup 零 "cross" 命名/Zig 三段 triple/musl.cc 分发层先例)与决策记录见 .agents/docs/2026-07-15-toolchain-target-naming-unification-design.md
    • canonical triple:x86_64-windows-gnu 为正典(D1);GNU 拼写 x86_64-w64-mingw32 及 4 段 Rust 拼写为永久别名,归一后进同一 target/<canonical>/ 目录(同一构建缓存)。macOS 产物目录随 canonical 变为 aarch64-macos
    • --target 封闭词汇表校验:打错字硬错 + did-you-mean (did you mean 'x86_64-linux-musl'?),不再静默 fall through 编成宿主产物 (最坏失败模式根治);自定义 triple 走显式 [target.X] 节逃生舱;planned 档位(riscv64 等)报「registered but not yet supported」。两条硬编码约定 (*-muslx86_64-w64-mingw32)改为词汇表数据行(pin + 默认 static)。
    • 单一 triple 解析器 triple.cppm:cfgpred/abi/model 谓词/registry 四处 平行解析收敛;abi 的 os 维 darwinmacos(与 cfg 词汇分叉消灭, darwin/arm64 作为约束别名接受)。
    • compat.cppm 兼容层:唯一知道旧拼写的文件(musl-gcc/gcc@V-musl/ -gcc/mingw/mingw-cross/clang),归一 + 单行 note: 提示;xim 分发包名 (mingw-cross-gcc 等)不动——"cross" 在分发层合法(musl.cc/Debian 先例)。
    • CLI 单名词 + --target 选项(D4,不设 mcpp target 子命令): toolchain install [gcc 16] --target <triple>(family 可省→约定 pin)、 toolchain default gcc@16 --target <triple>(默认变 pair,持久化 default + default_target 两键)、toolchain remove … --target <triple>; 主路径仍是 mcpp build --target <triple> 自动装链(零仪式)。
    • [build] target = "<triple>" 新 manifest 键(≙ cargo build.target): 「默认全静态 musl」的正确归宿(产物属性,非编译器家族属性);优先级 --target flag > [build] target > 全局 default_target > host。
    • toolchain list 两轴重排:Toolchains 块(family@version)+ Targets 块 (target × 状态 installed/available/planned,planned 行使词汇表用户可见); 修版本字典序排序 bug(9.4.0 不再排在 15.1.0 前);gcc X-musl 行不再被 llvm 劈开。README 平台表从词汇表重画(target × tier 维度,补 MSVC=✅ 与 windows-gnu 行——旧表 MSVC 仍标 planned 是错的)。
    • 修 Windows host 上 mingw 的门:Linux 上 toolchain install mingw 现在 合法(= 装交叉 payload,同一身份 host 分流);mcpp run 位置参数 help 改为 「Binary name」消除与 --target 的语义撞名。
    • 验证:单测 35(新增 triple/compat 套件);e2e 新增 103(typo/planned/逃生舱/ [build] target/别名同目录)、102 双拼写断言;本机实测双拼写同 Resolved 行+同缓存(alias 二跑 0.07s 全命中)、PE wine 真跑、musl 静态链、typo did-you-mean。

[0.0.92] — 2026-07-15

新增

  • Linux → Windows MinGW-w64 交叉工具链(mingw-cross)—— host≠target 一等公民。 在 Linux 主机上交叉编译出 Windows x86_64 PE,含 import std。补 0.0.89 msvc-mingw-design §4.4/§7 登记的延期项(交叉维:host≠target)。
    • 工具链:从源码构建的 GCC 16.1.0 mingw-w64 MSVCRT 交叉链(triple x86_64-w64-mingw32,跟随 Rust Tier-1 x86_64-pc-windows-gnu 的 CRT 选型); 自包含(自带 binutils/CRT/libstdc++ 含 bits/std.cc + libstdc++exp); 发布于 xlings-res/mingw-cross-gcc(GitHub+GitCode)+ xim-pkgindex
    • mcpp 侧:用户名 mingw-cross → xim mingw-cross-gcc(前端 x86_64-w64-mingw32-g++);解除 MinGW 的 Windows-host 门(Linux 主机可装,native mingw 仍 Windows-only);--target x86_64-w64-mingw32 约定解析(默认 static); 跳过 glibc/linux-headers(PE 自带 CRT)。
    • host≠target 化:PE 产物形态判断一律按 target 而非 host constexpr——std 模块源 探测补 <prefix>/<triple>/include/c++/ 子目录;自包含工具链跳过外部 binutils -B (musl + mingw);MinGW link 分支(-static / -lstdc++exp)由 if constexpr(is_windows) host 门提为运行期 is_mingw_target target 判定。
    • 验证:e2e 102_mingw_cross_wine.sh(# requires: mingw-cross wine,build --target → PE 静态自包含断言 → wine 跑 import std + 多模块);CI cross-build-test.ymlmingw-cross-wine job(OS-cross,wine)。全链实测闭环(install→build→wine)。
    • 设计:.agents/docs/2026-07-15-mingw-linux-cross-windows-design.md

[0.0.91] — 2026-07-15

新增

  • standard = "c++fly" — 一行启用"最新标准 + 全部实验特性"(语言 + 标准库)。 语义三件套,全部按 resolved 工具链自动判定:①族最新 -std= 档位(GCC16→c++26、 Clang→c++2c、MSVC→/std:c++latest);②该工具链支持的全部实验性语言特性门 (GCC≥16:反射 -freflection;契约随 -std=c++26 默认启用,实机探测定案); ③标准库实验门(libc++→-fexperimental-library)。不支持的特性软跳过并打印 summary(c++fly on <toolchain>: <std>; enabled: ...; skipped: ...)。 新模块 src/toolchain/cppfly.cppm 承载三张数据表(族×版本×stdlib)——首个真正 使用 Toolchain::version 做门控的查询点;产物汇入 0.0.90 的图全局方言旗标通道 (全图 TU + P1689 扫描 + std BMI 预构建同源),派生旗标并入指纹。 设计:.agents/docs/2026-07-14-std-features-experimental-gate-design.md。 e2e 100(gcc16 硬路径:零手写旗标跑通 std::meta 反射)/ 101(clang 软路径: c++2c + skipped summary)。

修复

  • standard = "c++latest" 在 GNU 族误拼 -std=c++latest(GCC/Clang 不识别, 构建必败):canonical 现经 cppfly 的"族最新档"表解析为真实档位(GCC16→ -std=c++26)。e2e 100 尾段回归覆盖。

[0.0.90] — 2026-07-13

新增

  • MSVC 原生构建后端(cl.exe)落地,0.0.88 的构建门移除。选定 msvc@systemmcpp build/run 直接用系统 MSVC 编译链接:
    • 环境模型:find_windows_sdk() + 从检测到的 VC tools/SDK 直接合成 INCLUDE/LIB/PATH(+VSLANG=1033),不跑 vcvarsall;SDK 缺失时检测/选择仍可用, 构建报带指引的明确错误;doctor 新增 SDK 与 mingw 检查行。
    • 模块管线:std/std.compat.ixx 单命令 staging(/ifcOutput → ifc.cache), 命名模块 .cppm/interface /TP 编译、/ifcSearchDir 消费; /scanDependencies 作为第三个编译器内建 P1689 扫描驱动接入 dyndep。
    • 链接:link.exe/lib.exe(SeparateLinker)+ 响应文件(绕 cmd 8191 限制), DLL=/DLL /IMPLIB:;deps=msvc(/showIncludes)头文件依赖;/MD|/MT CRT 随 linkage;/std:c++20|c++latest 映射;.obj 扩展名全链路。
    • fast-path 增量:构建缓存 env 槽新增 @env 多变量编码,增量构建重建 INCLUDE/LIB 环境。e2e 99(模块/import std/增量)+ 95 改造为真实构建断言。
  • [build] dialect_cxxflags + 方言旗标全图化(issue #210 修复)-freflection 等"改变标准库头声明集"的 flag 现随 -std= 的通道到达: 全局 cxxflags(项目+依赖所有 TU)、std/std.compat BMI 预构建命令、P1689 扫描。 known-list 自动提升(reflection/contracts/char8_t/_GLIBCXX_USE_CXX11_ABI)+ 显式 dialect_cxxflags 逃生舱;指纹早已包含这些 flag,修的是命令构造。 实证:#210 的最小复现(gcc16 + import std; + std::meta)输出 x 2/y 3; e2e 98 含依赖模块变体。

修复与优化

  • mingw 在非 Windows 主机的 toolchain install/default 现在明确报 windows-only(此前是 invalid xpkg target 'xim:mingw-gcc@')。
  • std 模块 staging 命令在 Windows 用 cd /d(跨盘;工作区 D: + 缓存 C: 的 真实 CI 布局)。
  • release 的 publish-ecosystem:镜像脚本改为批量上传+带耐心的 ranged-GET 验证、 验证超时不再删除资产(0.0.89 因逐资产"18s 即删重传"+全量 GET 探测触顶 20min 被杀);timeout 兜底 20→30。
  • stdmod 执行层支持工具链声明环境(capture_with_env);shell 引用平台化。

[0.0.89] — 2026-07-13

新增

  • MinGW-w64 工具链入 xlings 生态(Windows 原生 GCC,无需 Visual Studio)mcpp toolchain install mingw 16.1.0 / default mingw@16.1.0:xim 包 mingw-gcc(winlibs GCC 16.1.0 + MinGW-w64 14.0.0 UCRT 独立构建,镜像于 xlings-res/mingw-gcc,GitHub+GitCode 双端)。复用既有 GCC 后端 (gcm 模块管线、libstdc++ bits/std.ccimport std);Windows 上 libstdc++/libgcc 默认静态链接(产物免带 DLL,[build] static_stdlib=false 可关),linkage="static" 升级全静态。e2e 97 覆盖 install→default→ 多模块 build/run→独立 exe 验证;ci-windows 新增专项步骤。 连带修复:toolchain list 的 Available 段与部分版本解析此前硬编码按 "linux" 平台读取 xpkg 版本(Windows/macOS 上恒空);toolchain install 在 Windows/macOS 不再错误安装 glibc/linux-headers 依赖。

重构

  • 工具链后端抽象层(Part A,对 GCC/Clang 零行为变化,build.ninja 零 diff 实证)。新增 mcpp.toolchain.dialect(命令行拼写 traits:gnu/msvc 两行 数据,-I/-D/-std=/-c/-o/-O/-g/ar 及归档命令模板经其发射);BmiTraits 并入模块旗标拼写(compileModulesFlag/stdBmiUsePrefix/ moduleOutputPrefix/bmiSearchPrefix),flags.cppm 的 is_clang 分支改由 数据驱动;ProviderCapabilities.has_builtin_p1689_scan 取代 ninja 后端的 is_gcc 门;Toolchain::envOverrides(EnvVar 表,注入 ninja 子进程环境, 为 MSVC 后端 INCLUDE/LIB/PATH 预留);gcc provider 增加与 clang 同形的 std_module_build_commands(命令序列);resolve_link_model 在 Windows 显式返回 PE 空模型。设计:.agents/docs/2026-07-13-toolchain-backend- abstraction-msvc-mingw-design.md + 同日触点审计文档。

[0.0.88] — 2026-07-13

新增

  • MSVC 系统工具链支持(msvc@system,detection-first)。MSVC 作为首个 "系统工具链"接入:mcpp 负责定位与识别(vswhere → VSINSTALLDIR/ VS*COMNTOOLS → 标准安装路径三级发现;cl.exe banner 解析出编译器版本/架构, 容错本地化 banner),从不安装/卸载 MSVC 本体。
    • mcpp toolchain default msvc:检测系统 MSVC,打印 VS 产品/VC tools/ cl 版本与 std.ixx(import std)可用性,持久化稳定 spec msvc@system (不落具体版本,VS 升级后配置依然有效);未安装时输出安装指引 (VS Installer C++ 工作负载 / winget install …BuildTools)并退出非零。 msvc@19.44 形式为 pin 校验(仍取最新 VC tools,前缀不符则报错)。
    • mcpp toolchain list:Windows 上新增 System: 段展示检测到的 MSVC; install msvc 报告已装现状或给指引;remove msvc 明确拒绝(系统组件)。
    • mcpp self doctor:Windows 上新增 "msvc (system)" 检查段。
    • manifest 支持 [toolchain] windows = "msvc@system"(types.cppm 注释中的 既有 schema 首次落地);非 Windows 主机使用 msvc spec 时给出明确报错。
    • mcpp build:原生 cl.exe 构建(.ifc 管线)本版暂不支持,在工具链解析 后以单一 owned 错误信息拦截,并提示可用的 llvm@20.1.7(MSVC-ABI Clang)。
    • detect() 新增 cl.exe 分类路径(文件名短路,banner → 版本/triple), bmi_traits 预置 MSVC .ifc 分支;e2e 95/96 + 单测覆盖。
    • 设计文档:.agents/docs/2026-07-13-msvc-system-toolchain-detection-design.md

[0.0.87] — 2026-07-09

修复

  • 项目本地模式:不再把官方全局索引 xim 注入项目作用域。此前带自定义 [indices](本地 path 索引)的工程进入项目本地模式时,ensure_project_index_dir 会无条件把官方 xim 索引 append 进项目 .xlings.jsonindex_repos (config.cppm),意在让 xim:* 依赖在项目模式可解析。但 xlings 按"repo 落在 哪一组"决定作用域——项目 index_repos 里的包一律 PackageScope::Project,于是 xim全局工具(cmake/glibc/gcc/make/binutils 等)整体被错误地"项目化"、 装进项目 store 而非共享 registry。由此 build-dep 工具(如 xim:cmake)的 ELF interpreter 被指向项目 store 里未物化的 glibc → cannot execute,任何在 install() 里执行 glibc-动态 build-dep 工具的 compat 包(如从源码 CMake 构建的 OpenCV)在 mcpp test 下必现,且与宿主历史无关(fresh MCPP_HOME 亦复现)。 修复:移除该注入及配套的项目 data dir xim 副本暴露。xim(及其动态发现的 sub-index)是 xlings 全局默认索引,global 即默认作用域——xim:* 经全局 index_repos + registry 本地 clone 正常解析、装 registry,并经 additive 对项目 可见;只有用户在 [indices] 声明的本地自定义索引才项目化。设计与分析见 .agents/docs/2026-07-09-project-index-scope-global-infra-fix.md

[0.0.84] — 2026-07-08

修复

  • clang 驱动配置文件(cfg)补全头文件搜索路径:fixup_clang_cfg 再生成的 cfg 此前仅包含链接相关条目(-B/-L/动态链接器/rpath),缺少 C 标准库头文件 与内核头文件的搜索路径。该 cfg 服务于直接调用打包内 clang/clang++ (不经由 mcpp)的场景:缺少这两项时,此类调用仅在宿主系统存在 /usr/include 时可编译(依赖宿主环境,违背沙箱自包含约束),在无宿主开发头 文件的环境中直接报头文件缺失错误。本次补充 -isystem <glibc payload>/include-isystem <linux-headers payload>/include, 置于 libc++ 头文件条目之后以保持 #include_next 搜索链;生成内容与 xim-pkgindex 侧 llvm.lua 安装期生成的 cfg 保持一致,消除两个生成端之间的 内容差异。fixup 修订号升级至 hermetic-3,既有 payload 在下一次构建时自动 重新收敛,无需重新安装。验证方式:以 --sysroot=<空目录> 屏蔽宿主头文件后, 由 cfg 驱动的 clang/clang++ 直接调用编译与运行均通过;移除上述搜索路径的 对照组按预期失败。mcpp 自身构建路径不受影响(构建 flags 由 linkmodel 独立提供,不读取 cfg)。

修复

  • Linux llvm 工具链链接失败 cannot open Scrt1.o/crti.o/crtn.o(#195):clang-with-cfg 的 payload 链接路径此前只带 -L/-rpath/--dynamic-linker,缺少 CRT 启动对象的发现前缀 -B<glibc payload lib>——driver 查找 Scrt1.o/crti.o/crtn.o 只走 -B 前缀与 sysroot 派生路径,不查 -L。在装有宿主 libc6-dev 的机器上 driver 会静默兜底宿主 /lib 的 CRT (污染式"假绿"),在没有的机器(如全新 WSL2)上则把裸文件名传给 lld 直接失败。

新增 / 架构

  • 工具链链接模型单一化(hermetic toolchain link model):新增 mcpp.toolchain.linkmodel 作为「如何对该工具链的 C 库编译/链接」的唯一解析器(payload-first,--sysroot 回退), flags / stdmod / build_program / cfg 再生全部消费同一模型,消除四份漂移实现; 动态链接器名按 声明式 payload 元数据 → 按 triple 的 arch 映射 → glob 三级解析,全链 不再硬编码 ld-linux-x86-64.so.2(aarch64 glibc 的 loader 障碍随之消除)。详见 .agents/docs/2026-07-07-hermetic-toolchain-link-model-design.md
  • post-install fixup 归位为统一管线:ensure_post_install_fixup 成为所有工具链安装 路径(显式 install / 默认工具链 auto-install / manifest [toolchain] auto-install)共享 的唯一 fixup 入口,内容指纹 marker 幂等;此前 manifest 路径不跑任何 fixup。clang cfg 由行级补丁改为从链接模型确定性再生(同一 payload 在任何机器/安装路径产出一致 cfg, 人类直接使用 clang++ 同样获得 hermetic 的 CRT 发现)。
  • hermetic 链接校验:构建前用 -### 干跑断言 CRT 对象与生效 dynamic linker 全部解析 在沙箱(xpkgs registry)内,越界即报错并指明泄漏路径;逃生阀 [build] allow_host_libs = true / MCPP_ALLOW_HOST_LIBS=1。按 flag 集缓存判定。
  • 测试与 CI:新增 e2e 86_llvm_hermetic_link.sh(-### 前缀断言,双向防「链接失败」 与「宿主污染」回归);llvm e2e 解除 20.1.7 硬 pin(MCPP_E2E_LLVM_VERSION,默认最新 已装 payload);ci-linux-e2e 新增 无宿主工具链容器 job(debian:stable-slim,无 gcc / 无宿主 CRT)——唯一能真实复现 #195 环境类的 CI 形态。

[0.0.71] — 2026-06-29

新增

  • Feature 系统 v2 Stage 2a — 由 feature 激活的可选依赖:声明于 [feature-deps.<name>] 段(或 Lua 描述符中 feature 的嵌套 deps 表)的依赖为可选依赖,仅当该 feature 处于激活 状态(根 --features 或依赖 spec 的 features=[...])时才进入解析;声明于 [dependencies] 的 依赖始终解析。可选性由声明位置表达,无需额外的 optional=true 标志。实现上,prepare_build 在为根包播种解析 worklist 之前、以及在每个依赖的 manifest 加载之后,将该 manifest 的活跃 feature-deps 合并进其 dependencies 映射,后续既有的 worklist BFS 与 Stage 3 能力绑定即自动 接管——一个 backend-openblas feature 可同时拉取 provider(compat.openblas, provides=["blas"])并开启消费开关(implies=["use_blas"],requires=["blas"]),图中单一 provider 时能力自动绑定。Lua 描述符的 feature implies 亦补齐解析(此前仅 TOML 支持)。详见 .agents/docs/2026-06-29-feature-optional-dependencies-s2-design.md

    实现注记:上述两个 helper(activateFeatures/mergeActiveFeatureDeps)必须为 prepare_build 内的局部 lambda,而非文件作用域函数。若作为模块接口单元中的导出(inline)函数,其 std::map 实例化会泄入发射的 BMI,触发 GCC 16 modules 缺陷——另一导入 std 的翻译单元随即报 fatal error: failed to load pendings for __normal_iterator。局部化可将实例化限制在实现单元内。

[0.0.70] — 2026-06-29

修复

  • 首次初始化在海外网络与 GitHub 托管 CI 上的冷启动失败(index missing;patchelf / ninja bootstrap 失败):mcpp self env 为新建的 MCPP_HOME 播种 .xlings.json 时,将 mirror 字段 硬编码为 "CN"。xlings 的 normalize_mirror_ 仅接受 GLOBALCN 两个合法取值,故 "CN" 被直接采用并解析至 gitcode,致使 xlings 内置的区域探测 detect_install_mirror_() 被跳过——该例程 经 tinyhttps::probe_latency 测量 github 与 gitcode 的连接延迟,择可达且更低延迟者。在美国区域的 runner 上,gitcode 不可达或显著较慢(实测 github 70 ms、gitcode 1060 ms),由此索引与沙箱的冷 bootstrap 失败。本版将播种值改为 "auto":normalize_mirror_("auto") 判定为非法取值,xlings 视其 为未设置并执行自身探测,在美国区域解析至 GLOBAL、在中国大陆解析至 CN。镜像选择的职责由此归还 xlings(其已基于 tinyhttps 实现该机制),mcpp 不再代为决策。播种仅在 .xlings.json 不存在时发生, 显式的 mcpp self config --mirror CN|GLOBAL 配置不会被覆盖。

新增

  • MCPP_VERBOSE 环境变量:取非空且非 "0" 的值时,为每一次 mcpp 调用启用 verbose 日志,涵盖 e2e 脚本中未携带 flag 的 $MCPP 调用,便于 CI 诊断。该变量与既有的 MCPP_LOG_LEVEL(仅控制文件 日志级别)互补;显式 --quiet 仍具有更高优先级。该变量已在 fresh-install 等 workflow 中启用,但 不含运行「默认静默」输出断言的 e2e 套件。
  • update_index 冷启动重试:索引同步为网络 git 操作,单次瞬时故障原会直接导致冷启动失败。本版 改为有界退避重试(至多 3 次,退避 2 s / 4 s);成功路径于首次尝试即返回,稳态无额外延迟,仅失败 时方触发退避。

[0.0.69] — 2026-06-29

新增

  • Feature 系统 v2 — feature 可贡献「包自有 defines」+ capability(provides/requires)能力绑定: 解决「compat.eigen 启用 blas 特性后,compile_commands.json 里只有 -DMCPP_FEATURE_BLAS、 没有上游真正读的 -DEIGEN_USE_BLAS,特性形同未启用」这一类根因——旧版 feature 激活只能产出 -DMCPP_FEATURE_<NAME> 宏 + 门控源文件,无法表达任意宏、更无法做 backend 选择。本次按 「功能全覆盖 + 少即是多」收敛为两个原语(详见 .agents/docs/2026-06-29-feature-capability-model-design.md):

    • Stage 1 — feature defines:[features] 条目可写成表形式 name = { defines = ["EIGEN_USE_BLAS"], implies = [...] }(TOML 与 Lua 描述符两面均支持); 激活时每个裸名 define 脱糖为 -D<x> 加到该包编译标志,与自动的 -DMCPP_FEATURE_<NAME> 并存。按行业经验(vcpkg)刻意限制为「包自有命名空间宏」,feature 注入自由 cflags/ldflags,以保持 feature union 组合性。
    • Stage 3 — capabilities:包/特性可 provides/requires 一个抽象能力字符串(如 blas), 解析器从依赖图中绑定唯一 provider——确定性:[capabilities] pin / --cap 指定者胜出; 图中恰好一个 provider 自动绑定;零个多个未指定硬报错(绝不静默猜测)。 这把「静默用错/缺失后端」变成配置期显式报错。link/include 仍走既有依赖机制流动。

    Stage 2(feature 触发的可选依赖自动拉取 + 全图 feature union 统一)作为下一阶段:它需要把 特性计算提前到依赖解析之前(解析阶段重排),风险更高,且 capability/Eigen 用例并不依赖它 (provider 以显式依赖声明)。本次先发坚实的 S1+S3,符合设计文档「各阶段独立可发」原则。

[0.0.67] — 2026-06-26

修复

  • 带命名空间前缀的依赖解析失败 index entry not found in local clone(自定义 ns + 非规范文件名): 当一个包以「裸 name + 独立 namespace 字段」形态声明(如 aimol.tensorvia-cpu: name="tensorvia-cpu"namespace="aimol"),并以非规范文件名落盘在共享索引里 (pkgs/t/tensorvia-cpu.lua 而非 pkgs/a/aimol.tensorvia-cpu.lua)时,限定请求 aimol.tensorvia-cpu 报「索引条目缺失」,而裸名 tensorvia-cpu 却能解析。根因是 候选消歧 selectDependencyCandidate 用「规范文件名 <ns>.<short>.lua 是否存在」当身份 判据——描述符以非规范文件名落盘时,正确的 peer-root 候选 (aimol, tensorvia-cpu) 对消歧 器隐形,请求被钉死在错误的首选候选 (mcpplibs.aimol, …) 上并被身份门拒绝。修复:候选消歧 改为身份优先,经由加载路径同款的身份校验读取器(read_xpkg_lua*)按描述符声明的 (ns, name) 定位候选,文件名不再参与身份判定——选择层与加载层从此不可能对同一候选产生 分歧。详见 .agents/docs/2026-06-26-identity-first-resolution-no-filename.md

[0.0.66] — 2026-06-26

修复

  • LLVM 工具链产物运行期 libatomic.so.1: cannot open / 真用原子时链接报 undefined __atomic_*: 16 字节及超宽 std::atomic 会降级成 __atomic_* 外部调用,这些符号位于 libatomic (GCC 运行时库,LLVM 无对应物),而编译器驱动不会自动链接 libatomic。mcpp 现在在 Linux 链接行注入 -Wl,--push-state,--as-needed -latomic -Wl,--pop-state:真正用到原子的 程序自动链上并保留依赖,未用到的程序经 --as-needed 自动丢弃、产物零额外依赖。注入是 自守卫的——仅当工具链链接目录里存在可解析的 libatomic(动态链接 libatomic.so/.a, 静态链接 libatomic.a)时才发出 -latomic,因此对不附带 libatomic 的工具链零回归。 与之配套的 llvm 资源包需把 libatomic 打入 lib/<triple>/(详见 .agents/docs/2026-06-26-llvm22-libatomic-self-containment-design.md)。

[0.0.65] — 2026-06-25

修复

  • mcpp add gtest + mcpp buildduplicate symbol: main / LNK2005(#168): gtest 作为常规依赖时,其 gtest_main.cc(自带 main)被链进应用,与应用自身的 main 冲突。修复采用通用的「feature 门控源」机制:依赖描述符可声明 [mcpp].features.<名>.sources,被某 feature 列出的源默认不编译/链接,仅在该 feature 被请求(dep = { version="…", features=["…"] })时纳入。gtest 描述符把 gtest_main.cc 归入 main feature → 默认只链框架,不再撞 main;需要 gtest 提供 main 时 gtest = { version="1.15.2", features=["main"] } 显式开启。 门控仅作用于 mcpp build;mcpp test 保持既有的 dev 依赖 main 检测(0.0.64)不变。 详见 .agents/docs/2026-06-25-gtest-main-feature-and-add-dev-design.md

新增

  • mcpp add --dev <pkg>:把依赖写入 [dev-dependencies](测试专属,如 gtest; 由 mcpp test 消费,不链进 mcpp build 的应用)。

测试

  • 单元 SynthesizeFromXpkgLua.FeatureGatedSources(描述符 feature 门控源解析); e2e 79_gtest_regular_dep_feature_main.sh(#168 哨兵 + features=["main"] opt-in + add --dev)。

CI

  • release workflow 默认 xlings 版本 0.4.580.4.60(缓存键同步更新)。

[0.0.64] — 2026-06-25

修复

  • mcpp test 在自带 main() 的测试 + gtest dev-dep 下 duplicate symbol: main: gtest 的 gtest_main.cc 自带 main(),而 mcpp 此前把依赖的全部对象内联进每个 测试二进制,于是测试自己的 main()gtest_main.o 撞符号。修复:兑现依赖 描述符里已声明的 kind="lib"——把这类依赖编译成静态归档 lib<pkg>.a,链接在 测试对象之后;标准归档语义只在符号未定义时拉成员,故 gtest_main.omain 只在测试不自带 main 时才被拉入。{自带/框架 main} × {用/不用 gtest} 全部组合 皆正确,用户无感。纯模块依赖(如 mcpplibs.cmdline,无非模块对象)行为不变。 这是通用 link-model 改进、由既有描述符 kind 驱动,无 gtest 特例,未来 测试框架声明 kind="lib" 即自动适配。详见 .agents/docs/2026-06-25-dependency-archive-linking-design.md

测试

  • 新增单测 NinjaBackend.ArchiveInputsLinkedAfterObjects(归档须排在对象之后)与 跨平台 e2e 78_test_main_combinations.sh(四种 main×gtest 组合 mcpp test 全绿)。

[0.0.63] — 2026-06-25

修复

  • tests/ 目录无代码提示:clangd 在测试文件里对 gtest::InitGoogleTest()import std / import mcpplibs.* 全无补全。根因:compile_commands.json 是当次构建 plan 的镜像,mcpp build 的 plan 不含 tests/**/*.cpp 与 dev-deps,而它与 mcpp test 写同一个 cdb——后写覆盖前写,日常「编辑→build」循环里测试条目几乎总被擦掉。修复: write_compile_commands 由「全量覆盖」改为「合并保留」——保留当前 plan 未覆盖但 文件仍存在的旧条目(上次 mcpp test 写入的测试条目),剪除已删文件。mcpp build 自身 零改动:不解析、不下载任何 dev-deps,build-only 用户与构建图均不受影响(offline-first)。 跑一次 mcpp test 后,测试补全在后续所有 mcpp build 中持久生效。 详见 .agents/docs/2026-06-25-cdb-test-coverage-design.md

测试

  • 新增单测 tests/unit/test_compile_commands.cpp(合并/剪除/去重/坏 JSON 回退)与跨平台 e2e 77_cdb_preserves_test_entries.sh(mcpp test 后真实重建 mcpp build 仍保留测试条目)。

[0.0.62] — 2026-06-24

修复

  • macOS 链接 library not found for -lSystem(#43):macOS 链接命令此前从不显式传 SDK, 链接侧靠 clang 隐式探测(xcrun/SDKROOT → ld64 -syslibroot)去找 libSystem。干净的 CI Xcode runner 上探测正常、缺陷被掩盖;真机一旦 xcode-select 指向异常 / 只装 Command Line Tools / 新装 bundled clang,探测失效就 ld64.lld: library not found for -lSystem + 所有 libc 符号未定义。修复:f.ld 显式追加 -isysroot <SDK>,并给 macos::sdk_path() 加多级回退 (SDKROOTxcrunxcrun --sdk macosxxcode-select -p 推导 → 固定路径),即便 xcrun 返回空也能定位 SDK,把链接从「碰运气」变「确定」。(#162)
  • macOS 首跑需手动回车 / stdin 挂起:装 POSIX 工具链时进程等待 stdin,POSIX 路径也 seal stdin(</dev/null),不再要求交互按键。(#163)

测试

  • 新增跨平台 e2e 76_compile_commands_generated.sh:mcpp new + mcpp build 一个最小工程, 在 Linux / macOS / Windows 三平台断言根目录生成合法 compile_commands.json。因 mcpp build 含链接步骤,它同时是 macOS -lSystem 链接缺陷的跨平台回归哨兵。(#165)

[0.0.61] — 2026-06-24

新增

  • 离线优先的索引刷新:mcpp build 不再因 TTL 过期就自动联网 xlings update。改为 miss-triggered——依赖在本地索引里就直接用(零网络,消除弱网/Termux 首跑卡顿);依赖在 本地查不到时才刷新一次去拉它(打印 Refreshing package index — \` not found locally`, 并有 120s 防重,避免一个 build 里多个缺包各跑一遍全量 git 同步)。
  • mcpp index status:只读、全程不联网,显示 xim/mcpplibs 两索引的 present/fresh/age/path; 缺索引时提示显式 mcpp index update
  • install.sh 多架构:新增 linux-aarch64(aarch64 / arm64),并支持 GitHub→GitCode(CN) 镜像回退(MCPP_MIRROR=CN 强制 GitCode),让被墙网络下同一条安装命令可用。
  • first-init 细粒度计时日志:--verbose 下首次初始化(sandbox 布局、patchelf/ninja bootstrap) 各步带时间戳 + ScopedTimer 耗时([VERBOSE <ts>] … done (Δ=<ms>ms)),便于定位"卡很久"的步骤。

CI

  • e2e 套件拆为独立的 ci-linux-e2e.yml,与 build/单测/工具链矩阵并行,缩短每个 PR 的关键路径。
  • tests/e2e/run_all.sh 每个用例输出耗时 + 末尾「最慢优先」汇总,便于后续分片/优化。

杂项

  • 自托管清单改用 TOML 原生命名空间依赖写法 mcpplibs.cmdline = "0.0.1"(去掉遗留引号)。

[0.0.57] — 2026-06-20

修复

  • 包描述符解析改为 identity-first:不再「按候选文件名跨索引无序扫描、撞上第一个就返回」, 而是用描述符声明的规范 (ns, name) 二元组校验命中文件的身份。修复 compat.zlib 在全新 CI 上偶发 index entry has no mcpp field(外来 xim-pkgindex/.../zlib.lua 因目录遍历 顺序先被撞到而冒充 compat.zlib)。索引目录改为排序后确定性遍历。

重构

  • 新增统一的 canonical_xpkg_identity() 归一器(身份 = 二元组 (ns, name);ns 为可分层命名 空间路径,name 为单一末段;点号名 a.b 本质 (a, b))。归一三步:无声明 ns → 继承所属索引 默认 ns;求 FQN;按最后一个点切分。匹配 = 限定请求精确相等 / 非限定请求按默认搜索路径 [mcpplibs, compat]compat 降级为搜索路径里的数据项(kCompatNamespace),不再是匹配 分支。[indices] 路径索引的无命名空间描述符继承索引命名空间。

CI

  • ci-{linux,macos,windows}.yml 各加一步:用本次构建出的 mcpp git clonemcpp build / mcpp run 外部 C++ 工程 xlings(openxlings/xlings),验证自托管 mcpp 能构建真实外部项目。

[0.0.56] — 2026-06-19

修复

  • mcpp run / test / build 不再把目标的捆绑 glibc LD_LIBRARY_PATH 注入到 mcpp 自身进程,因而泄漏进它启动的宿主 /bin/sh。在 glibc 比捆绑版(2.39)更新的 发行版上,sh 会被强制加载捆绑的旧 libc,无法满足宿主 libtinfoGLIBC_2.42 符号而在目标运行前崩溃(报错形如 sh: ... version 'GLIBC_2.42' not found)。新增 platform::process::run_exec / capture_exec:直接 exec(不经 shell),额外环境 只作用于子进程;run / test / 快速路径 ninja / 整次构建 ninja 四个启动点全部改走它。

变更

  • mcpp pack --mode 模式更名,语义更清晰(旧名保留为永久别名,tarball 后缀冻结不变): bundle-projectvendored(默认)、bundle-allself-contained;新增 system 模式(完全依赖宿主提供所有共享库,用于发行版打包 / 同发行版部署)。 static 不变。两轴模型:libc 由 --target 选(gnu/musl),--mode 只选打包深度。

[0.0.55] — 2026-06-18

新增

  • [targets.<name>] 新增按目标的键 defines / cxxflags / cflags,作用于该目标 独占的入口源(它的 main)。用于二进制入口私有的标志(如 -DBUILD_SERVER=1、 局部告警抑制),不影响共享模块/实现对象(compile-once 模型不变)。需要穿透共享代码的 差异请用 workspace member 或 [features](#131)。
  • [targets.<name>] 新增 required_features:仅当列出的 feature 全部激活时才构建该目标, 否则静默跳过。是构建选择门禁,不激活 feature。
  • mcpp test 现在接受 --profile / --features / --strict,让被测代码与测试二进制 在所选 profile/feature 下编译(适合 sanitizer、契约求值语义等整次构建模式)。

变更

  • [targets.<name>] 下的不支持键不再被静默丢弃,而是产生 warning(--strict 下为 error), 并指引到正确的机制(workspace / features / profile)。
  • 文档 docs/05-mcpp-toml.md(及 docs/zh)新增"构建配置该放哪"的决策指引。 设计记录见 .agents/docs/2026-06-18-per-target-build-config-design.md

[0.0.54] — 2026-06-10

修复

  • mcpp new <name> --template <pkg>:对声明了命名空间的模板包(如 mcpplibs.llmapi 以裸名 llmapi 引用)现在能从描述符派生出 (namespace, shortName) 坐标,正确完成 semver 解析与安装(#130)。

其他

  • 架构重构(零行为变更):cli.cppm 从 6192 行精简为约 480 行的纯命令 分发层;src/cli/cmd_* 仅保留参数解析与路由,全部领域实现下沉到属主 子系统 —— mcpp.build.{prepare,execute}mcpp.toolchain.{post_install, lifecycle}mcpp.pm.index_managementmcpp.bmi_cache.maintenancemcpp.scaffold.createmcpp.publish.pipelinemcpp.pack.pipelinemcpp.doctormcpp.projectmcpp.fetcher.progress。 设计与迁移记录见 .agents/docs/2026-06-10-cli-modularization.md

[0.0.53] — 2026-06-09

新增

  • 库 / 组件下载现在与工具链下载一样显示实时进度条、字节进度与速度。自定义 / 项目索引依赖改经 xlings NDJSON interface install_packages 安装(仍落在项目 本地数据根,不改变安装位置与 install hook 顺序),不再静默卡住。

修复

  • 下载连接 / 预取大小阶段(totalBytes 尚未知)进度行不再"冻结"无反馈: 新增不确定态渲染,显示 connecting… + 已用时,流式无 Content-Length 时显示已下载字节,直到拿到总大小再切换为百分比进度条。

其他

  • 内置 xlings 版本上调至 0.4.51
  • 下载进度的状态机与渲染集中到 mcpp.ui(DownloadProgress),工具链 / 内置索引 / 自定义索引三条路径共用同一套 UI。

[0.0.46] — 2026-06-03

新增

  • 共享库 target 支持声明 soname,Linux 构建会传递 -Wl,-soname,..., 并在运行产物目录生成 ABI 名称 alias,供下游 DT_NEEDED / dlopen() 以标准 SONAME 加载。

修复

  • mcpp run / mcpp test 会把工具链 runtime 目录加入进程库搜索环境。 这修复了 GLX/OpenGL driver 这类经由 dlopen() 加载的库无法找到自身 DT_NEEDED 闭包的问题。

[0.0.45] — 2026-06-02

修复

  • 修复裸依赖选择器无法 fallback 到独立 root 包的问题。现在 imgui = "0.0.1" 会先尝试省略前缀的 mcpplibs/imgui,若候选包身份不匹配, 会继续匹配独立 root imgui,避免把非 mcpplibs 体系的包误解析为 mcpplibs.imgui
  • 选择候选 xpkg 描述时校验 package.name / package.namespace,并在 lockfile 中保留独立 root 包的空 namespace 身份。

[0.0.44] — 2026-06-02

修复

  • 修复 git branch 依赖的缓存身份和 lockfile source 元数据。branch 依赖现在会先 解析到具体 commit,缓存 key 会随远端 branch 更新而变化,lockfile 也会记录 git+<url>#branch=<name>@<sha> 而不是错误落到 index+mcpplibs@

[0.0.43] — 2026-06-02

新增

  • 支持在单个 [dependencies] / [dev-dependencies] / [build-dependencies] / [workspace.dependencies] 表中使用多段 dotted dependency selector,例如 imgui.core = "..." 会先尝试 mcpplibs.imgui/core,未命中时再尝试同级根 imgui/core
  • xpkg.luamcpp.deps 支持同样的 dotted selector 规则,方便 compat、 imgui 等生态根和 mcpplibs 并列演进。

改进

  • mcpp add 默认保留用户写入的 dotted selector,显式 namespace 仍可使用 ns:name 写入 [dependencies.<ns>]

[0.0.42] — 2026-06-01

新增

  • [package].standard 打通为一等 C++ 标准配置,默认仍为 c++23, 并支持 c++26 / c++2c 等写法。

修复

  • 编译 flags、compile_commands.json、fingerprint 与 import std 标准库 BMI 预构建命令现在使用同一个 active C++ 标准。
  • std.gcm / std.pcm cache 增加元数据校验,只有 compiler、stdlib、target、 standard、source 与 build command 匹配时才复用。
  • build.cxxflags 回归附加 C++ flags 语义,若写入 -std= 会提示迁移到 [package].standard

[0.0.41] — 2026-06-01

修复

  • 修复 Objective-C .m 源文件在 Ninja 后端被路由到 C++ 编译规则的问题。 .m 现在与 .c 一样使用 C/Objective-C 编译器与 cflags,避免 macOS GLFW 等上游 Objective-C 源被错误附加 -std=c++23

[0.0.40] — 2026-06-01

修复

  • 修复 project-local index 包的 xpm hook 工具依赖无法解析官方 xim 索引的问题。项目级 xlings 配置现在会在 custom/local index 旁边显式暴露 官方 xim 索引,让 xim:python 等 hook 工具依赖可用。

[0.0.39] — 2026-06-01

修复

  • 修复 project-local index 包安装时没有走项目 xlings 数据根的问题,本地 path 索引现在通过 xlings CLI 直接安装到项目数据目录,避免 hook 查找不到同索引包。
  • 修复包 install hook 运行前 mcpp.deps 尚未安装的问题,库/头文件依赖可以继续 留在 mcpp.deps,只有 hook 执行工具需要放入 xpm deps。

[0.0.38] — 2026-05-31

新增

  • 支持包描述拥有自己的 ldflags,依赖包声明的链接参数会随包源码编译 一起进入最终链接命令,消费方项目不再需要手动补齐第三方 C/C++ 库的私有链接参数。

[0.0.37] — 2026-05-31

修复

  • 修复 xlings 项目构建时自动索引刷新泄漏 xlings 内部 [N/M] index::path 输出的问题。mcpp 仍保留 Updating package index (auto-refresh) 状态行, 且该状态行走统一彩色 UI 输出;内部 xlings update 现在在自动刷新路径中 静默执行。
  • 修复自动索引 freshness 依赖不稳定目录 mtime 的问题,改用 mcpp-owned .mcpp-index-updated marker,避免 full prepare 时重复刷新索引。
  • 修复命名空间依赖命中 BMI cache 后仍显示 Compiling mcpplibs.* 的问题, cache key 与 UI 状态现在使用解析得到的 canonical dependency identity。
  • 修复 xim: 工具链自动安装时官方索引/目标包文件/.xlings-index-cache.json 可能陈旧或指向临时 sandbox 路径导致 package not found 的问题。

[0.0.36] — 2026-05-31

修复

  • 修复默认 mcpplibs 索引缺失时被其他 xlings 索引误判为 fresh 的问题。 mcpp build/search 现在会要求默认索引自身存在并处于 TTL 内,避免 compat.* 依赖在混合缓存状态下找不到。

[0.0.35] — 2026-05-30

新增

  • 支持包描述拥有自己的 cflags / cxxflags,依赖包源码编译时会继承所属包 的构建宏,消费方项目不再需要集中声明第三方 C 库的私有宏。
  • 支持 Form B mcpp.generated_files,官方索引包可以在包目录下生成少量配置头, 用于承载平台兼容宏或库私有配置。

修复

  • 修复本地 path 索引读取命名空间包时没有匹配 pkgs/<prefix>/<namespace>.<name>.lua 的问题。
  • 自定义索引首次同步时保留 mcpp 的 Fetching custom index repos 状态提示,但静默 xlings update 的内部逐项输出。

[0.0.33] — 2026-05-30

改进

  • 将 legacy dotted dependency key 兼容解析移入 mcpp.pm.compat.legacy 模块,保留 mcpp.pm.compat 作为 facade,并明确标注该兼容路径将在 mcpp 1.0.0 移除。

[0.0.32] — 2026-05-30

修复

  • 修复 project-local .xlings.json 生成时未转义 JSON 字符串的问题, 避免 Windows 本地 index 路径中的反斜杠导致 xlings 跳过项目索引。

[0.0.31] — 2026-05-30

修复

  • 修复 xlings 项目使用 mcpp 构建时 custom index 首次同步、project data root 查找和 local index 相对路径解析的问题。
  • 支持 canonical nested dependency 写法: [dependencies] capi.lua = "0.0.3"[dependencies.mcpplibs] capi.lua = "0.0.3"
  • 将 legacy flat dotted dependency key 兼容解析集中到 mcpp.pm.compat, 并标注该兼容路径将在 mcpp 1.0.0 移除。

[0.0.14] — 2026-05-13

LLVM / Clang 工具链支持与 xlings 镜像配置完善。

新增

  • LLVM / Clang 工具链支持 —— 新增基于 clang++clang-scan-depsllvm-arlld 的工具链探测与构建路径,支持 xlings llvm 包提供的 自包含 Linux LLVM 工具链。
  • import std 支持 —— LLVM libc++ 模块标准库可用时,自动发现 std.cppm / std.compat.cppm,并接入标准库 BMI 预构建流程。
  • mcpp self config --mirror —— 通过 xlings 抽象层配置 sandbox 镜像,默认初始化为 CN,CI 可显式切换为 GLOBAL

改进

  • 🔧 工具链 provider 拆分 —— 将通用模型、探测逻辑、GCC、Clang、LLVM provider 与 registry 分离到独立模块,为后续更多工具链扩展预留入口。
  • 🔧 xlings 索引兼容迁移 —— 自动将历史 mcpp-index 索引名迁移到 mcpplibs,避免旧 sandbox 状态影响新流程。

[0.0.4] — 2026-05-10

构建 / 环境体验优化三件套。

新增

  • Glob 排除模式 —— [modules].sources (以及 Form B 的 sources) 现在支持 ! 前缀的排除模式(类似 .gitignore):
    sources = ["src/**/*.cpp", "!src/**/*_test.cpp", "!src/**/*_fuzzer.cpp"]
    正向 glob 先展开、再减去 !-prefixed glob 命中的路径。解决了上游库 test/fuzzer 文件与源混放时不得不逐文件列举的问题(典型如 ftxui)。

改进

  • 🔧 xlings 布局调整 —— xlings 二进制从 <MCPP_HOME>/bin/xlings (与 mcpp 同目录)移至 <MCPP_HOME>/registry/bin/xlings (= <XLINGS_HOME>/bin/xlings)。由于 xlings 的 shim-creation guard 恰好检查 <XLINGS_HOME>/bin/xlings 是否存在,新布局下 ensure_sandbox_xlings_binary 自然变成 no-op,省去了之前的 hardlink 步骤。

  • 🔧 测试自动继承 sandbox PATH —— mcpp test 在调用测试二进制前, 自动把 sandbox 的 subos/default/bin(含 patchelf、ninja 等 一次性自举工具)追加到 $PATH,使 test 代码 shell-out 到这些工具时 不再报 "command not found"。

[0.0.3] — 2026-05-10

依赖解析体系的三步演进:0.0.2 release tag 之后合入 transitive walker, 这一版补齐 SemVer 合并(Level 2)+ 多版本 mangling 兜底(Level 1)。

新增

  • 依赖图传递性遍历 —— 直接依赖的子依赖(以及更深层)自动跟随入解析图, 消费者不必再在自己的 mcpp.toml 里把 grandchild 也写一遍;子依赖的 [build].include_dirs 也会沿链路传播,让中间层在编译时看得到 grandchild 的头文件。冲突检测同时区分 path / git / version 三类来源,跨来源不允许 混用。

  • SemVer 合并解析(Level 2) —— 同一个包在传递依赖图里被多个消费者 以不同版本约束声明时,resolver 会把两条原始约束 AND 合并(裸版本号视作 =X.Y.Z),向 index 重新查询,选出同时满足两侧的具体版本。若该版本与 此前已 pin 的不一致,旧的 manifest 与 [build].include_dirs 会被原地 替换为新版本的内容,孩子依赖也按新 manifest 重新入队。新增 e2e 32_semver_merge.sh 覆盖兼容合并 + 不可调和两条主链路。

  • 多版本 mangling 兜底(Level 1) —— SemVer 合并失败时(典型如 =0.0.1=0.0.2 这种无重叠的 pin),resolver 不再硬报错,而是把次要 版本的源码 stage 到 target/.mangled/<consumer>/... 下,通过正则改写 (export )?module X; / (export )?module X:Y; / (export )?import X; 把模块名替换成 <X>__v<M>_<m>_<p>__mcpp 形式,让两个 BMI 在同一构建图 里以不同模块名共存(C++23 module attachment 帮我们做 ABI 隔离,无需额外 namespace mangle)。直接 consumer 的源码也一并 stage + 改写,让它的 import 指向 mangled 副本。MVP 范围:仅处理 dep-as-consumer + 叶子 secondary 两种情形,主包做 consumer 或 secondary 还有自己的 transitive deps 时报清晰错误并建议显式 pin。新增 src/pm/mangle.cppm(纯改写 helper + 11 个单元测试)和 e2e 33_multi_version_mangling.sh

改进

  • 🔧 构建后端按需为多包做 obj 路径命名空间 —— plan.cppm 检测到 跨包同名源文件(多版本 mangling 后两个 parse.cppm 同时存在的常见情形) 时,自动把 obj/<file>.o 改为 obj/<sanitized-pkg>/<file>.o,.ddi 扫描产物随之放在 object 同目录下。无碰撞时仍是原始 obj/<file>.o 布局,不影响现有缓存命中。

第二个公开版本。新增 C 语言一等公民支持、xpkg 风格依赖命名空间、包管理子系统骨架重构,以及 lib-root 约定。

新增

  • C 语言源文件支持mcpp.toml[build] 段新增 cflagscxxflagsc_standard 三个字段;ninja 后端探测 .c 源文件后自动派 生兄弟 C 编译器(g++ → gccclang++ → clang、跨编译器前缀如 x86_64-linux-musl-gcc 同样适用),发出独立的 c_object 规则。 按文件扩展名分发:.cppm → cxx_module.c → c_object、其它 → cxx_object;dyndep / 模块扫描自动跳过 .c实测可直接编译 mbedtls 3.6.1 全部 108 个 .c 源文件(SHA-256 测试向量与 FIPS 180-4 一致)。

  • lib-root 约定 — 库项目(kind = "lib" / shared)的 primary module interface 默认在 src/<package-tail>.cppm,且必须 export module <full-package-name>;(无 :partition 后缀);可用 [lib].path = "src/foo.cppm" 显式覆盖(cargo lib.rs 风格)。 违规组合(显式 path 但文件缺失 / 文件 export partition / module 名 不匹配 [package].name)报 error;约定文件缺失只报 warning,给已有 项目软迁移时间。纯 binary 项目跳过所有检查。

  • xpkg 风格依赖命名空间mcpp.toml 现在原生支持三种依赖书写形式:

    • 平铺默认命名空间:gtest = "1.15.2"(mcpp, gtest),无引号
    • TOML 子表命名空间:[dependencies.mcpplibs] cmdline = "0.0.2"(mcpplibs, cmdline),无引号
    • 老式带点字符串(向后兼容):"mcpplibs.cmdline" = "0.0.2" 仍能解析
    • CLI 同步:mcpp add mcpplibs:cmdline@0.0.2 接受 <ns>:<name> 冒号分隔形式,写出仍是子表写法
    • 解析层在 DependencySpec 增加 namespace_ + shortName 结构化 字段,fetcher / lockfile / cache 等下层逻辑沿用现有完全限定 key。

改进

  • 🛠 src/pm/ 包管理子系统(7 步重构,全部完成) — 包管理相关代码 从 cli.cppm(3510→2900 行) / manifest.cppm / lockfile.cppm / fetcher.cppm / publish/xpkg_emit.cppm 中抽出,集中到独立的 src/pm/ 目录下,跟 build/ / toolchain/ / pack/ 平级。 最终 8 个内部模块:

    • pm/pm.cppm(子系统门面,re-export 数据类型)
    • pm/dep_spec.cppmDependencySpec + kDefaultNamespace
    • pm/index_spec.cppm — 占位,等索引仓配置实现
    • pm/lock_io.cppmmcpp.lock IO
    • pm/package_fetcher.cppm — xlings NDJSON 客户端
    • pm/resolver.cppmresolve_semver + is_version_constraint
    • pm/commands.cppmcmd_add / cmd_remove / cmd_update
    • pm/publisher.cppmemit_xpkg + tarball / sha256 / release helpers

    整个重构严格保持零行为变更:每一步独立 PR、独立 CI 通过、独立可 回滚;旧模块名(mcpp.lockfile / mcpp.fetcher / mcpp.publish.xpkg_emit) 保留薄 shim 透传到新模块,所有调用点零改动。规划与依赖图见 .agents/docs/2026-05-08-pm-subsystem-architecture.md §3-§5。

  • 📄 新增设计文档 .agents/docs/:

    • 2026-05-08-package-index-config.md — 多源包索引仓配置 + mcpp.lock 索引 commit 锁定 + 两层不可变性 (L1 publish policy + L2 lock mechanism)
    • 2026-05-08-pm-subsystem-architecture.md — 包管理子系统目标布局 与 7 步落地计划

修复

  • 🐛 path 依赖的 [package].name 比对支持 xpkg 标准 name + 旧式 <ns>.<name> 复合名两种形式,兼容当前 mcpp-index 描述符尚未迁移的 状态。
  • 🐛 module 扫描器解析 partition import(import :foo)时,不再把当前 TU 自己的 partition 后缀拼进 logical name。 之前 export module M:bar; 里的 import :foo; 被解析成 M:bar:foo (没人 provide,产生 7 条 stale warning);现在正确解析为兄弟分区 M:foo。GCC dyndep 实际能分辨,所以 build 不影响,但 mcpp 自己的 warning 噪音消失。在 mcpplibs/tinyhttps 上验证(7 条 warning → 0 条)。

兼容性

向后兼容。老的 mcpp.toml / mcpp.lock 不需要任何改动即可在 0.0.2 下 继续工作。带引号的 "ns.name" 形式继续被解析,只是新写出的 mcpp add 会用无引号的子表形式。

[0.0.1] — 2026-05-07

mcpp 首个公开发版本。

已具备的能力

  • ✅ 基础工程命令:mcpp new / build / run / clean / test
  • ✅ C++23 模块(import std / import foo.bar)一等公民支持
  • ✅ 跨项目依赖:mcpp-index 远程仓库、git、本地 path 三种来源
  • ✅ SemVer 约束:"foo" = "^0.0.1" / "~1.2.0" / ">=1, <2"
  • ✅ P1689 编译器驱动模块扫描 + ninja dyndep
  • ✅ 跨项目 BMI 持久缓存
  • ✅ 私有 toolchain 沙盒(mcpp toolchain install / default / list), 跟系统 PATH 完全隔离;首次使用自动装 musl-gcc 默认工具链
  • ✅ 部分版本号支持(mcpp toolchain install gcc 15 自动选最高匹配)
  • mcpp pack 三种自包含发布模式:
    • static — musl 全静态,单文件可分发
    • bundle-project(默认)— 只 bundle 项目第三方 .so
    • bundle-all — 全自包含含 ld-linux + libc,附 run.sh wrapper
  • mcpp self {doctor,env,version,explain} 自诊断
  • ✅ 下载 / 安装实时进度(速度、字节数、终端宽度自适应)
  • ✅ 项目相对路径显示(@mcpp/...、project-relative)

发布产物(GitHub Release)

  • mcpp-0.0.1-linux-x86_64.tar.gz — bundled tarball(mcpp + 内置 xlings)
  • mcpp-linux-x86_64.tar.gzlatest 别名
  • install.shcurl | bash 装机脚本
  • SHA256SUMS + 各资产 sha256 sidecar
  • 二进制为 musl 全静态 ELF,无 PT_INTERP / RUNPATH 依赖,任意 Linux x86_64 直接可跑

限制

  • 仅支持 Linux x86_64(glibc / musl 通用)
  • macOS / Windows / aarch64 还在路上
  • workspace、mcpp publish --auto(自动 PR 到 mcpp-index)等功能未发版

反馈

接口、命令、产物形态可能在后续小版本调整。issue / 想法 / 协作意向都欢迎到 issues 来。