• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 -DSK_RELEASE --pre-js $BASE_DIR/release.js"
29EXTRA_CFLAGS="\"-DSK_RELEASE\","
30IS_OFFICIAL_BUILD="true"
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 -g3 \
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"}
49elif [[ $@ == *simd* ]]; then
50  echo "Building with SIMD operations"
51  BUILD_DIR=${BUILD_DIR:="out/canvaskit_wasm_experimental_simd"}
52else
53  BUILD_DIR=${BUILD_DIR:="out/canvaskit_wasm"}
54fi
55
56if [[ $@ == *simd* ]]; then
57  RELEASE_CONF+=" -msimd128"
58  EXTRA_CFLAGS+="\"-msimd128\","
59fi
60
61mkdir -p $BUILD_DIR
62# sometimes the .a files keep old symbols around - cleaning them out makes sure
63# we get a fresh build.
64rm -f $BUILD_DIR/*.a
65
66GN_GPU="skia_enable_gpu=true skia_gl_standard = \"webgl\""
67GN_GPU_FLAGS="\"-DSK_DISABLE_LEGACY_SHADERCONTEXT\","
68WASM_GPU="-lGL -DSK_SUPPORT_GPU=1 -DSK_GL \
69          -DSK_DISABLE_LEGACY_SHADERCONTEXT --pre-js $BASE_DIR/cpu.js --pre-js $BASE_DIR/gpu.js\
70          -s USE_WEBGL2=1"
71if [[ $@ == *cpu* ]]; then
72  echo "Using the CPU backend instead of the GPU backend"
73  GN_GPU="skia_enable_gpu=false"
74  GN_GPU_FLAGS=""
75  WASM_GPU="-DSK_SUPPORT_GPU=0 -DSK_ENABLE_SKSL --pre-js $BASE_DIR/cpu.js -s USE_WEBGL2=0"
76fi
77
78SKP_JS="--pre-js $BASE_DIR/skp.js"
79GN_SKP_FLAGS=""
80WASM_SKP="-DSK_SERIALIZE_SKP"
81if [[ $@ == *no_skp_serialization* ]]; then
82  # This saves about 20kb compressed.
83  SKP_JS=""
84  WASM_SKP=""
85  GN_SKP_FLAGS="\"-DSK_DISABLE_EFFECT_DESERIALIZATION\","
86fi
87if [[ $@ == *no_effects_deserialization* ]]; then
88  # This saves about 60kb compressed.
89  echo "disabling effects deserialization"
90  GN_SKP_FLAGS="\"-DSK_DISABLE_EFFECT_DESERIALIZATION\","
91fi
92
93SKOTTIE_JS="--pre-js $BASE_DIR/skottie.js"
94SKOTTIE_BINDINGS="$BASE_DIR/skottie_bindings.cpp"
95
96SKOTTIE_LIB="$BUILD_DIR/libskottie.a \
97             $BUILD_DIR/libsksg.a"
98
99if [[ $@ == *no_skottie* ]]; then
100  echo "Omitting Skottie"
101  SKOTTIE_JS=""
102  SKOTTIE_LIB=""
103  SKOTTIE_BINDINGS=""
104fi
105
106GN_VIEWER="skia_use_expat=false"
107VIEWER_BINDINGS=""
108VIEWER_LIB=""
109
110if [[ $@ == *viewer* ]]; then
111  echo "Including viewer"
112  GN_VIEWER="skia_use_expat=true"
113  VIEWER_BINDINGS="$BASE_DIR/viewer_bindings.cpp"
114  VIEWER_LIB="$BUILD_DIR/libviewer_wasm.a"
115  IS_OFFICIAL_BUILD="false"
116fi
117
118MANAGED_SKOTTIE_BINDINGS="\
119  -DSK_INCLUDE_MANAGED_SKOTTIE=1 \
120  modules/skottie/utils/SkottieUtils.cpp"
121if [[ $@ == *no_managed_skottie* || $@ == *no_skottie* ]]; then
122  echo "Omitting managed Skottie"
123  MANAGED_SKOTTIE_BINDINGS="-DSK_INCLUDE_MANAGED_SKOTTIE=0"
124fi
125
126PARTICLES_JS="--pre-js $BASE_DIR/particles.js"
127PARTICLES_BINDINGS="$BASE_DIR/particles_bindings.cpp"
128PARTICLES_LIB="$BUILD_DIR/libparticles.a"
129
130if [[ $@ == *no_particles* ]]; then
131  echo "Omitting Particles"
132  PARTICLES_JS=""
133  PARTICLES_BINDINGS=""
134  PARTICLES_LIB=""
135fi
136
137if [[ $@ != *no_particles* || $@ != *no_skottie* ]] ; then
138  PARTICLES_BINDINGS+=" modules/skresources/src/SkResources.cpp"
139fi
140
141WASM_PATHOPS="-DSK_INCLUDE_PATHOPS"
142PATHOPS_JS="--pre-js $BASE_DIR/pathops.js"
143if [[ $@ == *no_pathops* ]] ; then
144  # This saves about 2kb compressed.
145  WASM_PATHOPS=""
146  PATHOPS_JS=""
147fi
148
149WASM_RT_SHADER="-DSK_INCLUDE_RUNTIME_EFFECT"
150RT_SHADER_JS="--pre-js $BASE_DIR/rt_shader.js"
151if [[ $@ == *no_rt_shader* ]] ; then
152  WASM_RT_SHADER=""
153  RT_SHADER_JS=""
154fi
155
156MATRIX_HELPER_JS="--pre-js $BASE_DIR/matrix.js"
157if [[ $@ == *no_matrix* ]]; then
158  echo "Omitting matrix helper code"
159  MATRIX_HELPER_JS=""
160fi
161
162HTML_CANVAS_API="--pre-js $BASE_DIR/htmlcanvas/preamble.js \
163--pre-js $BASE_DIR/htmlcanvas/util.js \
164--pre-js $BASE_DIR/htmlcanvas/color.js \
165--pre-js $BASE_DIR/htmlcanvas/font.js \
166--pre-js $BASE_DIR/htmlcanvas/canvas2dcontext.js \
167--pre-js $BASE_DIR/htmlcanvas/htmlcanvas.js \
168--pre-js $BASE_DIR/htmlcanvas/imagedata.js \
169--pre-js $BASE_DIR/htmlcanvas/lineargradient.js \
170--pre-js $BASE_DIR/htmlcanvas/path2d.js \
171--pre-js $BASE_DIR/htmlcanvas/pattern.js \
172--pre-js $BASE_DIR/htmlcanvas/radialgradient.js \
173--pre-js $BASE_DIR/htmlcanvas/postamble.js "
174if [[ $@ == *no_canvas* || $@ == *no_matrix* ]]; then
175  # Note: HTML Canvas bindings depend on the matrix helpers.
176  echo "Omitting bindings for HTML Canvas API"
177  HTML_CANVAS_API=""
178fi
179
180GN_FONT="skia_enable_fontmgr_custom_directory=false "
181WOFF2_FONT="skia_use_freetype_woff2=true"
182FONT_CFLAGS=""
183BUILTIN_FONT=""
184FONT_JS="--pre-js $BASE_DIR/font.js"
185if [[ $@ == *no_font* ]]; then
186  echo "Omitting the built-in font(s), font manager and all code dealing with fonts"
187  FONT_CFLAGS="-DSK_NO_FONTS"
188  WOFF2_FONT=""
189  FONT_JS=""
190  GN_FONT+="skia_enable_fontmgr_custom_embedded=false skia_enable_fontmgr_custom_empty=false"
191elif [[ $@ == *no_embedded_font* ]]; then
192  echo "Omitting the built-in font(s)"
193  GN_FONT+="skia_enable_fontmgr_custom_embedded=false skia_enable_fontmgr_custom_empty=true"
194else
195  # Generate the font's binary file (which is covered by .gitignore)
196  python tools/embed_resources.py \
197      --name SK_EMBEDDED_FONTS \
198      --input $BASE_DIR/fonts/NotoMono-Regular.ttf \
199      --output $BASE_DIR/fonts/NotoMono-Regular.ttf.cpp \
200      --align 4
201  BUILTIN_FONT="$BASE_DIR/fonts/NotoMono-Regular.ttf.cpp"
202  GN_FONT+="skia_enable_fontmgr_custom_embedded=true skia_enable_fontmgr_custom_empty=false"
203fi
204
205if [[ $@ == *no_woff2* ]]; then
206  WOFF2_FONT="skia_use_freetype_woff2=false"
207fi
208
209if [[ $@ == *no_alias_font* ]]; then
210EXTRA_CFLAGS+="\"-DCANVASKIT_NO_ALIAS_FONT\","
211FONT_CFLAGS+=" -DCANVASKIT_NO_ALIAS_FONT"
212fi
213
214GN_SHAPER="skia_use_icu=true skia_use_system_icu=false skia_use_harfbuzz=true skia_use_system_harfbuzz=false"
215SHAPER_LIB="$BUILD_DIR/libskunicode.a \
216            $BUILD_DIR/libharfbuzz.a \
217            $BUILD_DIR/libicu.a"
218if [[ $@ == *primitive_shaper* ]] || [[ $@ == *no_font* ]]; then
219  echo "Using the primitive shaper instead of the harfbuzz/icu one"
220  GN_SHAPER="skia_use_icu=false skia_use_harfbuzz=false"
221  SHAPER_LIB=""
222fi
223
224PARAGRAPH_JS="--pre-js $BASE_DIR/paragraph.js"
225PARAGRAPH_LIB="$BUILD_DIR/libskparagraph.a"
226PARAGRAPH_BINDINGS="-DSK_INCLUDE_PARAGRAPH=1 \
227  $BASE_DIR/paragraph_bindings.cpp \
228  $BASE_DIR/paragraph_bindings_gen.cpp"
229
230if [[ $@ == *no_paragraph* ]] || [[ $@ == *primitive_shaper* ]] || [[ $@ == *no_font* ]]; then
231  echo "Omitting paragraph (must have fonts and non-primitive shaper)"
232  PARAGRAPH_JS=""
233  PARAGRAPH_LIB=""
234  PARAGRAPH_BINDINGS=""
235fi
236
237DO_DECODE="true"
238if [[ $@ == *no_codecs* ]]; then
239  echo "Omitting codecs"
240  DO_DECODE="false"
241  ENCODE_PNG="false"
242  ENCODE_JPEG="false"
243  ENCODE_WEBP="false"
244else
245
246  ENCODE_PNG="true"
247  if [[ $@ == *no_encode_png* ]]; then
248    ENCODE_PNG="false"
249  fi
250
251  ENCODE_JPEG="false"
252  if [[ $@ == *force_encode_jpeg* ]]; then
253    ENCODE_JPEG="true"
254  fi
255
256  ENCODE_WEBP="false"
257  if [[ $@ == *force_encode_webp* ]]; then
258    ENCODE_WEBP="true"
259  fi
260
261fi # no_codecs
262
263# Turn off exiting while we check for ninja (which may not be on PATH)
264set +e
265NINJA=`which ninja`
266if [[ -z $NINJA ]]; then
267  git clone "https://chromium.googlesource.com/chromium/tools/depot_tools.git" --depth 1 $BUILD_DIR/depot_tools
268  NINJA=$BUILD_DIR/depot_tools/ninja
269fi
270# Re-enable error checking
271set -e
272
273./bin/fetch-gn
274
275echo "Compiling bitcode"
276
277# Inspired by https://github.com/Zubnix/skia-wasm-port/blob/master/build_bindings.sh
278./bin/gn gen ${BUILD_DIR} \
279  --args="cc=\"${EMCC}\" \
280  cxx=\"${EMCXX}\" \
281  ar=\"${EMAR}\" \
282  extra_cflags=[\"-s\", \"WARN_UNALIGNED=1\", \"-s\", \"MAIN_MODULE=1\",
283    \"-DSKNX_NO_SIMD\", \"-DSK_DISABLE_AAA\",
284    \"-DSK_FORCE_8_BYTE_ALIGNMENT\",
285    ${GN_GPU_FLAGS}
286    ${GN_SKP_FLAGS}
287    ${EXTRA_CFLAGS}
288  ] \
289  is_debug=false \
290  is_official_build=${IS_OFFICIAL_BUILD} \
291  is_component_build=false \
292  werror=true \
293  target_cpu=\"wasm\" \
294  \
295  skia_use_angle=false \
296  skia_use_dng_sdk=false \
297  skia_use_webgl=true \
298  skia_use_fontconfig=false \
299  skia_use_freetype=true \
300  skia_use_libheif=false \
301  skia_use_libjpeg_turbo_decode=${DO_DECODE} \
302  skia_use_libjpeg_turbo_encode=${ENCODE_JPEG} \
303  skia_use_libpng_decode=${DO_DECODE} \
304  skia_use_libpng_encode=${ENCODE_PNG} \
305  skia_use_libwebp_decode=${DO_DECODE} \
306  skia_use_libwebp_encode=${ENCODE_WEBP} \
307  skia_use_lua=false \
308  skia_use_piex=false \
309  skia_use_system_freetype2=false \
310  skia_use_system_libjpeg_turbo=false \
311  skia_use_system_libpng=false \
312  skia_use_system_libwebp=false \
313  skia_use_system_zlib=false\
314  skia_use_vulkan=false \
315  skia_use_wuffs=true \
316  skia_use_zlib=true \
317  \
318  ${GN_SHAPER} \
319  ${GN_GPU} \
320  ${GN_FONT} \
321  ${WOFF2_FONT} \
322  ${GN_VIEWER} \
323  \
324  skia_enable_skshaper=true \
325  skia_enable_skparagraph=true \
326  skia_enable_pdf=false"
327
328# Build all the libs we will need below
329parse_targets() {
330  for LIBPATH in $@; do
331    basename $LIBPATH
332  done
333}
334${NINJA} -C ${BUILD_DIR} libskia.a libskshaper.a \
335  $(parse_targets $SKOTTIE_LIB $VIEWER_LIB $PARTICLES_LIB $SHAPER_LIB $PARAGRAPH_LIB)
336
337export EMCC_CLOSURE_ARGS="--externs $BASE_DIR/externs.js "
338
339echo "Generating final wasm"
340
341# Disable '-s STRICT=1' outside of Linux until
342# https://github.com/emscripten-core/emscripten/issues/12118 is resovled.
343STRICTNESS="-s STRICT=1"
344if [[ `uname` != "Linux" ]]; then
345  echo "Disabling '-s STRICT=1'. See: https://github.com/emscripten-core/emscripten/issues/12118"
346  STRICTNESS=""
347fi
348
349# Emscripten prefers that the .a files go last in order, otherwise, it
350# may drop symbols that it incorrectly thinks aren't used. One day,
351# Emscripten will use LLD, which may relax this requirement.
352EMCC_DEBUG=1 ${EMCXX} \
353    $RELEASE_CONF \
354    -I. \
355    -Ithird_party/icu \
356    -Ithird_party/skcms \
357    -Ithird_party/externals/icu/source/common/ \
358    -DSK_DISABLE_AAA \
359    -DSK_FORCE_8_BYTE_ALIGNMENT \
360    -DEMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES=0 \
361    -fno-rtti \
362    $WASM_GPU \
363    $WASM_PATHOPS \
364    $WASM_RT_SHADER \
365    $WASM_SKP \
366    $FONT_CFLAGS \
367    -std=c++17 \
368    --bind \
369    --no-entry \
370    --pre-js $BASE_DIR/preamble.js \
371    --pre-js $BASE_DIR/color.js \
372    --pre-js $BASE_DIR/memory.js \
373    --pre-js $BASE_DIR/util.js \
374    --pre-js $BASE_DIR/interface.js \
375    $MATRIX_HELPER_JS \
376    $PARAGRAPH_JS \
377    $SKOTTIE_JS \
378    $PARTICLES_JS \
379    $PATHOPS_JS \
380    $FONT_JS \
381    $SKP_JS \
382    $RT_SHADER_JS \
383    $HTML_CANVAS_API \
384    --pre-js $BASE_DIR/postamble.js \
385    $BASE_DIR/canvaskit_bindings.cpp \
386    $PARTICLES_BINDINGS \
387    $SKOTTIE_BINDINGS \
388    $VIEWER_BINDINGS \
389    $MANAGED_SKOTTIE_BINDINGS \
390    $PARAGRAPH_BINDINGS \
391    $SKOTTIE_LIB \
392    $VIEWER_LIB \
393    $PARTICLES_LIB \
394    $PARAGRAPH_LIB \
395    $BUILD_DIR/libskshaper.a \
396    $SHAPER_LIB \
397    $BUILD_DIR/libskia.a \
398    $BUILTIN_FONT \
399    -s LLD_REPORT_UNDEFINED \
400    -s ALLOW_MEMORY_GROWTH=1 \
401    -s EXPORT_NAME="CanvasKitInit" \
402    -s EXPORTED_FUNCTIONS=['_malloc','_free'] \
403    -s FORCE_FILESYSTEM=0 \
404    -s FILESYSTEM=0 \
405    -s MODULARIZE=1 \
406    -s NO_EXIT_RUNTIME=1 \
407    -s INITIAL_MEMORY=128MB \
408    -s WASM=1 \
409    $STRICTNESS \
410    -o $BUILD_DIR/canvaskit.js
411