1#!/bin/bash
2# Copyright 2020 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 -DSK_DISABLE_TRACING"
30EXTRA_CFLAGS="\"-DSK_RELEASE\", \"-DSK_DISABLE_TRACING\""
31IS_OFFICIAL_BUILD="true"
32
33if [[ $@ == *full-build* ]]; then
34  # Full Skottie with all bells and whistles.
35  BUILD_TYPE="full"
36  BUILD_CFG="\
37    skia_enable_fontmgr_custom_embedded=true \
38    skia_enable_fontmgr_custom_empty=false \
39    skia_use_freetype=true \
40    skia_use_libgifcodec=true \
41    skia_use_harfbuzz=true \
42    skia_use_icu=true \
43    skia_use_libpng_decode=true \
44    skia_use_wuffs=true \
45    skia_use_zlib=true \
46    \
47    skia_use_system_freetype2=false \
48    skia_use_system_harfbuzz=false \
49    skia_use_system_icu=false \
50    skia_use_system_libpng=false \
51    skia_use_system_zlib=false\
52  "
53else
54  # Smallest usable Skottie.
55  BUILD_TYPE="minimal"
56  BUILD_CFG="\
57    skia_enable_fontmgr_custom_embedded=false \
58    skia_enable_fontmgr_custom_empty=true \
59    skia_use_freetype=false \
60    skia_use_libgifcodec=false \
61    skia_use_harfbuzz=false \
62    skia_use_icu=false \
63    skia_use_libpng_decode=false \
64    skia_use_wuffs=false \
65    skia_use_zlib=false \
66  "
67fi
68
69if [[ $@ == *debug* ]]; then
70  echo "Building a *${BUILD_TYPE}* Debug build"
71  EXTRA_CFLAGS="\"-DSK_DEBUG\""
72  RELEASE_CONF="-O0 --js-opts 0 -s DEMANGLE_SUPPORT=1 -s ASSERTIONS=1 -s GL_ASSERTIONS=1 -g4 \
73                --source-map-base /bin/ -DSK_DEBUG --pre-js $BASE_DIR/debug.js"
74  BUILD_DIR=${BUILD_DIR:="out/skottiekit_debug"}
75elif [[ $@ == *profiling* ]]; then
76  echo "Building a *${BUILD_TYPE}* build for profiling"
77  RELEASE_CONF+=" --profiling-funcs --closure 0"
78  BUILD_DIR=${BUILD_DIR:="out/skottiekit_profile"}
79else
80  BUILD_DIR=${BUILD_DIR:="out/skottiekit"}
81fi
82
83mkdir -p $BUILD_DIR
84# sometimes the .a files keep old symbols around - cleaning them out makes sure
85# we get a fresh build.
86rm -f $BUILD_DIR/*.a
87
88GN_GPU="skia_enable_gpu=true skia_gl_standard = \"webgl\""
89GN_GPU_FLAGS="\"-DSK_DISABLE_LEGACY_SHADERCONTEXT\","
90WASM_GPU="-lEGL -lGL -lGLESv2 -DSK_SUPPORT_GPU=1 -DSK_GL \
91          -DSK_DISABLE_LEGACY_SHADERCONTEXT --pre-js $BASE_DIR/cpu.js --pre-js $BASE_DIR/gpu.js\
92          -s USE_WEBGL2=1"
93if [[ $@ == *cpu* ]]; then
94  echo "Using the CPU backend instead of the GPU backend"
95  GN_GPU="skia_enable_gpu=false"
96  GN_GPU_FLAGS=""
97  WASM_GPU="-DSK_SUPPORT_GPU=0 --pre-js $BASE_DIR/cpu.js -s USE_WEBGL2=0"
98fi
99
100SKOTTIE_LIB="$BUILD_DIR/libskottie.a \
101             $BUILD_DIR/libsksg.a"
102
103
104MANAGED_SKOTTIE_BINDINGS="\
105  -DSK_INCLUDE_MANAGED_SKOTTIE=1 \
106  modules/skottie/utils/SkottieUtils.cpp"
107if [[ $@ == *no_managed_skottie* ]]; then
108  echo "Omitting managed Skottie"
109  MANAGED_SKOTTIE_BINDINGS="-DSK_INCLUDE_MANAGED_SKOTTIE=0"
110fi
111
112# Turn off exiting while we check for ninja (which may not be on PATH)
113set +e
114NINJA=`which ninja`
115if [[ -z $NINJA ]]; then
116  git clone "https://chromium.googlesource.com/chromium/tools/depot_tools.git" --depth 1 $BUILD_DIR/depot_tools
117  NINJA=$BUILD_DIR/depot_tools/ninja
118fi
119# Re-enable error checking
120set -e
121
122./bin/fetch-gn
123
124echo "Compiling bitcode"
125
126# Inspired by https://github.com/Zubnix/skia-wasm-port/blob/master/build_bindings.sh
127./bin/gn gen ${BUILD_DIR} \
128  --args="cc=\"${EMCC}\" \
129  cxx=\"${EMCXX}\" \
130  ar=\"${EMAR}\" \
131  extra_cflags_cc=[\"-frtti\"] \
132  extra_cflags=[\"-s\", \"WARN_UNALIGNED=1\", \"-s\", \"MAIN_MODULE=1\",
133    \"-DSKNX_NO_SIMD\", \"-DSK_DISABLE_AAA\",
134    \"-DSK_DISABLE_EFFECT_DESERIALIZATION\",
135    \"-DSK_FORCE_8_BYTE_ALIGNMENT\",
136    ${GN_GPU_FLAGS}
137    ${EXTRA_CFLAGS}
138  ] \
139  is_debug=false \
140  is_official_build=${IS_OFFICIAL_BUILD} \
141  is_component_build=false \
142  werror=true \
143  target_cpu=\"wasm\" \
144  \
145  ${BUILD_CFG} \
146  skia_use_angle=false \
147  skia_use_dng_sdk=false \
148  skia_use_egl=true \
149  skia_use_expat=false \
150  skia_use_fontconfig=false \
151  skia_use_libheif=false \
152  skia_use_libjpeg_turbo_decode=true \
153  skia_use_libjpeg_turbo_encode=false \
154  skia_use_libpng_encode=false \
155  skia_use_libwebp_decode=false \
156  skia_use_libwebp_encode=false \
157  skia_use_lua=false \
158  skia_use_piex=false \
159  skia_use_system_libjpeg_turbo=false \
160  skia_use_vulkan=false \
161  skia_enable_fontmgr_custom_directory=false \
162  \
163  ${GN_GPU} \
164  \
165  skia_enable_skshaper=true \
166  skia_enable_ccpr=false \
167  skia_enable_nga=false \
168  skia_enable_pdf=false"
169
170# Build all the libs we will need below
171
172${NINJA} -C ${BUILD_DIR} libskia.a libskottie.a libsksg.a libskshaper.a
173
174export EMCC_CLOSURE_ARGS="--externs $BASE_DIR/externs.js "
175
176echo "Generating final wasm"
177
178# Emscripten prefers that the .a files go last in order, otherwise, it
179# may drop symbols that it incorrectly thinks aren't used. One day,
180# Emscripten will use LLD, which may relax this requirement.
181${EMCXX} \
182    -I. \
183    $RELEASE_CONF \
184    -DSK_DISABLE_AAA \
185    -DSK_FORCE_8_BYTE_ALIGNMENT \
186    $WASM_GPU \
187    -std=c++17 \
188    --bind \
189    --no-entry \
190    --pre-js $BASE_DIR/preamble.js \
191    --pre-js $BASE_DIR/helper.js \
192    --pre-js $BASE_DIR/interface.js \
193    --pre-js $BASE_DIR/postamble.js \
194    $BASE_DIR/skottiekit_bindings.cpp \
195    modules/skresources/src/SkResources.cpp \
196    $MANAGED_SKOTTIE_BINDINGS \
197    $BUILD_DIR/libskottie.a \
198    $BUILD_DIR/libsksg.a \
199    $BUILD_DIR/libskshaper.a \
200    $BUILD_DIR/libskia.a \
201    -s ALLOW_MEMORY_GROWTH=1 \
202    -s EXPORT_NAME="SkottieKitInit" \
203    -s FORCE_FILESYSTEM=0 \
204    -s FILESYSTEM=0 \
205    -s MODULARIZE=1 \
206    -s NO_EXIT_RUNTIME=1 \
207    -s STRICT=1 \
208    -s INITIAL_MEMORY=128MB \
209    -s WARN_UNALIGNED=1 \
210    -s WASM=1 \
211    -o $BUILD_DIR/skottiekit.js
212