rust-skia
rust-skia copied to clipboard
Rust Bindings for the Skia Graphics Library
Safe Rust bindings to the Skia Graphics Library.
Skia Submodule Status: chrome/m105 (upstream changes, our changes).
Goals
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
Because we can't build on docs.rs, the cargo doc output for skia-safe is manually created and uploaded to rust-skia.github.io.
We (slowly) add more documentation by converting Skia's Doxygen comments to Rust.
Crate
A prerelease crate is available from crates.io and adding
[dependencies]
skia-safe = "0"
to your Cargo.toml should get you started.
On Linux you may run into trouble when OpenSSL libraries are missing. On Debian and Ubuntu they can be installed with:
sudo apt-get install pkg-config libssl-dev
For other platforms, more information is available at the OpenSSL 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's build.rs tries to download prebuilt binaries from the skia-binaries repository.
| Platform | Binaries |
|---|---|
| Windows | x86_64-pc-windows-msvc |
| Linux Ubuntu 16+ CentOS 7, 8 |
x86_64-unknown-linux-gnu |
| macOS | x86_64-apple-darwin |
| Android | aarch64-linux-androidx86_64-linux-android |
| iOS | aarch64-apple-iosx86_64-apple-ios |
| WebAssembly | wasm32-unknown-emscripten |
Wrappers & 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.rs will try to build Skia and generate the Rust bindings.
To prepare for that, LLVM and Python 3 are needed:
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.
On macOS
-
Install the Command Line Tools for Xcode with
xcode-select --installor download and install the Command Line Tools for Xcode.
-
macOS Mojave only: install the SDK headers:
sudo open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkgIf not installed, the Skia build may fail to build
SkJpegUtility.cppand the binding generation will fail with'TargetConditionals.h' file not found. Also note that the Command Line Tools and SDK headers should be reinstalled after an update of XCode. -
As an alternative to Apple's XCode LLVM, install LLVM via
brew install llvmorbrew install llvmand then setPATH,CPPFLAGS, andLDFLAGSlike 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\. -
- Install Python 3 with
pacman -S python.
- Install Python 3 with
-
Windows Shell (
Cmd.exe):- Download and install Python 3 from python.org.
-
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 like
libgl1-mesa-dev. - For X11, build with feature
x11. - For Wayland, install
libwayland-devand build with thewaylandfeature.
CentOS 7
-
Install the following packages:
sudo yum install gcc openssl-devel libX11-devel python3 fontconfig-devel mesa-libGL-devel
CentOS 8
-
Install the following packages:
sudo yum install gcc openssl-devel libX11-devel python3 clang fontconfig-devel mesa-libGL-devel -
Set
/usr/bin/python3as the defaultpythoncommand:sudo alternatives --set python /usr/bin/python3
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):
For example, to compile for aarch64:
- Install the rust target:
rustup target install aarch64-linux-android - Download the r21e NDK for your host architecture and unzip it.
- Compile your package for the
aarch64-linux-androidtarget:
On macOS:
export ANDROID_NDK=:path-to-android-ndk-r21e
export PATH=$PATH:$ANDROID_NDK/toolchains/llvm/prebuilt/darwin-x86_64/bin
export CC_aarch64_linux_android=aarch64-linux-android26-clang
export CXX_aarch64_linux_android=aarch64-linux-android26-clang++
export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android26-clang
cargo build -vv --target aarch64-linux-android
Note: we don't support Apple's Clang 11 to build for Android on macOS, so you need to install LLVM and set the PATH like instructed.
On Linux:
export ANDROID_NDK=:path-to-android-ndk-r21e
export PATH=$PATH:$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/bin
export CC_aarch64_linux_android=aarch64-linux-android26-clang
export CXX_aarch64_linux_android=aarch64-linux-android26-clang++
export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android26-clang
cargo build -vv --target aarch64-linux-android
On Windows the Android NDK clang executable must be invoked through .cmd scripts:
export ANDROID_NDK=:path-to-android-ndk-r21e
export PATH=$PATH:$ANDROID_NDK/toolchains/llvm/prebuilt/windows-x86_64/bin
export CC_aarch64_linux_android=aarch64-linux-android26-clang.cmd
export CXX_aarch64_linux_android=aarch64-linux-android26-clang++.cmd
export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android26-clang.cmd
cargo build -vv --target aarch64-linux-android
Notes:
- The
CARGO_TARGET_${TARGET}_LINKERenvironment variable name needs 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 the
ANDROID_NDKvariable must be defined before it's used in thePATHvariable. - Rebuilding skia-bindings with a different target may cause linker errors, in that case
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 WebAssembly
Install emscripten version 3.1.1 or superior. In the examples below, we assume
emsdk version 3.1.1 was installed with asdf.
Build with the wasm32-unknown-emscripten target (wasm32-unknown-unknown is
unsupported because it is fundamentally incompatible with linking C code:
export EMSDK=~/.asdf/installs/emsdk/3.1.1
export EMCC_CFLAGS="-s ERROR_ON_UNDEFINED_SYMBOLS=0"
cargo build --target wasm32-unknown-emscripten
The EMSDK environment variable must be set to the root of your emscripten SDK.
In EMCC_CFLAGS, -s ERROR_ON_UNDEFINED_SYMBOLS is a
workaround to build with
emscripten > 2.0.9.
If you want to enable WebGL, you will also have to set MAX_WEBGL_VERSION=2:
export EMSDK=~/.asdf/installs/emsdk/3.1.1
export EMCC_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 of ar so you will have to install the GNU version from homebrew:
brew install binutils
Then prepend binutils path for the build. The path depends on your CPU
architecture, and can be retrieved with brew info binutils. Here is an
example for Apple silicon:
export EMSDK=~/.asdf/installs/emsdk/3.1.1
export EMCC_CFLAGS="-s ERROR_ON_UNDEFINED_SYMBOLS=0"
export PATH="/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 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 and get to the point where cargo build is sufficient to build the bindings including Skia, and if that is not possible, clearly prompts to what's missing.
Example Applications
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.
skia-org
The other examples are taken from Skia's website and ported to the Rust API.
cargo run -- [OUTPUT_DIR]
to generate some Skia drawn PNG images in the directory OUTPUT_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 feature x11 needs to be enabled:
cargo run --example gl-window --features gl,x11
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 like to help making 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
- 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 by Jitter)
added build support for the
wasm32-unknown-emscriptentarget. - Osei Fortune (@triniwiz) contributed rendering SVG files.
Maintainers
- LongYinan (@Brooooooklyn)
- Armin (@pragmatrix)
License
MIT