From 0c623051f878c00aa8ca7afeb5c25b37d6a2b238 Mon Sep 17 00:00:00 2001 From: Marvel Renju Date: Sun, 26 Mar 2023 22:06:52 +0100 Subject: [PATCH] Link against libc for desktop linux --- src/vk/Commands.cs | 43 +++++++++++++++++++++++++++++++++++++++++-- src/vk/Libc.cs | 22 ++++++++++++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 src/vk/Libc.cs diff --git a/src/vk/Commands.cs b/src/vk/Commands.cs index 7583757..84466cf 100644 --- a/src/vk/Commands.cs +++ b/src/vk/Commands.cs @@ -104,7 +104,8 @@ public static NativeLibrary Load(string libraryName) { return new WindowsNativeLibrary(libraryName); } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) + else if ((RuntimeInformation.IsOSPlatform(OSPlatform.Linux) + && RuntimeInformation.OSDescription.Contains("Unix")) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX) #if NET5_0 || OperatingSystem.IsAndroid() @@ -113,6 +114,10 @@ public static NativeLibrary Load(string libraryName) { return new UnixNativeLibrary(libraryName); } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + return new LinuxNativeLibrary(libraryName); + } else { throw new PlatformNotSupportedException("Cannot load native libraries on this platform: " + RuntimeInformation.OSDescription); @@ -151,7 +156,7 @@ public UnixNativeLibrary(string libraryName) : base(libraryName) protected override IntPtr LoadLibrary(string libraryName) { Libdl.dlerror(); - IntPtr handle = Libdl.dlopen(libraryName, Libdl.RTLD_NOW); + IntPtr handle = Libc.dlopen(libraryName, Libdl.RTLD_NOW); if (handle == IntPtr.Zero && !Path.IsPathRooted(libraryName)) { string baseDir = AppContext.BaseDirectory; @@ -175,5 +180,39 @@ protected override IntPtr LoadFunction(string functionName) return Libdl.dlsym(NativeHandle, functionName); } } + + private class LinuxNativeLibrary : NativeLibrary + { + public LinuxNativeLibrary(string libraryName) : base(libraryName) + { + } + + protected override IntPtr LoadLibrary(string libraryName) + { + Libc.dlerror(); + IntPtr handle = Libc.dlopen(libraryName, Libc.RTLD_NOW); + if (handle == IntPtr.Zero && !Path.IsPathRooted(libraryName)) + { + string baseDir = AppContext.BaseDirectory; + if (!string.IsNullOrWhiteSpace(baseDir)) + { + string localPath = Path.Combine(baseDir, libraryName); + handle = Libc.dlopen(localPath, Libc.RTLD_NOW); + } + } + + return handle; + } + + protected override void FreeLibrary(IntPtr libraryHandle) + { + Libc.dlclose(libraryHandle); + } + + protected override IntPtr LoadFunction(string functionName) + { + return Libc.dlsym(NativeHandle, functionName); + } + } } } diff --git a/src/vk/Libc.cs b/src/vk/Libc.cs new file mode 100644 index 0000000..4f5bf63 --- /dev/null +++ b/src/vk/Libc.cs @@ -0,0 +1,22 @@ +using System; +using System.Runtime.InteropServices; + +namespace Vulkan +{ + internal static class Libc + { + [DllImport("libc")] + public static extern IntPtr dlopen(string fileName, int flags); + + [DllImport("libc")] + public static extern IntPtr dlsym(IntPtr handle, string name); + + [DllImport("libc")] + public static extern int dlclose(IntPtr handle); + + [DllImport("libc")] + public static extern string dlerror(); + + public const int RTLD_NOW = 0x002; + } +}