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.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

More Pre-Built Linux Libraries

mattleibow opened this issue · comments

Right now there is a pre-built library for Linux x64 that goes with each release. I want to add more to make life easier.

Leave comments and other feedback so that I can add other distros and architectures. Also for feedback is the platforms that a binary can be re-used. (For example, the Ubuntu 14.04 binary can also work on CentOS 7)

This doc has the list for .NET Core:
https://docs.microsoft.com/en-us/dotnet/core/linux-prerequisites?tabs=netcore2x
This is the platforms supported by mono:
https://www.mono-project.com/download/stable/#download-lin

Current Support

  • Musl-based using Alpine 3.7 (x64) (#1339)
  • Debian-based using Ubuntu 16.04 (x64)
  • Debian-based using Ubuntu 16.04 (ARM) (#1382)
  • Debian-based using Ubuntu 16.04 (ARM64) (#1382)

Proposed Support

  • Debian (x86)

Dropped

  • Raspberry Pi (ARM) (steps)
    Not actually because we have the PR #1382 that automatically supports it.
  • CentOS (x64)
    Not really because this should work with the Debian binaries.
  • RHEL 6/7 (x64)
    Not really because this should work with the Debian binaries.

VS bug #733081

commented

Ahhhh. a tip although not related to this topic (but it takes a little of my time to settle things done, so this is just for those who are not familiar with linux OS like me):
yum install libfontconfig1-dev will do nothing because there is no such entry. (as mentioned in https://github.com/mono/SkiaSharp/wiki/Building-on-Linux by @mattleibow )
apt-get is only for ubuntu while yum is for redhat (CentOS)
so on RH please do:
yum install fontconfig instead
and for OpenGL lib:
yum install libGL (note: I'm not sure whether this one is corresponding to libglu1-mesa-dev or not)

so steps to install libSkiaSharp for your CentOS:
1, copy the published .so file by @mattleibow to your NetCore container folder on your OS https://github.com/mono/SkiaSharp/releases/tag/v1.59.3
2, ldd libSkiaSharp.so to inspect dependencies (normally it will only show libfontconfig.so.1 not found)
3, yum install fontconfig
4, yum install libGL (emmm, have to be confirmed)

Actually i found that the lib works well after only setp 3 is done. (maybe I do not use some of OpenGL features?)

done, what a good day.

@jcyuan OpenGL is not required, but will be used if you are using the GPU surfaces. It is also loaded at runtime, and thus not needed at compile-time.

@jcyuan Could the package name for fontconfig may differ across distros?

commented

@mattleibow I don't know, actually once installed, I found the lib you mentioned 'libfontconfig.so.1' is located in /usr/lib64/ path, and actually the 'libSkiaSharp.so' uses it correctly as the ldd command shows libSkiaSharp.so refers to this path.
so I think that is only a different package name used between apt-get and yum?

To make life easier for everyone, I moved code around and added a new target to the GN files. Now, the native libSkiaSharp build is done with GN and ninja directly: https://github.com/mono/SkiaSharp/wiki/Building-on-Linux

Just FYI, I just used SkiaSharp.NativeAssets.Linux version 1.68.0-preview28 from nuget on ArchLinux and basic drawing works! I haven't done extensive testing, but the library does initialize and I can draw on a canvas and export the SKImage to a PNG.

That is great news!

Quoting from https://github.com/mono/SkiaSharp/releases/tag/v1.68.0:

More builds can be requested by leaving a comment on #453.

I'm wondering, what if I want to use SkiaSharp.Views.Forms in Linux? Do I need a Linux flavour of this nuget (https://www.nuget.org/packages/SkiaSharp.Views.Forms) or is it enough to have the SkiaSharp.NativeAssets.Linux dll in the same folder of the app?

Thanks

The SkiaSharp.Views.Forms NuGet is the managed views for Xamarin.Forms, and SkiaSharp.NativeAssets.Linux is the native engine. The reason that you may not have the GTK# working is that we don't yet support that. See #379

+1 for an Alpine NuGet build/ package please...!

Another link for the Raspberry PI enthusiasts. I have an ARM built here:

https://github.com/nicolasr75/libSkiaSharpArm

I will try to update it as soon as possible to 1.68.0.
It has been tested with .NET Core 2.1 and Avalonia UI.
Would be great of course if it would be available in this repo.

+1 for a Raspberry Pi build

@nicolasr75 looking forward to seeing your 1.68.0 ARM build - I'm really struggling to get it built myself. How did you go about building it?

@LordBenjamin check this issue #633 where I detailed most of the steps for 1.60.3

Debian - the nuget package does not restore any *.so files yet but the download version from https://github.com/mono/SkiaSharp/releases will work.

It should work with Debian. Is this a. NET Core app or a net45 desktop app?

By @LordBenjamin in #633 (comment)

Adding a step-by-step summary since it's taken me quite a while to work through this:

# check out skia and depot_tools as per https://github.com/mono/SkiaSharp/wiki/Building-on-Linux
git clone git clone https://github.com/mono/skia.git -b v1.68.0-preview28
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git

# check out RPI compilers as per https://github.com/mono/SkiaSharp/issues/633#issuecomment-420025558 and add to path
git clone https://github.com/raspberrypi/tools.git
export PATH="$PATH:<path-to-rpi-checkout>/tools/arm-bcm2708/arm-linux-gnueabihf/bin"

# installed libfontconfig on my RPI and then copied
# fcfreetype.h,  fcprivate.h and  fontconfig.h
# to
# <path-to-rpi-checkout>/tools/arm-bcm2708/arm-linux-gnueabihf/arm-linux-gnueabihf/include/fontconfig

# copied
# libfontconfig.a  libfontconfig.so  libfontconfig.so.1  libfontconfig.so.1.8.0
# to
# <path-to-rpi-checkout>/tools/arm-bcm2708/arm-linux-gnueabihf/arm-linux-gnueabihf/lib

# would it be possible to avoid the copy steps by installing libfontconfig:armhf directly on the build machine? I tried but couldn't get it to install

# change to skia directory - all work done here from now on
cd skia

# run git-sync-deps script (as per normal instructions)
python tools/git-sync-deps

# modified command line to use ARM cross-compilers from the RPI tools
./bin/gn gen 'out/linux/x64' --args='
    cc = "arm-linux-gnueabihf-gcc"
    cxx = "arm-linux-gnueabihf-g++"
    is_official_build=true skia_enable_tools=false
    target_os="linux" target_cpu="arm"
    skia_use_icu=false skia_use_sfntly=false skia_use_piex=true
    skia_use_system_expat=false skia_use_system_freetype2=false skia_use_system_libjpeg_turbo=false skia_use_system_libpng=false skia_use_system_libwebp=false skia_use_system_zlib=false
    skia_enable_gpu=true
    extra_cflags=[ "-DSKIA_C_DLL" ]
    linux_soname_version="68.0.0"'

# compile
../depot_tools/ninja 'SkiaSharp' -C 'out/linux/x64'

Need to figure out how to get the ARM libfontconfig files onto the build machine without having to copy them from a Raspian installation on a Pi.

I did try sudo apt-get install libfontconfig:armhf, but I couldn't get that to work under Ubuntu 18.04.1 LTS (missing package repos).

Here's the binary that I built earlier in case it's useful to anyone.

libSkiaSharp_1.68.0_armhf.zip

Edit: Replaced the 1.68.0-preview28 build with a new .so built from the stable tag that @mattleibow created.

@LordBenjamin where does the image (or whatever they use to set up the hardware) live? It might be possible to download some image or zip with the OS and copy out the files we need...

@LordBenjamin just an FYI, I noticed you were using the preview tag of skia - I forgot to push the tag of the stable release at the time so you should be good to go with v1.68.0 now.

Various images available for download at https://www.raspberrypi.org/downloads/raspbian/. I don't remember if libfontconfig is installed by default. The image is pretty large as well (4GB+).

My (naive) preference is to download libfontconfig directly from the Raspian package feed. It's a Debian based OS, so there are presumably tools that can retrieve and extract the package. We can then copy the files into the right place in the tools folder.

@mattleibow I've edited my comment on #633 to include missing steps that I noticed when rebuilding from the stable branch. Can you copy into your comment above (#453 (comment)) please?

@LordBenjamin the package feed is probably the correct thing to do... downloading the entire OS is probably something only an idiot would say ;)

Is there any danger distributing an optimized Clang Linux build instead of GCC based? Rebuilding from scratch using wiki instructions with Clang (--args='cc="clang" cxx="clang++" extra_cflags=[ "-DSKIA_C_DLL", "-O3"]') yields up to 10x performance improvement vs SkiaSharp.NativeAssets.Linux packages on some code paths

I will look into this. I saw the comment on skia-discuss and it looks to be getting a higher priority by the day.

+1 for Alpine support.

I took the instructions @LordBenjamin provided, and made a dirty but working script in this repo: https://github.com/EraYaN/EraYaN.SkiaSharp.NativeAssets.LinuxArm

It's not published yet since it might move or turn out to be badly made, but it might be nice inspiration for anyone looking to build an arm32 binary.

Theoretically replacing the raspbian tools for an arm64 one would let you build one for arm64 as well. Just remember to download the correct debs.

EDIT: Well skia seems to be broken on aarch64 due to a gcc issue. So clang in the only option for now. "Work around"

Yeah. I really need to switch to clang for Linux. I have a issue for that #686 but haven't the opportunity yet. It should be mostly easy as we are just using the gn tools and nothing special.

@sergeystoma I am looking to switch to clang in #767 :)

@LordBenjamin have you tried clang with arm/rasbian?

@mattleibow I had quite a few attempts with clang and didn't manage to build successfully. However, I was probably holding it wrong! I'll give it another go now that I've got a working process to compare against.

Sweet!

If anyone knows of any good builds/release out there, let me know and I'll link to it at the top. Or maybe a community wiki where if you have some build for some device/architecture you can send a PR. And again, votes so I can take it to PMs to talk priorities.

Having difficulties running latest native compiled file (1.68.0) on CentOS 7 under net471.

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.TypeInitializationException: The type initializer for 'SkiaSharp.SKImageInfo' threw an exception. ---> System.DllNotFoundException: libSkiaSharp at (wrapper managed-to-native) SkiaSharp.SkiaApi.sk_colortype_get_default_8888() at SkiaSharp.SKImageInfo..cctor () [0x00000] in <a0087d635ef94b8aaf6fe37af2df4f8d>:0 --- End of inner exception stack trace ---

ldd output
./libSkiaSharp.so: /lib64/libstdc++.so.6: version CXXABI_1.3.8 not found (required by ./libSkiaSharp.so) ./libSkiaSharp.so: /lib64/libstdc++.so.6: version GLIBCXX_3.4.21 not found (required by ./libSkiaSharp.so)

Last known "official" native build that appears to be working was 1.60.3.
Sorry if I had misunderstood supported platforms by this build.

Thanks for reporting. No, you are correct, it is a bug. It was also reported that Debian 9 was not working. SkiaSharp required a compiler/tooling bump so I bumped the Ubuntu from 14 to 16. It appears that we have quite a few older machines still in the wild.

I am hoping #767 will fix not only the issues on older distros, but also give a massive performance increase.

+1 for alpine3.8

+1 for alpine3.8

  • for alpine 3.8 and 3.9

+1 for alpine

+1 for alpine

+1 for alpine

+1 alpine =)

I built the library for Alpine 3.9: https://www.nuget.org/packages/Goelze.SkiaSharp.NativeAssets.AlpineLinux
The repository is here, and can theoretically be modified to build for different versions of Alpine.

I tried adding it to a ASP.NET Core 2.1 project to no avail it doesn't get copied to the output folder.

commented

@claunia yes the dotnet only copies the CLR dll to your publish folder, it won't copy the .so file, you have to manually copy it to your linux (etc OS), and do ldd command to inspect to see if some related .so missing in your OS, refer to: #453 (comment)

it doesn't get copied to the output folder.

That issue is filed at #794, where I mention the workaround I used.

@gman4455 sweet! Thanks!

I am thinking of moving most of the build logic for Linux out of the normal cake build and just using docker everywhere. This way, we can add a new Linux platform simply by adding a new Dockerfile.

With Linux, the CLI should copy the native files when you do a publish. If you do a build, then it only copies the outputs from your solution.

hi, i dowloaded the from libSkiaSharp.so https://jenkins.mono-project.com/view/Components/job/Components-SkiaSharp-Linux/79/Azure/processDownloadRequest/ArtifactsFor-79/3c31bd5c5701a6eb3651110b4708bb1d0492c7fc/output/native/linux/x64/libSkiaSharp.so.

My project is a net core 2.1 project, I include the library into my project with property "copy always" and also in my startup.cs, i put context.LoadUnmanagedLibrary(Path.Combine(Directory.GetCurrentDirectory(), "libSkiaSharp.so")) and i got error:

Unable to allocate pixels for the bitmap., at SkiaSharp.SKBitmap..ctor(SKImageInfo info, Int32 rowBytes) at SkiaSharp.SKBitmap..ctor(SKImageInfo info) at SkiaSharp.SKBitmap.Decode(SKCodec codec, SKImageInfo bitmapInfo) at SkiaSharp.SKBitmap.Decode(SKCodec codec) at SkiaSharp.SKBitmap.Decode(Stream stream)

My deploy machine is an amazon with OS CentOS Linux 7 (Core). I installed libgdiplus and also i install mono-complete.

I appreciate your help if i need install someting else. I dont know what else i need to install.

+1 for RHEL 6/7 (x64).

+1 for RHEL 6/7 (x64).

+1 for RHEL 6/7 (x64).

+1 for Raspberry Pi

+1 for Raspberry Pi

commented

+1 for RHEL 6/7 (x64).

Would massively appreciate an x86 / 32-bit version for Debian 10 on i386. I have tried to build it myself but I think the first problem I encountered was that the version of 'gn' included in the checkout was a 64-bit binary, which therefore failed to run.

I thought about changing the current Linux build to statically link the musl libc implementation. That way we should be able to support most distros without having a special build for each. Not sure how hard this would be to achieve. Ideally we include every dependency.

https://www.nuget.org/packages/Goelze.SkiaSharp.NativeAssets.AlpineLinux/ does not work with the latest version of SkiaSharp. Can AlpineLinux native assets become "official" and be published with each new version of SkiaSharp, like SkiaSharp.NativeAssets.Linux?

We could have a look at that now. I recently changed things so that the Linux native bits actually all build on Docker.

I hope I did it right to get alternate distros super easy. It should just be a docker file link this
https://github.com/mono/SkiaSharp/blob/master/scripts/Docker/ubuntu16/amd64/Dockerfile

And then add a chunk to the yaml
https://github.com/mono/SkiaSharp/blob/master/scripts/azure-pipelines.yml#L204

That should be all that is required. If not, then I didn't do so well and we need to fix that.

What actually runs is a docker build and then a docker run with a volume to the source
https://github.com/mono/SkiaSharp/blob/master/scripts/azure-templates-bootstrapper.yml#L125

Maybe have a go and see what happens.

We could add a linux-musl-x64 runtime that way nothing gets in conflict with the regular builds.

Oh, yeah. I'd like to add the core platforms that .NET Core supports to the main NuGet. Right now I just have linux-x64, so we can totally add things link Apline/musl. I just haven't gotten around to actually creating the Dockerfiles. But, I do see we have some links in this thread so far.

For ARM it's a bit in flux right now, my old attempt https://github.com/EraYaN/EraYaN.SkiaSharp.NativeAssets.LinuxArm still works (and we use/ship it successfully for some time now with Jellyfin) but docker is doing some funky stuff right now to make it easier, although it has not fully landed yet (ie. you need qemu to do a lot of things or just plain cross compile and then create a new docker image with the result.)

+1 for Ubuntu arm64 (Nvidia Jetson Nano)

+1 for Alpine

Hi,
+1 for Alpine

Does it work on the latest official Ubuntu 20.04 based container images available at:
https://hub.docker.com/_/microsoft-dotnet-core-sdk/
?

Thx.

Hi,
+1 for Alpine, please.

For those interested I got the library working on Alpine by installing:
Goelze.SkiaSharp.NativeAssets.AlpineLinux v1.68.0.1
SkiaSharp v1.68.0

And included this line in my docker file:
RUN apk --no-cache add fontconfig
(remember: you need the fontconfig to be in the deployed image, so it matters where you place it in the docker file)

Thanks,

+1 for Alpine.

Hi folks. I know that Alpine is a high priority, so working on that. Thanks to the community for stepping in. Right now I am just finishing up the previews for Web Assembly!

@JMan7777 it should work with the SkiaSharp.NativeAssets.Linux package on most Debian-based - including most Ubuntu versions.

FOLKS!!! After much delay and +1's, Alpine is now in the box!!! Just merged a Alpine x64 archive into master and will go out as a preview as soon as CI finishes up!

Right now, I am building using Alpine 3.9 but it runs all the way back to Alpine 3.7 (at least).

There are 2 builds, the default which requires the usual fontconfig install: apk add --no-cache fontconfig. And, the is the "no dependencies" build which drops some advanced font features but does not need any additional packages.

I just went for x64 right now, but if there are other architectures or platforms, keep up with the +1 for <OS> <Arch> and I'll try make sure to get it in.

You can also have a look t #1339 and see just how to submit a PR to add any Linux platform that is needed. Then you don't have to worry about maintaining it - because I'll have to 😉

Adding armv7a hf and arm64/aarch64 in #1382

Almost ready to close this now... Does anyone still use x86 Linux anymore? Is that still a thing?

What additional Linux variants do we actually need? Most things just work fine with the old Debian binaries.

:mips-interest

Hi @mattleibow

There is building libSkiaSharp.so document, but no libHarfBuzzSharp.so, how to build libHarfBuzzSharp.so?

Thanks,
Leslie Zhai

@xiangzhai you should be able to also build harfbuzz by swapping out the gn target from SkiaSharp to Harfbuzz.

Another way to build is you don't mind installing mono is to just use cake and run with the bootstrapper. The you can just execute the externals-linux cake task.

Hi @mattleibow

Thanks for your teaching!

Leslie Zhai

+1 for linux-musl-arm64

Thanks for all the votes folks!

I'm going to finally close this issue since we got most of the linux distros that are supported. If one is specifically needed, then feel free to open an issue for that one.

However, if you have a special linux that you need SkiaSharp for, you can probably modify one of the Docker files that we use for your distro: https://github.com/mono/SkiaSharp/tree/main/scripts/Docker

I am trying to deploy an app using the SkiaSharp libraries to AKS and I get this error:

System.AggregateException: One or more errors occurred. (The type initializer for 'SkiaSharp.SKData' threw an exception.) (The type initializer for 'SkiaSharp.SKData' threw an exception.)
---> System.TypeInitializationException: The type initializer for 'SkiaSharp.SKData' 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_data_new_empty()
at SkiaSharp.SKData..cctor()
--- End of inner exception stack trace ---
at SkiaSharp.SKData.Create(IntPtr address, Int32 length)
at SkiaSharp.SKBitmap.Decode(ReadOnlySpan1 buffer) at SkiaSharp.SKBitmap.Decode(Byte[] buffer) at System.Threading.Tasks.TaskReplicator.Replica.Execute() at AssetExtractor.PowerpointImageExtractor.<>c__DisplayClass12_0.<ConvertImages>b__0(ImageSize size) in /home/vsts/work/1/s/src/backend/AssetExtractor/ImageExtractor.cs:line 141 at System.Threading.Tasks.Parallel.<>c__DisplayClass33_02.b__0(Int32 i)
at System.Threading.Tasks.Parallel.<>c__DisplayClass19_0`1.b__1(RangeWorker& currentWorker, Int32 timeout, Boolean& replicationDelegateYieldedBeforeCompletion)
--- End of stack trace from previous location ---

But if I deploy the very same code to a Linux (Ubuntu) Azure app service, it works without any issues

This is the base Docker image getting deployed to AKS

mcr.microsoft.com/dotnet/aspnet:6.0

I am converting images from a other formats to .webp format

image

Any ideas

Thanks