This project provides up to date safe bindings that bridge idiomatic Rust with Skia’s C++ API on desktop and mobile platforms, including GPU rendering backends for Vulkan, Metal, OpenGL, and Direct3D.
Status
Documentation
The skia-safe API documentation is available on docs.rs.
Crate
A prerelease crate is available from crates.io. To get started, run
cargo add skia-safe
in your project’s folder. And you might want to take a look at the gl-window example if you plan to render to a window.
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’s build.rs attempts to download prebuilt binaries from the skia-binaries repository using the curl command line tool.
The supported wrappers, Skia codecs, and additional Skia features are documented in the skia-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.rs will try to build Skia and generate the Rust bindings.
For building Skia from source, LLVM, Python 3, and Ninja are required:
LLVM
We recommend the version that comes preinstalled with your platform, or, if not available, the latest official LLVM release. To see which version of LLVM/Clang is installed on your system, use clang --version.
Python 3
The build script probes for python --version and python3 --version and uses the first one that looks like a version 3 executable for building Skia.
Ninja
The build system for Skia. ninja is available as a binary package on all major platforms. Install ninja or ninja-build and make sure it is in your PATH with ninja --version.
If the environment variable LLVM_HOME is not defined, the build script will look for LLVM installations located at C:\Program Files\LLVM\, C:\LLVM\, and %USERPROFILE%\scoop\apps\llvm\current\.
If OpenGL libraries are missing, install the drivers for you graphics card, or a mesa package like libgl1-mesa-dev.
For X11, build with feature x11.
For Wayland, install libwayland-dev and build with the wayland feature.
For Android
Cross compilation to Android is supported for targeting 64 bit ARM and Intel x86 architectures (aarch64 and x86_64) for API Level 26 (Oreo, Android 8):
We recommend using cargo 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 for aarch64:
Install the Rust target:
rustup target install aarch64-linux-android
Download the r26d NDK (or newer) for your host architecture and unzip it.
Compile your project for the aarch64-linux-android target:
At the time of this writing, the Rust compiler will automatically add a -lgcc argument to the linker, which results in a linker error, because newer NDKs do not contain libgcc.a anymore. To fix this, we created a workaround and copy libunwind.a over to libgcc.a. Cargo apk does something similar.
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 the ANDROID_NDK variable must be defined before it’s used in the PATH variable.
Rebuilding skia-bindings with a different target may cause linker errors, in that case touch skia-bindings/build.rs will 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 ARM64e architecture is not supported yet.
For visionOS
Compilation to visionOS is supported on macOS targeting visionOS devices (--target aarch64-apple-visionos) and the visionOS simulator (--target aarch64-apple-visionos-sim). These are Rust tier 3 targets, so a nightly toolchain and -Z build-std are required, and the visionOS SDK must be installed via Xcode. Skia itself has no dedicated visionOS configuration, so it is built using its iOS code paths against the visionOS (xros) SDK. Prebuilt binaries are not provided; Skia is built from source. Only Metal is available as a GPU backend (visionOS has no OpenGL).
For WebAssembly
Install emscripten version 3.1.57 or newer and make sure that llvm / clang 16+ is installed. In the examples below, we assume
emsdk version 3.1.57 was installed with asdf.
On macOS there is a problem with the OS version of ar so you will have to install the GNU version from homebrew:
brew install binutils
Then prepend the binutils path to PATH. The path depends on your CPU
architecture, and can be retrieved with brew info binutils. Here is an
example for Apple silicon:
cargo build is sufficient to build the bindings including Skia. For situations in which Skia does not build or needs to be configured differently, some customization is supported in skia-bindings/build.rs. For more details take a look at the README of the skia-bindings package.
Please share your build experience so that we can try to automate the build further.
Example Applications
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 feature x11 needs to be enabled:
cargo run --example gl-window --features gl,x11
vulkan-window
An example application that opens a Window and renders a blue rectangle using Vulkano (contributed by @samizdatco in #1066)
cargo run --example vulkan-window --features "ganesh,vulkan"
To enable Vulkan validation layer messages and debug output in this example:
cargo run --example vulkan-window --features "ganesh,vulkan" -- --validate
To add Vulkan support to your system, the easiest way is to install the LunarG SDK, and enable “System Global Installation” in the installer.
metal-window
An example application that opens a Metal Window and renders a blue rectangle using Skia’s Ganesh backend. It is only supported on macOS.
cargo run --example metal-window --features "ganesh,metal"
metal-window-graphite
The same window example, but rendering with Skia’s Graphite backend instead of Ganesh. It is only supported on macOS.
cargo run --example metal-window-graphite --features "graphite,metal"
d3d-window
An example application that opens a Window and renders a rectangle using Direct3D 12 and Skia’s Ganesh backend (most of the code is adapted from the windows-rs Direct3D 12 sample). It is only supported on Windows. Use the arrow keys to move the rectangle and Escape to quit.
cargo run --example d3d-window --features d3d
icon
The icon example 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.
If you’d like to help with the bindings, take a look at the Wiki to 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 label help wanted. And if you’d like to help make the Rust API nicer to use, look out for open issues with the label api ergonomics.
Skia Submodule Status: chrome/m153 (upstream changes, our changes).
About
This project provides up to date safe bindings that bridge idiomatic Rust with Skia’s C++ API on desktop and mobile platforms, including GPU rendering backends for Vulkan, Metal, OpenGL, and Direct3D.
Status
Documentation
The skia-safe API documentation is available on docs.rs.
Crate
A prerelease crate is available from crates.io. To get started, run
in your project’s folder. And you might want to take a look at the gl-window example if you plan to render to a window.
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’s
build.rsattempts to download prebuilt binaries from the skia-binaries repository using thecurlcommand line tool.x86_64-pc-windows-msvcaarch64-pc-windows-msvcCentOS 7, 8
x86_64-unknown-linux-gnuaarch64-unknown-linux-gnux86_64-apple-darwinaarch64-apple-darwinaarch64-linux-androidx86_64-linux-androidaarch64-apple-iosaarch64-apple-ios-simx86_64-apple-ioswasm32-unknown-emscriptenWrappers & Codecs & Supported Features
The supported wrappers, Skia codecs, and additional Skia features are documented in the skia-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.For building Skia from source, LLVM, Python 3, and Ninja are required:
LLVM
We recommend the version that comes preinstalled with your platform, or, if not available, the latest official LLVM release. To see which version of LLVM/Clang is installed on your system, use
clang --version.Python 3
The build script probes for
python --versionandpython3 --versionand uses the first one that looks like a version 3 executable for building Skia.Ninja
The build system for Skia.
ninjais available as a binary package on all major platforms. Installninjaorninja-buildand make sure it is in yourPATHwithninja --version.On macOS
Install the Command Line Tools for Xcode with
or download and install the Command Line Tools for Xcode.
As an alternative to Apple’s Xcode LLVM, install LLVM via
brew install llvmand then setPATH,CPPFLAGS, andLDFLAGSas instructed.If the environment variables are not set, bindgen will most likely use the wrong
libclang.dyliband cause confusing compilation errors (see #228).On Windows
Have the latest versions of
gitand Rust ready.Install Visual Studio 2022 Build Tools or one of the other IDE editions. If you installed the IDE, make sure that the Desktop Development with C++ workload is installed.
Install the latest LLVM distribution.
If the environment variable
LLVM_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:
pacman -S python.Windows Shell (
Cmd.exe):Install and select the MSVC toolchain:
On Linux
Ubuntu 20+
libgl1-mesa-dev.x11.libwayland-devand build with thewaylandfeature.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 using cargo 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 for
aarch64:aarch64-linux-androidtarget:On macOS:
We don’t support Apple’s Clang to build for Android on macOS, so you need to install LLVM and set the
PATHlike instructed.On Linux:
On Windows the Android NDK Clang executable must be invoked through
.cmdscripts:Notes:
-lgccargument to the linker, which results in a linker error, because newer NDKs do not containlibgcc.aanymore. To fix this, we created a workaround and copylibunwind.aover tolibgcc.a. Cargo apk does something similar.CARGO_TARGET_${TARGET}_LINKERenvironment variable name needs to be all uppercase.ANDROID_NDKvariable must be defined before it’s used in thePATHvariable.touch 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 ARM64e architecture is not supported yet.For visionOS
Compilation to visionOS is supported on macOS targeting visionOS devices (
--target aarch64-apple-visionos) and the visionOS simulator (--target aarch64-apple-visionos-sim). These are Rust tier 3 targets, so a nightly toolchain and-Z build-stdare required, and the visionOS SDK must be installed via Xcode. Skia itself has no dedicated visionOS configuration, so it is built using its iOS code paths against the visionOS (xros) SDK. Prebuilt binaries are not provided; Skia is built from source. Only Metal is available as a GPU backend (visionOS has no OpenGL).For WebAssembly
Install
emscriptenversion 3.1.57 or newer and make sure that llvm / clang 16+ is installed. In the examples below, we assumeemsdkversion3.1.57was installed with asdf.Build with the
wasm32-unknown-emscriptentarget (wasm32-unknown-unknownis unsupported because it is fundamentally incompatible with linking C code:The
EMSDKenvironment variable must be set to the root of youremscriptenSDK.In
EMCC_CFLAGS,-s ERROR_ON_UNDEFINED_SYMBOLSis a workaround to build withemscripten > 2.0.9.If you want to enable WebGL, you will also have to set
MAX_WEBGL_VERSION=2:On macOS there is a problem with the OS version of
arso you will have to install the GNU version from homebrew:Then prepend the
binutilspath toPATH. The path depends on your CPU architecture, and can be retrieved withbrew info binutils. Here is an example for Apple silicon:Skia
cargo buildis sufficient to build the bindings including Skia. For situations in which Skia does not build or needs to be configured differently, some customization is supported inskia-bindings/build.rs. For more details take a look at the README of the skia-bindings package.Please share your build experience so that we can try to automate the build further.
Example Applications
gl-window
An example that opens an OpenGL Window and draws the rust-skia icon with skia-safe (contributed by @nornagon).
On Linux the feature
x11needs to be enabled:vulkan-window
An example application that opens a Window and renders a blue rectangle using Vulkano (contributed by @samizdatco in #1066)
To enable Vulkan validation layer messages and debug output in this example:
To add Vulkan support to your system, the easiest way is to install the LunarG SDK, and enable “System Global Installation” in the installer.
metal-window
An example application that opens a Metal Window and renders a blue rectangle using Skia’s Ganesh backend. It is only supported on macOS.
metal-window-graphite
The same window example, but rendering with Skia’s Graphite backend instead of Ganesh. It is only supported on macOS.
d3d-window
An example application that opens a Window and renders a rectangle using Direct3D 12 and Skia’s Ganesh backend (most of the code is adapted from the windows-rs Direct3D 12 sample). It is only supported on Windows. Use the arrow keys to move the rectangle and
Escapeto quit.icon
The
iconexample 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
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 from Skia’s website and ported to the Rust API.
to generate some Skia drawn PNG images in the directory
OUTPUT_DIR. To render with OpenGL, useAnd to show the drivers that are supported
Example Images
Fill, Radial Gradients, Stroke, Stroke with Gradient, Transparency:
Fill, Stroke, Text:
Sweep Gradient:
Dash Path Effect:
For more, you may take a look at the rust-skia.github.io repository.
This project needs contributions!
If you’d like to help with the bindings, take a look at the Wiki to 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 label help wanted. And if you’d like to help make the Rust API nicer to use, look out for open issues with the label api ergonomics.
More details can be found at CONTRIBUTING.md.
Notable Contributions
wasm32-unknown-emscriptentarget.Maintainers
License
MIT