blob: c74cbc5112f84595574a28fb485bf5f33ccff500 [file] [log] [blame]
load("@skia_user_config//:copts.bzl", "DEFAULT_COPTS")
load("//bazel:macros.bzl", "bool_flag", "skia_filegroup", "wasm_cc_binary")
load("//bazel/karma:karma_test.bzl", "karma_test")
package(
default_applicable_licenses = ["//:license"],
)
licenses(["notice"])
exports_files(
["npm_build/types/index.d.ts"],
visibility = ["//infra:__subpackages__"],
)
BASE_LINKOPTS = [
#"-flto", # https://github.com/emscripten-core/emsdk/issues/807
"--bind", # Compiles the source code using the Embind bindings to connect C/C++ and JavaScript
"-fno-rtti",
"--no-entry",
"-sALLOW_MEMORY_GROWTH",
"-sUSE_PTHREADS=0", # Disable pthreads
"-sMODULARIZE",
"-sDISABLE_EXCEPTION_CATCHING", # Disable all exception catching
"-sNODEJS_CATCH_EXIT=0", # We don't have a 'main' so disable exit() catching
"-sWASM",
"-sMAX_WEBGL_VERSION=2",
"-sUSE_WEBGL2=1",
"-sFORCE_FILESYSTEM=0",
"-sDYNAMIC_EXECUTION=0",
"-sFILESYSTEM=0",
"-sEXPORTED_FUNCTIONS=['_malloc','_free']",
]
RELEASE_OPTS = [
"-sASSERTIONS=0", # Turn off assertions
"-Oz",
]
DEBUG_OPTS = [
"--closure 0", # Do not use closure
"-sASSERTIONS", # Turn on assertions
"-sGL_ASSERTIONS",
"-O0",
"-g3",
]
skia_filegroup(
name = "hdrs",
srcs = [
"WasmCommon.h",
],
)
# See https://stackoverflow.com/a/57499321 for reference.
genrule(
name = "create_notomono_cpp",
srcs = ["fonts/NotoMono-Regular.ttf"],
outs = ["fonts/NotoMono-Regular.ttf.bazel.cpp"], # Distinct name from compile.sh's version
cmd = "$(location //tools:embed_resources) --name=SK_EMBEDDED_FONTS " +
"--input=modules/canvaskit/fonts/NotoMono-Regular.ttf " +
# The $@ means substitute in the one and only output location, which will be located
# in //bazel-out, not in the fonts subdirectory (although it will be available to clients
# in the fonts/ subdirectory as if it had been there all along.
"--output=$@ " +
"--align=4",
tools = ["//tools:embed_resources"],
)
# Note: These are defines that only impact the _bindings.cpp files in this folder.
# Any defines that need to effect the entire Skia build should go in //bazel/BUILD.bazel
CK_DEFINES = [
"CK_INCLUDE_PATHOPS",
"EMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES=0", # Allows us to compile with -fno-rtti
"SK_DISABLE_LEGACY_PARAGRAPH_UNICODE=1",
] + select({
":enable_fonts_true": ["CK_INCLUDE_PARAGRAPH"],
":enable_fonts_false": ["CK_NO_FONTS"],
}) + select({
":include_embedded_font_true": ["CK_EMBED_FONT"],
":include_embedded_font_false": [],
}) + select({
":enable_skp_serialization_true": ["CK_SERIALIZE_SKP=1"],
":enable_skp_serialization_false": [],
}) + select({
":enable_runtime_effect_true": ["CK_INCLUDE_RUNTIME_EFFECT=1"],
":enable_runtime_effect_false": [],
}) + select({
":enable_webgl_true": ["CK_ENABLE_WEBGL"],
"//conditions:default": [],
})
CK_RELEASE_OPTS = [
"--closure 1", # Run the closure compiler
# pass the externs file in
"--closure-args=--externs=$(location externs.js)",
]
CK_LINKOPTS = BASE_LINKOPTS + [
"-sEXPORT_NAME=CanvasKitInit",
"-sINITIAL_MEMORY=128MB",
# The order of these --pre-js flags matters! The preamble is a partially open scope and the
# postamble closes it. TODO(kjlubick) do we need to do it this way anymore?
"--pre-js",
"modules/canvaskit/preamble.js",
"--pre-js",
"modules/canvaskit/color.js",
"--pre-js",
"modules/canvaskit/memory.js",
"--pre-js",
"modules/canvaskit/util.js",
"--pre-js",
"modules/canvaskit/interface.js",
"--pre-js",
"modules/canvaskit/pathops.js",
] + select({
":enable_webgl_true": [
"--pre-js",
"modules/canvaskit/cpu.js",
"--pre-js",
"modules/canvaskit/webgl.js",
],
"//conditions:default": [
"--pre-js",
"modules/canvaskit/cpu.js",
],
}) + select({
":enable_fonts_true": [
"--pre-js",
"modules/canvaskit/font.js",
"--pre-js",
"modules/canvaskit/paragraph.js",
],
":enable_fonts_false": [],
}) + select({
":enable_canvas_polyfill_true": [
"--pre-js",
"modules/canvaskit/htmlcanvas/preamble.js",
"--pre-js",
"modules/canvaskit/htmlcanvas/util.js",
"--pre-js",
"modules/canvaskit/htmlcanvas/color.js",
"--pre-js",
"modules/canvaskit/htmlcanvas/font.js",
"--pre-js",
"modules/canvaskit/htmlcanvas/canvas2dcontext.js",
"--pre-js",
"modules/canvaskit/htmlcanvas/htmlcanvas.js",
"--pre-js",
"modules/canvaskit/htmlcanvas/htmlimage.js",
"--pre-js",
"modules/canvaskit/htmlcanvas/imagedata.js",
"--pre-js",
"modules/canvaskit/htmlcanvas/lineargradient.js",
"--pre-js",
"modules/canvaskit/htmlcanvas/path2d.js",
"--pre-js",
"modules/canvaskit/htmlcanvas/pattern.js",
"--pre-js",
"modules/canvaskit/htmlcanvas/radialgradient.js",
"--pre-js",
"modules/canvaskit/htmlcanvas/postamble.js",
],
":enable_canvas_polyfill_false": [],
}) + select({
":enable_skottie_true": [
"--pre-js",
"modules/canvaskit/skottie.js",
],
":enable_skottie_false": [],
}) + select({
":enable_skp_serialization_true": [
"--pre-js",
"modules/canvaskit/skp.js",
],
":enable_skp_serialization_false": [],
}) + select({
":enable_runtime_effect_true": [
"--pre-js",
"modules/canvaskit/rt_shader.js",
],
":enable_runtime_effect_false": [],
}) + select({
":build_for_debugger_true": [
"--pre-js",
"modules/canvaskit/debugger.js",
],
":build_for_debugger_false": [],
}) + select({
":include_matrix_js_true": [
"--pre-js",
"modules/canvaskit/matrix.js",
],
":include_matrix_js_false": [],
}) + [
# This must come last
"--pre-js",
"modules/canvaskit/postamble.js",
] + select({
"//bazel/common_config_settings:debug_build": DEBUG_OPTS + [
"--pre-js",
"modules/canvaskit/debug.js",
],
"//conditions:default": RELEASE_OPTS + CK_RELEASE_OPTS + [
"--pre-js",
"modules/canvaskit/release.js",
],
})
# All JS files that could possibly be included via --pre-js or --post-js.
# Whether they actually will be or not will be controlled above in the construction of CK_LINKOPTS.
JS_INTERFACE_FILES = [
"color.js",
"cpu.js",
"debug.js",
"font.js",
"interface.js",
"matrix.js",
"memory.js",
"paragraph.js",
"pathops.js",
"postamble.js",
"preamble.js",
"release.js",
"rt_shader.js",
"skottie.js",
"skp.js",
"util.js",
"webgl.js",
"webgpu.js",
] + [
"htmlcanvas/canvas2dcontext.js",
"htmlcanvas/color.js",
"htmlcanvas/font.js",
"htmlcanvas/htmlcanvas.js",
"htmlcanvas/htmlimage.js",
"htmlcanvas/imagedata.js",
"htmlcanvas/lineargradient.js",
"htmlcanvas/path2d.js",
"htmlcanvas/pattern.js",
"htmlcanvas/postamble.js",
"htmlcanvas/preamble.js",
"htmlcanvas/radialgradient.js",
"htmlcanvas/util.js",
] + select({
":build_for_debugger_true": ["debugger.js"],
":build_for_debugger_false": [],
})
CK_SRCS = [
"canvaskit_bindings.cpp",
":hdrs",
] + select({
":include_embedded_font_true": ["fonts/NotoMono-Regular.ttf.bazel.cpp"],
":include_embedded_font_false": [],
}) + select({
":enable_fonts_true": [
"paragraph_bindings.cpp",
"paragraph_bindings_gen.cpp",
],
":enable_fonts_false": [],
}) + select({
":enable_skottie_true": ["skottie_bindings.cpp"],
":enable_skottie_false": [],
}) + select({
":build_for_debugger_true": ["debugger_bindings.cpp"],
":build_for_debugger_false": [],
})
CK_COPTS = [
"-Wno-header-hygiene",
]
cc_binary(
name = "canvaskit.build",
srcs = CK_SRCS,
additional_linker_inputs = JS_INTERFACE_FILES + ["externs.js"],
copts = DEFAULT_COPTS + CK_COPTS,
linkopts = CK_LINKOPTS,
local_defines = CK_DEFINES,
# This target won't build successfully on its own because of missing emscripten
# headers etc. Therefore, we hide it from wildcards.
tags = ["manual"],
deps = [
"//:bmp_decode_codec",
"//:core",
"//:gif_decode_codec",
"//:ico_decode_codec",
"//:jpeg_decode_codec",
"//:jpeg_encode_codec",
"//:png_decode_codec",
"//:png_encode_codec",
"//:wbmp_decode_codec",
"//:webp_decode_codec",
"//:webp_encode_codec",
"//src/android:animated_image",
] + select({
":enable_fonts_true": [
"//:fontmgr_data_freetype",
"//:fontmgr_empty_freetype",
"//modules/skparagraph:skparagraph_harfbuzz_skunicode",
"//modules/skunicode:skunicode_icu",
],
":enable_fonts_false": [],
}) + select({
":enable_skottie_true": [
"//:skshaper_harfbuzz",
"//:skshaper_unicode",
"//:skunicode_icu",
"//modules/skottie",
"//modules/skottie/utils:skottie_utils",
"//modules/skottie/utils:text_editor",
],
":enable_skottie_false": [],
}) + select({
":build_for_debugger_true": [
"//tools/debugger",
],
":build_for_debugger_false": [],
}) + select({
":enable_webgl_true": [
"//:ganesh_gl",
"//:ganesh_webgl_factory",
],
"//conditions:default": [],
}),
)
wasm_cc_binary(
name = "canvaskit",
# Whatever is before the dot will be the name of the output js and wasm, aka "the stem".
# https://github.com/emscripten-core/emsdk/blob/82ad00499a42abde16b363239d2bc83bf5d863ab/bazel/emscripten_toolchain/wasm_cc_binary.bzl#L91
cc_target = ":canvaskit.build",
visibility = [
"//infra/debugger-app:__pkg__",
"//infra/jsfiddle:__pkg__",
"//infra/shaders:__pkg__",
"//infra/skottie:__pkg__",
],
)
bool_flag(
name = "enable_canvas_polyfill",
default = False,
)
bool_flag(
name = "enable_fonts",
default = False,
)
bool_flag(
name = "include_embedded_font",
default = False,
)
bool_flag(
name = "include_matrix_js",
default = False,
)
bool_flag(
name = "enable_skottie",
default = False,
)
bool_flag(
name = "enable_skp_serialization",
default = False,
)
bool_flag(
name = "enable_runtime_effect",
default = False,
)
bool_flag(
name = "enable_webgl",
default = False,
)
bool_flag(
name = "build_for_debugger",
default = False,
)
karma_test(
name = "canvaskit_js_tests",
srcs = [
":canvaskit/canvaskit.js",
# We want to make sure the CanvasKit JS is loaded before the loader script, so
# CanvasKitInit is defined. This loader script makes a promise...
"tests/init_with_gold_server.js",
"tests/util.js",
"tests/bazel_test_reporter.js",
# ...which is used by all of the tests
"tests/canvas_test.js",
"tests/canvas2d_test.js",
"tests/core_test.js",
"tests/font_test.js",
"tests/matrix_test.js",
"tests/paragraph_test.js",
"tests/path_test.js",
"tests/rtshader_test.js",
"tests/skottie_test.js",
],
config_file = "karma.bazel.js",
# The tests need the Gold server to be up and running so they can make POST requests to
# exfiltrate the PNGs they create.
env = "//modules/canvaskit/go/gold_test_env:gold_test_env",
static_files = [
":canvaskit/canvaskit.wasm",
"//modules/canvaskit/tests/assets:test_assets",
],
)
genrule(
name = "make version file",
srcs = ["make_version.sh"],
outs = ["version.js"],
cmd = "$< $@",
# This script uses the Git executable, which is not on the remote builders.
# Forcing the execution to be local ensures it will be in the path.
local = True,
visibility = ["//infra:__subpackages__"],
)