1--- 2title: 'How to build Skia' 3linkTitle: 'How to build Skia' 4 5weight: 20 6--- 7 8Make sure you have first followed the 9[instructions to download Skia](../download). 10 11Skia uses [GN](https://chromium.googlesource.com/chromium/src/tools/gn/) to 12configure its builds. 13 14## `is_official_build` and Third-party Dependencies 15 16Most users of Skia should set `is_official_build=true`, and most developers 17should leave it to its `false` default. 18 19This mode configures Skia in a way that's suitable to ship: an optimized build 20with no debug symbols, dynamically linked against its third-party dependencies 21using the ordinary library search path. 22 23In contrast, the developer-oriented default is an unoptimized build with full 24debug symbols and all third-party dependencies built from source and embedded 25into libskia. This is how we do all our manual and automated testing. 26 27Skia offers several features that make use of third-party libraries, like 28libpng, libwebp, or libjpeg-turbo to decode images, or ICU and sftnly to subset 29fonts. All these third-party dependencies are optional and can be controlled by 30a GN argument that looks something like `skia_use_foo` for appropriate `foo`. 31 32If `skia_use_foo` is enabled, enabling `skia_use_system_foo` will build and link 33Skia against the headers and libraries found on the system paths. 34`is_official_build=true` enables all `skia_use_system_foo` by default. You can 35use `extra_cflags` and `extra_ldflags` to add include or library paths if 36needed. 37 38## Supported and Preferred Compilers 39 40While Skia should compile with GCC, MSVC, and other compilers, a number of 41routines in Skia's software backend have been written to run fastest when 42compiled with Clang. If you depend on software rasterization, image decoding, or 43color space conversion and compile Skia with a compiler other than Clang, you 44will see dramatically worse performance. This choice was only a matter of 45prioritization; there is nothing fundamentally wrong with non-Clang compilers. 46So if this is a serious issue for you, please let us know on the mailing list. 47 48Skia makes use of C++17 language features (compiles with `-std=c++17` flag) and 49thus requires a C++17 compatible compiler. Clang 5 and later implement all of 50the features of the c++17 standard. Older compilers that lack C++17 support may 51produce non-obvious compilation errors. You can configure your build to use 52specific executables for `cc` and `cxx` invocations using e.g. 53`--args='cc="clang" cxx="clang++"'` GN build arguments, as illustrated in 54[Quickstart](#quickstart). This can be useful for building Skia without needing to 55modify your machine's default compiler toolchain. 56 57If you do not specify `cc` and `cxx` in your gn arguments, Skia will default to 58`cc` and `c++`. This is often GCC by default on many platforms, not Clang. 59 60## Quickstart 61 62Run `gn gen` to generate your build files. As arguments to `gn gen`, pass a name 63for your build directory, and optionally `--args=` to configure the build type. 64 65To build Skia as a static library in a build directory named `out/Static`: 66 67``` 68bin/gn gen out/Static --args='is_official_build=true' 69``` 70 71To build Skia as a shared library (DLL) in a build directory named `out/Shared`: 72 73``` 74bin/gn gen out/Shared --args='is_official_build=true is_component_build=true' 75``` 76 77If you find that you don't have `bin/gn`, make sure you've run: 78 79``` 80python3 tools/git-sync-deps 81``` 82 83For a list of available build arguments, take a look at `gn/skia.gni`, or run: 84 85``` 86bin/gn args out/Debug --list 87``` 88 89GN allows multiple build folders to coexist; each build can be configured 90separately as desired. For example: 91 92``` 93bin/gn gen out/Debug 94bin/gn gen out/Release --args='is_debug=false' 95bin/gn gen out/Clang --args='cc="clang" cxx="clang++"' 96bin/gn gen out/Cached --args='cc_wrapper="ccache"' 97bin/gn gen out/RTTI --args='extra_cflags_cc=["-frtti"]' 98``` 99 100Once you have generated your build files, run Ninja to compile and link Skia: 101 102``` 103ninja -C out/Static 104``` 105 106If some header files are missing, install the corresponding dependencies: 107 108``` 109tools/install_dependencies.sh 110``` 111 112To pull new changes and rebuild: 113 114``` 115git pull 116python tools/git-sync-deps 117ninja -C out/Static 118``` 119 120## Android 121 122To build Skia for Android you need an 123[Android NDK](https://developer.android.com/ndk/index.html). 124 125If you do not have an NDK and have access to CIPD, you can use one of these 126commands to fetch the NDK our bots use: 127 128``` 129./bin/fetch-sk 130./bin/sk asset download android_ndk_linux /tmp/ndk # on Linux 131./bin/sk asset download android_ndk_darwin /tmp/ndk # on Mac 132./bin/sk.exe asset download android_ndk_windows C:/ndk # on Windows 133``` 134 135When generating your GN build files, pass the path to your `ndk` and your 136desired `target_cpu`: 137 138``` 139bin/gn gen out/arm --args='ndk="/tmp/ndk" target_cpu="arm"' 140bin/gn gen out/arm64 --args='ndk="/tmp/ndk" target_cpu="arm64"' 141bin/gn gen out/x64 --args='ndk="/tmp/ndk" target_cpu="x64"' 142bin/gn gen out/x86 --args='ndk="/tmp/ndk" target_cpu="x86"' 143``` 144 145Other arguments like `is_debug` and `is_component_build` continue to work. 146Tweaking `ndk_api` gives you access to newer Android features like Vulkan. 147 148To test on an Android device, push the binary and `resources` over, and run it 149as normal. You may find `bin/droid` convenient. 150 151``` 152ninja -C out/arm64 153adb push out/arm64/dm /data/local/tmp 154adb push resources /data/local/tmp 155adb shell "cd /data/local/tmp; ./dm --src gm --config gl" 156``` 157 158## ChromeOS 159 160To cross-compile Skia for arm ChromeOS devices the following is needed: 161 162- Clang 4 or newer 163- An armhf sysroot 164- The (E)GL lib files on the arm chromebook to link against. 165 166To compile Skia for an x86 ChromeOS device, one only needs Clang and the lib 167files. 168 169If you have access to CIPD, you can fetch all of these as follows: 170 171``` 172./bin/sk asset download clang_linux /opt/clang 173./bin/sk asset download armhf_sysroot /opt/armhf_sysroot 174./bin/sk asset download chromebook_arm_gles /opt/chromebook_arm_gles 175./bin/sk asset download chromebook_x86_64_gles /opt/chromebook_x86_64_gles 176``` 177 178If you don't have authorization to use those assets, then see the README.md 179files for 180[armhf_sysroot](https://skia.googlesource.com/skia/+/main/infra/bots/assets/armhf_sysroot/README.md), 181[chromebook_arm_gles](https://skia.googlesource.com/skia/+/main/infra/bots/assets/chromebook_arm_gles/README.md), 182and 183[chromebook_x86_64_gles](https://skia.googlesource.com/skia/+/main/infra/bots/assets/chromebook_x86_64_gles/README.md) 184for instructions on creating those assets. 185 186Once those files are in place, generate the GN args that resemble the following: 187 188``` 189#ARM 190cc= "/opt/clang/bin/clang" 191cxx = "/opt/clang/bin/clang++" 192 193extra_asmflags = [ 194 "--target=armv7a-linux-gnueabihf", 195 "--sysroot=/opt/armhf_sysroot/", 196 "-march=armv7-a", 197 "-mfpu=neon", 198 "-mthumb", 199] 200extra_cflags=[ 201 "--target=armv7a-linux-gnueabihf", 202 "--sysroot=/opt/armhf_sysroot", 203 "-I/opt/chromebook_arm_gles/include", 204 "-I/opt/armhf_sysroot/include/", 205 "-I/opt/armhf_sysroot/include/c++/4.8.4/", 206 "-I/opt/armhf_sysroot/include/c++/4.8.4/arm-linux-gnueabihf/", 207 "-DMESA_EGL_NO_X11_HEADERS", 208 "-funwind-tables", 209] 210extra_ldflags=[ 211 "--sysroot=/opt/armhf_sysroot", 212 "-B/opt/armhf_sysroot/bin", 213 "-B/opt/armhf_sysroot/gcc-cross", 214 "-L/opt/armhf_sysroot/gcc-cross", 215 "-L/opt/armhf_sysroot/lib", 216 "-L/opt/chromebook_arm_gles/lib", 217 "--target=armv7a-linux-gnueabihf", 218] 219target_cpu="arm" 220skia_use_fontconfig = false 221skia_use_system_freetype2 = false 222skia_use_egl = true 223 224 225# x86_64 226cc= "/opt/clang/bin/clang" 227cxx = "/opt/clang/bin/clang++" 228extra_cflags=[ 229 "-I/opt/clang/include/c++/v1/", 230 "-I/opt/chromebook_x86_64_gles/include", 231 "-DMESA_EGL_NO_X11_HEADERS", 232 "-DEGL_NO_IMAGE_EXTERNAL", 233] 234extra_ldflags=[ 235 "-stdlib=libc++", 236 "-fuse-ld=lld", 237 "-L/opt/chromebook_x86_64_gles/lib", 238] 239target_cpu="x64" 240skia_use_fontconfig = false 241skia_use_system_freetype2 = false 242skia_use_egl = true 243``` 244 245Compile dm (or another executable of your choice) with ninja, as per usual. 246 247Push the binary to a chromebook via ssh and 248[run dm as normal](/docs/dev/testing/tests) using the gles GPU config. 249 250Most chromebooks by default have their home directory partition marked as 251noexec. To avoid "permission denied" errors, remember to run something like: 252 253``` 254sudo mount -i -o remount,exec /home/chronos 255``` 256 257## Mac 258 259Mac users may want to pass `--ide=xcode` to `bin/gn gen` to generate an Xcode 260project. 261 262Mac GN builds assume an Intel CPU by default. If you are building for Apple 263Silicon (M1 and newer) instead, add a gn arg to set `target_cpu="arm64"`: 264 265``` 266bin/gn gen out/AppleSilicon --args='target_cpu="arm64"' 267``` 268 269Googlers should see [go/skia-corp-xcode](http://go/skia-corp-xcode) for 270instructions on setting up Xcode on a corp machine. 271 272### Python 273 274The version of Python supplied by Apple is a few versions out of date, 275and it is known to interact poorly with our build system. We recommend 276installing the latest official version of Python from 277https://www.python.org/downloads/. Then run 278"Applications/Python 3.11/Install Certificates.command". 279 280## iOS 281 282Run GN to generate your build files. Set `target_os="ios"` to build for iOS. 283This defaults to `target_cpu="arm64"`. To use the iOS simulator, set 284`ios_use_simulator=true` and set `target_cpu` to your Mac's architecture. 285On an Intel Mac, setting `target_cpu="x64"` alone will also target the iOS 286simulator. 287 288``` 289bin/gn gen out/ios64 --args='target_os="ios"' 290bin/gn gen out/ios32 --args='target_os="ios" target_cpu="arm"' 291bin/gn gen out/iossim-apple --args='target_os="ios" target_cpu="arm64" ios_use_simulator=true' 292bin/gn gen out/iossim-intel --args='target_os="ios" target_cpu="x64"' 293``` 294 295By default this will also package (and for non-simulator devices, sign) iOS test binaries. 296If you wish to skip signing (for testing compilation alone, for example), you can disable it by 297setting `skia_ios_use_signing` to `false`. 298 299When signing, the build defaults to a Google signing identity and provisioning profile. 300To use a different one 301set the GN args `skia_ios_identity` to match your code signing identity and 302`skia_ios_profile` to the name of your provisioning profile, e.g. 303 304``` 305skia_ios_identity=".*Jane Doe.*" 306skia_ios_profile="iPad Profile"` 307``` 308 309A list of identities can be found by typing `security find-identity` on the 310command line. The name of the provisioning profile should be available on the 311Apple Developer site. Alternatively, you can examine the installed provisioning profile files in the Finder 312by going to `~/Library/MobileDevice/Provisioning Profiles`, selecting a `.mobileprovision` file, 313and hitting space. The value of `skia_ios_profile` can either be the string 314given at the top of that file or on the Developer site, or the absolute path 315to the file. 316 317If you find yourself missing a Google signing identity or provisioning profile, 318you'll want to have a read through go/appledev. 319 320For signed packages `ios-deploy` makes installing and running them on a device 321easy: 322 323``` 324ios-deploy -b out/Debug/dm.app -d --args "--match foo" 325``` 326 327If you wish to deploy through Xcode you can generate a project by passing `--ide=xcode` to 328`bin/gn gen`. If you are using Xcode version 10 or later, you may need to go to 329`Project Settings...` and verify that `Build System:` is set to 330`Legacy Build System`. 331 332Deploying to a device with an OS older than the current SDK can be done by 333setting the `ios_min_target` arg: 334 335``` 336ios_min_target = "<major>.<minor>" 337``` 338 339where `<major>.<minor>` is the iOS version on the device, e.g., 12.0 or 11.4. 340 341## Windows 342 343Skia can build on Windows with Visual Studio 2017 or 2019. If GN is unable to 344locate either of those, it will print an error message. In that case, you can 345pass your `VC` path to GN via `win_vc`. 346 347Skia can be compiled with the free 348[Build Tools for Visual Studio 2017 or 2019](https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2019). 349 350The bots use a packaged 2019 toolchain, which Googlers can download like this: 351 352``` 353./bin/sk.exe asset download win_toolchain C:/toolchain 354``` 355 356You can then pass the VC and SDK paths to GN by setting your GN args: 357 358``` 359win_vc = "C:\toolchain\VC" 360win_sdk = "C:\toolchain\win_sdk" 361``` 362 363This toolchain is the only way we support 32-bit builds, by also setting 364`target_cpu="x86"`. 365 366The Skia build assumes that the PATHEXT environment variable contains ".EXE". 367 368### **Highly Recommended**: Build with clang-cl 369 370Skia uses generated code that is only optimized when Skia is built with clang. 371Other compilers get generic unoptimized code. 372 373Setting the `cc` and `cxx` gn args is _not_ sufficient to build with clang-cl. 374These variables are ignored on Windows. Instead set the variable `clang_win` to 375your LLVM installation directory. If you installed the prebuilt LLVM downloaded 376from [here](https://releases.llvm.org/download.html 'LLVM Download') in the 377default location, that would be: 378 379``` 380clang_win = "C:\Program Files\LLVM" 381``` 382 383Follow the standard Windows path specification and not MinGW convention (e.g. 384`C:\Program Files\LLVM` not ~~`/c/Program Files/LLVM`~~). 385 386If you will be compiling the rest of your program with a compiler other than 387Clang, add this GN argument as well: 388 389``` 390is_trivial_abi = false 391``` 392 393### Visual Studio Solutions 394 395If you use Visual Studio, you may want to pass `--ide=vs` to `bin/gn gen` to 396generate `all.sln`. That solution will exist within the GN directory for the 397specific configuration, and will only build/run that configuration. 398 399If you want a Visual Studio Solution that supports multiple GN configurations, 400there is a helper script. It requires that all of your GN directories be inside 401the `out` directory. First, create all of your GN configurations as usual. Pass 402`--ide=vs` when running `bin/gn gen` for each one. Then: 403 404``` 405python3 gn/gn_meta_sln.py 406``` 407 408This creates a new dedicated output directory and solution file 409`out/sln/skia.sln`. It has one solution configuration for each GN configuration, 410and supports building and running any of them. It also adjusts syntax 411highlighting of inactive code blocks based on preprocessor definitions from the 412selected solution configuration. 413 414## Windows ARM64 415 416There is early, experimental support for 417[Windows 10 on ARM](https://docs.microsoft.com/en-us/windows/arm/). This 418currently requires (a recent version of) MSVC, and the 419`Visual C++ compilers and libraries for ARM64` individual component in the 420Visual Studio Installer. For Googlers, the win_toolchain asset includes the 421ARM64 compiler. 422 423To use that toolchain, set the `target_cpu` GN argument to `"arm64"`. Note that 424OpenGL is not supported by Windows 10 on ARM, so Skia's GL backends are stubbed 425out, and will not work. ANGLE is supported: 426 427``` 428bin/gn gen out/win-arm64 --args='target_cpu="arm64" skia_use_angle=true' 429``` 430 431This will produce a build of Skia that can use the software or ANGLE backends, 432in DM. Viewer only works when launched with `--backend angle`, because the 433software backend tries to use OpenGL to display the window contents. 434 435## CMake 436 437We have added a GN-to-CMake translator mainly for use with IDEs that like CMake 438project descriptions. This is not meant for any purpose beyond development. 439 440``` 441bin/gn gen out/config --ide=json --json-ide-script=../../gn/gn_to_cmake.py 442``` 443