1#!/bin/bash 2# Copyright 2018 Google LLC 3# 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7set -ex 8 9BASE_DIR=`cd $(dirname ${BASH_SOURCE[0]}) && pwd` 10# This expects the environment variable EMSDK to be set 11if [[ ! -d $EMSDK ]]; then 12 cat >&2 << "EOF" 13Be sure to set the EMSDK environment variable to the location of Emscripten SDK: 14 15 https://emscripten.org/docs/getting_started/downloads.html 16EOF 17 exit 1 18fi 19 20# Navigate to SKIA_HOME from where this file is located. 21pushd $BASE_DIR/../.. 22 23source $EMSDK/emsdk_env.sh 24EMCC=`which emcc` 25EMCXX=`which em++` 26EMAR=`which emar` 27 28RELEASE_CONF="-Oz --closure 1 --llvm-lto 1 -DSK_RELEASE --pre-js $BASE_DIR/release.js \ 29 -DGR_GL_CHECK_ALLOC_WITH_GET_ERROR=0" 30EXTRA_CFLAGS="\"-DSK_RELEASE\", \"-DGR_GL_CHECK_ALLOC_WITH_GET_ERROR=0\"," 31 32# Tracing will be disabled in release/profiling unless this flag is seen. Tracing will 33# be on debug builds always. 34if [[ $@ != *force_tracing* ]] ; then 35 RELEASE_CONF+=" -DSK_DISABLE_TRACING" 36 EXTRA_CFLAGS+="\"-DSK_DISABLE_TRACING\"," 37fi 38 39if [[ $@ == *debug* ]]; then 40 echo "Building a Debug build" 41 EXTRA_CFLAGS="\"-DSK_DEBUG\"" 42 RELEASE_CONF="-O0 --js-opts 0 -s DEMANGLE_SUPPORT=1 -s ASSERTIONS=1 -s GL_ASSERTIONS=1 -g4 \ 43 --source-map-base /node_modules/canvaskit/bin/ -DSK_DEBUG --pre-js $BASE_DIR/debug.js" 44 BUILD_DIR=${BUILD_DIR:="out/canvaskit_wasm_debug"} 45elif [[ $@ == *profiling* ]]; then 46 echo "Building a build for profiling" 47 RELEASE_CONF+=" --profiling-funcs --closure 0" 48 BUILD_DIR=${BUILD_DIR:="out/canvaskit_wasm_profile"} 49else 50 BUILD_DIR=${BUILD_DIR:="out/canvaskit_wasm"} 51fi 52 53mkdir -p $BUILD_DIR 54# sometimes the .a files keep old symbols around - cleaning them out makes sure 55# we get a fresh build. 56rm -f $BUILD_DIR/*.a 57 58GN_GPU="skia_enable_gpu=true skia_gl_standard = \"webgl\"" 59GN_GPU_FLAGS="\"-DSK_DISABLE_LEGACY_SHADERCONTEXT\"," 60WASM_GPU="-lEGL -lGLESv2 -DSK_SUPPORT_GPU=1 \ 61 -DSK_DISABLE_LEGACY_SHADERCONTEXT --pre-js $BASE_DIR/cpu.js --pre-js $BASE_DIR/gpu.js\ 62 -s USE_WEBGL2=1" 63if [[ $@ == *cpu* ]]; then 64 echo "Using the CPU backend instead of the GPU backend" 65 GN_GPU="skia_enable_gpu=false" 66 GN_GPU_FLAGS="" 67 WASM_GPU="-DSK_SUPPORT_GPU=0 --pre-js $BASE_DIR/cpu.js -s USE_WEBGL2=0" 68fi 69 70SKP_JS="--pre-js $BASE_DIR/skp.js" 71GN_SKP_FLAGS="" 72WASM_SKP="-DSK_SERIALIZE_SKP" 73if [[ $@ == *no_skp* ]]; then 74 GN_SKP_FLAGS="\"-DSK_DISABLE_READBUFFER\"," 75 WASM_SKP="-DSK_DISABLE_READBUFFER" 76 SKP_JS="" 77fi 78 79SKOTTIE_JS="--pre-js $BASE_DIR/skottie.js" 80SKOTTIE_BINDINGS="$BASE_DIR/skottie_bindings.cpp" 81 82SKOTTIE_LIB="$BUILD_DIR/libskottie.a \ 83 $BUILD_DIR/libsksg.a" 84 85if [[ $@ == *no_skottie* ]]; then 86 echo "Omitting Skottie" 87 SKOTTIE_JS="" 88 SKOTTIE_LIB="" 89 SKOTTIE_BINDINGS="" 90fi 91 92MANAGED_SKOTTIE_BINDINGS="\ 93 -DSK_INCLUDE_MANAGED_SKOTTIE=1 \ 94 modules/skottie/utils/SkottieUtils.cpp" 95if [[ $@ == *no_managed_skottie* || $@ == *no_skottie* ]]; then 96 echo "Omitting managed Skottie" 97 MANAGED_SKOTTIE_BINDINGS="-DSK_INCLUDE_MANAGED_SKOTTIE=0" 98fi 99 100GN_PARTICLES="skia_enable_sksl_interpreter=true" 101PARTICLES_JS="--pre-js $BASE_DIR/particles.js" 102PARTICLES_BINDINGS="$BASE_DIR/particles_bindings.cpp" 103PARTICLES_LIB="$BUILD_DIR/libparticles.a" 104 105if [[ $@ == *no_particles* ]]; then 106 echo "Omitting Particles" 107 GN_PARTICLES="skia_enable_sksl_interpreter=false" 108 PARTICLES_JS="" 109 PARTICLES_BINDINGS="" 110 PARTICLES_LIB="" 111fi 112 113if [[ $@ != *no_particles* || $@ != *no_skottie* ]] ; then 114 PARTICLES_BINDINGS+=" modules/skresources/src/SkResources.cpp" 115fi 116 117WASM_PATHOPS="-DSK_INCLUDE_PATHOPS" 118PATHOPS_JS="--pre-js $BASE_DIR/pathops.js" 119if [[ $@ == *no_pathops* ]] ; then 120 WASM_PATHOPS="" 121 PATHOPS_JS="" 122fi 123 124WASM_RT_SHADER="-DSK_INCLUDE_RUNTIME_EFFECT" 125RT_SHADER_JS="--pre-js $BASE_DIR/rt_shader.js" 126if [[ $@ == *no_rt_shader* ]] ; then 127 WASM_RT_SHADER="" 128 RT_SHADER_JS="" 129fi 130 131HTML_CANVAS_API="--pre-js $BASE_DIR/htmlcanvas/preamble.js \ 132--pre-js $BASE_DIR/htmlcanvas/util.js \ 133--pre-js $BASE_DIR/htmlcanvas/color.js \ 134--pre-js $BASE_DIR/htmlcanvas/font.js \ 135--pre-js $BASE_DIR/htmlcanvas/canvas2dcontext.js \ 136--pre-js $BASE_DIR/htmlcanvas/htmlcanvas.js \ 137--pre-js $BASE_DIR/htmlcanvas/imagedata.js \ 138--pre-js $BASE_DIR/htmlcanvas/lineargradient.js \ 139--pre-js $BASE_DIR/htmlcanvas/path2d.js \ 140--pre-js $BASE_DIR/htmlcanvas/pattern.js \ 141--pre-js $BASE_DIR/htmlcanvas/radialgradient.js \ 142--pre-js $BASE_DIR/htmlcanvas/postamble.js " 143if [[ $@ == *no_canvas* ]]; then 144 echo "Omitting bindings for HTML Canvas API" 145 HTML_CANVAS_API="" 146fi 147 148GN_FONT="skia_enable_fontmgr_empty=false skia_enable_fontmgr_custom_empty=false" 149FONT_CFLAGS="" 150BUILTIN_FONT="$BASE_DIR/fonts/NotoMono-Regular.ttf.cpp" 151FONT_JS="--pre-js $BASE_DIR/font.js" 152if [[ $@ == *no_font* ]]; then 153 echo "Omitting the built-in font(s), font manager and all code dealing with fonts" 154 BUILTIN_FONT="" 155 FONT_CFLAGS="-DSK_NO_FONTS" 156 FONT_JS="" 157 GN_FONT="skia_enable_fontmgr_empty=true skia_enable_fontmgr_custom_empty=false" 158elif [[ $@ == *no_embedded_font* ]]; then 159 echo "Omitting the built-in font(s)" 160 BUILTIN_FONT="" 161 GN_FONT="skia_enable_fontmgr_empty=false skia_enable_fontmgr_custom_empty=true" 162else 163 # Generate the font's binary file (which is covered by .gitignore) 164 python tools/embed_resources.py \ 165 --name SK_EMBEDDED_FONTS \ 166 --input $BASE_DIR/fonts/NotoMono-Regular.ttf \ 167 --output $BASE_DIR/fonts/NotoMono-Regular.ttf.cpp \ 168 --align 4 169fi 170 171GN_SHAPER="skia_use_icu=true skia_use_system_icu=false skia_use_harfbuzz=true skia_use_system_harfbuzz=false" 172SHAPER_LIB="$BUILD_DIR/libharfbuzz.a \ 173 $BUILD_DIR/libicu.a" 174SHAPER_TARGETS="libharfbuzz.a libicu.a" 175if [[ $@ == *primitive_shaper* ]] || [[ $@ == *no_font* ]]; then 176 echo "Using the primitive shaper instead of the harfbuzz/icu one" 177 GN_SHAPER="skia_use_icu=false skia_use_harfbuzz=false" 178 SHAPER_LIB="" 179 SHAPER_TARGETS="" 180fi 181 182PARAGRAPH_JS="--pre-js $BASE_DIR/paragraph.js" 183PARAGRAPH_LIB="$BUILD_DIR/libskparagraph.a" 184PARAGRAPH_BINDINGS="-DSK_INCLUDE_PARAGRAPH=1 \ 185 $BASE_DIR/paragraph_bindings.cpp" 186 187if [[ $@ == *no_paragraph* ]] || [[ $@ == *primitive_shaper* ]] || [[ $@ == *no_font* ]]; then 188 echo "Omitting paragraph (must have fonts and non-primitive shaper)" 189 PARAGRAPH_JS="" 190 PARAGRAPH_LIB="" 191 PARAGRAPH_BINDINGS="" 192fi 193 194 195# Turn off exiting while we check for ninja (which may not be on PATH) 196set +e 197NINJA=`which ninja` 198if [[ -z $NINJA ]]; then 199 git clone "https://chromium.googlesource.com/chromium/tools/depot_tools.git" --depth 1 $BUILD_DIR/depot_tools 200 NINJA=$BUILD_DIR/depot_tools/ninja 201fi 202# Re-enable error checking 203set -e 204 205./bin/fetch-gn 206 207echo "Compiling bitcode" 208 209# Inspired by https://github.com/Zubnix/skia-wasm-port/blob/master/build_bindings.sh 210./bin/gn gen ${BUILD_DIR} \ 211 --args="cc=\"${EMCC}\" \ 212 cxx=\"${EMCXX}\" \ 213 ar=\"${EMAR}\" \ 214 extra_cflags_cc=[\"-frtti\"] \ 215 extra_cflags=[\"-s\", \"WARN_UNALIGNED=1\", \"-s\", \"MAIN_MODULE=1\", 216 \"-DSKNX_NO_SIMD\", \"-DSK_DISABLE_AAA\", 217 \"-DSK_DISABLE_EFFECT_DESERIALIZATION\", 218 \"-DSK_FORCE_8_BYTE_ALIGNMENT\", 219 ${GN_GPU_FLAGS} 220 ${GN_SKP_FLAGS} 221 ${EXTRA_CFLAGS} 222 ] \ 223 is_debug=false \ 224 is_official_build=true \ 225 is_component_build=false \ 226 werror=true \ 227 target_cpu=\"wasm\" \ 228 \ 229 skia_use_angle=false \ 230 skia_use_dng_sdk=false \ 231 skia_use_egl=true \ 232 skia_use_expat=false \ 233 skia_use_fontconfig=false \ 234 skia_use_freetype=true \ 235 skia_use_libheif=false \ 236 skia_use_libjpeg_turbo=true \ 237 skia_use_libpng=true \ 238 skia_use_libwebp=true \ 239 skia_use_lua=false \ 240 skia_use_piex=false \ 241 skia_use_system_freetype2=false \ 242 skia_use_system_libjpeg_turbo=false \ 243 skia_use_system_libpng=false \ 244 skia_use_system_libwebp=false \ 245 skia_use_system_zlib=false\ 246 skia_use_vulkan=false \ 247 skia_use_wuffs=true \ 248 skia_use_zlib=true \ 249 \ 250 ${GN_SHAPER} \ 251 ${GN_GPU} \ 252 ${GN_FONT} \ 253 ${GN_PARTICLES} \ 254 \ 255 skia_enable_skshaper=true \ 256 skia_enable_ccpr=false \ 257 skia_enable_nvpr=false \ 258 skia_enable_skparagraph=true \ 259 skia_enable_pdf=false" 260 261# Build all the libs, we'll link the appropriate ones down below 262${NINJA} -C ${BUILD_DIR} libskia.a libskottie.a libsksg.a \ 263 libskparagraph.a libskshaper.a libparticles.a $SHAPER_TARGETS 264 265export EMCC_CLOSURE_ARGS="--externs $BASE_DIR/externs.js " 266 267echo "Generating final wasm" 268 269# Emscripten prefers that the .a files go last in order, otherwise, it 270# may drop symbols that it incorrectly thinks aren't used. One day, 271# Emscripten will use LLD, which may relax this requirement. 272${EMCXX} \ 273 $RELEASE_CONF \ 274 -I. \ 275 -Ithird_party/icu \ 276 -Ithird_party/skcms \ 277 -Ithird_party/externals/icu/source/common/ \ 278 -DSK_DISABLE_AAA \ 279 -DSK_FORCE_8_BYTE_ALIGNMENT \ 280 $WASM_GPU \ 281 $WASM_PATHOPS \ 282 $WASM_RT_SHADER \ 283 $WASM_SKP \ 284 $FONT_CFLAGS \ 285 -std=c++17 \ 286 --bind \ 287 --pre-js $BASE_DIR/preamble.js \ 288 --pre-js $BASE_DIR/helper.js \ 289 --pre-js $BASE_DIR/interface.js \ 290 $PARAGRAPH_JS \ 291 $SKOTTIE_JS \ 292 $PARTICLES_JS \ 293 $PATHOPS_JS \ 294 $FONT_JS \ 295 $SKP_JS \ 296 $RT_SHADER_JS \ 297 $HTML_CANVAS_API \ 298 --pre-js $BASE_DIR/postamble.js \ 299 --post-js $BASE_DIR/ready.js \ 300 $BASE_DIR/canvaskit_bindings.cpp \ 301 $PARTICLES_BINDINGS \ 302 $SKOTTIE_BINDINGS \ 303 $MANAGED_SKOTTIE_BINDINGS \ 304 $PARAGRAPH_BINDINGS \ 305 $SKOTTIE_LIB \ 306 $PARTICLES_LIB \ 307 $PARAGRAPH_LIB \ 308 $BUILD_DIR/libskshaper.a \ 309 $SHAPER_LIB \ 310 $BUILD_DIR/libskia.a \ 311 $BUILTIN_FONT \ 312 -s ALLOW_MEMORY_GROWTH=1 \ 313 -s EXPORT_NAME="CanvasKitInit" \ 314 -s FORCE_FILESYSTEM=0 \ 315 -s FILESYSTEM=0 \ 316 -s MODULARIZE=1 \ 317 -s NO_EXIT_RUNTIME=1 \ 318 -s STRICT=1 \ 319 -s TOTAL_MEMORY=128MB \ 320 -s WARN_UNALIGNED=1 \ 321 -s WASM=1 \ 322 -o $BUILD_DIR/canvaskit.js 323