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.4k stars 535 forks source link

[BUG] Unable to load shared library 'libSkiaSharp' or one of its dependencies in AWS Linux #964

Closed KevinDJones closed 4 years ago

KevinDJones commented 4 years ago

Description

I built out a .NET Core 2.1 API that uses SkiaSharp. Works great on Windows & Mac. Deployed to AWS Amazon Linux 2 (Amazon's custom version of CentOS). When I hit the endpoint, I get:

Unable to load shared library 'libSkiaSharp' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: liblibSkiaSharp: cannot open shared object file: No such file or directory

I've already added SkiaSharp.NativeAssets.Linux to my project. I tried putting libSkiaSharp.so in my bin folder to no avail.

I took the error's advice and enabled LD_DEBUG and found the following:

7332:     find library=libSkiaSharp [0]; searching
7332:      search cache=/etc/ld.so.cache
7332:      search path=/lib64/tls:/lib64:/usr/lib64/tls:/usr/lib64(system search path)
7332:trying file=/lib64/tls/libSkiaSharp
7332:trying file=/lib64/libSkiaSharp
7332:trying file=/usr/lib64/tls/libSkiaSharp
7332:trying file=/usr/lib64/libSkiaSharp

So I copied libSkiaSharp.so to /usr/lib64 and then it started working! But this isn't ideal in my production environment, and I'd much rather it just look locally as opposed to deep in the system. Is there somewhere else I can put it without needing to access the AWS machine it's running on?

f2calv commented 4 years ago

I have a similar issue with a .NET Core 3.0 deployment, it was working fine during preview releases of .NET Core 3 up-to preview 9, then seemingly when .NET Core 3.0 final was released it then failed with the same error as you.

Adding the following to my Dockerfile fixed the issue;

I guess the underlying image and its dependencies must have changed (regardless of having SkiaSharp.NativeAssets.Linux installed), so maybe this tweak will help...

mattleibow commented 4 years ago

If you aren't doing things with text, or if you are brining your own fonts, you could try https://www.nuget.org/packages/SkiaSharp.NativeAssets.Linux.NoDependencies

This NuGet is the same as SkiaSharp.NativeAssets.Linux, but does not have the fontconfig dependency. The downside is that it doesn't have the same support of features - mostly font finding. But it can still draw text.

eoware commented 4 years ago

I built a lambda layer based on the instructions from this page, using my lambda project instead of the one in the post: https://www.leadtools.com/help/sdk/v20/tutorials/documents/cross-platform/dotnet-core/convert-documents-using-aws-lambda.html This makes it so my lambda actually runs without exception -- no more "Unable to load shared library 'libSkiaSharp' or one of its dependencies", but the output is what I am guessing is a default, just a small white square, not the output I get when I run the function locally in debug mode. My project basically just does some DrawText calls to a canvas.

For reference, the libraries the script adds for the layer are: libbz2.so.1 libc.so.6 libdl.so.2 libexpat.so.1 libfontconfig.so.1 libfreetype.so.6 libm.so.6 libpng15.so.15 libpthread.so.0 libuuid.so.1 libz.so.1

matt-moody commented 4 years ago

I have a similar issue with a .NET Core 3.0 deployment, it was working fine during preview releases of .NET Core 3 up-to preview 9, then seemingly when .NET Core 3.0 final was released it then failed with the same error as you.

Adding the following to my Dockerfile fixed the issue;

  • RUN apt-get update && apt-get install -y libfontconfig1

I guess the underlying image and its dependencies must have changed (regardless of having SkiaSharp.NativeAssets.Linux installed), so maybe this tweak will help...

@f2calv your solution worked for me! Thank you for posting this! I am running .net core 3.1 and was running into the OP above listed error during my cloud deployments to google app engine. During local development on my mac, I had zero issues so you can imagine I was quite perplexed by google app engine giving me grief over this. I tried every variation of the SkiaSharp, SkiaSharp.NativeAssets.Linux, SkaiSharp.NativeAssets.Linux.NoDependencies and every single one failed when deployed to the cloud (all worked while developing on my local machine). Once I flipped over to using a custom docker file and added the libfontconfig1 package, my cloud deployed code worked as expected.

Here's how I solved this

For those who come after me, here is a snippet of nuget packages in my .csproj:

      <PackageReference Include="SkiaSharp" Version="2.80.1" />
      <PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.80.1" />

and a snippet of my Dockerfile:

# Build runtime image
FROM gcr.io/google-appengine/aspnetcore:3.1
RUN apt-get update && apt-get install -y libfontconfig1
mattleibow commented 4 years ago

@matt-moody apologies for the grief. I noticed there was a bug in the 2.80.1 package where the NoDependencies binaries still required fontconfig. This was fixed in 2.80.2 and release last week.

However, your solution to install fontconfig and use SkiaSharp.NativeAssets.Linux instead is the best option as you get access to all the font lookup and such.

mattleibow commented 4 years ago

I'll close this as it appears to be related to #1341 and fixed in https://github.com/mono/SkiaSharp/pull/1416

matt-moody commented 4 years ago

@mattleibow - Just an FYI version 2.80.2 fixed my missing assembly issue when I installed SkaiSharp.NativeAssets.Linux.NoDependencies and removed my apt-get step in my docker file. Thanks for the quick follow up.

eoware commented 4 years ago

What isn't usable in the library with SkiaSharp.NativeAssets.Linux.NoDependencies used and fontconfig not available? Can you still draw text? Are there any fonts or a default font still guaranteed to be available across platforms?

mattleibow commented 3 years ago

The NoDependencies version can't search for fonts based on characters or other fonts. Basically, you have to manually load fonts - either by family name or file. Other than that, it should be able to do most things.

thylux commented 3 years ago

Been struggling for 2 days with this because I need fonts in a AWS Lambda, so I can't use SkiaSharp.NativeAssets.Linux.NoDependencies and didn't have how to install libfontconfig1.

AWS recently launched Lambda with docker and so we now have how to install the dependencies we need.

What you need in aws-lambda-tools-defaults.json is to:

Create a dockerfile (and adapt for the fw version you use):

FROM public.ecr.aws/lambda/dotnet:core3.1

WORKDIR /var/task

# This COPY command copies the .NET Lambda project's build artifacts from the host machine into the image.
# The source of the COPY should match where the .NET Lambda project publishes its build artifacts. If the Lambda function is being built
# with the AWS .NET Lambda Tooling, the `--docker-host-build-output-dir` switch controls where the .NET Lambda project
# will be built. The .NET Lambda project templates default to having `--docker-host-build-output-dir`
# set in the aws-lambda-tools-defaults.json file to "bin/Release/net5.0/linux-x64/publish".
#
# Alternatively Docker multi-stage build could be used to build the .NET Lambda project inside the image.
# For more information on this approach checkout the project's README.md file.
COPY "bin/Release/netcore3.1/linux-x64/publish"  .

# Install these if you need access to System.Drawing
# https://aws.amazon.com/blogs/developer/net-5-aws-lambda-support-with-container-images/
#RUN yum install -y amazon-linux-extras
#RUN amazon-linux-extras install epel -y
#RUN yum install -y libgdiplus

RUN yum install -y fontconfig freetype freetype-devel fontconfig-devel libstdc++

If you are using a serverless.template update to something like in the image below:

image