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
26 changes: 26 additions & 0 deletions .agents/docs/2026-10-18-glfw-windows-link.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# GLFW Windows package closure

The existing gui-stack and imgui-window members gate GLFW behind Linux, leaving
Windows package compilation/linkage untested. Add a standalone glfw workspace
member with a local compat index and no other direct dependencies. Test Null
windows everywhere and require native Win32 initialization and hidden window
behavior on Windows; use GLFW_NO_API and GLFW_INCLUDE_NONE.

PR #538's initial Windows run (39048720103, job 117442681476) reproduced
undefined LoadCursorW, CreateWindowExW, RegisterClassExW and DragAcceptFiles.
All references originate in GLFW's own win32 sources, not the consumer.

Declare user32 (window/input), gdi32 (pixel formats), and shell32 (drag/drop) in
windows.runtime.libraries. Upstream CMake gets user32/shell32 from CMake's default
Windows standard libraries; the direct clang driver does not. Retain the existing
dialect-neutral form rather than raw linker flags. GLFW dynamically loads its
OpenGL, XInput, DirectInput and DWM functions; no new import libraries are needed
for those. Application calls to OpenGL/Vulkan remain the consumer's responsibility.

Keep the existing package versions and upstream 3.4 archive, URLs, SHA and
install hook. This is a descriptor-only fix: xpkg refreshes the descriptor, so
no new package version is needed when the source is unchanged. The new test
consumes upstream version 3.4.

Validation: CI uses mcpp 2026.10.1.2. Initial Windows failure is the regression
proof; final PR checks must cover the fix, including execution of the Win32 test.
1 change: 1 addition & 0 deletions mcpp.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ members = [
"tests/examples/godot-cpp-v10",
"tests/examples/grpc-codegen",
"tests/examples/grpc-module",
"tests/examples/glfw",
"tests/examples/gui-stack",
"tests/examples/imgui",
"tests/examples/imgui-module",
Expand Down
7 changes: 6 additions & 1 deletion pkgs/c/compat.glfw.lua
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,12 @@ package = {
-- consumer's build. `runtime.libraries` renders as gdi32.lib for
-- MSVC and -lgdi32 for GNU.
runtime = {
libraries = { "gdi32" },
-- GLFW calls User32 window/input APIs, GDI pixel-format APIs,
-- and Shell32 drag/drop APIs itself. CMake's Windows defaults
-- hide user32/shell32; a direct clang consumer needs them here.
-- OpenGL, XInput, DirectInput and DWM are dynamically loaded by
-- GLFW, so they do not require additional import libraries.
libraries = { "user32", "gdi32", "shell32" },
},
},
},
Expand Down
19 changes: 19 additions & 0 deletions tests/examples/glfw/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Standalone GLFW smoke test

From the repository root, run `mcpp test -p glfw` (including on Windows).
The manifest redirects `compat` to this checkout so the test checks the PR's
package descriptor rather than the published index.

The test checks the upstream version and creates a Null-platform window on every
platform. On Windows it also requires the Win32 backend, creates a hidden native
window, checks its size and user pointer, polls events, and closes it. A failed
initialization or window creation fails the test. No visible window or graphics
context is required.

The only direct dependency is `compat.glfw`. `GLFW_INCLUDE_NONE` and
`GLFW_NO_API` keep graphics API headers and context creation out of this test.
GLFW's own native system-library references belong in the package descriptor;
libraries used directly by an application (for example OpenGL entry points or a
Vulkan loader) belong to that application. GLFW dynamically loads several
optional Windows APIs, so their DLL names alone are not a reason to add import
libraries. Keep dialect-neutral native link requirements in `runtime.libraries`.
9 changes: 9 additions & 0 deletions tests/examples/glfw/mcpp.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "glfw-tests"
version = "0.1.0"

[dependencies.compat]
glfw = "3.4"

[indices]
compat = { path = "../../.." }
51 changes: 51 additions & 0 deletions tests/examples/glfw/tests/window.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include <cstdio>
#include <cstring>

static void error(int code, const char* description) {
std::fprintf(stderr, "GLFW error %d: %s\n", code, description);
}

static bool window_test(int platform) {
glfwInitHint(GLFW_PLATFORM, platform);
if (!glfwInit()) return false;
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
GLFWwindow* window = glfwCreateWindow(640, 480, "compat.glfw smoke", nullptr, nullptr);
bool ok = window && glfwGetPlatform() == platform;
if (window) {
int width = 0, height = 0;
glfwGetWindowSize(window, &width, &height);
int marker = 42;
glfwSetWindowUserPointer(window, &marker);
ok = ok && width == 640 && height == 480 &&
glfwGetWindowUserPointer(window) == &marker &&
!glfwWindowShouldClose(window);
if (!ok) std::fprintf(stderr, "platform %x: size=%dx%d, expected=640x480, user_pointer=%d, should_close=%d\n",
platform, width, height,
glfwGetWindowUserPointer(window) == &marker,
glfwWindowShouldClose(window));
glfwSetWindowShouldClose(window, GLFW_TRUE);
ok = ok && glfwWindowShouldClose(window);
glfwPollEvents();
glfwDestroyWindow(window);
}
glfwTerminate();
return ok;
}

int main() {
glfwSetErrorCallback(error);
int major = 0, minor = 0, revision = 0;
glfwGetVersion(&major, &minor, &revision);
if (major != 3 || minor != 4 || revision != 0) return 1;
if (!window_test(GLFW_PLATFORM_NULL)) return 2;
#ifdef _WIN32
// Require the real Win32 backend too: a null-only test misses native links.
if (!glfwPlatformSupported(GLFW_PLATFORM_WIN32)) return 3;
if (!std::strstr(glfwGetVersionString(), "Win32")) return 4;
if (!window_test(GLFW_PLATFORM_WIN32)) return 5;
#endif
return 0;
}
Loading