Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 173 additions & 0 deletions .agents/docs/2026-08-10-bump-eui-neo-0.5.6-plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
# Design doc: bump `compat.eui-neo` to 0.5.6

Date: 2026-08-10

Follow-up to `.agents/docs/2026-08-05-add-eui-neo-0.5.5-plan.md` (0.5.3 → 0.5.5).
Upstream released 0.5.6; this bumps the index from 0.5.5 to 0.5.6.

## Source and version

| | |
|---|---|
| Upstream | `https://github.com/sudoevolve/EUI-NEO` |
| Version | `0.5.6` (latest release) |
| Tarball | `archive/refs/tags/v0.5.6.tar.gz` |
| sha256 | `0df8d79897a480566b0989060f206431d12c4a83eb7aef50b8e5d21f1676abf8` (computed twice, stable; 14,794,160 bytes) |
| Wrap dir | `EUI-NEO-0.5.6/` — absorbed by the standard `*/` glob prefix, no `install()` hook |
| CN mirror | **pending** — no `mcpp-res` write access on this machine (same as 0.5.5); plain-string url fallback |
| License | Apache-2.0 (unchanged) |

0.5.5 tarball re-downloaded during this work and its sha256 re-derived — matches the
descriptor's `cf0da91d…`, which validates the download/verify pipeline.

## What changed upstream (0.5.5 → 0.5.6)

The release is substantial (32 commits, 86 files changed, 5 contributors), but almost all
of it is either build-system plumbing, app/example wiring, or the new `modules/` tree
(keyboard/serial modules) — none of which the compat descriptor touches. The only thing
that matters for this index is the **core library source list**:

- `CORE_SOURCES` gains exactly one file: `core/window/window_input_backend.cpp`. Upstream
moved the input/IME event pumping (mouse buttons, scroll, text composition, key queueing)
out of `window_backend.cpp` into its own TU.
- Everything else the descriptor names is unchanged in upstream's `CORE_SOURCES` /
OpenGL block / glfw `ime_bridge.c` / vulkan feature list — verified by diffing the
0.5.5 and 0.5.6 `CMakeLists.txt` source blocks.
- `3rd/dependencies.cmake` and the `3rd/` directory are **byte-identical** across the two
tags — all eight vendored dependencies stay at the versions the descriptor pins
(freetype 2.13.3, libpng 1.6.43, zlib 1.3.1, glfw 3.4, glad 651a425, yyjson 0.12.0, tray
8dd1358, opengl).

### The new TU compiles on both backends with no new deps

`window_input_backend.cpp` has two `#if`-branches that match the descriptor's generated
backend header exactly:

- **GLFW branch** (default): reaches `core/platform/ime_bridge.h` (`eui_ime_*` — supplied by
`ime_bridge.c`, already in the base source list) and `<GLFW/glfw3.h>` (`compat.glfw`, already
a dep). The `core::detail::inputQueue` / `core::queueKeyInput` / `core::queueScrollInput`
helpers it calls live in the header-only `core/input/input_state.h` — no new TU needed.
- **SDL2 branch** (`sdl2` feature): needs only `<SDL.h>` (`compat.sdl2`, already the feature's dep).

`core/input/` is headers-only in both tags (`input_state.h`, `input_types.h`), so no new
compiled input sources are introduced by the refactor.

## Descriptor changes (`pkgs/e/compat.eui-neo.lua`)

1. `xpm.{linux,macosx,windows}` each gain a `["0.5.6"]` entry (0.5.3/0.5.5 retained).
2. Base `sources` goes 24 → 25: `*/core/window/window_input_backend.cpp` added to the
Window layer group.
3. Header comment updated to v0.5.6 + the `window_input_backend.cpp` note; wrap-layer
mention `EUI-NEO-0.5.5/` → `EUI-NEO-0.5.6/`.
4. No feature/deps/cflags changes: the `-fno-char8_t` package-wide flag is still required —
re-verified that 0.5.6 still returns `path::u8string()` as `std::string` in
`core/platform/platform.cpp:616`, `core/render/shadertoy_json.cpp:40/260`,
`core/render/image_source.cpp:216/220/574`. Backend-exclusivity encoding unchanged
(`mcpp_eui_backends.h` reads `MCPP_FEATURE_VULKAN`/`MCPP_FEATURE_SDL2`, which 0.5.6's
`window_input_backend.cpp` also keys off).

## CN mirror: pending (fallback form used)

`gtc` still not installed and no `~/.config/gitcode-tool/config.json` on this machine, so the
0.5.6 mirror cannot be published from here. Per `docs/cn-mirror.md`'s no-write-access
fallback, the 0.5.6 entries use a **plain-string url** (GLOBAL upstream release);
`check_mirror_urls.lua` exempts plain strings, so lint stays green and CN users fall back to
upstream. The 0.5.3 entries keep their `{ GLOBAL, CN }` tables.

Once `mcpp-res/eui-neo` has a `0.5.6` release (same tarball as GLOBAL for byte-identical
sha), flip the 0.5.6 `url` to `{ GLOBAL = …, CN =
"https://gitcode.com/mcpp-res/eui-neo/releases/download/0.5.6/eui-neo-0.5.6.tar.gz" }`.
sha256 does not change.

## Test members

All six `tests/examples/eui-neo*` members bumped their `compat.eui-neo` dep from `0.5.5` to
`0.5.6` so the whole feature surface (markdown / vulkan / sdl2+network / app-main / window)
exercises the new version. CI's selective-member logic already maps the descriptor edit to
these members (`pkgs/e/compat.eui-neo.lua` → `$lib = eui-neo` → all six match).

Note: `tests/examples/eui-neo-window` includes `core/input/input_state.h` directly, so the
0.5.6 input refactor is exercised from a consumer TU too, not just through the lib's own
sources.

## API break caught by local verification: `app::*` impl moved out of the umbrella

`eui-neo-window`(the own-main member) failed the first local run at LINK time:

```
undefined symbol: app::initialize(void*) / app::update(...) / app::render(...) / app::shutdown()
```

Root cause is a 0.5.6 umbrella change: `include/eui_neo.h` **dropped
`#include "eui/detail/dsl_app_impl.h"`** (and the Windows `<windows.h>` block it carried).
That header is what emits `app::initialize/update/render/shutdown` + `openWindow()` into a
consumer TU. In 0.5.6 upstream scoped it to the app-main entry points — only
`core/app/glfw_app_main.cpp` and `core/app/sdl2_app_main.cpp` include it directly — so
`eui-neo-app-main` (whose main() IS glfw_app_main.cpp) still links, while the hand-written
`eui-neo-window` main() lost the impl. The other members never call the `app::*` driver
functions, so they pass regardless.

Fix: `tests/examples/eui-neo-window/tests/window.cpp` now includes
`"eui/detail/dsl_app_impl.h"` explicitly — exactly what upstream's own app-main TU does. It
compiles cleanly in a plain consumer TU: no `u8string()`/char8_t in the header or its core
includes, no `EUI_RENDER_BACKEND_*` macro dependency (verified by grep), and `3rd/stb_image.h`
resolves through the descriptor's existing `"*"` include dir. The `eui-neo` member's
`header.cpp` comment was also updated to stop claiming the umbrella emits `app::update/render`.

(No descriptor change was needed for this — the library build is unaffected; it is a
consumer-surface change upstream made.)

## Verification

- `mcpp xpkg parse` (mcpp 2026.8.10.1) → `parse OK`: versions 0.5.3/0.5.5/0.5.6 on all three
platforms, sources 25, features 6.
- Repo lint loop (lua 5.4): syntax / required fields / no-leading-v / `check_mirror_urls.lua` /
`check_package_name.lua` all pass.
- Local `mcpp test -p <member>` (mcpp 2026.8.10.1, linux, `MCPP_INDEX_MIRROR=GLOBAL`, cold
member dirs) — all six members pass:

| member | result |
|---|---|
| eui-neo (default OpenGL+GLFW) | `test result ok. 1 passed; 0 failed` |
| eui-neo-markdown | exit=0 |
| eui-neo-app-main | exit=0 |
| eui-neo-window | `test result ok` (after the dsl_app_impl.h fix) |
| eui-neo-sdl2 (SDL2+network) | `test result ok` — `SDL driver=dummy, curl 8.21.0-DEV ssl=OpenSSL/3.5.1` |
| eui-neo-vulkan | `test result ok` — `backend=vulkan, loader api 1.4.357` |

Local network was intermittently hung on the mcpp registry downloads during this run; the
EUI-NEO / curl / sdl2 / Vulkan-Loader tarballs were verified by sha256 and pre-seeded into
the member package caches (then extracted, matching what mcpp's install does) to keep the
cold builds moving. This is an environment workaround, not a descriptor concern.

> NOTE: local mcpp is 2026.8.10.1; the CI `MCPP_VERSION` pin was ALSO bumped 2026.8.8.2 →
> 2026.8.10.1 as part of this PR (see below). The user opts to verify locally with the
> newest mcpp; its rapid-release policy makes newer preferable.
>
> macosx/windows cannot be exercised on this linux box; the windows `app-main` TU
> (`_WIN32_WINNT`, winmm/user32/pdh) and the mac Cocoa tray link are re-exercised by CI's
> other two runners.

## CI MCPP_VERSION bump 2026.8.8.2 → 2026.8.10.1 (pre-existing linux failure fix)

First CI run of this PR: all six eui-neo members FAILED on **linux** (both default/gcc and
llvm legs, fast ~35s install-phase failures) while macos and windows PASSED. Reproduced
locally with a fresh mcpp 2026.8.8.2 (MCPP_HOME pointed at the tarball root):

```
error: xlings install_packages failed (exit 1) for 'compat.glx-runtime@2026.08.08'
xlings reported: E_INVALID_INPUT: package 'xim:libglvnd@>=1.7.0.1' not found
```

Root cause is a **pre-existing pin/registry mismatch, not the eui-neo bump**:
`compat.eui-neo` → `compat.glfw` (linux profile) → `compat.glx-runtime@2026.08.08` →
`xim:libglvnd@>=1.7.0.1`. mcpp 2026.8.8.2's registry cannot resolve `xim:libglvnd`; macos
(no X11 profile) and windows are unaffected, and mcpp 2026.8.10.1's registry carries it.
The same failure is why main's `graphics install` check has been red on every recent main
commit (b4e28f2 / d3909f7 / 1e0c71b).

Fix: bump `MCPP_VERSION` in `.github/workflows/validate.yml` to 2026.8.10.1 (kept the 2026.8.8.2
glibc-runtime-binding note, added the libglvnd reason). `index.toml` `min_mcpp` is left at
2026.8.3.3 — no descriptor uses new grammar, and repo history shows the pin moves
independently of the floor. `tests/check_graphics_install_side_effects.sh` only mentions
2026.8.8.2 in comments (the "2026.8.8.2+" floor), which 2026.8.10.1 satisfies.
17 changes: 11 additions & 6 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,18 +138,23 @@ env:
# 撞上时是响亮报错而不是静默用错包;下限是一道让整个索引对旧客户端失效的闸门
# (mcpp#349),只该在描述符真的读不动时抬。这里读得动,差的是解析得对。
#
# 2026.8.8.2 是本 PR 的**前置**,不是顺手升级
# 2026.8.8.2 曾经是本 pin 的**前置**,不是顺手升级:
#
# `compat.glx-runtime` 依赖 mesa,mesa 声明 `xim:glibc@>=2.38`;下限被任何更高
# 版本满足,于是安装图形栈会在既有 glibc 旁边**再装一个**。2026.8.8.2 之前的
# mcpp 用 `readdir` 的第一项来解析「那个 glibc payload」,编译侧与产物的
# interpreter 因此可以指向不同版本 —— 这正是 #179 落地后 `asio-module` 和
# `core` 变红、并导致整份改动被 #180 revert 的原因。
# `core` 变红、并导致整份改动被 #180 revert 的原因。用早于 2026.8.8.2 的 mcpp
# 重新落地这份改动,就是在仍会犯这个错的引擎上复现事故条件;
# tests/check_graphics_install_side_effects.sh 也需要它 —— 该测试在更旧的 mcpp
# 上失败是**有意的**。
#
# 用早于 2026.8.8.2 的 mcpp 重新落地这份改动,就是在仍会犯这个错的引擎上复现
# 事故条件。tests/check_graphics_install_side_effects.sh 也需要它 —— 该测试在
# 更旧的 mcpp 上失败是**有意的**。
MCPP_VERSION: "2026.8.8.2"
# 2026.8.10.1 又加了一层:2026.8.8.2 的 registry 无法解析
# `xim:libglvnd@>=1.7.0.1` —— compat.glx-runtime@2026.08.08 在 linux 上的硬依赖,
# 任何经 compat.glfw 的 X11 profile 触及图形栈的包(eui-neo 等)都会踩到,导致
# linux 上安装即失败(main 的 graphics 检查因此持续变红)。2026.8.10.1 的 registry
# 带上了 libglvnd;glibc 修复(2026.8.8.2)依然被满足。
MCPP_VERSION: "2026.8.10.1"

jobs:
lint:
Expand Down
27 changes: 23 additions & 4 deletions pkgs/e/compat.eui-neo.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,19 @@
-- genuinely vendored single-file headers live at its root (stb_image,
-- nanosvg, nanosvgrast) and the sources include them as `"3rd/stb_image.h"`.
--
-- The build recipe below tracks upstream `CMakeLists.txt` (v0.5.5): CORE_SOURCES
-- The build recipe below tracks upstream `CMakeLists.txt` (v0.5.6): CORE_SOURCES
-- plus the OpenGL backend and, for the glfw window backend, `ime_bridge.c`.
-- 0.5.5 grew a Shadertoy subsystem: render_backend.h and include/eui/types.h now
-- include core/render/shadertoy.h unconditionally, and opengl_backend.cpp calls
-- releaseShaderToys(), so shadertoy.cpp / shadertoy_json.cpp / shadertoy_primitive.cpp
-- and opengl_shadertoy.cpp are part of the lib, not optional (vulkan_shadertoy.cpp
-- joins the `vulkan` feature the same way).
-- joins the `vulkan` feature the same way). 0.5.6 adds `core/window/window_input_backend.cpp`
-- to CORE_SOURCES (upstream moved the input/IME event pumping into its own TU) —
-- the ONLY lib source-list change between the two versions; everything else the
-- descriptor names is byte-identical in upstream's CORE_SOURCES.
--
-- All `mcpp` paths are GLOBS relative to the verdir; the leading `*/` absorbs
-- the GitHub tarball's `EUI-NEO-0.5.5/` wrap layer.
-- the GitHub tarball's `EUI-NEO-0.5.6/` wrap layer.
package = {
spec = "1",
namespace = "compat",
Expand All @@ -41,14 +44,18 @@ package = {
CN = "https://gitcode.com/mcpp-res/eui-neo/releases/download/0.5.3/eui-neo-0.5.3.tar.gz" },
sha256 = "6951ac330d0307c633bafe720b7888bf32785103eb16973adb4ee05ef06e64d1",
},
-- CN mirror for 0.5.5 not published yet (no mcpp-res write access here);
-- CN mirror for 0.5.5/0.5.6 not published yet (no mcpp-res write access here);
-- plain-string url keeps lint green and lets CN users fall back to
-- upstream, per docs/cn-mirror.md. Flip to { GLOBAL, CN } once the
-- gitcode release exists — sha256 stays the same.
["0.5.5"] = {
url = "https://github.com/sudoevolve/EUI-NEO/archive/refs/tags/v0.5.5.tar.gz",
sha256 = "cf0da91d7544fe406b704922137fd4d55ed080b3e647501e0ca5303abb00eb98",
},
["0.5.6"] = {
url = "https://github.com/sudoevolve/EUI-NEO/archive/refs/tags/v0.5.6.tar.gz",
sha256 = "0df8d79897a480566b0989060f206431d12c4a83eb7aef50b8e5d21f1676abf8",
},
},
macosx = {
["0.5.3"] = {
Expand All @@ -60,6 +67,10 @@ package = {
url = "https://github.com/sudoevolve/EUI-NEO/archive/refs/tags/v0.5.5.tar.gz",
sha256 = "cf0da91d7544fe406b704922137fd4d55ed080b3e647501e0ca5303abb00eb98",
},
["0.5.6"] = {
url = "https://github.com/sudoevolve/EUI-NEO/archive/refs/tags/v0.5.6.tar.gz",
sha256 = "0df8d79897a480566b0989060f206431d12c4a83eb7aef50b8e5d21f1676abf8",
},
},
windows = {
["0.5.3"] = {
Expand All @@ -71,6 +82,10 @@ package = {
url = "https://github.com/sudoevolve/EUI-NEO/archive/refs/tags/v0.5.5.tar.gz",
sha256 = "cf0da91d7544fe406b704922137fd4d55ed080b3e647501e0ca5303abb00eb98",
},
["0.5.6"] = {
url = "https://github.com/sudoevolve/EUI-NEO/archive/refs/tags/v0.5.6.tar.gz",
sha256 = "0df8d79897a480566b0989060f206431d12c4a83eb7aef50b8e5d21f1676abf8",
},
},
},

Expand Down Expand Up @@ -157,6 +172,10 @@ package = {
"*/core/platform/ime_bridge.c",
-- Window layer
"*/core/window/window_backend.cpp",
-- 0.5.6: input/IME event pumping moved out of window_backend.cpp into
-- its own TU (upstream CORE_SOURCES). GLFW branch rides on ime_bridge.h
-- (ime_bridge.c, already compiled) + glfw; SDL2 branch needs only SDL.
"*/core/window/window_input_backend.cpp",
},

targets = { ["eui-neo"] = { kind = "lib" } },
Expand Down
2 changes: 1 addition & 1 deletion tests/examples/eui-neo-app-main/mcpp.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ name = "eui-neo-app-main-tests"
version = "0.1.0"

[dependencies.compat]
eui-neo = { version = "0.5.5", features = ["app-main"] }
eui-neo = { version = "0.5.6", features = ["app-main"] }
2 changes: 1 addition & 1 deletion tests/examples/eui-neo-markdown/mcpp.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ version = "0.1.0"
# what switches components/markdown.h from its fallback to the real parser.

[dependencies.compat]
eui-neo = { version = "0.5.5", features = ["markdown"] }
eui-neo = { version = "0.5.6", features = ["markdown"] }
2 changes: 1 addition & 1 deletion tests/examples/eui-neo-sdl2/mcpp.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ version = "0.1.0"
# into a real libcurl-backed implementation. The render backend stays OpenGL,
# unnamed — naming a feature no longer costs you the defaults.
[dependencies.compat]
eui-neo = { version = "0.5.5", features = ["sdl2", "network"] }
eui-neo = { version = "0.5.6", features = ["sdl2", "network"] }
2 changes: 1 addition & 1 deletion tests/examples/eui-neo-vulkan/mcpp.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ version = "0.1.0"
# package resolves the exclusive choice in its own preprocessor from the
# MCPP_FEATURE_* flags. The window backend stays GLFW, unnamed.
[dependencies.compat]
eui-neo = { version = "0.5.5", features = ["vulkan"] }
eui-neo = { version = "0.5.6", features = ["vulkan"] }

[build]
cxxflags = ["-DHAVE_EUI_VULKAN=1"]
2 changes: 1 addition & 1 deletion tests/examples/eui-neo-window/mcpp.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ name = "eui-neo-window-tests"
version = "0.1.0"

[dependencies.compat]
eui-neo = "0.5.5"
eui-neo = "0.5.6"
7 changes: 7 additions & 0 deletions tests/examples/eui-neo-window/tests/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
// so there is no reason to cfg-gate this the way the X11-consuming members are.
#include <eui_neo.h>

// 0.5.6 dropped `eui/detail/dsl_app_impl.h` from the umbrella `eui_neo.h`
// (upstream scoped it to the app-main entry points, which include it directly).
// This member is the OWN-main shape — nothing in the package drives the loop —
// so app::initialize/update/render/shutdown are emitted HERE by including the
// impl header, exactly as upstream's core/app/glfw_app_main.cpp does.
#include "eui/detail/dsl_app_impl.h"

#include "core/input/input_state.h"
#include "core/platform/platform.h"
#include "core/render/render_backend.h"
Expand Down
2 changes: 1 addition & 1 deletion tests/examples/eui-neo/mcpp.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ name = "eui-neo-tests"
version = "0.1.0"

[dependencies.compat]
eui-neo = "0.5.5"
eui-neo = "0.5.6"
12 changes: 7 additions & 5 deletions tests/examples/eui-neo/tests/header.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
// to a Form A consumer, and links against real symbols from the built lib.
//
// `#include <eui_neo.h>` is the whole point of the header-compat shape. The
// umbrella pulls in eui/detail/dsl_app_impl.h, which emits app::update() /
// app::render() into THIS translation unit and leaves two symbols for the
// application to supply — app::dslAppConfig() and app::compose(). Defining
// them here is exactly what upstream's examples/*.cpp do, so this test is a
// faithful minimal consumer.
// umbrella declares the DSL app surface (eui/dsl_app.h) and leaves two symbols
// for the application to supply — app::dslAppConfig() and app::compose().
// Since 0.5.6 the umbrella no longer pulls in eui/detail/dsl_app_impl.h (the
// impl lives in the app-main entry points instead), but THIS TU only defines
// the two app symbols and never calls app::initialize/update/render — so it
// links without the impl header, and defining the app symbols is exactly what
// upstream's examples/*.cpp do, making this test a faithful minimal consumer.
//
// The assertion itself runs on eui::json::Document: it lives in
// core/platform/json.cpp, so a package that compiled zero translation units
Expand Down
Loading