iOS: bootstrap Vulkan via main-binary dlsym (vkGetInstanceProcAddr re-exported)

This commit is contained in:
Virgile Bello
2026-06-11 15:04:56 +09:00
parent 9505c364ee
commit fa0b794902
2 changed files with 14 additions and 5 deletions
@@ -28,13 +28,12 @@ namespace Stride.Graphics
// when one is installed (e.g. via 'brew install vulkan-loader') because only the loader
// chains validation layers — bundled MoltenVK alone is an ICD and ignores VK_LAYER_*.
// If no loader is available, fall back to the bundled MoltenVK at runtimes/<rid>/native/.
// On iOS, MoltenVK is statically linked into the app bundle (iOS forbids dlopen of
// arbitrary dylibs); "__Internal" resolves to the main executable's symbol table,
// so Vortice's NativeLibrary.GetExport finds vkGetInstanceProcAddr there.
// On iOS, MoltenVK is statically linked into the app binary: dlopen the executable itself,
// which exports vkGetInstanceProcAddr (see Stride.Core.NativeLibraries.targets).
string vkLibraryName = Platform.Type switch
{
PlatformType.macOS => ResolveMacOSVulkanLibrary(),
PlatformType.iOS => "__Internal",
PlatformType.iOS => Environment.ProcessPath,
_ => null,
};
var result = vkInitialize(vkLibraryName);
@@ -17,7 +17,9 @@
Platform-specific handling:
- Desktop (Windows/Linux/macOS): Native libs copied as None items
- Android: Native libs added as AndroidNativeLibrary
- iOS: Native libs linked via mtouch arguments
- iOS: Native libs added as NativeReference (Kind=Static, ForceLoad=True) so libfoo.a is
whole-archive linked into the main executable; libMoltenVK.a additionally re-exports
vkGetInstanceProcAddr so Vortice.Vulkan's dlsym-based loader finds it.
================================================================
-->
@@ -197,6 +199,14 @@
<ForceLoad>True</ForceLoad>
<SmartLink>False</SmartLink>
</NativeReference>
<!-- libMoltenVK.a: re-export vkGetInstanceProcAddr from the final binary's dynamic
symbol table. Vortice.Vulkan bootstraps with NativeLibrary.Load("__Internal") +
NativeLibrary.GetExport(handle, "vkGetInstanceProcAddr") → dlsym, which only sees
dynamically-exported symbols. Static-linked .a symbols are local by default ("t" in
nm), so without this flag Vortice's vkInitialize returns ErrorInitializationFailed. -->
<NativeReference Update="@(NativeReference)"
Condition="$([System.String]::new('%(Identity)').EndsWith('libMoltenVK.a'))"
LinkerFlags="-Wl,-exported_symbol,_vkGetInstanceProcAddr" />
</ItemGroup>
</Target>