I try to create a Xamarin.iOS class library, which uses SkiaSharp internally. I would like to distribute the final class library as a single dll without external dependencies. For this purpose I use ILMerge (or ILRepack). Final dll is successfully created but when I try to call some method from my class library I get DllNotFoundException. Here is the stack trace:
{System.DllNotFoundException: @rpath/libSkiaSharp.framework/libSkiaSharp at (wrapper managed-to-native) SkiaSharp.SkiaApi:sk_filestream_new (string) at SkiaSharp.SKFileStream..ctor (System.String path) [0x00000] in <9d222c42d8aa4f729033b25ddebc012a>:0 at SkiaSharp.SKBitmap.Decode (System.String filename) [0x00011] in <9d222c42d8aa4f729033b25ddebc012a>:0 at TestMerge.TestClass.TestMethod (System.String imageFile) [0x00001] in <9d222c42d8aa4f729033b25ddebc012a>:0 at Tests.Xamarin.Tests.Test001 () [0x00002] in /Users/mac1/Projects/awxamarin/Xamarin.Tests/Tests.Xamarin/Tests.cs:19 }
Steps to reproduce:
Create some simple public class with method that uses SkiaSharp. For example
namespace TestMerge
{
public class TestClass
{
public static void TestMethod(string imageFile)
{
SkiaSharp.SKBitmap bmp = SkiaSharp.SKBitmap.Decode(imageFile);
}
}
}
Build the project and merge dlls using ILMerge (or ILRepack if you like it more). Here is the command used to merge dlls:
ILMerge.exe /log:C:\Temp\ILMerge.log /internalize /ndebug /targetplatform:v4,"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\Xamarin.iOS\v1.0" /out:C:\Temp\TestMerge.dll C:\Temp\TestMerge\TestMerge\bin\Debug\TestMerge.dll C:\Temp\TestMerge\TestMerge\bin\Debug\SkiaSharp.dll
I tried to decompile my dll and libSkiaSharp.framework is there, it is embedded as a resource, just like in SkiaSharp.dll. Any help is appreciated, I am stuck with this. By the way, exactly the same approach works fine for Xamarin.Android.
I finally get it worked. The solution was simple as always :). To make it work it is required to add the following attribute into the AssemblyInfo.cs of the main class library project:
[assembly: ObjCRuntime.LinkWith("libSkiaSharp.framework", SmartLink = true)]
Hope this will be useful for others