feat: add compat.eui-neo 0.5.3 with selectable render and window backends - #133
Conversation
EUI-NEO as a Form B compat package: ~20 core TUs compiled into one lib, public headers exposed via include_dirs, so consumers write `#include <eui_neo.h>`. The C++23 module surface is out of scope — upstream ships no module interface units. Sourced from upstream's v0.5.3 release tag with a real sha256, not a fork's branch head. Upstream vendors freetype/glfw/libpng/zlib/glad/tray/yyjson/md4c under 3rd/; none are built here — each is already in this index at the same version, which is what the six packages from mcpplibs#131 were for. Two features: `app-main` gates upstream's glfw entry point (the compat.gtest `main` pattern), `markdown` pulls compat.md4c and publishes EUI_HAS_MD4C as an interface define so the header-only component compiles in on the consumer side. core/platform/platform.cpp goes through a uniquely named generated TU. It collides with compat.glfw's src/platform.c in mcpp's flat per-link obj/ dir (mcpp#233/#240), and the collision was dropping BOTH objects: a cold 646-object link had neither core::platform::* nor _glfwSelectPlatform in it, and still went green because nothing referenced them. With the stub the link carries 648 objects and both are back. Verified cold on linux-x86_64 with mcpp 0.0.109 (the validate.yml pin): `mcpp test -p eui-neo` and `mcpp test -p eui-neo-markdown` both pass, the latter asserting the md4c parser is really active while the former asserts it is really gated off. Design: .agents/docs/2026-07-29-add-eui-neo-plan.md Supersedes the descriptor originally proposed in mcpplibs#133 (previous head 3f862e8). Co-authored-by: FarnaHerry <108510510+FarnaHerry@users.noreply.github.com> Co-authored-by: SPeak Agent <248744407+speak-agent@users.noreply.github.com>
3f862e8 to
d3541a1
Compare
|
Force-pushed a rebase + rewrite of this branch (previous head Two reasons it turned into a rewrite rather than a plain rebase: 1. 20 of the 23 files were already on 2. The package was compiling zero translation units, and CI was green. The That also explains the note in the old test — "Form B to Form A include propagation not yet supported" was a misdiagnosis. Other changes worth calling out:
And one thing this surfaced that is not specific to this PR: Verified cold on linux-x86_64 with mcpp 0.0.109 — both members pass, feature gating checked in both directions, full |
8a654e2 to
ff226c0
Compare
ff226c0 to
2047c79
Compare
7c20b79 to
c35884e
Compare
…ends EUI-NEO as a Form B compat package: the core TUs compiled into one lib, public headers exposed via include_dirs, so consumers write `#include <eui_neo.h>`. The C++23 module surface is out of scope — upstream ships no module interface units. Builds on mcpplibs#134 (compat.vulkan / sdl2 / curl), and carries two fixes to that half that only a machine with a GPU could have found — see below. Backend selection. Upstream compiles exactly one render backend and one window backend, dispatching on `#if OPENGL ... #elif VULKAN` and `#if SDL2` / else-GLFW, so defining both halves of either pair silently picks the first. mcpp features are additive with no `default-features = false` (mcpp#242), and all three obvious encodings fail silently: a `default` feature carrying defines/sources/deps is inert, `default = { implies = ... }` always applies, and a package-level define cannot be unset. Verified with probes on 0.0.109 and 2026.7.29.1. What works is resolving the choice in the preprocessor from the -DMCPP_FEATURE_<NAME> flags mcpp already passes, via a force-included header. That exposed a second problem: mcpp routes `cflags` to C translation units and `cxxflags` to C++ ones. The first revision carried only `cflags = { "-DEUI_RENDER_BACKEND_OPENGL=1" }`, so render_backend.cpp never saw it — the package built, linked, passed its tests, and had no render backend. REAL GUI VERIFICATION, on a workstation with an X display and an RTX 4080: all four backend combinations open a window, create the backend and present three frames, with no environment variables set. Getting the Vulkan half there needed two changes, both invisible to a headless test: * compat.vulkan-runtime (new) — the loader found every host ICD manifest and then failed to dlopen any driver, because an mcpp binary runs under mcpp's own glibc and a bare-soname dlopen never searches the host path. This is the counterpart of compat.glx-runtime, which is why OpenGL already worked: a symlink farm plus runtime.library_dirs, no vendored driver. Instance extensions 4 -> 22. Versioned sonames only — library_dirs lands on the link line too, so a bare libxcb.so there shadows compat.xcb. * compat.vulkan is now kind="shared" with soname libvulkan.so.1. SDL2's SDL_CreateWindow(SDL_WINDOW_VULKAN) dlopens libvulkan.so.1 and resolves surface creation through whatever it finds; against a static loader the application ends up with two, and createSurface gets an instance the second one never saw. Shared, the application, GLFW (via glfwInitVulkanLoader) and SDL all converge on one object — which is what the loader is designed to be. Also: glfwInitVulkanLoader must be called before glfwInit. Upstream's glfw_app_main.cpp gets this right; a consumer writing its own entry point must too. Verified cold on all three platforms with mcpp 0.0.109, plus the local GUI harness on Linux. Design: .agents/docs/2026-07-29-add-eui-neo-plan.md Co-authored-by: SPeak Agent <248744407+speak-agent@users.noreply.github.com>
c35884e to
f529d54
Compare
Rebased onto
mainnow that #134 has landed — thevulkan,sdl2andnetworkfeaturesresolve against
compat.vulkan/compat.sdl2/compat.curlfrom it. 12 files.Adds EUI-NEO 0.5.3 as
compat.eui-neoin header-compat shape: the core TUscompiled into one lib, public headers exposed via
include_dirs, so consumers write#include <eui_neo.h>. The C++23 module surface (import eui;) is out of scope — upstreamships no module interface units.
Source
sudoevolve/EUI-NEO@v0.5.3(latest release)6951ac33…e64d1(computed twice, stable)EUI-NEO-0.5.3/— absorbed by the*/glob prefix, noinstall()hookgitcode.com/mcpp-res/eui-neo@0.5.3, byte-identicalDependencies
Upstream vendors its whole dependency set under
3rd/. None of it is built here — eachone is already in this index at the version upstream pins, which is what the six packages
from #131 were for:
compat.freetype2.13.3,compat.libpng1.6.43,compat.zlib,compat.glfw3.4,compat.opengl,compat.glad(the exact commit3rd/dependencies.cmakefetches),compat.yyjson0.12.0,compat.tray, pluscompat.md4cbehind a feature.Backends are a real choice, and
defaultcannot express itUpstream compiles exactly one render backend and one window backend, dispatching on
#if defined(EUI_RENDER_BACKEND_OPENGL) … #elif …VULKANand#if defined(EUI_WINDOW_BACKEND_SDL2)/ else-GLFW. Define both halves of either pair andthe first silently wins — the caller's choice is ignored, and since neither backend runs
headless, CI never notices.
mcpp features are additive with no
default-features = false(mcpp#242). Three encodingswere tried and each failed silently:
default = { defines/sources/deps }default = { implies = [...] }Verified with probes on both mcpp 0.0.109 (the CI pin) and 2026.7.29.1 (latest at
time of writing) — identical, so this is not something a version bump fixes.
The first row is the dangerous one. An early revision read it as Cargo's rule ("suppressed
when features are named"), which looks identical from a single observation. What disproved
it was the plain
eui-neomember passing its smoke test whilecreateRenderBackend()compiled to its
#elsebranch and returned a null backend.What works: mcpp already passes
-DMCPP_FEATURE_<NAME>into the package's own TUs, sothe exclusivity is resolved in the preprocessor by a force-included header, and the
features carry only sources and dependencies. Strictly better than a
defaultwould havebeen — naming an unrelated feature no longer drops the backends:
cflagsis C-onlyForce-including that header exposed a second problem: mcpp routes
cflagsto Ctranslation units and
cxxflagsto C++ ones. With-includeincflagsalone, exactlythree objects received it —
ime_bridge.c,native_bridge.c,tray_bridge.c.The first revision of this PR carried
cflags = { "-DEUI_RENDER_BACKEND_OPENGL=1" }andnothing else, so
render_backend.cppnever saw it: the package built, linked, passed itstests, and had no render backend at all. Both lists now carry the flag;
NOMINMAXonWindows got the same treatment.
Features
vulkancompat.vulkansdl2compat.sdl2networkcompat.curl+EUI_HAS_CURL=1markdowncompat.md4c+EUI_HAS_MD4C=1interface defineapp-mainint main()and render loopapp-main-sdl2markdownis the one with a behavioural probe:components/markdown.hcompiles one oftwo definitions of
parseMarkdownBlocksdepending onEUI_HAS_MD4C, sotests/examples/eui-neoasserts the fallback andeui-neo-markdownasserts the realparser — the feature is verified in both directions.
Verification
Cold, all three platforms in CI, four members:
Backend selection is verified structurally, not by trusting a green test. Each member's
dispatch TU is checked for which backend it references:
render_backend.o→window_backend.o→eui-neo(no features)OpenGLRenderBackendglfwCreateWindoweui-neo-vulkanVulkanRenderBackendglfwCreateWindoweui-neo-sdl2OpenGLRenderBackendSDL_CreateWindoweui-neo-markdownOpenGLRenderBackendglfwCreateWindowThe last row is what catches a
default-based regression.compat.vulkanhas no Windows build (see #134), soeui-neo-vulkangates with[target.'cfg(...)']and asserts the default OpenGL configuration there instead.What is NOT covered
text rasterization, image decode, input and IME are unexercised — every test here is
headless by construction.
app-main/app-main-sdl2have no workspace member — they cannot, since theirmain()opens a window.app-mainwas verified out-of-tree on linux: it compiles,supplies
main()(T maininglfw_app_main.o), and links against a consumer that hasnone; the run then exits 255 for want of a display.
tray is a compiled no-op (no GTK3 / libappindicator in this index).
Consumer contract
eui_neo.hpulls ineui/detail/dsl_app_impl.h, which leaves two symbols for theapplication to define — omitting them is a link error, not a compile error:
All four test members do this, mirroring upstream's
examples/*.cpp.Design:
.agents/docs/2026-07-29-add-eui-neo-plan.md