kleisauke / net-vips

.NET binding for libvips.
https://kleisauke.github.io/net-vips/
MIT License
401 stars 32 forks source link

NetVips is set on loading dlls on Arch linux #186

Closed Silverdimond closed 1 year ago

Silverdimond commented 1 year ago

While trying using NetVips Version 2.2.0 on linux with dotnet7 I keep getting exceptions telling me the libvips-42.dll was not found

System.DllNotFoundException: Unable to load shared library 'libvips-42.dll' or one of its dependencies. In order to help diagnose loading problems, consider using a tool like strace. If you're using glibc, consider setting the LD_DEBUG environment variable:
(PROJECT BIN DEBUG DIR)/runtimes/linux-x64/native/libvips-42.dll.so: cannot open shared object file: No such file or directory
/usr/share/dotnet/shared/Microsoft.NETCore.App/7.0.0/libvips-42.dll.so: cannot open shared object file: No such file or directory
(PROJECT BIN DEBUG DIR)/libvips-42.dll.so: cannot open shared object file: No such file or directory
(PROJECT BIN DEBUG DIR)/runtimes/linux-x64/native/liblibvips-42.dll.so: cannot open shared object file: No such file or directory
/usr/share/dotnet/shared/Microsoft.NETCore.App/7.0.0/liblibvips-42.dll.so: cannot open shared object file: No such file or directory
(PROJECT BIN DEBUG DIR)/liblibvips-42.dll.so: cannot open shared object file: No such file or directory
(PROJECT BIN DEBUG DIR)/runtimes/linux-x64/native/libvips-42.dll: cannot open shared object file: No such file or directory
/usr/share/dotnet/shared/Microsoft.NETCore.App/7.0.0/libvips-42.dll: cannot open shared object file: No such file or directory
(PROJECT BIN DEBUG DIR)/libvips-42.dll: cannot open shared object file: No such file or directory
(PROJECT BIN DEBUG DIR)/runtimes/linux-x64/native/liblibvips-42.dll: cannot open shared object file: No such file or directory
/usr/share/dotnet/shared/Microsoft.NETCore.App/7.0.0/liblibvips-42.dll: cannot open shared object file: No such file or directory
(PROJECT BIN DEBUG DIR)/liblibvips-42.dll: cannot open shared object file: No such file or directory

With NetVips.Native Version 8.13.2 (PROJECT BIN DEBUG DIR)/runtimes/linux-x64/native/libvips.so.42 does exist but (PROJECT BIN DEBUG DIR)/runtimes/linux-x64/native/libvips-42.dll.so doesn't. Decompiling using fuget image And decompiling using jetbrains rider image Leads me to believe it is trying to find the a sort of .dll.so hybrid which is just not present in the runtimes native folder. Either way renaming (PROJECT BIN DEBUG DIR)/runtimes/linux-x64/native/libvips.so.42 to (PROJECT BIN DEBUG DIR)/runtimes/linux-x64/native/libvips-42.dll.so doesn't fix the issue because it requests a different dll libgobject-2.0-0.dll. According to nuget.info libgobject-2.0-0 isn't even shipped image but I am assuming it is referring to libglib-2.0.so (provided by glib2 on the arch linux core repo) But it can't load libglib-2.0.so by asking for libgobject-2.0-0.dll.so I doubt that the distro has anything to do with this but I am using EndeavourOS with the 5.15.82-1-lts kernel

kleisauke commented 1 year ago

The NetVips NuGet package is packaged in a multi-targeted manner, it uses a different DLL on the OS on which it is deployed (i.e. runtimes/linux/lib/netstandard2.0/NetVips.dll on Linux and runtimes/osx/lib/netstandard2.0/NetVips.dll on macOS).

On Linux specifically, all shared libraries point to libvips.so.42 (allowing the pre-built binaries to be distributed as a single shared library). https://github.com/kleisauke/net-vips/blob/ec9a3adf3d6bb961134ef2ca1c1e0c82247225f4/src/NetVips/Interop/Libraries.Linux.cs#L5-L13 (note that this file was renamed to Libraries.Unix.cs in commit 3ebac038aee6506a402df6c70de8b51f87c2d8fa to ensure compatibility with FreeBSD and variants)

Given this information, I suspect that the Runtime Identifier (RID) is incorrectly set, causing the wrong DLL to be referenced. Could you provide the information of the following commands?

$ dotnet --info
$ echo $DOTNET_RUNTIME_ID
Silverdimond commented 1 year ago

Running the previously mentioned commands results in this information

❰silver❙~❱✔≻ dotnet --info
.NET SDK:
 Version:   7.0.100
 Commit:    e12b7af219

Runtime Environment:
 OS Name:     endeavouros
 OS Version:  
 OS Platform: Linux
 RID:         arch-x64
 Base Path:   /usr/share/dotnet/sdk/7.0.100/

Host:
  Version:      7.0.0
  Architecture: x64
  Commit:       d099f075e4

.NET SDKs installed:
  6.0.111 [/usr/share/dotnet/sdk]
  7.0.100 [/usr/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.11 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 7.0.0 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.11 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.0 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  None

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download
❰silver❙~❱✔≻ echo $DOTNET_RUNTIME_ID

(the second command's result is empty)

Silverdimond commented 1 year ago

https://bugs.archlinux.org/task/59195 could be related to this odd arch-x64 runtime identifier but in that case this issue would be a fault of the arch linux dotnet package

Silverdimond commented 1 year ago

Replacing all dotnet related packages (pacman -Qq | grep -E 'dotnet|standard|aspnet')

aspnet-runtime
aspnet-runtime-6.0
aspnet-targeting-pack
aspnet-targeting-pack-6.0
dotnet-host
dotnet-runtime
dotnet-runtime-6.0
dotnet-sdk
dotnet-sdk-6.0
dotnet-targeting-pack
dotnet-targeting-pack-6.0
netstandard-targeting-pack

to their -bin arch user repository counterparts (via yay)

aspnet-runtime-6.0-bin
aspnet-runtime-bin
aspnet-targeting-pack-6.0
aspnet-targeting-pack-bin
dotnet-host-bin
dotnet-runtime-6.0-bin
dotnet-runtime-bin
dotnet-sdk-6.0-bin
dotnet-sdk-bin
dotnet-targeting-pack-6.0-bin
dotnet-targeting-pack-bin
netstandard-targeting-pack-bin

has changed the output of dotnet --info to

.NET SDK:
 Version:   7.0.100
 Commit:    e12b7af219

Runtime Environment:
 OS Name:     endeavouros
 OS Version:  
 OS Platform: Linux
 RID:         linux-x64
 Base Path:   /usr/share/dotnet/sdk/7.0.100/

Host:
  Version:      7.0.0
  Architecture: x64
  Commit:       d099f075e4

.NET SDKs installed:
  6.0.403 [/usr/share/dotnet/sdk]
  7.0.100 [/usr/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.11 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 7.0.0 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.11 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.0 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  None

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download

And that fixes the dll loading issue So the RID was to blame after all

kleisauke commented 1 year ago

It looks like this is being tracked in issue https://github.com/dotnet/runtime/issues/62554, which also affects the System.IO.Ports NuGet package.

the second command's result is empty

This is expected, you can overridde the detected RID with that environment variable, so in most cases it's not set.