From 27b41e0f45824ee60118d99d316dc2edd180d516 Mon Sep 17 00:00:00 2001 From: Pascal Severin Date: Tue, 29 Sep 2026 18:57:13 +0200 Subject: [PATCH 1/2] Fix Windows/macOS CI: platform-guard dlclose in GlContext destroy (M2-GL-01) The M2-GL-01 merge (62ef1f7) broke the non-Linux P0 lanes: Impl::destroy() called dlclose() unconditionally, but is included only where the Linux EGL headless path compiles (!__APPLE__ && !_WIN32), and dlclose does not exist on Windows. macOS arm64/intel (clang++ 'use of undeclared identifier dlclose') and windows-msvc (MSVC C3861) failed to compile gl_context.cpp; the Linux lanes passed because the declaration is available there. The dlopen handle is assigned only in the Linux-only createHeadless branch, so eglHandle is always null on Windows/macOS: guard the close with the same platform condition as the include. Behavior on Linux is unchanged (RAII release of the dlopened libEGL). --- src/laige-render/gl_context.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/laige-render/gl_context.cpp b/src/laige-render/gl_context.cpp index 52246f0..d0885d1 100644 --- a/src/laige-render/gl_context.cpp +++ b/src/laige-render/gl_context.cpp @@ -244,9 +244,15 @@ struct GlContext::Impl { if (egl.destroyDisplay != nullptr && eglDisplay != nullptr) { egl.destroyDisplay(eglDisplay); } + // libEGL is dlopened only on the Linux headless path (createHeadless + // #else branch); on Windows/macOS eglHandle is always null and + // is not included (see the include guard above), so the + // close is compiled only where the handle can exist. +#if !defined(__APPLE__) && !defined(_WIN32) if (eglHandle != nullptr) { dlclose(eglHandle); } +#endif } else { if (window != nullptr) { glfwDestroyWindow(window); // destroys the context with it From 2f974d17fe08903f9ccf7c9570e7596ca722427e Mon Sep 17 00:00:00 2001 From: Pascal Severin Date: Tue, 29 Sep 2026 19:18:19 +0200 Subject: [PATCH 2/2] Fix macOS CI: guard Linux-only EGL constants from -Wunused-const-variable Once the dlclose hard error stopped aborting the TU, AppleClang's deferred unused-variable diagnostics surfaced: the seven EGL constants in the egl namespace are referenced only from the Linux-only createHeadless branch, so on macOS (and any other non-Linux platform) they are unused and -Werror,-Wunused-const-variable (NFR-8.10) rejects them. Guard the constants with the same platform condition as the include and the dlopen call. Values and Linux behavior are unchanged. --- src/laige-render/gl_context.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/laige-render/gl_context.cpp b/src/laige-render/gl_context.cpp index d0885d1..ebdafd2 100644 --- a/src/laige-render/gl_context.cpp +++ b/src/laige-render/gl_context.cpp @@ -67,6 +67,10 @@ using Int = std::int32_t; using Bool = std::int32_t; using Enum = std::int32_t; +// These constants are referenced only from the Linux headless path +// (the #else createHeadless branch); without the guard, AppleClang's +// -Wunused-const-variable (-Werror, NFR-8.10) rejects them on macOS. +#if !defined(__APPLE__) && !defined(_WIN32) constexpr Int kNone = 0x3038; // EGL_OPENGL_API — the eglBindAPI argument. Verified against the P0 // distro's EGL headers (noble libglvnd 1.7.0): the GLVND dispatcher @@ -80,6 +84,7 @@ constexpr Int kContextMinorVersion = 0x30FB; constexpr Int kContextProfileMask = 0x30FD; constexpr Int kCoreProfileBit = 0x00000001; constexpr Enum kPlatformSurfacelessMesa = 0x31DD; // EGL_MESA_platform_surfaceless +#endif struct FnTable { Display (*getPlatformDisplay)(Enum platform, void* nativeDisplay,