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

Linux : System.DllNotFoundException: Unable to load DLL 'libSkiaSharp' #517

Closed
Jonesie opened this issue May 11, 2018 · 35 comments
Closed

Comments

@Jonesie
Copy link

Jonesie commented May 11, 2018

Description

I have a .Net Core 2.0 web api running in a linux docker container locally.
Ive copied libSkiaSharp to the /app and /app/bin/.../Debug and Release folders just to be sure.
My dockerfile installs libfontconfig1.
Running ldd libSkiaSharp.so I see:

root@65c88e99a65f:/app# ldd libSkiaSharp.so
        linux-vdso.so.1 (0x00007ffcd954a000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f92d82fc000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f92d80f8000)
        libfontconfig.so.1 => /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 (0x00007f92d7eba000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f92d7bb6000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f92d799f000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f92d7600000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f92d8d90000)
        libfreetype.so.6 => /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007f92d7351000)
        libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f92d7127000)
        libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f92d6f0d000)
        libpng16.so.16 => /usr/lib/x86_64-linux-gnu/libpng16.so.16 (0x00007f92d6cda000)

When I call the first action that uses SkiaSharp, I get the dreaded error:

{System.TypeInitializationException: The type initializer for 'SkiaSharp.SKAbstractManagedWStream' threw an exception. ---> System.DllNotFoundException: Unable to load DLL 'libSkiaSharp': The specified module or one of its dependencies could not be found.
 (Exception from HRESULT: 0x8007007E)
   at SkiaSharp.SkiaApi.sk_managedwstream_set_delegates(IntPtr pWrite, IntPtr pFlush, IntPtr pBytesWritten, IntPtr pDestroy)
   at SkiaSharp.SKAbstractManagedWStream..cctor()
   --- End of inner exception stack trace ---
   at SkiaSharp.SKAbstractManagedWStream..ctor(Boolean owns)
   at SkiaSharp.SKManagedWStream..ctor(Stream managedStream)
...

Code

n/a

Expected Behavior

It should load the so file.

Actual Behavior

It either cant find the so file or it cant find one of it's dependencies.

Basic Information

  • Version with issue: 1.60.0
  • Last known good version: ?
  • IDE: Visual Studio
  • Platform Target Frameworks:
    • Linux: asp.netcore 2.08 docker image which I Debian Jessie - so it that like 16.10?
  • Target Devices:
    • Web app
@Jonesie
Copy link
Author

Jonesie commented May 11, 2018

As an aside, it would be cool if there was some better documentation or a sample app showing how to set this up. I've had to dig around the interwebs for a day to get this far. Running everything on windows is a dream. I mistakenly thought linux would be as easy. I should have known better.

Once I get this working I promise to blog it.

@mattleibow
Copy link
Contributor

The first thing to check is to make sure the libSkiaSharp.so lives next to the SkiaSharp.dll.
I have a socket sample here: https://github.com/mattleibow/SkiaSharp-Docker

If this doesn't help, could you share your Dockerfile?

@Jonesie
Copy link
Author

Jonesie commented May 11, 2018

So that's really curious. I cant see SkiaSharp.dll anywhere in the container or on my windows build. GAC?

@Jonesie
Copy link
Author

Jonesie commented May 11, 2018

Here's the docker file:

FROM microsoft/aspnetcore:2.0.8 AS base
RUN apt-get update;apt-get install libfontconfig1 -y

WORKDIR /app
EXPOSE 80

FROM microsoft/aspnetcore-build:2.0.5-2.1.4 AS build
WORKDIR /src

COPY . .
WORKDIR /src/Api
RUN dotnet restore 
RUN dotnet build -c Release -o /app

FROM build AS publish
RUN dotnet publish -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Api.dll"]

@Jonesie
Copy link
Author

Jonesie commented May 11, 2018

The API is a netcore2.0 build. It references a netstandard2.0 class lib:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <LangVersion>7.3</LangVersion>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="SkiaSharp" Version="1.60.0" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\Contracts.Services\Contracts.Services.csproj" />
    <ProjectReference Include="..\Models\Models.csproj" />
    <ProjectReference Include="..\Problems\Problems.csproj" />
  </ItemGroup>

</Project>

I added a package ref for SkiaSharp to the Api project also, just in case.

Neither of the projects has SkiaSharp.dll in the output folders.

@Jonesie
Copy link
Author

Jonesie commented May 11, 2018

In the container:
SkiaSharp.dll is in ~/.nuget/packages/skiasharp/1.60.0/lib/netstandard1.3
libSkiaSharp.so is in /app/bin/Release/netcoreapp2.0

@Jonesie
Copy link
Author

Jonesie commented May 11, 2018

Oh, I see your docker and build is quite different to the standard one Im using. I'll try that... after a beer or two. Cheers

@mattleibow
Copy link
Contributor

@Jonesie I created a new Web API, and it also fails for me - I have spent the last 3 hours trying to figure out why. I will update s soon as I figure out what is causing the file to not be found.

@mattleibow
Copy link
Contributor

Struggled enough, going to contact someone who knows ;)

@Jonesie
Copy link
Author

Jonesie commented May 12, 2018

I also created a new web api and published using -r linux-x64 and also had the prebuilt libskiasharp.so copied to the output. The app started ok but didnt respons to web requests:

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.Run(async (context) =>
            {
                using (var stream = new System.IO.MemoryStream())
                using (var skStream = new SkiaSharp.SKManagedWStream(stream))
                {
                    await context.Response.WriteAsync("Hello World!");
                }
            });
        }

So Im not sure if it found the so - maybe not. Doing it this way produces a Self Contained Deployment. I didnt need to update the csproj fle - it seems publish -r RID is enough to do the correct build.

My docker file is:

#FROM microsoft/aspnetcore:2.0 AS base
FROM microsoft/dotnet:2.0-runtime-deps as base
#FROM microsoft/aspnetcore-build:2.0 AS base
RUN apt-get update;apt-get install libfontconfig1 nano -y
WORKDIR /app
EXPOSE 80

FROM microsoft/aspnetcore-build:2.0 AS build
WORKDIR /src
COPY WebApplication1/WebApplication1.csproj WebApplication1/
RUN dotnet restore WebApplication1/WebApplication1.csproj
COPY . .
WORKDIR /src/WebApplication1
RUN dotnet build WebApplication1.csproj -c Release -o /app

FROM build AS publish
RUN dotnet publish WebApplication1.csproj -c Release -r linux-x64 -o /app/pub

FROM base AS final
WORKDIR /app
COPY --from=publish /app/pub .
ENTRYPOINT ["WebApplication1"]

Building the compose from VS seems to do something different. I dont get the SDD output, just the normal windows looking files. Weird, but probably something I did.

I then tried to make a similar change to my real app and all hell broke lose. Lots of nuget downgrade warnings. NU1605.

Sigh...

@mattleibow
Copy link
Contributor

All right, I think I discovered something. This is my current code - this is pretty mush the same as the same as the default template, but with SkiaSharp and libSkiaSharp.so added:
https://github.com/mattleibow/SkiaSharpWebApi-Docker

This thing I noticed was that it runs from the command line, see .\build.ps1. If you go to http://localhost:80/api/colortype after running it, it works fine.

Visual Studio does something else... Not sure what, I hope to talk to Docker/VS guys and find out.

@Jonesie
Copy link
Author

Jonesie commented May 13, 2018

I think I get it now, although I dont have anything working quite yet.
When I run the docker project in VS it creates it's own compose file and sets this thus:

docker-compose -f "C:\Dev\rc\docker-compose.yml" -f "C:\Dev\src\docker-compose.override.yml" -f "C:\Dev\src\obj\Docker\docker-compose.vs.debug.g.yml" -p dockercompose10230428442250841413 --no-ansi up -d --build --force-recreate --remove-orphans
1>

The main thing with this is that it sets the volume for /app to the source folder for the project:

volumes:
      - C:\Dev\src\Api:/app
      - C:\Users\peter\vsdbg\vs2017u5:/remote_debugger:ro
      - C:\Users\peter\.nuget\packages\:/root/.nuget/packages:ro
      - C:\Program Files\dotnet\sdk\NuGetFallbackFolder:/root/.nuget/fallbackpackages:ro

So when I bash into the container Im just seeing my own hdd and if I create the image using docker build then I see the correct (?) linux binaries.

This is hideous black magic crap that I thought Microsoft had learned not to do!

@Jonesie
Copy link
Author

Jonesie commented May 13, 2018

Oh and that compose file also has this:

build:
      target: base

Which I think should be 'final'

@Jonesie
Copy link
Author

Jonesie commented May 13, 2018

Yes! Fixed it. I copied the so file to C:\Users\peter\.nuget\packages\skiasharp\1.60.0\lib\netstandard1.3 and restarted the container from VS. Works fine. This sounds sort of obvious now I think about it...

I'll see if I can deploy to AWS ECS with my scripted image build.

@mattleibow
Copy link
Contributor

I suppose that is fine for debugging... What if you copy the .so to the working directory that is used by the VS compose? Does that work?

I think I must create a NuGet for each Linux platform (sharing what we can) so that you can just add that. I need to investigate moving all the native files out of the core package as it is getting quite huge now

@Jonesie
Copy link
Author

Jonesie commented May 14, 2018

Ive got everything working again now. I found some problems with my image build but I also managed to get a stand-alone build working nicely. I'm writing up a blog post now.

@Jonesie
Copy link
Author

Jonesie commented May 15, 2018

Ahhh.

NUGET_FALLBACK_PACKAGES=/root/.nuget/fallbackpackages

@Jonesie
Copy link
Author

Jonesie commented May 16, 2018

@mattleibow
Copy link
Contributor

Ah, that was a good read. Thanks for looking around and debunking the magic.
I will continue to pester my guy until this works out the box for the F5 fun.

@AlexandreLaborde
Copy link

Hello @mattleibow and @Jonesie,

I am trying to get the .NetCore sample to run on my Ubuntu 18.04 machine and I think I have the same issue.

Basically all I did was to download the samples from the latest release 1.60.1, open the solution in Monodevelop and run it, and I got the following error.

Unhandled Exception: System.TypeInitializationException: The type initializer for 'SkiaSharp.SKImageInfo' threw an exception. ---> System.DllNotFoundException: 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
at SkiaSharp.SkiaApi.sk_colortype_get_default_8888()
at SkiaSharp.SKImageInfo..cctor()
--- End of inner exception stack trace ---
at SkiaSharp.SKImageInfo..ctor(Int32 width, Int32 height)
at SkiaSharpSample.Program.Main(String[] args) in /home/alexandre/Downloads/samples/Basic/NetCore/SkiaSharpSample/Program.cs:line 13
bash: line 1: 22565 Aborted (core dumped) /usr/share/dotnet/dotnet "/home/alexandre/Downloads/samples/Basic/NetCore/SkiaSharpSample/bin/Debug/netcoreapp2.0/SkiaSharpSample.dll"

Press any key to continue...

I tried coping the libSkiaSharp.so file to where the SkiaSharpSample.dll was being created and I doesn't seem to make any difference. I have also tried to compile the libSkiaSharp.so myself using the new and legacy methods on the wiki but they have both failed.

@mattleibow I have read that the libSkiaSharp.so was built in Ubuntu 14.04, does that mean that it only works in 14.04?

Am I doing something wrong ? What I am supposed to do with the libSkiaSharp.so file?

Thanks in advance!

@AlexandreLaborde
Copy link

AlexandreLaborde commented Jun 11, 2018

Hey I have found out the issue after some inspiration from @Jonesie blog post.
In order to compile the .NetCore apps you need to add the libSkiaSharp.so file in
/usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.0/

To run the GTK example just put the file in /home/alexandre/Downloads/samples/Basic/Gtk/SkiaSharpSample/bin/Debug/

@rjcobain
Copy link

I had this issue when running in one of the dotnet runtime docker images. By enabling LD_DEBUG=all env variable, I found out that it was due to missing dependencies of libSkia. I needed to add the following two packages, libfreetype6 libfontconfig1

@kieronlanning
Copy link

Has anyone found a foolproof way of using SkiaSharp in a .NET Core 2.1 Linux image (ideally alpine, for size)?

No-matter what I try, I always endup with System.DllNotFoundException: Unable to load DLL 'libSkiaSharp' error.

@Jonesie
Copy link
Author

Jonesie commented Oct 6, 2018

Has anyone found a foolproof way of using SkiaSharp in a .NET Core 2.1 Linux image (ideally alpine, for size)?

No-matter what I try, I always endup with System.DllNotFoundException: Unable to load DLL 'libSkiaSharp' error.

http://jonesie.kiwi/2018/05/16/skiasharp-on-a-linux-container/

@kieronlanning
Copy link

kieronlanning commented Oct 6, 2018

Thanks @Jonesie. Confirmed that worked for non-alpine versions. Here's what mine looks like:

# Define images.
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
FROM microsoft/dotnet:2.1-sdk AS build

# Copy the output from the source machine.
FROM build as dotnetcore-build
WORKDIR /src
COPY . .

# Build the solution
RUN dotnet build -v quiet -c Release --configfile ./NuGet.config ./SkiaLibTest.sln

# Publish the project
RUN dotnet publish -v quiet -c Release -o /app ./SkiaLibTest/SkiaLibTest.csproj

WORKDIR /app

RUN wget -q https://github.com/mono/SkiaSharp/releases/download/v1.60.3/libSkiaSharp.so

RUN chmod -x libSkiaSharp.so

# Set the content to the published results.
FROM base AS final

# Set working directory as /app and copy build content in.
WORKDIR /app

COPY --from=dotnetcore-build /app .

RUN apt-get update; apt-get install libfontconfig1 -y

ENV ASPNETCORE_URLS=http://+:80

EXPOSE 80

ENTRYPOINT ["dotnet", "SkiaLibTest.dll"]

If I get one that works for Alpine, I'll post that too.

@mattleibow
Copy link
Contributor

Alpine may not work as it is a very different Linux to what is used to compile libSkiaSharp. You may have to compile your own.

I believe it has to do with the fact that Debian uses glibc and Alpine uses something else. AFK ATM, but I think it's that.

@kieronlanning
Copy link

Thanks for the info @mattleibow.

@mattleibow
Copy link
Contributor

Closing this issue as it mostly has been resolved. New NuGet packages will be released to avoid all this work.

To support Alpine, please add your vote/comment here so we can prioritize: #453

@JackyLoo
Copy link

JackyLoo commented Dec 8, 2018

Has anyone found a foolproof way of using SkiaSharp in a .NET Core 2.1 Linux image (ideally alpine, for size)?
No-matter what I try, I always endup with System.DllNotFoundException: Unable to load DLL 'libSkiaSharp' error.

http://jonesie.kiwi/2018/05/16/skiasharp-on-a-linux-container/

It shows "Service Unavailable" when I hit the link, would you mind sharing your solution again, please?

@Jonesie
Copy link
Author

Jonesie commented Dec 8, 2018

Has anyone found a foolproof way of using SkiaSharp in a .NET Core 2.1 Linux image (ideally alpine, for size)?
No-matter what I try, I always endup with System.DllNotFoundException: Unable to load DLL 'libSkiaSharp' error.

http://jonesie.kiwi/2018/05/16/skiasharp-on-a-linux-container/

It shows "Service Unavailable" when I hit the link, would you mind sharing your solution again, please?

Dang. VM died. It's back now.

@mattleibow
Copy link
Contributor

@JackyLoo, since the v1.68 release, you no longer need to do all this work. Just install the SkiaSharp.NativeAssets.Linux package - #312

@automagisk
Copy link

automagisk commented Dec 14, 2018

Hi, I'm using SkiaSharp on a Synology NAS running Linux. I have had SkiaSharp working just fine but since I upgraded to .NET Core 2.2 and SkiaSharp 1.68 I have had this issue with DllNotFound. Have tried adding the NativeAssets-package but still get the same error. Have posted a question on Stack Overflow here. Don't know what to try really. Any suggestions?
I have also tried adding the so-file manually with wget and chmod as suggested above.

@mattleibow
Copy link
Contributor

@automagisk what linux are you running?

Also, is it possible to make sure SkiaSharp 1.60.3 works on your upgraded 2.2 or SkiaSharp 1.68.0 runs on the older 2.1. Just need to confirm which one broke which.

Note, we upgraded or build bot to Ubuntu 16.04 for new GCC. It was working on the Ubuntu 14.01, but maybe there is another issue.

@automagisk
Copy link

automagisk commented Dec 14, 2018

Synology DSM uses a custom Linux version it seems. Just tried reverting to 1.60.3 and got the same error so it looks like it's Core 2.2. Update: Looks to be something else that's wrong. I have reverted to Core 2.0 and 1.60.0 and it still doesn't work. Mmmm weird. I have to keep trying and reverting until it works.

@mattleibow
Copy link
Contributor

OK, :(
I think it might be better to open a new issue with details specific to your case. This way we can track the issue and prioritize.

@ghost ghost locked as resolved and limited conversation to collaborators Aug 19, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants