• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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": [
87        "CK_INCLUDE_RUNTIME_EFFECT=1",
88        "CK_DEBUG_TRACE_JSON=1",
89    ],
90    ":enable_runtime_effect_false": [],
91}) + select({
92    ":enable_webgl_true": ["CK_ENABLE_WEBGL"],
93    "//conditions:default": [],
94})
95
96CK_RELEASE_OPTS = [
97    "--closure 1",  # Run the closure compiler
98    # pass the externs file in
99    "--closure-args=--externs=$(location externs.js)",
100]
101
102CK_LINKOPTS = BASE_LINKOPTS + [
103    "-sEXPORT_NAME=CanvasKitInit",
104    "-sINITIAL_MEMORY=128MB",
105    # The order of these --pre-js flags matters! The preamble is a partially open scope and the
106    # postamble closes it. TODO(kjlubick) do we need to do it this way anymore?
107    "--pre-js",
108    "modules/canvaskit/preamble.js",
109    "--pre-js",
110    "modules/canvaskit/color.js",
111    "--pre-js",
112    "modules/canvaskit/memory.js",
113    "--pre-js",
114    "modules/canvaskit/util.js",
115    "--pre-js",
116    "modules/canvaskit/interface.js",
117    "--pre-js",
118    "modules/canvaskit/pathops.js",
119] + select({
120    ":enable_webgl_true": [
121        "--pre-js",
122        "modules/canvaskit/cpu.js",
123        "--pre-js",
124        "modules/canvaskit/webgl.js",
125    ],
126    "//conditions:default": [
127        "--pre-js",
128        "modules/canvaskit/cpu.js",
129    ],
130}) + select({
131    ":enable_fonts_true": [
132        "--pre-js",
133        "modules/canvaskit/font.js",
134        "--pre-js",
135        "modules/canvaskit/paragraph.js",
136    ],
137    ":enable_fonts_false": [],
138}) + select({
139    ":enable_canvas_polyfill_true": [
140        "--pre-js",
141        "modules/canvaskit/htmlcanvas/preamble.js",
142        "--pre-js",
143        "modules/canvaskit/htmlcanvas/util.js",
144        "--pre-js",
145        "modules/canvaskit/htmlcanvas/color.js",
146        "--pre-js",
147        "modules/canvaskit/htmlcanvas/font.js",
148        "--pre-js",
149        "modules/canvaskit/htmlcanvas/canvas2dcontext.js",
150        "--pre-js",
151        "modules/canvaskit/htmlcanvas/htmlcanvas.js",
152        "--pre-js",
153        "modules/canvaskit/htmlcanvas/htmlimage.js",
154        "--pre-js",
155        "modules/canvaskit/htmlcanvas/imagedata.js",
156        "--pre-js",
157        "modules/canvaskit/htmlcanvas/lineargradient.js",
158        "--pre-js",
159        "modules/canvaskit/htmlcanvas/path2d.js",
160        "--pre-js",
161        "modules/canvaskit/htmlcanvas/pattern.js",
162        "--pre-js",
163        "modules/canvaskit/htmlcanvas/radialgradient.js",
164        "--pre-js",
165        "modules/canvaskit/htmlcanvas/postamble.js",
166    ],
167    ":enable_canvas_polyfill_false": [],
168}) + select({
169    ":enable_skottie_true": [
170        "--pre-js",
171        "modules/canvaskit/skottie.js",
172    ],
173    ":enable_skottie_false": [],
174}) + select({
175    ":enable_skp_serialization_true": [
176        "--pre-js",
177        "modules/canvaskit/skp.js",
178    ],
179    ":enable_skp_serialization_false": [],
180}) + select({
181    ":enable_runtime_effect_true": [
182        "--pre-js",
183        "modules/canvaskit/rt_shader.js",
184    ],
185    ":enable_runtime_effect_false": [],
186}) + select({
187    ":build_for_debugger_true": [
188        "--pre-js",
189        "modules/canvaskit/debugger.js",
190    ],
191    ":build_for_debugger_false": [],
192}) + select({
193    ":include_matrix_js_true": [
194        "--pre-js",
195        "modules/canvaskit/matrix.js",
196    ],
197    ":include_matrix_js_false": [],
198}) + [
199    # This must come last
200    "--pre-js",
201    "modules/canvaskit/postamble.js",
202] + select({
203    "//bazel/common_config_settings:debug_build": DEBUG_OPTS + [
204        "--pre-js",
205        "modules/canvaskit/debug.js",
206    ],
207    "//conditions:default": RELEASE_OPTS + CK_RELEASE_OPTS + [
208        "--pre-js",
209        "modules/canvaskit/release.js",
210    ],
211})
212
213# All JS files that could possibly be included via --pre-js or --post-js.
214# Whether they actually will be or not will be controlled above in the construction of CK_LINKOPTS.
215JS_INTERFACE_FILES = [
216    "color.js",
217    "cpu.js",
218    "debug.js",
219    "font.js",
220    "interface.js",
221    "matrix.js",
222    "memory.js",
223    "paragraph.js",
224    "pathops.js",
225    "postamble.js",
226    "preamble.js",
227    "release.js",
228    "rt_shader.js",
229    "skottie.js",
230    "skp.js",
231    "util.js",
232    "webgl.js",
233    "webgpu.js",
234] + [
235    "htmlcanvas/canvas2dcontext.js",
236    "htmlcanvas/color.js",
237    "htmlcanvas/font.js",
238    "htmlcanvas/htmlcanvas.js",
239    "htmlcanvas/htmlimage.js",
240    "htmlcanvas/imagedata.js",
241    "htmlcanvas/lineargradient.js",
242    "htmlcanvas/path2d.js",
243    "htmlcanvas/pattern.js",
244    "htmlcanvas/postamble.js",
245    "htmlcanvas/preamble.js",
246    "htmlcanvas/radialgradient.js",
247    "htmlcanvas/util.js",
248] + select({
249    ":build_for_debugger_true": ["debugger.js"],
250    ":build_for_debugger_false": [],
251})
252
253CK_SRCS = [
254    "canvaskit_bindings.cpp",
255    ":hdrs",
256] + select({
257    ":include_embedded_font_true": ["fonts/NotoMono-Regular.ttf.bazel.cpp"],
258    ":include_embedded_font_false": [],
259}) + select({
260    ":enable_fonts_true": [
261        "paragraph_bindings.cpp",
262        "paragraph_bindings_gen.cpp",
263    ],
264    ":enable_fonts_false": [],
265}) + select({
266    ":enable_skottie_true": ["skottie_bindings.cpp"],
267    ":enable_skottie_false": [],
268}) + select({
269    ":build_for_debugger_true": ["debugger_bindings.cpp"],
270    ":build_for_debugger_false": [],
271})
272
273CK_COPTS = [
274    "-Wno-header-hygiene",
275]
276
277cc_binary(
278    name = "canvaskit.build",
279    srcs = CK_SRCS,
280    additional_linker_inputs = JS_INTERFACE_FILES + ["externs.js"],
281    copts = DEFAULT_COPTS + CK_COPTS,
282    linkopts = CK_LINKOPTS,
283    local_defines = CK_DEFINES,
284    # This target won't build successfully on its own because of missing emscripten
285    # headers etc. Therefore, we hide it from wildcards.
286    tags = ["manual"],
287    deps = [
288        "//:bmp_decode_codec",
289        "//:core",
290        "//:gif_decode_codec",
291        "//:ico_decode_codec",
292        "//:jpeg_decode_codec",
293        "//:jpeg_encode_codec",
294        "//:png_decode_codec",
295        "//:png_encode_codec",
296        "//:wbmp_decode_codec",
297        "//:webp_decode_codec",
298        "//:webp_encode_codec",
299        "//src/android:animated_image",
300    ] + select({
301        ":enable_fonts_true": [
302            "//:fontmgr_data_freetype",
303            "//:fontmgr_empty_freetype",
304            "//modules/skparagraph:skparagraph_harfbuzz_skunicode",
305            "//modules/skunicode:skunicode_icu",
306        ],
307        ":enable_fonts_false": [],
308    }) + select({
309        ":enable_skottie_true": [
310            "//:skshaper_harfbuzz",
311            "//:skshaper_unicode",
312            "//:skunicode_icu",
313            "//modules/skottie",
314            "//modules/skottie/utils:skottie_utils",
315            "//modules/skottie/utils:text_editor",
316        ],
317        ":enable_skottie_false": [],
318    }) + select({
319        ":build_for_debugger_true": [
320            "//tools/debugger",
321        ],
322        ":build_for_debugger_false": [],
323    }) + select({
324        ":enable_webgl_true": [
325            "//:ganesh_gl",
326            "//:ganesh_webgl_factory",
327        ],
328        "//conditions:default": [],
329    }) + select({
330        ":enable_runtime_effect_true": ["//tools/sksltrace:sksltraceutils"],
331        ":enable_runtime_effect_false": [],
332    }),
333)
334
335wasm_cc_binary(
336    name = "canvaskit",
337    # Whatever is before the dot will be the name of the output js and wasm, aka "the stem".
338    # https://github.com/emscripten-core/emsdk/blob/82ad00499a42abde16b363239d2bc83bf5d863ab/bazel/emscripten_toolchain/wasm_cc_binary.bzl#L91
339    cc_target = ":canvaskit.build",
340    visibility = [
341        "//infra/debugger-app:__pkg__",
342        "//infra/jsfiddle:__pkg__",
343        "//infra/shaders:__pkg__",
344        "//infra/skottie:__pkg__",
345    ],
346)
347
348bool_flag(
349    name = "enable_canvas_polyfill",
350    default = False,
351)
352
353bool_flag(
354    name = "enable_fonts",
355    default = False,
356)
357
358bool_flag(
359    name = "include_embedded_font",
360    default = False,
361)
362
363bool_flag(
364    name = "include_matrix_js",
365    default = False,
366)
367
368bool_flag(
369    name = "enable_skottie",
370    default = False,
371)
372
373bool_flag(
374    name = "enable_skp_serialization",
375    default = False,
376)
377
378bool_flag(
379    name = "enable_runtime_effect",
380    default = False,
381)
382
383bool_flag(
384    name = "enable_webgl",
385    default = False,
386)
387
388bool_flag(
389    name = "build_for_debugger",
390    default = False,
391)
392
393karma_test(
394    name = "canvaskit_js_tests",
395    srcs = [
396        ":canvaskit/canvaskit.js",
397        # We want to make sure the CanvasKit JS is loaded before the loader script, so
398        # CanvasKitInit is defined. This loader script makes a promise...
399        "tests/init_with_gold_server.js",
400        "tests/util.js",
401        "tests/bazel_test_reporter.js",
402        # ...which is used by all of the tests
403        "tests/canvas_test.js",
404        "tests/canvas2d_test.js",
405        "tests/core_test.js",
406        "tests/font_test.js",
407        "tests/matrix_test.js",
408        "tests/paragraph_test.js",
409        "tests/path_test.js",
410        "tests/rtshader_test.js",
411        "tests/skottie_test.js",
412    ],
413    config_file = "karma.bazel.js",
414    # The tests need the Gold server to be up and running so they can make POST requests to
415    # exfiltrate the PNGs they create.
416    env = "//modules/canvaskit/go/gold_test_env:gold_test_env",
417    static_files = [
418        ":canvaskit/canvaskit.wasm",
419        "//modules/canvaskit/tests/assets:test_assets",
420    ],
421)
422
423genrule(
424    name = "make version file",
425    srcs = ["make_version.sh"],
426    outs = ["version.js"],
427    cmd = "$< $@",
428    # This script uses the Git executable, which is not on the remote builders.
429    # Forcing the execution to be local ensures it will be in the path.
430    local = True,
431    visibility = ["//infra:__subpackages__"],
432)
433