xref: /aosp_15_r20/external/skia/modules/canvaskit/BUILD.bazel (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1load("@skia_user_config//:copts.bzl", "DEFAULT_COPTS")
2load("//bazel:macros.bzl", "bool_flag", "skia_filegroup", "wasm_cc_binary")
3load("//bazel/karma:karma_test.bzl", "karma_test")
4
5package(
6    default_applicable_licenses = ["//:license"],
7)
8
9licenses(["notice"])
10
11exports_files(
12    ["npm_build/types/index.d.ts"],
13    visibility = ["//infra:__subpackages__"],
14)
15
16BASE_LINKOPTS = [
17    #"-flto",  # https://github.com/emscripten-core/emsdk/issues/807
18    "--bind",  # Compiles the source code using the Embind bindings to connect C/C++ and JavaScript
19    "-fno-rtti",
20    "--no-entry",
21    "-sALLOW_MEMORY_GROWTH",
22    "-sUSE_PTHREADS=0",  # Disable pthreads
23    "-sMODULARIZE",
24    "-sDISABLE_EXCEPTION_CATCHING",  # Disable all exception catching
25    "-sNODEJS_CATCH_EXIT=0",  # We don't have a 'main' so disable exit() catching
26    "-sWASM",
27    "-sMAX_WEBGL_VERSION=2",
28    "-sUSE_WEBGL2=1",
29    "-sFORCE_FILESYSTEM=0",
30    "-sDYNAMIC_EXECUTION=0",
31    "-sFILESYSTEM=0",
32    "-sEXPORTED_FUNCTIONS=['_malloc','_free']",
33]
34
35RELEASE_OPTS = [
36    "-sASSERTIONS=0",  # Turn off assertions
37    "-Oz",
38]
39
40DEBUG_OPTS = [
41    "--closure 0",  # Do not use closure
42    "-sASSERTIONS",  # Turn on assertions
43    "-sGL_ASSERTIONS",
44    "-O0",
45    "-g3",
46]
47
48skia_filegroup(
49    name = "hdrs",
50    srcs = [
51        "WasmCommon.h",
52    ],
53)
54
55# See https://stackoverflow.com/a/57499321 for reference.
56genrule(
57    name = "create_notomono_cpp",
58    srcs = ["fonts/NotoMono-Regular.ttf"],
59    outs = ["fonts/NotoMono-Regular.ttf.bazel.cpp"],  # Distinct name from compile.sh's version
60    cmd = "$(location //tools:embed_resources) --name=SK_EMBEDDED_FONTS " +
61          "--input=modules/canvaskit/fonts/NotoMono-Regular.ttf " +
62          # The $@ means substitute in the one and only output location, which will be located
63          # in //bazel-out, not in the fonts subdirectory (although it will be available to clients
64          # in the fonts/ subdirectory as if it had been there all along.
65          "--output=$@ " +
66          "--align=4",
67    tools = ["//tools:embed_resources"],
68)
69
70# Note: These are defines that only impact the _bindings.cpp files in this folder.
71# Any defines that need to effect the entire Skia build should go in //bazel/BUILD.bazel
72CK_DEFINES = [
73    "CK_INCLUDE_PATHOPS",
74    "EMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES=0",  # Allows us to compile with -fno-rtti
75    "SK_DISABLE_LEGACY_PARAGRAPH_UNICODE=1",
76] + select({
77    ":enable_fonts_true": ["CK_INCLUDE_PARAGRAPH"],
78    ":enable_fonts_false": ["CK_NO_FONTS"],
79}) + select({
80    ":include_embedded_font_true": ["CK_EMBED_FONT"],
81    ":include_embedded_font_false": [],
82}) + select({
83    ":enable_skp_serialization_true": ["CK_SERIALIZE_SKP=1"],
84    ":enable_skp_serialization_false": [],
85}) + select({
86    ":enable_runtime_effect_true": ["CK_INCLUDE_RUNTIME_EFFECT=1"],
87    ":enable_runtime_effect_false": [],
88}) + select({
89    ":enable_webgl_true": ["CK_ENABLE_WEBGL"],
90    "//conditions:default": [],
91})
92
93CK_RELEASE_OPTS = [
94    "--closure 1",  # Run the closure compiler
95    # pass the externs file in
96    "--closure-args=--externs=$(location externs.js)",
97]
98
99CK_LINKOPTS = BASE_LINKOPTS + [
100    "-sEXPORT_NAME=CanvasKitInit",
101    "-sINITIAL_MEMORY=128MB",
102    # The order of these --pre-js flags matters! The preamble is a partially open scope and the
103    # postamble closes it. TODO(kjlubick) do we need to do it this way anymore?
104    "--pre-js",
105    "modules/canvaskit/preamble.js",
106    "--pre-js",
107    "modules/canvaskit/color.js",
108    "--pre-js",
109    "modules/canvaskit/memory.js",
110    "--pre-js",
111    "modules/canvaskit/util.js",
112    "--pre-js",
113    "modules/canvaskit/interface.js",
114    "--pre-js",
115    "modules/canvaskit/pathops.js",
116] + select({
117    ":enable_webgl_true": [
118        "--pre-js",
119        "modules/canvaskit/cpu.js",
120        "--pre-js",
121        "modules/canvaskit/webgl.js",
122    ],
123    "//conditions:default": [
124        "--pre-js",
125        "modules/canvaskit/cpu.js",
126    ],
127}) + select({
128    ":enable_fonts_true": [
129        "--pre-js",
130        "modules/canvaskit/font.js",
131        "--pre-js",
132        "modules/canvaskit/paragraph.js",
133    ],
134    ":enable_fonts_false": [],
135}) + select({
136    ":enable_canvas_polyfill_true": [
137        "--pre-js",
138        "modules/canvaskit/htmlcanvas/preamble.js",
139        "--pre-js",
140        "modules/canvaskit/htmlcanvas/util.js",
141        "--pre-js",
142        "modules/canvaskit/htmlcanvas/color.js",
143        "--pre-js",
144        "modules/canvaskit/htmlcanvas/font.js",
145        "--pre-js",
146        "modules/canvaskit/htmlcanvas/canvas2dcontext.js",
147        "--pre-js",
148        "modules/canvaskit/htmlcanvas/htmlcanvas.js",
149        "--pre-js",
150        "modules/canvaskit/htmlcanvas/htmlimage.js",
151        "--pre-js",
152        "modules/canvaskit/htmlcanvas/imagedata.js",
153        "--pre-js",
154        "modules/canvaskit/htmlcanvas/lineargradient.js",
155        "--pre-js",
156        "modules/canvaskit/htmlcanvas/path2d.js",
157        "--pre-js",
158        "modules/canvaskit/htmlcanvas/pattern.js",
159        "--pre-js",
160        "modules/canvaskit/htmlcanvas/radialgradient.js",
161        "--pre-js",
162        "modules/canvaskit/htmlcanvas/postamble.js",
163    ],
164    ":enable_canvas_polyfill_false": [],
165}) + select({
166    ":enable_skottie_true": [
167        "--pre-js",
168        "modules/canvaskit/skottie.js",
169    ],
170    ":enable_skottie_false": [],
171}) + select({
172    ":enable_skp_serialization_true": [
173        "--pre-js",
174        "modules/canvaskit/skp.js",
175    ],
176    ":enable_skp_serialization_false": [],
177}) + select({
178    ":enable_runtime_effect_true": [
179        "--pre-js",
180        "modules/canvaskit/rt_shader.js",
181    ],
182    ":enable_runtime_effect_false": [],
183}) + select({
184    ":build_for_debugger_true": [
185        "--pre-js",
186        "modules/canvaskit/debugger.js",
187    ],
188    ":build_for_debugger_false": [],
189}) + select({
190    ":include_matrix_js_true": [
191        "--pre-js",
192        "modules/canvaskit/matrix.js",
193    ],
194    ":include_matrix_js_false": [],
195}) + [
196    # This must come last
197    "--pre-js",
198    "modules/canvaskit/postamble.js",
199] + select({
200    "//bazel/common_config_settings:debug_build": DEBUG_OPTS + [
201        "--pre-js",
202        "modules/canvaskit/debug.js",
203    ],
204    "//conditions:default": RELEASE_OPTS + CK_RELEASE_OPTS + [
205        "--pre-js",
206        "modules/canvaskit/release.js",
207    ],
208})
209
210# All JS files that could possibly be included via --pre-js or --post-js.
211# Whether they actually will be or not will be controlled above in the construction of CK_LINKOPTS.
212JS_INTERFACE_FILES = [
213    "color.js",
214    "cpu.js",
215    "debug.js",
216    "font.js",
217    "interface.js",
218    "matrix.js",
219    "memory.js",
220    "paragraph.js",
221    "pathops.js",
222    "postamble.js",
223    "preamble.js",
224    "release.js",
225    "rt_shader.js",
226    "skottie.js",
227    "skp.js",
228    "util.js",
229    "webgl.js",
230    "webgpu.js",
231] + [
232    "htmlcanvas/canvas2dcontext.js",
233    "htmlcanvas/color.js",
234    "htmlcanvas/font.js",
235    "htmlcanvas/htmlcanvas.js",
236    "htmlcanvas/htmlimage.js",
237    "htmlcanvas/imagedata.js",
238    "htmlcanvas/lineargradient.js",
239    "htmlcanvas/path2d.js",
240    "htmlcanvas/pattern.js",
241    "htmlcanvas/postamble.js",
242    "htmlcanvas/preamble.js",
243    "htmlcanvas/radialgradient.js",
244    "htmlcanvas/util.js",
245] + select({
246    ":build_for_debugger_true": ["debugger.js"],
247    ":build_for_debugger_false": [],
248})
249
250CK_SRCS = [
251    "canvaskit_bindings.cpp",
252    ":hdrs",
253] + select({
254    ":include_embedded_font_true": ["fonts/NotoMono-Regular.ttf.bazel.cpp"],
255    ":include_embedded_font_false": [],
256}) + select({
257    ":enable_fonts_true": [
258        "paragraph_bindings.cpp",
259        "paragraph_bindings_gen.cpp",
260    ],
261    ":enable_fonts_false": [],
262}) + select({
263    ":enable_skottie_true": ["skottie_bindings.cpp"],
264    ":enable_skottie_false": [],
265}) + select({
266    ":build_for_debugger_true": ["debugger_bindings.cpp"],
267    ":build_for_debugger_false": [],
268})
269
270CK_COPTS = [
271    "-Wno-header-hygiene",
272]
273
274cc_binary(
275    name = "canvaskit.build",
276    srcs = CK_SRCS,
277    additional_linker_inputs = JS_INTERFACE_FILES + ["externs.js"],
278    copts = DEFAULT_COPTS + CK_COPTS,
279    linkopts = CK_LINKOPTS,
280    local_defines = CK_DEFINES,
281    # This target won't build successfully on its own because of missing emscripten
282    # headers etc. Therefore, we hide it from wildcards.
283    tags = ["manual"],
284    deps = [
285        "//:bmp_decode_codec",
286        "//:core",
287        "//:gif_decode_codec",
288        "//:ico_decode_codec",
289        "//:jpeg_decode_codec",
290        "//:jpeg_encode_codec",
291        "//:png_decode_codec",
292        "//:png_encode_codec",
293        "//:wbmp_decode_codec",
294        "//:webp_decode_codec",
295        "//:webp_encode_codec",
296        "//src/android:animated_image",
297    ] + select({
298        ":enable_fonts_true": [
299            "//:fontmgr_data_freetype",
300            "//:fontmgr_empty_freetype",
301            "//modules/skparagraph:skparagraph_harfbuzz_skunicode",
302            "//modules/skunicode:skunicode_icu",
303        ],
304        ":enable_fonts_false": [],
305    }) + select({
306        ":enable_skottie_true": [
307            "//:skshaper_harfbuzz",
308            "//:skshaper_unicode",
309            "//:skunicode_icu",
310            "//modules/skottie",
311            "//modules/skottie/utils:skottie_utils",
312            "//modules/skottie/utils:text_editor",
313        ],
314        ":enable_skottie_false": [],
315    }) + select({
316        ":build_for_debugger_true": [
317            "//tools/debugger",
318        ],
319        ":build_for_debugger_false": [],
320    }) + select({
321        ":enable_webgl_true": [
322            "//:ganesh_gl",
323            "//:ganesh_webgl_factory",
324        ],
325        "//conditions:default": [],
326    }),
327)
328
329wasm_cc_binary(
330    name = "canvaskit",
331    # Whatever is before the dot will be the name of the output js and wasm, aka "the stem".
332    # https://github.com/emscripten-core/emsdk/blob/82ad00499a42abde16b363239d2bc83bf5d863ab/bazel/emscripten_toolchain/wasm_cc_binary.bzl#L91
333    cc_target = ":canvaskit.build",
334    visibility = [
335        "//infra/debugger-app:__pkg__",
336        "//infra/jsfiddle:__pkg__",
337        "//infra/shaders:__pkg__",
338        "//infra/skottie:__pkg__",
339    ],
340)
341
342bool_flag(
343    name = "enable_canvas_polyfill",
344    default = False,
345)
346
347bool_flag(
348    name = "enable_fonts",
349    default = False,
350)
351
352bool_flag(
353    name = "include_embedded_font",
354    default = False,
355)
356
357bool_flag(
358    name = "include_matrix_js",
359    default = False,
360)
361
362bool_flag(
363    name = "enable_skottie",
364    default = False,
365)
366
367bool_flag(
368    name = "enable_skp_serialization",
369    default = False,
370)
371
372bool_flag(
373    name = "enable_runtime_effect",
374    default = False,
375)
376
377bool_flag(
378    name = "enable_webgl",
379    default = False,
380)
381
382bool_flag(
383    name = "build_for_debugger",
384    default = False,
385)
386
387karma_test(
388    name = "canvaskit_js_tests",
389    srcs = [
390        ":canvaskit/canvaskit.js",
391        # We want to make sure the CanvasKit JS is loaded before the loader script, so
392        # CanvasKitInit is defined. This loader script makes a promise...
393        "tests/init_with_gold_server.js",
394        "tests/util.js",
395        "tests/bazel_test_reporter.js",
396        # ...which is used by all of the tests
397        "tests/canvas_test.js",
398        "tests/canvas2d_test.js",
399        "tests/core_test.js",
400        "tests/font_test.js",
401        "tests/matrix_test.js",
402        "tests/paragraph_test.js",
403        "tests/path_test.js",
404        "tests/rtshader_test.js",
405        "tests/skottie_test.js",
406    ],
407    config_file = "karma.bazel.js",
408    # The tests need the Gold server to be up and running so they can make POST requests to
409    # exfiltrate the PNGs they create.
410    env = "//modules/canvaskit/go/gold_test_env:gold_test_env",
411    static_files = [
412        ":canvaskit/canvaskit.wasm",
413        "//modules/canvaskit/tests/assets:test_assets",
414    ],
415)
416
417genrule(
418    name = "make version file",
419    srcs = ["make_version.sh"],
420    outs = ["version.js"],
421    cmd = "$< $@",
422    # This script uses the Git executable, which is not on the remote builders.
423    # Forcing the execution to be local ensures it will be in the path.
424    local = True,
425    visibility = ["//infra:__subpackages__"],
426)
427