Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

M1 not supported #77

Closed
mHooshdar opened this issue Apr 24, 2022 · 13 comments
Closed

M1 not supported #77

mHooshdar opened this issue Apr 24, 2022 · 13 comments

Comments

@mHooshdar
Copy link

mHooshdar commented Apr 24, 2022

Hi, I tried this package on MacBook with M1 processor and I got this error:

I tried it on another mac and it is been worked. I think that this package does not M1 processor
Can you help me to solve this?

 ---> System.NotSupportedException: Unable to load native library. The platform may be missing native dependencies (libjpeg62, etc). Or the current platform is not supported.
   at WkHtmlToPdfDotNet.ModuleFactory.GetModule()
   at WkHtmlToPdfDotNet.PdfTools.Load()
   at WkHtmlToPdfDotNet.BasicConverter.Convert(IDocument document)
   at WkHtmlToPdfDotNet.SynchronizedConverter.<>n__0(IDocument document)
   at WkHtmlToPdfDotNet.SynchronizedConverter.<>c__DisplayClass4_0.<Convert>b__0()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__272_0(Object obj)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.Wait()
   at WkHtmlToPdfDotNet.SynchronizedConverter.Invoke[TResult](Func`1 delegate)
   at WkHtmlToPdfDotNet.SynchronizedConverter.Convert(IDocument document)
   at Nacho.Infrastructure.HtmlToPdfConverter.<>c__DisplayClass2_0.<ConvertToPdf>b__0() in /Users/mhooshdar/Desktop/Alibaba/hydra-nacho/src/Nacho.Infrastructure/HtmlToPdfConverter.cs:line 23
   at System.Threading.Tasks.Task.InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__272_0(Object obj)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
   at Nacho.Infrastructure.HtmlToPdfConverter.ConvertToPdf(String html) in /Users/mhooshdar/Desktop/Alibaba/hydra-nacho/src/Nacho.Infrastructure/HtmlToPdfConverter.cs:line 21
   at Nacho.Application.Handlers.GetTicketHandler.ConvertToPdf(String html) in /Users/mhooshdar/Desktop/Alibaba/hydra-nacho/src/Nacho.Application/Handlers/GetTicketHandler.cs:line 51
   at Nacho.Application.Handlers.GetTicketHandler.Handle[TModel](GetTicketRequest`1 request) in /Users/mhooshdar/Desktop/Alibaba/hydra-nacho/src/Nacho.Application/Handlers/GetTicketHandler.cs:line 31
   at Nacho.Host.Controllers.DomesticFlightController.GetTicket(Nullable`1 outputFormat) in /Users/mhooshdar/Desktop/Alibaba/hydra-nacho/src/Nacho.Host/Controllers/DomesticFlightController.cs:line 49
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Logged|12_1(ControllerActionInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ExceptionContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Prometheus.HttpMetrics.HttpRequestDurationMiddleware.Invoke(HttpContext context)
   at Prometheus.HttpMetrics.HttpRequestCountMiddleware.Invoke(HttpContext context)
   at Prometheus.HttpMetrics.HttpInProgressMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
@HakanL
Copy link
Owner

HakanL commented May 6, 2022

Since this project is just a wrapper around the native library, my guess is that it fails to load the native library. Try to install it directly and see if there's a different binary for M1 than what's in this solution.

@pasih
Copy link

pasih commented May 10, 2022

I have a M1 laptop and I was testing this the other day. Command line wkhtmltopdf works fine. I tried to copy the libwkhtmltox.dylib that came with the binary to the nuget package's runtimes directory but it didn't seem to work.

Should it work without changes to ModuleFactory? The error originates from there but I didn't have time to investigate further then. Do we need a new module (akin to WkHtmlModuleLinux64) with correct DLLNAME?

@HakanL
Copy link
Owner

HakanL commented May 10, 2022

@pasih In theory the .NET runtime should use the correct subfolder to get the native library. Is the dylib file the same for M1 as for regular Macs, or do they have a specific M1 (it's ARM isn't it?) file?

@pasih
Copy link

pasih commented May 11, 2022

I installed it from brew but I presume it's different (ARM). What I tried was copying the .dylib files (libwkhtmltox.0.12.6.dylib libwkhtmltox.0.12.dylib, libwkhtmltox.0.dylib and libwkhtmltox.dylib - most of them are just symlinks though) from /usr/local/lib to my ~/.nuget/packages/haukcode.wkhtmltopdfdotnet/1.5.72/runtimes/osx-arm64/native/ folder. Once the dotnet project loads, those are copied to bin/Debug/net6.0/runtimes/osx-arm64/native/.

I think these locations are correct but I haven't really had to deal with loading libraries in nuget packages so I could be mistaken.

@HakanL
Copy link
Owner

HakanL commented May 16, 2022

I have added Linux ARM64 support now, but from what I can find on the WkHtmlToPdf parent page, it doesn't seem like they have builds for OSX ARM64 (M1) to run this wrapper in .NET for ARM64. It works in Docker on the M1 using ARM64 since I've just added the native library for that. And I can run it directly on the Mac but in X64 mode (emulated). It is my understanding that we need native ARM64 OSX package of wkhtmltopdf (parent project) to fully/natively support this.

@BrianHawley
Copy link

See also wkhtmltopdf/packaging#98

@TimZander
Copy link

TimZander commented May 10, 2023

I'm running into issues getting this working on M2 processor. Is there a resolution to this issue?

Edited to say: I have been able to install wkhtmltopdf with brew running natively. And been able to call the binary natively in terminal. I will be deploying to AppService with a Windows host, so no forseen issue there, but I would love to be able to develop against this on my mac. Can I point the package to the installed binary and have it use that when doing my development?

@TimZander
Copy link

Unfortunately it appears that the binary installed with brew is x86_64, not arm 64 native.

% file /usr/local/bin/wkhtmltopdf
/usr/local/bin/wkhtmltopdf: Mach-O 64-bit executable x86_64

@HakanL
Copy link
Owner

HakanL commented May 10, 2023

I see, so it's using emulation. But then that should work under the .NET project as well, maybe it's just not probing the correct location?

@TimZander
Copy link

Thanks, I'll look into placing it in a different location.

@HakanL HakanL closed this as completed Jul 17, 2024
@TimZander
Copy link

I never got this working @HakanL
Were you able to?

@HakanL
Copy link
Owner

HakanL commented Jul 17, 2024

@TimZander I assume it's an issue with the native library not having native support for the M1. I don't think there's much we can do, short of building the wkthmltopdf binaries for the platform. When loading the native library from .NET there aren't a lot of controls, we're basically just saying we need this DLL: https://github.com/HakanL/WkHtmlToPdf-DotNet/blob/master/src/WkHtmlToPdf-DotNet/WkHtmlModule.cs#L83
Perhaps the .NET loader detects that it's Arm64 and looks for that type of binary. I remember looking at SqLite when I forked this project to see how they embed the native binaries, maybe you can get some ideas from there and see if they have a solution/workaround.
I closed the issue because I think it's an issue outside the project, but feel free to re-open if you find any more. I'm happy to accept a fix/PR, I just don't know if it's anything in this project that can be fixed.

@HakanL
Copy link
Owner

HakanL commented Jul 17, 2024

@TimZander I played with this a little more on my M1. I was doing my tests with .NET8, but I think the same will apply to 6 and 7 (any that supports ARM64). If I install the .NET SDK 8 for x64 and run it via that version of dotnet then it runs fine (/usr/local/share/dotnet/x64/dotnet run). If I run it via the ARM64 dotnet (on the path) then it can't find the native library (because one doesn't exist). If I publish the TestConsoleApp targeting osx-x64 then it works fine, osx-arm64 doesn't. I don't think there's really anything wrong here, as much as I'd love for a native arm64 build to be available of the wkthmltox native library, until one is available we won't be able to run this natively in the arm64 space. If the caller (.net) is arm64 then I doubt there is a way for it to load a x64 native library via Rosetta, maybe there is a way, this is outside my knowledge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants