skia2/modules/canvaskit/BUILD.bazel
Kevin Lubick 4bd08c52c0 [infra] Add SkParagraph (harfbuzz, ICU) to Canvaskit Bazel build.
As a follow-up to https://skia-review.googlesource.com/c/skia/+/476219,
this sketches out how we can maybe use cc_library for the things
in //modules to make sure something in //src doesn't depend on
anything in //modules, for example.

The following succeeds:
bazel build //modules/skparagraph:skparagraph --config=clang \
  --shaper_backend=harfbuzz_shaper --with_icu

As does `make bazel_canvaskit_debug` in //modules/canvaskit

Suggested Review Order:
 - third_party/BUILD.bazel for ICU and harfbuzz rules. Pay
   special attention to the genrules used to call the python
   script for turning the icu .dat file into .S or .cpp.
 - bazelrc and bazel/ for new flags and defines that control
   use of ICU and harfbuzz. Unlike GN, with the public_defines
   that get added in automatically if icu or harfbuzz is
   depended upon, we need to set the defines at the top level.
   This necessity might go away if we change the atoms to
   depend on //modules/skshaper, which could define that flag.
 - Top level BUILD.bazel files in //modules/skparagraph,
   //modules/skshaper, //modules/skunicode, //modules/canvaskit
 - All other .bazel file changes are automatic.

Bug: skia:12541
Change-Id: I38a9e0a9261d7e142eeb271c2ddb23f362f91473
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/478116
Reviewed-by: Ben Wagner <bungeman@google.com>
Reviewed-by: Leandro Lovisolo <lovisolo@google.com>
2021-11-30 21:01:06 +00:00

322 lines
8.8 KiB
Python

load("@emsdk//emscripten_toolchain:wasm_rules.bzl", "wasm_cc_binary")
load("//bazel/common_config_settings:defs.bzl", "bool_flag")
load("//bazel:cc_binary_with_flags.bzl", "cc_binary_with_flags")
package(default_visibility = ["//:__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
"--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",
"-sFORCE_FILESYSTEM=0",
"-sFILESYSTEM=0",
]
RELEASE_OPTS = [
# We disable closure for now, because we need a way to pass in the externs file,
# which does not appear to be exposed on the emscripten toolchain.
# "--closure 1", # Run the closure compiler
"-sASSERTIONS=0", # Turn off assertions
"-Oz",
]
DEBUG_OPTS = [
"--closure 0", # Do not use closure
"-sASSERTIONS", # Turn on assertions
"-sGL_ASSERTIONS",
]
GM_OPTS = [
"-sEXPORT_NAME=InitWasmGMTests",
"--pre-js",
"modules/canvaskit/gm.js",
]
filegroup(
name = "hdrs",
srcs = [
"WasmCommon.h",
],
)
cc_binary_with_flags(
name = "gm_bindings_with_flags",
testonly = True,
srcs = [
"gm_bindings.cpp",
":hdrs",
"//gm:gms", # Required for the registry to work
],
additional_linker_inputs = ["gm.js"],
cc_binary_name = "gm_bindings",
linkopts = select({
"//bazel/common_config_settings:debug_build": BASE_LINKOPTS + GM_OPTS + DEBUG_OPTS,
"//bazel/common_config_settings:release_build": BASE_LINKOPTS + GM_OPTS + RELEASE_OPTS,
"//conditions:default": BASE_LINKOPTS + GM_OPTS + RELEASE_OPTS,
}),
local_defines = [
"SK_GL",
"SK_USE_WEBGL",
],
set_flags = {
"include_decoder": [
"jpeg_decode_codec",
"png_decode_codec",
"webp_decode_codec",
"gif_decode_codec",
],
"gpu_backend": [
"gl_backend",
],
"with_gl_standard": [
"webgl_standard",
],
},
# This target won't build successfully on its own because of missing emscripten
# headers etc. Therefore, we hide it from wildcards.
tags = ["manual"],
deps = [
"//:gms",
"//:hash_and_encode",
"//:tests",
],
)
wasm_cc_binary(
name = "gm_bindings_wasm",
testonly = True,
cc_target = ":gm_bindings_with_flags",
)
# 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"],
)
CK_DEFINES = select({
":enable_fonts_true": ["SK_INCLUDE_PARAGRAPH=1"],
":enable_fonts_false": ["SK_NO_FONTS"],
})
CK_OPTS = 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.
"--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/matrix.js",
] + select({
"//bazel/common_config_settings:gl_backend": [
"--pre-js",
"modules/canvaskit/cpu.js",
"--pre-js",
"modules/canvaskit/gpu.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/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": [],
}) + [
"--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 + [
"--pre-js",
"modules/canvaskit/release.js",
],
})
# All JS files that could be included via --pre-js or --post-js
JS_INTERFACE_FILES = [
"color.js",
"cpu.js",
"debug.js",
"externs.js",
"font.js",
"gpu.js",
"interface.js",
"matrix.js",
"memory.js",
"paragraph.js",
"particles.js",
"pathops.js",
"postamble.js",
"preamble.js",
"release.js",
"rt_shader.js",
"skottie.js",
"skp.js",
"util.js",
] + [
"htmlcanvas/canvas2dcontext.js",
"htmlcanvas/color.js",
"htmlcanvas/font.js",
"htmlcanvas/htmlcanvas.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",
]
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": [],
})
cc_binary_with_flags(
name = "canvaskit_with_flags",
srcs = CK_SRCS,
additional_linker_inputs = JS_INTERFACE_FILES,
# wasm_cc_binary makes the canvaskit.js/canvaskit.wasm based on the actual name
# of the executable.
cc_binary_name = "canvaskit",
features = [
# https://github.com/emscripten-core/emsdk/blob/846f683bea839899164cdbe287f92f7ae952428e/bazel/emscripten_toolchain/crosstool.bzl#L1051
"emcc_debug_link",
],
linkopts = CK_OPTS,
local_defines = CK_DEFINES,
set_flags = {
"include_decoder": [
"jpeg_decode_codec",
"png_decode_codec",
"webp_decode_codec",
"gif_decode_codec",
],
"include_encoder": [
"jpeg_encode_codec",
"png_encode_codec",
],
# TODO(kjlubick) make this optional, depending on enable_fonts
"fontmgr_factory": [
"custom_embedded_fontmgr_factory",
],
"include_fontmgr": [
"custom_embedded_fontmgr",
],
"gpu_backend": [
"gl_backend",
],
"with_gl_standard": [
"webgl_standard",
],
"use_icu": [
"True",
],
"shaper_backend": [
"harfbuzz_shaper",
],
},
# This target won't build successfully on its own because of missing emscripten
# headers etc. Therefore, we hide it from wildcards.
tags = ["manual"],
deps = [
"//:skia_core",
] + select({
":enable_fonts_true": [
"//modules/skparagraph:skparagraph",
],
":enable_fonts_false": [],
}),
)
wasm_cc_binary(
name = "canvaskit_wasm",
cc_target = ":canvaskit_with_flags",
)
bool_flag(
default = True,
flag_name = "enable_canvas_polyfill",
)
bool_flag(
default = True,
flag_name = "enable_fonts",
)
bool_flag(
default = True,
flag_name = "include_embedded_font",
)