Skip to content

Commit 675a544

Browse files
committed
test(eui-neo): un-gate both window members to all three platforms
Both members were [target.'cfg(linux)']-gated, which made them compile to `int main() { return 0; }` on macOS and Windows — trivially green, zero coverage, and it left `glfw_app_main.cpp` uncompiled on every platform after all. imgui-window and gui-stack are linux-only because they pull the X11 packages directly. compat.eui-neo and compat.glfw are not, and the four existing eui-neo members already build on every runner. Audited before un-gating: every core/ header these TUs reach (window_types, window_backend, render_backend, primitive_geometry, render_surface, platform, input_state, input_types, ime_bridge) is platform-clean — no windows.h, no Cocoa, no GL — and every GLFW entry point used is portable. core::releaseInputQueue reaches eui_ime_uninstall_message_filter, which ime_bridge.c defines on all three. Also add GLFW_INCLUDE_NONE before <GLFW/glfw3.h>, as core/input/input_state.h does, so GLFW does not pull a GL header of its own choosing (GL/gl.h on Windows, the deprecated OpenGL/gl.h on macOS). Drop the redundant `glfw = "3.4"` from both members. mcpp propagates a transitive dependency's include_dirs and link inputs to the consumer, and compat.eui-neo already depends on compat.glfw everywhere — verified by removing the line and rebuilding. Matches the existing convention: eui-neo-sdl2 includes <SDL.h>/<curl/curl.h> and eui-neo-vulkan calls vkEnumerateInstanceVersion, neither re-declaring those packages. macOS/Windows are CI-verified only; there is no runner for either here. The opt-in windowed run stays linux-only (both runners are headless), same as imgui-window. Descriptor comment fix while re-probing the encoding: it claimed "there is no `default-features = false` (mcpp#242)". Wrong — #242 shipped in 0.0.98. The accurate statement is that its seedDefault gate is manifest-side and a `default` feature declared in an xpkg DESCRIPTOR is never seeded at all, so the consumer has nothing to switch off. Re-probed with `default = { defines = { ... } }` and a plain consumer: macro absent on 0.0.109. MCPP_VERSION deliberately stays at 0.0.109: #242 (0.0.98), #243 (0.0.99) and #233/#240 (0.0.97/0.0.98) are all at or below the pin, and nothing in 2026.7.27.1 .. 2026.7.29.2 touches feature semantics, so a bump buys no simplification here.
1 parent b56db0b commit 675a544

6 files changed

Lines changed: 133 additions & 49 deletions

File tree

‎.agents/docs/2026-07-30-eui-neo-window-and-app-main-members.md‎

Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,28 @@ per consuming project).
3939
| `eui-neo-window` | off | hand-written `main()` in the test TU | `core::window`, OpenGL backend, `ScopedRenderBackend`, paced loop, freetype text |
4040
| `eui-neo-app-main` | **on** | upstream `glfw_app_main.cpp` | the feature's source compiles; `main` really comes from the package |
4141

42-
Both are `[target.'cfg(linux)']`-gated, matching `imgui-window`, `gui-stack` and the
43-
rest of the X11/GLFW stack in this index. Off-Linux they declare no dependencies and
44-
the test TU compiles to `int main() { return 0; }`.
45-
46-
Both declare `compat.glfw` **directly** rather than leaning on the transitive edge:
47-
each calls GLFW itself (`glfwPollEvents`/`glfwWindowShouldClose` in one,
48-
`glfwSetWindowShouldClose` in the other), because EUI's `core::window` facade
49-
exposes no event-pump entry point.
42+
Both build on **all three platforms**, deliberately not `cfg`-gated. `imgui-window`
43+
and `gui-stack` are linux-only because they pull the X11 packages directly;
44+
`compat.eui-neo` and `compat.glfw` are not, and the four existing eui-neo members
45+
already build on every runner. Audited before un-gating: every `core/` header these
46+
TUs reach (`window_types.h`, `window_backend.h`, `render_backend.h`,
47+
`primitive_geometry.h`, `render_surface.h`, `platform.h`, `input_state.h`,
48+
`input_types.h`, `ime_bridge.h`) is platform-clean — no `windows.h`, no Cocoa, no GL
49+
— and every GLFW entry point used is portable. `core::releaseInputQueue` reaches
50+
`eui_ime_uninstall_message_filter`, which `ime_bridge.c` defines on all three
51+
platforms.
52+
53+
Both add `GLFW_INCLUDE_NONE` before `<GLFW/glfw3.h>`, as `core/input/input_state.h`
54+
does, so GLFW does not pull a GL header of its own choosing (`GL/gl.h` on Windows,
55+
the deprecated `OpenGL/gl.h` on macOS). EUI reaches GL through `compat.glad`.
56+
57+
Neither re-declares `compat.glfw`, even though both call GLFW directly (EUI's
58+
`core::window` facade exposes no event-pump entry point). mcpp propagates a
59+
transitive dependency's `include_dirs` and link inputs to the consumer, and
60+
`compat.eui-neo` already depends on `compat.glfw` on every platform. Verified by
61+
dropping the line and rebuilding both members. This matches the existing
62+
convention: `eui-neo-sdl2` includes `<SDL.h>` and `<curl/curl.h>`, `eui-neo-vulkan`
63+
calls `vkEnumerateInstanceVersion`, and neither declares those packages.
5064

5165
## Why the run is opt-in
5266

@@ -126,15 +140,41 @@ by running it:
126140
Neither is a descriptor bug; both are upstream behaviour a consumer must know, and
127141
neither was discoverable from the headless members.
128142
143+
## Why the mcpp pin does NOT move
144+
145+
Checked before writing any of this, because the encoding in this descriptor is ugly
146+
enough to be worth re-testing against a newer client. `MCPP_VERSION` stays at
147+
**0.0.109**.
148+
149+
The three capabilities that could simplify `compat.eui-neo` all landed **at or before
150+
0.0.109**, which is already the pin: `default-features = false` (#242, 0.0.98),
151+
feature→feature forwarding (#243, 0.0.99), obj-path disambiguation (#233/#240,
152+
0.0.97/0.0.98). The four releases after it — `2026.7.27.1`, `.28.2`, `.29.1`,
153+
`.29.2` — carry the date-based version scheme, the private-glibc `LD_LIBRARY_PATH`
154+
fix (#291), 4-segment version parsing, xlings pin hygiene, `[build].defines` before
155+
the P1689 scan (#297), the musl/MinGW `build.mcpp` host helper (#298), `mcpp add`
156+
index validation (#307) and SemVer routing (#309). `git log v0.0.109..HEAD` over the
157+
feature/resolver/plan sources returns nothing that touches feature semantics.
158+
159+
One correction to the descriptor's own comment while re-probing: it claimed "there is
160+
no `default-features = false` (mcpp#242)". That is wrong — #242 shipped in 0.0.98.
161+
The accurate statement is that its `seedDefault` gate is **manifest**-side, and a
162+
`default` feature declared in an xpkg **descriptor** is never seeded at all, so the
163+
consumer has nothing to switch off. Re-probed by giving the package
164+
`default = { defines = { "MCPP_PROBE_DEFAULT_APPLIED=1" } }` and checking the macro
165+
from a plain consumer TU: absent on 0.0.109. The generated-header + forced-`-include`
166+
encoding therefore stays as it is. Worth filing upstream as a descriptor-side gap in
167+
#242's coverage.
168+
129169
## Verification
130170
131171
Local, mcpp **0.0.109** (matching `validate.yml` `env.MCPP_VERSION`), linux-x86_64,
132172
gcc 16.1.0, X11 display with NVIDIA GL 4.6.
133173
134174
```
135175
headless MCPP_RUN_WINDOW=1
136-
eui-neo-window ok (0.08s) ok (60 frames, 120 rect / 120 text draws)
137-
eui-neo-app-main ok (0.07s) ok (60 frames, 118 rect / 118 text draws)
176+
eui-neo-window ok (0.08s) ok (60 frames in 0.98s, 120 rect / 120 text draws)
177+
eui-neo-app-main ok (0.08s) ok (60 frames, 118 rect / 118 text draws)
138178
eui-neo (existing) ok
139179
eui-neo-markdown (existing) ok
140180
```
@@ -143,10 +183,25 @@ eui-neo-markdown (existing) ok
143183
`check_cross_package_refs.lua` all pass on the touched descriptor. The descriptor
144184
change is comment-only.
145185
186+
**macOS and Windows are CI-verified only.** There is no runner for either here, so
187+
the build+link half of both members on those platforms is asserted by the
188+
`workspace (macos)` / `workspace (windows)` legs, not locally. Two things are new
189+
there and worth watching on the first run:
190+
191+
* `glfw_app_main.cpp` has never been compiled on any platform. Its Windows half
192+
(`<mmsystem.h>`, `GLFW_EXPOSE_NATIVE_WIN32`, `glfw3native.h`, `timeBeginPeriod`,
193+
`MonitorFromWindow`, `EnumDisplaySettingsW`) needs `-lwinmm` and `-luser32`, both
194+
already in the descriptor's `windows.ldflags`.
195+
* these are the first members to link `compat.glfw` off Linux from their **own** code
196+
rather than through `compat.eui-neo`, which exercises the macOS
197+
`Cocoa`/`IOKit`/`CoreFoundation` frameworks and the Windows `-lgdi32` from a
198+
consumer link.
199+
146200
## Not done
147201
148202
* `app-main-sdl2` stays uncovered. It is the same shape against `compat.sdl2`, and
149203
covering it means a fifth window member for one `sources` line; worth doing if the
150204
SDL2 window backend gains real users.
151-
* macOS/Windows only get the build+link half, same as `imgui-window`. The opt-in run
152-
has been exercised on linux-x86_64 only.
205+
* The **opt-in windowed run** has been exercised on linux-x86_64 only. macOS and
206+
Windows runners are headless, so they get build+link only — same as
207+
`imgui-window`.

‎pkgs/e/compat.eui-neo.lua‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,18 @@ package = {
174174
-- / else-GLFW. Define both halves of either pair and the first one
175175
-- silently wins, ignoring what the consumer asked for.
176176
--
177-
-- mcpp features are purely additive and there is no
178-
-- `default-features = false` (mcpp#242). The obvious encodings all
179-
-- fail on 0.0.109, each in its own way — all three verified with
180-
-- probes, because each failure is silent:
177+
-- mcpp features are purely additive here. `default-features = false`
178+
-- does exist (mcpp#242, since 0.0.98) — but its `seedDefault` gate lives
179+
-- on the MANIFEST side, and a `default` feature declared in an xpkg
180+
-- DESCRIPTOR is never seeded to begin with, so there is nothing for the
181+
-- consumer to switch off. Re-probed on 0.0.109 by giving this package a
182+
-- `default = { defines = {...} }` and checking the macro from a plain
183+
-- consumer: absent. Unchanged in the newest mcpp (2026.7.29.2) — nothing
184+
-- has touched the feature system since 0.0.109, so a version bump buys
185+
-- no simplification of the encoding below.
186+
--
187+
-- The obvious encodings all fail on 0.0.109, each in its own way — all
188+
-- three verified with probes, because each failure is silent:
181189
--
182190
-- * `default = { defines/sources/deps = … }` is INERT. Not
183191
-- "suppressed when features are named" — never applied at all. A

‎tests/examples/eui-neo-app-main/mcpp.toml‎

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,24 @@
1010
# enables `app-main` may not contain any translation unit of its own that
1111
# defines main(). See the note in pkgs/e/compat.eui-neo.lua.
1212
#
13-
# Linux-only (cfg): the whole X11/GLFW/GL stack is linux-gated across this
14-
# index, matching tests/examples/imgui-window. Off-Linux the member has no
15-
# dependencies and the test TU compiles to a no-op.
13+
# ALL THREE PLATFORMS, deliberately not cfg-gated. `app-main` selects upstream's
14+
# GLFW entry point, which is the default window backend on every platform, and
15+
# nothing in it is linux-specific — but until this member existed it was compiled
16+
# on NONE of them, so the windows `-fno-char8_t` / winmm+user32+pdh half of the
17+
# descriptor and the macOS Cocoa link were both unexercised for that TU.
1618
#
17-
# compat.glfw is a DIRECT dependency because the test TU calls
18-
# glfwSetWindowShouldClose() itself to bound the opt-in window run.
19+
# compat.glfw is NOT re-declared here even though this TU calls
20+
# glfwSetWindowShouldClose()/glfwGetCurrentContext() itself to bound the opt-in
21+
# window run: mcpp propagates a transitive dependency's `include_dirs` and link
22+
# inputs to the consumer, and compat.eui-neo already depends on compat.glfw on
23+
# every platform. Same convention as tests/examples/eui-neo-sdl2 and
24+
# eui-neo-vulkan, which include <SDL.h> / <vulkan/vulkan.h> without re-declaring
25+
# either.
1926
#
2027
# The `compat` index redirect is inherited from the workspace root.
2128
[package]
2229
name = "eui-neo-app-main-tests"
2330
version = "0.1.0"
2431

25-
[target.'cfg(linux)'.dependencies.compat]
32+
[dependencies.compat]
2633
eui-neo = { version = "0.5.3", features = ["app-main"] }
27-
glfw = "3.4"

‎tests/examples/eui-neo-app-main/tests/app_main.cpp‎

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,22 @@
2222
// point belongs to the package, the gate cannot live in main() — it lives in
2323
// a namespace-scope constructor, which runs before it. Headless CI links the
2424
// real binary, executes the guard, and exits 0.
25-
#if defined(__linux__)
26-
25+
//
26+
// Builds on all three platforms: GLFW is upstream's default window backend
27+
// everywhere, and nothing below is platform-specific.
2728
#include <eui_neo.h>
2829

2930
#include "core/render/render_backend.h"
3031

32+
// GLFW would otherwise pull a GL header of its own choosing (GL/gl.h on Windows,
33+
// the deprecated OpenGL/gl.h on macOS). EUI reaches GL through compat.glad, so
34+
// this TU wants the GLFW API and nothing else — the same thing
35+
// core/input/input_state.h does before its own include.
36+
#ifndef GLFW_INCLUDE_NONE
37+
#define GLFW_INCLUDE_NONE
38+
#endif
3139
#include <GLFW/glfw3.h>
40+
3241
import std;
3342

3443
namespace {
@@ -162,11 +171,3 @@ void compose(eui::Ui& ui, const eui::Screen& screen) {
162171
}
163172

164173
} // namespace app
165-
166-
#else
167-
168-
// Off-Linux the member declares no dependencies, so there is nothing to link
169-
// against and no package-supplied main() either — this TU has to provide one.
170-
int main() { return 0; }
171-
172-
#endif

‎tests/examples/eui-neo-window/mcpp.toml‎

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,30 @@
88
# construction (json + platform flags), so window creation, the OpenGL backend,
99
# the text/freetype path and the render loop were previously uncovered.
1010
#
11-
# Linux-only (cfg), matching tests/examples/imgui-window and the rest of the
12-
# X11/GLFW stack in this index. The window run needs a display and is opt-in
13-
# (MCPP_RUN_WINDOW=1); headless CI compiles + links the whole loop and returns 0.
11+
# ALL THREE PLATFORMS, deliberately not cfg-gated. Unlike tests/examples/
12+
# imgui-window and gui-stack — linux-only because they pull the X11 packages
13+
# directly — compat.eui-neo and compat.glfw both build on linux/macosx/windows,
14+
# and the four existing eui-neo members already prove that on every runner. What
15+
# was never compiled anywhere is a CONSUMER translation unit that includes
16+
# core/window, core/render and <GLFW/glfw3.h>, which is exactly what this member
17+
# is. None of the headers it reaches carry platform-specific includes.
1418
#
15-
# compat.glfw is a DIRECT dependency, not just a transitive one: this project's
16-
# own translation unit calls glfwPollEvents()/glfwWindowShouldClose(), because
17-
# EUI's core::window facade exposes no event-pump entry point.
19+
# The window run needs a display and is opt-in (MCPP_RUN_WINDOW=1); headless CI
20+
# compiles + links the whole loop on each OS and returns 0.
21+
#
22+
# compat.glfw is NOT re-declared here even though this TU calls glfwPollEvents()
23+
# and glfwWindowShouldClose() itself (EUI's core::window facade exposes no
24+
# event-pump entry point). mcpp propagates a transitive dependency's
25+
# `include_dirs` and link inputs to the consumer, so the edge through
26+
# compat.eui-neo is enough — verified by dropping the line and rebuilding. Same
27+
# convention as tests/examples/eui-neo-sdl2 (`#include <SDL.h>`, `<curl/curl.h>`)
28+
# and eui-neo-vulkan (`vkEnumerateInstanceVersion`), neither of which re-declares
29+
# what it reaches through a feature.
1830
#
1931
# The `compat` index redirect is inherited from the workspace root.
2032
[package]
2133
name = "eui-neo-window-tests"
2234
version = "0.1.0"
2335

24-
[target.'cfg(linux)'.dependencies.compat]
36+
[dependencies.compat]
2537
eui-neo = "0.5.3"
26-
glfw = "3.4"

‎tests/examples/eui-neo-window/tests/window.cpp‎

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,24 @@
1616
// The window run needs a display, so it is opt-in via MCPP_RUN_WINDOW=1, exactly
1717
// as in tests/examples/imgui-window. Headless CI compiles and links the whole
1818
// loop — which is where a descriptor regression would surface — and returns 0.
19-
#if defined(__linux__)
20-
19+
//
20+
// Builds on all three platforms. Every core/ header below is platform-clean (no
21+
// windows.h, no Cocoa, no GL), and every GLFW entry point used here is portable,
22+
// so there is no reason to cfg-gate this the way the X11-consuming members are.
2123
#include <eui_neo.h>
2224

2325
#include "core/input/input_state.h"
2426
#include "core/platform/platform.h"
2527
#include "core/render/render_backend.h"
2628
#include "core/window/window_backend.h"
2729

30+
// GLFW would otherwise pull a GL header of its own choosing (GL/gl.h on Windows,
31+
// the deprecated OpenGL/gl.h on macOS). EUI reaches GL through compat.glad, so
32+
// this TU wants the GLFW API and nothing else — the same thing
33+
// core/input/input_state.h does before its own include.
34+
#ifndef GLFW_INCLUDE_NONE
35+
#define GLFW_INCLUDE_NONE
36+
#endif
2837
#include <GLFW/glfw3.h>
2938

3039
import std;
@@ -304,9 +313,3 @@ int main() {
304313
std::println("compat.eui-neo[own main]: linked; window run is opt-in (MCPP_RUN_WINDOW=1)");
305314
return 0;
306315
}
307-
308-
#else
309-
310-
int main() { return 0; }
311-
312-
#endif

0 commit comments

Comments
 (0)