mono / SkiaSharp

SkiaSharp is a cross-platform 2D graphics API for .NET platforms based on Google's Skia Graphics Library. It provides a comprehensive 2D API that can be used across mobile, server and desktop models to render images.
MIT License
4.5k stars 538 forks source link

[BUG] [WASM] HarfBuzzSharp Linker Errors #1725

Closed nor0x closed 2 years ago

nor0x commented 3 years ago

Description I'm using SkiaSharp + HarfBuzzSharp in a WebAssembly application. I have disabled the linker to reduce the build time for the project which leads to various issues listed below. With the linker enabled the build works fine but takes significantly longer.

This is the setup i'm using:

i'm inspecting the build logs with detailed verbosity and get the following output with System.Exception: Failed to generate AOT layout Behavior

... linker-out > pinvoke-table.h.tmp (TaskId:779)
[00:01:57.7838172] Unhandled exception. System.Exception: Parameter types of pinvoke callback method 'System.IntPtr GetTableDelegateProxyImplementation(System.IntPtr, HarfBuzzSharp.Tag, System.IntPtr)' needs to be blittable. (TaskId:779)                 
[00:01:57.7839076]    at PInvokeTableGenerator.Error(String msg) in D:\a\1\s\src\Uno.Wasm.Tuner\PInvokeTableGenerator.net5.cs:line 328 (TaskId:779)

Unhandled exception. System.Exception: The return type 'HarfBuzzSharp.UnicodeCombiningClass' of pinvoke callback method 'HarfBuzzSharp.UnicodeCombiningClass CombiningClassProxyImplementation(System.IntPtr, System.UInt32, System.Void*)' needs to be blittable.

Basic Information

Reproduction Link

https://github.com/nor0x/skiasharp-1720

Gillibald commented 3 years ago

Do you have a working Ubuntu WSL environment?

nor0x commented 3 years ago

yes, i have WSL1 and WSL2 ready

nor0x commented 3 years ago

i have tried it with the latest preview versions .preview-150 and the issue is still present

Gillibald commented 3 years ago

Most likely an error in the tooling. We need to explicitly define how these enums are handled by p/invoke https://github.com/mono/SkiaSharp/blob/main/binding/HarfBuzzSharp.Shared/HarfBuzzApi.generated.cs#L5722

@mattleibow

martinaxure commented 3 years ago

I'm running into the same issue with .preview-152 whether or not I turn on linking. I'm using SkiaSharp.Views.Blazor

nor0x commented 3 years ago

@mattleibow sorry to ping again but are there any updates or plans on this? disabling the linker would really help us reducing our build times for web assembly. i would be happy to contribute myself but i'm not that deep into HarfBuzzApi.generated

mattleibow commented 3 years ago

Oh golly. Let me see. That is generated and maybe something is funny.

mattleibow commented 3 years ago

Seems to be a bug in .NET 6: https://github.com/dotnet/runtime/issues/61350

I'll try get a workaround for now.

mattleibow commented 2 years ago

Merged a workaround for now

nor0x commented 2 years ago

thank you very much for the fast help! i will test it with my application, is it in the preview-feed already?

martinaxure commented 2 years ago

@nor0x, did you end up building it for yourself? It still hasn't been updated on the nuget feeds.

mattleibow commented 2 years ago

It should be on the https://aka.ms/skiasharp-eap/index.json feeds. Check the latest 2.88.x previews.

nor0x commented 2 years ago

i have the skiasharp-eap feed but the latest version seems to be 2.88.0-preview.155 from 29th of October and this one doesn't have the fix

martinaxure commented 2 years ago

Thank you, @mattleibow! I didn't see the EAP feed on the README.md page 🤦

I'm good to go and Harfbuzz is compiling in my Blazor project.

nor0x commented 2 years ago

latest .171 is available for me now. Thank you 👏👏

martinaxure commented 2 years ago

While I added this to my project file:

<PackageReference Include="HarfBuzzSharp" Version="2.8.2-preview.171" />

I am not seeing libHarfBuzzSharp included in the wasm build:

22> "C:\Program Files\dotnet\packs\Microsoft.NET.Runtime.Emscripten.2.0.23.Sdk.win-x64\6.0.0\tools\bin\wasm-ld.exe" -o C:\Users\martin\git\RP-web\WebRP\Client\obj\Debug\net6.0\wasm\for-build\dotnet.wasm C:\Users\martin\.nuget\packages\skiasharp.nativeassets.webassembly\2.88.0-preview.171\buildTransitive\netstandard1.0\..\..\build\netstandard1.0\libSkiaSharp.a\2.0.23\libSkiaSharp.a C:\Users\martin\git\RP-web\WebRP\Client\obj\Debug\net6.0\wasm\for-build\pinvoke.o C:\Users\martin\git\RP-web\WebRP\Client\obj\Debug\net6.0\wasm\for-build\driver.o C:\Users\martin\git\RP-web\WebRP\Client\obj\Debug\net6.0\wasm\for-build\corebindings.o "C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Runtime.Mono.browser-wasm\6.0.0\runtimes\browser-wasm\native\libicui18n.a" "C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Runtime.Mono.browser-wasm\6.0.0\runtimes\browser-wasm\native\libicuuc.a" "C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Runtime.Mono.browser-wasm\6.0.0\runtimes\browser-wasm\native\libmono-component-debugger-static.a" "C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Runtime.Mono.browser-wasm\6.0.0\runtimes\browser-wasm\native\libmono-component-diagnostics_tracing-stub-static.a" "C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Runtime.Mono.browser-wasm\6.0.0\runtimes\browser-wasm\native\libmono-component-hot_reload-static.a" "C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Runtime.Mono.browser-wasm\6.0.0\runtimes\browser-wasm\native\libmono-ee-interp.a" "C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Runtime.Mono.browser-wasm\6.0.0\runtimes\browser-wasm\native\libmono-icall-table.a" "C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Runtime.Mono.browser-wasm\6.0.0\runtimes\browser-wasm\native\libmono-ilgen.a" "C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Runtime.Mono.browser-wasm\6.0.0\runtimes\browser-wasm\native\libmono-profiler-aot.a" "C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Runtime.Mono.browser-wasm\6.0.0\runtimes\browser-wasm\native\libmonosgen-2.0.a" "C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Runtime.Mono.browser-wasm\6.0.0\runtimes\browser-wasm\native\libSystem.IO.Compression.Native.a" "C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Runtime.Mono.browser-wasm\6.0.0\runtimes\browser-wasm\native\libSystem.Native.a" "-LC:\Program Files\dotnet\packs\Microsoft.NET.Runtime.Emscripten.2.0.23.Sdk.win-x64\6.0.0\tools\emscripten\cache\sysroot\lib\wasm32-emscripten" "C:\Program Files\dotnet\packs\Microsoft.NET.Runtime.Emscripten.2.0.23.Sdk.win-x64\6.0.0\tools\emscripten\cache\sysroot\lib\wasm32-emscripten\libgl.a" "C:\Program Files\dotnet\packs\Microsoft.NET.Runtime.Emscripten.2.0.23.Sdk.win-x64\6.0.0\tools\emscripten\cache\sysroot\lib\wasm32-emscripten\libal.a" "C:\Program Files\dotnet\packs\Microsoft.NET.Runtime.Emscripten.2.0.23.Sdk.win-x64\6.0.0\tools\emscripten\cache\sysroot\lib\wasm32-emscripten\libhtml5.a" "C:\Program Files\dotnet\packs\Microsoft.NET.Runtime.Emscripten.2.0.23.Sdk.win-x64\6.0.0\tools\emscripten\cache\sysroot\lib\wasm32-emscripten\libc.a" "C:\Program Files\dotnet\packs\Microsoft.NET.Runtime.Emscripten.2.0.23.Sdk.win-x64\6.0.0\tools\emscripten\cache\sysroot\lib\wasm32-emscripten\libcompiler_rt.a" "C:\Program Files\dotnet\packs\Microsoft.NET.Runtime.Emscripten.2.0.23.Sdk.win-x64\6.0.0\tools\emscripten\cache\sysroot\lib\wasm32-emscripten\libc++.a" "C:\Program Files\dotnet\packs\Microsoft.NET.Runtime.Emscripten.2.0.23.Sdk.win-x64\6.0.0\tools\emscripten\cache\sysroot\lib\wasm32-emscripten\libc++abi.a" "C:\Program Files\dotnet\packs\Microsoft.NET.Runtime.Emscripten.2.0.23.Sdk.win-x64\6.0.0\tools\emscripten\cache\sysroot\lib\wasm32-emscripten\libdlmalloc.a" "C:\Program Files\dotnet\packs\Microsoft.NET.Runtime.Emscripten.2.0.23.Sdk.win-x64\6.0.0\tools\emscripten\cache\sysroot\lib\wasm32-emscripten\libc_rt_wasm.a" "C:\Program Files\dotnet\packs\Microsoft.NET.Runtime.Emscripten.2.0.23.Sdk.win-x64\6.0.0\tools\emscripten\cache\sysroot\lib\wasm32-emscripten\libsockets.a" -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-cxx-exceptions -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --allow-undefined --export putchar --export stackSave --export stackRestore --export stackAlloc --export __wasm_call_ctors --export __errno_location --export malloc --export free --export __cxa_is_pointer_type --export __cxa_can_catch --export setThrew --export memalign --export memset --export emscripten_main_thread_process_queued_calls --export _get_tzname --export _get_daylight --export _get_timezone --export ntohs --export htons --export htonl --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-table -z stack-size=5242880 --initial-memory=536870912 --no-entry --max-memory=2147483648 --global-base=1024
22> "C:\Program Files\dotnet\packs\Microsoft.NET.Runtime.Emscripten.2.0.23.Sdk.win-x64\6.0.0\tools\bin\wasm-emscripten-finalize" --minimize-wasm-changes -g --dyncalls-i64 --dwarf C:\Users\martin\git\RP-web\WebRP\Client\obj\Debug\net6.0\wasm\for-build\dotnet.wasm -o C:\Users\martin\git\RP-web\WebRP\Client\obj\Debug\net6.0\wasm\for-build\dotnet.wasm --detect-features
22> "C:\Program Files\dotnet\packs\Microsoft.NET.Runtime.Emscripten.2.0.23.Node.win-x64\6.0.0\tools\bin\node.exe" "C:\Program Files\dotnet\packs\Microsoft.NET.Runtime.Emscripten.2.0.23.Sdk.win-x64\6.0.0\tools\emscripten\src\compiler.js" C:\Users\martin\AppData\Local\Temp\tmpf3nrw8za.txt
22> "C:\Program Files\dotnet\packs\Microsoft.NET.Runtime.Emscripten.2.0.23.Sdk.win-x64\6.0.0\tools\bin\llvm-objcopy.exe" C:\Users\martin\git\RP-web\WebRP\Client\obj\Debug\net6.0\wasm\for-build\dotnet.wasm C:\Users\martin\git\RP-web\WebRP\Client\obj\Debug\net6.0\wasm\for-build\dotnet.wasm --remove-section=producers
22>Optimizing dotnet.wasm ...

And am accordingly seeing the following error:

crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: libHarfBuzzSharp
System.DllNotFoundException: libHarfBuzzSharp
   at HarfBuzzSharp.Buffer..ctor()

How is SkiaSharp.Views.Blazor getting the files into the wasm build?

Thanks in advance.

martinaxure commented 2 years ago

I noticed that the packages aren't adding HarfBuzzSharp.NativeAssets.WebAssembly as a Compile time assembly. I tried adding them manually, but it didn't help much.

image

Gillibald commented 2 years ago

Even adding the NativeAssets package didn't solve this for me.

I had to add the library manually:

 <ItemGroup>
    <NativeFileReference Include="libHarfBuzzSharp.a" />
  </ItemGroup>

Just extract the library from the package. The Emscripten version should match. .nuget\packages\harfbuzzsharp.nativeassets.webassembly\2.8.2-preview.171\build\netstandard1.0\libHarfBuzzSharp.a\2.0.23

martinaxure commented 2 years ago

@Gillibald, thank you, this worked! @mattleibow, would you like me to file a bug for this one?

JensKrumsieck commented 2 years ago

You do not have to extract the file from your .nuget-Folder. The following worked for me (in an ItemGroup-Block): <NativeFileReference Include="$(HarfBuzzSharpStaticLibraryPath)\2.0.23\*.a" />