-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Description
OK, so... this is an issue that's been around for a long time, I'm sure. I've not really had reason to hit it before. And now I have.
Scenario
I'm trying to package a module with a dependency that does p/invoking via native runtime libraries. The library is SkiaSharp. This library cannot be used without native runtimes.
I'd like to be able to handle native runtimes correctly from a compiled PowerShell cmdlet / module.
Problem
The issue then becomes that these native runtimes are different on each platform. Each platform expects that the libraries will be in the same folder as the SkiaSharp.dll. This can't be done for every platform at once, as several of the platform-specific libraries have the same name.
The folder structure after running dotnet publish looks like this:
Ignoring the tizen runtimes (I think they're for Android or something? not sure), a few of the libraries have the same filenames, namely the Windows libraries for the two architectures. A temporary workaround is to put as much as possible in the same folder and ignore that x86 Windows still exists.
Attempted Solutions
We have tried to work around the problem by selectively importing the native libraries, but this is entirely impossible with PowerShell as they throw Bad IL format errors. We have tried:
Import-Module .\bin\Debug\netstandard2.0\publish\runtimes\<platform>\native\<runtime_file>Add-Type -Path .\bin\Debug\netstandard2.0\publish\runtimes\<platform>\native\<runtime_file>[System.Reflection.Assembly]::LoadFile((Resolve-Path ".\bin\Debug\netstandard2.0\publish\runtimes\<platform>\native\<runtime_file>"))
Possible Solutions
- Ability to specify dependencies such as these by relative path in a PSD1 on a per-platform basis, which is respected with
Import-Moduleand loaded correctly. - Some kind of handling in PowerShellGet for native runtimes on a per-platform basis? Possibly handled via NuGet in terms of pulling down the exact runtime required on a specific platform.
There's probably a neater solution I'm missing, feel free to add any suggestions.
Files
Source & module files for reference, if you should like to attempt anything with them:
https://github.com/vexx32/PSWordCloud/tree/Cmdlet/PSWordCloud
Running PSWordCloud
To use:
- Publish the source files for this module with
dotnet publish - Import the PSM1 file in the linked folder with
Import-Module - Attempt to pipe some text into
New-WordCloud -Path .\test.svg
This will work on Windows thanks to the PSM1 manually modifying $env:Path to add all the native runtime folders. This solution is terribly messy and absolutely makes a right royal mess of $env:Path for anyone importing the module. I would like to avoid this.
It attempts to do similar on Mac OS and Linux, but in these cases it seems the path for native runtime libraries isn't searched correctly. The only currently available workaround is manually copying these libraries to the same folder as SkiaSharp.dll which is... less than great.
