Skip to content

Commit 44bb7fa

Browse files
feat: add compat.eui-neo 0.5.3 with selectable render and window backends (#133)
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 #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>
1 parent 6da8452 commit 44bb7fa

15 files changed

Lines changed: 1489 additions & 23 deletions

File tree

.agents/docs/2026-07-29-add-eui-neo-plan.md

Lines changed: 482 additions & 0 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ mcpp self config --mirror CN # 切换至国内镜像,默认使用 GLOBAL 上
3838
| 运行时 loader compat(纯源码,绕开上游 codegen/asm) | [`compat.vulkan`](pkgs/c/compat.vulkan.lua)(Khronos loader:`loader/generated/` 已签入,汇编路径经 `UNKNOWN_FUNCTIONS_SUPPORTED` 降级为纯 C,故无需 CMake/Python/汇编器;windows 延后)· [`compat.vulkan-headers`](pkgs/c/compat.vulkan-headers.lua) |
3939
| 全源码直编 + 生成 config(仅缺口平台) | [`compat.curl`](pkgs/c/compat.curl.lua)(win32 用上游签入 config,unix 生成) · [`compat.sdl2`](pkgs/c/compat.sdl2.lua)(win/mac 用上游签入 config,linux 生成 + 手工开 X11) |
4040
| 补索引空缺的头文件包 | [`compat.glx-headers`](pkgs/c/compat.glx-headers.lua)(libglvnd 的 `GL/glx.h`,Khronos registry 不含,SDL 的 X11 后端必需) |
41+
| C++ 应用框架 compat(依赖复用索引内既有包) | [`compat.eui-neo`](pkgs/e/compat.eui-neo.lua)(上游 `3rd/` 自带 8 个 vendored 依赖,此处一个不编,全部改指索引内同版本 `compat.*`) |
42+
| 互斥后端(同包多后端二选一) | [`compat.eui-neo`](pkgs/e/compat.eui-neo.lua)`opengl`/`vulkan``glfw`/`sdl2`**`default` feature 在 mcpp 上不可用**(带 `defines/sources/deps` 完全不生效;带 `implies` 反而恒生效),可行解是用 `-DMCPP_FEATURE_<NAME>` 在强制包含头里做前置判定。另注意 `cflags` 只作用于 C TU,C++ 需 `cxxflags` |
43+
| 宿主运行时适配(不 vendor 驱动) | [`compat.glx-runtime`](pkgs/c/compat.glx-runtime.lua) · [`compat.vulkan-runtime`](pkgs/c/compat.vulkan-runtime.lua)(mcpp 产物跑在自带 glibc 下,裸 soname 的 `dlopen` 够不到宿主驱动;用符号链接农场 + `runtime.library_dirs` 打通。注意 farm 只放带版本号的 soname —— `library_dirs` 同时进链接行) |
4144
| 恒开的 interface define | [`compat.curl`](pkgs/c/compat.curl.lua)`CURL_STATICLIB`:`cflags` 恒开但包私有,feature `defines` 可达消费端但需点名 —— `default = { implies = … }` 无条件生效,恰好两者兼得 |
4245
| 单包多 major(形态随版本切换) | [`compat.catch2`](pkgs/c/compat.catch2.lua)(3.x 编 `src/catch2/` 出静态库;2.x 走 `single_include/` header-only) |
4346
| 外部构建系统(`install()` 从源码构建) | [`compat.openblas`](pkgs/c/compat.openblas.lua)(Make) · [`compat.openssl`](pkgs/c/compat.openssl.lua)(Perl Configure + Make,静态 libssl/libcrypto) |

mcpp.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ members = [
1919
"tests/examples/core",
2020
"tests/examples/curl",
2121
"tests/examples/eigen",
22+
"tests/examples/eui-neo",
23+
"tests/examples/eui-neo-markdown",
24+
"tests/examples/eui-neo-sdl2",
25+
"tests/examples/eui-neo-vulkan",
2226
"tests/examples/ffmpeg",
2327
"tests/examples/ffmpeg-module",
2428
"tests/examples/fmtlib.fmt",

pkgs/c/compat.vulkan-runtime.lua

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
-- compat.vulkan-runtime — host Vulkan ICD adapter for mcpp Linux applications.
2+
--
3+
-- The exact counterpart of `compat.glx-runtime`, for the same reason and in the
4+
-- same shape. A GPU driver cannot be a package: the ICD has to match the kernel
5+
-- driver on the machine it runs on, so the GL runtime plan
6+
-- (.agents/docs/2026-06-03-gl-runtime-packages-plan.md) settled on modelling it
7+
-- as a HOST CAPABILITY rather than "silently pretending vendor drivers are
8+
-- normal redistributable packages". Nothing is vendored here either — this is a
9+
-- symlink farm plus the metadata that makes it reachable.
10+
--
11+
-- WHAT IT FIXES. `compat.vulkan` builds the Khronos loader, and the loader finds
12+
-- every ICD manifest on the host correctly. It then fails to dlopen a single
13+
-- driver:
14+
--
15+
-- DRIVER: Found the following files: /usr/share/vulkan/icd.d/lvp_icd.json …
16+
-- ERROR: libvulkan_lvp.so: cannot open shared object file
17+
--
18+
-- The libraries are right there in /usr/lib/x86_64-linux-gnu. What cannot reach
19+
-- them is the process: an mcpp-built binary runs under mcpp's OWN glibc
20+
--
21+
-- interp: …/xpkgs/xim-x-glibc/2.39/lib64/ld-linux-x86-64.so.2
22+
-- rpath : …/xim-x-glibc/2.39/lib64:…/xim-x-gcc/…/lib64:$ORIGIN
23+
--
24+
-- so a bare-soname dlopen from inside the sandbox does not search the host's
25+
-- library path at all. `runtime.library_dirs` below puts a package-owned
26+
-- directory of symlinks on that path, which is precisely how `compat.glx-runtime`
27+
-- makes host OpenGL work — and why the OpenGL backends already run while Vulkan
28+
-- did not.
29+
--
30+
-- THE PATTERN LIST covers the ICDs plus their transitive dependencies, because
31+
-- the whole chain has to resolve through the same directory. Mesa's software
32+
-- rasterizer pulls LLVM; NVIDIA pulls its own family. `libstdc++` is in the list
33+
-- and that is not an oversight: mcpp links libstdc++ STATICALLY (it is absent
34+
-- from a built binary's NEEDED), so a dlopen'd C++ ICD like lavapipe has nothing
35+
-- to resolve against unless the host copy is provided here.
36+
--
37+
-- NOTHING IS REQUIRED. Unlike `compat.glx-runtime`, which errors when libGL is
38+
-- missing, a machine with no Vulkan driver at all is a legitimate configuration
39+
-- — every CI runner in this repo is one. The farm is then simply empty and the
40+
-- loader reports its own four extensions, which is what
41+
-- `tests/examples/vulkan` asserts.
42+
package = {
43+
spec = "1",
44+
namespace = "compat",
45+
name = "vulkan-runtime",
46+
description = "Host Vulkan ICD runtime adapter for mcpp Linux applications",
47+
licenses = {"Apache-2.0"},
48+
repo = "https://github.com/KhronosGroup/Vulkan-Loader",
49+
type = "package",
50+
51+
xpm = {
52+
linux = {
53+
["2026.07.29"] = {
54+
-- Nothing is downloaded that matters: the package's content is
55+
-- the symlink farm install() builds from the host. This is just
56+
-- a stable, tiny anchor so the xpm entry is well-formed, the
57+
-- same trick compat.glx-runtime uses with an OpenGL-Registry
58+
-- README.
59+
url = "https://raw.githubusercontent.com/KhronosGroup/Vulkan-Loader/vulkan-sdk-1.4.357.0/README.md",
60+
sha256 = "21ec0987a05bd680ecd11f8be747e27744d7558f7318736f6cb8a5c5ec1b8ba8",
61+
},
62+
},
63+
},
64+
65+
mcpp = {
66+
language = "c++23",
67+
import_std = false,
68+
c_standard = "c11",
69+
sources = { "mcpp_generated/vulkan_runtime_empty.c" },
70+
targets = { ["vulkan_runtime"] = { kind = "lib" } },
71+
deps = {},
72+
runtime = {
73+
library_dirs = { "mcpp_generated/vulkan_runtime/lib" },
74+
capabilities = { "vulkan.icd.driver" },
75+
provides = { "vulkan.icd.driver" },
76+
},
77+
},
78+
}
79+
80+
import("xim.libxpkg.pkginfo")
81+
import("xim.libxpkg.log")
82+
83+
local function sh_quote(value)
84+
return "'" .. tostring(value):gsub("'", "'\\''") .. "'"
85+
end
86+
87+
local function split_paths(value)
88+
local out = {}
89+
if not value or value == "" then
90+
return out
91+
end
92+
for item in tostring(value):gmatch("[^:]+") do
93+
if item ~= "" then
94+
table.insert(out, item)
95+
end
96+
end
97+
return out
98+
end
99+
100+
local function candidate_dirs()
101+
local out = {}
102+
local seen = {}
103+
local function add(dir)
104+
if dir and dir ~= "" and not seen[dir] and os.isdir(dir) then
105+
seen[dir] = true
106+
table.insert(out, dir)
107+
end
108+
end
109+
110+
for _, dir in ipairs(split_paths(os.getenv("MCPP_HOST_VULKAN_LIBRARY_PATH"))) do
111+
add(dir)
112+
end
113+
add("/lib/x86_64-linux-gnu")
114+
add("/usr/lib/x86_64-linux-gnu")
115+
add("/lib64")
116+
add("/usr/lib64")
117+
add("/usr/lib")
118+
return out
119+
end
120+
121+
-- ICDs first, then the transitive set they pull in — the whole chain has to
122+
-- resolve through this one directory. Verified against Mesa's lavapipe (LLVM,
123+
-- drm, expat, xcb, wayland, zstd) and NVIDIA's ICD, which is libGLX_nvidia.so.0
124+
-- and drags the libnvidia* family.
125+
--
126+
-- EVERY DEPENDENCY PATTERN IS VERSIONED (`lib*.so.*`), deliberately. mcpp puts
127+
-- `runtime.library_dirs` on the LINK line as well as the runtime path, so a bare
128+
-- `libxcb.so` harvested here would shadow this index's own `compat.xcb` and the
129+
-- link fails with `undefined reference to XauDisposeAuth`. Versioned sonames are
130+
-- invisible to the linker (it resolves `-lxcb` through `libxcb.so`/`libxcb.a`)
131+
-- and are exactly what dlopen asks for, so the split is not a workaround so much
132+
-- as the correct spelling. `compat.glx-runtime` never hit this only because the
133+
-- GL family it harvests is not otherwise linked from the index.
134+
--
135+
-- The Mesa ICDs themselves are genuinely named `libvulkan_lvp.so` with no
136+
-- version, which is safe: nothing links `-lvulkan_lvp`.
137+
--
138+
-- The host's own `libvulkan.so*` is deliberately NOT harvested: `compat.vulkan`
139+
-- builds the loader itself, as a shared object with the canonical
140+
-- `libvulkan.so.1` soname, and a second one on the path would be resolved by
141+
-- SDL2's `dlopen` instead. One loader per process is the whole point.
142+
local host_vulkan_patterns = {
143+
-- Mesa ICDs: lavapipe, intel, radeon, nouveau, virtio, asahi, gfxstream
144+
"libvulkan_*.so",
145+
-- NVIDIA's ICD and its family
146+
"libGLX_nvidia.so.*",
147+
"libnvidia*.so.*",
148+
-- transitive dependencies, versioned only
149+
"libLLVM*.so.*",
150+
"libdrm*.so.*",
151+
"libexpat.so.*",
152+
-- The X client stack, including its own auth dependencies. Incomplete is
153+
-- worse than absent here: a farm carrying libxcb.so.1 but not libXau.so.6
154+
-- shadows the host copy that would otherwise have resolved, and the
155+
-- executable fails to start.
156+
"libxcb*.so.*",
157+
"libX11-xcb.so.*",
158+
"libXau.so.*",
159+
"libXdmcp.so.*",
160+
"libbsd.so.*",
161+
"libmd.so.*",
162+
"libxshmfence.so.*",
163+
"libwayland-client.so.*",
164+
"libz.so.*",
165+
"libzstd.so.*",
166+
"libelf.so.*",
167+
"libffi.so.*",
168+
"libedit.so.*",
169+
"libtinfo.so.*",
170+
"libxml2.so.*",
171+
"libstdc++.so.*",
172+
}
173+
174+
local function link_runtime_libs(outdir)
175+
os.mkdir(outdir)
176+
for _, dir in ipairs(candidate_dirs()) do
177+
for _, pattern in ipairs(host_vulkan_patterns) do
178+
os.exec(
179+
"for lib in " .. sh_quote(dir) .. "/" .. pattern ..
180+
"; do [ -e \"$lib\" ] || continue; " ..
181+
"ln -sf \"$lib\" " .. sh_quote(outdir) .. "/\"$(basename \"$lib\")\"; " ..
182+
"done"
183+
)
184+
end
185+
end
186+
return true
187+
end
188+
189+
function install()
190+
os.tryrm(pkginfo.install_dir())
191+
os.mkdir(pkginfo.install_dir())
192+
193+
local generated = path.join(pkginfo.install_dir(), "mcpp_generated")
194+
os.mkdir(generated)
195+
io.writefile(path.join(generated, "vulkan_runtime_empty.c"),
196+
"int mcpp_compat_vulkan_runtime_anchor(void) { return 0; }\n")
197+
198+
return link_runtime_libs(path.join(generated, "vulkan_runtime", "lib"))
199+
end

pkgs/c/compat.vulkan.lua

Lines changed: 84 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,32 @@
2020
-- entry points (ones this loader version has never heard of) get no
2121
-- trampoline, which no consumer in this index uses.
2222
--
23-
-- WINDOWS IS DEFERRED. A statically linked loader is not something upstream
24-
-- supports there: the only static option in its CMake is `APPLE_STATIC_LOADER`,
25-
-- gated to macOS and carrying the warning that it "will only work on MacOS and
26-
-- is not supported" elsewhere. Built anyway, the Windows loader links but faults
27-
-- at the first entry point (0xC0000005 out of vkEnumerateInstanceVersion). Linux
28-
-- is not covered by that option either, but a static loader is the ordinary
29-
-- case there and works — Chromium ships one. Rather than carry a package that
30-
-- crashes, this follows `compat.openssl` and declares no windows xpm entry;
31-
-- consumers gate with `[target.'cfg(...)']`.
23+
-- WINDOWS TAKES A DIFFERENT SHAPE: an import library, not a built loader.
24+
--
25+
-- A statically linked loader cannot work there, and the reason is in upstream's
26+
-- own source rather than just its docs. `vk_loader_platform.h` says the Windows
27+
-- build "does initialization in the first API call made, using
28+
-- InitOnceExecuteOnce, EXCEPT for initialization primitives which must be done
29+
-- in DllMain" — and `loader_windows.c`'s DllMain is what creates `loader_lock`
30+
-- and `loader_preload_icd_lock`. A static library never gets a DllMain, so the
31+
-- first API call takes an uninitialized CRITICAL_SECTION and faults
32+
-- (0xC0000005 out of vkEnumerateInstanceVersion, observed in CI). macOS escapes
33+
-- this through `APPLE_STATIC_LOADER` + pthread_once; Linux through
34+
-- `__attribute__((constructor))`. Windows has neither.
35+
--
36+
-- The supported Windows arrangement is the ordinary one every Vulkan
37+
-- application uses: link `vulkan-1.lib` and let the system `vulkan-1.dll`,
38+
-- installed by any GPU driver, do the ICD loading. The windows xpm entry is
39+
-- therefore a small artifact carrying that import library — symbol stubs, no
40+
-- code — generated from Khronos' own `loader/vulkan-1.def` (shipped in this
41+
-- very loader tarball) with a single reproducible command:
42+
--
43+
-- llvm-dlltool -d vulkan-1.def -l lib/vulkan-1.lib -m i386:x86-64
44+
--
45+
-- Deliberately NOT an install() hook running that command at build time: the
46+
-- hook would have to locate llvm-dlltool inside the resolved toolchain, and the
47+
-- output is a fixed function of an upstream text file. Prebuilt Windows
48+
-- artifacts on xlings-res are the pattern `compat.openssl` already anticipates.
3249
--
3350
-- SYSCONFDIR / FALLBACK_*_DIRS are the ICD and layer manifest search paths.
3451
-- Upstream's CMake derives them from the install prefix; the values below are
@@ -65,14 +82,24 @@ package = {
6582
sha256 = "54f2537df22313768da0317dda2abdaaab7711b4081c48c869a79db343d0ae70",
6683
},
6784
},
68-
-- windows deferred, see the note at the top of this file.
85+
windows = {
86+
["1.4.357.0"] = {
87+
url = {
88+
GLOBAL = "https://github.com/xlings-res/vulkan-import/releases/download/1.4.357.1/vulkan-import-1.4.357.1.tar.gz",
89+
CN = "https://gitcode.com/mcpp-res/vulkan-import/releases/download/1.4.357.1/vulkan-import-1.4.357.1.tar.gz",
90+
},
91+
sha256 = "37a206f866f75f54a56bdb428e4767c9926acd3f8abc8e1b9539853bb45acbf9",
92+
},
93+
},
6994
},
7095

7196
mcpp = {
7297
language = "c++23",
7398
import_std = false,
7499
c_standard = "c11",
75100

101+
-- `*/loader*` simply match nothing in the windows artifact, which
102+
-- carries only lib/ and the .def.
76103
include_dirs = { "*/loader", "*/loader/generated", "mcpp_generated" },
77104

78105
-- SYSCONFDIR / FALLBACK_*_DIRS have to reach the compiler as STRING
@@ -83,6 +110,8 @@ package = {
83110
-- the command line entirely — the same move `compat.opencv5` made for
84111
-- its space-bearing defines.
85112
generated_files = {
113+
["mcpp_generated/vulkan_import_anchor.c"] =
114+
"int mcpp_compat_vulkan_import_anchor(void) { return 0; }\n",
86115
["mcpp_generated/mcpp_vulkan_paths.h"] = [==[
87116
/* Manifest search paths for the Vulkan loader — see the descriptor note. */
88117
#pragma once
@@ -111,6 +140,22 @@ package = {
111140
"*/loader/wsi.c",
112141
},
113142

143+
-- SHARED, with the canonical soname — not a static lib, and the choice
144+
-- is load-bearing rather than stylistic.
145+
--
146+
-- The Vulkan loader is designed to be the one shared object in a
147+
-- process. SDL2 insists on that: `SDL_CreateWindow(SDL_WINDOW_VULKAN)`
148+
-- calls `SDL_Vulkan_LoadLibrary(NULL)`, which dlopens `libvulkan.so.1`
149+
-- and resolves surface creation through whatever it finds. Built
150+
-- static, an application ends up with TWO loaders — its own for
151+
-- `vkCreateInstance`, SDL's for `vkCreateXlibSurfaceKHR` — and
152+
-- `createSurface` fails on an instance the second loader never saw.
153+
-- Measured, not assumed. Shared, everyone (the application, GLFW via
154+
-- glfwInitVulkanLoader, SDL via dlopen) converges on this one object.
155+
--
156+
-- The soname is what makes SDL's bare `dlopen("libvulkan.so.1")` land
157+
-- here, so it is not optional either. Same shape the X11 family in this
158+
-- index already uses.
114159
targets = { ["vulkan"] = { kind = "lib" } },
115160
deps = { ["compat.vulkan-headers"] = "1.4.357.0" },
116161

@@ -125,6 +170,12 @@ package = {
125170
-- loader_linux.c: it sorts physical devices by PCI bus info so
126171
-- device 0 is the discrete GPU rather than whichever ICD replied
127172
-- first.
173+
-- SHARED here, and the choice is load-bearing: SDL2's
174+
-- SDL_CreateWindow(SDL_WINDOW_VULKAN) dlopens libvulkan.so.1 and
175+
-- resolves surface creation through whatever it finds. Static, an
176+
-- application ends up with two loaders and createSurface fails on
177+
-- an instance the second never saw.
178+
targets = { ["vulkan"] = { kind = "shared", soname = "libvulkan.so.1" } },
128179
sources = { "*/loader/loader_linux.c" },
129180
cflags = {
130181
"-D_GNU_SOURCE",
@@ -144,6 +195,11 @@ package = {
144195
["compat.x11"] = "1.8.13",
145196
["compat.xcb"] = "1.17.0",
146197
["compat.xorgproto"] = "2025.1",
198+
-- Without this the loader finds every ICD manifest and then
199+
-- fails to dlopen a single driver: an mcpp binary runs under
200+
-- mcpp's own glibc, whose search path does not include the
201+
-- host's. See the note at the top of compat.vulkan-runtime.
202+
["compat.vulkan-runtime"] = "2026.07.29",
147203
},
148204
-- dlopen for the ICDs and layers; pthread for the loader's locks.
149205
ldflags = { "-ldl", "-lpthread", "-lm" },
@@ -184,6 +240,23 @@ package = {
184240
},
185241
},
186242

187-
-- No `windows` block: see the deferral note at the top.
243+
windows = {
244+
-- Nothing to compile: the artifact is the import library plus the
245+
-- .def it came from. The anchor keeps a buildable target, the same
246+
-- shape `compat.opengl` uses for a headers-only package.
247+
--
248+
-- The artifact is packed FLAT — lib/ at the archive root, no wrap
249+
-- directory — because `-L` is not glob-expanded the way
250+
-- include_dirs and sources are. With a wrap layer the relative
251+
-- `-Llib` below misses and the link fails with
252+
-- "LNK1181: cannot open input file 'vulkan-1.lib'".
253+
sources = { "mcpp_generated/vulkan_import_anchor.c" },
254+
ldflags = { "-Llib", "-lvulkan-1" },
255+
runtime = {
256+
-- vulkan-1.dll ships with the GPU driver, not with us.
257+
dlopen_libs = { "vulkan-1.dll" },
258+
capabilities = { "vulkan.icd.driver" },
259+
},
260+
},
188261
},
189262
}

0 commit comments

Comments
 (0)