Skip to content

rust-skia/rust-skia

Repository files navigation

Safe Rust bindings for theSkia Graphics Library.

crates.iolicenseWindows QALinux QAmacOS QA

Skia Submodule Status: chrome/m127 (upstream changes,our changes).

About

This project providesup to datesafe bindings that bridge idiomatic Rust with Skia's C++ API on desktop and mobile platforms, including GPU rendering backends forVulkan,Metal,OpenGL,andDirect3D.

Status

Documentation

Because wecan't build on docs.rs,thecargo docoutput for skia-safe is manually created and uploaded torust-skia.github.io.

We (slowly)add more documentationby converting Skia's Doxygen comments to Rust.

Crate

A prerelease crate is available fromcrates.ioand invoking

cargo add skia-safe

in your project's folder should get you started. And you might want to take a look at thegl-windowexample if you plan to render to a window.

On Linuxyou may run into trouble whenOpenSSL librariesare missing. OnDebianandUbuntuthey can be installed with:

sudo apt-get install pkg-config libssl-dev

For other platforms, more information is available at theOpenSSL crate documentation.

Platform Support, Build Targets, and Prebuilt Binaries

Because building Skia takes a lot of time and needs tools that may be missing, the skia-bindings crate'sbuild.rsattempts to download prebuilt binaries fromthe skia-binaries repositoryusing thecurlcommand line tool.

Platform Binaries
Windows x86_64-pc-windows-msvc
Linux Ubuntu 16+
CentOS 7, 8
x86_64-unknown-linux-gnu
aarch64-unknown-linux-gnu
macOS x86_64-apple-darwin
aarch64-apple-darwin
Android aarch64-linux-android
x86_64-linux-android
iOS aarch64-apple-ios
x86_64-apple-ios
WebAssembly wasm32-unknown-emscripten

Wrappers & Codecs & Supported Features

The supported wrappers, Skia codecs, and additional Skia features are documented in theskia-safe package's readme.Prebuilt binaries are available for most feature combinations.

Building

If the target platform or feature configuration is not available as a prebuilt binary, skia-bindings'build.rswill try to build Skia and generate the Rust bindings.

To prepare for that,LLVMandPython 3are needed:

LLVM

We recommend the version that comes preinstalled with your platform, or, if not available, thelatest official LLVM release.To see which version of LLVM/Clang is installed on your system, useclang --version.

Python 3

The build script probes forPython --versionandPython 3 --versionand uses the first one that looks like a version 3 executable for building Skia.

On macOS

  • Install the Command Line Tools for Xcode with

    xcode-select --install

    or download and install theCommand Line Tools for Xcode.

  • macOS Mojave only:install the SDK headers:

    sudo open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg

    If not installed, the Skia buildmayfail to buildSkJpegUtility.cppand the binding generationwillfail with'TargetConditionals.h' file not found.Also note that the Command Line ToolsandSDK headersshouldbe reinstalled after an update of XCode.

  • As an alternative to Apple's XCode LLVM, install LLVM viabrew install llvmorbrew install llvmand then setPATH,CPPFLAGS,andLDFLAGSlike instructed.

    If the environment variables are not set,bindgenwill most likely use the wronglibclang.dyliband cause confusing compilation errors (see #228).

On Windows

  • Have the latest versions ofgitand Rust ready.

  • Install Visual Studio 2022 Build Toolsor one of the other IDE editions. If you installed the IDE, make sure that theDesktop Development with C++ workloadis installed.

  • Install thelatest LLVMdistribution.

    If the environment variableLLVM_HOMEis not defined, the build script will look for LLVM installations located atC:\Program Files\LLVM\,C:\LLVM\,and%USERPROFILE%\scoop\apps\llvm\current\.

  • MSYS2:

    • Install Python 3 withpacman -S Python.
  • Windows Shell (Cmd.exe):

  • Install and select the MSVC toolchain:

    rustup default stable-msvc

On Linux

Ubuntu 16+

  • LLVM/Clang should be available already, if not,install the latest version.
  • If OpenGL libraries are missing, install the drivers for you graphics card, or a mesa package likelibgl1-mesa-dev.
  • ForX11,build with featurex11.
  • ForWayland,installlibwayland-devand build with thewaylandfeature.

CentOS 7

CentOS 8

  • Install the following packages:

    sudo yum install gcc openssl-devel libX11-devel Python 3 clang fontconfig-devel mesa-libGL-devel
  • Set/usr/bin/ Python 3as the defaultPythoncommand:

    sudo alternatives --set Python /usr/bin/ Python 3

For Android

Cross compilation to Android is supported for targeting 64 bit ARM and Intel x86 architectures (aarch64andx86_64) for API Level 26 (Oreo, Android 8):

We recommend to usecargo apk,but if that does not work for you, following are some instructions on how we build Android targets with GitHub Actions:

For example, to compile foraarch64:

  1. Install the Rust target:
    rustup target install aarch64-linux-android
  2. Download ther26d NDK(or newer) for your host architecture and unzip it.
  3. Compile your project for theaarch64-linux-androidtarget:

OnmacOS:

exportANDROID_NDK=:path-to-android-ndk-r26d
exportPATH=$PATH:$ANDROID_NDK/toolchains/llvm/prebuilt/darwin-x86_64/bin
exportCC_aarch64_linux_android=aarch64-linux-android26-clang
exportCXX_aarch64_linux_android=aarch64-linux-android26-clang++
exportAR_aarch64_linux_android=llvm-ar
exportCARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android26-clang

cargo build -vv --target aarch64-linux-android

We don't support Apple's Clang to build for Android on macOS, so you need to install LLVM and set thePATHlike instructed.

OnLinux:

exportANDROID_NDK=:path-to-android-ndk-r26d
exportPATH=$PATH:$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/bin
exportCC_aarch64_linux_android=aarch64-linux-android26-clang
exportCXX_aarch64_linux_android=aarch64-linux-android26-clang++
exportAR_aarch64_linux_android=llvm-ar
exportCARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android26-clang

cargo build -vv --target aarch64-linux-android

OnWindowsthe Android NDK Clang executable must be invoked through.cmdscripts:

exportANDROID_NDK=:path-to-android-ndk-r26d
exportPATH=$PATH:$ANDROID_NDK/toolchains/llvm/prebuilt/windows-x86_64/bin
exportCC_aarch64_linux_android=aarch64-linux-android26-clang.cmd
exportCXX_aarch64_linux_android=aarch64-linux-android26-clang++.cmd
exportAR_aarch64_linux_android=llvm-ar
exportCARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android26-clang.cmd

cargo build -vv --target aarch64-linux-android

Notes:

  • At the time of this writing, the Rust compiler willautomatically add a-lgccargumentto the linker, which results in a linker error, because newer NDKs do not containlibgcc.aanymore. To fix this, we created a workaround andcopylibunwind.aover tolibgcc.a.Cargo apk does somethingsimilar.
  • TheCARGO_TARGET_${TARGET}_LINKERenvironment variable nameneeds to be all uppercase.
  • In some older shells (for example macOS High Sierra), environment variable replacement can not be used when the variable was defined on the same line. Therefore theANDROID_NDKvariable must be defined before it's used in thePATHvariable.
  • Rebuilding skia-bindings with a different target may cause linker errors, in that casetouch skia-bindings/build.rswill force a rebuild (#10).

For iOS

Compilation to iOS is supported on macOS targeting the iOS simulator (--target x86_64-apple-ios) and 64 bit ARM devices (--target aarch64-apple-ios). The ARM64earchitecture isnot supported yet.

For WebAssembly

Installemscriptenversion 3.1.57 or superior and make sure that llvm / clang 16+ is installed. In the examples below, we assume emsdkversion3.1.57was installed withasdf.

Build with thewasm32-unknown-emscriptentarget (wasm32-unknown-unknownis unsupported because it isfundamentally incompatible with linking C code:

exportEMSDK=~/.asdf/installs/emsdk/3.1.57
exportEMCC_CFLAGS="-s ERROR_ON_UNDEFINED_SYMBOLS=0"

cargo build --target wasm32-unknown-emscripten

TheEMSDKenvironment variable must be set to the root of youremscriptenSDK.

InEMCC_CFLAGS,-s ERROR_ON_UNDEFINED_SYMBOLSis a workaroundto build with emscripten > 2.0.9.

If you want to enable WebGL, you will also have to setMAX_WEBGL_VERSION=2:

exportEMSDK=~/.asdf/installs/emsdk/3.1.57
exportEMCC_CFLAGS="-s ERROR_ON_UNDEFINED_SYMBOLS=0 -s MAX_WEBGL_VERSION=2"

cargo build --target wasm32-unknown-emscripten --features gl

On MacOS there is a problem with the OS version ofarso you will have to install the GNU version from homebrew:

brew install binutils

Then prependbinutilspath for the build. The path depends on your CPU architecture, and can be retrieved withbrew info binutils.Here is an example for Apple silicon:

exportEMSDK=~/.asdf/installs/emsdk/3.1.57
exportEMCC_CFLAGS="-s ERROR_ON_UNDEFINED_SYMBOLS=0"
exportPATH="/opt/homebrew/opt/binutils/bin:$PATH"

cargo build --target wasm32-unknown-emscripten

Skia

For situations in which Skia does not build or needs to be configured differently, we support some customization support inskia-bindings/build.rs.For more details take a look at theREADME of the skia-bindings package.

Please share your build experience so that we can try to automate the build and get to the point wherecargo buildissufficient to build the bindingsincludingSkia, and if that is not possible, clearly prompts to what's missing.

Example Applications

icon

Theiconexample generates the rust-skia icon in the current directory. It computes the position of all the gear teeth etc. based on parameters such as the number of teeth and wheel radius.

If you were able to build the project, run

cargo run --example icon 512

It has a single optional parameter which is the size in pixels for the PNG file. Without parameters, it’ll produce PNG frames for the animated version.

skia-org

The other examples are taken fromSkia's websiteandported to the Rust API.

cargo run -- [OUTPUT_DIR]

to generate some Skia drawn PNG images in the directoryOUTPUT_DIR.To render with OpenGL, use

cargo run -- [OUTPUT_DIR] --driver opengl

And to show the drivers that are supported

cargo run -- --help

gl-window

An example that opens an OpenGL Window and draws the rust-skia icon with skia-safe (contributed by@nornagon).

cargo run --example gl-window --features gl

On Linux the featurex11needs to be enabled:

cargo run --example gl-window --features gl,x11

Example Images

Fill, Radial Gradients, Stroke, Stroke with Gradient, Transparency: Rust-skia icon

Fill, Stroke, Text:

Fill, Stroke, Text

Sweep Gradient:

Sweep Gradient

Dash Path Effect:

Dash Path Effect

For more, you may take a look at therust-skia.github.iorepository.

This project needs contributions!

If you'd like to help with the bindings, take a look at theWikito get started and create an issue to prevent duplicate work. For smaller tasks, grep for "TODO" s in the source code. And for heroic work, check out the labelhelp wanted.And if you like to help making the Rust API nicer to use, look out for open issues with the labelapi ergonomics.

More details can be found atCONTRIBUTING.md.

Notable Contributions

  • Denis Kolodin (@DenisKolodin) contributed build support for Android.
  • Alberto González Palomo (@AlbertoGP) designed the Rust-Skia Logo and the example program that renders it.
  • Luper Rouch (@flupke,sponsored byJitter) added build support for thewasm32-unknown-emscriptentarget.
  • Osei Fortune (@triniwiz) contributed rendering SVG files.

Maintainers

License

MIT