diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index d118a3d..1d77f48 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -404,7 +404,65 @@ jobs: "$1" "$2" "$3" "$4" "$5" "$6" "$i" "$7" done } - if [ "$full" = 1 ]; then ln=3; mn=1; wn=2; else ln=1; mn=1; wn=1; fi + # Shard count follows the WORK, per platform, measured. + # + # It used to be binary — full run: linux 3 / macos 1 / windows 2, + # anything else: 1 each — which asserts two things that are not + # true. "A partial run is small": touching a widely consumed + # descriptor selects every member that consumes it, and this PR's + # `pkgs/c/compat.openssl.lua` selected four; one linux shard took + # grpc-codegen (3563s) and grpc-module (1701s) back to back and was + # cancelled at exactly 1h30m, the job cap. "A full macOS run fits in + # one shard": at 6922s measured it does not — it fit only while the + # total sat just under the cap, and the run that added grpc-codegen + # (1715s on macOS) pushed it to 1h30m20s. + # + # Sharding is not only a wall-clock lever. Each shard is its own job + # with its own `timeout-minutes`, so it is also how the work is made + # to FIT. That is the half the "macOS concurrency is 1, so extra + # shards run back to back" note above left out: back to back is fine + # when the alternative is not finishing. + # + # tests/member-timings.tsv already holds every member's measured + # cost and plan_shards.lua already packs by it (LPT), so the fan-out + # comes from the same table: sum this run's members for that + # platform and take one shard per ~70 minutes, which leaves ~20 + # minutes of headroom under the 90-minute cap for a cold cache. + # + # The caps are where runner concurrency comes back in: linux 3 (the + # measured concurrency — a 4th shard would queue), macOS 2, windows + # 2. Past those, more shards buy fit that is already there and pay + # another checkout + mcpp download + cache restore. + # + # Full run, from the table: linux 13570s over 3 -> ~75min/shard + # (observed slowest 77), macOS 6922s over 2 -> ~57, windows 8043s + # over 2 -> ~67. linux is the tight one — its cap binds before the + # ~70-minute target does, so it is the first place to look if a + # cold full run starts brushing 90 again. The levers, in order: + # raise the linux cap to 4 (costs a queued runner), then the job + # timeout. + shards_for() { # platform cap -> shard count + local secs + secs=$(XPLAT="$1" lua5.4 -e ' + local plat = os.getenv("XPLAT") + local sel, all = {}, (os.getenv("MEMBERS") == "__ALL__") + if not all then + for m in (os.getenv("MEMBERS") or ""):gmatch("%S+") do sel[m] = true end + end + local total = 0 + for line in io.lines("tests/member-timings.tsv") do + local p, m, s = line:match("^(%S+)\t(%S+)\t(%d+)$") + if p == plat and m and (all or sel[m]) then total = total + tonumber(s) end + end + print(total)') + local n=$(( secs / 4200 + 1 )) + [ "$n" -gt "$2" ] && n="$2" + echo "$1 work: ${secs}s (measured) -> $n shard(s)" >&2 + echo "$n" + } + ln=$(shards_for linux 3) + mn=$(shards_for macos 2) + wn=$(shards_for windows 2) { printf '{"include":[' emit linux ubuntu-latest linux-x86_64 tar.gz bin/mcpp registry/bin/xlings "$ln" diff --git a/mcpp.toml b/mcpp.toml index 570c917..3c380a6 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -36,6 +36,7 @@ members = [ "tests/examples/godot-cpp-module", "tests/examples/godot-cpp-module-v10", "tests/examples/godot-cpp-v10", + "tests/examples/grpc-codegen", "tests/examples/grpc-module", "tests/examples/gui-stack", "tests/examples/imgui", diff --git a/pkgs/c/compat.openssl.lua b/pkgs/c/compat.openssl.lua index 46a4fd3..52a7a3d 100644 --- a/pkgs/c/compat.openssl.lua +++ b/pkgs/c/compat.openssl.lua @@ -59,7 +59,23 @@ package = { xpm = { linux = { - deps = { "xim:make@latest", "xim:perl@latest" }, + -- glibc + linux-headers are here for the same reason make and perl + -- are: this package builds through its own Makefile with a bare + -- `cc`, so every tool it uses has to be something this descriptor + -- resolved, not something it hopes to find. See cc_override(). + -- + -- The specs are xim:gcc's own, character for character, and NOT + -- `@latest`. openssl's objects are linked into projects built by + -- that gcc, so the C library it compiles against has to be the one + -- the toolchain uses; `@latest` would be free to resolve a NEWER + -- glibc than the toolchain's and introduce symbols the final link + -- cannot satisfy. Matching the ranges means both resolve the same + -- node -- already on disk wherever gcc is, so this costs a + -- resolution rather than a download. + deps = { + "xim:make@latest", "xim:perl@latest", + "xim:glibc@>=2.39", "xim:linux-headers@5.11.1", + }, ["3.5.1"] = { url = { GLOBAL = "https://github.com/openssl/openssl/releases/download/openssl-3.5.1/openssl-3.5.1.tar.gz", @@ -161,13 +177,80 @@ end -- inherit the resolved toolchain's sysroot flags — it just runs `cc`. On macOS -- the toolchain in PATH is xim's llvm, which has no macOS SDK wired up, so -- every compile would fail on . Pin Apple's own driver, which finds --- the SDK by itself. Left alone elsewhere: on linux the xim gcc carries its --- own payload and is the right compiler to use. +-- the SDK by itself. +-- +-- On linux the compiler used to be left to PATH, on the strength of "the xim +-- gcc carries its own payload and is the right compiler to use". The binary is +-- right; the assumption that it is SELF-SUFFICIENT is not. PATH reaches it +-- through its xvm shim, and the shim injects `--sysroot=` resolved +-- against **the subos the calling process resolved to** (xim-pkgindex +-- pkgs/g/gcc.lua) -- whose own comment states the other half of the contract: +-- +-- Consumers that bypass the shim supply their own header flags. +-- +-- OpenSSL's Makefile is exactly such a consumer: it calls a bare `cc`. So the +-- flags are this hook's business, the same way `make` and `perl` already are. +-- +-- Leaving it ambient breaks whenever the resolved subos is not the one holding +-- the toolchain. This hook runs with its cwd inside the CONSUMING PROJECT's +-- xlings home (/.mcpp/.xlings/data/runtimedir/openssl-), so the subos +-- resolves to the PROJECT one, which holds only what that project installed -- +-- no usr/include, usually no usr/ at all. A `--sysroot` at an empty tree does +-- not fall back to the default search, it SUPPRESSES it, and every compile +-- dies a long way from the cause: +-- +-- include/internal/common.h:14:11: fatal error: stdlib.h: No such file +-- .../xim-x-gcc/16.1.0/lib/gcc/.../limits.h:210:15: fatal error: limits.h +-- +-- (the second is gcc's own `#include_next`, which reads like a broken compiler +-- and is not). +-- +-- So resolve the C library the way make and perl are resolved -- from declared +-- build deps -- and hand openssl the three things the payload gcc needs: +-- headers (-isystem), crt objects (-B) and -lc (-L). `--sysroot` is re-pointed +-- at the glibc payload root, which is NOT FHS-shaped and therefore contributes +-- no search path of its own: it neutralises whatever the shim injected without +-- opening a door to the host's /usr/include. A later --sysroot wins, so this +-- needs no cooperation from the shim. +-- +-- This is a local restatement of what mcpp's own link model does +-- (src/build/flags.cppm, "payload-first, --sysroot fallback"). Duplicating a +-- decision is a real cost; the alternative is worse, because openssl builds +-- outside mcpp's compile rules by construction and has no other way to be told. +-- If xim ever hands install() hooks a ready CC/CFLAGS, this should become that. +local function libc_payloads() + local glibc = pkginfo.build_dep("xim:glibc") or pkginfo.build_dep("glibc") + local kern = pkginfo.build_dep("xim:linux-headers") + or pkginfo.build_dep("linux-headers") + local groot = glibc and glibc.path + local kroot = kern and kern.path + if not (groot and os.isfile(path.join(groot, "include", "stdlib.h"))) then + return nil + end + return groot, kroot +end + local function cc_override() if os.host() == "macosx" and os.isfile("/usr/bin/cc") then return "CC=/usr/bin/cc " end - return "" + if os.host() ~= "linux" then return "" end + + local groot, kroot = libc_payloads() + if not groot then + log.warn("openssl: no xim:glibc payload resolved; leaving CC to PATH" + .. " (fails if the active subos carries no libc headers)") + return "" + end + local libdir = os.isdir(path.join(groot, "lib64")) + and path.join(groot, "lib64") or path.join(groot, "lib") + local cc = "gcc --sysroot=" .. groot + .. " -isystem " .. path.join(groot, "include") + if kroot and os.isdir(path.join(kroot, "include")) then + cc = cc .. " -isystem " .. path.join(kroot, "include") + end + cc = cc .. " -B " .. libdir .. " -L " .. libdir + return "CC=" .. sh_quote(cc) .. " " end -- Does this perl actually RUN, with the core modules Configure opens with? diff --git a/pkgs/g/grpc-plugin.lua b/pkgs/g/grpc-plugin.lua index ae9da6d..7cc49c6 100644 --- a/pkgs/g/grpc-plugin.lua +++ b/pkgs/g/grpc-plugin.lua @@ -31,28 +31,28 @@ package = { linux = { ["1.83.0"] = { url = { - GLOBAL = "https://github.com/mcpplibs/grpc-m/archive/refs/tags/v1.83.0-3.tar.gz", - CN = "https://gitcode.com/mcpp-res/grpc/releases/download/1.83.0/grpc-m-1.83.0-3.tar.gz", + GLOBAL = "https://github.com/mcpplibs/grpc-m/archive/refs/tags/v1.83.0-4.tar.gz", + CN = "https://gitcode.com/mcpp-res/grpc/releases/download/1.83.0/grpc-m-1.83.0-4.tar.gz", }, - sha256 = "9a0514a325e348fb013a89bb7b1acb9b41f42d5e9f3c92cee8be788e1e48d74f", + sha256 = "991e9928e0fde0bd9a9fdc80229d976438f03d953b6679a6a71edab258c54baa", }, }, macosx = { ["1.83.0"] = { url = { - GLOBAL = "https://github.com/mcpplibs/grpc-m/archive/refs/tags/v1.83.0-3.tar.gz", - CN = "https://gitcode.com/mcpp-res/grpc/releases/download/1.83.0/grpc-m-1.83.0-3.tar.gz", + GLOBAL = "https://github.com/mcpplibs/grpc-m/archive/refs/tags/v1.83.0-4.tar.gz", + CN = "https://gitcode.com/mcpp-res/grpc/releases/download/1.83.0/grpc-m-1.83.0-4.tar.gz", }, - sha256 = "9a0514a325e348fb013a89bb7b1acb9b41f42d5e9f3c92cee8be788e1e48d74f", + sha256 = "991e9928e0fde0bd9a9fdc80229d976438f03d953b6679a6a71edab258c54baa", }, }, windows = { ["1.83.0"] = { url = { - GLOBAL = "https://github.com/mcpplibs/grpc-m/archive/refs/tags/v1.83.0-3.tar.gz", - CN = "https://gitcode.com/mcpp-res/grpc/releases/download/1.83.0/grpc-m-1.83.0-3.tar.gz", + GLOBAL = "https://github.com/mcpplibs/grpc-m/archive/refs/tags/v1.83.0-4.tar.gz", + CN = "https://gitcode.com/mcpp-res/grpc/releases/download/1.83.0/grpc-m-1.83.0-4.tar.gz", }, - sha256 = "9a0514a325e348fb013a89bb7b1acb9b41f42d5e9f3c92cee8be788e1e48d74f", + sha256 = "991e9928e0fde0bd9a9fdc80229d976438f03d953b6679a6a71edab258c54baa", }, }, }, diff --git a/pkgs/g/grpc.lua b/pkgs/g/grpc.lua index 3c2cd09..c33d7b9 100644 --- a/pkgs/g/grpc.lua +++ b/pkgs/g/grpc.lua @@ -6,9 +6,10 @@ -- 索引(#151),满打满算一天,唯一的消费者是本仓的 tests/examples/grpc-module。 -- 为一天的历史留一份永久重复条目不划算。 -- --- 归档换成 v1.83.0-2:`src/` / `include/` / `third_party/` 与 v1.83.0 逐字节相同, --- 多出的只有 plugin/(grpc_cpp_plugin)与 rules/(grpcgen)。v1.83.0 的 sha256 已 --- 经发布过,移动 tag 会让它校验失败(mcpp#349:发布数据不得让程序失效),故另起。 +-- 归档现为 v1.83.0-4。历次重打包中 `src/` / `include/` / `third_party/` 与 +-- v1.83.0 逐字节相同,变的只有 plugin/(grpc_cpp_plugin)、rules/(grpcgen) +-- 与本包 manifest 的 codegen feature。已发布过的 sha256 不能靠移动 tag 复用 +-- (mcpp#349:发布数据不得让程序失效),所以每次重打包都另起一个 tag。 -- Form A descriptor: the public gRPC package ships its own mcpp.toml, so this -- file carries metadata and a download address and nothing else. mcpp's default -- lookup finds /*/mcpp.toml inside the GitHub source tarball wrap. @@ -58,19 +59,19 @@ package = { linux = { ["1.83.0"] = { url = { - GLOBAL = "https://github.com/mcpplibs/grpc-m/archive/refs/tags/v1.83.0-3.tar.gz", - CN = "https://gitcode.com/mcpp-res/grpc/releases/download/1.83.0/grpc-m-1.83.0-3.tar.gz", + GLOBAL = "https://github.com/mcpplibs/grpc-m/archive/refs/tags/v1.83.0-4.tar.gz", + CN = "https://gitcode.com/mcpp-res/grpc/releases/download/1.83.0/grpc-m-1.83.0-4.tar.gz", }, - sha256 = "9a0514a325e348fb013a89bb7b1acb9b41f42d5e9f3c92cee8be788e1e48d74f", + sha256 = "991e9928e0fde0bd9a9fdc80229d976438f03d953b6679a6a71edab258c54baa", }, }, macosx = { ["1.83.0"] = { url = { - GLOBAL = "https://github.com/mcpplibs/grpc-m/archive/refs/tags/v1.83.0-3.tar.gz", - CN = "https://gitcode.com/mcpp-res/grpc/releases/download/1.83.0/grpc-m-1.83.0-3.tar.gz", + GLOBAL = "https://github.com/mcpplibs/grpc-m/archive/refs/tags/v1.83.0-4.tar.gz", + CN = "https://gitcode.com/mcpp-res/grpc/releases/download/1.83.0/grpc-m-1.83.0-4.tar.gz", }, - sha256 = "9a0514a325e348fb013a89bb7b1acb9b41f42d5e9f3c92cee8be788e1e48d74f", + sha256 = "991e9928e0fde0bd9a9fdc80229d976438f03d953b6679a6a71edab258c54baa", }, }, -- No windows block, and the reason is a DEPENDENCY rather than gRPC: diff --git a/pkgs/g/grpcgen.lua b/pkgs/g/grpcgen.lua index eb7d01f..be94ded 100644 --- a/pkgs/g/grpcgen.lua +++ b/pkgs/g/grpcgen.lua @@ -31,28 +31,28 @@ package = { linux = { ["1.83.0"] = { url = { - GLOBAL = "https://github.com/mcpplibs/grpc-m/archive/refs/tags/v1.83.0-3.tar.gz", - CN = "https://gitcode.com/mcpp-res/grpc/releases/download/1.83.0/grpc-m-1.83.0-3.tar.gz", + GLOBAL = "https://github.com/mcpplibs/grpc-m/archive/refs/tags/v1.83.0-4.tar.gz", + CN = "https://gitcode.com/mcpp-res/grpc/releases/download/1.83.0/grpc-m-1.83.0-4.tar.gz", }, - sha256 = "9a0514a325e348fb013a89bb7b1acb9b41f42d5e9f3c92cee8be788e1e48d74f", + sha256 = "991e9928e0fde0bd9a9fdc80229d976438f03d953b6679a6a71edab258c54baa", }, }, macosx = { ["1.83.0"] = { url = { - GLOBAL = "https://github.com/mcpplibs/grpc-m/archive/refs/tags/v1.83.0-3.tar.gz", - CN = "https://gitcode.com/mcpp-res/grpc/releases/download/1.83.0/grpc-m-1.83.0-3.tar.gz", + GLOBAL = "https://github.com/mcpplibs/grpc-m/archive/refs/tags/v1.83.0-4.tar.gz", + CN = "https://gitcode.com/mcpp-res/grpc/releases/download/1.83.0/grpc-m-1.83.0-4.tar.gz", }, - sha256 = "9a0514a325e348fb013a89bb7b1acb9b41f42d5e9f3c92cee8be788e1e48d74f", + sha256 = "991e9928e0fde0bd9a9fdc80229d976438f03d953b6679a6a71edab258c54baa", }, }, windows = { ["1.83.0"] = { url = { - GLOBAL = "https://github.com/mcpplibs/grpc-m/archive/refs/tags/v1.83.0-3.tar.gz", - CN = "https://gitcode.com/mcpp-res/grpc/releases/download/1.83.0/grpc-m-1.83.0-3.tar.gz", + GLOBAL = "https://github.com/mcpplibs/grpc-m/archive/refs/tags/v1.83.0-4.tar.gz", + CN = "https://gitcode.com/mcpp-res/grpc/releases/download/1.83.0/grpc-m-1.83.0-4.tar.gz", }, - sha256 = "9a0514a325e348fb013a89bb7b1acb9b41f42d5e9f3c92cee8be788e1e48d74f", + sha256 = "991e9928e0fde0bd9a9fdc80229d976438f03d953b6679a6a71edab258c54baa", }, }, }, diff --git a/tests/examples/grpc-codegen/build.mcpp b/tests/examples/grpc-codegen/build.mcpp new file mode 100644 index 0000000..9ec8d70 --- /dev/null +++ b/tests/examples/grpc-codegen/build.mcpp @@ -0,0 +1,23 @@ +// One line, and it finds every .proto under proto/ by itself. +// +// The rule comes from the `grpcgen` package, which this project does NOT +// declare on linux/macOS: `grpc = { features = ["codegen"] }` re-exports it, +// along with protoc and grpc_cpp_plugin. Which tools gRPC codegen needs is the +// gRPC package's knowledge. +import std; +import mcpp; +import grpcgen; + +int main() { + // No gRPC on windows — compat.openssl has no windows xpm entry, so the + // grpc package is linux/macOS only and there is nothing to generate. The + // guard is on the CALL, not the import: `import grpcgen;` is a + // compile-time dependency and cannot be conditional (docs/01 §4.2 forbids + // #if-guarded imports), so the module is declared on windows too — it is a + // pure C++23 rule package with no platform-limited dependencies of its own. + // + // Same shape as tests/examples/protobuf-protoc: return 0 so the member + // still builds, and let the test compile to a visible skip. + if (std::string_view(mcpp::target_os()) == "windows") return 0; + return grpcgen::generate_all() ? 0 : 1; +} diff --git a/tests/examples/grpc-codegen/mcpp.toml b/tests/examples/grpc-codegen/mcpp.toml new file mode 100644 index 0000000..db817a2 --- /dev/null +++ b/tests/examples/grpc-codegen/mcpp.toml @@ -0,0 +1,46 @@ +# grpc-codegen test project: the ONE-DEPENDENCY form of gRPC codegen. +# +# Its sibling tests/examples/grpc-module covers the module surface with no +# codegen at all. This member covers what that one's header says is impossible: +# +# "NO protoc output anywhere: gRPC's codegen needs host tools mcpp cannot +# hand a consumer" +# +# That stopped being true in mcpp 2026.8.6.2. `features = ["codegen"]` makes +# the grpc package re-export protoc, grpc_cpp_plugin and the grpcgen rule to +# whoever depends on it, so this manifest names ONE package and build.mcpp is +# one line — and the .proto below is compiled from a stub that did not exist +# when the build started. +# +# What this member protects, and what no other member can: +# * `reexport = true` really reaches a consumer through the published index +# (every other test of it is a path dependency in mcpp's own e2e); +# * `rerun_if_changed_glob` really drives `generate_all()` — the file list is +# never written down anywhere; +# * the host tools are built for the BUILD machine and produce stubs that +# link against the runtime this project links, which is the property the +# whole design exists to make inexpressible-to-get-wrong. +# +# linux + macOS only, for the same reason grpc-module is: compat.openssl has no +# windows xpm entry, so on windows this member carries no dependency and the +# test compiles to a no-op main(). +[package] +name = "grpc-codegen-tests" +version = "0.1.0" + +# `cfg(unix)`, not one block per OS: the condition is "everywhere gRPC +# resolves", and what excludes windows is compat.openssl having no xpm entry +# there — a single fact, so a single predicate. mcpp evaluates `unix` as +# family == "unix" (src/build/prepare.cppm, alongside any()/all()/not()). +[target.'cfg(unix)'.dependencies.grpc] +grpc = { version = "1.83.0", features = ["codegen"] } + +[target.'cfg(unix)'.build] +cxxflags = ["-DHAVE_GRPC=1"] + +# windows carries the RULE but not gRPC itself, so build.mcpp compiles (its +# `import grpcgen;` cannot be conditional) and then returns early. grpcgen is a +# pure C++23 rule package — no openssl, no platform-limited dependency — which +# is why it is available here while grpc is not. +[target.'cfg(windows)'.dependencies.mcpplibs] +grpcgen = { version = "1.83.0", host-module = true } diff --git a/tests/examples/grpc-codegen/proto/echo.proto b/tests/examples/grpc-codegen/proto/echo.proto new file mode 100644 index 0000000..1d8c390 --- /dev/null +++ b/tests/examples/grpc-codegen/proto/echo.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; +package echotest; + +message EchoRequest { string text = 1; } +message EchoReply { string text = 1; } + +service Echo { + rpc Say (EchoRequest) returns (EchoReply); +} diff --git a/tests/examples/grpc-codegen/tests/codegen.cpp b/tests/examples/grpc-codegen/tests/codegen.cpp new file mode 100644 index 0000000..747c875 --- /dev/null +++ b/tests/examples/grpc-codegen/tests/codegen.cpp @@ -0,0 +1,37 @@ +// Asserts the generated stubs exist, compile and carry the SERVICE — a +// protobuf-only run would produce echo.pb.* and no Echo::Service, so a +// half-configured codegen cannot pass this. +// +// HAVE_GRPC comes from this project's own cfg-gated cxxflags: the package is +// linux/macOS-only, so elsewhere this file is an empty main(). +#ifdef HAVE_GRPC + +#include +#include + +#include "echo.pb.h" +#include "echo.grpc.pb.h" + +int main() { + // The message half: a real generated type, round-tripped. + echotest::EchoRequest req; + req.set_text("mcpp"); + std::string wire; + if (!req.SerializeToString(&wire)) return 1; + echotest::EchoRequest back; + if (!back.ParseFromString(wire)) return 1; + if (back.text() != "mcpp") return 1; + + // The SERVICE half — this is what grpc_cpp_plugin produced, and what a + // protoc-only run would not have. + const std::string method = echotest::Echo::service_full_name(); + std::printf("service = %s\n", method.c_str()); + if (method != "echotest.Echo") return 1; + + std::printf("grpc-codegen: OK\n"); + return 0; +} + +#else +int main() { return 0; } +#endif diff --git a/tests/examples/grpc-module/mcpp.toml b/tests/examples/grpc-module/mcpp.toml index 714b9a8..d11bd9a 100644 --- a/tests/examples/grpc-module/mcpp.toml +++ b/tests/examples/grpc-module/mcpp.toml @@ -7,27 +7,30 @@ # resolve from the published index, which is the point: this member proves the # descriptor works against the real dependency set. # -# NO protoc output anywhere: gRPC's codegen needs host tools mcpp cannot hand a -# consumer, so this exercises the module surface instead. grpc-m's own -# examples/helloworld covers the generated-stub path end to end. +# NO protoc output anywhere: this member exercises the MODULE surface. Codegen +# is a separate member, tests/examples/grpc-codegen, which declares one +# dependency and lets the grpc package hand it the whole toolchain. +# +# (This used to read "gRPC's codegen needs host tools mcpp cannot hand a +# consumer". That stopped being true in mcpp 2026.8.6.2 — `reexport = true` +# is exactly the mechanism for handing them over.) [package] name = "grpc-module-tests" version = "0.1.0" -# linux + macOS only: the package has no windows xpm entry (its compat.openssl +# unix only: the package has no windows xpm entry (its compat.openssl # dependency has none yet), so on windows this member carries no dependency at # all and the test compiles to a no-op main() — the same shape # tests/examples/openssl uses for the same underlying reason. -[target.'cfg(linux)'.dependencies.grpc] -grpc = "1.83.0" - -[target.'cfg(linux)'.build] -cxxflags = ["-DHAVE_GRPC=1"] - -[target.'cfg(macos)'.dependencies.grpc] +# +# One `cfg(unix)` rather than a linux block and an identical macos block: the +# condition is a single fact ("gRPC resolves everywhere except windows"), so it +# should be written once. mcpp evaluates `unix` as family == "unix" +# (src/build/prepare.cppm, alongside any()/all()/not()). +[target.'cfg(unix)'.dependencies.grpc] grpc = "1.83.0" -[target.'cfg(macos)'.build] +[target.'cfg(unix)'.build] cxxflags = ["-DHAVE_GRPC=1"] [indices] diff --git a/tests/member-timings.tsv b/tests/member-timings.tsv index 2c8a912..8c844db 100644 --- a/tests/member-timings.tsv +++ b/tests/member-timings.tsv @@ -28,6 +28,7 @@ linux godot-cpp 573 linux godot-cpp-module 549 linux godot-cpp-module-v10 392 linux godot-cpp-v10 504 +linux grpc-codegen 3563 linux grpc-module 1701 linux gui-stack 81 linux imgui 6 @@ -89,6 +90,7 @@ macos godot-cpp 333 macos godot-cpp-module 256 macos godot-cpp-module-v10 215 macos godot-cpp-v10 230 +macos grpc-codegen 1715 macos grpc-module 880 macos gui-stack 1 macos imgui 4 @@ -152,6 +154,7 @@ windows godot-cpp 742 windows godot-cpp-module 636 windows godot-cpp-module-v10 684 windows godot-cpp-v10 566 +windows grpc-codegen 31 windows grpc-module 1 windows gui-stack 1 windows imgui 6