feat: add compat.c-ares 1.34.5 - #149
Merged
Merged
Conversation
The last index-side piece before grpc-m: with abseil, protobuf(+upb), re2 and
now c-ares, the gRPC package has to vendor only gRPC's own source.
WHY IT IS HERE AT ALL. An earlier plan was to ship the first gRPC without
c-ares, since upstream has a sanctioned knob (grpc_no_ares=true → GRPC_ARES=0).
That was the wrong call: gRPC enables c-ares by default and so does everyone
else, and an index package should not quietly ship less than upstream. The
shape is default-on, switchable off — grpc-m will carry Cargo-style
`[features] default = ["ares"]` and consumers turn it off with
`default-features = false`.
It cannot be built the other way round. mcpp features are ADDITIVE, so putting
-DGRPC_ARES=0 in the base flags and having the feature flip it to 1 would put
both on the command line. The off-switch therefore lives in grpc-m's
build.mcpp (emit GRPC_ARES=0 only when the feature is absent, and drop the 7
ares TUs), while the dependency stays declarative in [feature-deps.ares] —
build.mcpp is explicitly not allowed to add a registry dependency.
SHAPE. c-ares normally learns about its host from configure/CMake writing
ares_config.h. That step is replaced by a frozen per-OS snapshot under
generated_files — the same shape compat.ffmpeg / compat.curl / compat.sdl2
already use. The upstream RELEASE tarball (a `make dist` product, not the tag
archive) already ships include/ares_build.h and src/lib/config-win32.h, so
neither is synthesized here.
The snapshots are gRPC 1.83.0's own third_party/cares/config_{linux,darwin,
windows}/ares_config.h. Not borrowed at random: gRPC pins c-ares at exactly
this release (submodule d3a507e == tag v1.34.5) and maintains those files
precisely so the library can be built without c-ares' own build system.
KNOWN TRADE-OFF, recorded rather than hidden: those snapshots are more
conservative than 1.34.5's ares_config.h.cmake template — 96 of the template's
143 HAVE_* symbols, missing HAVE_EPOLL, HAVE_GETIFADDRS, HAVE_GETRANDOM,
HAVE_IF_NAMETOINDEX among others. Missing means 0, so c-ares takes portable
fallbacks (poll rather than epoll). All 91 TUs compile with zero warnings, so
this is a performance/feature degradation, not a functional gap; regenerating
richer snapshots from c-ares' own CMake is a follow-up.
Flags are upstream's (gRPC third_party/cares/cares.BUILD). Two are
load-bearing rather than hygiene: HAVE_CONFIG_H is what makes
src/lib/ares_setup.h include ares_config.h at all, and _GNU_SOURCE is required
on glibc — without it <unistd.h>/<string.h> hide gethostname, clock_gettime,
strcasecmp and getservbyport_r, and four TUs fail with implicit-declaration
errors. src/lib/**/*.c is safe to glob: upstream keeps tests and tools in
test/ and src/tools/, and no TU under src/lib defines main().
Verified cold with the pinned mcpp 2026.8.3.3, gcc@16.1.0,
MCPP_INDEX_MIRROR=GLOBAL, MCPP_BUILD_CACHE=local, target/ and .mcpp/ removed
first: `test result ok`, 92 objects linked (91 sources + the test).
The test is entirely OFFLINE — it never sends a DNS query, so it does not
depend on the runner's name resolution. It covers library init/cleanup, a
channel with options, a set/get round trip of the server list as CSV (real
string + record parsing), ares_inet_pton/ntop both ways, and ares_strerror,
and it asserts that malformed input is REJECTED (a bad server CSV,
"999.1.1.1") — otherwise "parsing succeeded" would prove nothing. It also
asserts the version is 1.34.5, so a silently different vendored version cannot
pass.
CN mirror published and closed-loop checked: mcpp-res/c-ares@1.34.5 returns
http=200 and is byte-identical to GLOBAL. Cross-package basename check: c-ares
collides with none of abseil / protobuf / upb / re2.
Alongside this, gRPC 1.83.0 was compiled in full with mcpp's gcc@16.1.0 —
1001 TUs (999 gRPC sources + 2 third_party/address_sorting), including the
resolver path that goes through this package's real headers and config
snapshot. The only extra include dirs needed are third_party/address_sorting/
include and third_party/xxhash, both of which have real content in gRPC's own
tree, and the only file that must be excluded is
src/core/ext/upb-gen/google/protobuf/descriptor.upb_minitable.c — byte-for-byte
identical to the bootstrap copy compat.protobuf's upb feature already brings.
Sunrisepeak
added a commit
that referenced
this pull request
Aug 4, 2026
The end of the gRPC track that #147 (abseil, protobuf), #148 (re2, the protobuf `upb` feature) and #149 (c-ares) built toward. gRPC itself lands as a Form A descriptor pointing at mcpplibs/grpc-m. WHY THIS ONE CANNOT BE A COMPAT DESCRIPTOR. Every other heavy library here points at an upstream tarball. gRPC publishes none: v1.83.0 has no release assets at all, and its tag archive carries abseil, protobuf, re2, boringssl and zlib as EMPTY submodule placeholders — one directory entry each — so there is nothing for url+sha256 to address. grpc-m's release tarball IS that artifact: upstream's src/ and include/ vendored with zero patches, plus the two third_party pieces gRPC really ships (address_sorting, xxhash). What it does NOT vendor is why it belongs on this index rather than standing alone: abseil, protobuf(+upb), re2, c-ares, OpenSSL and zlib all come from the packages here, so a consumer that also uses protobuf or abseil directly links ONE copy instead of colliding with a second vendored set. No CMake, no Bazel, no configure step — checked, not assumed: gRPC's tree contains no .h.in or config.h.cmake, and its generated upb code is checked in upstream, so mcpp needs only include paths. All 1001 TUs are compiled by the resolved toolchain, so nothing inherits a foreign C++ ABI the way an install()-driven CMake build would (which is what ruled that route out for gRPC in the first place). The source list is upstream's own — the union of add_library(gpr), grpc, grpc++ and address_sorting — and grpc-m's tools/gen_sources.py --check runs in that repo's CI to prove the manifest has not drifted from the vendored tree. One file is excluded: src/core/ext/upb-gen/google/protobuf/descriptor.upb_minitable.c, byte-for-byte identical to the bootstrap copy compat.protobuf's `upb` feature compiles. LINUX + MACOS ONLY, and the reason is a dependency rather than gRPC: compat.openssl has no windows xpm entry, so resolution there fails with E_NOT_FOUND before anything compiles, and gRPC's secure build cannot drop TLS. The member is gated the way tests/examples/openssl already is — cfg-gated dependency, no-op main() on windows. #150 is the fix for the underlying gap. The member drives `import grpc;` only and carries no protoc output: gRPC's codegen needs host tools mcpp cannot hand a consumer, so grpc-m's own examples/helloworld covers the generated-stub path while this member covers the module surface. It asserts the error path too (a Status that is NOT ok), so an always-OK stub could not pass. Verified with the pinned mcpp 2026.8.3.3, gcc@16.1.0, MCPP_BUILD_CACHE=local, target/ and .mcpp/ removed first — the package downloads from the descriptor's real release tarball and sha: Compiling mcpplibs.grpc v1.83.0 grpc::Version() = 1.83.0 grpc module: OK test result ok. 1 passed; 0 failed; finished in 247.85s grpc-m's own CI is green on both platforms for the tagged commit (linux 54m21s, macOS 29m49s), where examples/helloworld stands a real server on a loopback port and makes a real unary RPC. CN mirror published and closed-loop checked: mcpp-res/grpc@1.83.0 returns http=200 and is byte-identical to GLOBAL.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The last index-side piece before
grpc-m(follows #147, #148). With abseil,protobuf(+upb), re2 and now c-ares, the gRPC package has to vendor only gRPC's own
source.
Why it is here at all
An earlier plan was to ship the first gRPC without c-ares — upstream does have a
sanctioned knob (
grpc_no_ares=true→GRPC_ARES=0). That was the wrong call: gRPCenables c-ares by default and so does everyone else, and an index package should not
quietly ship less than upstream. The right shape is default-on, switchable off:
grpc-mwill carry Cargo-style[features] default = ["ares"], and consumers turn itoff with
default-features = false.It cannot be built the other way round. mcpp features are additive, so putting
-DGRPC_ARES=0in the base flags and having the feature flip it to1would put bothon the command line. The off-switch therefore lives in grpc-m's
build.mcpp(emitGRPC_ARES=0only when the feature is absent, and drop the 7 ares TUs), while thedependency stays declarative in
[feature-deps.ares]— build.mcpp is explicitly notallowed to add a registry dependency.
Shape: only one file is missing
c-ares normally learns about its host from configure/CMake writing
ares_config.h.That step is replaced by a frozen per-OS snapshot under
generated_files— the sameshape
compat.ffmpeg/compat.curl/compat.sdl2already use. The upstreamrelease tarball (a
make distproduct, not the tag archive) already shipsinclude/ares_build.handsrc/lib/config-win32.h, so neither is synthesized here.The snapshots are gRPC 1.83.0's own
third_party/cares/config_{linux,darwin,windows}/ ares_config.h. Not borrowed at random: gRPC pins c-ares at exactly this release(submodule
d3a507e== tagv1.34.5) and maintains those files precisely so thelibrary can be built without c-ares' own build system.
Known trade-off, recorded rather than hidden: those snapshots are more conservative
than 1.34.5's
ares_config.h.cmaketemplate — 96 of the template's 143HAVE_*symbols, missing
HAVE_EPOLL,HAVE_GETIFADDRS,HAVE_GETRANDOM,HAVE_IF_NAMETOINDEXamong others. Missing means 0, so c-ares takes portable fallbacks(poll rather than epoll). All 91 TUs compile with zero warnings, so this is a
performance/feature degradation, not a functional gap; regenerating richer snapshots
from c-ares' own CMake is a follow-up.
Flags are upstream's, and two are load-bearing
From gRPC's
third_party/cares/cares.BUILD:HAVE_CONFIG_H— without itsrc/lib/ares_setup.hnever includesares_config.hat all._GNU_SOURCE— required on glibc: without it<unistd.h>/<string.h>hidegethostname,clock_gettime,strcasecmpandgetservbyport_r, and four TUs failwith implicit-declaration errors (measured).
src/lib/**/*.cis safe to glob: upstream keeps tests and tools intest/andsrc/tools/, and no TU undersrc/libdefinesmain().Verification
Cold, CI configuration (pinned mcpp
2026.8.3.3, gcc@16.1.0,GLOBAL,MCPP_BUILD_CACHE=local),target/and.mcpp/removed first:test result ok,92 objects linked (91 sources + the test).
The test is entirely offline — it never sends a DNS query, so it does not depend on
the runner's name resolution. It covers library init/cleanup, a channel with options, a
set/get round trip of the server list as CSV (real string + record parsing),
ares_inet_pton/ntopboth ways, andares_strerror— and asserts that malformedinput is rejected (a bad server CSV,
999.1.1.1), otherwise "parsing succeeded"would prove nothing. It also asserts the version is 1.34.5, so a silently different
vendored version cannot pass.
CN mirror published and closed-loop checked:
mcpp-res/c-ares@1.34.5,http=200,byte-identical to GLOBAL. Cross-package basename check: c-ares collides with none of
abseil / protobuf / upb / re2.
Alongside this: gRPC compiled in full
gRPC 1.83.0 was compiled end-to-end with mcpp's gcc@16.1.0 — 1001 TUs (999 gRPC
sources + 2
third_party/address_sorting), including the resolver path that goesthrough this package's real headers and config snapshot. The only extra include dirs
needed are
third_party/address_sorting/includeandthird_party/xxhash, both withreal content in gRPC's own tree. The only file that must be excluded is
src/core/ext/upb-gen/google/protobuf/descriptor.upb_minitable.c— byte-for-byteidentical to the bootstrap copy
compat.protobuf'supbfeature already brings.Full write-up:
.agents/docs/2026-08-04-add-c-ares-plan.md.