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 24EMCXX=`which em++` 25 26if [[ $@ == *debug* ]]; then 27 echo "Building a Debug build" 28 DEBUG=true 29 EXTRA_CFLAGS="\"-DSK_DEBUG\", \"-DGPU_TEST_UTILS\", " 30 RELEASE_CONF="-O1 --js-opts 0 -sDEMANGLE_SUPPORT=1 -frtti -sASSERTIONS=1 -sGL_ASSERTIONS=1 -g \ 31 -DSK_DEBUG --pre-js $BASE_DIR/debug.js" 32 BUILD_DIR=${BUILD_DIR:="out/wasm_gm_tests_debug"} 33else 34 echo "Building a release build" 35 DEBUG=false 36 BUILD_DIR=${BUILD_DIR:="out/wasm_gm_tests"} 37 RELEASE_CONF="-O3 -DSK_RELEASE --pre-js $BASE_DIR/release.js \ 38 -DGPU_TEST_UTILS" 39 EXTRA_CFLAGS="\"-DSK_RELEASE\", \"-DGPU_TEST_UTILS\", " 40fi 41 42IS_OFFICIAL_BUILD="false" 43 44mkdir -p $BUILD_DIR 45# sometimes the .a files keep old symbols around - cleaning them out makes sure 46# we get a fresh build. 47rm -f $BUILD_DIR/*.a 48 49GN_GPU="skia_enable_ganesh=true skia_gl_standard = \"webgl\"" 50GN_GPU_FLAGS="\"-DSK_DISABLE_LEGACY_SHADERCONTEXT\"," 51WASM_GPU="-lGL -DSK_GANESH -DSK_GL -DCK_ENABLE_WEBGL \ 52 -DSK_DISABLE_LEGACY_SHADERCONTEXT --pre-js $BASE_DIR/cpu.js --pre-js $BASE_DIR/webgl.js\ 53 -sUSE_WEBGL2=1" 54 55GM_LIB="$BUILD_DIR/libgm_wasm.a" 56 57GN_FONT="skia_enable_fontmgr_custom_directory=false " 58BUILTIN_FONT="$BASE_DIR/fonts/NotoMono-Regular.ttf.cpp" 59# Generate the font's binary file (which is covered by .gitignore) 60python3 tools/embed_resources.py \ 61 --name SK_EMBEDDED_FONTS \ 62 --input $BASE_DIR/fonts/NotoMono-Regular.ttf \ 63 --output $BASE_DIR/fonts/NotoMono-Regular.ttf.cpp \ 64 --align 4 65GN_FONT+="skia_enable_fontmgr_custom_embedded=true skia_enable_fontmgr_custom_empty=false" 66 67 68GN_SHAPER="skia_use_icu=true skia_use_system_icu=false skia_use_harfbuzz=true skia_use_system_harfbuzz=false" 69 70./bin/fetch-ninja 71NINJA=third_party/ninja/ninja 72 73./bin/fetch-gn 74 75echo "Compiling bitcode" 76 77# Inspired by https://github.com/Zubnix/skia-wasm-port/blob/master/build_bindings.sh 78./bin/gn gen ${BUILD_DIR} \ 79 --args="skia_emsdk_dir=\"${EMSDK}\" \ 80 extra_cflags_cc=[\"-frtti\"] \ 81 extra_cflags=[\"-sMAIN_MODULE=1\", 82 \"-DSKNX_NO_SIMD\", \"-DSK_FORCE_AAA\", 83 \"-DSK_FORCE_8_BYTE_ALIGNMENT\", 84 ${GN_GPU_FLAGS} 85 ${EXTRA_CFLAGS} 86 ] \ 87 is_debug=${DEBUG} \ 88 is_official_build=${IS_OFFICIAL_BUILD} \ 89 is_trivial_abi=true \ 90 is_component_build=false \ 91 werror=true \ 92 target_cpu=\"wasm\" \ 93 \ 94 skia_use_angle=false \ 95 skia_use_dng_sdk=false \ 96 skia_use_webgl=true \ 97 skia_use_fontconfig=false \ 98 skia_use_freetype=true \ 99 skia_use_libheif=true \ 100 skia_use_libjpeg_turbo_decode=true \ 101 skia_use_libjpeg_turbo_encode=true \ 102 skia_use_libpng_decode=true \ 103 skia_use_libpng_encode=true \ 104 skia_use_libwebp_decode=true \ 105 skia_use_libwebp_encode=true \ 106 skia_use_lua=false \ 107 skia_use_piex=true \ 108 skia_use_system_freetype2=false \ 109 skia_use_system_libjpeg_turbo=false \ 110 skia_use_system_libpng=false \ 111 skia_use_system_libwebp=false \ 112 skia_use_system_zlib=false\ 113 skia_use_vulkan=false \ 114 skia_use_wuffs=true \ 115 skia_use_zlib=true \ 116 \ 117 ${GN_SHAPER} \ 118 ${GN_GPU} \ 119 ${GN_FONT} \ 120 skia_use_expat=true \ 121 skia_enable_svg=true \ 122 skia_enable_skshaper=true \ 123 skia_enable_skparagraph=true \ 124 skia_enable_pdf=false" 125 126# Build all the libs we will need below 127parse_targets() { 128 for LIBPATH in $@; do 129 basename $LIBPATH 130 done 131} 132${NINJA} -C ${BUILD_DIR} libskia.a libskshaper.a libskunicode_core.a libskunicode_icu.a \ 133 $(parse_targets $GM_LIB) 134 135echo "Generating final wasm" 136 137# Defines for the emscripten compilation step, which builds the tests 138# Aim to match the defines that would be set by gn for the skia compilation step. 139SKIA_DEFINES=" 140-DSK_FORCE_AAA \ 141-DSK_FORCE_8_BYTE_ALIGNMENT \ 142-DSK_HAS_WUFFS_LIBRARY \ 143-DSK_HAS_HEIF_LIBRARY \ 144-DSK_CODEC_DECODES_WEBP \ 145-DSK_CODEC_DECODES_PNG \ 146-DSK_CODEC_DECODES_JPEG \ 147-DSK_SHAPER_HARFBUZZ_AVAILABLE \ 148-DSK_UNICODE_AVAILABLE \ 149-DSK_UNICODE_ICU_IMPLEMENTATION \ 150-DSK_ENABLE_SVG \ 151-DSK_TRIVIAL_ABI=[[clang::trivial_abi]]" 152 153GMS_TO_BUILD="gm/*.cpp" 154TESTS_TO_BUILD="tests/*.cpp" 155 156# When developing locally, it can be faster to focus only on the gms or tests you care about 157# (since they all have to be recompiled/relinked) every time. To do so, mark the following as true 158if false; then 159 GMS_TO_BUILD="gm/gm.cpp" 160 TESTS_TO_BUILD="tests/BulkRectTest.cpp tests/Test.cpp" 161fi 162 163# These gms do not compile or link with the WASM code. Thus, we omit them. 164GLOBIGNORE="gm/compressed_textures.cpp:"\ 165"gm/animated_gif.cpp:"\ 166"gm/fiddle.cpp:"\ 167"gm/fontations.cpp:"\ 168"gm/fontations_ft_compare.cpp:"\ 169"gm/video_decoder.cpp:" 170 171# These tests do not compile with the WASM code (require other deps). 172GLOBIGNORE+="tests/CodecTest.cpp:"\ 173"tests/CodecAnimTest.cpp:"\ 174"tests/ColorSpaceTest.cpp:"\ 175"tests/DrawOpAtlasTest.cpp:"\ 176"tests/EncodeTest.cpp:"\ 177"tests/FontMgrAndroidTest.cpp:"\ 178"tests/FontMgrAndroidParserTest.cpp:"\ 179"tests/FontMgrFontConfigTest.cpp:"\ 180"tests/FontationsTest.cpp:"\ 181"tests/FontationsFtCompTest.cpp:"\ 182"tests/FontScanner_FontationsTest.cpp:"\ 183"tests/FontScanner_FreeTypeTest.cpp:"\ 184"tests/FCITest.cpp:"\ 185"tests/JpegGainmapTest.cpp:"\ 186"tests/SkPngRustDecoderTest.cpp:"\ 187"tests/SkPngRustEncoderTest.cpp:"\ 188"tests/TypefaceMacTest.cpp:" 189 190# These tests do complex things with TestContexts, which is not easily supported for the WASM 191# test harness. Thus we omit them. 192GLOBIGNORE+="tests/BackendAllocationTest.cpp:"\ 193"tests/EGLImageTest.cpp:"\ 194"tests/ImageTest.cpp:"\ 195"tests/SurfaceSemaphoreTest.cpp:"\ 196"tests/TextureBindingsResetTest.cpp:"\ 197"tests/VkHardwareBufferTest.cpp:" 198 199# All the tests in these files crash. 200GLOBIGNORE+="tests/GrThreadSafeCacheTest.cpp:" 201 202# Bazel-related ignores (test runners, incompatible GMs, etc.). 203GLOBIGNORE+="gm/png_codec.cpp" 204 205# Emscripten prefers that the .a files go last in order, otherwise, it 206# may drop symbols that it incorrectly thinks aren't used. One day, 207# Emscripten will use LLD, which may relax this requirement. 208EMCC_DEBUG=1 ${EMCXX} \ 209 $RELEASE_CONF \ 210 -I. \ 211 -DGPU_TEST_UTILS \ 212 $SKIA_DEFINES \ 213 $WASM_GPU \ 214 -std=c++17 \ 215 --profiling-funcs \ 216 --profiling \ 217 --bind \ 218 --no-entry \ 219 --pre-js $BASE_DIR/gm.js \ 220 tools/Resources.cpp \ 221 $BASE_DIR/gm_bindings.cpp \ 222 $GMS_TO_BUILD \ 223 $TESTS_TO_BUILD \ 224 $GM_LIB \ 225 $BUILD_DIR/libskshaper.a \ 226 $BUILD_DIR/libskunicode_core.a \ 227 $BUILD_DIR/libskunicode_icu.a \ 228 $BUILD_DIR/libsvg.a \ 229 $BUILD_DIR/libskia.a \ 230 $BUILTIN_FONT \ 231 -sALLOW_MEMORY_GROWTH=1 \ 232 -sEXPORT_NAME="InitWasmGMTests" \ 233 -sEXPORTED_FUNCTIONS=['_malloc','_free'] \ 234 -sFORCE_FILESYSTEM=1 \ 235 -sFILESYSTEM=1 \ 236 -sMODULARIZE=1 \ 237 -sNO_EXIT_RUNTIME=1 \ 238 -sINITIAL_MEMORY=256MB \ 239 -sWASM=1 \ 240 -sSTRICT=1 \ 241 -o $BUILD_DIR/wasm_gm_tests.js 242