diff --git a/.agents/docs/2026-08-05-codegen-ecosystem-design.md b/.agents/docs/2026-08-05-codegen-ecosystem-design.md index 8ee1dfc..c4a3c9a 100644 --- a/.agents/docs/2026-08-05-codegen-ecosystem-design.md +++ b/.agents/docs/2026-08-05-codegen-ecosystem-design.md @@ -5,7 +5,7 @@ > .5.2 才让 `host-module = true` 规则包真正可用 —— 规则里能 `import std;` 与 `import mcpp;`) > 涉及:本仓库的 `plugin/`(新)、`rules/`(新)、`templates/`、`examples/`、 > `.github/workflows/ci.yml`;`mcpp-index` 的 `compat.protobuf` 与新条目 -> `mcpplibs.grpc-plugin` / `mcpplibs.grpcgen` +> `grpc:grpc-plugin` / `mcpplibs:grpcgen` --- @@ -143,9 +143,9 @@ features = { 3. **`main` 要写成 `*/src/...`**:Form B 包的源码在版本目录下的包装目录里,`*` 代表 tarball 顶层文件夹名。mcpp 2026.8.5.1 起 `main` 会像 `sources` 一样展开这个 glob。 -### 4.2 新条目 `mcpplibs.grpc-plugin` +### 4.2 新条目 `grpc:grpc-plugin` -与 `mcpplibs.grpc` 同一个仓库、同一个 tag,Form A(自带 `plugin/mcpp.toml`)。 +与 `grpc:grpc` 同一个仓库、同一个 tag,Form A(自带 `plugin/mcpp.toml`)。 平台覆盖是 **linux/macos/windows** —— 它只需要 libprotoc,**不受 compat.openssl 的 windows 缺口限制**(主包受)。 @@ -209,11 +209,21 @@ Timestamp / Duration / Any,所以这不是边角情况 —— 它是**用户 ### 5.3 三个包,一个 tag -| 包 | 是什么 | 消费者怎么写 | -|---|---|---| -| `mcpplibs.grpc` | gRPC 运行时 | `grpc = "1.83.0"` | -| `mcpplibs.grpc-plugin` | `grpc_cpp_plugin`(codegen 工具) | `{ version = "1.83.0", tools = ["grpc_cpp_plugin"] }` | -| `mcpplibs.grpcgen` | 构建规则(host module) | `{ version = "1.83.0", host-module = true }` | +| 包 | 代码是谁的 | 是什么 | 消费者怎么写 | +|---|---|---|---| +| `grpc:grpc` | 上游 grpc/grpc | gRPC 运行时 | `grpc.grpc = "1.83.0"` | +| `grpc:grpc-plugin` | 上游 `src/compiler/*` | `grpc_cpp_plugin`(codegen 工具) | `grpc.grpc-plugin = { version = "1.83.0", tools = ["grpc_cpp_plugin"] }` | +| `mcpplibs:grpcgen` | **本仓库自己写的** | 构建规则(host module) | `grpcgen = { version = "1.83.0", host-module = true }` | + +**命名空间说的是这个库是谁的,不是谁打的包。** gRPC 运行时与 codegen 插件都是上游 +代码(`Copyright gRPC authors`),所以归 `grpc`;`grpcgen` 是本仓库写的 163 行规则, +归 `mcpplibs`。索引里 `nlohmann.json` / `fmtlib.fmt` / `chriskohlhoff.asio` / +`godotengine.godot-cpp-m` 早就是这个口径。 + +代价是裸名够不到:`dep_spec.cppm` 的裸名梯级写死为 `(mcpplibs, X) → (compat, X) → +(∅, X)`,而 `kDefaultNamespace = "mcpplibs"`。所以运行时与插件必须写限定形式, +`grpcgen` 因为留在默认命名空间仍可裸写。这不是损失 —— 限定名把「这是谁的库」写进了 +依赖声明本身。 三者同 tag、同版本号,CI 的 `package-versions-match` 机器校验 —— 版本漂开正是本 方案要消灭的那类错配。 diff --git a/README.md b/README.md index 953c5fd..54a3d21 100644 --- a/README.md +++ b/README.md @@ -32,11 +32,11 @@ Greeter replied: Hello mcpp Or add it to an existing project: ```bash -mcpp add grpc +mcpp add grpc.grpc ``` ```toml -[dependencies.mcpplibs] +[dependencies.grpc] grpc = "1.83.0" ``` @@ -82,10 +82,10 @@ the codegen rule, and that is the entire setup: ```toml [dependencies] -grpc = "1.83.0" -grpc-plugin = { version = "1.83.0", tools = ["grpc_cpp_plugin"] } -grpcgen = { version = "1.83.0", host-module = true } -compat.protobuf = { version = "35.1", tools = ["protoc"] } +grpc.grpc = "1.83.0" +grpc.grpc-plugin = { version = "1.83.0", tools = ["grpc_cpp_plugin"] } +grpcgen = { version = "1.83.0", host-module = true } +compat.protobuf = { version = "35.1", tools = ["protoc"] } ``` ```cpp @@ -145,7 +145,7 @@ the day that entry lands. | `ares` | **on** | The c-ares asynchronous DNS resolver, matching upstream gRPC. Turn it off with `default-features = false`: 7 TUs and the `compat.c-ares` dependency drop out and `GRPC_ARES=0` is defined, so gRPC uses its native resolver — upstream's own `grpc_no_ares=true` configuration. | ```toml -[dependencies.mcpplibs] +[dependencies.grpc] grpc = { version = "1.83.0", default-features = false } # no c-ares ``` diff --git a/README.zh.md b/README.zh.md index cf53ef9..ad390e7 100644 --- a/README.zh.md +++ b/README.zh.md @@ -31,11 +31,11 @@ Greeter replied: Hello mcpp 或加入已有工程: ```bash -mcpp add grpc +mcpp add grpc.grpc ``` ```toml -[dependencies.mcpplibs] +[dependencies.grpc] grpc = "1.83.0" ``` @@ -79,10 +79,10 @@ gRPC 需要两个宿主工具 —— `protoc` 与 `grpc_cpp_plugin` —— 自 * ```toml [dependencies] -grpc = "1.83.0" -grpc-plugin = { version = "1.83.0", tools = ["grpc_cpp_plugin"] } -grpcgen = { version = "1.83.0", host-module = true } -compat.protobuf = { version = "35.1", tools = ["protoc"] } +grpc.grpc = "1.83.0" +grpc.grpc-plugin = { version = "1.83.0", tools = ["grpc_cpp_plugin"] } +grpcgen = { version = "1.83.0", host-module = true } +compat.protobuf = { version = "35.1", tools = ["protoc"] } ``` ```cpp @@ -138,7 +138,7 @@ windows 所需的编译/链接选项已经写在 `mcpp.toml` 里,等那个条目 | `ares` | **开** | c-ares 异步 DNS 解析器,与上游 gRPC 一致。用 `default-features = false` 关闭:7 个 TU 与 `compat.c-ares` 依赖一并移除,并定义 `GRPC_ARES=0`,gRPC 改用原生解析器 —— 即上游自己的 `grpc_no_ares=true` 配置。 | ```toml -[dependencies.mcpplibs] +[dependencies.grpc] grpc = { version = "1.83.0", default-features = false } # 不带 c-ares ``` diff --git a/templates/greeter/mcpp.toml.in b/templates/greeter/mcpp.toml.in index 37b651d..79af0a4 100644 --- a/templates/greeter/mcpp.toml.in +++ b/templates/greeter/mcpp.toml.in @@ -21,12 +21,20 @@ sources = ["src/main.cpp"] kind = "bin" main = "src/main.cpp" -[dependencies.mcpplibs] +# The `grpc` namespace, because both of these are UPSTREAM gRPC code — the +# runtime and, below, the codegen plugin's src/compiler/* sources. A namespace +# names whose library it is, not who packaged it. +[dependencies.grpc] {{self.name}} = "{{self.version}}" # The gRPC C++ codegen plugin — a package of its own rather than a target # inside gRPC, because a code generator needs a .proto parser and a C++ # emitter, not TLS, DNS and a regex engine. grpc-plugin = { version = "{{self.version}}", tools = ["grpc_cpp_plugin"] } + +# grpcgen is NOT upstream — it is the codegen rule this repository wrote, so it +# lives in mcpplibs (which is also mcpp's default namespace, hence no prefix +# needed when writing it). +[dependencies.mcpplibs] # The codegen RULE. `host-module = true` makes its module importable from # build.mcpp, which is why build.mcpp is three lines instead of sixty. It is # build-time only — not compiled into or linked with this project.