Skip to content

Latest commit

 

History

History
85 lines (65 loc) · 4.81 KB

File metadata and controls

85 lines (65 loc) · 4.81 KB

SPEC-008:库的接口:公开模块、发布闭包与两种形态的一致

项 值
规范编号 SPEC-008
标题 库的接口:公开模块、发布闭包与两种形态的一致
状态 草案 v0.1
版本 0.1
最后修改 2026-09-28
对应实现 第一阶段(只警告)mcpp >= 2026.9.28.3;第二阶段未实现
相关设计文档 .agents/docs/2026-09-28-build-cost-foreign-toolsets-and-library-surface-design.md(§5)
相关 issue mcpp#734
使用文档 docs/04 - mcpp.toml([lib])、docs/12 - 二进制分发

本规范规定一个库包对消费方公开什么、mcpp pack 发布什么,以及同一个包以源码形态和打包形态 到达消费方时接口保持一致的条件。库包提供给构建程序的模块(构建插件的模块)由 SPEC-007 §9 规定,不在本规范范围内。

规范用语与实现状态标记见 规范索引。

1. 目标

性质 含义
语义清楚 消费方可以导入的、包随包发布的、包保留的,各有一个名字
一致 无论包以源码还是以打包形态到达,消费方看到同一个接口
稳定 接口是一个由包自己的声明决定的集合,消费方可以跨版本依赖它
可分发 打包形态完整(消费方可以基于它编译)且最小(接口闭包之外的单元不外泄)
简洁 每个包一处声明,以 C++ 本身表达(一个模块及其转出),不另维护列表
兼容 今天能构建的清单不因本规范停止构建

2. 定义

  • 接口根:[lib].path 所指的单元;未写时按约定为 src/<包名最后一段>.<模块接口扩展名>。 它必须声明主模块接口(export module <name>;),不能是分区。
  • 公开模块:接口根的模块,以及它用 export import 传递地转出的模块与分区。消费方可以 导入的就是这些名字。
  • 公开头文件:include/ 下的文件(docs/12)。
  • 接口:公开模块与公开头文件的合集。
  • 发布闭包:公开模块的接口传递地导入的每个单元,无论是否转出。消费方构建公开模块的 BMI 需要它们。
  • 保留单元:包的其余单元。它们编入库中,但不随包发布。

公开模块与发布闭包的区分是本规范的核心:前者是消费方可以依赖的契约,后者是 BMI 的构建需要。

3. 规则

  • I1 一个包的接口与它到达消费方的形态无关。(第一阶段:由 W3 警告陈述,源码构建不受限制)
  • I2 一个包至多有一个接口根,因此它有一个与身份 (namespace, name) 对应的可导入名字。代码 组织为多个模块的包,由接口根以 export import 转出它们(门面形式)。不设接口根的列表。
  • I3 公开模块的名字应当以包的身份为前缀:<namespace>.<name> 或其下的 <namespace>.<name>.<part>,因为模块名在一个程序中是全局的。(第一阶段:建议;引擎已拒绝同一 图中的同名模块)
  • I4 只发布头文件的接口是正当的。库可以用模块实现自己而只发布头文件,例如 C API。这样的库 没有接口根,公开模块为空。
  • I5 打包形态恰好包含发布闭包与公开头文件。(已实现)

4. 诊断(第一阶段:只警告,mcpp >= 2026.9.28.3)

每条诊断由读取接口的步骤发出,且只对能修改它的包发出。

编号 发出者 条件 陈述的后果
W1 mcpp build,只对当前构建的包 lib 目标导出模块且没有接口根 mcpp pack 发布的库不带模块接口
W2 mcpp pack 有未进入发布闭包的导出主模块,逐个写出 使用打包形态的消费方无法导入它们
W3 mcpp build,只对当前构建的包 包导入了某个有接口根的依赖的非公开模块;该依赖不是本包所在工作区的成员(同一工作区的成员总是与本包一起从源码构建) 从源码构建成功,对打包形态会失败

mcpp pack 的 "Withheld" 一行列出每个未发布的单元,包括包没有接口根的情形。(已实现)

5. 第二阶段(条件,未设计)

W1 与 W2 在三个条件同时成立时成为错误,并提供声明"只发布头文件"的写法:

  1. mcpp-index 的扫描报告了导出模块而没有接口根的库,以及其中有意只发布头文件的库;
  2. 索引 min_mcpp 所指的引擎版本能读取该声明;更旧的引擎忽略 [lib] 中的未知键,因此声明不会 使旧客户端失败,但也不会在旧客户端上生效;
  3. 本规范进入评审状态。

扫描结果为零时,W1 与 W2 已完成它们的作用,第二阶段只剩报告。

6. 变更记录

版本 日期 变更
0.1 2026-09-28 首版草案(mcpp#734):定义、I1 至 I5、第一阶段的 W1 至 W3 与完整的 Withheld 报告。