Repository navigation
Description
What exists, and what it already closed
src/build/plan.cppm (runtimeDeployFiles, add_deploy): every *.dll under a dependency's runtime.library_dirs is copied to bin/<filename> beside the executable. The filter is the .dll extension and the destination is flattened into bin/. linkIntent.deployFiles ("explicit and platform-neutral") also lands at bin/<filename>.
That was enough for Windows Vulkan. mcpplibs/mcpp-index#395 ships vulkan-1.dll inside compat.vulkan 1.4.357.3 with runtime.library_dirs = { "bin" }, and on windows-2022 — confirmed to have no system loader — mcpp build, mcpp test, and mcpp pack followed by a run from a clean directory with PATH = System32 all load the deployed DLL (loader api 1.4.357). Transitive dependencies and test binaries are covered too (checked locally with 2026.9.11.2).
What macOS needs — measured
mcpplibs/mcpp-index#396, run 34611138464, macos-15 arm64, mcpp 2026.9.11.2, a probe program depending on compat.vulkan (the statically linked loader, APPLE_STATIC_LOADER):
- CoreFoundation, for an unbundled executable, reports the main bundle's resources directory as the executable's own directory:
bundle url = /Users/runner/work/_temp/cfprobe/bin resources dir = /Users/runner/work/_temp/cfprobe/bin - The loader (
loader/loader.c) puts<resources dir>/vulkan/icd.dat the front of its ICD search path.
| case | exit | result |
|---|---|---|
| A — no MoltenVK anywhere | 0 | vkCreateInstance = VK_ERROR_INCOMPATIBLE_DRIVER, "Found no drivers!", 0 devices |
B — bin/libMoltenVK.dylib + bin/vulkan/icd.d/MoltenVK_icd.json with "library_path": "../../libMoltenVK.dylib" |
0 | vkCreateInstance = 0, 1 device: Apple Paravirtual device |
B2 — same, absolute library_path |
0 | 1 device |
B3 — the whole bin/ copied to another directory, relative library_path |
0 | manifest found at the new location, 1 device |
C — VK_DRIVER_FILES=<abs manifest> |
0 | 1 device |
(The instance enables VK_KHR_portability_enumeration with VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; that part is the consumer's.)
So the layout works and is relocatable (B3). A package holding MoltenVK only needs mcpp to put two files there.
What a package cannot do today
- On Mach-O,
runtime.library_dirsbecomes an RPATH, not a copy — and the loader reaches the ICD through the manifest'slibrary_path, not through the executable's RPATH. - Deployment is
.dll-only, solibMoltenVK.dylibis not copied. - The destination is flattened, so there is no way to place
vulkan/icd.d/MoltenVK_icd.json.
Ask
A structured deploy declaration whose destination is relative to the executable's directory and may contain subdirectories, honored on every platform — for example:
runtime = {
deploy = {
{ from = "lib/libMoltenVK.dylib", to = "." },
{ from = "share/vulkan/icd.d/MoltenVK_icd.json", to = "vulkan/icd.d" },
},
},No rewrite at deploy time is needed: a relative library_path travels with the directory (B3). The existing add_deploy collision check carries over unchanged if it keys on the full relative destination instead of the filename.
Related, but not this issue
mcpp pack refuses Mach-O programs today (cannot package the Mach-O program '…' yet — the closure is resolved through LD_TRACE_LOADED_OBJECTS, which dyld does not honour). So carrying these files in a packed macOS program waits on that. The deploy above already makes mcpp run, mcpp test, and shipping the build tree work.
Not urgent
Nothing crashes without MoltenVK (case A), and VK_DRIVER_FILES works in the meantime (case C). Filing so the macOS half of the Vulkan closure has a precise, measured target.
Activity
docs(vulkan): the cross-platform closure as implemented and measured
docs(vulkan): the cross-platform closure as implemented and measured (#…
feat(khronos.vulkan-hpp): 1.4.357.1 follows compat.vulkan 1.4.357.3; …
feat: the engine gaps left open after the SDK batch (2026.9.12.2)
The engine gaps left open after the SDK batch (2026.9.12.2) (#619)
Sunrisepeak commentedon Sep 11, 2026
Resolved in mcpp 2026.9.12.2 (#619).
runtime.deploy = [{ from, to }], in mcpp.toml and in descriptors, places a runtime file in a directory relative to the executable.to = "."means beside the executable, andbin/vulkan/icd.d/<file>is reached withto = "vulkan/icd.d"./-separated, not absolute, names no drive, and has no empty,.or..component. A malformed entry is refused naming its index.mcpp packcarries bothdeploy_filesanddeployat the same relative paths; before this, pack read neither list.deployis a key of its own because an older descriptor reader does not terminate on a table insidedeploy_files.Measured by tests/e2e/646 on Linux, macOS and Windows CI, and by 649 for pack.
Android, iOS and Web for a UI framework: the engine half of #622 (202…