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 support #90

Closed
tmds opened this issue Jun 16, 2016 · 70 comments
Closed

Linux support #90

tmds opened this issue Jun 16, 2016 · 70 comments

Comments

@tmds
Copy link

tmds commented Jun 16, 2016

Does SkiaSharp work on Linux?

@migueldeicaza
Copy link
Contributor

migueldeicaza commented Jun 17, 2016

SkiaSharp should, but the native supporting code needs to be compiled individually on each Linux distribution.

Sadly, NuGet was not designed to cope with this scenario, so there is not much that we can do to ship precompiled binaries.

What we should do is at least provide a simple Makefile to create the native library support, so third parties can build/install it easily.

@tmds
Copy link
Author

tmds commented Jun 17, 2016

@migueldeicaza compilations could be provided for several linux flavors using the runtimes/RID feature: https://dotnet.github.io/docs/core-concepts/rid-catalog.html

@mattleibow
Copy link
Contributor

@tmds An ARM Linux was actually work with this guy: #18
@migueldeicaza not too sure of all the limitations, but as the native dll is the only thing that needs switching... is it possible to do something like this for a few supported (popular) versions of Linux: https://github.com/mono/SkiaSharp/blob/master/binding/SkiaSharp.Desktop/SkiaSharp.dll.config

@migueldeicaza
Copy link
Contributor

The issue is not identifying the library, the issue is that creating a package with the binaries is incredibly cumbersome (you need to create a package with all available systems upfront, build the native bits, and then package all the bits together).

What should ideally happen is that these native binaries should be "addons" to the core package, and could be published independently of the core package.

@KarolKolenda
Copy link

KarolKolenda commented Jul 4, 2016

@migueldeicaza Any idea when makefiles for popular distros will be available? Is it going to happen this year or are we looking more at 2017? With .Net Core in the wild, lack of server side graphics library in Linux environment all of the sudden seems like a pressing matter.

That being said, you are doing wonderful things with SkiaSharp and in Windows as GDI+ replacement it is just amazing.

@kekekeks
Copy link
Contributor

kekekeks commented Jul 6, 2016

@migueldeicaza I think if you compile skia using sufficiently old distro (e. g. CentOS 6, Debian 5) it will just work everywhere. In the worst case you can just bundle dependencies (skia don't really need much: libfontconfig, libfreetype, libz, libpng12) and rely only on libc which is guaranteed to be present by LSB.

@jameswalmsley
Copy link

I'm looking into the build.cake file and trying to work out how to convert it to build for linux.
Are there any attempts of pointers for me to start updating the build system.

@mattleibow
Copy link
Contributor

mattleibow commented Aug 11, 2016

@jameswalmsley I would say you probably need to just get the externals building. These are grouped using the Task ("externals-<platform>") steps. For the case of Linux, I would suggest following the Android style: Task ("externals-android") https://github.com/mono/SkiaSharp/blob/v1.53.0/build.cake#L674-L724

It pretty much follows the official docs by google: https://skia.org/user/quick/linux

It follows the pattern of:

  1. set global env vars
  2. set gyp defines for platform
  3. build *.a (using ninja) for platform
  4. link all *.a together into a dynamic library of some sort
  5. repeat 2-4 for each platform

In the case of Android, I did step 4 using ndk-build, but you could use whatever it is that is used on Linux. @galvesribeiro did it without much trouble, after he built his compilers first ;)

Basically, build all the *.a files and then dynamically link them together. Let me know how this goes as we do want to have support for as many platforms as possible.

The rest of the stuff is pure C#/.NET P/Invoke

@galvesribeiro
Copy link

Yes. Build for Android linux is already there on the Gyp files however, if you plan to build it to any other linux, you will either have to hack the .gyp files to point to your dependencies (specially if you are cross compiling to another arch) and the output will be a bunch of .a. After that all compiled, you need to link it to the skiasharp. I had everything statically linked since the ld and glibc on the targed device was too old (pre-C++11).

Basically this is the buld script:

export PATH=/home/guto/x-tools/arm-unknown-linux-gnueabi.485/bin:/home/guto/x-tools/crosstool-ng/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/guto/dev/chromium/depot_tools
export TARGETMACH=arm-arm1176jzs-linux-gnueabi
export BUILDMACH=i686-pc-linux-gnu
export CROSS=arm-arm1176jzs-linux-gnueabi
export CC=${CROSS}-gcc
export LD=${CROSS}-ld
export CXX=${CROSS}-g++
export STRIP=${CROSS}-strip
export LINK=${CROSS}-g++
export AS=${CROSS}-as
export AR=${CROSS}-ar
export RANLIB=${CROSS}-ranlib
export NM=${CROSS}-nm
export CROSS_COMPILE="arm-arm1176jzs-linux-gnueabi"
export PKG_CONFIG_PATH=/home/guto/dev/libs/lib/pkgconfig
export INSTALLPATH=/home/guto/dev/libs/

GYP_DEFINES='skia_gpu=0 skia_pdf= skia_os=linux skia_arch_type=arm' SK_SUPPORT_PDF=0  CC='arm-unknown-linux-gnueabi-gcc' CXX='arm-unknown-linux-gnueabi-g++' PKG_CONFIG_PATH=/home/guto/dev/libs/lib/pkgconfig LDFLAGS=-L/home/guto/dev/libs/lib  python bin/sync-and-gyp

ninja -C out/Release skia_lib

//Compiling source to object files
$CXX -MMD /home/guto/dev/SkiaSharp/native-builds/src/SkiaKeeper.c /home/guto/dev/SkiaSharp/native-builds/src/SkManagedStream.cpp /home/guto/dev/SkiaSharp/native-builds/src/sk_managedstream.cpp /home/guto/dev/SkiaSharp/native-builds/src/sk_xamarin.cpp -g -fPIC -O3 -DSKIA_DLL -DSKIA_IMPLEMENTATION=1 -DSK_INTERNAL -DSK_BUILD_FOR_UNIX -I/home/guto/dev/SkiaSharp/skia/include -I/home/guto/dev/SkiaSharp/skia/include/c -I/home/guto/dev/SkiaSharp/skia/include/config -I/home/guto/dev/SkiaSharp/skia/include/core -I/home/guto/dev/SkiaSharp/skia/include/pathops -I/home/guto/dev/SkiaSharp/skia/include/pipe -I/home/guto/dev/SkiaSharp/skia/include/ports -I/home/guto/dev/SkiaSharp/skia/include/private -I/home/guto/dev/SkiaSharp/skia/include/utils -I/home/guto/dev/SkiaSharp/skia/include/images -I/home/guto/dev/SkiaSharp/skia/src/c -I/home/guto/dev/SkiaSharp/skia/src/core -I/home/guto/dev/SkiaSharp/skia/src/sfnt -I/home/guto/dev/SkiaSharp/skia/src/image -I/home/guto/dev/SkiaSharp/skia/src/opts -I/home/guto/dev/SkiaSharp/skia/src/utils -I/home/guto/dev/SkiaSharp/skia/include/gpu -I/home/guto/dev/SkiaSharp/skia/src/gpu -I/home/guto/SSBuild/SkiaSharp/SkiaSharp/obj/Debug/prec/Debug -L/home/guto/dev/libs/lib -lfontconfig -c -std=c++11

//Generating shared object "libSkiaSharp.so" from object files
$CXX -shared -o Release/libSkiaSharp.so SkiaKeeper.o sk_managedstream.o SkManagedStream.o sk_xamarin.o -L/home/guto/dev/SkiaSharp/skia/out/Release/lib -Wl,--start-group /home/guto/dev/SkiaSharp/skia/out/Release/libskia_core.a /home/guto/dev/SkiaSharp/skia/out/Release/libskia_ports.a /home/guto/dev/SkiaSharp/skia/out/Release/libskia_images.a /home/guto/dev/SkiaSharp/skia/out/Release/libskia_sfnt.a /home/guto/dev/SkiaSharp/skia/out/Release/libskia_opts.a /home/guto/dev/SkiaSharp/skia/out/Release/libskia_codec.a /home/guto/dev/SkiaSharp/skia/out/Release/libskia_effects.a /home/guto/dev/SkiaSharp/skia/out/Release/libskia_utils.a -Wl,--end-group /home/guto/dev/SkiaSharp/skia/out/Release/libpng_static.a /home/guto/dev/libs/lib/libfreetype.a /home/guto/dev/libs/lib/libfontconfig.so /home/guto/dev/libs/lib/libz.a /home/guto/dev/libs/lib/libturbojpeg.a /home/guto/dev/libs/lib/libjpeg.a /home/guto/dev/libs/lib/libexpat.a /home/guto/dev/libs/lib/libwebp.a /home/guto/dev/libs/lib/libwebpdecoder.a /home/guto/dev/libs/lib/libwebpdemux.a /home/guto/dev/libs/lib/libwebpextras.a /home/guto/dev/libs/lib/libwebpmux.a  /home/guto/x-tools/arm-unknown-linux-gnueabi.485/arm-unknown-linux-gnueabi/lib/libstdc++.a -L/home/guto/dev/libs/lib -lfontconfig

One can create a makefile and make things easier but this native linux "macumba" is not something we are good here. So thanks to @mattleibow we got it to work.

The C# side of SkiaSharp is just PInvokes with a .Net like APIs, so just point it to the right lib name and you are set.

I hope it help.

@mattleibow
Copy link
Contributor

Thanks for this @galvesribeiro!

@kekekeks
Copy link
Contributor

Hello guys, I have some tips for you here. When I was messing with skia on linux half a year ago, I've run into an issue with really huge library file (50MB+). I've managed to strip it down to 2MB.

  • Linker has a wonderful flag --gc-sections which allows it to remove parts that aren't needed by the final so binary. The issue is it doesn't work properly for shared libs unless you specify -ffunction-sections -fdata-sections compiler flags for each source file
  • Disabling RTTI also saves a great deal of space

You can find a patch to skia.gyp here: https://github.com/AvaloniaUI/libperspesk/blob/master/linux/skia.patch

Another issue with linking it was the fact that for some reason linker doesn't work properly with static library dependencies when you compile your shared library. --whole-archive just bloats your binary size and even then doesn't always work. So the trick is to unpack object files from static libs using ar utility and then combine them into one. The script for that is here: https://github.com/AvaloniaUI/libperspesk/blob/master/linux/mergelibs.sh

I also recommend you to specify --no-undefined linker flag so you won't run into weird undefined symbol errors at runtime, and could figure out dependencies properly.

My old makefile is here:

https://github.com/AvaloniaUI/libperspesk/blob/master/linux/Makefile#L32

@kekekeks
Copy link
Contributor

Oh, forgot to add the script that downloads and actually builds skia itself: https://github.com/AvaloniaUI/libperspesk/blob/master/linux/getskia.sh

@galvesribeiro
Copy link

I wish I had that! Hehehe btw, after strip, my release build was 3mb with everything statically linked.

@jameswalmsley
Copy link

@mattleibow Did you see this? https://github.com/phusion/holy-build-box

@kekekeks
Copy link
Contributor

kekekeks commented Jan 12, 2017

If anyone is interested, I've managed to run Cake in that docker container.

First, you need to acquire mono-opt package for CentOS 5. For some reason I wasn't able to use the repo, so I've downloaded it manually from https://copr-be.cloud.fedoraproject.org/results/tpokorra/mono-opt/epel-5-x86_64/00496651-mono-opt/mono-opt-4.6.2-1.x86_64.rpm . In case it gets deleted, here is mega link: https://mega.nz/#!cswD2Jza!EqE-Q_rwmTK0vwYeNDaWSGm0aHK6y5roF1BHZdPGtz8

You need to install this package with --no-gpg-check option. You also need to install curl and unzip packages. Synchronizing certs is also mandatory.

yum install -y --nogpgcheck ./mono-opt-4.6.2-1.x86_64.rpm
yum install -y curl unzip
source /opt/mono/env.sh

After that you should be able to run bootstrapper.sh. Of course it would need more steps to produce an actual build.

BTW, last time when I was messing with Skia, my library was depending on:

        linux-vdso.so.1 =>  (0x00007ffd7adf3000)
        libfreetype.so.6 => /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007f1cabc08000)
        libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f1cab9ee000)
        libfontconfig.so.1 => /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 (0x00007f1cab7af000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f1cab591000)
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f1cab20f000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1caaf06000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1caab3c000)
        libpng12.so.0 => /lib/x86_64-linux-gnu/libpng12.so.0 (0x00007f1caa916000)
        libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f1caa6ec000)
        /lib64/ld-linux-x86-64.so.2 (0x000055b85c884000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f1caa4d5000)

So it probably should be possible to provide a build of Skia that works everywhere

@cyriltovena
Copy link

Hello Guys,

I was able to get the whole thing working on .net core on linux. I will share that when I have some time. If someone is interested and can't wait let me know and I'll share my new gn target. (Not using gyp)

@ghost
Copy link

ghost commented Jan 20, 2017

@Kuqd I'm interested in learning that, I've been working on a way to make a Wayland Program under Linux. (Would love to avoid using OpenGL.)

@mattleibow
Copy link
Contributor

@Kuqd I am busy looking to get Linux support in, especially for .NET Core. I have been using gyp because that was there, but if it is possible to share what you have done I would like to try using gn. Also, what OS specs are you running?

@kekekeks
Copy link
Contributor

Not using gyp is actually a good idea, since there is a lot of stuff hardcoded there. With custom scripts it should be much easier to build in unusual environments like ARM platforms with custom toolchains, HBB, etc.

@mattleibow
Copy link
Contributor

Just referencing this as it is relevant: NuGet/Home#3114

@mattleibow
Copy link
Contributor

I have created a partially complete script and makefile.
I have been using Ubuntu 14.04 and right now it can fully build, package and run fine, but many things are hardcoded and may not work on other versions or flavors. I am still working on this, and this was more for testing purposes. But, the output is fully functional and all the bits are there.

Build Script:

Task ("externals-linux")
.WithCriteria (
!FileExists ("native-builds/lib/linux/x64/libSkiaSharp.so"))
.WithCriteria (IsRunningOnLinux ())
.Does (() =>
{
var ninja = DEPOT_PATH.CombineWithFilePath ("ninja").FullPath;
// set up the gyp environment variables
AppendEnvironmentVariable ("PATH", DEPOT_PATH.FullPath);
var targets =
"skia_lib pdf dng_sdk libSkKTX sksl piex raw_codec zlib libetc1 " +
"libwebp_dsp_enc opts_avx opts_sse42 opts_hsw xml svg";
var buildArch = new Action<string, string> ((arch, folder) => {
// setup outputs
var outPath = SKIA_PATH.Combine ("out").Combine (folder).FullPath;
CreateDirectory (outPath);
SetEnvironmentVariable ("SKIA_OUT", outPath);
// build skia_lib
RunGyp ("skia_os='linux' skia_arch_type='" + arch + "' skia_gpu=1 skia_pic=1 skia_pdf_use_sfntly=0", "ninja");
RunProcess (ninja, new ProcessSettings {
Arguments = "-C out/" + folder + "/Release " + targets,
WorkingDirectory = SKIA_PATH.FullPath,
});
// build libSkiaSharp
RunProcess ("make", new ProcessSettings {
Arguments = "ARCH=" + folder + " VERSION=" + VERSION_FILE,
WorkingDirectory = "native-builds/libSkiaSharp_linux",
});
});
buildArch ("x86_64", "x64");
// copy output
foreach (var folder in new [] { "x64" }) {
if (!DirectoryExists ("native-builds/lib/linux/" + folder)) {
CreateDirectory ("native-builds/lib/linux/" + folder);
}
CopyFileToDirectory ("native-builds/libSkiaSharp_linux/bin/" + folder + "/libSkiaSharp.so." + VERSION_SONAME, "native-builds/lib/linux/" + folder);
}
});

Makefile: https://github.com/mono/SkiaSharp/blob/21306d6267aeadcba31255d823e89edd54055440/native-builds/libSkiaSharp_linux/Makefile

The basic steps are to gyp (create the internal makefiles), ninja (build the skia static libraries), and make (create the dynamic, linked libSkiaSharp). The Makefile is also pretty straight forward, take the skia outputs, and the xamarin classes and link together. I don't actually do anything specific for linux.

I am still using gyp right now, but I will be looking to switch to gn sometime in the near future.

@cyriltovena
Copy link

cyriltovena commented Feb 3, 2017

Sorry I was away, here is the target to add to the build.gn:

component("libSkiaSharp") {
	sources = [
		"../../native-builds/src/sk_managedstream.cpp",
		"../../native-builds/src/sk_xamarin.cpp",
		"../../native-builds/src/SkiaKeeper.c",
		"../../native-builds/src/SkManagedStream.cpp",
	 ]
	include_dirs = [
		"include/c",
		"include/config",
		"include/core",
		"include/effects",
		"include/pathops",
		"include/codec",
		"include/pathops",
		"include/pipe",
		"include/ports",
		"include/private",
		"include/utils",
		"include/images",
		"src/c",
		"src/core",
		"src/sfnt",
		"src/image",
		"src/opts",
		"src/utils",
		"include/gpu",
		"src/gpu"
	]
	public_deps = [":skia"]
	configs += [":skia_library",":skia_public"]
	visibility = [ ":*" ]  # Prevent accidental dependencies.
  }

then run this :

gn gen ../../native-builds/lib/linux/x64/ --args="is_component_build=true is_debug=false"
ninja -C ../../native-builds/lib/linux/x64/ libSkiaSharp

This is going to build 2 so :

libSkiasharp.so and libskia.so, libSkiasharp.so depend on libskia.so, so make sure you update your LD_LIBRARY_PATH correclty on linux.

I also have the .netstandard (1.6) project, with build task to create the correct nugetpackage that you can use on linux and .net core.If I have time I can create a pull request later @mattleibow , next month.

The project I have is using the new visual studio 2017 RC3 (so you need the last toolchain) csproj, I've added my .net standard binding to SkiaSharp\binding\SkiaSharp.NETStandard\SkiaSharp.NETStandard.csproj :

<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
  <PropertyGroup>
    <Description>SkiaSharp for .net standard</Description>
    <TargetFramework>netstandard1.6</TargetFramework>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
    <DebugType>portable</DebugType>
    <AssemblyName>SkiaSharp.NetStandard</AssemblyName>
    <OutputType>library</OutputType>
    <RuntimeIdentifiers>win7-x64;win7-x86;linux-x64</RuntimeIdentifiers>
    <PackageOutputPath>..\..\..\..\built_packages\</PackageOutputPath>
    <IncludeSymbols>true</IncludeSymbols>
    <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)' == 'Release' ">
    <Optimize>True</Optimize>
    <DefineConstants>
    </DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)' == 'Debug' ">
    <Optimize>False</Optimize>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="..\Binding\*.cs" Exclude="bin\**;obj\**;**\*.xproj;packages\**;Properties\**" />
    <Compile Remove=".vscode\**" />
    <Compile Remove=".vs\**" />
    <EmbeddedResource Remove=".vscode\**" />
    <EmbeddedResource Remove=".vs\**" />
    <None Remove=".vscode\**" />
    <None Remove=".vs\**" />
    <Content Include="..\..\native-builds\lib\windows\x64\libSkiaSharp.dll">
      <PackagePath>runtimes\win7-x64\native</PackagePath>
      <Pack>true</Pack>
    </Content>
    <Content Include="..\..\native-builds\lib\windows\x86\libSkiaSharp.dll">
      <PackagePath>runtimes\win7-x86\native</PackagePath>
      <Pack>true</Pack>
    </Content>
    <Content Include="..\..\native-builds\lib\linux\x64\libSkiaSharp.so">
      <PackagePath>runtimes\linux-x64\native\libSkiaSharp.so</PackagePath>
      <Pack>true</Pack>
    </Content>
    <Content Include="..\..\native-builds\lib\linux\x64\libskia.so">
      <PackagePath>runtimes\linux-x64\native\libskia.so</PackagePath>
      <Pack>true</Pack>
    </Content>
  </ItemGroup>
  <ItemGroup>
    <None Include="README.md" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="System.IO.UnmanagedMemoryStream" Version="4.3.0" />
  </ItemGroup>
</Project>

Once you have the package built all you need is to add a root nuget.config to fetch from the local folder like such:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <config>
    <add key="http_proxy" value="http://proxy-mtl.ubisoft.org:3128/" />
  </config>
   <packageSources>
      <!--To inherit the global NuGet package sources remove the <clear/> line below -->
      <clear />
      <add key="local" value="built_packages" />
      <add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" />
   </packageSources>
</configuration>

then you can reference it like that in your project :

 <PackageReference Include="SkiaSharp.NETStandard">
      <Version>1.0.0</Version>
      <PrivateAssets>All</PrivateAssets>
    </PackageReference>

I can provide built package if you want, but you will need to make sure that you fullfil all shared libraries dependencies use:

ldd libskia.so`` and ``ldd libSkiasharp.so to see what's missing.

We're are in a middle of a big launch so can't really do more.

I'm having very good performance by the way on ubuntu ! :) Hope it helps

Cyril

@kekekeks
Copy link
Contributor

#238 Docker image and changes needed to produce a portable library that should work on most modern Linux distributions.

@mattleibow
Copy link
Contributor

mattleibow commented Feb 12, 2017

I am looking at what is pulled in when adding the GPU bits. It is quite a bit and maybe the experts can tell me how much of this really portable. My local build and that of the holy build box is very similar:

Holy Build Box:

linux-vdso.so.1 =>  (0x00007ffe04f5d000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f696e40f000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f696e20b000)
libfontconfig.so.1 => /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 (0x00007f696dfce000)
libGL.so.1 => /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1 (0x00007f696dd66000)
libGLU.so.1 => /usr/lib/x86_64-linux-gnu/libGLU.so.1 (0x00007f696daf8000)
libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f696d7c2000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f696d4be000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f696d1b8000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f696cfa1000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f696cbdc000)
/lib64/ld-linux-x86-64.so.2 (0x000056496cd15000)
libfreetype.so.6 => /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007f696c939000)
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f696c70e000)
libxcb-dri3.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-dri3.so.0 (0x00007f696c50b000)
libxcb-present.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-present.so.0 (0x00007f696c308000)
libxcb-sync.so.1 => /usr/lib/x86_64-linux-gnu/libxcb-sync.so.1 (0x00007f696c101000)
libxshmfence.so.1 => /usr/lib/x86_64-linux-gnu/libxshmfence.so.1 (0x00007f696beff000)
libglapi.so.0 => /usr/lib/x86_64-linux-gnu/libglapi.so.0 (0x00007f696bcd1000)
libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007f696babe000)
libXdamage.so.1 => /usr/lib/x86_64-linux-gnu/libXdamage.so.1 (0x00007f696b8bb000)
libXfixes.so.3 => /usr/lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007f696b6b5000)
libX11-xcb.so.1 => /usr/lib/x86_64-linux-gnu/libX11-xcb.so.1 (0x00007f696b4b2000)
libxcb-glx.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-glx.so.0 (0x00007f696b29b000)
libxcb-dri2.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-dri2.so.0 (0x00007f696b096000)
libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f696ae76000)
libXxf86vm.so.1 => /usr/lib/x86_64-linux-gnu/libXxf86vm.so.1 (0x00007f696ac70000)
libdrm.so.2 => /usr/lib/x86_64-linux-gnu/libdrm.so.2 (0x00007f696aa62000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f696a848000)
libpng12.so.0 => /lib/x86_64-linux-gnu/libpng12.so.0 (0x00007f696a622000)
libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f696a41d000)
libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f696a217000)

Full -v: https://gist.github.com/mattleibow/f98bdd8b5a1bfc824f175a905bc48a9c

My Local Build:

linux-vdso.so.1 =>  (0x00007ffddb1c9000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f0543d08000)
libfontconfig.so.1 => /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 (0x00007f0543acc000)
libGL.so.1 => /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1 (0x00007f0543863000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f054355f000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f0543259000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f0543042000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0542c7d000)
/lib64/ld-linux-x86-64.so.2 (0x0000556078b83000)
libfreetype.so.6 => /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007f05429da000)
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f05427af000)
libxcb-dri3.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-dri3.so.0 (0x00007f05425ac000)
libxcb-present.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-present.so.0 (0x00007f05423a9000)
libxcb-sync.so.1 => /usr/lib/x86_64-linux-gnu/libxcb-sync.so.1 (0x00007f05421a2000)
libxshmfence.so.1 => /usr/lib/x86_64-linux-gnu/libxshmfence.so.1 (0x00007f0541fa0000)
libglapi.so.0 => /usr/lib/x86_64-linux-gnu/libglapi.so.0 (0x00007f0541d72000)
libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007f0541b5f000)
libXdamage.so.1 => /usr/lib/x86_64-linux-gnu/libXdamage.so.1 (0x00007f054195c000)
libXfixes.so.3 => /usr/lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007f0541756000)
libX11-xcb.so.1 => /usr/lib/x86_64-linux-gnu/libX11-xcb.so.1 (0x00007f0541553000)
libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f054121e000)
libxcb-glx.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-glx.so.0 (0x00007f0541007000)
libxcb-dri2.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-dri2.so.0 (0x00007f0540e01000)
libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f0540be2000)
libXxf86vm.so.1 => /usr/lib/x86_64-linux-gnu/libXxf86vm.so.1 (0x00007f05409dc000)
libdrm.so.2 => /usr/lib/x86_64-linux-gnu/libdrm.so.2 (0x00007f05407cd000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f05405c9000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f05403af000)
libpng12.so.0 => /lib/x86_64-linux-gnu/libpng12.so.0 (0x00007f0540189000)
libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f053ff84000)
libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f053fd7e000)

Full -v: https://gist.github.com/mattleibow/636ffaf7e9edf081bb08b094cdce3bea

@galvesribeiro
Copy link

libGL.so.1 => /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1 (0x00007f696dd66000)
libGLU.so.1 => /usr/lib/x86_64-linux-gnu/libGLU.so.1 (0x00007f696daf8000)
libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f696d7c2000)

Would be nice if X11, GL and HW acceleration would be optional/configurable while building... That would make low-powered/non-X11 targets to use it as well...

@mattleibow
Copy link
Contributor

Also, about x86/32-bit builds. Is there a way to do this on a 64-bit OS? And should I even try?

The same build config and I get these errors:

/usr/bin/ld: cannot find -lfontconfig
/usr/bin/ld: cannot find -lGL
/usr/bin/ld: cannot find -lGLU
/usr/bin/ld: cannot find -lX11

It appears those packages only come with either x86 or x64 libraries, not both. Should I just use an x86 environment, or is there a clean way to do this properly?

@mattleibow
Copy link
Contributor

@galvesribeiro Let me see if I can make that a nice flag that can be set...

@galvesribeiro
Copy link

@mattleibow just noticed one thing... HBB is x86/x64 only :(

I wonder if someone with experience in that could create the same environment using https://buildroot.org/ since it support more targets including ARM.

@kekekeks
Copy link
Contributor

@mattleibow LDFLAGS, CFLAGS and CXXFLAGS from environment shouldn't completely override values from your Makefile, you just append your defaults to them.

@SebastianStehle
Copy link

Hi,

how is it going with the Linux integration? I would like to integrate Skiasharp to an application that is deployed via docker containers. Unfortunately I am not a Linux expert. Installing some dependencies to my docker container would be perfectly fine for me too.

I am a little bit lost at the moment.

@kekekeks
Copy link
Contributor

@SebastianStehle you can grab Avalonia.Skia.Linux.Natives nuget package with prebuilt libSkiaSharp.so that should work for most libc based distros (Debian/Ubuntu/RHEL/CentOS)

@SebastianStehle
Copy link

Is there something else I have to do? I always get "Unable to load DLL 'libSkiaSharp': The specified module could not be found."

I also tried to add add the *.so file as runtimeTarget to SkiaSharp:

 "runtimes/linux-x64/native/libSkiaSharp.so": {
	"rid": "linux-x64",
	"assetType": "native"
  }

I also tested other rid, e.g. just linux But it does not work so far

@kekekeks
Copy link
Contributor

  1. Check that libSkiaSharp.so is deployed with your app when you run dotnet publish
  2. I think, this particular version of the library needs the following:
  NEEDED               libpthread.so.0
  NEEDED               libdl.so.2
  NEEDED               libfontconfig.so.1
  NEEDED               libGL.so.1
  NEEDED               libGLU.so.1
  NEEDED               libX11.so.6
  NEEDED               libstdc++.so.6
  NEEDED               libm.so.6
  NEEDED               libgcc_s.so.1
  NEEDED               libc.so.6

@SebastianStehle
Copy link

Yes, it is deloyed to the following folder: "runtimes/linux-x64/native/libSkiaSharp.so", I also tested it to move the file to another folder, e.g. the root, but it does not help so far. Do you have a small example

I will check that the other libraries are there as well. I guess I would get another error, e.g. cannot open shared object file 'libGL.so.1" or so.

@kekekeks
Copy link
Contributor

Check the library with ldd command it should give you the list of missing dependencies.

I guess, I need to update the package so it won't require libGL.

@SebastianStehle
Copy link

Hi,
I tested it with an updated docker file:

FROM microsoft/aspnetcore:1.1.1

WORKDIR /app

COPY . .

RUN apt-get update \
 && apt-get install -y --no-install-recommends libfontconfig libgl1-mesa-dev \
 && apt-get clean \

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

Now I have all the dependencies (checked with ldd)

Before the following dependencies were missing:

libfontconfig.so.1
libGL.so.1
libGLU.so.1
libX11.so.6

I still get the same error, when I run the container (on a linux host):

System.DllNotFoundException: Unable to load DLL 'libSkiaSharp': The specified module could not be found.

@kekekeks
Copy link
Contributor

I've updated the package (1.56.1.3) so it only requires libfontconfig.so.1 and you don't need x11/gl deps anymore.

Also make sure that libSkiaSharp.so has executable flag set.

@mattleibow
Copy link
Contributor

Thanks for your work on this @kekekeks. I am still waiting on our release engineering team to get a nice build of SkiaSharp out. I hope building linux using the new scripts is easer than it was. As you noticed, the last version (1.56.2) had no hard dependencies on anything except fontconfig.

Right now I am in the process of updating to the m57 release of skia. This also comes with the new build system GN. A fair bit has changed with the build system, and I think for the better.

@kekekeks
Copy link
Contributor

I'm using your latest scripts with slightly modified holy-build-box-based docker image from before (I had to remove built-in LDFLAGS since they override ones from your Makefile).

Unfortunately I'm can't provide a proper dockerfile, since environment setup process involves some issues with installing Mono and I was unable to get it automated.

I recommend to use the same approach, since it produces a portable binary that can run on almost all distros that matter.

@SebastianStehle
Copy link

SebastianStehle commented Mar 13, 2017

I have moved forward a small step. Now I get:

    Error: assembly specified in the dependencies manifest was not found -- package: 'skiasharp', version: '1.56.2', path: 'lib/netstandard1.3/SkiaSharp.dll'	

My dockerfile

    FROM microsoft/aspnetcore:1.1.1

RUN apt-get update \
 && apt-get install -y --no-install-recommends libfontconfig \
 && apt-get clean \
 
WORKDIR /app

COPY . .

RUN ldd runtimes/linux-x64/native/libSkiaSharp.so
RUN chmod -x runtimes/linux-x64/native/libSkiaSharp.so

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

If I don't install libfontconfig I get the old error. Chaning the paths in deps.json does not make a difference.

I also noticed that there is a mismatch here in Skiasharp.dll:

[assembly: AssemblyVersion("1.56.0.0")]
[assembly: AssemblyFileVersion("1.56.1.0")]

Don't know if this is an issue but I also noticed some minor differences on .NET Core in Linux vs Win (often related to network stack btw.).

@kekekeks
Copy link
Contributor

Error: assembly specified in the dependencies manifest was not found -- package: 'skiasharp', version: '1.56.2', path: 'lib/netstandard1.3/SkiaSharp.dll'

It seems that you are doing something wrong with publishing. Make sure, that your project has proper runtime identifier included and that you have restored deps using said identifier before running dotnet publish.

I'd also recommend to create a self-contained bundle and run it on generic debian image.

@SebastianStehle
Copy link

SebastianStehle commented Mar 13, 2017

I cleaned everything, called "dotnet restore", "dotnet publish" and thats it. My csproj ist very simple as well:

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

  <PropertyGroup>
	<OutputType>Exe</OutputType>
	<TargetFramework>netcoreapp1.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
	<PackageReference Include="Avalonia.Skia.Linux.Natives" Version="1.56.1.3" />
	<PackageReference Include="SkiaSharp" Version="1.56.1" />
  </ItemGroup>

</Project>

The published version works correctly on Windows, also on another machine.

Btw: I also tested version 1.56.1 of Skiasharp, therefore the different version numbers, but it does not change anything.

@kekekeks
Copy link
Contributor

You need dotnet publish to get a somewhat portable bundle. You won't get your dependencies to the target machine otherwise.

@SebastianStehle
Copy link

Sorry, I was already very tired when I wrote it. I made a dotnet publish.

@kekekeks
Copy link
Contributor

I suggest to either create a self-contained bundle or simply run from source. Always work for me that way.

@hurricanehrndz
Copy link

I'm trying to figure out why cake is being used for native linux builds at all? Correct me if I'm wrong but to built a native linux library the only thing required is to build libskia and than run make within the "native-builds/libSkiaSharp_linux/" . Using dotnetcore and cake just seems over and above as to what is really needed to compile the native linux library.

@mattleibow
Copy link
Contributor

mattleibow commented Jun 8, 2017

@hurricanehrndz The reason for that is basically 2 reasons: I am not that clued up on make (or what the linux guys are using these days), and there are a few extra steps:

https://github.com/mono/SkiaSharp/blob/master/cake/BuildExternals.cake#L102-L105
https://github.com/mono/SkiaSharp/blob/master/cake/BuildExternals.cake#L711-L781

After working on this project, my skills have moved up a tiny bit, but I haven't had time to update the scripts. The best thing would be to actually mix all of this into the Makefile and just call make from cake. Thus, no need for any dependencies if you are just building native.

And, I will mention that the build process has improved recently - the first few versions did not use the nice gn tool, and was a bit harder to do with my very limited knowledge.

If you can go make and have the time, you can move this logic into the Makefile and send a PR. Everyone in the linux side of SkiaSharp will love you. ❤️ 🐧

@mattleibow
Copy link
Contributor

Let me close this issue and open new issues with more specific tasks. As of now, linux support is available and working, just a bit rough to do.

The issue to move the build into make: #311
The issue to distribute linux binaries: #312

I am closing this issue as it is quite big and is really too broad an issue. If any further questions, comments or issues are for linux support, either use the above issues or just create a new issue with your comment. This way the tasks are smaller and actionable, as well as easier to consume.

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

No branches or pull requests

10 participants