Skip to content

ci(winhdr): classify Winsock2/asio headers by dependency, not directory#2651

Merged
stephenberry merged 1 commit into
mainfrom
ci/winhdr-classify-by-dependency
Jun 19, 2026
Merged

ci(winhdr): classify Winsock2/asio headers by dependency, not directory#2651
stephenberry merged 1 commit into
mainfrom
ci/winhdr-classify-by-dependency

Conversation

@stephenberry

Copy link
Copy Markdown
Owner

Follow-up to #2630. Makes the Windows header-compatibility check classify headers by their actual Winsock2/asio dependency instead of by hard-coded directory.

Problem

The check splits headers into a WIN32_LEAN_AND_MEAN group and an unsanitized group using directory globs (net/*, rpc/*) plus an explicit list. That's correct for today's tree but fragile: a future header that pulls in Winsock2/asio from outside those directories silently lands in the unsanitized group and fails with an opaque Winsock.h-vs-Winsock2.h redefinition error, with the fix buried in this CI CMakeLists.txt.

Change

Derive the lean set from the headers' own #include directives: seed on direct asio/winsock includes, then propagate along the rooted "glaze/..." include graph to a fixed point. The set now tracks real dependencies and stays correct as headers are added, moved, or renamed.

On the current tree this reduces the lean group from 20 (by directory) to the 6 headers that actually reach Winsock2/asio:

glaze/ext/glaze_asio.hpp
glaze/file/hostname_include.hpp
glaze/net/http_client.hpp
glaze/net/http_server.hpp
glaze/net/websocket_client.hpp
glaze/net/websocket_connection.hpp

The 14 over-matched headers move to the unsanitized group, where they're additionally checked against the small macro (lean mode omits it) — a small coverage gain.

This also drops the load-bearing registry.hpp include-ordering hack: the non-standalone *_registry_impl.hpp fragments (which specialize templates declared only in their parent) are excluded from direct inclusion and exercised transitively through rpc/registry.hpp.

Aggregate-TU rationale (doc only)

Also adds a comment recording why each group is compiled as one aggregate translation unit rather than per-header/per-subdir: a local sweep found ~25 public headers are not standalone (they rely on declarations from an earlier include, e.g. util/dump.hppstring_literal, core/array_apply.hppsize_t). Splitting would surface spurious failures unrelated to Windows macros. Real macro collisions are still pinpointed via the compiler's #include stack and the named macro-preservation #error checks.

Verification

  • The classification logic and generated TUs were validated locally with cmake -P against the live tree: 240 unsanitized + 6 lean + 3 excluded fragments = 249; fragments appear in neither TU; net/http.hpp (#undef DELETE) sits safely in the unsanitized TU with DELETE correctly not asserted per-header.
  • The change is compile-neutral by construction (both TUs define min/max/ERROR identically; only Winsock differs). The windows-header-compatibility workflow runs on this PR and is the authoritative cross-check.

The Windows header-compatibility check split headers into a
WIN32_LEAN_AND_MEAN group and an unsanitized group using hard-coded
directory globs (net/*, rpc/*) plus an explicit list. That is correct for
today's tree but fragile: a future header that pulls in Winsock2/asio from
outside those directories silently lands in the unsanitized group and
fails with an opaque Winsock-vs-Winsock2 redefinition error, with the fix
buried in this CI CMakeLists.

Derive the lean set from the headers' own #include directives instead:
seed on direct asio/winsock includes, then propagate along the rooted
"glaze/..." include graph to a fixed point. The set now tracks real
dependencies and stays correct as headers are added, moved, or renamed.
On the current tree this reduces the lean group from 20 (by directory) to
the 6 headers that actually reach Winsock2/asio; the 14 over-matched
headers move to the unsanitized group, where they are additionally checked
against the `small` macro.

This also drops the load-bearing registry.hpp include-ordering hack: the
non-standalone *_registry_impl.hpp fragments (which specialize templates
declared only in their parent) are excluded from direct inclusion and
exercised transitively through rpc/registry.hpp.

Also documents why each header group is compiled as one aggregate
translation unit rather than per-header or per-subdir: many Glaze headers
are not standalone (they depend on declarations from an earlier include),
so splitting would surface spurious failures unrelated to Windows macros.
Real macro collisions remain pinpointed via the compiler's #include stack
and the named macro-preservation #error checks.
@stephenberry stephenberry merged commit 3808593 into main Jun 19, 2026
54 checks passed
@stephenberry stephenberry deleted the ci/winhdr-classify-by-dependency branch June 19, 2026 01:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant