Skip to content

runtime deploy: let a dependency place non-.dll runtime files beside the executable — a .dylib and a manifest in a subdirectory, which macOS Vulkan needs (measured working) #615

Description

@Sunrisepeak

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.d at 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_dirs becomes an RPATH, not a copy — and the loader reaches the ICD through the manifest's library_path, not through the executable's RPATH.
  • Deployment is .dll-only, so libMoltenVK.dylib is 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions