• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2016 Google Inc.
2#
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6import("gn/codec.gni")
7import("gn/fuchsia_defines.gni")
8import("gn/shared_sources.gni")
9import("gn/skia.gni")
10import("gn/toolchain/wasm.gni")
11
12if (is_fuchsia) {
13  import("//build/fuchsia/sdk.gni")
14  import("build/fuchsia/fuchsia_download_sdk.gni")
15}
16
17if (skia_use_dawn) {
18  import("//third_party/externals/dawn/scripts/dawn_features.gni")
19}
20
21if (defined(skia_settings)) {
22  import(skia_settings)
23}
24
25import("gn/ios.gni")
26
27# Skia public API, generally provided by :skia.
28config("skia_public") {
29  include_dirs = [ "." ]
30
31  defines = [
32    "SK_CODEC_DECODES_BMP",
33    "SK_CODEC_DECODES_WBMP",
34  ]
35  cflags_objcc = []
36  if (is_component_build) {
37    defines += [ "SKIA_DLL" ]
38  }
39  if (is_fuchsia || is_linux) {
40    defines += [ "SK_R32_SHIFT=16" ]
41  }
42  if (skia_enable_optimize_size) {
43    defines += [ "SK_ENABLE_OPTIMIZE_SIZE" ]
44  }
45  if (skia_enable_precompile) {
46    defines += [ "SK_ENABLE_PRECOMPILE" ]
47  }
48  if (is_fuchsia) {
49    defines += fuchsia_defines
50  }
51  if (is_wasm) {
52    defines += wasm_defines
53  }
54  if (skia_gl_standard == "gles") {
55    defines += [ "SK_ASSUME_GL_ES=1" ]
56  } else if (skia_gl_standard == "gl") {
57    defines += [ "SK_ASSUME_GL=1" ]
58  } else if (skia_gl_standard == "webgl") {
59    defines += [ "SK_ASSUME_WEBGL=1" ]
60  }
61  if (skia_enable_ganesh) {
62    defines += [ "SK_GANESH" ]
63  }
64  if (skia_enable_graphite) {
65    defines += [ "SK_GRAPHITE" ]
66  }
67  if (skia_disable_tracing) {
68    defines += [ "SK_DISABLE_TRACING" ]
69  }
70  if (skia_use_perfetto) {
71    defines += [ "SK_USE_PERFETTO" ]
72  }
73  if (skia_use_safe_libcxx) {
74    defines += [ "_LIBCPP_ENABLE_ASSERTIONS=1" ]
75  }
76
77  # Some older versions of the Clang toolchain change the visibility of
78  # symbols decorated with API_AVAILABLE macro to be visible. Users of such
79  # toolchains suppress the use of this macro till toolchain updates are made.
80  if (is_mac || is_ios) {
81    if (skia_enable_api_available_macro) {
82      defines += [ "SK_ENABLE_API_AVAILABLE" ]
83    } else {
84      cflags_objcc += [ "-Wno-unguarded-availability" ]
85    }
86  }
87}
88
89# Skia internal APIs, used by Skia itself and a few test tools.
90config("skia_private") {
91  visibility = [ "./*" ]
92
93  defines = [ "SK_GAMMA_APPLY_TO_A8" ]
94  if (skia_use_fixed_gamma_text) {
95    defines += [
96      "SK_GAMMA_EXPONENT=1.4",
97      "SK_GAMMA_CONTRAST=0.0",
98    ]
99  }
100  if (is_skia_dev_build && !is_wasm) {
101    defines += [
102      "SK_ALLOW_STATIC_GLOBAL_INITIALIZERS=1",
103      "GPU_TEST_UTILS=1",
104    ]
105  }
106  libs = []
107  lib_dirs = []
108  if (skia_use_gl && skia_use_angle) {
109    defines += [ "SK_ANGLE" ]
110  }
111  if (skia_use_vma) {
112    defines += [ "SK_USE_VMA" ]
113  }
114  if (skia_enable_winuwp) {
115    defines += [ "SK_WINUWP" ]
116  }
117  if (skia_print_sksl_shaders) {
118    defines += [ "SK_PRINT_SKSL_SHADERS" ]
119  }
120  if (skia_print_native_shaders) {
121    defines += [ "SK_PRINT_NATIVE_SHADERS" ]
122  }
123
124  # Temporary staging flag:
125  defines += [ "SK_ENABLE_AVX512_OPTS" ]
126}
127
128# Any code that's linked into Skia-the-library should use this config via += skia_library_configs.
129config("skia_library") {
130  visibility = [ "./*" ]
131  defines = [ "SKIA_IMPLEMENTATION=1" ]
132}
133
134skia_library_configs = [
135  ":skia_public",
136  ":skia_private",
137  ":skia_library",
138]
139
140# Use for CPU-specific Skia code that needs particular compiler flags.
141template("opts") {
142  if (invoker.enabled) {
143    skia_source_set(target_name) {
144      visibility = [ ":*" ]
145      check_includes = false
146      configs = skia_library_configs
147      forward_variables_from(invoker, "*")
148      if (defined(invoker.configs)) {
149        configs += invoker.configs
150      }
151    }
152  } else {
153    # If not enabled, a phony empty target that swallows all otherwise unused variables.
154    skia_source_set(target_name) {
155      visibility = [ ":*" ]
156      check_includes = false
157      forward_variables_from(invoker,
158                             "*",
159                             [
160                               "sources",
161                               "cflags",
162                             ])
163    }
164  }
165}
166
167is_x86 = current_cpu == "x64" || current_cpu == "x86"
168is_loong64 = current_cpu == "loong64"
169
170opts("hsw") {
171  enabled = is_x86
172  sources = skia_opts.hsw_sources
173  if (is_win) {
174    cflags = [ "/arch:AVX2" ]
175  } else {
176    cflags = [ "-march=haswell" ]
177  }
178}
179
180opts("skx") {
181  enabled = is_x86
182  sources = skia_opts.skx_sources
183  if (is_win) {
184    cflags = [ "/arch:AVX512" ]
185  } else {
186    cflags = [ "-march=skylake-avx512" ]
187  }
188}
189
190opts("lasx") {
191  enabled = is_loong64
192  sources = skia_opts.lasx_sources
193  cflags = [ "-mlasx" ]
194}
195
196# Any feature of Skia that requires third-party code should be optional and use this template.
197template("optional") {
198  if (invoker.enabled) {
199    config(target_name + "_public") {
200      if (defined(invoker.public_defines)) {
201        defines = invoker.public_defines
202      }
203      if (defined(invoker.public_configs)) {
204        configs = invoker.public_configs
205      }
206    }
207    skia_source_set(target_name) {
208      visibility = [ ":*" ]
209      check_includes = false
210      configs = skia_library_configs
211
212      # "*" clobbers the current scope; append to existing configs
213      forward_variables_from(invoker,
214                             "*",
215                             [
216                               "configs",
217                               "public_defines",
218                               "sources_for_tests",
219                               "sources_when_disabled",
220                             ])
221      if (defined(invoker.configs)) {
222        configs += invoker.configs
223      }
224      all_dependent_configs = [ ":" + target_name + "_public" ]
225    }
226    if (defined(invoker.sources_for_tests) && skia_enable_tools) {
227      skia_source_set(target_name + "_tests") {
228        visibility = [ ":*" ]
229        check_includes = false
230        configs = skia_library_configs
231
232        # "*" clobbers the current scope; append to existing configs
233        forward_variables_from(invoker,
234                               "*",
235                               [
236                                 "configs",
237                                 "public_defines",
238                                 "sources",
239                                 "sources_for_tests",
240                                 "sources_when_disabled",
241                               ])
242        if (defined(invoker.configs)) {
243          configs += invoker.configs
244        }
245        testonly = true
246        sources = invoker.sources_for_tests
247        if (!defined(deps)) {
248          deps = []
249        }
250        deps += [
251          ":test",
252          ":" + target_name,
253        ]
254        all_dependent_configs = [ ":" + target_name + "_public" ]
255      }
256    }
257  } else {
258    skia_source_set(target_name) {
259      visibility = [ ":*" ]
260      configs = skia_library_configs
261
262      # "*" clobbers the current scope; append to existing configs
263      forward_variables_from(invoker,
264                             "*",
265                             [
266                               "configs",
267                               "public",
268                               "public_defines",
269                               "public_deps",
270                               "deps",
271                               "libs",
272                               "frameworks",
273                               "sources",
274                               "sources_for_tests",
275                               "sources_when_disabled",
276                             ])
277      if (defined(invoker.configs)) {
278        configs += invoker.configs
279      }
280      if (defined(invoker.sources_when_disabled)) {
281        sources = invoker.sources_when_disabled
282      }
283    }
284    if (defined(invoker.sources_for_tests)) {
285      skia_source_set(target_name + "_tests") {
286        visibility = [ ":*" ]
287      }
288    }
289  }
290}
291
292optional("android_utils") {
293  enabled = skia_enable_android_utils
294
295  public = [
296    "client_utils/android/BRDAllocator.h",
297    "client_utils/android/BitmapRegionDecoder.h",
298    "client_utils/android/FrontBufferedStream.h",
299  ]
300  public_defines = [ "SK_ENABLE_ANDROID_UTILS" ]
301  sources = [
302    "client_utils/android/BitmapRegionDecoder.cpp",
303    "client_utils/android/FrontBufferedStream.cpp",
304  ]
305}
306
307optional("fontmgr_android") {
308  enabled = skia_enable_fontmgr_android
309
310  deps = [
311    ":typeface_freetype",
312    ":typeface_proxy",
313    "//third_party/expat",
314  ]
315  public_defines = [ "SK_FONTMGR_ANDROID_AVAILABLE" ]
316  public = skia_ports_fontmgr_android_public
317  sources = skia_ports_fontmgr_android_sources
318  sources_for_tests = [ "tests/FontMgrAndroidParserTest.cpp" ]
319}
320
321# if building Skia for API >= 30 and not using custom fonts, enable
322# skia_enable_fontmgr_android_ndk and disable skia_enable_fontmgr_android
323optional("fontmgr_android_ndk") {
324  enabled = skia_enable_fontmgr_android_ndk
325
326  deps = [
327    ":typeface_freetype",
328    ":typeface_proxy",
329  ]
330  libs = [ "android" ]
331  public_defines = [ "SK_FONTMGR_ANDROID_NDK_AVAILABLE" ]
332  public = skia_ports_fontmgr_android_ndk_public
333  sources = skia_ports_fontmgr_android_ndk_sources
334}
335
336optional("fontmgr_custom") {
337  enabled =
338      skia_enable_fontmgr_custom_directory ||
339      skia_enable_fontmgr_custom_embedded || skia_enable_fontmgr_custom_empty
340
341  deps = [ ":typeface_freetype" ]
342  sources = skia_ports_fontmgr_custom_sources
343}
344
345optional("fontmgr_custom_directory") {
346  enabled = skia_enable_fontmgr_custom_directory
347  public_defines = [ "SK_FONTMGR_FREETYPE_DIRECTORY_AVAILABLE" ]
348  deps = [
349    ":fontmgr_custom",
350    ":typeface_freetype",
351  ]
352  public = skia_ports_fontmgr_directory_public
353  sources = skia_ports_fontmgr_directory_sources
354}
355
356optional("fontmgr_custom_embedded") {
357  enabled = skia_enable_fontmgr_custom_embedded
358  public_defines = [ "SK_FONTMGR_FREETYPE_EMBEDDED_AVAILABLE" ]
359  deps = [
360    ":fontmgr_custom",
361    ":typeface_freetype",
362  ]
363  public = skia_ports_fontmgr_embedded_public
364  sources = skia_ports_fontmgr_embedded_sources
365}
366
367optional("fontmgr_custom_empty") {
368  enabled = skia_enable_fontmgr_custom_empty
369  public_defines = [ "SK_FONTMGR_FREETYPE_EMPTY_AVAILABLE" ]
370  deps = [
371    ":fontmgr_custom",
372    ":typeface_freetype",
373  ]
374  public = skia_ports_fontmgr_empty_public
375  sources = skia_ports_fontmgr_empty_sources
376}
377
378skia_source_set("typeface_proxy") {
379  configs = [ ":skia_public" ]
380  sources = skia_ports_typeface_proxy_sources
381}
382
383optional("fontmgr_fontconfig") {
384  enabled = skia_enable_fontmgr_fontconfig
385  public_defines = [ "SK_FONTMGR_FONTCONFIG_AVAILABLE" ]
386
387  # The public header includes fontconfig.h and uses FcConfig*
388  public_deps = [ "//third_party:fontconfig" ]
389  public = skia_ports_fontmgr_fontconfig_public
390  deps = [
391    ":typeface_freetype",
392    ":typeface_proxy",
393  ]
394  sources = skia_ports_fontmgr_fontconfig_sources
395  sources_for_tests = [ "tests/FontMgrFontConfigTest.cpp" ]
396}
397
398skia_source_set("fontscanner_tests") {
399  testonly = true
400
401  deps = [ ":skia" ]
402  sources = [
403    "tests/FontScanner.cpp",
404    "tests/FontScanner.h",
405  ]
406}
407
408optional("fontmgr_FontConfigInterface") {
409  enabled = skia_enable_fontmgr_FontConfigInterface
410  public_defines = [ "SK_FONTMGR_FCI_AVAILABLE" ]
411  deps = [
412    ":typeface_freetype",
413    "//third_party:fontconfig",
414  ]
415  public = skia_ports_fci_public
416  sources = skia_ports_fci_sources
417  sources_for_tests = [ "tests/FCITest.cpp" ]
418}
419
420optional("fontmgr_fontations_empty") {
421  enabled = skia_use_fontations
422  public_defines = [ "SK_FONTMGR_FONTATIONS_AVAILABLE" ]
423
424  deps = [ ":typeface_fontations" ]
425  public = skia_ports_fontmgr_fontations_public
426  sources = skia_ports_fontmgr_fontations_sources
427}
428
429optional("fontmgr_fuchsia") {
430  enabled = skia_enable_fontmgr_fuchsia
431  public_defines = [ "SK_FONTMGR_FUCHSIA_AVAILABLE" ]
432  deps = []
433
434  if (is_fuchsia && using_fuchsia_sdk) {
435    deps += [ "//build/fuchsia/fidl:fuchsia.fonts" ]
436  } else {
437    deps = [ "//sdk/fidl/fuchsia.fonts" ]
438  }
439  public = skia_ports_fontmgr_fuchsia_public
440  sources = skia_ports_fontmgr_fuchsia_sources
441}
442
443optional("fontmgr_mac_ct") {
444  enabled = skia_use_fonthost_mac
445
446  public_defines = [
447    "SK_TYPEFACE_FACTORY_CORETEXT",
448    "SK_FONTMGR_CORETEXT_AVAILABLE",
449  ]
450  public = skia_ports_fontmgr_coretext_public
451  sources = skia_ports_fontmgr_coretext_sources
452  sources_for_tests = [ "tests/TypefaceMacTest.cpp" ]
453
454  if (is_mac) {
455    frameworks = [
456      # AppKit symbols NSFontWeightXXX may be dlsym'ed.
457      "AppKit.framework",
458      "ApplicationServices.framework",
459    ]
460  }
461
462  if (is_ios) {
463    frameworks = [
464      "CoreFoundation.framework",
465      "CoreGraphics.framework",
466      "CoreText.framework",
467
468      # UIKit symbols UIFontWeightXXX may be dlsym'ed.
469      "UIKit.framework",
470    ]
471  }
472}
473
474optional("fontmgr_win") {
475  enabled = skia_enable_fontmgr_win
476
477  public_defines = [
478    "SK_TYPEFACE_FACTORY_DIRECTWRITE",
479    "SK_FONTMGR_DIRECTWRITE_AVAILABLE",
480  ]
481  public = skia_ports_windows_fonts_public
482  sources = skia_ports_windows_fonts_sources
483  if (skia_dwritecore_sdk != "") {
484    defines = [ "DWRITE_CORE" ]
485    if (is_win && is_clang) {
486      # Clang complains about these headers, so mark them as system. These
487      # headers are hiding SDK headers of the same name, which are also
488      # included as system headers, so these need to go first in the cflags
489      # "includes" before the SDK. gn appends configs in the order listed,
490      # so these flags will be first.
491      cflags = [
492        "-imsvc",
493        "${skia_dwritecore_sdk}/include",
494      ]
495    } else {
496      include_dirs = [ "${skia_dwritecore_sdk}/include" ]
497    }
498  }
499}
500
501optional("fontmgr_win_gdi") {
502  enabled = skia_enable_fontmgr_win_gdi
503  public_defines = [ "SK_FONTMGR_GDI_AVAILABLE" ]
504  public = skia_ports_windows_fonts_public
505  sources = skia_ports_fonthost_win_sources
506  libs = [ "Gdi32.lib" ]
507}
508
509if (skia_lex) {
510  skia_executable("sksllex") {
511    sources = [
512      "src/sksl/lex/DFA.h",
513      "src/sksl/lex/DFAState.h",
514      "src/sksl/lex/LexUtil.h",
515      "src/sksl/lex/Main.cpp",
516      "src/sksl/lex/NFA.cpp",
517      "src/sksl/lex/NFA.h",
518      "src/sksl/lex/NFAState.h",
519      "src/sksl/lex/NFAtoDFA.h",
520      "src/sksl/lex/RegexNode.cpp",
521      "src/sksl/lex/RegexNode.h",
522      "src/sksl/lex/RegexParser.cpp",
523      "src/sksl/lex/RegexParser.h",
524      "src/sksl/lex/TransitionTable.cpp",
525      "src/sksl/lex/TransitionTable.h",
526    ]
527    include_dirs = [ "." ]
528  }
529
530  action("run_sksllex") {
531    script = "gn/run_sksllex.py"
532    deps = [ ":sksllex(//gn/toolchain:$host_toolchain)" ]
533    sources = [ "src/sksl/lex/sksl.lex" ]
534
535    # GN insists its outputs should go somewhere underneath target_out_dir, so we trick it with a
536    # path that starts with target_out_dir and then uses ".." to back up into the src dir.
537    outputs = [
538      "$target_out_dir/" + rebase_path("src/sksl/SkSLLexer.h", target_out_dir),
539      # the script also modifies the corresponding .cpp file, but if we tell GN that it gets
540      # confused due to the same file being named by two different paths
541    ]
542    sksllex_path = "$root_out_dir/"
543    if (host_toolchain != default_toolchain_name) {
544      sksllex_path += "$host_toolchain/"
545    }
546    sksllex_path += "sksllex"
547    if (host_os == "win") {
548      sksllex_path += ".exe"
549    }
550    args = [
551      rebase_path(sksllex_path),
552      rebase_path("bin/clang-format"),
553      rebase_path("bin/fetch-clang-format"),
554      rebase_path("src"),
555    ]
556  }
557} else {
558  group("run_sksllex") {
559  }
560}
561
562if (skia_compile_modules || skia_compile_sksl_tests) {
563  # Copy the module source files into the same directory as skslc.
564  copy("sksl_modules") {
565    sources = [
566      "src/sksl/sksl_compute.sksl",
567      "src/sksl/sksl_frag.sksl",
568      "src/sksl/sksl_gpu.sksl",
569      "src/sksl/sksl_graphite_frag.sksl",
570      "src/sksl/sksl_graphite_frag_es2.sksl",
571      "src/sksl/sksl_graphite_vert.sksl",
572      "src/sksl/sksl_graphite_vert_es2.sksl",
573      "src/sksl/sksl_public.sksl",
574      "src/sksl/sksl_rt_shader.sksl",
575      "src/sksl/sksl_shared.sksl",
576      "src/sksl/sksl_vert.sksl",
577    ]
578    skslc_dir = "$root_out_dir/"
579    if (host_toolchain != default_toolchain_name) {
580      skslc_dir += "$host_toolchain/"
581    }
582    outputs = [ "$skslc_dir/{{source_file_part}}" ]
583  }
584}
585
586if (skia_compile_modules) {
587  # Generate the sksl-minify binary.
588  skia_executable("sksl-minify") {
589    defines = [
590      "SKSL_STANDALONE",
591      "SK_DISABLE_TRACING",
592    ]
593    sources = skslc_deps
594    sources += [
595      "tools/sksl-minify/SkSLMinify.cpp",
596      "tools/skslc/ProcessWorklist.cpp",
597      "tools/skslc/ProcessWorklist.h",
598    ]
599    libs = []
600    if (is_win) {
601      sources += [ "src/utils/SkGetExecutablePath_win.cpp" ]
602    } else if (is_mac || is_ios) {
603      sources += [ "src/utils/SkGetExecutablePath_mac.cpp" ]
604    } else if (is_linux || is_android) {
605      sources += [ "src/utils/SkGetExecutablePath_linux.cpp" ]
606    }
607    if (is_win) {
608      sources += skia_ports_windows_sources
609    } else {
610      sources += [ "src/ports/SkOSFile_posix.cpp" ]
611      libs += [ "dl" ]
612    }
613    sources += skia_sksl_core_sources
614    sources += skia_sksl_codegen_sources
615    include_dirs = [ "." ]
616    deps = [ ":run_sksllex" ]
617  }
618
619  sksl_minify_path = "$root_out_dir/"
620  if (host_toolchain != default_toolchain_name) {
621    sksl_minify_path += "$host_toolchain/"
622  }
623  sksl_minify_path += "sksl-minify"
624  if (host_os == "win") {
625    sksl_minify_path += ".exe"
626  }
627
628  # Use minify_sksl.py to precompile all of the modules.
629  minify_sksl_sources = get_target_outputs(":sksl_modules")
630
631  minify_sksl_outputs = []
632  foreach(src, minify_sksl_sources) {
633    name = get_path_info(src, "name")
634
635    # GN insists its outputs should go somewhere underneath target_out_dir, so we trick it with a
636    # path that starts with target_out_dir and then uses ".." to back up into the src dir.
637    minify_sksl_outputs += [ "$target_out_dir/" + rebase_path(
638                                 "src/sksl/generated/$name.minified.sksl",
639                                 target_out_dir) ]
640    minify_sksl_outputs += [ "$target_out_dir/" + rebase_path(
641                                 "src/sksl/generated/$name.unoptimized.sksl",
642                                 target_out_dir) ]
643  }
644
645  action("minify_sksl") {
646    script = "gn/minify_sksl.py"
647    deps = [
648      ":sksl-minify(//gn/toolchain:$host_toolchain)",
649      ":sksl_modules",
650    ]
651    sources = minify_sksl_sources
652    outputs = minify_sksl_outputs
653    args = [
654      rebase_path(sksl_minify_path),
655      rebase_path("src/sksl/generated"),
656    ]
657    args += rebase_path(minify_sksl_sources)
658  }
659
660  if (skia_compile_sksl_tests) {
661    # Minify our existing .rts files into golden minified outputs.
662    import("gn/sksl_tests.gni")
663    action("minify_sksl_tests") {
664      script = "gn/minify_sksl_tests.py"
665      deps = [
666        ":sksl-minify(//gn/toolchain:$host_toolchain)",
667        ":sksl_modules",
668      ]
669      sources = []
670      outputs = []
671      response_file_contents = []
672      args = [
673        # Comments match the variable names in minify_sksl_tests.py
674        rebase_path(sksl_minify_path),  # sksl_minify
675        rebase_path("src/sksl/sksl_shared.sksl"),  # shared_module
676        rebase_path("src/sksl/sksl_public.sksl"),  # public_module
677        rebase_path("src/sksl/sksl_rt_shader.sksl"),  # public_module
678        rebase_path("resources"),  # input_root_dir
679        rebase_path("tests"),  # output_root_dir
680        "{{response_file_name}}",  # input_file
681      ]
682
683      testsDir = get_path_info("tests/sksl/", "abspath")
684      resourcesDir = get_path_info("resources/sksl/", "abspath")
685
686      foreach(partialPath, sksl_minify_tests_sources) {
687        dst = testsDir + partialPath
688        src = resourcesDir + partialPath
689
690        dir = get_path_info(dst, "dir")
691        name = get_path_info(dst, "name")
692        ext = get_path_info(dst, "extension")
693        if (ext == "rts" || ext == "privrts" || ext == "rtcf" || ext == "rtb" ||
694            ext == "mfrag" || ext == "mvert") {
695          response_file_contents += [ rebase_path(src) ]
696          sources += [ src ]
697          outputs += [ target_out_dir + "/" +
698                       rebase_path(dir + "/" + name + ".minified.sksl",
699                                   target_out_dir) ]
700        }
701      }
702    }
703  }
704} else {
705  group("minify_sksl") {
706  }
707  group("minify_sksl_tests") {
708  }
709}
710
711# `Compile SkSL Tests` relies on skslc and the precompiled modules.
712if (skia_compile_sksl_tests) {
713  # Build skslc.
714  skia_executable("skslc") {
715    defines = [
716      "SKSL_STANDALONE",
717      "SK_DISABLE_TRACING",
718      "SK_COMPILE_WITH_GN",
719    ]
720    sources = skslc_deps
721    sources += [
722      "tools/skslc/Main.cpp",
723      "tools/skslc/ProcessWorklist.cpp",
724      "tools/skslc/ProcessWorklist.h",
725    ]
726    libs = []
727    if (is_win) {
728      sources += [ "src/utils/SkGetExecutablePath_win.cpp" ]
729    } else if (is_mac || is_ios) {
730      sources += [ "src/utils/SkGetExecutablePath_mac.cpp" ]
731    } else if (is_linux || is_android) {
732      sources += [ "src/utils/SkGetExecutablePath_linux.cpp" ]
733    }
734    if (is_win) {
735      sources += skia_ports_windows_sources
736    } else {
737      sources += [ "src/ports/SkOSFile_posix.cpp" ]
738      libs += [ "dl" ]
739    }
740    sources += skia_sksl_codegen_sources
741    sources += skia_sksl_core_sources
742    sources += skia_sksl_hlsl_sources
743    sources += skia_sksl_pipeline_sources
744    sources += skia_sksl_tracing_sources
745    sources += skia_sksl_validate_spirv_sources
746    sources += skia_sksl_validate_wgsl_sources
747    include_dirs = [ "." ]
748    deps = [
749      ":run_sksllex",
750      "//third_party/externals/dawn/src/tint/api:api",
751      "//third_party/externals/spirv-tools:spvtools",
752      "//third_party/externals/spirv-tools:spvtools_val",
753      "//third_party/spirv-cross:spirv_cross",
754    ]
755  }
756
757  skslc_path = "$root_out_dir/"
758  if (host_toolchain != default_toolchain_name) {
759    skslc_path += "$host_toolchain/"
760  }
761  skslc_path += "skslc"
762  if (host_os == "win") {
763    skslc_path += ".exe"
764  }
765
766  # Build the test files using skslc.
767  import("gn/sksl_tests.gni")
768  template("compile_sksl") {
769    # Compile the passed-in `sources` into `outputs` using skslc, with the given language/settings.
770    action("compile_sksl_${target_name}") {
771      script = "gn/compile_sksl_tests.py"
772      deps = [
773        ":sksl_modules",
774        ":skslc(//gn/toolchain:$host_toolchain)",
775      ]
776      sources = []
777      outputs = []
778      response_file_contents = []
779      args = [
780        # Comments are the variable name in compile_sksl_tests.py
781        rebase_path(skslc_path),  # skslc
782        invoker.lang,  # lang
783        invoker.settings,  # settings
784        rebase_path("resources"),  # input_root_dir
785        rebase_path("tests"),  # output_root_dir
786        "{{response_file_name}}",  # input_file
787      ]
788
789      testsDir = get_path_info("tests/sksl/", "abspath")
790      resourcesDir = get_path_info("resources/sksl/", "abspath")
791
792      foreach(partialPath, invoker.sources) {
793        dst = testsDir + partialPath
794        src = resourcesDir + partialPath
795
796        dir = get_path_info(dst, "dir")
797        name = get_path_info(dst, "name")
798        ext = get_path_info(dst, "extension")
799        response_file_contents += [ rebase_path(src) ]
800        sources += [ src ]
801
802        foreach(outExtension, invoker.outExtensions) {
803          # SPIR-V uses separate extensions for .vert and .compute shaders.
804          if (ext == "vert" && outExtension == ".asm.frag") {
805            outExtension = ".asm.vert"
806          } else if (ext == "compute" && outExtension == ".asm.frag") {
807            outExtension = ".asm.comp"
808          }
809          outputs +=
810              [ target_out_dir + "/" +
811                rebase_path(dir + "/" + name + outExtension, target_out_dir) ]
812        }
813      }
814    }
815  }
816  compile_sksl("glsl_tests") {
817    sources = sksl_glsl_tests_sources + sksl_glsl_settings_tests_sources
818    outExtensions = [ ".glsl" ]
819    lang = "--glsl"
820    settings = "--settings"
821  }
822  compile_sksl("glsl_nosettings_tests") {
823    sources = sksl_glsl_settings_tests_sources
824    outExtensions = [ "StandaloneSettings.glsl" ]
825    lang = "--glsl"
826    settings = "--nosettings"
827  }
828  compile_sksl("metal_tests") {
829    sources = sksl_metal_tests_sources
830    outExtensions = [ ".metal" ]
831    lang = "--metal"
832    settings = "--settings"
833  }
834  compile_sksl("hlsl_tests") {
835    sources = sksl_hlsl_tests_sources
836    outExtensions = [ ".hlsl" ]
837    lang = "--hlsl"
838    settings = "--settings"
839  }
840  compile_sksl("skrp_tests") {
841    sources = sksl_skrp_tests_sources
842    outExtensions = [ ".skrp" ]
843    lang = "--skrp"
844    settings = "--settings"
845  }
846  compile_sksl("stage_tests") {
847    sources = sksl_stage_tests_sources
848    outExtensions = [ ".stage" ]
849    lang = "--stage"
850    settings = "--settings"
851  }
852  compile_sksl("spirv_tests") {
853    sources = sksl_spirv_tests_sources
854    outExtensions = [ ".asm.frag" ]
855    lang = "--spirv"
856    settings = "--settings"
857  }
858  compile_sksl("wgsl_tests") {
859    sources = sksl_wgsl_tests_sources
860    outExtensions = [ ".wgsl" ]
861    lang = "--wgsl"
862    settings = "--settings"
863  }
864} else {
865  group("compile_sksl_glsl_tests") {
866  }
867  group("compile_sksl_glsl_nosettings_tests") {
868  }
869  group("compile_sksl_metal_tests") {
870  }
871  group("compile_sksl_hlsl_tests") {
872  }
873  group("compile_sksl_skrp_tests") {
874  }
875  group("compile_sksl_spirv_tests") {
876  }
877  group("compile_sksl_wgsl_tests") {
878  }
879}
880
881group("compile_all_sksl_tests") {
882  deps = [
883    ":compile_sksl_glsl_nosettings_tests",
884    ":compile_sksl_glsl_tests",
885    ":compile_sksl_hlsl_tests",
886    ":compile_sksl_metal_tests",
887    ":compile_sksl_skrp_tests",
888    ":compile_sksl_spirv_tests",
889    ":compile_sksl_wgsl_tests",
890  ]
891}
892
893optional("gpu_shared") {
894  enabled = skia_enable_ganesh || skia_enable_graphite
895
896  configs = []
897  deps = []
898  libs = []
899  public_defines = []
900  public_deps = []
901  frameworks = []
902
903  sources = skia_shared_gpu_sources
904  sources += skia_sksl_pipeline_sources
905  sources += skia_sksl_codegen_sources
906
907  if (skia_use_dawn) {
908    public_defines += [ "SK_DAWN" ]
909
910    # When building for WASM, the WebGPU headers are provided by Emscripten. For native builds we
911    # have to depend on Dawn directly.
912    if (!skia_use_webgpu) {
913      public_deps += [
914        "//third_party/externals/dawn/include/dawn:cpp_headers",
915        "//third_party/externals/dawn/src/dawn:cpp",
916        "//third_party/externals/dawn/src/dawn:proc",
917      ]
918
919      if (dawn_enable_d3d12 || dawn_enable_d3d11 || dawn_enable_desktop_gl ||
920          dawn_enable_metal || dawn_enable_opengles || dawn_enable_vulkan) {
921        public_deps += [ "//third_party/externals/dawn/src/dawn/native" ]
922      }
923      if (dawn_enable_d3d12) {
924        libs += [
925          "d3d12.lib",
926          "dxgi.lib",
927          "d3dcompiler.lib",
928        ]
929      } else if (dawn_enable_metal) {
930        frameworks += [ "Metal.framework" ]
931      }
932    }
933  }
934
935  if (skia_use_direct3d) {
936    sources += skia_sksl_hlsl_sources
937    deps += [ "//third_party/spirv-cross:spirv_cross" ]
938  }
939
940  if (skia_use_vulkan) {
941    public_defines += [ "SK_VULKAN" ]
942    sources += skia_shared_vk_sources
943    configs += [ ":use_skia_vulkan_headers" ]
944    if (skia_enable_vulkan_debug_layers) {
945      public_defines += [ "SK_ENABLE_VK_LAYERS" ]
946    }
947    if (skia_use_vma) {
948      sources += skia_vma_sources
949      public_deps += [ "src/gpu/vk/vulkanmemoryallocator" ]
950    }
951  }
952
953  if (skia_use_metal) {
954    public_defines += [ "SK_METAL" ]
955    sources += skia_shared_mtl_sources
956  }
957
958  if (is_android) {
959    sources += skia_shared_android_sources
960  }
961}
962
963optional("gpu") {
964  enabled = skia_enable_ganesh
965  deps = [
966    ":gpu_shared",
967    ":minify_sksl",
968    ":run_sksllex",
969  ]
970  if (skia_generate_workarounds) {
971    deps += [ ":workaround_list" ]
972  }
973  configs = []
974  public_defines = []
975  public_configs = []
976  public_deps = []
977
978  public = skia_gpu_public
979  sources = skia_ganesh_private
980
981  libs = []
982  frameworks = []
983
984  if (is_android) {
985    sources += skia_gpu_android_private
986
987    # this lib is required to link against AHardwareBuffer
988    if (defined(ndk_api) && ndk_api >= 26) {
989      libs += [ "android" ]
990    }
991  }
992
993  if (skia_use_gl) {
994    public_defines += [ "SK_GL" ]
995    if (is_android) {
996      sources += [
997        "src/gpu/ganesh/gl/egl/GrGLMakeEGLInterface.cpp",
998        "src/gpu/ganesh/gl/egl/GrGLMakeNativeInterface_egl.cpp",
999      ]
1000      sources += skia_android_gl_sources
1001
1002      # this lib is required to link against AHardwareBuffer
1003      if (defined(ndk_api) && ndk_api >= 26) {
1004        libs += [ "android" ]
1005      }
1006    } else if (skia_use_egl) {
1007      if (skia_use_epoxy_egl) {
1008        sources += [ "src/gpu/ganesh/gl/epoxy/GrGLMakeEpoxyEGLInterface.cpp" ]
1009        libs += [ "epoxy" ]
1010      } else {
1011        sources += [
1012          "src/gpu/ganesh/gl/egl/GrGLMakeEGLInterface.cpp",
1013          "src/gpu/ganesh/gl/egl/GrGLMakeNativeInterface_egl.cpp",
1014        ]
1015        libs += [ "EGL" ]
1016      }
1017    } else if (skia_use_webgl) {
1018      sources += [ "src/gpu/ganesh/gl/webgl/GrGLMakeNativeInterface_webgl.cpp" ]
1019    } else if (is_linux && skia_use_x11) {
1020      sources += [
1021        "src/gpu/ganesh/gl/glx/GrGLMakeGLXInterface.cpp",
1022        "src/gpu/ganesh/gl/glx/GrGLMakeNativeInterface_glx.cpp",
1023      ]
1024      libs += [ "GL" ]
1025    } else if (is_mac) {
1026      sources += [ "src/gpu/ganesh/gl/mac/GrGLMakeNativeInterface_mac.cpp" ]
1027    } else if (is_ios) {
1028      sources += [ "src/gpu/ganesh/gl/iOS/GrGLMakeNativeInterface_iOS.cpp" ]
1029    } else if (is_win && !skia_enable_winuwp) {
1030      sources += [
1031        "src/gpu/ganesh/gl/win/GrGLMakeNativeInterface_win.cpp",
1032        "src/gpu/ganesh/gl/win/GrGLMakeWinInterface.cpp",
1033      ]
1034      if (target_cpu != "arm64") {
1035        libs += [ "OpenGL32.lib" ]
1036      }
1037    } else {
1038      sources += [ "src/gpu/ganesh/gl/GrGLMakeNativeInterface_none.cpp" ]
1039    }
1040    public += skia_gpu_gl_public
1041    sources += skia_gpu_gl_private
1042  }
1043
1044  if (skia_use_vulkan) {
1045    public += skia_gpu_vk_public
1046    sources += skia_gpu_vk_private
1047    configs += [ ":use_skia_vulkan_headers" ]
1048    if (is_fuchsia) {
1049      if (using_fuchsia_sdk) {
1050        public_deps += [ "$fuchsia_sdk_root/pkg:vulkan" ]
1051      } else {
1052        public_deps += [ "//src/graphics/lib/vulkan" ]
1053      }
1054    }
1055    if (is_android) {
1056      sources += skia_gpu_vk_android_private
1057    }
1058  }
1059
1060  if (skia_use_direct3d) {
1061    public_defines += [ "SK_DIRECT3D" ]
1062    deps += [ "//third_party/d3d12allocator" ]
1063    sources += skia_direct3d_sources
1064    if (skia_enable_direct3d_debug_layer) {
1065      public_defines += [ "SK_ENABLE_D3D_DEBUG_LAYER" ]
1066    }
1067    libs += [
1068      "d3d12.lib",
1069      "dxgi.lib",
1070      "d3dcompiler.lib",
1071    ]
1072  }
1073
1074  cflags_objcc = []
1075  if (skia_use_metal) {
1076    public_defines += [ "SK_METAL" ]
1077    public += skia_gpu_metal_public
1078    sources += skia_gpu_metal_private
1079    sources += skia_gpu_metal_cpp
1080    if (skia_enable_metal_debug_info) {
1081      public_defines += [ "SK_ENABLE_MTL_DEBUG_INFO" ]
1082    }
1083    frameworks += [ "Metal.framework" ]
1084    frameworks += [ "Foundation.framework" ]
1085    if (is_ios) {
1086      frameworks += [ "UIKit.framework" ]
1087    }
1088    cflags_objcc += [ "-fobjc-arc" ]
1089  }
1090
1091  if (is_debug || skia_build_for_debugger) {
1092    public_defines += [ "SK_ENABLE_DUMP_GPU" ]
1093  }
1094}
1095
1096optional("vello") {
1097  enabled = skia_enable_vello_shaders
1098  public_defines = [ "SK_ENABLE_VELLO_SHADERS" ]
1099  public_deps = [ "//third_party/vello" ]
1100}
1101
1102optional("heif") {
1103  enabled = skia_use_libheif
1104  public_defines = [ "SK_HAS_HEIF_LIBRARY" ]
1105
1106  # This HEIF decoding functionality is a part of the Android Framework.
1107  # https://android.googlesource.com/platform/frameworks/av/+/master/media/libheif/include/HeifDecoderAPI.h
1108  # There isn't a way to compile that library outside of it, so we just link against
1109  # the library. This feature is not supported on other platforms (and we haven't
1110  # yet tried something like https://github.com/strukturag/libheif/tree/master/libheif).
1111  # The dependency for Android is set in gn_to_bp.py.
1112  deps = []
1113
1114  sources = [ "src/codec/SkHeifCodec.cpp" ]
1115}
1116
1117optional("avif") {
1118  enabled = skia_use_libavif
1119  public_defines = [ "SK_CODEC_DECODES_AVIF" ]
1120
1121  deps = [ "//third_party/libavif" ]
1122
1123  sources = [ "src/codec/SkAvifCodec.cpp" ]
1124}
1125
1126optional("crabbyavif") {
1127  enabled = skia_use_crabbyavif
1128  public_defines = [ "SK_CODEC_DECODES_AVIF" ]
1129
1130  # AVIF decoding is provided by CrabbyAvif (a Rust library). Since skia's
1131  # standalone builds do not support Rust, it is only being enabled when
1132  # building for the Android framework.
1133  # The dependency for Android is set in gn_to_bp.py
1134  deps = []
1135  sources = [ "src/codec/SkCrabbyAvifCodec.cpp" ]
1136}
1137
1138optional("jpeg_mpf") {
1139  enabled = skia_use_jpeg_gainmaps &&
1140            (skia_use_libjpeg_turbo_encode || skia_use_libjpeg_turbo_decode)
1141  sources = [
1142    "src/codec/SkJpegMultiPicture.cpp",
1143    "src/codec/SkJpegSegmentScan.cpp",
1144  ]
1145}
1146
1147optional("jpeg_decode") {
1148  enabled = skia_use_libjpeg_turbo_decode
1149  public_defines = [ "SK_CODEC_DECODES_JPEG" ]
1150
1151  deps = [ "//third_party/libjpeg-turbo:libjpeg" ]
1152  sources = [
1153    "src/codec/SkJpegCodec.cpp",
1154    "src/codec/SkJpegDecoderMgr.cpp",
1155    "src/codec/SkJpegMetadataDecoderImpl.cpp",
1156    "src/codec/SkJpegSourceMgr.cpp",
1157    "src/codec/SkJpegUtility.cpp",
1158  ]
1159  if (skia_use_jpeg_gainmaps) {
1160    # Theoretically this doesn't need to be public, but this allows gn_to_bp.py to see it, and seems
1161    # to align with other codec support. See b/265939413
1162    public_defines += [ "SK_CODEC_DECODES_JPEG_GAINMAPS" ]
1163    deps += [
1164      ":jpeg_mpf",
1165      ":xml",
1166    ]
1167    sources += skia_codec_jpeg_xmp
1168  }
1169}
1170
1171optional("jpeg_encode") {
1172  enabled = skia_use_libjpeg_turbo_encode && !skia_use_ndk_images
1173  public_defines = [ "SK_CODEC_ENCODES_JPEG" ]
1174
1175  deps = [ "//third_party/libjpeg-turbo:libjpeg" ]
1176  public = skia_encode_jpeg_public
1177  sources = skia_encode_jpeg_srcs
1178
1179  if (skia_use_jpeg_gainmaps) {
1180    deps += [ ":jpeg_mpf" ]
1181    sources += [ "src/encode/SkJpegGainmapEncoder.cpp" ]
1182  }
1183}
1184
1185optional("jpegxl_decode") {
1186  enabled = skia_use_libjxl_decode
1187  public_defines = [ "SK_CODEC_DECODES_JPEGXL" ]
1188
1189  deps = [ "//third_party/libjxl" ]
1190  sources = [ "src/codec/SkJpegxlCodec.cpp" ]
1191}
1192
1193optional("ndk_images") {
1194  enabled = skia_use_ndk_images
1195  public_defines = [ "SK_ENABLE_NDK_IMAGES" ]
1196  sources = [
1197    "src/ports/SkImageEncoder_NDK.cpp",
1198    "src/ports/SkImageGeneratorNDK.cpp",
1199    "src/ports/SkNDKConversions.cpp",
1200  ]
1201  libs = [ "jnigraphics" ]
1202}
1203
1204optional("graphite") {
1205  configs = []
1206  libs = []
1207  frameworks = []
1208  public_defines = []
1209
1210  enabled = skia_enable_graphite
1211  deps = [
1212    ":gpu_shared",
1213    ":vello",
1214  ]
1215  public = skia_graphite_public
1216  sources = skia_graphite_sources
1217  sources += skia_sksl_graphite_modules_sources
1218
1219  if (is_android) {
1220    sources += skia_graphite_android_private
1221  }
1222
1223  if (skia_enable_vello_shaders) {
1224    sources += skia_graphite_vello_sources
1225  }
1226
1227  if (skia_use_dawn) {
1228    public += skia_graphite_dawn_public
1229    sources += skia_graphite_dawn_sources
1230  }
1231  if (skia_use_metal) {
1232    public_defines += [ "SK_METAL" ]
1233    public += skia_graphite_mtl_public
1234    sources += skia_graphite_mtl_sources
1235    if (skia_enable_metal_debug_info) {
1236      public_defines += [ "SK_ENABLE_MTL_DEBUG_INFO" ]
1237    }
1238    frameworks += [ "Metal.framework" ]
1239    frameworks += [ "Foundation.framework" ]
1240    if (is_ios) {
1241      frameworks += [ "UIKit.framework" ]
1242    }
1243  }
1244  if (skia_use_vulkan) {
1245    public += skia_graphite_vk_public
1246    sources += skia_graphite_vk_sources
1247    configs += [ ":use_skia_vulkan_headers" ]
1248  }
1249  if (skia_enable_precompile) {
1250    public += skia_graphite_precompile_public
1251    sources += skia_graphite_precompile_sources
1252  }
1253  if (is_debug) {
1254    public_defines += [ "SK_PIPELINE_LIFETIME_LOGGING" ]
1255  }
1256}
1257
1258optional("pdf") {
1259  enabled = skia_use_zlib && skia_enable_pdf && skia_use_libjpeg_turbo_decode &&
1260            skia_use_libjpeg_turbo_encode
1261  public_defines = [ "SK_SUPPORT_PDF" ]
1262
1263  deps = [ "//third_party/zlib" ]
1264  public = skia_pdf_public
1265  sources = skia_pdf_sources
1266  sources_when_disabled = [ "src/pdf/SkDocument_PDF_None.cpp" ]
1267  if (skia_pdf_subset_harfbuzz) {
1268    deps += [ "//third_party/harfbuzz" ]
1269    defines = [ "SK_PDF_USE_HARFBUZZ_SUBSET" ]
1270  }
1271}
1272
1273optional("pdf_jpeg_helpers") {
1274  enabled = skia_use_zlib && skia_enable_pdf && skia_use_libjpeg_turbo_decode &&
1275            skia_use_libjpeg_turbo_encode
1276  deps = [
1277    ":jpeg_decode",
1278    ":jpeg_encode",
1279    ":pdf",
1280  ]
1281  public = skia_pdf_jpeg_public
1282}
1283
1284optional("xps") {
1285  enabled = skia_use_xps && is_win
1286  public_defines = [ "SK_SUPPORT_XPS" ]
1287  public = skia_xps_public
1288  sources = skia_xps_sources
1289}
1290
1291optional("png_decode_libpng") {
1292  enabled = skia_use_libpng_decode
1293  public_defines = [
1294    "SK_CODEC_DECODES_ICO",
1295    "SK_CODEC_DECODES_PNG",
1296    "SK_CODEC_DECODES_PNG_WITH_LIBPNG",
1297  ]
1298  sources_for_tests = [ "tests/PngGainmapTest.cpp" ]
1299
1300  deps = [ "//third_party/libpng" ]
1301  sources = [ "src/codec/SkIcoCodec.cpp" ] + skia_codec_png_base +
1302            skia_codec_libpng_srcs
1303}
1304
1305optional("png_encode") {
1306  enabled = skia_use_libpng_encode && !skia_use_ndk_images
1307  public_defines = [
1308    "SK_CODEC_ENCODES_PNG",
1309    "SK_CODEC_ENCODES_PNG_WITH_LIBPNG",
1310  ]
1311
1312  public = skia_encode_png_public
1313  deps = [ "//third_party/libpng" ]
1314  sources = skia_encode_png_srcs
1315}
1316
1317optional("raw") {
1318  enabled = skia_use_dng_sdk && skia_use_libjpeg_turbo_decode && skia_use_piex
1319  public_defines = [ "SK_CODEC_DECODES_RAW" ]
1320
1321  deps = [
1322    "//third_party/dng_sdk",
1323    "//third_party/libjpeg-turbo:libjpeg",
1324    "//third_party/piex",
1325  ]
1326
1327  # SkRawCodec catches any exceptions thrown by dng_sdk, insulating the rest of
1328  # Skia.
1329  configs = [ "gn/portable:add_exceptions" ]
1330
1331  sources = [ "src/codec/SkRawCodec.cpp" ]
1332}
1333
1334optional("typeface_freetype") {
1335  enabled = skia_use_freetype
1336
1337  public_defines = [ "SK_TYPEFACE_FACTORY_FREETYPE" ]
1338  deps = [ "//third_party/freetype2" ]
1339  sources = skia_ports_freetype_sources
1340  sources_for_tests = [ "tests/FontScanner_FreeTypeTest.cpp" ]
1341}
1342
1343bazel_args = []
1344if (is_mac && target_cpu == "arm64") {
1345  # TODO: Normally the target toolchain would be specified with `--platforms` but that doesn't
1346  # work. When building and running on an arm64 mac, setting `--host_platform` seems to do the
1347  # right thing but may not be the right build configuration in the long run.
1348  bazel_args += [ "--host_platform=//bazel/platform:mac_arm64_hermetic" ]
1349}
1350if (is_debug) {
1351  bazel_args += [ "--compilation_mode=dbg" ]
1352} else {
1353  bazel_args += [ "--compilation_mode=opt" ]
1354}
1355
1356if (skia_use_fontations) {
1357  action("fontations_rust_side_bazel_build") {
1358    script = "gn/bazel_build.py"
1359    sources = [
1360      "src/ports/fontations/BUILD.bazel",
1361      "src/ports/fontations/src/ffi.rs",
1362    ]
1363    outputs = [ "$root_out_dir/libbridge_rust_side.a" ]
1364    args =
1365        [
1366          "//src/ports/fontations:bridge_rust_side",
1367          rebase_path("//bazel-bin/src/ports/fontations/libbridge_rust_side.a",
1368                      root_build_dir),
1369        ] + bazel_args
1370  }
1371
1372  # We only use Bazel to get the generated `.cc` and `.h` file and then compile
1373  # them on GN/ninja side using `skia_source_set` below.  This ensures that the
1374  # same C++ stdlib and compiler is used throughout the build (in some scenarios
1375  # Bazel may end up using different ones).
1376  action("fontations_ffi_bazel_build") {
1377    script = "gn/bazel_build.py"
1378    sources = [
1379      "src/ports/fontations/BUILD.bazel",
1380      "src/ports/fontations/src/ffi.rs",
1381    ]
1382    outputs = [
1383      "$root_out_dir/src/ports/fontations/src/ffi.rs.h",
1384      "$root_out_dir/src/ports/fontations/src/ffi.rs.cc",
1385    ]
1386    args = [
1387             "//src/ports/fontations:fontations_ffi",
1388
1389             # we want the header to not simply be copied into the output directory,
1390             # but in the same path as the Bazel build uses.
1391             rebase_path("//bazel-bin/src/ports/fontations/src/ffi.rs.h",
1392                         root_build_dir) + "=src/ports/fontations/src/ffi.rs.h",
1393             rebase_path("//bazel-bin/src/ports/fontations/src/ffi.rs.cc",
1394                         root_build_dir) +
1395                 "=src/ports/fontations/src/ffi.rs.cc",
1396           ] + bazel_args
1397  }
1398  config("fontations_ffi_public_config") {
1399    include_dirs = [
1400      # This is where `src/ports/fontations/src/ffi.rs.h` was put by Bazel
1401      "$root_out_dir",
1402    ]
1403  }
1404  config("fontations_ffi_private_config") {
1405    include_dirs = [
1406      # This entry is needed so that `ffi.rs.cc` can resolve
1407      # `#include "src/ports/fontations/src/ffi.rs.h"`
1408      ".",
1409    ]
1410  }
1411  skia_source_set("fontations_ffi") {
1412    deps = [
1413      ":fontations_ffi_bazel_build",
1414      ":fontations_rust_side_bazel_build",
1415    ]
1416    public = [ "${root_out_dir}/src/ports/fontations/src/ffi.rs.h" ]
1417    sources = [ "${root_out_dir}/src/ports/fontations/src/ffi.rs.cc" ]
1418    libs = [ "$root_out_dir/libbridge_rust_side.a" ]
1419    public_configs = [ ":fontations_ffi_public_config" ]
1420    configs = [ ":fontations_ffi_private_config" ]
1421  }
1422}
1423
1424optional("typeface_fontations") {
1425  public_defines = [ "SK_TYPEFACE_FACTORY_FONTATIONS" ]
1426  enabled = skia_use_fontations
1427  public_deps = [ ":fontations_ffi" ]
1428  sources = skia_ports_typeface_fontations_sources
1429  sources_for_tests = [
1430    "tests/FontationsTest.cpp",
1431    "tests/FontationsFtCompTest.cpp",
1432    "tests/FontScanner_FontationsTest.cpp",
1433  ]
1434}
1435
1436if (skia_use_rust_png_decode || skia_use_rust_png_encode) {
1437  # We only use Bazel to get the generated `.cc` and `.h` file and then compile
1438  # them on GN/ninja side using `skia_source_set` below.  This ensures that the
1439  # same C++ stdlib and compiler is used throughout the build (in some scenarios
1440  # Bazel may end up using different ones).
1441  action("rust_png_ffi_bazel_build") {
1442    script = "gn/bazel_build.py"
1443    sources = [
1444      "experimental/rust_png/ffi/BUILD.bazel",
1445      "experimental/rust_png/ffi/FFI.h",
1446      "experimental/rust_png/ffi/FFI.rs",
1447    ]
1448    outputs = [
1449      "$root_out_dir/librust_png_ffi_rs.a",
1450      "$root_out_dir/experimental/rust_png/ffi/FFI.rs.h",
1451      "$root_out_dir/experimental/rust_png/ffi/FFI.rs.cc",
1452    ]
1453    args =
1454        [
1455          "//experimental/rust_png/ffi:*",
1456
1457          rebase_path("//bazel-bin/experimental/rust_png/ffi/libffi_rs.a",
1458                      root_build_dir) + "=librust_png_ffi_rs.a",
1459
1460          # we want the `cxx`-generated headers to not simply be copied into
1461          # the output directory, but in the same path as the Bazel build
1462          # uses.
1463          rebase_path("//bazel-bin/experimental/rust_png/ffi/FFI.rs.h",
1464                      root_build_dir) + "=experimental/rust_png/ffi/FFI.rs.h",
1465          rebase_path("//bazel-bin/experimental/rust_png/ffi/FFI.rs.cc",
1466                      root_build_dir) + "=experimental/rust_png/ffi/FFI.rs.cc",
1467        ] + bazel_args
1468  }
1469  action("rust_png_cxx_core_bazel_build") {
1470    script = "gn/bazel_build.py"
1471    sources = [
1472      "WORKSPACE.bazel",
1473      "bazel/external/cxx/BUILD.bazel",
1474      "bazel/external/cxx/BUILD.bazel.skia",
1475    ]
1476    outputs = [
1477      "$root_out_dir/librust_png_cxx_core_lib.a",
1478      "$root_out_dir/third_party/rust/cxx/v1/cxx.h",
1479    ]
1480    args = [
1481             "@cxx//:core-lib",
1482
1483             rebase_path("//bazel-bin/external/cxx/libcore-lib.a",
1484                         root_build_dir) + "=librust_png_cxx_core_lib.a",
1485
1486             # we want the `cxx.h` header to not simply be copied into the
1487             # output directory, but in the same path as the Bazel build uses.
1488             rebase_path(
1489                     "//bazel-bin/external/cxx/_virtual_includes/core-lib/third_party/rust/cxx/v1/cxx.h",
1490                     root_build_dir) + "=third_party/rust/cxx/v1/cxx.h",
1491           ] + bazel_args
1492  }
1493  config("rust_png_cxx_bridge_public_config") {
1494    include_dirs = [
1495      # This is where `experimental/rust_png/ffi/FFI.rs.h` and
1496      # `third_party/rust/cxx/v1/cxx.h` were put by Bazel
1497      "$root_out_dir",
1498    ]
1499  }
1500  config("rust_png_cxx_bridge_private_config") {
1501    include_dirs = [
1502      # This entry is needed so that `FFI.rs.cc` can resolve
1503      # `#include "experimental/rust_png/ffi/FFI.h"`
1504      ".",
1505    ]
1506  }
1507  skia_source_set("rust_png_cxx_bridge") {
1508    deps = [ ":rust_png_ffi_bazel_build" ]
1509    public = [ "${root_out_dir}/experimental/rust_png/ffi/FFI.rs.h" ]
1510    sources = [ "${root_out_dir}/experimental/rust_png/ffi/FFI.rs.cc" ]
1511    libs = [ "$root_out_dir/librust_png_ffi_rs.a" ]
1512    public_configs = [ ":rust_png_cxx_bridge_public_config" ]
1513    configs = [ ":rust_png_cxx_bridge_private_config" ]
1514  }
1515}
1516
1517optional("png_decode_rust") {
1518  public_defines = [ "SK_CODEC_DECODES_PNG_WITH_RUST" ]
1519  enabled = skia_use_rust_png_decode
1520  public = skia_codec_rust_png_public
1521  sources = skia_codec_rust_png + skia_codec_png_base
1522  sources_for_tests = [ "tests/SkPngRustDecoderTest.cpp" ]
1523
1524  deps = [
1525    ":rust_png_cxx_bridge",
1526    ":rust_png_cxx_core_bazel_build",
1527  ]
1528  libs = [ "$root_out_dir/librust_png_cxx_core_lib.a" ]
1529}
1530
1531optional("png_encode_rust") {
1532  public_defines = [ "SK_CODEC_ENCODES_PNG_WITH_RUST" ]
1533  enabled = skia_use_rust_png_encode
1534  public = skia_encode_rust_png_public  # From `gn/core.gni`
1535  sources =
1536      skia_encode_rust_png_srcs + skia_encode_png_base  # From `gn/core.gni`
1537  sources_for_tests = [ "tests/SkPngRustEncoderTest.cpp" ]
1538  deps = [
1539    ":rust_png_cxx_bridge",
1540    ":rust_png_cxx_core_bazel_build",
1541  ]
1542  libs = [ "$root_out_dir/librust_png_cxx_core_lib.a" ]
1543}
1544
1545optional("webp_decode") {
1546  enabled = skia_use_libwebp_decode
1547  public_defines = [ "SK_CODEC_DECODES_WEBP" ]
1548
1549  deps = [ "//third_party/libwebp" ]
1550  sources = [ "src/codec/SkWebpCodec.cpp" ]
1551}
1552
1553optional("webp_encode") {
1554  enabled = skia_use_libwebp_encode && !skia_use_ndk_images
1555  public_defines = [ "SK_CODEC_ENCODES_WEBP" ]
1556  public = skia_encode_webp_public
1557
1558  deps = [ "//third_party/libwebp" ]
1559  sources = skia_encode_webp_srcs
1560}
1561
1562optional("wuffs") {
1563  enabled = skia_use_wuffs
1564  public_defines = [
1565    "SK_HAS_WUFFS_LIBRARY",
1566    "SK_CODEC_DECODES_GIF",
1567  ]
1568
1569  deps = [ "//third_party/wuffs" ]
1570  sources = [ "src/codec/SkWuffsCodec.cpp" ]
1571}
1572
1573optional("xml") {
1574  enabled = skia_use_expat || skia_use_jpeg_gainmaps
1575  public_defines = [ "SK_XML" ]
1576
1577  deps = [ "//third_party/expat" ]
1578  sources = skia_xml_sources + skia_codec_xmp + [
1579              "src/svg/SkSVGCanvas.cpp",
1580              "src/svg/SkSVGDevice.cpp",
1581            ]
1582}
1583
1584if (skia_enable_ganesh && skia_generate_workarounds) {
1585  action("workaround_list") {
1586    script = "tools/build_workaround_header.py"
1587
1588    inputs = [ "src/gpu/gpu_workaround_list.txt" ]
1589
1590    # GN insists its outputs should go somewhere underneath root_out_dir, so we trick it with a
1591    # path that starts with root_out_dir and then uses ".." to back up into the src dir.
1592    output_file =
1593        rebase_path("include/gpu/ganesh/GrDriverBugWorkaroundsAutogen.h",
1594                    root_out_dir)
1595
1596    outputs = [ "$root_out_dir/$output_file" ]
1597    args = [
1598      "--output-file",
1599      "$output_file",
1600    ]
1601
1602    foreach(file, inputs) {
1603      args += [ rebase_path(file, root_build_dir) ]
1604    }
1605  }
1606}
1607
1608import("gn/codec.gni")
1609
1610skia_component("skia") {
1611  public_configs = [ ":skia_public" ]
1612  configs = skia_library_configs
1613
1614  public_deps = [
1615    ":fontmgr_FontConfigInterface",
1616    ":fontmgr_android",
1617    ":fontmgr_android_ndk",
1618    ":fontmgr_custom_directory",
1619    ":fontmgr_custom_embedded",
1620    ":fontmgr_custom_empty",
1621    ":fontmgr_fontations_empty",
1622    ":fontmgr_fontconfig",
1623    ":fontmgr_fuchsia",
1624    ":fontmgr_mac_ct",
1625    ":fontmgr_win",
1626    ":fontmgr_win_gdi",
1627    ":gpu",
1628    ":graphite",
1629    ":jpeg_encode",
1630    ":pdf",
1631    ":pdf_jpeg_helpers",
1632    ":png_encode",
1633    ":webp_encode",
1634    ":xps",
1635  ]
1636
1637  deps = [
1638    ":android_utils",
1639    ":avif",
1640    ":crabbyavif",
1641    ":heif",
1642    ":hsw",
1643    ":jpeg_decode",
1644    ":jpegxl_decode",
1645    ":lasx",
1646    ":minify_sksl",
1647    ":ndk_images",
1648    ":png_decode_libpng",
1649    ":png_decode_rust",
1650    ":raw",
1651    ":skx",
1652    ":typeface_fontations",
1653    ":vello",
1654    ":webp_decode",
1655    ":wuffs",
1656    ":xml",
1657    "modules/skcms",
1658  ]
1659
1660  public = skia_core_public
1661  public += skia_codec_public
1662  public += skia_utils_public
1663  public += skia_effects_public
1664  public += skia_effects_imagefilter_public
1665
1666  sources = []
1667  sources += skia_core_sources
1668  sources += skia_utils_private
1669  sources += skia_utils_chromium
1670  sources += skia_effects_sources
1671  sources += skia_colorfilters_sources
1672  sources += skia_effects_imagefilter_sources
1673  sources += skia_codec_shared
1674  sources += skia_codec_decode_bmp
1675  sources += skia_encode_srcs
1676  sources += skia_sksl_core_sources
1677  sources += skia_sksl_core_module_sources
1678  sources += skia_sksl_tracing_sources
1679  sources += skia_ports_sources
1680  sources += [
1681    "src/android/SkAndroidFrameworkUtils.cpp",
1682    "src/android/SkAnimatedImage.cpp",
1683    "src/codec/SkAndroidCodec.cpp",
1684    "src/codec/SkAndroidCodecAdapter.cpp",
1685    "src/codec/SkSampledCodec.cpp",
1686    "src/ports/SkDiscardableMemory_none.cpp",
1687    "src/ports/SkMemory_malloc.cpp",
1688    "src/sfnt/SkOTTable_name.cpp",
1689    "src/sfnt/SkOTUtils.cpp",
1690  ]
1691
1692  defines = []
1693  libs = []
1694
1695  if (skia_build_for_debugger) {
1696    defines += [ "SK_BUILD_FOR_DEBUGGER" ]
1697  }
1698
1699  if (skia_use_no_jpeg_encode) {
1700    sources += skia_no_encode_jpeg_srcs
1701  }
1702  if (skia_use_no_png_encode) {
1703    sources += skia_no_encode_png_srcs
1704  }
1705  if (skia_use_no_webp_encode) {
1706    sources += skia_no_encode_webp_srcs
1707  }
1708
1709  if (is_win) {
1710    sources += skia_ports_windows_sources + [
1711                 "src/ports/SkDebug_win.cpp",
1712                 "src/ports/SkImageGeneratorWIC.cpp",
1713               ]
1714    libs += [
1715      "Ole32.lib",
1716      "OleAut32.lib",
1717    ]
1718
1719    if (!skia_enable_winuwp) {
1720      libs += [
1721        "FontSub.lib",
1722        "User32.lib",
1723        "Usp10.lib",
1724      ]
1725    }
1726  } else {
1727    sources += [ "src/ports/SkOSFile_posix.cpp" ]
1728    if (is_ios) {
1729      sources += [ "src/ports/SkOSFile_ios.h" ]
1730    }
1731    libs += [ "dl" ]
1732  }
1733
1734  if (is_android) {
1735    deps += [ "//third_party/expat" ]
1736    if (defined(ndk) && ndk != "") {
1737      deps += [ "//third_party/cpu-features" ]
1738    }
1739    sources += [ "src/ports/SkDebug_android.cpp" ]
1740    libs += [
1741      "EGL",
1742      "GLESv2",
1743      "log",
1744    ]
1745  }
1746
1747  if (is_linux || is_wasm) {
1748    sources += [ "src/ports/SkDebug_stdio.cpp" ]
1749    if (skia_use_egl) {
1750      libs += [ "GLESv2" ]
1751    }
1752  }
1753
1754  if (is_mac) {
1755    public += [ "include/ports/SkCFObject.h" ]
1756    sources += [
1757      "src/ports/SkDebug_stdio.cpp",
1758      "src/ports/SkImageGeneratorCG.cpp",
1759    ]
1760    frameworks = [
1761      "ApplicationServices.framework",
1762      "OpenGL.framework",
1763    ]
1764  }
1765
1766  if (is_ios) {
1767    public += [ "include/ports/SkCFObject.h" ]
1768    sources += [
1769      "src/ports/SkDebug_stdio.cpp",
1770      "src/ports/SkImageGeneratorCG.cpp",
1771    ]
1772    frameworks = [
1773      "CoreFoundation.framework",
1774      "ImageIO.framework",
1775      "MobileCoreServices.framework",
1776    ]
1777  }
1778
1779  if (is_fuchsia) {
1780    sources += [ "src/ports/SkDebug_stdio.cpp" ]
1781  }
1782
1783  if (skia_enable_spirv_validation) {
1784    deps += [ "//third_party/externals/spirv-tools:spvtools_val" ]
1785    defines += [ "SK_ENABLE_SPIRV_VALIDATION" ]
1786  }
1787
1788  if (skia_include_multiframe_procs) {
1789    sources += [ "tools/SkSharingProc.cpp" ]
1790  }
1791
1792  # Overrides TRACE_EVENT0..2 macros (etc) to map to Perfetto's tracing macros.
1793  # Currently only supported in Android framework.
1794  if (skia_android_framework_use_perfetto) {
1795    defines += [ "SK_ANDROID_FRAMEWORK_USE_PERFETTO" ]
1796    sources += [ "src/android/SkAndroidFrameworkPerfettoStaticStorage.cpp" ]
1797  }
1798
1799  if (!skia_enable_ganesh && !skia_enable_graphite) {
1800    sources += skia_no_slug_srcs
1801  }
1802}
1803
1804# DebugCanvas used in experimental/wasm-skp-debugger
1805if (is_wasm) {
1806  skia_static_library("debugcanvas") {
1807    public_configs = [ ":skia_public" ]
1808
1809    sources = [
1810      "tools/SkSharingProc.cpp",
1811      "tools/UrlDataManager.cpp",
1812      "tools/debugger/DebugCanvas.cpp",
1813      "tools/debugger/DebugLayerManager.cpp",
1814      "tools/debugger/DrawCommand.cpp",
1815      "tools/debugger/JsonWriteBuffer.cpp",
1816    ]
1817  }
1818}
1819
1820skia_static_library("pathkit") {
1821  check_includes = false
1822  public_configs = [ ":skia_public" ]
1823  configs = skia_library_configs
1824
1825  deps = [ ":hsw" ]
1826
1827  sources = []
1828  sources += skia_pathops_sources
1829  sources += skia_pathops_public
1830  sources += [
1831    "src/base/SkArenaAlloc.cpp",
1832    "src/base/SkBezierCurves.cpp",
1833    "src/base/SkContainers.cpp",
1834    "src/base/SkCubics.cpp",
1835    "src/base/SkFloatingPoint.cpp",
1836    "src/base/SkMalloc.cpp",
1837    "src/base/SkMathPriv.cpp",
1838    "src/base/SkQuads.cpp",
1839    "src/base/SkSafeMath.cpp",
1840    "src/base/SkSemaphore.cpp",
1841    "src/base/SkTDArray.cpp",
1842    "src/base/SkThreadID.cpp",
1843    "src/base/SkUTF.cpp",
1844    "src/base/SkUtils.cpp",
1845    "src/core/SkAnalyticEdge.cpp",
1846    "src/core/SkContourMeasure.cpp",
1847    "src/core/SkCubicMap.cpp",
1848    "src/core/SkEdge.cpp",
1849    "src/core/SkEdgeBuilder.cpp",
1850    "src/core/SkEdgeClipper.cpp",
1851    "src/core/SkGeometry.cpp",
1852    "src/core/SkIDChangeListener.cpp",
1853    "src/core/SkLineClipper.cpp",
1854    "src/core/SkMallocPixelRef.cpp",
1855    "src/core/SkMatrix.cpp",
1856    "src/core/SkOpts.cpp",
1857    "src/core/SkPaint.cpp",
1858    "src/core/SkPaintPriv.cpp",
1859    "src/core/SkPath.cpp",
1860    "src/core/SkPathBuilder.cpp",
1861    "src/core/SkPathEffect.cpp",
1862    "src/core/SkPathMeasure.cpp",
1863    "src/core/SkPathRef.cpp",
1864    "src/core/SkPathUtils.cpp",
1865    "src/core/SkPoint.cpp",
1866    "src/core/SkRRect.cpp",
1867    "src/core/SkReadBuffer.cpp",
1868    "src/core/SkRect.cpp",
1869    "src/core/SkStream.cpp",
1870    "src/core/SkString.cpp",
1871    "src/core/SkStringUtils.cpp",
1872    "src/core/SkStroke.cpp",
1873    "src/core/SkStrokeRec.cpp",
1874    "src/core/SkStrokerPriv.cpp",
1875    "src/effects/SkDashPathEffect.cpp",
1876    "src/effects/SkTrimPathEffect.cpp",
1877    "src/ports/SkDebug_stdio.cpp",
1878    "src/ports/SkMemory_malloc.cpp",
1879    "src/utils/SkDashPath.cpp",
1880    "src/utils/SkParse.cpp",
1881    "src/utils/SkParsePath.cpp",
1882  ]
1883}
1884
1885group("modules") {
1886  deps = [
1887    "modules/bentleyottmann",
1888    "modules/skottie",
1889    "modules/skparagraph",
1890    "modules/skshaper",
1891    "modules/svg",
1892  ]
1893
1894  if (is_wasm) {
1895    deps += [ "modules/canvaskit" ]
1896  }
1897}
1898
1899config("use_skia_vulkan_headers") {
1900  include_dirs = [ "include/third_party/vulkan" ]
1901  defines = [ "SK_USE_INTERNAL_VULKAN_HEADERS" ]
1902}
1903
1904config("vulkan_memory_allocator") {
1905  include_dirs = [ "$skia_vulkan_memory_allocator_dir/include" ]
1906}
1907
1908# Targets guarded by skia_enable_tools may use //third_party freely.
1909if (skia_enable_tools) {
1910  skia_public_includes = [
1911    "client_utils/android",
1912    "include/android",
1913    "include/codec",
1914    "include/config",
1915    "include/core",
1916    "include/docs",
1917    "include/effects",
1918    "include/encode",
1919    "include/gpu",
1920    "include/pathops",
1921    "include/ports",
1922    "include/svg",
1923    "include/utils",
1924    "include/utils/mac",
1925    "modules/skottie/include",
1926    "modules/skparagraph/include",
1927    "modules/skshaper/include",
1928    "modules/svg/include",
1929  ]
1930
1931  # Used by gn_to_bp.py to list our public include dirs.
1932  skia_source_set("public") {
1933    configs = [ ":skia_public" ]
1934    include_dirs = skia_public_includes
1935  }
1936
1937  config("skia.h_config") {
1938    include_dirs = [ "$target_gen_dir" ]
1939  }
1940  action("skia.h") {
1941    public_configs = [ ":skia.h_config" ]
1942    skia_h = "$target_gen_dir/skia.h"
1943    script = "gn/find_headers.py"
1944
1945    args = [ rebase_path("//bin/gn") ] + [ rebase_path("//") ] +
1946           [ rebase_path(skia_h, root_build_dir) ] +
1947           rebase_path(skia_public_includes)
1948    depfile = "$skia_h.deps"
1949    outputs = [ skia_h ]
1950  }
1951
1952  if (is_linux && target_cpu == "x64") {
1953    skia_executable("fiddle") {
1954      check_includes = false
1955      libs = []
1956      sources = [
1957        "tools/fiddle/draw.cpp",
1958        "tools/fiddle/fiddle_main.cpp",
1959      ]
1960
1961      if (skia_use_egl) {
1962        sources += [ "tools/fiddle/egl_context.cpp" ]
1963      } else {
1964        sources += [ "tools/fiddle/null_context.cpp" ]
1965      }
1966      testonly = true
1967      deps = [
1968        ":flags",
1969        ":gpu_tool_utils",
1970        ":skia",
1971        ":skia.h",
1972        "modules/skottie",
1973        "modules/skparagraph",
1974        "modules/skshaper",
1975        "modules/svg",
1976      ]
1977    }
1978  }
1979
1980  config("cpp17") {
1981    if (is_win) {
1982      cflags_cc = [ "/std:c++17" ]
1983    } else {
1984      cflags_cc = [ "-std=c++17" ]
1985    }
1986  }
1987
1988  skia_source_set("public_headers_warnings_check") {
1989    sources = [ "tools/public_headers_warnings_check.cpp" ]
1990    configs = [
1991      ":use_skia_vulkan_headers",
1992      ":cpp17",
1993    ]
1994    if (defined(skia_header_target_default_configs)) {
1995      configs += skia_header_target_default_configs
1996    }
1997    deps = [
1998      ":skia",
1999      ":skia.h",
2000      "modules/skottie",
2001      "modules/skshaper",
2002    ]
2003
2004    if (skia_use_dawn) {
2005      deps += [ "//third_party/externals/dawn/include/dawn:headers" ]
2006    }
2007  }
2008
2009  template("test_lib") {
2010    config(target_name + "_config") {
2011      if (defined(invoker.public_defines)) {
2012        defines = invoker.public_defines
2013      }
2014    }
2015    skia_source_set(target_name) {
2016      forward_variables_from(invoker, "*", [])
2017      check_includes = false
2018      public_configs = [
2019        ":" + target_name + "_config",
2020        ":skia_private",
2021      ]
2022
2023      if (!defined(deps)) {
2024        deps = []
2025      }
2026      deps += [ ":skia" ]
2027      testonly = true
2028    }
2029  }
2030
2031  template("test_app") {
2032    if (is_ios) {
2033      ios_app_bundle(target_name) {
2034        forward_variables_from(invoker,
2035                               "*",
2036                               [
2037                                 "output_name",
2038                                 "visibility",
2039                                 "is_shared_library",
2040                               ])
2041        testonly = true
2042        extra_configs = [ ":skia_private" ]
2043        launchscreen = "platform_tools/ios/app/LaunchScreen.storyboard"
2044        data_sources = [ "resources" ]
2045        if ("True" == exec_script("//gn/checkdir.py",
2046                                  [ rebase_path("skps", root_build_dir) ],
2047                                  "trim string")) {
2048          data_sources += [ "skps" ]
2049        }
2050        if ("True" == exec_script("//gn/checkdir.py",
2051                                  [ rebase_path("mskps", root_build_dir) ],
2052                                  "trim string")) {
2053          data_sources += [ "mskps" ]
2054        }
2055      }
2056    } else {
2057      # !is_ios
2058
2059      if (defined(invoker.is_shared_library) && invoker.is_shared_library) {
2060        skia_shared_library("lib" + target_name) {
2061          output_dir = root_build_dir
2062          forward_variables_from(invoker, "*", [ "is_shared_library" ])
2063          if (!defined(configs)) {
2064            configs = []
2065          }
2066          configs += [ ":skia_private" ]
2067          testonly = true
2068        }
2069      } else {
2070        _executable = target_name
2071        skia_executable(_executable) {
2072          check_includes = false
2073          output_dir = root_build_dir
2074          forward_variables_from(invoker, "*", [ "is_shared_library" ])
2075          if (!defined(configs)) {
2076            configs = []
2077          }
2078          configs += [ ":skia_private" ]
2079          testonly = true
2080        }
2081      }
2082      if (is_android && skia_android_serial != "" && defined(_executable)) {
2083        action("push_" + target_name) {
2084          output_dir = root_build_dir
2085          script = "gn/push_to_android.py"
2086          deps = [ ":" + _executable ]
2087          _stamp = "$target_gen_dir/$_executable.pushed_$skia_android_serial"
2088          outputs = [ _stamp ]
2089          args = [
2090            rebase_path("$root_build_dir/$_executable"),
2091            skia_android_serial,
2092            rebase_path(_stamp),
2093          ]
2094          testonly = true
2095        }
2096      }
2097    }
2098  }
2099
2100  test_lib("load_dynamic_library") {
2101    configs = [ ":skia_private" ]
2102    deps = [ ":skia" ]
2103    sources = [ "tools/library/LoadDynamicLibrary.h" ]
2104    if (is_win) {
2105      sources += [ "tools/library/LoadDynamicLibrary_win.cpp" ]
2106    } else {
2107      sources += [ "tools/library/LoadDynamicLibrary_posix.cpp" ]
2108    }
2109  }
2110
2111  test_lib("gpu_tool_utils") {
2112    public_defines = []
2113
2114    # Bots and even devs may not have Vulkan headers, so put
2115    # include/third_party/vulkan on our path so they're always available.
2116    all_dependent_configs = [ ":use_skia_vulkan_headers" ]
2117
2118    defines = []
2119    if (skia_enable_discrete_gpu) {
2120      defines += [ "SK_ENABLE_DISCRETE_GPU" ]
2121    }
2122
2123    deps = [ ":load_dynamic_library" ]
2124    public_deps = []
2125    sources = [
2126      "tools/gpu/BackendSurfaceFactory.cpp",
2127      "tools/gpu/BackendSurfaceFactory.h",
2128      "tools/gpu/BackendTextureImageFactory.cpp",
2129      "tools/gpu/BackendTextureImageFactory.h",
2130      "tools/gpu/ContextType.cpp",
2131      "tools/gpu/ContextType.h",
2132      "tools/gpu/FlushFinishTracker.cpp",
2133      "tools/gpu/FlushFinishTracker.h",
2134      "tools/gpu/GrContextFactory.cpp",
2135      "tools/gpu/GrContextFactory.h",
2136      "tools/gpu/GrTest.cpp",
2137      "tools/gpu/ManagedBackendTexture.cpp",
2138      "tools/gpu/ManagedBackendTexture.h",
2139      "tools/gpu/MemoryCache.cpp",
2140      "tools/gpu/MemoryCache.h",
2141      "tools/gpu/ProtectedUtils.cpp",
2142      "tools/gpu/ProtectedUtils.h",
2143      "tools/gpu/ProxyUtils.cpp",
2144      "tools/gpu/ProxyUtils.h",
2145      "tools/gpu/TestCanvas.cpp",
2146      "tools/gpu/TestCanvas.h",
2147      "tools/gpu/TestContext.cpp",
2148      "tools/gpu/TestOps.cpp",
2149      "tools/gpu/TestOps.h",
2150      "tools/gpu/YUVUtils.cpp",
2151      "tools/gpu/YUVUtils.h",
2152      "tools/gpu/mock/MockTestContext.cpp",
2153      "tools/text/gpu/TextBlobTools.cpp",
2154    ]
2155
2156    libs = []
2157    frameworks = []
2158
2159    if (skia_use_gl) {
2160      sources += [ "tools/gpu/gl/GLTestContext.cpp" ]
2161      if (is_ios) {
2162        sources += [ "tools/gpu/gl/iOS/CreatePlatformGLTestContext_iOS.mm" ]
2163        frameworks += [ "OpenGLES.framework" ]
2164      } else if (is_mac) {
2165        sources += [ "tools/gpu/gl/mac/CreatePlatformGLTestContext_mac.cpp" ]
2166      }
2167      if (skia_use_angle) {
2168        deps += [ "//third_party/angle2" ]
2169        sources += [ "tools/gpu/gl/angle/GLTestContext_angle.cpp" ]
2170      }
2171    }
2172
2173    if (skia_use_gl && target_cpu != "wasm") {
2174      if (is_android || skia_use_egl) {
2175        sources += [ "tools/gpu/gl/egl/CreatePlatformGLTestContext_egl.cpp" ]
2176        libs += [ "EGL" ]
2177      } else if (is_linux) {
2178        sources += [ "tools/gpu/gl/glx/CreatePlatformGLTestContext_glx.cpp" ]
2179        libs += [
2180          "GLU",
2181          "GL",
2182          "X11",
2183        ]
2184      } else if (is_win) {
2185        sources += [
2186          "tools/gpu/gl/win/CreatePlatformGLTestContext_win.cpp",
2187          "tools/gpu/gl/win/SkWGL.h",
2188          "tools/gpu/gl/win/SkWGL_win.cpp",
2189        ]
2190        libs += [ "Gdi32.lib" ]
2191        if (target_cpu != "arm64") {
2192          libs += [ "OpenGL32.lib" ]
2193        }
2194      }
2195    }
2196
2197    if (skia_use_vulkan) {
2198      sources += [ "tools/gpu/vk/VkTestContext.h" ]
2199      sources += [ "tools/gpu/vk/VkTestContext.cpp" ]
2200      sources += [ "tools/gpu/vk/VkTestHelper.h" ]
2201      sources += [ "tools/gpu/vk/VkTestHelper.cpp" ]
2202      sources += [ "tools/gpu/vk/VkTestMemoryAllocator.h" ]
2203      sources += [ "tools/gpu/vk/VkTestMemoryAllocator.cpp" ]
2204      sources += [ "tools/gpu/vk/VkTestUtils.h" ]
2205      sources += [ "tools/gpu/vk/VkTestUtils.cpp" ]
2206      sources += [ "tools/gpu/vk/VkYcbcrSamplerHelper.h" ]
2207      sources += [ "tools/gpu/vk/VkYcbcrSamplerHelper.cpp" ]
2208      all_dependent_configs += [ ":vulkan_memory_allocator" ]
2209    }
2210    if (skia_use_metal) {
2211      sources += [ "tools/gpu/mtl/MtlTestContext.mm" ]
2212    }
2213    if (skia_use_direct3d) {
2214      sources += [ "tools/gpu/d3d/D3DTestContext.cpp" ]
2215      sources += [ "tools/gpu/d3d/D3DTestUtils.cpp" ]
2216    }
2217    if (skia_use_dawn) {
2218      public_deps += [ "//third_party/externals/dawn/include/dawn:headers" ]
2219      if (is_clang) {
2220        cflags_cc = [ "-Wno-microsoft-cast" ]
2221      }
2222    }
2223    if (!skia_enable_ganesh) {
2224      sources -= [ "tools/gpu/GrTest.cpp" ]
2225      sources -= [ "tools/gpu/TestOps.cpp" ]
2226      sources -= [ "tools/gpu/TestOps.h" ]
2227    } else {
2228      sources += [
2229        "tools/gpu/ganesh/AtlasTextOpTools.cpp",
2230        "tools/gpu/ganesh/AtlasTextOpTools.h",
2231        "tools/gpu/ganesh/GrAtlasTools.cpp",
2232        "tools/gpu/ganesh/GrAtlasTools.h",
2233      ]
2234    }
2235    if (skia_enable_graphite) {
2236      sources += [
2237        "tools/graphite/ContextFactory.cpp",
2238        "tools/graphite/ContextFactory.h",
2239        "tools/graphite/GraphiteTestContext.cpp",
2240        "tools/graphite/GraphiteTestContext.h",
2241        "tools/graphite/GraphiteToolUtils.cpp",
2242        "tools/graphite/GraphiteToolUtils.h",
2243        "tools/graphite/ProtectedUtils_Graphite.cpp",
2244        "tools/graphite/UniqueKeyUtils.cpp",
2245        "tools/graphite/UniqueKeyUtils.h",
2246      ]
2247      if (skia_use_dawn) {
2248        sources += [
2249          "tools/graphite/dawn/GraphiteDawnTestContext.cpp",
2250          "tools/graphite/dawn/GraphiteDawnTestContext.h",
2251        ]
2252      }
2253      if (skia_use_metal) {
2254        sources += [
2255          "tools/graphite/mtl/GraphiteMtlTestContext.h",
2256          "tools/graphite/mtl/GraphiteMtlTestContext.mm",
2257        ]
2258      }
2259      if (skia_use_vulkan) {
2260        sources += [
2261          "tools/graphite/vk/GraphiteVulkanTestContext.cpp",
2262          "tools/graphite/vk/GraphiteVulkanTestContext.h",
2263        ]
2264      }
2265      if (skia_enable_precompile) {
2266        sources += [
2267          "tools/graphite/precompile/PipelineCallbackHandler.cpp",
2268          "tools/graphite/precompile/PipelineCallbackHandler.h",
2269          "tools/graphite/precompile/PrecompileEffectFactories.cpp",
2270          "tools/graphite/precompile/PrecompileEffectFactories.h",
2271        ]
2272      }
2273    }
2274
2275    if (is_fuchsia && using_fuchsia_sdk) {
2276      libs +=
2277          [ "${fuchsia_sdk_path}/arch/${target_cpu}/sysroot/lib/libzircon.so" ]
2278    }
2279  }  # test_lib("gpu_tool_utils")
2280
2281  test_lib("flags") {
2282    sources = [
2283      "tools/flags/CommandLineFlags.cpp",
2284      "tools/flags/CommandLineFlags.h",
2285    ]
2286  }
2287
2288  test_lib("common_flags_config") {
2289    sources = [
2290      "tools/flags/CommonFlags.h",
2291      "tools/flags/CommonFlagsConfig.cpp",
2292      "tools/flags/CommonFlagsConfig.h",
2293    ]
2294    deps = [ ":flags" ]
2295    public_deps = [ ":gpu_tool_utils" ]
2296  }
2297  test_lib("common_flags_gpu") {
2298    sources = [ "tools/flags/CommonFlagsGanesh.cpp" ]
2299    deps = [ ":flags" ]
2300    public_deps = [ ":gpu_tool_utils" ]
2301  }
2302  test_lib("common_flags_graphite") {
2303    sources = [ "tools/flags/CommonFlagsGraphite.cpp" ]
2304    deps = [ ":flags" ]
2305    public_deps = [ ":gpu_tool_utils" ]
2306  }
2307  test_lib("common_flags_images") {
2308    sources = [ "tools/flags/CommonFlagsImages.cpp" ]
2309    deps = [ ":flags" ]
2310  }
2311
2312  test_lib("trace") {
2313    deps = [ ":flags" ]
2314    sources = [
2315      "tools/trace/ChromeTracingTracer.cpp",
2316      "tools/trace/ChromeTracingTracer.h",
2317      "tools/trace/EventTracingPriv.cpp",
2318      "tools/trace/EventTracingPriv.h",
2319      "tools/trace/SkDebugfTracer.cpp",
2320      "tools/trace/SkDebugfTracer.h",
2321    ]
2322    if (skia_use_perfetto) {
2323      deps += [ "//third_party/perfetto" ]
2324      sources += [
2325        "tools/trace/SkPerfettoTrace.cpp",
2326        "tools/trace/SkPerfettoTrace.h",
2327      ]
2328      defines = [ "SK_USE_PERFETTO" ]
2329    }
2330  }
2331
2332  test_lib("tool_utils") {
2333    sources = [
2334      "tools/AndroidSkDebugToStdOut.cpp",
2335      "tools/AutoreleasePool.h",
2336      "tools/DDLPromiseImageHelper.cpp",
2337      "tools/DDLPromiseImageHelper.h",
2338      "tools/DDLTileHelper.cpp",
2339      "tools/DDLTileHelper.h",
2340      "tools/DecodeUtils.cpp",
2341      "tools/DecodeUtils.h",
2342      "tools/EncodeUtils.cpp",
2343      "tools/EncodeUtils.h",
2344      "tools/GpuToolUtils.h",
2345      "tools/LsanSuppressions.cpp",
2346      "tools/ProcStats.cpp",
2347      "tools/ProcStats.h",
2348      "tools/Resources.cpp",
2349      "tools/Resources.h",
2350      "tools/RuntimeBlendUtils.cpp",
2351      "tools/RuntimeBlendUtils.h",
2352      "tools/SkMetaData.cpp",
2353      "tools/SkMetaData.h",
2354      "tools/Stats.h",
2355      "tools/TestFontDataProvider.cpp",
2356      "tools/TestFontDataProvider.h",
2357      "tools/ToolUtils.cpp",
2358      "tools/ToolUtils.h",
2359      "tools/TsanSuppressions.cpp",
2360      "tools/UrlDataManager.cpp",
2361      "tools/UrlDataManager.h",
2362      "tools/debugger/DebugCanvas.cpp",
2363      "tools/debugger/DebugCanvas.h",
2364      "tools/debugger/DebugLayerManager.cpp",
2365      "tools/debugger/DebugLayerManager.h",
2366      "tools/debugger/DrawCommand.cpp",
2367      "tools/debugger/DrawCommand.h",
2368      "tools/debugger/JsonWriteBuffer.cpp",
2369      "tools/debugger/JsonWriteBuffer.h",
2370      "tools/fonts/FontToolUtils.cpp",
2371      "tools/fonts/FontToolUtils.h",
2372      "tools/fonts/RandomScalerContext.cpp",
2373      "tools/fonts/RandomScalerContext.h",
2374      "tools/fonts/TestEmptyTypeface.h",
2375      "tools/fonts/TestFontMgr.cpp",
2376      "tools/fonts/TestFontMgr.h",
2377      "tools/fonts/TestSVGTypeface.cpp",
2378      "tools/fonts/TestSVGTypeface.h",
2379      "tools/fonts/TestTypeface.cpp",
2380      "tools/fonts/TestTypeface.h",
2381      "tools/sksltrace/SkSLTraceUtils.cpp",
2382      "tools/sksltrace/SkSLTraceUtils.h",
2383      "tools/text/SkTextBlobTrace.cpp",
2384      "tools/text/SkTextBlobTrace.h",
2385      "tools/timer/TimeUtils.h",
2386      "tools/timer/Timer.cpp",
2387      "tools/timer/Timer.h",
2388    ]
2389    if (skia_enable_svg) {
2390      sources += [
2391        "tools/SvgPathExtractor.cpp",
2392        "tools/SvgPathExtractor.h",
2393      ]
2394    }
2395    if (skia_use_libpng_decode) {
2396      sources += [
2397        "tools/MSKPPlayer.cpp",
2398        "tools/MSKPPlayer.h",
2399        "tools/SkSharingProc.cpp",
2400        "tools/SkSharingProc.h",
2401      ]
2402    }
2403
2404    if (target_cpu != "wasm") {
2405      sources += [ "tools/CrashHandler.cpp" ]
2406    }
2407    libs = []
2408    frameworks = []
2409    if (is_ios) {
2410      sources += [ "tools/ios_utils.m" ]
2411      sources += [ "tools/ios_utils.h" ]
2412      sources += [ "tools/AutoreleasePool.mm" ]
2413      frameworks += [ "Foundation.framework" ]
2414    } else if (is_mac) {
2415      sources += [ "tools/AutoreleasePool.mm" ]
2416      frameworks += [ "Foundation.framework" ]
2417    } else if (is_win && !skia_enable_winuwp) {
2418      libs += [ "DbgHelp.lib" ]
2419    }
2420
2421    defines = []
2422    if (skia_tools_require_resources) {
2423      defines += [ "SK_TOOLS_REQUIRE_RESOURCES" ]
2424    }
2425    deps = [ ":flags" ]
2426    if (skia_enable_svg) {
2427      deps += [ "modules/svg" ]
2428    }
2429    public_deps = [
2430      ":gpu_tool_utils",
2431      "modules/jsonreader",
2432    ]
2433  }
2434
2435  test_lib("etc1") {
2436    sources = [ "third_party/etc1/etc1.cpp" ]
2437  }
2438
2439  import("gn/gm.gni")
2440  test_lib("gm") {
2441    sources = gm_sources
2442    if (skia_use_gl) {
2443      sources += gl_gm_sources
2444    }
2445    if (!skia_enable_ganesh) {
2446      sources -= ganesh_gm_sources
2447    }
2448    if (skia_use_fontations) {
2449      sources += fontations_gm_sources
2450    }
2451    deps = [
2452      ":etc1",
2453      ":flags",
2454      ":skia",
2455      ":tool_utils",
2456      "modules/skottie",
2457      "modules/skottie:gm",
2458      "modules/skparagraph",
2459      "modules/skparagraph:gm",
2460      "modules/skresources",
2461      "modules/skshaper",
2462    ]
2463    if (is_skia_dev_build) {
2464      sources += [ "gm/fiddle.cpp" ]
2465      deps += [ ":skia.h" ]
2466    }
2467    public_deps = [ ":gpu_tool_utils" ]
2468
2469    if (skia_use_ffmpeg) {
2470      deps += [ "experimental/ffmpeg:video_decoder" ]
2471      sources += [ "gm/video_decoder.cpp" ]
2472    }
2473  }
2474
2475  test_lib("test") {
2476    sources = [
2477      "tests/CtsEnforcement.cpp",
2478      "tests/Test.cpp",
2479      "tests/Test.h",
2480      "tests/TestHarness.cpp",
2481      "tests/TestHarness.h",
2482      "tests/TestUtils.cpp",
2483      "tests/TestUtils.h",
2484    ]
2485    deps = [
2486      ":flags",
2487      ":skia",
2488      ":tool_utils",
2489    ]
2490    public_deps = [
2491      ":gpu_tool_utils",  # Test.h #includes headers from this target.
2492    ]
2493  }
2494
2495  import("gn/tests.gni")
2496  test_lib("tests") {
2497    sources = tests_sources + pathops_tests_sources
2498    frameworks = []
2499    if (skia_use_metal) {
2500      sources += metal_tests_sources
2501      cflags_objcc = [ "-fobjc-arc" ]
2502      frameworks += [ "MetalKit.framework" ]
2503    }
2504    if (skia_use_jpeg_gainmaps) {
2505      sources += jpeg_gainmap_tests_sources
2506    }
2507    if (skia_use_gl) {
2508      sources += gl_tests_sources
2509    }
2510    if (skia_use_vulkan) {
2511      sources += skia_gpu_vk_chromium_public
2512      sources += skia_gpu_vk_chromium_private
2513    }
2514    if (skia_enable_graphite) {
2515      sources += graphite_tests_sources
2516      if (skia_use_dawn) {
2517        sources += graphite_dawn_tests_sources
2518      }
2519      if (skia_use_metal) {
2520        sources += graphite_metal_tests_sources
2521      }
2522      if (skia_use_vulkan) {
2523        sources += graphite_vulkan_tests_sources
2524      }
2525    }
2526    if (!skia_enable_ganesh) {
2527      sources -= ganesh_tests_sources
2528    }
2529    if (skia_enable_precompile) {
2530      sources += precompile_tests_sources
2531    }
2532    deps = [
2533      ":flags",
2534      ":fontmgr_FontConfigInterface_tests",
2535      ":fontmgr_android_tests",
2536      ":fontmgr_fontconfig_tests",
2537      ":fontmgr_mac_ct_tests",
2538      ":fontscanner_tests",
2539      ":png_decode_libpng_tests",
2540      ":png_decode_rust_tests",
2541      ":png_encode_rust_tests",
2542      ":skia",
2543      ":test",
2544      ":tool_utils",
2545      ":typeface_fontations_tests",
2546      "modules/bentleyottmann:tests",
2547      "modules/skottie:tests",
2548      "modules/skparagraph:tests",
2549      "modules/sksg:tests",
2550      "modules/skshaper",
2551      "modules/skshaper:tests",
2552      "modules/skunicode:tests",
2553      "modules/svg:tests",
2554      "//third_party/libpng",
2555      "//third_party/libwebp",
2556      "//third_party/zlib",
2557    ]
2558  }
2559
2560  import("gn/bench.gni")
2561  test_lib("bench") {
2562    sources = bench_sources
2563    if (skia_enable_graphite) {
2564      sources += graphite_bench_sources
2565    }
2566    if (!skia_enable_ganesh) {
2567      sources -= ganesh_bench_sources
2568    }
2569    deps = [
2570      ":flags",
2571      ":gm",
2572      ":gpu_tool_utils",
2573      ":skia",
2574      ":tool_utils",
2575      "modules/skparagraph:bench",
2576      "modules/skshaper",
2577    ]
2578  }
2579
2580  if (is_linux || is_mac || skia_enable_optimize_size) {
2581    if (skia_enable_skottie) {
2582      test_app("skottie_tool") {
2583        deps = [ "modules/skottie:tool" ]
2584      }
2585      test_app("skottie_tool_cpu") {
2586        deps = [ "modules/skottie:tool_cpu" ]
2587      }
2588      test_app("skottie_tool_gpu") {
2589        deps = [ "modules/skottie:tool_gpu" ]
2590      }
2591      test_app("skottie_preshape_tool") {
2592        deps = [ "modules/skottie:preshape_tool" ]
2593      }
2594    }
2595    if (skia_enable_svg && skia_use_expat && defined(is_skia_standalone)) {
2596      test_app("svg_tool") {
2597        deps = [ "modules/svg:tool" ]
2598      }
2599    }
2600  }
2601
2602  test_lib("hash_and_encode") {
2603    sources = [
2604      "tools/HashAndEncode.cpp",
2605      "tools/HashAndEncode.h",
2606    ]
2607    deps = [
2608      ":flags",
2609      ":skia",
2610      "//third_party/libpng",
2611    ]
2612  }
2613  if (target_cpu != "wasm") {
2614    test_app("convert-to-nia") {
2615      sources = [ "tools/convert-to-nia.cpp" ]
2616      deps = [ ":skia" ]
2617    }
2618    test_app("imgcvt") {
2619      sources = [ "tools/imgcvt.cpp" ]
2620      configs = [ ":use_skia_vulkan_headers" ]
2621      deps = [
2622        ":skia",
2623        "modules/skcms",
2624      ]
2625    }
2626    test_app("dm") {
2627      sources = [
2628        "dm/DM.cpp",
2629        "dm/DMGpuTestProcs.cpp",
2630        "dm/DMJsonWriter.cpp",
2631        "dm/DMJsonWriter.h",
2632        "dm/DMSrcSink.cpp",
2633        "dm/DMSrcSink.h",
2634      ]
2635      deps = [
2636        ":common_flags_config",
2637        ":common_flags_gpu",
2638        ":common_flags_graphite",
2639        ":common_flags_images",
2640        ":compile_all_sksl_tests",
2641        ":flags",
2642        ":gm",
2643        ":gpu_tool_utils",
2644        ":hash_and_encode",
2645        ":skia",
2646        ":tests",
2647        ":tool_utils",
2648        ":trace",
2649        "modules/skottie",
2650        "modules/skottie:utils",
2651        "modules/skshaper",
2652        "modules/skunicode",
2653      ]
2654      if (skia_use_libpng_decode) {
2655        deps += [ "modules/svg" ]
2656      }
2657    }
2658    test_app("filterfuzz") {
2659      sources = [ "experimental/filterfuzz/filterfuzz.cpp" ]
2660      deps = [
2661        ":flags",
2662        ":skia",
2663        ":tool_utils",
2664      ]
2665    }
2666
2667    if (!skia_enable_optimize_size && !skia_use_fontations &&
2668        !skia_enable_vello_shaders) {
2669      # optional separate library to dlopen when running CanvasStateTests.
2670      skia_shared_library("canvas_state_lib") {
2671        sources = [
2672          "tests/CanvasStateHelpers.cpp",
2673          "tests/CanvasStateHelpers.h",
2674        ]
2675        deps = [ ":skia" ]
2676      }
2677    }
2678  }
2679
2680  if (!is_win) {
2681    test_app("blob_cache_sim") {
2682      sources = [ "tools/blob_cache_sim.cpp" ]
2683      deps = [
2684        ":skia",
2685        ":tool_utils",
2686      ]
2687    }
2688  }
2689
2690  if (skia_use_libpng_decode) {
2691    test_app("nanobench") {
2692      sources = [
2693        "bench/nanobench.cpp",
2694        "bench/nanobench.h",
2695      ]
2696      deps = [
2697        ":bench",
2698        ":common_flags_config",
2699        ":common_flags_gpu",
2700        ":common_flags_graphite",
2701        ":common_flags_images",
2702        ":flags",
2703        ":gm",
2704        ":gpu_tool_utils",
2705        ":skia",
2706        ":tool_utils",
2707        ":trace",
2708        "modules/skparagraph",
2709        "modules/skshaper",
2710        "modules/skunicode",
2711        "modules/svg",
2712      ]
2713    }
2714  }
2715
2716  test_app("skpinfo") {
2717    sources = [ "tools/skpinfo.cpp" ]
2718    configs = [ ":use_skia_vulkan_headers" ]
2719    deps = [
2720      ":flags",
2721      ":skia",
2722    ]
2723  }
2724
2725  if (skia_use_ffmpeg) {
2726    test_app("skottie2movie") {
2727      sources = [ "tools/skottie2movie.cpp" ]
2728      deps = [
2729        ":flags",
2730        ":gpu_tool_utils",
2731        ":skia",
2732        "experimental/ffmpeg:video_encoder",
2733        "modules/skottie",
2734        "modules/skottie:utils",
2735      ]
2736    }
2737  }
2738
2739  if (skia_use_libpng_decode) {
2740    test_app("skpbench") {
2741      sources = [
2742        "bench/BigPath.cpp",
2743        "tools/skpbench/skpbench.cpp",
2744      ]
2745      deps = [
2746        ":common_flags_config",
2747        ":common_flags_gpu",
2748        ":flags",
2749        ":gpu_tool_utils",
2750        ":skia",
2751        ":tool_utils",
2752      ]
2753    }
2754  }
2755
2756  if (is_linux && skia_use_icu) {
2757    test_app("sktexttopdf") {
2758      sources = [ "tools/using_skia_and_harfbuzz.cpp" ]
2759      deps = [
2760        ":skia",
2761        "modules/skshaper",
2762      ]
2763    }
2764  }
2765
2766  if (is_linux || is_mac) {
2767    test_app("create_test_font") {
2768      sources = [ "tools/fonts/create_test_font.cpp" ]
2769      deps = [ ":skia" ]
2770      assert_no_deps = [
2771        # tool_utils requires the output of this app.
2772        ":tool_utils",
2773      ]
2774    }
2775  }
2776
2777  if (skia_use_expat) {
2778    test_app("create_test_font_color") {
2779      sources = [ "tools/fonts/create_test_font_color.cpp" ]
2780      deps = [
2781        ":flags",
2782        ":skia",
2783        ":tool_utils",
2784        "//modules/svg",
2785      ]
2786    }
2787  }
2788
2789  test_app("get_images_from_skps") {
2790    sources = [ "tools/get_images_from_skps.cpp" ]
2791    deps = [
2792      ":flags",
2793      ":skia",
2794    ]
2795  }
2796
2797  test_app("fuzz") {
2798    sources = [
2799      "fuzz/Fuzz.cpp",
2800      "fuzz/Fuzz.h",
2801      "fuzz/FuzzCanvas.cpp",
2802      "fuzz/FuzzCommon.cpp",
2803      "fuzz/FuzzCommon.h",
2804      "fuzz/FuzzCreateDDL.cpp",
2805      "fuzz/FuzzCubicRoots.cpp",
2806      "fuzz/FuzzDDLThreading.cpp",
2807      "fuzz/FuzzDrawFunctions.cpp",
2808      "fuzz/FuzzEncoders.cpp",
2809      "fuzz/FuzzGradients.cpp",
2810      "fuzz/FuzzMain.cpp",
2811      "fuzz/FuzzParsePath.cpp",
2812      "fuzz/FuzzPathMeasure.cpp",
2813      "fuzz/FuzzPathop.cpp",
2814      "fuzz/FuzzPolyUtils.cpp",
2815      "fuzz/FuzzQuadRoots.cpp",
2816      "fuzz/FuzzRegionOp.cpp",
2817      "fuzz/FuzzSkParagraph.cpp",
2818      "fuzz/FuzzTriangulation.cpp",
2819      "fuzz/oss_fuzz/FuzzAndroidCodec.cpp",
2820      "fuzz/oss_fuzz/FuzzAnimatedImage.cpp",
2821      "fuzz/oss_fuzz/FuzzCOLRv1.cpp",
2822      "fuzz/oss_fuzz/FuzzColorspace.cpp",
2823      "fuzz/oss_fuzz/FuzzImage.cpp",
2824      "fuzz/oss_fuzz/FuzzImageFilterDeserialize.cpp",
2825      "fuzz/oss_fuzz/FuzzIncrementalImage.cpp",
2826      "fuzz/oss_fuzz/FuzzJSON.cpp",
2827      "fuzz/oss_fuzz/FuzzParsePath.cpp",
2828      "fuzz/oss_fuzz/FuzzPathDeserialize.cpp",
2829      "fuzz/oss_fuzz/FuzzRegionDeserialize.cpp",
2830      "fuzz/oss_fuzz/FuzzRegionSetPath.cpp",
2831      "fuzz/oss_fuzz/FuzzSKP.cpp",
2832      "fuzz/oss_fuzz/FuzzSKSL2GLSL.cpp",
2833      "fuzz/oss_fuzz/FuzzSKSL2Metal.cpp",
2834      "fuzz/oss_fuzz/FuzzSKSL2Pipeline.cpp",
2835      "fuzz/oss_fuzz/FuzzSKSL2SPIRV.cpp",
2836      "fuzz/oss_fuzz/FuzzSKSL2WGSL.cpp",
2837      "fuzz/oss_fuzz/FuzzSVG.cpp",
2838      "fuzz/oss_fuzz/FuzzSkDescriptorDeserialize.cpp",
2839      "fuzz/oss_fuzz/FuzzSkMeshSpecification.cpp",
2840      "fuzz/oss_fuzz/FuzzSkParagraph.cpp",
2841      "fuzz/oss_fuzz/FuzzSkRuntimeBlender.cpp",
2842      "fuzz/oss_fuzz/FuzzSkRuntimeColorFilter.cpp",
2843      "fuzz/oss_fuzz/FuzzSkRuntimeEffect.cpp",
2844      "fuzz/oss_fuzz/FuzzTextBlobDeserialize.cpp",
2845      "tools/UrlDataManager.cpp",
2846      "tools/debugger/DebugCanvas.cpp",
2847      "tools/debugger/DebugLayerManager.cpp",
2848      "tools/debugger/DrawCommand.cpp",
2849      "tools/debugger/JsonWriteBuffer.cpp",
2850      "tools/fonts/FontToolUtils.cpp",
2851    ]
2852
2853    if (skia_enable_graphite && skia_enable_precompile) {
2854      sources += [ "fuzz/FuzzPrecompile.cpp" ]
2855    }
2856    deps = [
2857      ":flags",
2858      ":gpu_tool_utils",
2859      ":skia",
2860      "modules/jsonreader",
2861      "modules/skottie:fuzz",
2862      "modules/skparagraph",
2863      "modules/svg",
2864    ]
2865  }
2866
2867  test_app("dump_record") {
2868    sources = [ "tools/dump_record.cpp" ]
2869    deps = [
2870      ":flags",
2871      ":skia",
2872    ]
2873  }
2874
2875  if (skia_use_libpng_decode) {
2876    test_app("skdiff") {
2877      sources = [
2878        "tools/skdiff/skdiff.cpp",
2879        "tools/skdiff/skdiff_html.cpp",
2880        "tools/skdiff/skdiff_main.cpp",
2881        "tools/skdiff/skdiff_utils.cpp",
2882      ]
2883      deps = [ ":skia" ]
2884    }
2885
2886    test_app("skp_parser") {
2887      sources = [ "tools/skp_parser.cpp" ]
2888      deps = [
2889        ":skia",
2890        ":tool_utils",
2891      ]
2892    }
2893  }
2894
2895  if (!is_win) {
2896    source_set("skqp_lib") {  # Not a skia_source_set
2897      check_includes = false
2898      testonly = true
2899      public_configs = [ ":skia_private" ]
2900      sources = [
2901        "tools/skqp/src/skqp.cpp",
2902        "tools/skqp/src/skqp.h",
2903        "tools/skqp/src/skqp_GpuTestProcs.cpp",
2904      ]
2905      deps = [
2906        ":gm",
2907        ":skia",
2908        ":tests",
2909        ":tool_utils",
2910      ]
2911    }
2912    if (skia_use_libpng_decode) {
2913      test_app("skqp") {
2914        sources = [ "tools/skqp/src/skqp_main.cpp" ]
2915        include_dirs = [ "//" ]
2916        lib_dirs = []
2917        deps = [ ":skqp_lib" ]
2918      }
2919    }
2920  }
2921  if (is_fuchsia) {
2922    # Build a package repository for skqp on Fuchsia.
2923    group("skqp_repo") {
2924      testonly = true
2925      deps = [ "//build/fuchsia/skqp:skqp_repo" ]
2926    }
2927  }
2928  if (is_android) {
2929    shared_library("libskqp_jni") {  # Not a skia_shared_library
2930      configs += [ ":skia_private" ]
2931      testonly = true
2932      sources = [ "tools/skqp/src/jni_skqp.cpp" ]
2933      deps = [
2934        ":skia",
2935        ":skqp_lib",
2936        ":tool_utils",
2937      ]
2938      libs = [ "android" ]
2939    }
2940  }
2941  if (is_android && skia_use_gl) {
2942    test_app("skottie_android") {
2943      is_shared_library = true
2944
2945      sources = [ "platform_tools/android/apps/skottie/skottielib/src/main/cpp/native-lib.cpp" ]
2946      libs = []
2947
2948      deps = [
2949        ":skia",
2950        "modules/skottie",
2951        "modules/skshaper",
2952        "modules/skunicode",
2953      ]
2954    }
2955
2956    test_app("jetski") {
2957      is_shared_library = true
2958
2959      sources = [
2960        "modules/jetski/src/Canvas.cpp",
2961        "modules/jetski/src/ColorFilters.cpp",
2962        "modules/jetski/src/Gradients.cpp",
2963        "modules/jetski/src/Image.cpp",
2964        "modules/jetski/src/ImageFilter.cpp",
2965        "modules/jetski/src/JetSki.cpp",
2966        "modules/jetski/src/Matrix.cpp",
2967        "modules/jetski/src/Paint.cpp",
2968        "modules/jetski/src/Path.cpp",
2969        "modules/jetski/src/PathBuilder.cpp",
2970        "modules/jetski/src/RuntimeShaderBuilder.cpp",
2971        "modules/jetski/src/Shader.cpp",
2972        "modules/jetski/src/SkottieAnimation.cpp",
2973        "modules/jetski/src/Surface.cpp",
2974        "modules/jetski/src/Surface.h",
2975        "modules/jetski/src/SurfaceThread.cpp",
2976        "modules/jetski/src/SurfaceThread.h",
2977        "modules/jetski/src/Utils.cpp",
2978      ]
2979      libs = [
2980        "android",
2981        "jnigraphics",
2982      ]
2983
2984      deps = [
2985        ":skia",
2986        "modules/skottie:skottie",
2987        "tools/window:window",
2988      ]
2989    }
2990  }
2991
2992  if (is_ios && skia_enable_skottie) {
2993    group("skottie_ios") {
2994      deps = [ "tools/skottie_ios_app" ]
2995    }
2996  }
2997
2998  test_lib("sk_app") {
2999    public_deps = [
3000      ":gpu_tool_utils",
3001      ":skia",
3002    ]
3003    sources = [
3004      "tools/sk_app/Application.h",
3005      "tools/sk_app/CommandSet.cpp",
3006      "tools/sk_app/CommandSet.h",
3007      "tools/sk_app/Window.cpp",
3008      "tools/sk_app/Window.h",
3009    ]
3010    libs = []
3011    frameworks = []
3012
3013    if (is_android) {
3014      sources += [
3015        "tools/sk_app/android/Window_android.cpp",
3016        "tools/sk_app/android/Window_android.h",
3017        "tools/sk_app/android/main_android.cpp",
3018        "tools/sk_app/android/surface_glue_android.cpp",
3019        "tools/sk_app/android/surface_glue_android.h",
3020      ]
3021      libs += [ "android" ]
3022    } else if (is_linux) {
3023      sources += [
3024        "tools/sk_app/unix/Window_unix.cpp",
3025        "tools/sk_app/unix/Window_unix.h",
3026        "tools/sk_app/unix/keysym2ucs.c",
3027        "tools/sk_app/unix/keysym2ucs.h",
3028        "tools/sk_app/unix/main_unix.cpp",
3029      ]
3030      libs += [
3031        "GL",  # Used by raster window context, so cannot be behind skia_use_gl.
3032        "X11",
3033      ]
3034    } else if (is_win) {
3035      sources += [
3036        "tools/sk_app/win/Window_win.cpp",
3037        "tools/sk_app/win/Window_win.h",
3038        "tools/sk_app/win/main_win.cpp",
3039      ]
3040    } else if (is_mac) {
3041      sources += [
3042        "tools/sk_app/mac/Window_mac.h",
3043        "tools/sk_app/mac/Window_mac.mm",
3044        "tools/sk_app/mac/main_mac.mm",
3045      ]
3046      frameworks += [
3047        "QuartzCore.framework",
3048        "Cocoa.framework",
3049        "Foundation.framework",
3050      ]
3051    } else if (is_ios) {
3052      sources += [
3053        "tools/sk_app/ios/Window_ios.h",
3054        "tools/sk_app/ios/Window_ios.mm",
3055        "tools/sk_app/ios/main_ios.mm",
3056      ]
3057      frameworks += [ "QuartzCore.framework" ]
3058    }
3059
3060    deps = [
3061      ":tool_utils",
3062      "tools/window",
3063    ]
3064    if (is_android) {
3065      deps += [ "//third_party/native_app_glue" ]
3066    }
3067    if (skia_use_gl && skia_use_angle) {
3068      deps += [ "//third_party/angle2" ]
3069    }
3070  }
3071
3072  if (!skia_use_vulkan && (is_mac || is_linux || is_win)) {
3073    test_app("fiddle_examples") {
3074      sources = [
3075        "tools/fiddle/all_examples.cpp",
3076        "tools/fiddle/examples.cpp",
3077        "tools/fiddle/examples.h",
3078      ]
3079      if (is_win) {
3080        cflags = [
3081          "/wd4756",  # Overflow in constant arithmetic
3082          "/wd4305",  # truncation from 'double' to 'float'
3083        ]
3084      }
3085      deps = [
3086        ":skia",
3087        ":skia.h",
3088        "modules/skottie",
3089        "modules/skparagraph",
3090        "modules/skshaper",
3091        "modules/svg",
3092      ]
3093    }
3094  }
3095
3096  # sk_app can work without GL but viewer always runs raster through a GL window context.
3097  if (skia_use_gl) {
3098    test_app("viewer") {
3099      is_shared_library = is_android
3100      sources = [
3101        "tools/viewer/3DSlide.cpp",
3102        "tools/viewer/AndroidShadowsSlide.cpp",
3103        "tools/viewer/AnimBlurSlide.cpp",
3104        "tools/viewer/AnimTimer.h",
3105        "tools/viewer/AnimatedImageSlide.cpp",
3106        "tools/viewer/AnimatedImageSlide.h",
3107        "tools/viewer/AnimatedRectsSlide.cpp",
3108        "tools/viewer/AnimatedTextSlide.cpp",
3109        "tools/viewer/ArcSlide.cpp",
3110        "tools/viewer/AtlasSlide.cpp",
3111        "tools/viewer/AudioSlide.cpp",
3112        "tools/viewer/BisectSlide.cpp",
3113        "tools/viewer/BisectSlide.h",
3114        "tools/viewer/CameraSlide.cpp",
3115        "tools/viewer/ChartSlide.cpp",
3116        "tools/viewer/ChineseFlingSlide.cpp",
3117        "tools/viewer/ClickHandlerSlide.cpp",
3118        "tools/viewer/ClickHandlerSlide.h",
3119        "tools/viewer/ClipSlide.cpp",
3120        "tools/viewer/ClockSlide.cpp",
3121        "tools/viewer/CowboySlide.cpp",
3122        "tools/viewer/DegenerateQuadsSlide.cpp",
3123        "tools/viewer/DegenerateTwoPtRadialsSlide.cpp",
3124        "tools/viewer/FatBitsSlide.cpp",
3125        "tools/viewer/FilterBoundsSlide.cpp",
3126        "tools/viewer/FitCubicToCircleSlide.cpp",
3127        "tools/viewer/FlutterAnimateSlide.cpp",
3128        "tools/viewer/GMSlide.cpp",
3129        "tools/viewer/GMSlide.h",
3130        "tools/viewer/GlyphTransformSlide.cpp",
3131        "tools/viewer/GradientsSlide.cpp",
3132        "tools/viewer/GraphitePrimitivesSlide.cpp",
3133        "tools/viewer/ImGuiLayer.cpp",
3134        "tools/viewer/ImGuiLayer.h",
3135        "tools/viewer/ImageFilterDAGSlide.cpp",
3136        "tools/viewer/ImageSlide.cpp",
3137        "tools/viewer/ImageSlide.h",
3138        "tools/viewer/LayersSlide.cpp",
3139        "tools/viewer/ManyRectsSlide.cpp",
3140        "tools/viewer/MaterialShadowsSlide.cpp",
3141        "tools/viewer/MegaStrokeSlide.cpp",
3142        "tools/viewer/MeshGradientSlide.cpp",
3143        "tools/viewer/MeshSlide.cpp",
3144        "tools/viewer/MixerSlide.cpp",
3145        "tools/viewer/MotionMarkSlide.cpp",
3146        "tools/viewer/PatchSlide.cpp",
3147        "tools/viewer/PathClipSlide.cpp",
3148        "tools/viewer/PathEffectsSlide.cpp",
3149        "tools/viewer/PathLerpSlide.cpp",
3150        "tools/viewer/PathOverstrokeSlide.cpp",
3151        "tools/viewer/PathSlide.cpp",
3152        "tools/viewer/PathTessellatorsSlide.cpp",
3153        "tools/viewer/PathTextSlide.cpp",
3154        "tools/viewer/ProtectedSlide.cpp",
3155        "tools/viewer/QuadStrokerSlide.cpp",
3156        "tools/viewer/RectanizerSlide.cpp",
3157        "tools/viewer/RepeatTileSlide.cpp",
3158        "tools/viewer/SBIXSlide.cpp",
3159        "tools/viewer/SGSlide.cpp",
3160        "tools/viewer/SKPSlide.cpp",
3161        "tools/viewer/SKPSlide.h",
3162        "tools/viewer/SVGFileSlide.cpp",
3163        "tools/viewer/ShadowColorSlide.cpp",
3164        "tools/viewer/ShadowReferenceSlide.cpp",
3165        "tools/viewer/ShadowUtilsSlide.cpp",
3166        "tools/viewer/ShipSlide.cpp",
3167        "tools/viewer/SimpleStrokerSlide.cpp",
3168        "tools/viewer/SkSLDebuggerSlide.cpp",
3169        "tools/viewer/SkSLDebuggerSlide.h",
3170        "tools/viewer/SkSLSlide.cpp",
3171        "tools/viewer/SkSLSlide.h",
3172        "tools/viewer/SkottieSlide.cpp",
3173        "tools/viewer/SkottieSlide.h",
3174        "tools/viewer/Slide.h",
3175        "tools/viewer/SlideDir.cpp",
3176        "tools/viewer/SlideDir.h",
3177        "tools/viewer/SlidesSlide.cpp",
3178        "tools/viewer/StatsLayer.cpp",
3179        "tools/viewer/StatsLayer.h",
3180        "tools/viewer/StringArtSlide.cpp",
3181        "tools/viewer/StrokeVerbSlide.cpp",
3182        "tools/viewer/SvgSlide.cpp",
3183        "tools/viewer/SvgSlide.h",
3184        "tools/viewer/TextBoxSlide.cpp",
3185        "tools/viewer/TextureUploadSlide.cpp",
3186        "tools/viewer/ThinAASlide.cpp",
3187        "tools/viewer/TimingSlide.cpp",
3188        "tools/viewer/TouchGesture.cpp",
3189        "tools/viewer/TouchGesture.h",
3190        "tools/viewer/TypefaceSlide.cpp",
3191        "tools/viewer/VariableWidthStrokerSlide.cpp",
3192        "tools/viewer/Viewer.cpp",
3193        "tools/viewer/Viewer.h",
3194        "tools/viewer/XferSlide.cpp",
3195      ]
3196      libs = []
3197
3198      deps = [
3199        ":common_flags_config",
3200        ":common_flags_gpu",
3201        ":common_flags_graphite",
3202        ":flags",
3203        ":gm",
3204        ":gpu_tool_utils",
3205        ":sk_app",
3206        ":skia",
3207        ":tool_utils",
3208        ":trace",
3209        ":xml",
3210        "modules/audioplayer",
3211        "modules/skottie",
3212        "modules/skottie:utils",
3213        "modules/skparagraph:slides",
3214        "modules/skresources",
3215        "modules/sksg:slides",
3216        "modules/skshaper:skshaper",
3217        "modules/skunicode",
3218        "//third_party/delaunator",
3219        "//third_party/imgui",
3220      ]
3221      if (skia_use_libpng_decode) {
3222        deps += [ "modules/svg" ]
3223
3224        sources += [
3225          "tools/viewer/MSKPSlide.cpp",
3226          "tools/viewer/MSKPSlide.h",
3227        ]
3228      }
3229      if (skia_use_vulkan) {
3230        deps += [
3231          "//third_party/externals/spirv-tools:spvtools",
3232
3233          #spvtools depends on this but doesn't deps it in.
3234          "//third_party/externals/spirv-tools:spvtools_val",
3235        ]
3236      }
3237    }
3238  }
3239
3240  if (skia_use_vulkan) {
3241    test_app("VulkanBasic") {
3242      # Bots and even devs may not have Vulkan headers, so put
3243      # include/third_party/vulkan on our path so they're always available.
3244      all_dependent_configs = [
3245        ":use_skia_vulkan_headers",
3246        ":vulkan_memory_allocator",
3247      ]
3248
3249      sources = [ "example/VulkanBasic.cpp" ]
3250      sources += [ "tools/gpu/vk/VkTestMemoryAllocator.h" ]
3251      sources += [ "tools/gpu/vk/VkTestMemoryAllocator.cpp" ]
3252      sources += [ "tools/gpu/vk/VkTestUtils.h" ]
3253      sources += [ "tools/gpu/vk/VkTestUtils.cpp" ]
3254      deps = [
3255        ":load_dynamic_library",
3256        ":skia",
3257      ]
3258    }
3259  }
3260
3261  if (is_ios && skia_use_metal && skia_enable_ganesh) {
3262    group("minimal_ios_mtl_skia_app") {
3263      deps = [ "experimental/minimal_ios_mtl_skia_app" ]
3264    }
3265  }
3266
3267  if (is_linux || is_win || is_mac) {
3268    test_app("editor") {
3269      is_shared_library = is_android
3270      deps = [ "modules/skplaintexteditor:editor_app" ]
3271    }
3272  }
3273
3274  skia_executable("image_diff_metric") {
3275    sources = [ "tools/image_diff_metric.cpp" ]
3276    deps = [ ":skia" ]
3277  }
3278
3279  group("modules_testonly") {
3280    testonly = true
3281    deps = []
3282    if (is_wasm) {
3283      deps += [ "modules/canvaskit:viewer_wasm" ]
3284    }
3285  }
3286
3287  if (skia_build_fuzzers) {
3288    template("libfuzzer_app") {
3289      skia_executable(target_name) {
3290        output_dir = root_build_dir
3291        check_includes = false
3292        forward_variables_from(invoker, "*", [ "is_shared_library" ])
3293        if (!defined(configs)) {
3294          configs = []
3295        }
3296        configs += [ ":skia_private" ]
3297        sources += [
3298          "fuzz/Fuzz.cpp",
3299          "fuzz/FuzzCommon.cpp",
3300        ]
3301        deps += [
3302          ":flags",
3303          ":gpu_tool_utils",
3304          ":skia",
3305          ":tool_utils",
3306        ]
3307        defines = [
3308          "SK_BUILD_FOR_LIBFUZZER",
3309          "SK_BUILD_FOR_FUZZER",
3310        ]
3311        if (skia_use_libfuzzer_defaults) {
3312          cflags = [ "-fsanitize=fuzzer" ]
3313          ldflags = [ "-fsanitize=fuzzer" ]
3314        }
3315        testonly = true
3316      }
3317    }
3318
3319    libfuzzer_app("region_deserialize") {
3320      sources = [ "fuzz/oss_fuzz/FuzzRegionDeserialize.cpp" ]
3321      deps = []
3322    }
3323
3324    libfuzzer_app("image_filter_deserialize") {
3325      sources = [ "fuzz/oss_fuzz/FuzzImageFilterDeserialize.cpp" ]
3326      deps = [ "modules/svg" ]
3327    }
3328
3329    libfuzzer_app("region_set_path") {
3330      sources = [ "fuzz/oss_fuzz/FuzzRegionSetPath.cpp" ]
3331      deps = []
3332    }
3333
3334    libfuzzer_app("textblob_deserialize") {
3335      sources = [ "fuzz/oss_fuzz/FuzzTextBlobDeserialize.cpp" ]
3336      deps = [ "modules/svg" ]
3337    }
3338
3339    libfuzzer_app("path_deserialize") {
3340      sources = [ "fuzz/oss_fuzz/FuzzPathDeserialize.cpp" ]
3341      deps = []
3342    }
3343
3344    libfuzzer_app("image_decode") {
3345      sources = [ "fuzz/oss_fuzz/FuzzImage.cpp" ]
3346      deps = []
3347    }
3348
3349    libfuzzer_app("animated_image_decode") {
3350      sources = [ "fuzz/oss_fuzz/FuzzAnimatedImage.cpp" ]
3351      deps = []
3352    }
3353
3354    libfuzzer_app("api_create_ddl") {
3355      sources = [
3356        "fuzz/FuzzCreateDDL.cpp",
3357        "fuzz/oss_fuzz/FuzzAPICreateDDL.cpp",
3358      ]
3359      deps = [
3360        "modules/svg",
3361        "//third_party/libpng",
3362      ]
3363    }
3364
3365    libfuzzer_app("api_draw_functions") {
3366      sources = [
3367        "fuzz/FuzzDrawFunctions.cpp",
3368        "fuzz/oss_fuzz/FuzzDrawFunctions.cpp",
3369      ]
3370      deps = []
3371    }
3372
3373    libfuzzer_app("api_ddl_threading") {
3374      sources = [
3375        "fuzz/FuzzDDLThreading.cpp",
3376        "fuzz/oss_fuzz/FuzzDDLThreading.cpp",
3377      ]
3378      deps = []
3379    }
3380
3381    libfuzzer_app("api_gradients") {
3382      sources = [
3383        "fuzz/FuzzGradients.cpp",
3384        "fuzz/oss_fuzz/FuzzGradients.cpp",
3385      ]
3386      deps = []
3387    }
3388
3389    libfuzzer_app("api_image_filter") {
3390      sources = [
3391        "fuzz/FuzzCanvas.cpp",
3392        "fuzz/oss_fuzz/FuzzAPIImageFilter.cpp",
3393      ]
3394      deps = [ "//third_party/libpng" ]
3395    }
3396
3397    libfuzzer_app("api_path_measure") {
3398      sources = [
3399        "fuzz/FuzzPathMeasure.cpp",
3400        "fuzz/oss_fuzz/FuzzPathMeasure.cpp",
3401      ]
3402      deps = []
3403    }
3404
3405    libfuzzer_app("api_pathop") {
3406      sources = [
3407        "fuzz/FuzzPathop.cpp",
3408        "fuzz/oss_fuzz/FuzzPathop.cpp",
3409      ]
3410      deps = []
3411    }
3412
3413    libfuzzer_app("api_triangulation") {
3414      sources = [
3415        "fuzz/FuzzTriangulation.cpp",
3416        "fuzz/oss_fuzz/FuzzTriangulation.cpp",
3417      ]
3418      deps = []
3419    }
3420
3421    libfuzzer_app("api_raster_n32_canvas") {
3422      sources = [
3423        "fuzz/FuzzCanvas.cpp",
3424        "fuzz/oss_fuzz/FuzzRasterN32Canvas.cpp",
3425      ]
3426      deps = [
3427        "modules/svg",
3428        "//third_party/libpng",
3429      ]
3430    }
3431
3432    libfuzzer_app("api_regionop") {
3433      sources = [
3434        "fuzz/FuzzRegionOp.cpp",
3435        "fuzz/oss_fuzz/FuzzRegionOp.cpp",
3436      ]
3437      deps = []
3438    }
3439
3440    if (skia_enable_ganesh) {
3441      libfuzzer_app("api_mock_gpu_canvas") {
3442        sources = [
3443          "fuzz/FuzzCanvas.cpp",
3444          "fuzz/oss_fuzz/FuzzMockGPUCanvas.cpp",
3445        ]
3446        deps = [
3447          "modules/svg",
3448          "//third_party/libpng",
3449        ]
3450      }
3451    }
3452
3453    if (skia_enable_graphite && skia_enable_precompile) {
3454      libfuzzer_app("api_precompile") {
3455        sources = [
3456          "fuzz/FuzzPrecompile.cpp",
3457          "fuzz/oss_fuzz/FuzzPrecompile.cpp",
3458        ]
3459        deps = []
3460      }
3461    }
3462
3463    libfuzzer_app("api_null_canvas") {
3464      sources = [
3465        "fuzz/FuzzCanvas.cpp",
3466        "fuzz/oss_fuzz/FuzzNullCanvas.cpp",
3467      ]
3468      deps = [
3469        "modules/svg",
3470        "//third_party/libpng",
3471      ]
3472    }
3473
3474    libfuzzer_app("api_skparagraph") {
3475      sources = [
3476        "fuzz/FuzzSkParagraph.cpp",
3477        "fuzz/oss_fuzz/FuzzSkParagraph.cpp",
3478      ]
3479      deps = [ "modules/skparagraph" ]
3480    }
3481
3482    libfuzzer_app("api_svg_canvas") {
3483      sources = [
3484        "fuzz/FuzzCanvas.cpp",
3485        "fuzz/oss_fuzz/FuzzAPISVGCanvas.cpp",
3486      ]
3487      deps = [
3488        "modules/svg",
3489        "//third_party/libpng",
3490      ]
3491    }
3492
3493    libfuzzer_app("png_encoder") {
3494      sources = [
3495        "fuzz/FuzzEncoders.cpp",
3496        "fuzz/oss_fuzz/FuzzPNGEncoder.cpp",
3497      ]
3498      deps = []
3499    }
3500
3501    libfuzzer_app("jpeg_encoder") {
3502      sources = [
3503        "fuzz/FuzzEncoders.cpp",
3504        "fuzz/oss_fuzz/FuzzJPEGEncoder.cpp",
3505      ]
3506      deps = []
3507    }
3508
3509    libfuzzer_app("webp_encoder") {
3510      sources = [
3511        "fuzz/FuzzEncoders.cpp",
3512        "fuzz/oss_fuzz/FuzzWEBPEncoder.cpp",
3513      ]
3514      deps = []
3515    }
3516
3517    libfuzzer_app("skottie_json") {
3518      sources = [ "modules/skottie/fuzz/FuzzSkottieJSON.cpp" ]
3519      deps = [
3520        "modules/jsonreader",
3521        "modules/skottie:skottie",
3522        "modules/svg",
3523      ]
3524    }
3525
3526    libfuzzer_app("skjson") {
3527      sources = [ "fuzz/oss_fuzz/FuzzJSON.cpp" ]
3528      deps = [ "modules/jsonreader" ]
3529    }
3530
3531    libfuzzer_app("api_polyutils") {
3532      sources = [
3533        "fuzz/FuzzPolyUtils.cpp",
3534        "fuzz/oss_fuzz/FuzzPolyUtils.cpp",
3535      ]
3536      deps = [ ":skia" ]
3537    }
3538
3539    libfuzzer_app("android_codec") {
3540      sources = [ "fuzz/oss_fuzz/FuzzAndroidCodec.cpp" ]
3541      deps = []
3542    }
3543
3544    libfuzzer_app("image_decode_incremental") {
3545      sources = [ "fuzz/oss_fuzz/FuzzIncrementalImage.cpp" ]
3546      deps = []
3547    }
3548
3549    libfuzzer_app("sksl2glsl") {
3550      sources = [ "fuzz/oss_fuzz/FuzzSKSL2GLSL.cpp" ]
3551      deps = []
3552    }
3553
3554    libfuzzer_app("sksl2metal") {
3555      sources = [ "fuzz/oss_fuzz/FuzzSKSL2Metal.cpp" ]
3556      deps = []
3557    }
3558
3559    libfuzzer_app("sksl2pipeline") {
3560      sources = [ "fuzz/oss_fuzz/FuzzSKSL2Pipeline.cpp" ]
3561      deps = []
3562    }
3563
3564    libfuzzer_app("sksl2spirv") {
3565      sources = [ "fuzz/oss_fuzz/FuzzSKSL2SPIRV.cpp" ]
3566      deps = []
3567    }
3568
3569    libfuzzer_app("sksl2wgsl") {
3570      sources = [ "fuzz/oss_fuzz/FuzzSKSL2WGSL.cpp" ]
3571      deps = []
3572    }
3573
3574    libfuzzer_app("skdescriptor_deserialize") {
3575      sources = [ "fuzz/oss_fuzz/FuzzSkDescriptorDeserialize.cpp" ]
3576      deps = []
3577    }
3578
3579    libfuzzer_app("svg_dom") {
3580      sources = [ "fuzz/oss_fuzz/FuzzSVG.cpp" ]
3581      deps = [ "modules/svg" ]
3582    }
3583
3584    libfuzzer_app("skruntimeblender") {
3585      sources = [ "fuzz/oss_fuzz/FuzzSkRuntimeBlender.cpp" ]
3586      deps = []
3587    }
3588
3589    libfuzzer_app("skruntimecolorfilter") {
3590      sources = [ "fuzz/oss_fuzz/FuzzSkRuntimeColorFilter.cpp" ]
3591      deps = []
3592    }
3593
3594    libfuzzer_app("skruntimeeffect") {
3595      sources = [ "fuzz/oss_fuzz/FuzzSkRuntimeEffect.cpp" ]
3596      deps = []
3597    }
3598
3599    libfuzzer_app("skmeshspecification") {
3600      sources = [ "fuzz/oss_fuzz/FuzzSkMeshSpecification.cpp" ]
3601      deps = []
3602    }
3603
3604    libfuzzer_app("skp") {
3605      sources = [ "fuzz/oss_fuzz/FuzzSKP.cpp" ]
3606      deps = []
3607    }
3608
3609    libfuzzer_app("colrv1") {
3610      sources = [ "fuzz/oss_fuzz/FuzzCOLRv1.cpp" ]
3611      deps = []
3612    }
3613
3614    libfuzzer_app("quad_roots") {
3615      sources = [
3616        "fuzz/FuzzQuadRoots.cpp",
3617        "fuzz/oss_fuzz/FuzzQuadRoots.cpp",
3618      ]
3619      deps = []
3620    }
3621
3622    libfuzzer_app("cubic_roots") {
3623      sources = [
3624        "fuzz/FuzzCubicRoots.cpp",
3625        "fuzz/oss_fuzz/FuzzCubicRoots.cpp",
3626      ]
3627      deps = []
3628    }
3629
3630    libfuzzer_app("skcolorspace") {
3631      sources = [ "fuzz/oss_fuzz/FuzzColorspace.cpp" ]
3632      deps = []
3633    }
3634
3635    libfuzzer_app("parse_path") {
3636      sources = [ "fuzz/oss_fuzz/FuzzParsePath.cpp" ]
3637      deps = []
3638    }
3639  }
3640}
3641
3642if (skia_build_rust_targets) {
3643  action("rust_hello_world") {
3644    script = "gn/bazel_build.py"
3645    sources = [ "experimental/rust_cxx/hello-world.rs" ]
3646    outputs = [ "$root_out_dir/rust_hello_world" ]
3647    args = [
3648      "//experimental/rust_cxx:rust_hello_world",
3649      "../../bazel-bin/experimental/rust_cxx/rust_hello_world",
3650    ]
3651  }
3652
3653  action("cpp_with_rust") {
3654    script = "gn/bazel_build.py"
3655    sources = [
3656      "experimental/rust_cxx/hype-bridge.rs",
3657      "experimental/rust_cxx/main.cpp",
3658    ]
3659    outputs = [ "$root_out_dir/cpp_with_rust" ]
3660    args = [
3661      "//experimental/rust_cxx:cpp_with_rust",
3662      "../../bazel-bin/experimental/rust_cxx/cpp_with_rust",
3663    ]
3664  }
3665}
3666