| 12 Dec 2024 |
6pak | it does | 20:03:24 |
GGG | * if it doesn't then there's no point in using it as we already statically know all the libraries that are loaded through DllImport | 20:03:35 |
6pak | actually maybe only for the libraryName overload that also takes in the assembly | 20:04:57 |
GGG | seems like neither do:
Given a library name, this method searches specific paths based on the runtime configuration, input parameters, and attributes of the calling assembly. If the searchPath parameter is non-null, the flags in this enumeration are used. Otherwise, the flags specified by the DefaultDllImportSearchPathsAttribute on the calling assembly, if any are present, are used. This method does not invoke the resolver registered using SetDllImportResolver(Assembly, DllImportResolver) method. Starting with .NET 5, this method does invoke the AssemblyLoadContext.LoadUnmanagedDll method and the AssemblyLoadContext.ResolvingUnmanagedDll event.
| 20:06:00 |
GGG | so I honestly don't think there's a point in using SetDllImportResolver as they're all static known strings we can modify directly | 20:06:36 |
GGG | not to mention if, for some reason, some app decides to use their own DllImportResolver then that'd make our tool not work | 20:08:44 |
6pak | In reply to @gggkiller:matrix.org
seems like neither do:
Given a library name, this method searches specific paths based on the runtime configuration, input parameters, and attributes of the calling assembly. If the searchPath parameter is non-null, the flags in this enumeration are used. Otherwise, the flags specified by the DefaultDllImportSearchPathsAttribute on the calling assembly, if any are present, are used. This method does not invoke the resolver registered using SetDllImportResolver(Assembly, DllImportResolver) method. Starting with .NET 5, this method does invoke the AssemblyLoadContext.LoadUnmanagedDll method and the AssemblyLoadContext.ResolvingUnmanagedDll event.
oh, I was thinking of AssemblyLoadContext.ResolvingUnmanagedDll then | 20:11:57 |
6pak | which I think is also called for dllimports | 20:12:08 |
GGG | ok, got it working by overriding the DllImports, I think I'll make a minimal version with it and then if you want to convert it to the ResolvingUnmanagedDll event, I'll leave it up to you since you know more about this library than me 6pak | 23:40:32 |
GGG | if you're okay with it | 23:40:34 |
| 13 Dec 2024 |
GGG | ok, managed to write the code for an auto patchcil command, haven't tested yet, will leave that for tomorrow https://github.com/GGG-KILLER/patchcil/blob/main/src/Commands/AutoCommand.cs | 06:33:41 |
GGG | seems to output the expected errors, although I'll have to see about finding the libraries:
$ patchcil auto -r linux-x64 --paths /nix/store/zc4zc1rcf3vj4x3zbqnkpjifj31qijbg-avalonia-ilspy-7.2-rc/lib/avalonia-ilspy/Avalonia.X11.dll
searching for dependencies of /nix/store/zc4zc1rcf3vj4x3zbqnkpjifj31qijbg-avalonia-ilspy-7.2-rc/lib/avalonia-ilspy/Avalonia.X11.dll
libICE.so.6 -> not found!
libSM.so.6 -> not found!
libc -> not found!
libX11.so.6 -> not found!
libXrandr.so.2 -> not found!
libXi.so.6 -> not found!
libXcursor.so.1 -> not found!
libglib-2.0.so.0 -> not found!
libgobject-2.0.so.0 -> not found!
libgtk-3.so.0 -> not found!
libgdk-3.so.0 -> not found!
libGL.so.1 -> not found!
patchcil-auto: 12 dependencies could not be satisfied
error: patchcil-auto could not satisfy dependency libICE.so.6 wanted by /nix/store/zc4zc1rcf3vj4x3zbqnkpjifj31qijbg-avalonia-ilspy-7.2-rc/lib/avalonia-ilspy/Avalonia.X11.dll
error: patchcil-auto could not satisfy dependency libSM.so.6 wanted by /nix/store/zc4zc1rcf3vj4x3zbqnkpjifj31qijbg-avalonia-ilspy-7.2-rc/lib/avalonia-ilspy/Avalonia.X11.dll
error: patchcil-auto could not satisfy dependency libc wanted by /nix/store/zc4zc1rcf3vj4x3zbqnkpjifj31qijbg-avalonia-ilspy-7.2-rc/lib/avalonia-ilspy/Avalonia.X11.dll
error: patchcil-auto could not satisfy dependency libX11.so.6 wanted by /nix/store/zc4zc1rcf3vj4x3zbqnkpjifj31qijbg-avalonia-ilspy-7.2-rc/lib/avalonia-ilspy/Avalonia.X11.dll
error: patchcil-auto could not satisfy dependency libXrandr.so.2 wanted by /nix/store/zc4zc1rcf3vj4x3zbqnkpjifj31qijbg-avalonia-ilspy-7.2-rc/lib/avalonia-ilspy/Avalonia.X11.dll
error: patchcil-auto could not satisfy dependency libXi.so.6 wanted by /nix/store/zc4zc1rcf3vj4x3zbqnkpjifj31qijbg-avalonia-ilspy-7.2-rc/lib/avalonia-ilspy/Avalonia.X11.dll
error: patchcil-auto could not satisfy dependency libXcursor.so.1 wanted by /nix/store/zc4zc1rcf3vj4x3zbqnkpjifj31qijbg-avalonia-ilspy-7.2-rc/lib/avalonia-ilspy/Avalonia.X11.dll
error: patchcil-auto could not satisfy dependency libglib-2.0.so.0 wanted by /nix/store/zc4zc1rcf3vj4x3zbqnkpjifj31qijbg-avalonia-ilspy-7.2-rc/lib/avalonia-ilspy/Avalonia.X11.dll
error: patchcil-auto could not satisfy dependency libgobject-2.0.so.0 wanted by /nix/store/zc4zc1rcf3vj4x3zbqnkpjifj31qijbg-avalonia-ilspy-7.2-rc/lib/avalonia-ilspy/Avalonia.X11.dll
error: patchcil-auto could not satisfy dependency libgtk-3.so.0 wanted by /nix/store/zc4zc1rcf3vj4x3zbqnkpjifj31qijbg-avalonia-ilspy-7.2-rc/lib/avalonia-ilspy/Avalonia.X11.dll
error: patchcil-auto could not satisfy dependency libgdk-3.so.0 wanted by /nix/store/zc4zc1rcf3vj4x3zbqnkpjifj31qijbg-avalonia-ilspy-7.2-rc/lib/avalonia-ilspy/Avalonia.X11.dll
error: patchcil-auto could not satisfy dependency libGL.so.1 wanted by /nix/store/zc4zc1rcf3vj4x3zbqnkpjifj31qijbg-avalonia-ilspy-7.2-rc/lib/avalonia-ilspy/Avalonia.X11.dll
patchcil-auto failed to find all the required dependencies.
Add the missing dependencies to --libs or use `--ignore-missing="foo.so.1 bar.so etc.so"`.
| 06:36:58 |
6pak | looks pretty good | 15:52:03 |
6pak | rid-graph-gen is interesting, but fyi there is a C# reader for the graph here https://github.com/dotnet/dotnet/blob/v9.0.101/src/nuget-client/src/NuGet.Core/NuGet.Packaging/RuntimeModel/JsonRuntimeFormat.cs | 15:52:34 |
6pak | which the sdk uses | 15:52:38 |
6pak | so you could have just done JsonRuntimeFormat.ReadRuntimeGraph(<$(RuntimeIdentifierGraphPath) from msbuild>).ExpandRuntime("linux-x64") | 15:53:14 |
6pak | and looking more into the runtimes/{rid}/native/{libname}.so pattern seems like it's only a build-time nuget thing | 16:24:33 |
6pak | the runtime only looks at the .deps.json file to discover the library paths, which dotnet sdk populates from nuget info | 16:25:38 |
6pak | * and looking more into the runtimes/{rid}/native/{libname}.so pattern, seems like it's only a build-time nuget thing | 16:26:54 |
6pak | and it does pick just the best matching rid, but only inside one dependency | 16:42:40 |
6pak | and even though it has the full library path, it registers the directory as a search path | 16:43:59 |
6pak | so if lib A has runtimes/linux-x64/native/liba.so and lib B has runtimes/linux-musl-x64/native/libb.so, both runtimes/linux-x64/native and runtimes/linux-musl-x64/native will be registered as native search paths | 16:47:02 |
GGG | In reply to @6pak:matrix.org so you could have just done JsonRuntimeFormat.ReadRuntimeGraph(<$(RuntimeIdentifierGraphPath) from msbuild>).ExpandRuntime("linux-x64") That's an interesting idea, however I wanted to have everything as optimized as possible, although I know most of the overhead will be in AsmResolver, I wanted to have little to no overhead on anything else so this doesn't slow down any builds My long term objective with this is to use NativeAOT to have a really good cold start performance | 22:04:01 |
GGG | Don't know if I'm overthinking this though | 22:04:14 |
GGG | In reply to @6pak:matrix.org and looking more into the runtimes/{rid}/native/{libname}.so pattern, seems like it's only a build-time nuget thing Yes, however my plan is to use autoPatchcil on the nuget restore step so nuget libraries with native tools and stuff work just fine Long term I also want to find and transform any self-contained deployments into framework dependent ones so that they use the nixpkgs SDK/runtime instead of their own bundled one, that way we can avoid issues with ICU, openssl and libz | 22:06:56 |
GGG | * Yes, however my plan is to use autoPatchcil on the nuget restore step so nuget libraries with native tools and stuff work just fine as they'll probably run on the build step (like the grpc package and entity framework)
Long term I also want to find and transform any self-contained deployments into framework dependent ones so that they use the nixpkgs SDK/runtime instead of their own bundled one, that way we can avoid issues with ICU, openssl and libz | 22:07:42 |
GGG | In reply to @6pak:matrix.org the runtime only looks at the .deps.json file to discover the library paths, which dotnet sdk populates from nuget info That's good to know, I'll look into it and try to add that logic into the command | 22:08:50 |
GGG | Also, while running it in a dry run against avalonia, I ran into something rather unpleasant | 22:11:45 |
GGG | There's `.dll` and `.dylib` imports in it as well, so it won't be as plug'n'play as `autoPatchelfHook`, I had to add quite a few thing to the ignores list like `*.dll`, `kernel32`, `user32` and more | 22:13:17 |
GGG | It might be worth adding an option to exclude certain files on top of ignoring certain imports | 22:13:51 |