• 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("//build/ohos.gni")
7import("//foundation/arkui/ace_engine/ace_config.gni")
8import("//foundation/graphic/graphic_2d/graphic_config.gni")
9import("gn/flutter_defines.gni")
10import("gn/fuchsia_defines.gni")
11import("gn/shared_sources.gni")
12import("gn/skia.gni")
13
14if (defined(is_mingw) && is_mingw == true) {
15  is_win = true
16}
17
18if (is_fuchsia) {
19  import("${skia_root_dir}/build/fuchsia/sdk.gni")
20  import("build/fuchsia/fuchsia_download_sdk.gni")
21}
22
23if (skia_use_dawn) {
24  import("${skia_third_party_dir}/externals/dawn/scripts/dawn_features.gni")
25}
26
27if (defined(skia_settings)) {
28  import(skia_settings)
29}
30
31import("gn/ios.gni")
32
33config("skia_wno") {
34  cflags = [
35    "-Wno-deprecated-declarations",
36    "-Wno-pessimizing-move",
37    "-Wno-return-type",
38    "-Wno-sign-compare",
39    "-Wno-sometimes-uninitialized",
40    "-Wno-unknown-pragmas",
41    "-Wno-unused-function",
42    "-Wno-unused-private-field",
43    "-Wno-unused-variable",
44    "-Wno-c++17-extensions",
45  ]
46  if (is_ohos && is_clang && (target_cpu == "arm" || target_cpu == "arm64")) {
47    cflags += [ "-flto=thin" ]
48    if (enhanced_opt) {
49      cflags += [ "-fwhole-program-vtables" ]
50      if (graphic_2d_feature_enable_pgo &&
51          graphic_2d_feature_product != "default") {
52        cflags += [
53          "-fprofile-use=" + rebase_path(
54                  "${graphic_2d_feature_pgo_path}/libskia_canvaskit.profdata",
55                  root_build_dir),
56          "-Wno-error=backend-plugin",
57          "-Wno-profile-instr-out-of-date",
58          "-Wno-profile-instr-unprofiled",
59        ]
60      }
61      if (graphic_2d_feature_product == "pc" && target_cpu == "arm64" &&
62          current_cpu == "arm64") {
63        cflags += [ "-moutline-atomics" ]
64      }
65    }
66  }
67
68  ldflags = [
69    "--stdlib=libc++",
70    "-lc++",
71    "-lc++abi",
72  ]
73}
74
75# Skia public API, generally provided by :skia.
76config("skia_public") {
77  include_dirs = [ "." ]
78
79  defines = [ "NEW_SKIA" ]
80  include_dirs += [ "//base/hiviewdfx/hitrace/interfaces/native/innerkits/include/hitrace_meter" ]
81  if (defined(skia_ohos_debug) && skia_ohos_debug) {
82    defines += [ "SKIA_OHOS_DEBUG" ]
83  }
84  if (is_ohos && (target_cpu == "arm" || target_cpu == "arm64")) {
85    defines += [ "SKIA_OHOS_FOR_OHOS_TRACE" ]
86  }
87  cflags_objcc = []
88  if (is_skia_dev_build) {
89    defines += [ "GR_TEST_UTILS=1" ]
90  }
91  if (is_skia_component_build) {
92    defines += [ "SKIA_DLL" ]
93  }
94  if (is_arkui_x && defined(is_android) && is_android) {
95    defines += [ "SK_BUILD_FOR_ANDROID" ]
96  }
97  defines += [ "SK_BUILD_FOR_OHOS" ]
98  if (is_fuchsia || is_linux) {
99    defines += [ "SK_R32_SHIFT=16" ]
100  }
101  if (skia_enable_flutter_defines) {
102    defines += flutter_defines
103  }
104  if (!skia_enable_gpu) {
105    defines += [ "SK_SUPPORT_GPU=0" ]
106  }
107  if (skia_enable_sksl) {
108    defines += [ "SK_ENABLE_SKSL" ]
109  }
110  if (is_fuchsia) {
111    defines += fuchsia_defines
112  }
113  if (skia_gl_standard == "gles") {
114    defines += [ "SK_ASSUME_GL_ES=1" ]
115  } else if (skia_gl_standard == "gl") {
116    defines += [ "SK_ASSUME_GL=1" ]
117  } else if (skia_gl_standard == "webgl") {
118    defines += [
119      "SK_ASSUME_WEBGL=1",
120      "SK_USE_WEBGL",
121    ]
122  }
123  if (!skia_enable_skgpu_v1) {
124    defines += [ "SK_GPU_V1=0" ]
125  }
126  if (ace_enable_skia_small_page_texture && is_ohos) {
127    defines += [ "SK_ENABLE_SMALL_PAGE" ]
128  }
129
130  # Some older versions of the Clang toolchain change the visibility of
131  # symbols decorated with API_AVAILABLE macro to be visible. Users of such
132  # toolchains suppress the use of this macro till toolchain updates are made.
133  if (is_mac) {
134    defines += [ "SK_GL_ENABLE_330_MAC" ]
135  }
136  if (is_mac || is_ios) {
137    if (skia_enable_api_available_macro) {
138      defines += [ "SK_ENABLE_API_AVAILABLE" ]
139    } else {
140      cflags_objcc += [ "-Wno-unguarded-availability" ]
141    }
142  }
143  if (is_win) {
144    defines += [ "SK_BUILD_FOR_WIN" ]
145  }
146}
147
148# Skia internal APIs, used by Skia itself and a few test tools.
149config("skia_private") {
150  visibility = [ "./*" ]
151
152  cflags = [
153    "-Wno-format",
154    "-fvisibility=hidden",
155  ]
156
157  cflags_cc = [
158    "-Wno-array-parameter",
159    "-fvisibility-inlines-hidden",
160  ]
161
162  defines = [ "SK_GAMMA_APPLY_TO_A8" ]
163  if (target_cpu == "x86_64" || current_os == "windows" ||
164      current_os == "mac" || current_os == "linux" || current_os == "ios") {
165    cflags_cc += [ "-Wno-psabi" ]
166  }
167  if (skia_use_fixed_gamma_text) {
168    defines += [
169      "SK_GAMMA_EXPONENT=1.0",
170      "SK_GAMMA_CONTRAST=0.0",
171    ]
172  }
173  if (is_skia_dev_build) {
174    defines += [ "SK_ALLOW_STATIC_GLOBAL_INITIALIZERS=1" ]
175    if (skia_enable_graphite) {
176      defines += [ "GRAPHITE_TEST_UTILS=1" ]
177    }
178  }
179  libs = []
180  lib_dirs = []
181  if (skia_use_gl && skia_use_angle) {
182    defines += [ "SK_ANGLE" ]
183  }
184  if (skia_use_vma) {
185    defines += [ "SK_USE_VMA" ]
186  }
187  if (skia_enable_winuwp) {
188    defines += [ "SK_WINUWP" ]
189  }
190}
191
192# Any code that's linked into Skia-the-library should use this config via += skia_library_configs.
193config("skia_library") {
194  visibility = [ "./*" ]
195  defines = [ "SKIA_IMPLEMENTATION=1" ]
196}
197
198skia_library_configs = [
199  ":skia_public",
200  ":skia_private",
201  ":skia_library",
202]
203
204# Use for CPU-specific Skia code that needs particular compiler flags.
205template("opts") {
206  if (invoker.enabled) {
207    skia_source_set(target_name) {
208      visibility = [ ":*" ]
209      check_includes = false
210      configs = skia_library_configs
211      forward_variables_from(invoker, "*")
212      if (defined(invoker.configs)) {
213        configs += invoker.configs
214      }
215    }
216  } else {
217    # If not enabled, a phony empty target that swallows all otherwise unused variables.
218    skia_source_set(target_name) {
219      visibility = [ ":*" ]
220      check_includes = false
221      forward_variables_from(invoker,
222                             "*",
223                             [
224                               "sources",
225                               "cflags",
226                             ])
227    }
228  }
229}
230
231is_x86 = current_cpu == "x64" || current_cpu == "x86"
232
233opts("none") {
234  enabled = !is_x86 && current_cpu != "arm" && current_cpu != "arm64"
235  sources = skia_opts.none_sources
236  cflags = []
237}
238
239opts("armv7") {
240  enabled = current_cpu == "arm"
241  sources = skia_opts.armv7_sources + skia_opts.neon_sources
242  cflags = []
243}
244
245opts("arm64") {
246  enabled = current_cpu == "arm64"
247  sources = skia_opts.arm64_sources
248  cflags = []
249}
250
251opts("crc32") {
252  enabled = current_cpu == "arm64"
253  sources = skia_opts.crc32_sources
254  cflags = [ "-march=armv8-a+crc" ]
255}
256
257opts("sse2") {
258  enabled = is_x86
259  sources = skia_opts.sse2_sources
260  if (!is_clang && is_win) {
261    defines = [ "SK_CPU_SSE_LEVEL=SK_CPU_SSE_LEVEL_SSE2" ]
262  } else {
263    cflags = [ "-msse2" ]
264  }
265}
266
267opts("ssse3") {
268  enabled = is_x86
269  sources = skia_opts.ssse3_sources
270  if (!is_clang && is_win) {
271    defines = [ "SK_CPU_SSE_LEVEL=SK_CPU_SSE_LEVEL_SSSE3" ]
272  } else {
273    cflags = [ "-mssse3" ]
274  }
275}
276
277opts("sse41") {
278  enabled = is_x86
279  sources = skia_opts.sse41_sources
280  if (!is_clang && is_win) {
281    defines = [ "SK_CPU_SSE_LEVEL=SK_CPU_SSE_LEVEL_SSE41" ]
282  } else {
283    cflags = [ "-msse4.1" ]
284  }
285}
286
287opts("sse42") {
288  enabled = is_x86
289  sources = skia_opts.sse42_sources
290  if (!is_clang && is_win) {
291    defines = [ "SK_CPU_SSE_LEVEL=SK_CPU_SSE_LEVEL_SSE42" ]
292  } else {
293    cflags = [ "-msse4.2" ]
294  }
295}
296
297opts("avx") {
298  enabled = is_x86
299  sources = skia_opts.avx_sources
300  if (is_win && !is_mingw) {
301    cflags = [ "/arch:AVX" ]
302  } else {
303    cflags = [ "-mavx" ]
304    if (is_mac && is_debug) {
305      cflags += [ "-fno-stack-check" ]  # Work around skia:9709
306    }
307  }
308}
309
310opts("hsw") {
311  enabled = is_x86
312  sources = skia_opts.hsw_sources
313  if (is_win && !is_mingw) {
314    cflags = [ "/arch:AVX2" ]
315  } else {
316    cflags = [ "-march=haswell" ]
317    if (is_mac && is_debug) {
318      cflags += [ "-fno-stack-check" ]  # Work around skia:9709
319    }
320  }
321}
322
323opts("skx") {
324  enabled = is_x86
325  sources = skia_opts.skx_sources
326  if (is_win && !is_mingw) {
327    cflags = [ "/arch:AVX512" ]
328  } else {
329    cflags = [ "-march=skylake-avx512" ]
330    if (is_mac && is_debug) {
331      cflags += [ "-fno-stack-check" ]  # Work around skia:9709
332    }
333  }
334}
335
336# Any feature of Skia that requires third-party code should be optional and use this template.
337template("optional") {
338  if (invoker.enabled) {
339    config(target_name + "_public") {
340      if (defined(invoker.public_defines)) {
341        defines = invoker.public_defines
342      }
343      if (defined(invoker.public_configs)) {
344        configs = invoker.public_configs
345      }
346      if (defined(invoker.public_include_dirs)) {
347        include_dirs = invoker.public_include_dirs
348      }
349    }
350    skia_source_set(target_name) {
351      visibility = [ ":*" ]
352      check_includes = false
353      configs = skia_library_configs
354      configs += [ ":skia_wno" ]
355
356      # "*" clobbers the current scope; append to existing configs
357      forward_variables_from(invoker,
358                             "*",
359                             [
360                               "configs",
361                               "public_defines",
362                               "sources_for_tests",
363                               "sources_when_disabled",
364                             ])
365      if (defined(invoker.configs)) {
366        configs += invoker.configs
367      }
368      all_dependent_configs = [ ":" + target_name + "_public" ]
369    }
370    if (defined(invoker.sources_for_tests) && skia_enable_tools) {
371      skia_source_set(target_name + "_tests") {
372        visibility = [ ":*" ]
373        check_includes = false
374        configs = skia_library_configs
375
376        # "*" clobbers the current scope; append to existing configs
377        forward_variables_from(invoker,
378                               "*",
379                               [
380                                 "configs",
381                                 "public_defines",
382                                 "sources",
383                                 "sources_for_tests",
384                                 "sources_when_disabled",
385                               ])
386        if (defined(invoker.configs)) {
387          configs += invoker.configs
388        }
389        testonly = true
390        sources = invoker.sources_for_tests
391        if (!defined(deps)) {
392          deps = []
393        }
394        deps += [ ":test" ]
395        all_dependent_configs = [ ":" + target_name + "_public" ]
396      }
397    }
398  } else {
399    skia_source_set(target_name) {
400      visibility = [ ":*" ]
401      configs = skia_library_configs
402
403      # "*" clobbers the current scope; append to existing configs
404      forward_variables_from(invoker,
405                             "*",
406                             [
407                               "configs",
408                               "public",
409                               "public_defines",
410                               "public_deps",
411                               "deps",
412                               "libs",
413                               "frameworks",
414                               "sources",
415                               "sources_for_tests",
416                               "sources_when_disabled",
417                             ])
418      if (defined(invoker.configs)) {
419        configs += invoker.configs
420      }
421      if (defined(invoker.sources_when_disabled)) {
422        sources = invoker.sources_when_disabled
423      }
424    }
425    if (defined(invoker.sources_for_tests)) {
426      skia_source_set(target_name + "_tests") {
427        visibility = [ ":*" ]
428      }
429    }
430  }
431}
432
433optional("android_utils") {
434  enabled = skia_enable_android_utils
435
436  public = [
437    "client_utils/android/BRDAllocator.h",
438    "client_utils/android/BitmapRegionDecoder.h",
439    "client_utils/android/FrontBufferedStream.h",
440  ]
441  public_defines = [ "SK_ENABLE_ANDROID_UTILS" ]
442  sources = [
443    "client_utils/android/BitmapRegionDecoder.cpp",
444    "client_utils/android/FrontBufferedStream.cpp",
445  ]
446}
447
448group("fontmgr_factory") {
449  public_deps = [ skia_fontmgr_factory ]
450}
451
452optional("fontmgr_empty_factory") {
453  if (use_oh_skia) {
454    enabled = false
455  } else {
456    enabled = true
457  }
458  sources = [ "src/ports/SkFontMgr_empty_factory.cpp" ]
459}
460
461optional("fontmgr_android") {
462  enabled = skia_enable_fontmgr_android
463
464  deps = [
465    ":typeface_freetype",
466    "${skia_third_party_dir}/expat",
467  ]
468  public = [ "include/ports/SkFontMgr_android.h" ]
469  sources = [
470    "src/ports/SkFontMgr_android.cpp",
471    "src/ports/SkFontMgr_android_parser.cpp",
472    "src/ports/SkFontMgr_android_parser.h",
473  ]
474  sources_for_tests = [ "tests/FontMgrAndroidParserTest.cpp" ]
475}
476optional("fontmgr_android_factory") {
477  enabled = skia_enable_fontmgr_android
478  deps = [ ":fontmgr_android" ]
479  sources = [ "src/ports/SkFontMgr_android_factory.cpp" ]
480}
481
482optional("fontmgr_custom") {
483  enabled =
484      skia_enable_fontmgr_custom_directory ||
485      skia_enable_fontmgr_custom_embedded || skia_enable_fontmgr_custom_empty
486
487  deps = [ ":typeface_freetype" ]
488  public = [ "src/ports/SkFontMgr_custom.h" ]
489  sources = [ "src/ports/SkFontMgr_custom.cpp" ]
490}
491
492optional("fontmgr_symbol_load") {
493  enabled = skia_enable_fontmgr_ohos || skia_enable_fontmgr_win ||
494            skia_use_fonthost_mac
495  include_dirs = [
496    "//third_party/skia/include/private",
497    "//third_party/skia/include/core",
498    "//third_party/skia/src/core",
499    "//third_party/skia/src/ports",
500    "//third_party/skia/src/ports/skia_ohos",
501  ]
502  deps = [
503    ":typeface_freetype",
504    "${skia_third_party_dir}/expat",
505    "//third_party/jsoncpp:jsoncpp_static",
506  ]
507  if (is_component_build) {
508    deps += [ "//third_party/bounds_checking_function:libsec_shared" ]
509  } else {
510    deps += [ "//third_party/bounds_checking_function:libsec_static" ]
511  }
512
513  deps += [ ":ohos_fontconfig.json" ]
514  public = [ "src/ports/skia_ohos/HmSymbolConfig_ohos.h" ]
515  sources = [ "src/ports/skia_ohos/HmSymbolConfig_ohos.cpp" ]
516}
517
518optional("fontmgr_custom_directory") {
519  enabled = skia_enable_fontmgr_custom_directory
520
521  deps = [
522    ":fontmgr_custom",
523    ":typeface_freetype",
524  ]
525  public = [ "include/ports/SkFontMgr_directory.h" ]
526  sources = [ "src/ports/SkFontMgr_custom_directory.cpp" ]
527}
528optional("fontmgr_custom_directory_factory") {
529  enabled = skia_enable_fontmgr_custom_directory
530  deps = [ ":fontmgr_custom_directory" ]
531  sources = [ "src/ports/SkFontMgr_custom_directory_factory.cpp" ]
532  if (use_linux) {
533    defines = [ "SK_BUILD_FONT_MGR_FOR_PREVIEW_LINUX" ]
534  }
535  if (is_arkui_x) {
536    sources -= [ "src/ports/SkFontMgr_custom_directory_factory.cpp" ]
537  }
538}
539
540optional("fontmgr_custom_embedded") {
541  enabled = skia_enable_fontmgr_custom_embedded
542
543  deps = [
544    ":fontmgr_custom",
545    ":typeface_freetype",
546  ]
547  sources = [ "src/ports/SkFontMgr_custom_embedded.cpp" ]
548}
549optional("fontmgr_custom_embedded_factory") {
550  enabled = skia_enable_fontmgr_custom_embedded
551  deps = [ ":fontmgr_custom_embedded" ]
552  sources = [ "src/ports/SkFontMgr_custom_embedded_factory.cpp" ]
553}
554
555optional("fontmgr_custom_empty") {
556  enabled = skia_enable_fontmgr_custom_empty
557
558  deps = [
559    ":fontmgr_custom",
560    ":typeface_freetype",
561  ]
562  public = [ "include/ports/SkFontMgr_empty.h" ]
563  sources = [ "src/ports/SkFontMgr_custom_empty.cpp" ]
564}
565optional("fontmgr_custom_empty_factory") {
566  enabled = skia_enable_fontmgr_custom_empty
567  deps = [ ":fontmgr_custom_empty" ]
568  sources = [ "src/ports/SkFontMgr_custom_empty_factory.cpp" ]
569}
570
571optional("fontmgr_fontconfig") {
572  if (use_oh_skia) {
573    enabled = false
574  } else {
575    enabled = skia_enable_fontmgr_fontconfig
576  }
577
578  # The public header includes fontconfig.h and uses FcConfig*
579  public_deps = [ "${skia_third_party_dir}:fontconfig" ]
580  public = [ "include/ports/SkFontMgr_fontconfig.h" ]
581  deps = [ ":typeface_freetype" ]
582  sources = [ "src/ports/SkFontMgr_fontconfig.cpp" ]
583  sources_for_tests = [ "tests/FontMgrFontConfigTest.cpp" ]
584}
585optional("fontmgr_fontconfig_factory") {
586  if (use_oh_skia) {
587    enabled = false
588  } else {
589    enabled = skia_enable_fontmgr_fontconfig
590  }
591
592  deps = [ ":fontmgr_fontconfig" ]
593  sources = [ "src/ports/SkFontMgr_fontconfig_factory.cpp" ]
594}
595
596optional("fontmgr_FontConfigInterface") {
597  if (use_oh_skia) {
598    enabled = false
599  } else {
600    enabled = skia_enable_fontmgr_FontConfigInterface
601  }
602
603  deps = [
604    ":typeface_freetype",
605    "${skia_third_party_dir}:fontconfig",
606  ]
607  public = [
608    "include/ports/SkFontConfigInterface.h",
609    "include/ports/SkFontMgr_FontConfigInterface.h",
610  ]
611  sources = [
612    "src/ports/SkFontConfigInterface.cpp",
613    "src/ports/SkFontConfigInterface_direct.cpp",
614    "src/ports/SkFontConfigInterface_direct_factory.cpp",
615    "src/ports/SkFontConfigTypeface.h",
616    "src/ports/SkFontMgr_FontConfigInterface.cpp",
617  ]
618}
619optional("fontmgr_FontConfigInterface_factory") {
620  enabled = skia_enable_fontmgr_FontConfigInterface
621  deps = [ ":fontmgr_FontConfigInterface" ]
622  sources = [ "src/ports/SkFontMgr_FontConfigInterface_factory.cpp" ]
623}
624
625optional("fontmgr_fuchsia") {
626  enabled = skia_enable_fontmgr_fuchsia
627
628  deps = []
629
630  if (is_fuchsia && using_fuchsia_sdk) {
631    deps += [ "${skia_root_dir}/build/fuchsia/fidl:fuchsia.fonts" ]
632  } else {
633    deps = [ "${skia_root_dir}/sdk/fidl/fuchsia.fonts" ]
634  }
635  public = [ "src/ports/SkFontMgr_fuchsia.h" ]
636  sources = [ "src/ports/SkFontMgr_fuchsia.cpp" ]
637}
638
639optional("fontmgr_mac_ct") {
640  enabled = skia_use_fonthost_mac
641
642  public = [
643    "include/ports/SkFontMgr_mac_ct.h",
644    "include/ports/SkTypeface_mac.h",
645  ]
646  sources = [
647    "src/ports/SkFontMgr_mac_ct.cpp",
648    "src/ports/SkScalerContext_mac_ct.cpp",
649    "src/ports/SkScalerContext_mac_ct.h",
650    "src/ports/SkTypeface_mac_ct.cpp",
651    "src/ports/SkTypeface_mac_ct.h",
652  ]
653  if (use_oh_skia && !is_arkui_x) {
654    # Use hos font
655    sources += [
656      "//third_party/skia/src/ports/SkFontMgr_config_parser.cpp",
657      "//third_party/skia/src/ports/SkFontMgr_config_parser.h",
658      "//third_party/skia/src/ports/SkFontMgr_preview.cpp",
659      "//third_party/skia/src/ports/SkFontMgr_preview.h",
660    ]
661    include_dirs = [
662      "//third_party/skia/include/core",
663      "//third_party/skia/include/private",
664      "//third_party/skia/src/core",
665      "//third_party/skia/src/ports",
666      "//third_party/skia/src/ports/skia_ohos",
667    ]
668    defines = [ "SK_BUILD_FONT_MGR_FOR_PREVIEW_MAC" ]
669    deps = [
670      ":fontmgr_symbol_load",
671      "${skia_third_party_dir}/expat",
672      "//third_party/jsoncpp:jsoncpp_static",
673    ]
674  }
675  sources_for_tests = [ "tests/TypefaceMacTest.cpp" ]
676
677  if (is_mac) {
678    frameworks = [
679      # AppKit symbols NSFontWeightXXX may be dlsym'ed.
680      "AppKit.framework",
681      "ApplicationServices.framework",
682    ]
683  }
684
685  if (is_ios) {
686    frameworks = [
687      "CoreFoundation.framework",
688      "CoreGraphics.framework",
689      "CoreText.framework",
690
691      # UIKit symbols UIFontWeightXXX may be dlsym'ed.
692      "UIKit.framework",
693    ]
694  }
695}
696optional("fontmgr_mac_ct_factory") {
697  enabled = skia_use_fonthost_mac
698  deps = [ ":fontmgr_mac_ct" ]
699  sources = [ "src/ports/SkFontMgr_mac_ct_factory.cpp" ]
700  defines = [ "SK_BUILD_FONT_MGR_FOR_PREVIEW_MAC" ]
701  if (is_arkui_x) {
702    defines += [ "USE_DEFAULT_FONT" ]
703  }
704}
705
706optional("fontmgr_win") {
707  enabled = skia_enable_fontmgr_win
708
709  public = [ "include/ports/SkTypeface_win.h" ]
710  sources = [
711    "src/fonts/SkFontMgr_indirect.cpp",
712    "src/ports/SkFontMgr_win_dw.cpp",
713    "src/ports/SkScalerContext_win_dw.cpp",
714    "src/ports/SkScalerContext_win_dw.h",
715    "src/ports/SkTypeface_win_dw.cpp",
716    "src/ports/SkTypeface_win_dw.h",
717  ]
718  if (use_oh_skia) {
719    # Use hos font
720    sources += [
721      "//third_party/skia/src/ports/SkFontMgr_config_parser.cpp",
722      "//third_party/skia/src/ports/SkFontMgr_config_parser.h",
723      "//third_party/skia/src/ports/SkFontMgr_preview.cpp",
724      "//third_party/skia/src/ports/SkFontMgr_preview.h",
725    ]
726
727    include_dirs = [
728      "//third_party/skia/include/core",
729      "//third_party/skia/include/private",
730      "//third_party/skia/src/core",
731      "//third_party/skia/src/ports",
732      "//third_party/skia/src/ports/skia_ohos",
733    ]
734    defines = [ "SK_BUILD_FONT_MGR_FOR_PREVIEW_WIN" ]
735    deps = [
736      ":fontmgr_symbol_load",
737      "${skia_third_party_dir}/expat",
738      "//third_party/jsoncpp:jsoncpp_static",
739    ]
740  }
741}
742
743if (use_oh_skia && !is_arkui_x) {
744  ohos_prebuilt_etc("ohos_fontconfig.json") {
745    source = "//third_party/skia/src/ports/skia_ohos/config/fontconfig.json"
746    part_name = "skia"
747    subsystem_name = "thirdparty"
748  }
749
750  optional("fontmgr_ohos") {
751    enabled = skia_enable_fontmgr_ohos
752
753    public = [
754      "src/ports/skia_ohos/FontConfig_ohos.h",
755      "src/ports/skia_ohos/FontInfo_ohos.h",
756      "src/ports/skia_ohos/SkFontMgr_ohos.h",
757      "src/ports/skia_ohos/SkFontStyleSet_ohos.h",
758      "src/ports/skia_ohos/SkTypeface_ohos.h",
759    ]
760    sources = [
761      "src/ports/skia_ohos/FontConfig_ohos.cpp",
762      "src/ports/skia_ohos/SkFontMgr_ohos.cpp",
763      "src/ports/skia_ohos/SkFontMgr_ohos_factory.cpp",
764      "src/ports/skia_ohos/SkFontStyleSet_ohos.cpp",
765      "src/ports/skia_ohos/SkTypeface_ohos.cpp",
766    ]
767
768    include_dirs = [
769      "//third_party/skia/include/private",
770      "//third_party/skia/include/core",
771      "//third_party/skia/src/core",
772      "//third_party/skia/src/ports",
773      "//third_party/skia/src/ports/skia_ohos",
774    ]
775
776    deps = [
777      ":fontmgr_symbol_load",
778      ":typeface_freetype",
779      "${skia_third_party_dir}/expat",
780      "//third_party/jsoncpp:jsoncpp_static",
781    ]
782    if (is_component_build) {
783      deps += [ "//third_party/bounds_checking_function:libsec_shared" ]
784    } else {
785      deps += [ "//third_party/bounds_checking_function:libsec_static" ]
786    }
787
788    deps += [ ":ohos_fontconfig.json" ]
789
790    if (graphic_2d_feature_wuji_enable) {
791      deps += [ "$ace_graphic_ext:ohos_fonts_wuji" ]
792    } else if (ace_engine_standard_fonts_enable) {
793      deps += [
794        "//base/global/system_resources:ohos_fonts",
795        "//third_party/noto-cjk:fonts_notocjk",
796        "//third_party/notofonts:fonts_notofonts",
797      ]
798    }
799
800    if (use_mingw_win) {
801      defines = [ "SK_BUILD_FONT_MGR_FOR_PREVIEW_WIN" ]
802    } else if (use_mac) {
803      defines = [ "SK_BUILD_FONT_MGR_FOR_PREVIEW_MAC" ]
804    } else if (use_linux) {
805      defines = [ "SK_BUILD_FONT_MGR_FOR_PREVIEW_LINUX" ]
806    } else if (is_ohos) {
807      deps += [ "//base/startup/init/interfaces/innerkits:libbegetutil" ]
808      defines = [ "SK_BUILD_FONT_MGR_FOR_OHOS" ]
809    }
810  }
811}
812
813optional("fontmgr_win_factory") {
814  enabled = skia_enable_fontmgr_win
815  deps = [ ":fontmgr_win" ]
816  sources = [ "src/ports/SkFontMgr_win_dw_factory.cpp" ]
817  defines = [ "SK_BUILD_FONT_MGR_FOR_PREVIEW_WIN" ]
818}
819
820optional("fontmgr_win_gdi") {
821  enabled = skia_enable_fontmgr_win_gdi
822
823  public = [ "include/ports/SkTypeface_win.h" ]
824  sources = [ "src/ports/SkFontHost_win.cpp" ]
825
826  # libs = [ "Gdi32.lib" ]
827  libs = [ "gdi32" ]
828}
829
830if (skia_lex) {
831  skia_executable("sksllex") {
832    sources = [
833      "src/sksl/lex/DFA.h",
834      "src/sksl/lex/DFAState.h",
835      "src/sksl/lex/LexUtil.h",
836      "src/sksl/lex/Main.cpp",
837      "src/sksl/lex/NFA.cpp",
838      "src/sksl/lex/NFA.h",
839      "src/sksl/lex/NFAState.h",
840      "src/sksl/lex/NFAtoDFA.h",
841      "src/sksl/lex/RegexNode.cpp",
842      "src/sksl/lex/RegexNode.h",
843      "src/sksl/lex/RegexParser.cpp",
844      "src/sksl/lex/RegexParser.h",
845      "src/sksl/lex/TransitionTable.cpp",
846      "src/sksl/lex/TransitionTable.h",
847    ]
848    include_dirs = [ "." ]
849  }
850
851  action("run_sksllex") {
852    script = "gn/run_sksllex.py"
853    deps = [ ":sksllex(//gn/toolchain:$host_toolchain)" ]
854    sources = [ "src/sksl/lex/sksl.lex" ]
855
856    # GN insists its outputs should go somewhere underneath target_out_dir, so we trick it with a
857    # path that starts with target_out_dir and then uses ".." to back up into the src dir.
858    outputs = [
859      "$target_out_dir/" + rebase_path("src/sksl/SkSLLexer.h", target_out_dir),
860      # the script also modifies the corresponding .cpp file, but if we tell GN that it gets
861      # confused due to the same file being named by two different paths
862    ]
863    sksllex_path = "$root_out_dir/"
864    sksllex_path += "sksllex"
865    if (host_os == "win") {
866      sksllex_path += ".exe"
867    }
868    args = [
869      rebase_path(sksllex_path),
870      rebase_path("bin/clang-format"),
871      rebase_path("bin/fetch-clang-format"),
872      rebase_path("src"),
873    ]
874  }
875} else {
876  group("run_sksllex") {
877  }
878}
879
880# `Compile SkSL Tests` relies on skslc.
881if (skia_compile_sksl_tests) {
882  skia_executable("skslc") {
883    defines = [
884      "SKSL_STANDALONE",
885      "SK_DISABLE_TRACING",
886      "SK_ENABLE_SPIRV_CROSS",
887      "SK_ENABLE_SPIRV_VALIDATION",
888    ]
889    sources = [
890      "src/core/SkArenaAlloc.cpp",
891      "src/core/SkBlockAllocator.cpp",
892      "src/core/SkCpu.cpp",
893      "src/core/SkData.cpp",
894      "src/core/SkHalf.cpp",
895      "src/core/SkMalloc.cpp",
896      "src/core/SkMath.cpp",
897      "src/core/SkMatrixInvert.cpp",
898      "src/core/SkSemaphore.cpp",
899      "src/core/SkStream.cpp",
900      "src/core/SkString.cpp",
901      "src/core/SkStringUtils.cpp",
902      "src/core/SkStringView.cpp",
903      "src/core/SkThreadID.cpp",
904      "src/core/SkUtils.cpp",
905      "src/core/SkVM.cpp",
906      "src/gpu/GrMemoryPool.cpp",
907      "src/gpu/GrShaderUtils.cpp",
908      "src/ports/SkMemory_malloc.cpp",
909      "src/ports/SkOSFile_stdio.cpp",
910      "src/sksl/SkSLMain.cpp",
911      "src/utils/SkJSON.cpp",
912      "src/utils/SkJSONWriter.cpp",
913      "src/utils/SkParse.cpp",
914      "src/utils/SkUTF.cpp",
915    ]
916    if (is_win) {
917      sources += [ "src/ports/SkOSFile_win.cpp" ]
918    } else {
919      sources += [ "src/ports/SkOSFile_posix.cpp" ]
920    }
921    sources += skia_sksl_sources
922    sources += skia_sksl_gpu_sources
923    include_dirs = [ "." ]
924    deps = [
925      ":run_sksllex",
926      "${skia_third_party_dir}/externals/spirv-tools:spvtools",
927      "${skia_third_party_dir}/externals/spirv-tools:spvtools_val",
928      "${skia_third_party_dir}/spirv-cross:spirv_cross",
929    ]
930  }
931
932  skslc_path = "$root_out_dir/"
933  if (host_toolchain != default_toolchain_name) {
934    skslc_path += "$host_toolchain/"
935  }
936  skslc_path += "skslc"
937  if (host_os == "win") {
938    skslc_path += ".exe"
939  }
940
941  copy("sksl_pre_includes") {
942    sources = [
943      "src/sksl/sksl_frag.sksl",
944      "src/sksl/sksl_gpu.sksl",
945      "src/sksl/sksl_public.sksl",
946      "src/sksl/sksl_rt_shader.sksl",
947      "src/sksl/sksl_vert.sksl",
948    ]
949    outputs = [ "$root_out_dir/{{source_file_part}}" ]
950  }
951
952  dehydrate_sksl_sources = get_target_outputs(":sksl_pre_includes")
953
954  dehydrate_sksl_outputs = []
955  foreach(src, dehydrate_sksl_sources) {
956    name = get_path_info(src, "name")
957
958    # GN insists its outputs should go somewhere underneath target_out_dir, so we trick it with a
959    # path that starts with target_out_dir and then uses ".." to back up into the src dir.
960    dehydrate_sksl_outputs += [ "$target_out_dir/" + rebase_path(
961                                    "src/sksl/generated/$name.dehydrated.sksl",
962                                    target_out_dir) ]
963  }
964
965  action("dehydrate_sksl") {
966    script = "gn/dehydrate_sksl.py"
967    deps = [
968      ":sksl_pre_includes",
969      ":skslc(//gn/toolchain:$host_toolchain)",
970    ]
971    sources = dehydrate_sksl_sources
972    outputs = dehydrate_sksl_outputs
973    args = [
974      rebase_path(skslc_path),
975      rebase_path("src/sksl/generated"),
976    ]
977    args += rebase_path(dehydrate_sksl_sources)
978  }
979} else {
980  group("dehydrate_sksl") {
981  }
982}
983
984if (skia_compile_sksl_tests) {
985  import("gn/sksl_tests.gni")
986
987  template("compile_sksl") {
988    # Compile the passed-in `sources` into `outputs` using skslc, with the given language/settings.
989    action("compile_sksl_${target_name}") {
990      script = "gn/compile_sksl_tests.py"
991      deps = [
992        ":sksl_pre_includes",
993        ":skslc(//gn/toolchain:$host_toolchain)",
994      ]
995      sources = []
996      outputs = []
997      response_file_contents = []
998      args = [
999        rebase_path(skslc_path),
1000        invoker.lang,
1001        invoker.settings,
1002        "{{response_file_name}}",
1003      ]
1004
1005      testsDir = get_path_info("tests", "abspath")
1006      resourcesDir = get_path_info("resources", "abspath")
1007
1008      foreach(partialPath, invoker.sources) {
1009        dst = testsDir + partialPath
1010        src = resourcesDir + partialPath
1011
1012        dir = get_path_info(dst, "dir")
1013
1014        # We want to support double-extensions (for '.dsl.cpp') but GN doesn't natively handle this.
1015        # Workaround: http://go/ggroup/a/chromium.org/g/gn-dev/c/RdEpjeYtb-4
1016        # For input path "file.aa.bb", name will contain "file" and ext will contain ".aa.bb".
1017        # For input path "file.cc", name will contain "file" and ext will contain ".cc".
1018        nameTmp = get_path_info(dst, "name")
1019        name = get_path_info(nameTmp, "name")
1020        ext = get_path_info(nameTmp, "extension")
1021        ext += get_path_info(dst, "extension")
1022        response_file_contents += rebase_path([
1023                                                src,
1024                                                dir,
1025                                              ])
1026        sources += [ src ]
1027
1028        foreach(outExtension, invoker.outExtensions) {
1029          # SPIR-V uses separate extensions for .vert shaders.
1030          if (ext == "vert" && outExtension == ".asm.frag") {
1031            outExtension = ".asm.vert"
1032          }
1033          outputs +=
1034              [ target_out_dir + "/" +
1035                rebase_path(dir + "/" + name + outExtension, target_out_dir) ]
1036        }
1037      }
1038    }
1039  }
1040  compile_sksl("glsl_tests") {
1041    sources = sksl_glsl_tests_sources + sksl_glsl_settings_tests_sources
1042    outExtensions = [ ".glsl" ]
1043    lang = "--glsl"
1044    settings = "--settings"
1045  }
1046  compile_sksl("glsl_nosettings_tests") {
1047    sources = sksl_glsl_settings_tests_sources
1048    outExtensions = [ "StandaloneSettings.glsl" ]
1049    lang = "--glsl"
1050    settings = "--nosettings"
1051  }
1052  compile_sksl("metal_tests") {
1053    sources = sksl_metal_tests_sources
1054    outExtensions = [ ".metal" ]
1055    lang = "--metal"
1056    settings = "--settings"
1057  }
1058  compile_sksl("skvm_tests") {
1059    sources = sksl_skvm_tests_sources
1060    outExtensions = [ ".skvm" ]
1061    lang = "--skvm"
1062    settings = "--settings"
1063  }
1064  compile_sksl("stage_tests") {
1065    sources = sksl_stage_tests_sources
1066    outExtensions = [ ".stage" ]
1067    lang = "--stage"
1068    settings = "--settings"
1069  }
1070  compile_sksl("spirv_tests") {
1071    sources = sksl_spirv_tests_sources
1072    outExtensions = [ ".asm.frag" ]
1073    lang = "--spirv"
1074    settings = "--settings"
1075  }
1076} else {
1077  group("compile_sksl_glsl_tests") {
1078  }
1079  group("compile_sksl_glsl_nosettings_tests") {
1080  }
1081  group("compile_sksl_metal_tests") {
1082  }
1083  group("compile_sksl_skvm_tests") {
1084  }
1085  group("compile_sksl_spirv_tests") {
1086  }
1087}
1088
1089optional("gpu_shared") {
1090  enabled = skia_enable_gpu || skia_enable_graphite
1091
1092  sources = skia_shared_gpu_sources
1093}
1094
1095optional("gpu") {
1096  enabled = skia_enable_gpu
1097  deps = [
1098    ":compile_sksl_glsl_nosettings_tests",
1099    ":compile_sksl_glsl_tests",
1100    ":compile_sksl_metal_tests",
1101    ":compile_sksl_skvm_tests",
1102    ":compile_sksl_spirv_tests",
1103    ":dehydrate_sksl",
1104    ":gpu_shared",
1105    ":run_sksllex",
1106  ]
1107  if (skia_generate_workarounds) {
1108    deps += [ ":workaround_list" ]
1109  }
1110  public_defines = []
1111  public_configs = []
1112  public_deps = []
1113
1114  sources = skia_gpu_sources + skia_sksl_gpu_sources
1115  if (!skia_enable_skgpu_v1) {
1116    sources -= skia_skgpu_v1_sources
1117  }
1118
1119  libs = []
1120  frameworks = []
1121
1122  if (skia_use_gl) {
1123    public_defines += [ "SK_GL" ]
1124    if (is_android) {
1125      sources += [
1126        "src/gpu/gl/egl/GrGLMakeEGLInterface.cpp",
1127        "src/gpu/gl/egl/GrGLMakeNativeInterface_egl.cpp",
1128      ]
1129
1130      # this lib is required to link against AHardwareBuffer
1131      libs += [ "android" ]
1132    } else if (skia_use_egl || is_ohos) {
1133      sources += [
1134        "src/gpu/gl/egl/GrGLMakeEGLInterface.cpp",
1135        "src/gpu/gl/egl/GrGLMakeNativeInterface_egl.cpp",
1136      ]
1137      if (use_oh_skia) {
1138        include_dirs = [
1139          "//third_party/EGL/api",
1140          "//third_party/openGLES/api",
1141        ]
1142        deps += [ "//foundation/graphic/graphic_2d:libgl" ]
1143      } else {
1144        libs += [ "EGL" ]
1145      }
1146    } else if (skia_use_webgl) {
1147      sources += [ "src/gpu/gl/webgl/GrGLMakeNativeInterface_webgl.cpp" ]
1148    } else if (is_linux && skia_use_x11) {
1149      sources += [
1150        "src/gpu/gl/glx/GrGLMakeGLXInterface.cpp",
1151        "src/gpu/gl/glx/GrGLMakeNativeInterface_glx.cpp",
1152      ]
1153      libs += [ "GL" ]
1154    } else if (is_mac) {
1155      sources += [ "src/gpu/gl/mac/GrGLMakeNativeInterface_mac.cpp" ]
1156    } else if (is_ios) {
1157      sources += [ "src/gpu/gl/iOS/GrGLMakeNativeInterface_iOS.cpp" ]
1158    } else if (is_win && !skia_enable_winuwp) {
1159      sources += [ "src/gpu/gl/win/GrGLMakeNativeInterface_win.cpp" ]
1160      libs += [ "opengl32" ]
1161    } else {
1162      sources += [ "src/gpu/gl/GrGLMakeNativeInterface_none.cpp" ]
1163    }
1164    sources += skia_gl_gpu_sources
1165  }
1166
1167  if (skia_use_vulkan) {
1168    public_defines += [ "SK_VULKAN" ]
1169    if (skia_use_vma) {
1170      deps += [ "third_party/vulkanmemoryallocator" ]
1171    }
1172    public_deps += [ "//third_party/vulkan-headers:vulkan_headers" ]
1173    sources += skia_vk_sources
1174    if (skia_enable_vulkan_debug_layers) {
1175      public_defines += [ "SK_ENABLE_VK_LAYERS" ]
1176    }
1177    if (is_fuchsia) {
1178      if (using_fuchsia_sdk) {
1179        public_deps += [ "$fuchsia_sdk_root/pkg:vulkan" ]
1180      } else {
1181        public_deps += [ "${skia_root_dir}/src/graphics/lib/vulkan" ]
1182      }
1183    }
1184    if (skia_vk_enable_partialrender) {
1185      public_defines += [ "SK_VK_PARTIALRENDER" ]
1186    }
1187  }
1188
1189  if (is_android && (skia_use_gl || skia_use_vulkan)) {
1190    # this lib is required to link against AHardwareBuffer
1191    if (defined(ndk_api) && ndk_api >= 26) {
1192      libs += [ "android" ]
1193    }
1194  }
1195
1196  if (skia_use_dawn) {
1197    public_defines += [ "SK_DAWN" ]
1198    sources += skia_dawn_sources
1199    public_deps +=
1200        [ "${skia_third_party_dir}/externals/dawn/src/dawn:dawn_headers" ]
1201    deps += [
1202      "${skia_third_party_dir}/externals/dawn/src/dawn:dawn_proc",
1203      "${skia_third_party_dir}/externals/dawn/src/dawn:dawncpp",
1204    ]
1205    if (dawn_enable_d3d12 || dawn_enable_desktop_gl || dawn_enable_metal ||
1206        dawn_enable_opengles || dawn_enable_vulkan) {
1207      deps += [ "${skia_third_party_dir}/externals/dawn/src/dawn_native" ]
1208    }
1209    if (dawn_enable_d3d12) {
1210      libs += [
1211        "d3d12.lib",
1212        "dxgi.lib",
1213        "d3dcompiler.lib",
1214      ]
1215    } else if (dawn_enable_metal) {
1216      frameworks += [ "Metal.framework" ]
1217    }
1218  }
1219
1220  if (skia_use_direct3d) {
1221    public_defines += [
1222      "SK_DIRECT3D",
1223      "SK_ENABLE_SPIRV_CROSS",
1224    ]
1225    deps += [
1226      "${skia_third_party_dir}/d3d12allocator",
1227      "${skia_third_party_dir}/spirv-cross:spirv_cross",
1228    ]
1229    sources += skia_direct3d_sources
1230    if (skia_enable_direct3d_debug_layer) {
1231      public_defines += [ "SK_ENABLE_D3D_DEBUG_LAYER" ]
1232    }
1233    libs += [
1234      "d3d12.lib",
1235      "dxgi.lib",
1236      "d3dcompiler.lib",
1237    ]
1238  }
1239
1240  cflags_objcc = []
1241  if (skia_use_metal) {
1242    public_defines += [ "SK_METAL" ]
1243    sources += skia_metal_sources
1244    if (skia_enable_metal_debug_info) {
1245      public_defines += [ "SK_ENABLE_MTL_DEBUG_INFO" ]
1246    }
1247    frameworks += [ "Metal.framework" ]
1248    frameworks += [ "Foundation.framework" ]
1249    if (is_ios) {
1250      frameworks += [ "UIKit.framework" ]
1251    }
1252    cflags_objcc += [ "-fobjc-arc" ]
1253  }
1254
1255  if (is_debug) {
1256    public_defines += [ "SK_ENABLE_DUMP_GPU" ]
1257  }
1258}
1259
1260optional("gif") {
1261  enabled = !skia_use_wuffs && skia_use_libgifcodec
1262  _libgifcodec_gni_path = "third_party/externals/libgifcodec/libgifcodec.gni"
1263  if ("True" ==
1264      exec_script("gn/checkpath.py",
1265                  [ rebase_path(_libgifcodec_gni_path, root_build_dir) ],
1266                  "trim string")) {
1267    public_defines = [ "SK_USE_LIBGIFCODEC" ]
1268    public_include_dirs = [
1269      ".",
1270      skia_libgifcodec_path,
1271    ]
1272    include_dirs = public_include_dirs
1273    import(_libgifcodec_gni_path)
1274    sources = rebase_path(libgifcodec_sources + libgifcodec_public,
1275                          ".",
1276                          skia_libgifcodec_path)
1277  }
1278}
1279
1280optional("heif") {
1281  enabled = skia_use_libheif
1282  public_defines = [ "SK_HAS_HEIF_LIBRARY" ]
1283
1284  # This HEIF decoding functionality is a part of the Android Framework.
1285  # https://android.googlesource.com/platform/frameworks/av/+/master/media/libheif/include/HeifDecoderAPI.h
1286  # There isn't a way to compile that library outside of it, so we just link against
1287  # the library. This feature is not supported on other platforms (and we haven't
1288  # yet tried something like https://github.com/strukturag/libheif/tree/master/libheif).
1289  # The dependency for Android is set in gn_to_bp.py.
1290  deps = []
1291
1292  sources = [ "src/codec/SkHeifCodec.cpp" ]
1293}
1294
1295optional("jpeg_decode") {
1296  enabled = skia_use_libjpeg_turbo_decode
1297  public_defines = [ "SK_CODEC_DECODES_JPEG" ]
1298
1299  deps = [ "${skia_third_party_dir}/libjpeg-turbo:libjpeg" ]
1300  sources = [
1301    "src/codec/SkJpegCodec.cpp",
1302    "src/codec/SkJpegDecoderMgr.cpp",
1303    "src/codec/SkJpegUtility.cpp",
1304  ]
1305}
1306
1307optional("jpeg_encode") {
1308  enabled = skia_use_libjpeg_turbo_encode
1309  public_defines = [ "SK_ENCODE_JPEG" ]
1310
1311  deps = [ "${skia_third_party_dir}/libjpeg-turbo:libjpeg" ]
1312  public = [ "include/encode/SkJpegEncoder.h" ]
1313  sources = [
1314    "src/images/SkJPEGWriteUtility.cpp",
1315    "src/images/SkJpegEncoder.cpp",
1316  ]
1317}
1318
1319optional("ndk_images") {
1320  enabled = skia_use_ndk_images
1321  public_defines = [ "SK_ENABLE_NDK_IMAGES" ]
1322  sources = [
1323    "src/ports/SkImageEncoder_NDK.cpp",
1324    "src/ports/SkImageGeneratorNDK.cpp",
1325    "src/ports/SkNDKConversions.cpp",
1326  ]
1327  libs = [ "jnigraphics" ]
1328}
1329
1330optional("graphite") {
1331  libs = []
1332  frameworks = []
1333
1334  enabled = skia_enable_graphite
1335  deps = [ ":gpu_shared" ]
1336  public_defines = [ "SK_GRAPHITE_ENABLED" ]
1337  public = skia_graphite_public
1338  sources = skia_graphite_sources
1339  if (skia_use_metal) {
1340    public_defines += [ "SK_METAL" ]
1341    sources += skia_graphite_mtl_sources
1342    if (skia_enable_metal_debug_info) {
1343      public_defines += [ "SK_ENABLE_MTL_DEBUG_INFO" ]
1344    }
1345    frameworks += [ "Metal.framework" ]
1346    frameworks += [ "Foundation.framework" ]
1347  }
1348}
1349
1350optional("pdf") {
1351  enabled = skia_use_zlib && skia_enable_pdf
1352  public_defines = [ "SK_SUPPORT_PDF" ]
1353
1354  if (use_oh_skia) {
1355    deps = [ "//third_party/zlib:libz" ]
1356  } else {
1357    deps = [ "${skia_third_party_dir}/zlib" ]
1358  }
1359  if (skia_use_libjpeg_turbo_decode) {
1360    deps += [ ":jpeg_decode" ]
1361  }
1362  if (skia_use_libjpeg_turbo_encode) {
1363    deps += [ ":jpeg_encode" ]
1364  }
1365  public = skia_pdf_public
1366  sources = skia_pdf_sources
1367  sources_when_disabled = [ "src/pdf/SkDocument_PDF_None.cpp" ]
1368  if (skia_use_icu && skia_use_harfbuzz && skia_pdf_subset_harfbuzz) {
1369    deps += [ "${skia_third_party_dir}/harfbuzz" ]
1370    defines = [ "SK_PDF_USE_HARFBUZZ_SUBSET" ]
1371  } else if (skia_use_icu && skia_use_sfntly) {
1372    deps += [ "${skia_third_party_dir}/sfntly" ]
1373    defines = [ "SK_PDF_USE_SFNTLY" ]
1374  }
1375}
1376
1377optional("xps") {
1378  enabled = skia_use_xps && is_win && !is_mingw
1379  public_defines = [ "SK_SUPPORT_XPS" ]
1380  public = skia_xps_public
1381  sources = skia_xps_sources
1382}
1383
1384optional("png_decode") {
1385  enabled = skia_use_libpng_decode
1386  public_defines = [ "SK_CODEC_DECODES_PNG" ]
1387
1388  deps = [ "${skia_third_party_dir}/libpng" ]
1389  sources = [
1390    "src/codec/SkIcoCodec.cpp",
1391    "src/codec/SkPngCodec.cpp",
1392  ]
1393
1394  defines = [ "ICO_CODEC_HW_HIGH_QUALITY_DECODE" ]
1395}
1396
1397optional("png_encode") {
1398  enabled = skia_use_libpng_encode
1399  public_defines = [ "SK_ENCODE_PNG" ]
1400
1401  deps = [ "${skia_third_party_dir}/libpng" ]
1402  sources = [ "src/images/SkPngEncoder.cpp" ]
1403}
1404
1405optional("raw") {
1406  enabled = skia_use_dng_sdk && skia_use_libjpeg_turbo_decode && skia_use_piex
1407  public_defines = [ "SK_CODEC_DECODES_RAW" ]
1408
1409  deps = [
1410    "${skia_third_party_dir}/dng_sdk",
1411    "${skia_third_party_dir}/libjpeg-turbo:libjpeg",
1412    "${skia_third_party_dir}/piex",
1413  ]
1414
1415  # SkRawCodec catches any exceptions thrown by dng_sdk, insulating the rest of
1416  # Skia.
1417  configs = [ "gn/portable:add_exceptions" ]
1418
1419  sources = [ "src/codec/SkRawCodec.cpp" ]
1420}
1421
1422import("third_party/skcms/skcms.gni")
1423skia_source_set("skcms") {
1424  cflags = []
1425  if (!is_win || is_clang) {
1426    cflags += [
1427      "-w",
1428      "-std=c++11",
1429    ]
1430  }
1431
1432  public = [ "include/third_party/skcms/skcms.h" ]
1433  include_dirs = [ "include/third_party/skcms" ]
1434  sources = rebase_path(skcms_sources, ".", "third_party/skcms")
1435}
1436
1437optional("typeface_freetype") {
1438  if (use_oh_skia) {
1439    enabled = skia_use_freetype2
1440  } else {
1441    enabled = skia_use_freetype
1442  }
1443
1444  deps = [ "${skia_third_party_dir}/freetype2" ]
1445  sources = [
1446    "src/ports/SkFontHost_FreeType.cpp",
1447    "src/ports/SkFontHost_FreeType_common.cpp",
1448    "src/ports/SkFontHost_FreeType_common.h",
1449  ]
1450}
1451
1452optional("webp_decode") {
1453  enabled = skia_use_libwebp_decode
1454  public_defines = [ "SK_CODEC_DECODES_WEBP" ]
1455
1456  deps = [ "${skia_third_party_dir}/libwebp" ]
1457  sources = [ "src/codec/SkWebpCodec.cpp" ]
1458}
1459
1460optional("webp_encode") {
1461  enabled = skia_use_libwebp_encode
1462  public_defines = [ "SK_ENCODE_WEBP" ]
1463
1464  deps = [ "${skia_third_party_dir}/libwebp" ]
1465  sources = [ "src/images/SkWebpEncoder.cpp" ]
1466}
1467
1468optional("wuffs") {
1469  enabled = skia_use_wuffs
1470  public_defines = [ "SK_HAS_WUFFS_LIBRARY" ]
1471
1472  deps = [ "${skia_third_party_dir}/wuffs" ]
1473  sources = [ "src/codec/SkWuffsCodec.cpp" ]
1474}
1475
1476optional("xml") {
1477  enabled = skia_use_expat
1478  public_defines = [ "SK_XML" ]
1479
1480  deps = [ "${skia_third_party_dir}/expat" ]
1481  sources = [
1482    "src/svg/SkSVGCanvas.cpp",
1483    "src/svg/SkSVGDevice.cpp",
1484    "src/xml/SkDOM.cpp",
1485    "src/xml/SkDOMParser.cpp",
1486    "src/xml/SkXMLParser.cpp",
1487    "src/xml/SkXMLWriter.cpp",
1488  ]
1489}
1490
1491optional("skvm_jit") {
1492  enabled = skia_enable_skvm_jit_when_possible
1493  public_defines = [ "SKVM_JIT_WHEN_POSSIBLE" ]
1494  if (skia_vtune_path != "") {
1495    public_defines += [ "SKVM_JIT_VTUNE" ]
1496    public_include_dirs = [ "$skia_vtune_path/include" ]
1497    libs = [ "$skia_vtune_path/lib64/jitprofiling.lib" ]
1498  }
1499}
1500
1501if (skia_enable_gpu && skia_generate_workarounds) {
1502  action("workaround_list") {
1503    script = "tools/build_workaround_header.py"
1504
1505    inputs = [ "src/gpu/gpu_workaround_list.txt" ]
1506
1507    # GN insists its outputs should go somewhere underneath root_out_dir, so we trick it with a
1508    # path that starts with root_out_dir and then uses ".." to back up into the src dir.
1509    output_file =
1510        rebase_path("include/gpu/GrDriverBugWorkaroundsAutogen.h", root_out_dir)
1511
1512    outputs = [ "$root_out_dir/$output_file" ]
1513    args = [
1514      "--output-file",
1515      "$output_file",
1516    ]
1517
1518    foreach(file, inputs) {
1519      args += [ rebase_path(file, root_build_dir) ]
1520    }
1521  }
1522}
1523
1524skia_component("skia") {
1525}
1526
1527if (use_oh_skia) {
1528  config("skia_config") {
1529    include_dirs = [ "//third_party/skia" ]
1530
1531    defines = skia_common_defines
1532  }
1533
1534  config("harfbuzz_config") {
1535    include_dirs = [ "//third_party/skia/third_party/externals/harfbuzz/src" ]
1536
1537    defines = [
1538      "HAVE_ICU",
1539      "HAVE_ICU_BUILTIN",
1540      "HAVE_OT",
1541      "HAVE_CONFIG_OVERRIDE_H",
1542      "HB_NO_FALLBACK_SHAPE",
1543      "HB_NO_WIN1256",
1544    ]
1545  }
1546
1547  config("icu_config") {
1548    include_dirs = [ "${skia_third_party_dir}/externals/icu/source/common" ]
1549    if (is_arkui_x) {
1550      include_dirs = []
1551      include_dirs = [ "//third_party/icu/icu4c/source/common" ]
1552    }
1553  }
1554
1555  template("make_skia_deps") {
1556    forward_variables_from(invoker, "*")
1557    ohos_source_set("skia_$platform") {
1558      part_name = "skia"
1559      subsystem_name = "thirdparty"
1560      license_file = "//third_party/skia/LICENSE"
1561      public_configs = [
1562        ":skia_config",
1563        ":harfbuzz_config",
1564        ":icu_config",
1565      ]
1566
1567      if (is_arkui_x) {
1568        public_deps = [ ":skia_canvaskit_static" ]
1569      } else {
1570        public_deps = [ ":skia_canvaskit" ]
1571      }
1572    }
1573  }
1574
1575  ohos_source_set("skia_canvaskit_static") {
1576    part_name = "skia"
1577    subsystem_name = "thirdparty"
1578
1579    include_dirs = [ "${skia_third_party_dir}/externals/libgifcodec" ]
1580    public_configs = [ ":skia_public" ]
1581    configs = skia_library_configs
1582    public_deps = [
1583      ":fontmgr_FontConfigInterface",
1584      ":fontmgr_android",
1585      ":fontmgr_custom_directory",
1586      ":fontmgr_custom_directory_factory",
1587      ":fontmgr_custom_embedded",
1588      ":fontmgr_fontconfig",
1589      ":skcms",
1590      ":xps",
1591    ]
1592
1593    if (is_ios) {
1594      public_deps += [ ":gpu" ]
1595    } else {
1596      if (defined(ace_enable_gpu) && ace_enable_gpu) {
1597        public_deps += [ ":gpu" ]
1598      }
1599    }
1600    deps = [
1601      ":android_utils",
1602      ":arm64",
1603      ":armv7",
1604      ":avx",
1605      ":crc32",
1606      ":fontmgr_factory",
1607      ":gif",
1608      ":heif",
1609      ":hsw",
1610      ":jpeg_decode",
1611      ":jpeg_encode",
1612      ":none",
1613      ":png_decode",
1614      ":png_encode",
1615      ":raw",
1616      ":skvm_jit",
1617      ":skx",
1618      ":sse2",
1619      ":sse41",
1620      ":sse42",
1621      ":ssse3",
1622      ":webp_decode",
1623      ":webp_encode",
1624      ":xml",
1625      "modules/skresources",
1626      "modules/skshaper",
1627      "modules/skunicode",
1628      "modules/svg",
1629    ]
1630
1631    public = skia_core_public
1632    public += skia_utils_public
1633    public += skia_effects_public
1634    public += skia_effects_imagefilter_public
1635
1636    sources = []
1637    sources += skia_core_sources
1638    sources += skia_utils_sources
1639    sources += skia_effects_sources
1640    sources += skia_effects_imagefilter_sources
1641    sources += [
1642      "src/android/SkAndroidFrameworkUtils.cpp",
1643      "src/android/SkAnimatedImage.cpp",
1644      "src/codec/SkAndroidCodec.cpp",
1645      "src/codec/SkAndroidCodecAdapter.cpp",
1646      "src/codec/SkBmpBaseCodec.cpp",
1647      "src/codec/SkBmpCodec.cpp",
1648      "src/codec/SkBmpMaskCodec.cpp",
1649      "src/codec/SkBmpRLECodec.cpp",
1650      "src/codec/SkBmpStandardCodec.cpp",
1651      "src/codec/SkCodec.cpp",
1652      "src/codec/SkCodecImageGenerator.cpp",
1653      "src/codec/SkColorTable.cpp",
1654      "src/codec/SkEncodedInfo.cpp",
1655      "src/codec/SkMaskSwizzler.cpp",
1656      "src/codec/SkMasks.cpp",
1657      "src/codec/SkParseEncodedOrigin.cpp",
1658      "src/codec/SkSampledCodec.cpp",
1659      "src/codec/SkSampler.cpp",
1660      "src/codec/SkStreamBuffer.cpp",
1661      "src/codec/SkSwizzler.cpp",
1662      "src/codec/SkWbmpCodec.cpp",
1663      "src/images/SkImageEncoder.cpp",
1664      "src/ports/SkDiscardableMemory_none.cpp",
1665      "src/ports/SkGlobalInitialization_default.cpp",
1666      "src/ports/SkImageGenerator_skia.cpp",
1667      "src/ports/SkMemory_malloc.cpp",
1668      "src/ports/SkOSFile_stdio.cpp",
1669      "src/sfnt/SkOTTable_name.cpp",
1670      "src/sfnt/SkOTUtils.cpp",
1671    ]
1672
1673    defines = skia_common_defines
1674    cflags = skia_common_cflags
1675    if (!defined(ace_enable_gpu) || !ace_enable_gpu) {
1676      defines += [
1677        "SK_BUILD_FOR_UNIX",
1678        "SK_SUPPORT_GPU=0",
1679      ]
1680      defines -= [ "SK_GL" ]
1681    }
1682    cflags_cc = [ "-Wno-unknown-pragmas" ]
1683    libs = []
1684
1685    if (skia_enable_sksl) {
1686      deps += [ ":dehydrate_sksl" ]
1687      sources += skia_sksl_sources
1688    }
1689
1690    if (is_android) {
1691      deps += [ "${skia_third_party_dir}/expat" ]
1692      if (defined(ndk) && ndk != "") {
1693        deps += [ "${skia_third_party_dir}/cpu-features" ]
1694      }
1695      sources += [ "src/ports/SkDebug_android.cpp" ]
1696      libs += [
1697        "EGL",
1698        "GLESv2",
1699        "log",
1700      ]
1701    }
1702
1703    if (is_mac) {
1704      public += [ "include/ports/SkCFObject.h" ]
1705      sources += [
1706        "src/ports/SkDebug_stdio.cpp",
1707        "src/ports/SkImageEncoder_CG.cpp",
1708        "src/ports/SkImageGeneratorCG.cpp",
1709      ]
1710      frameworks = [
1711        "ApplicationServices.framework",
1712        "OpenGL.framework",
1713      ]
1714    }
1715
1716    if (is_ios) {
1717      public += [ "include/ports/SkCFObject.h" ]
1718      sources += [
1719        "src/ports/SkDebug_stdio.cpp",
1720        "src/ports/SkImageEncoder_CG.cpp",
1721        "src/ports/SkImageGeneratorCG.cpp",
1722      ]
1723      frameworks = [
1724        "CoreFoundation.framework",
1725        "ImageIO.framework",
1726        "MobileCoreServices.framework",
1727      ]
1728    }
1729
1730    if (is_win) {
1731      sources += [ "src/ports/SkOSFile_win.cpp" ]
1732    } else {
1733      sources += [ "src/ports/SkOSFile_posix.cpp" ]
1734    }
1735
1736    if (skia_include_multiframe_procs) {
1737      sources += [ "tools/SkSharingProc.cpp" ]
1738    }
1739  }
1740
1741  config("skia_canvaskit_link_config") {
1742    if (is_ohos && is_clang && (target_cpu == "arm" || target_cpu == "arm64")) {
1743      ldflags = [
1744        "-Wl,--lto-O2",
1745        "-Wl,-mllvm",
1746        "-Wl,-wholeprogramdevirt-check=fallback",
1747        "-Wl,-Bsymbolic",
1748      ]
1749    }
1750  }
1751
1752  ohos_shared_library("skia_canvaskit") {
1753    part_name = "skia"
1754    innerapi_tags = [ "platformsdk" ]
1755    subsystem_name = "thirdparty"
1756
1757    include_dirs = [ "${skia_third_party_dir}/externals/libgifcodec" ]
1758    public_configs = [ ":skia_public" ]
1759    configs = skia_library_configs
1760    if (enhanced_opt) {
1761      configs += [ ":skia_canvaskit_link_config" ]
1762    }
1763    public_deps = [
1764      ":fontmgr_FontConfigInterface",
1765      ":fontmgr_android",
1766      ":fontmgr_custom_directory",
1767      ":fontmgr_custom_directory_factory",
1768      ":fontmgr_custom_embedded",
1769      ":fontmgr_fontconfig",
1770      ":fontmgr_mac_ct",
1771      ":fontmgr_ohos",
1772      ":fontmgr_win",
1773      ":fontmgr_win_gdi",
1774      ":pdf",
1775      ":skcms",
1776      ":xps",
1777    ]
1778
1779    if (is_arkui_x) {
1780      public_deps -= [ ":fontmgr_ohos" ]
1781    }
1782
1783    if (is_ios) {
1784      public_deps += [ ":gpu" ]
1785    } else {
1786      if (defined(ace_enable_gpu) && ace_enable_gpu) {
1787        public_deps += [ ":gpu" ]
1788      }
1789    }
1790    deps = [
1791      ":android_utils",
1792      ":arm64",
1793      ":armv7",
1794      ":avx",
1795      ":crc32",
1796      ":fontmgr_factory",
1797      ":gif",
1798      ":heif",
1799      ":hsw",
1800      ":jpeg_decode",
1801      ":jpeg_encode",
1802      ":none",
1803      ":png_decode",
1804      ":png_encode",
1805      ":raw",
1806      ":skvm_jit",
1807      ":skx",
1808      ":sse2",
1809      ":sse41",
1810      ":sse42",
1811      ":ssse3",
1812      ":webp_decode",
1813      ":webp_encode",
1814      ":xml",
1815      "modules/skresources",
1816      "modules/skshaper",
1817      "modules/skunicode",
1818      "modules/svg",
1819    ]
1820
1821    public = skia_core_public
1822    public += skia_utils_public
1823    public += skia_effects_public
1824    public += skia_effects_imagefilter_public
1825
1826    sources = []
1827    sources += skia_core_sources
1828    sources += skia_utils_sources
1829    sources += skia_effects_sources
1830    sources += skia_effects_imagefilter_sources
1831    sources += [
1832      "src/android/SkAndroidFrameworkUtils.cpp",
1833      "src/android/SkAnimatedImage.cpp",
1834      "src/codec/SkAndroidCodec.cpp",
1835      "src/codec/SkAndroidCodecAdapter.cpp",
1836      "src/codec/SkBmpBaseCodec.cpp",
1837      "src/codec/SkBmpCodec.cpp",
1838      "src/codec/SkBmpMaskCodec.cpp",
1839      "src/codec/SkBmpRLECodec.cpp",
1840      "src/codec/SkBmpStandardCodec.cpp",
1841      "src/codec/SkCodec.cpp",
1842      "src/codec/SkCodecImageGenerator.cpp",
1843      "src/codec/SkColorTable.cpp",
1844      "src/codec/SkEncodedInfo.cpp",
1845      "src/codec/SkMaskSwizzler.cpp",
1846      "src/codec/SkMasks.cpp",
1847      "src/codec/SkParseEncodedOrigin.cpp",
1848      "src/codec/SkSampledCodec.cpp",
1849      "src/codec/SkSampler.cpp",
1850      "src/codec/SkStreamBuffer.cpp",
1851      "src/codec/SkSwizzler.cpp",
1852      "src/codec/SkWbmpCodec.cpp",
1853      "src/images/SkImageEncoder.cpp",
1854      "src/ports/SkDiscardableMemory_none.cpp",
1855      "src/ports/SkGlobalInitialization_default.cpp",
1856      "src/ports/SkImageGenerator_skia.cpp",
1857      "src/ports/SkMemory_malloc.cpp",
1858      "src/ports/SkOSFile_stdio.cpp",
1859      "src/sfnt/SkOTTable_name.cpp",
1860      "src/sfnt/SkOTUtils.cpp",
1861    ]
1862
1863    defines = skia_common_defines
1864    cflags = skia_common_cflags
1865    if (!defined(ace_enable_gpu) || !ace_enable_gpu) {
1866      defines += [
1867        "SK_BUILD_FOR_UNIX",
1868        "SK_SUPPORT_GPU=0",
1869      ]
1870      defines -= [ "SK_GL" ]
1871    }
1872    cflags_cc = [ "-Wno-unknown-pragmas" ]
1873    libs = []
1874
1875    if (skia_enable_sksl) {
1876      deps += [ ":dehydrate_sksl" ]
1877      sources += skia_sksl_sources
1878    }
1879
1880    if (is_win) {
1881      sources += [
1882        "src/ports/SkDebug_win.cpp",
1883        "src/ports/SkImageEncoder_WIC.cpp",
1884        "src/ports/SkImageGeneratorWIC.cpp",
1885        "src/ports/SkOSFile_win.cpp",
1886        "src/ports/SkOSLibrary_win.cpp",
1887      ]
1888      libs += [
1889        # "Ole32.lib",
1890        # "OleAut32.lib",
1891      ]
1892
1893      if (!skia_enable_winuwp) {
1894        libs += [
1895          # "FontSub.lib",
1896          # "User32.lib",
1897          # "Usp10.lib",
1898        ]
1899      }
1900      libs += [
1901        "kernel32",
1902        "gdi32",
1903        "fontsub",
1904        "ole32",
1905        "oleaut32",
1906        "psapi",
1907        "user32",
1908        "usp10",
1909        "uuid",
1910        "windowscodecs",
1911      ]
1912    } else {
1913      sources += [
1914        "src/ports/SkOSFile_posix.cpp",
1915        "src/ports/SkOSLibrary_posix.cpp",
1916      ]
1917      libs += [ "dl" ]
1918    }
1919    if (is_ohos) {
1920      sources += [ "//third_party/skia/src/ports/SkDebug_ohos.cpp" ]
1921      external_deps = [
1922        "hilog:libhilog",
1923        "hitrace:hitrace_meter",
1924      ]
1925    }
1926
1927    if (is_android) {
1928      deps += [ "${skia_third_party_dir}/expat" ]
1929      if (defined(ndk) && ndk != "") {
1930        deps += [ "${skia_third_party_dir}/cpu-features" ]
1931      }
1932      sources += [ "src/ports/SkDebug_android.cpp" ]
1933      libs += [
1934        "EGL",
1935        "GLESv2",
1936        "log",
1937      ]
1938    }
1939
1940    if (is_linux || target_cpu == "wasm") {
1941      sources += [ "src/ports/SkDebug_stdio.cpp" ]
1942      if (skia_use_egl) {
1943        libs += [ "GLESv2" ]
1944      }
1945    }
1946
1947    if (is_mac) {
1948      public += [ "include/ports/SkCFObject.h" ]
1949      sources += [
1950        "src/ports/SkDebug_stdio.cpp",
1951        "src/ports/SkImageEncoder_CG.cpp",
1952        "src/ports/SkImageGeneratorCG.cpp",
1953      ]
1954      frameworks = [
1955        "ApplicationServices.framework",
1956        "OpenGL.framework",
1957      ]
1958    }
1959
1960    if (is_ios) {
1961      public += [ "include/ports/SkCFObject.h" ]
1962      sources += [
1963        "src/ports/SkDebug_stdio.cpp",
1964        "src/ports/SkImageEncoder_CG.cpp",
1965        "src/ports/SkImageGeneratorCG.cpp",
1966      ]
1967      frameworks = [
1968        "CoreFoundation.framework",
1969        "ImageIO.framework",
1970        "MobileCoreServices.framework",
1971      ]
1972    }
1973
1974    if (is_fuchsia) {
1975      sources += [ "src/ports/SkDebug_stdio.cpp" ]
1976    }
1977
1978    #if (skia_enable_spirv_validation) {
1979    #  deps += [ "${skia_third_party_dir}/externals/spirv-tools:spvtools_val" ]
1980    #  defines += [ "SK_ENABLE_SPIRV_VALIDATION" ]
1981    #}
1982
1983    if (skia_include_multiframe_procs) {
1984      sources += [ "tools/SkSharingProc.cpp" ]
1985    }
1986
1987    if (defined(ddgr_ext_configs)) {
1988      defines += ddgr_ext_configs.ddgr_defines
1989    }
1990  }
1991
1992  foreach(item, ace_platforms) {
1993    make_skia_deps(item.name) {
1994      platform = item.name
1995      config = {
1996      }
1997
1998      if (defined(item.config)) {
1999        config = item.config
2000      }
2001    }
2002  }
2003}
2004
2005# DebugCanvas used in experimental/wasm-skp-debugger
2006if (target_cpu == "wasm") {
2007  skia_static_library("debugcanvas") {
2008    public_configs = [ ":skia_public" ]
2009
2010    sources = [
2011      "tools/SkSharingProc.cpp",
2012      "tools/UrlDataManager.cpp",
2013      "tools/debugger/DebugCanvas.cpp",
2014      "tools/debugger/DebugLayerManager.cpp",
2015      "tools/debugger/DrawCommand.cpp",
2016      "tools/debugger/JsonWriteBuffer.cpp",
2017    ]
2018  }
2019}
2020
2021skia_static_library("pathkit") {
2022  check_includes = false
2023  public_configs = [ ":skia_public" ]
2024  configs = skia_library_configs
2025
2026  deps = [
2027    ":arm64",
2028    ":armv7",
2029    ":avx",
2030    ":crc32",
2031    ":hsw",
2032    ":none",
2033    ":sse2",
2034    ":sse41",
2035    ":sse42",
2036    ":ssse3",
2037  ]
2038
2039  sources = []
2040  sources += skia_pathops_sources
2041  sources += skia_pathops_public
2042  sources += [
2043    "src/core/SkAnalyticEdge.cpp",
2044    "src/core/SkArenaAlloc.cpp",
2045    "src/core/SkContourMeasure.cpp",
2046    "src/core/SkCubicMap.cpp",
2047    "src/core/SkEdge.cpp",
2048    "src/core/SkEdgeBuilder.cpp",
2049    "src/core/SkEdgeClipper.cpp",
2050    "src/core/SkGeometry.cpp",
2051    "src/core/SkIDChangeListener.cpp",
2052    "src/core/SkLineClipper.cpp",
2053    "src/core/SkMalloc.cpp",
2054    "src/core/SkMallocPixelRef.cpp",
2055    "src/core/SkMath.cpp",
2056    "src/core/SkMatrix.cpp",
2057    "src/core/SkOpts.cpp",
2058    "src/core/SkPaint.cpp",
2059    "src/core/SkPaintPriv.cpp",
2060    "src/core/SkPath.cpp",
2061    "src/core/SkPathBuilder.cpp",
2062    "src/core/SkPathEffect.cpp",
2063    "src/core/SkPathMeasure.cpp",
2064    "src/core/SkPathRef.cpp",
2065    "src/core/SkPoint.cpp",
2066    "src/core/SkRRect.cpp",
2067    "src/core/SkReadBuffer.cpp",
2068    "src/core/SkRect.cpp",
2069    "src/core/SkSemaphore.cpp",
2070    "src/core/SkStream.cpp",
2071    "src/core/SkString.cpp",
2072    "src/core/SkStringUtils.cpp",
2073    "src/core/SkStroke.cpp",
2074    "src/core/SkStrokeRec.cpp",
2075    "src/core/SkStrokerPriv.cpp",
2076    "src/core/SkThreadID.cpp",
2077    "src/core/SkUtils.cpp",
2078    "src/effects/SkDashPathEffect.cpp",
2079    "src/effects/SkTrimPathEffect.cpp",
2080    "src/ports/SkDebug_stdio.cpp",
2081    "src/ports/SkMemory_malloc.cpp",
2082    "src/utils/SkDashPath.cpp",
2083    "src/utils/SkParse.cpp",
2084    "src/utils/SkParsePath.cpp",
2085    "src/utils/SkUTF.cpp",
2086  ]
2087}
2088
2089group("modules") {
2090  deps = [
2091    "modules/particles",
2092    "modules/skottie",
2093    "modules/skparagraph",
2094    "modules/skshaper",
2095    "modules/svg",
2096  ]
2097}
2098
2099group("experimental") {
2100  deps = [ "experimental/sktext" ]
2101}
2102
2103config("our_vulkan_headers") {
2104  include_dirs = [ "//third_party/vulkan_headers/include" ]
2105}
2106
2107# Targets guarded by skia_enable_tools may use //third_party freely.
2108if (skia_enable_tools) {
2109  skia_public_includes = [
2110    "client_utils/android",
2111    "include/android",
2112    "include/c",
2113    "include/codec",
2114    "include/config",
2115    "include/core",
2116    "include/docs",
2117    "include/effects",
2118    "include/encode",
2119    "include/gpu",
2120    "include/pathops",
2121    "include/ports",
2122    "include/svg",
2123    "include/utils",
2124    "include/utils/mac",
2125    "modules/particles/include",
2126    "modules/skottie/include",
2127    "modules/skparagraph/include",
2128    "modules/skshaper/include",
2129    "modules/svg/include",
2130  ]
2131
2132  # Used by gn_to_bp.py to list our public include dirs.
2133  skia_source_set("public") {
2134    configs = [ ":skia_public" ]
2135    include_dirs = skia_public_includes
2136  }
2137
2138  config("skia.h_config") {
2139    include_dirs = [ "$target_gen_dir" ]
2140  }
2141  action("skia.h") {
2142    public_configs = [ ":skia.h_config" ]
2143    skia_h = "$target_gen_dir/skia.h"
2144    script = "gn/find_headers.py"
2145
2146    args = [ rebase_path("${skia_root_dir}/bin/gn") ] + [ rebase_path("//") ] +
2147           [ rebase_path(skia_h, root_build_dir) ] +
2148           rebase_path(skia_public_includes)
2149    depfile = "$skia_h.deps"
2150    outputs = [ skia_h ]
2151  }
2152
2153  if (target_cpu == "x64") {
2154    skia_executable("fiddle") {
2155      check_includes = false
2156      libs = []
2157      sources = [
2158        "tools/fiddle/draw.cpp",
2159        "tools/fiddle/fiddle_main.cpp",
2160      ]
2161
2162      if (skia_use_egl) {
2163        sources += [ "tools/fiddle/egl_context.cpp" ]
2164      } else {
2165        sources += [ "tools/fiddle/null_context.cpp" ]
2166      }
2167      testonly = true
2168      deps = [
2169        ":flags",
2170        ":gpu_tool_utils",
2171        ":skia",
2172        ":skia.h",
2173        "modules/particles",
2174        "modules/skottie",
2175        "modules/skparagraph",
2176        "modules/skshaper",
2177        "modules/svg",
2178      ]
2179    }
2180  }
2181
2182  config("cpp14") {
2183    if (is_win && !is_mingw) {
2184      cflags_cc = [ "/std:c++14" ]
2185    } else {
2186      cflags_cc = [ "-std=c++14" ]
2187    }
2188  }
2189
2190  skia_source_set("public_headers_warnings_check") {
2191    sources = [ "tools/public_headers_warnings_check.cpp" ]
2192    configs = [
2193      ":our_vulkan_headers",
2194      ":cpp14",
2195    ]
2196    if (defined(skia_header_target_default_configs)) {
2197      configs += skia_header_target_default_configs
2198    }
2199    deps = [
2200      ":skia",
2201      ":skia.h",
2202      "modules/skottie",
2203      "modules/skshaper",
2204    ]
2205
2206    if (skia_use_dawn) {
2207      deps += [ "${skia_third_party_dir}/externals/dawn/src/dawn:dawn_headers" ]
2208    }
2209  }
2210
2211  template("test_lib") {
2212    config(target_name + "_config") {
2213      if (defined(invoker.public_defines)) {
2214        defines = invoker.public_defines
2215      }
2216    }
2217    skia_source_set(target_name) {
2218      forward_variables_from(invoker, "*", [])
2219      check_includes = false
2220      public_configs = [
2221        ":" + target_name + "_config",
2222        ":skia_private",
2223        ":skia_wno",
2224      ]
2225
2226      if (!defined(deps)) {
2227        deps = []
2228      }
2229      deps += [ ":skia" ]
2230      if (use_oh_skia) {
2231        deps -= [ ":skia" ]
2232        deps += [ ":skia_canvaskit" ]
2233      }
2234      testonly = true
2235    }
2236  }
2237
2238  template("test_app") {
2239    if (is_ios) {
2240      ios_app_bundle(target_name) {
2241        forward_variables_from(invoker,
2242                               "*",
2243                               [
2244                                 "output_name",
2245                                 "visibility",
2246                                 "is_shared_library",
2247                               ])
2248        testonly = true
2249        extra_configs = [ ":skia_private" ]
2250        launchscreen = "platform_tools/ios/app/LaunchScreen.storyboard"
2251        data_sources = [ "resources" ]
2252        if ("True" == exec_script("${skia_root_dir}/gn/checkdir.py",
2253                                  [ rebase_path("skps", root_build_dir) ],
2254                                  "trim string")) {
2255          data_sources += [ "skps" ]
2256        }
2257        if ("True" == exec_script("${skia_root_dir}/gn/checkdir.py",
2258                                  [ rebase_path("mskps", root_build_dir) ],
2259                                  "trim string")) {
2260          data_sources += [ "mskps" ]
2261        }
2262      }
2263    } else {
2264      # !is_ios
2265
2266      if (defined(invoker.is_shared_library) && invoker.is_shared_library) {
2267        skia_shared_library("lib" + target_name) {
2268          output_dir = root_build_dir
2269          forward_variables_from(invoker, "*", [ "is_shared_library" ])
2270          if (!defined(configs)) {
2271            configs = []
2272          }
2273          configs += [
2274            ":skia_private",
2275            ":skia_wno",
2276          ]
2277          testonly = true
2278        }
2279      } else {
2280        _executable = target_name
2281        skia_executable(_executable) {
2282          check_includes = false
2283          output_dir = root_build_dir
2284          forward_variables_from(invoker, "*", [ "is_shared_library" ])
2285          if (!defined(configs)) {
2286            configs = []
2287          }
2288          configs += [
2289            ":skia_private",
2290            ":skia_wno",
2291          ]
2292          testonly = true
2293        }
2294      }
2295      if (is_android && skia_android_serial != "" && defined(_executable)) {
2296        action("push_" + target_name) {
2297          output_dir = root_build_dir
2298          script = "gn/push_to_android.py"
2299          deps = [ ":" + _executable ]
2300          _stamp = "$target_gen_dir/$_executable.pushed_$skia_android_serial"
2301          outputs = [ _stamp ]
2302          args = [
2303            rebase_path("$root_build_dir/$_executable"),
2304            skia_android_serial,
2305            rebase_path(_stamp),
2306          ]
2307          testonly = true
2308        }
2309      }
2310    }
2311  }
2312
2313  test_lib("gpu_tool_utils") {
2314    public_defines = []
2315
2316    # Bots and even devs may not have Vulkan headers, so put
2317    # include/third_party/vulkan on our path so they're always available.
2318    all_dependent_configs = [ ":our_vulkan_headers" ]
2319
2320    defines = []
2321    if (skia_enable_discrete_gpu) {
2322      defines += [ "SK_ENABLE_DISCRETE_GPU" ]
2323    }
2324
2325    deps = []
2326    public_deps = []
2327    sources = [
2328      "tools/gpu/BackendSurfaceFactory.cpp",
2329      "tools/gpu/BackendSurfaceFactory.h",
2330      "tools/gpu/BackendTextureImageFactory.cpp",
2331      "tools/gpu/BackendTextureImageFactory.h",
2332      "tools/gpu/FlushFinishTracker.cpp",
2333      "tools/gpu/FlushFinishTracker.h",
2334      "tools/gpu/GrContextFactory.cpp",
2335      "tools/gpu/GrTest.cpp",
2336      "tools/gpu/ManagedBackendTexture.cpp",
2337      "tools/gpu/ManagedBackendTexture.h",
2338      "tools/gpu/MemoryCache.cpp",
2339      "tools/gpu/MemoryCache.h",
2340      "tools/gpu/ProxyUtils.cpp",
2341      "tools/gpu/TestContext.cpp",
2342      "tools/gpu/TestOps.cpp",
2343      "tools/gpu/TestOps.h",
2344      "tools/gpu/YUVUtils.cpp",
2345      "tools/gpu/YUVUtils.h",
2346      "tools/gpu/gl/GLTestContext.cpp",  # See comment below about
2347                                         # GrContextFactory workaround.
2348      "tools/gpu/mock/MockTestContext.cpp",
2349    ]
2350
2351    libs = []
2352    frameworks = []
2353
2354    if (skia_use_gl) {
2355      sources +=
2356          [ "tools/gpu/gl/command_buffer/GLTestContext_command_buffer.cpp" ]
2357      if (is_ios) {
2358        sources += [ "tools/gpu/gl/iOS/CreatePlatformGLTestContext_iOS.mm" ]
2359        frameworks += [ "OpenGLES.framework" ]
2360      } else if (is_mac) {
2361        sources += [ "tools/gpu/gl/mac/CreatePlatformGLTestContext_mac.cpp" ]
2362      }
2363      if (skia_use_angle) {
2364        deps += [ "${skia_third_party_dir}/angle2" ]
2365        sources += [ "tools/gpu/gl/angle/GLTestContext_angle.cpp" ]
2366      }
2367    }
2368
2369    # We need the GLTestContext on Vulkan-only builds for the persistent GL context workaround in
2370    # in GrContextFactory. This only matters for OSes that can run Vulkan.
2371    if ((skia_use_gl || skia_use_vulkan) && target_cpu != "wasm") {
2372      if (is_android || skia_use_egl || is_ohos) {
2373        sources += [ "tools/gpu/gl/egl/CreatePlatformGLTestContext_egl.cpp" ]
2374
2375        if (is_ohos) {
2376          include_dirs = [ "//third_party/EGL/api" ]
2377          deps += [ "//foundation/graphic/graphic_2d:libgl" ]
2378        } else {
2379          libs += [ "EGL" ]
2380        }
2381      } else if (is_linux) {
2382        sources += [ "tools/gpu/gl/glx/CreatePlatformGLTestContext_glx.cpp" ]
2383        libs += [
2384          "GLU",
2385          "GL",
2386          "X11",
2387        ]
2388      } else if (is_win) {
2389        sources += [ "tools/gpu/gl/win/CreatePlatformGLTestContext_win.cpp" ]
2390
2391        # libs += [ "Gdi32.lib" ]
2392        libs += [ "gdi32" ]
2393        if (target_cpu != "arm64") {
2394          # libs += [ "OpenGL32.lib" ]
2395          libs += [ "opengl32" ]
2396        }
2397      }
2398    }
2399
2400    if (skia_use_vulkan) {
2401      sources += [ "tools/gpu/vk/VkTestContext.h" ]
2402      sources += [ "tools/gpu/vk/VkTestContext.cpp" ]
2403      sources += [ "tools/gpu/vk/VkTestHelper.h" ]
2404      sources += [ "tools/gpu/vk/VkTestHelper.cpp" ]
2405      sources += [ "tools/gpu/vk/VkTestUtils.h" ]
2406      sources += [ "tools/gpu/vk/VkTestUtils.cpp" ]
2407      sources += [ "tools/gpu/vk/VkYcbcrSamplerHelper.h" ]
2408      sources += [ "tools/gpu/vk/VkYcbcrSamplerHelper.cpp" ]
2409    }
2410    if (skia_use_metal) {
2411      sources += [ "tools/gpu/mtl/MtlTestContext.mm" ]
2412    }
2413    if (skia_use_direct3d) {
2414      sources += [ "tools/gpu/d3d/D3DTestContext.cpp" ]
2415      sources += [ "tools/gpu/d3d/D3DTestUtils.cpp" ]
2416    }
2417    if (skia_use_dawn) {
2418      public_deps +=
2419          [ "${skia_third_party_dir}/externals/dawn/src/dawn:dawn_headers" ]
2420      sources += [ "tools/gpu/dawn/DawnTestContext.cpp" ]
2421      if (is_clang) {
2422        cflags_cc = [ "-Wno-microsoft-cast" ]
2423      }
2424    }
2425    if (!skia_enable_skgpu_v1) {
2426      sources -= [ "tools/gpu/GrTest.cpp" ]
2427      sources -= [ "tools/gpu/TestOps.cpp" ]
2428      sources -= [ "tools/gpu/TestOps.h" ]
2429    }
2430    if (skia_enable_graphite) {
2431      sources += [ "tools/graphite/ContextFactory.h" ]
2432      sources += [ "tools/graphite/ContextFactory.cpp" ]
2433      sources += [ "tools/graphite/GraphiteTestContext.h" ]
2434      sources += [ "tools/graphite/GraphiteTestContext.cpp" ]
2435      if (skia_use_metal) {
2436        sources += [ "tools/graphite/mtl/GraphiteMtlTestContext.h" ]
2437        sources += [ "tools/graphite/mtl/MtlTestContext.mm" ]
2438      }
2439    }
2440
2441    if (is_fuchsia && using_fuchsia_sdk) {
2442      libs +=
2443          [ "${fuchsia_sdk_path}/arch/${target_cpu}/sysroot/lib/libzircon.so" ]
2444    }
2445  }  # test_lib("gpu_tool_utils")
2446
2447  test_lib("flags") {
2448    sources = [ "tools/flags/CommandLineFlags.cpp" ]
2449  }
2450
2451  test_lib("common_flags_config") {
2452    sources = [ "tools/flags/CommonFlagsConfig.cpp" ]
2453    deps = [ ":flags" ]
2454    public_deps = [ ":gpu_tool_utils" ]
2455  }
2456  test_lib("common_flags_gpu") {
2457    sources = [ "tools/flags/CommonFlagsGpu.cpp" ]
2458    deps = [ ":flags" ]
2459    public_deps = [ ":gpu_tool_utils" ]
2460  }
2461  test_lib("common_flags_images") {
2462    sources = [ "tools/flags/CommonFlagsImages.cpp" ]
2463    deps = [ ":flags" ]
2464  }
2465  test_lib("common_flags_fontmgr") {
2466    sources = [ "tools/flags/CommonFlagsFontMgr.cpp" ]
2467    deps = [ ":flags" ]
2468  }
2469  test_lib("common_flags_aa") {
2470    sources = [ "tools/flags/CommonFlagsAA.cpp" ]
2471    deps = [ ":flags" ]
2472  }
2473
2474  test_lib("trace") {
2475    deps = [ ":flags" ]
2476    sources = [
2477      "tools/trace/ChromeTracingTracer.cpp",
2478      "tools/trace/ChromeTracingTracer.h",
2479      "tools/trace/EventTracingPriv.cpp",
2480      "tools/trace/EventTracingPriv.h",
2481      "tools/trace/SkDebugfTracer.cpp",
2482      "tools/trace/SkDebugfTracer.h",
2483    ]
2484  }
2485
2486  test_lib("tool_utils") {
2487    sources = [
2488      "tools/AndroidSkDebugToStdOut.cpp",
2489      "tools/AutoreleasePool.h",
2490      "tools/DDLPromiseImageHelper.cpp",
2491      "tools/DDLPromiseImageHelper.h",
2492      "tools/DDLTileHelper.cpp",
2493      "tools/DDLTileHelper.h",
2494      "tools/LsanSuppressions.cpp",
2495      "tools/MSKPPlayer.cpp",
2496      "tools/MSKPPlayer.h",
2497      "tools/ProcStats.cpp",
2498      "tools/ProcStats.h",
2499      "tools/Resources.cpp",
2500      "tools/Resources.h",
2501      "tools/RuntimeBlendUtils.cpp",
2502      "tools/RuntimeBlendUtils.h",
2503      "tools/SkMetaData.cpp",
2504      "tools/SkMetaData.h",
2505      "tools/SkSharingProc.cpp",
2506      "tools/SkSharingProc.h",
2507      "tools/Stats.h",
2508      "tools/ToolUtils.cpp",
2509      "tools/ToolUtils.h",
2510      "tools/UrlDataManager.cpp",
2511      "tools/UrlDataManager.h",
2512      "tools/debugger/DebugCanvas.cpp",
2513      "tools/debugger/DebugCanvas.h",
2514      "tools/debugger/DebugLayerManager.cpp",
2515      "tools/debugger/DebugLayerManager.h",
2516      "tools/debugger/DrawCommand.cpp",
2517      "tools/debugger/DrawCommand.h",
2518      "tools/debugger/JsonWriteBuffer.cpp",
2519      "tools/debugger/JsonWriteBuffer.h",
2520      "tools/fonts/RandomScalerContext.cpp",
2521      "tools/fonts/RandomScalerContext.h",
2522      "tools/fonts/TestEmptyTypeface.h",
2523      "tools/fonts/TestFontMgr.cpp",
2524      "tools/fonts/TestFontMgr.h",
2525      "tools/fonts/TestSVGTypeface.cpp",
2526      "tools/fonts/TestSVGTypeface.h",
2527      "tools/fonts/TestTypeface.cpp",
2528      "tools/fonts/TestTypeface.h",
2529      "tools/fonts/ToolUtilsFont.cpp",
2530      "tools/random_parse_path.cpp",
2531      "tools/random_parse_path.h",
2532      "tools/timer/TimeUtils.h",
2533      "tools/timer/Timer.cpp",
2534      "tools/timer/Timer.h",
2535    ]
2536    if (target_cpu != "wasm") {
2537      sources += [ "tools/CrashHandler.cpp" ]
2538    }
2539    libs = []
2540    frameworks = []
2541    if (is_ios) {
2542      sources += [ "tools/ios_utils.m" ]
2543      sources += [ "tools/ios_utils.h" ]
2544      if (skia_use_metal) {
2545        sources += [ "tools/AutoreleasePool.mm" ]
2546      }
2547      frameworks += [ "Foundation.framework" ]
2548    } else if (is_mac) {
2549      if (skia_use_metal) {
2550        sources += [ "tools/AutoreleasePool.mm" ]
2551        frameworks += [ "Foundation.framework" ]
2552      }
2553    } else if (is_win && !is_mingw && !skia_enable_winuwp) {
2554      libs += [ "DbgHelp.lib" ]
2555    }
2556
2557    defines = []
2558    if (skia_tools_require_resources) {
2559      defines += [ "SK_TOOLS_REQUIRE_RESOURCES" ]
2560    }
2561    deps = [
2562      ":flags",
2563      "modules/svg",
2564    ]
2565    public_deps = [ ":gpu_tool_utils" ]
2566  }
2567
2568  test_lib("etc1") {
2569    sources = [ "third_party/etc1/etc1.cpp" ]
2570  }
2571
2572  import("gn/gm.gni")
2573  test_lib("gm") {
2574    sources = gm_sources
2575    if (skia_use_gl) {
2576      sources += gl_gm_sources
2577    }
2578    if (!skia_enable_skgpu_v1) {
2579      sources -= skgpu_v1_gm_sources
2580    }
2581    deps = [
2582      ":etc1",
2583      ":flags",
2584      ":skia",
2585      ":tool_utils",
2586      "modules/particles",
2587      "modules/skottie",
2588      "modules/skottie:gm",
2589      "modules/skparagraph",
2590      "modules/skparagraph:gm",
2591      "modules/skshaper",
2592    ]
2593    if (is_ohos) {
2594      deps += [
2595        "//base/hiviewdfx/hitrace/interfaces/native/innerkits:hitrace_meter",
2596      ]
2597    }
2598    if (use_oh_skia) {
2599      deps -= [
2600        ":skia",
2601        "modules/skshaper",
2602      ]
2603      deps += [ ":skia_canvaskit" ]
2604    }
2605    if (is_skia_dev_build) {
2606      sources += [ "gm/fiddle.cpp" ]
2607      deps += [ ":skia.h" ]
2608    }
2609    public_deps = [ ":gpu_tool_utils" ]
2610
2611    if (skia_use_ffmpeg) {
2612      deps += [ "experimental/ffmpeg:video_decoder" ]
2613      sources += [ "gm/video_decoder.cpp" ]
2614    }
2615  }
2616
2617  test_lib("test") {
2618    sources = [
2619      "tests/Test.cpp",
2620      "tests/Test.h",
2621      "tests/TestUtils.cpp",
2622      "tests/TestUtils.h",
2623    ]
2624    deps = [
2625      ":flags",
2626      ":skia",
2627      ":tool_utils",
2628    ]
2629    if (use_oh_skia) {
2630      deps -= [ ":skia" ]
2631      deps += [ ":skia_canvaskit" ]
2632    }
2633    public_deps = [
2634      ":gpu_tool_utils",  # Test.h #includes headers from this target.
2635    ]
2636  }
2637
2638  import("gn/tests.gni")
2639  test_lib("tests") {
2640    sources = tests_sources + pathops_tests_sources
2641    frameworks = []
2642    if (skia_use_metal) {
2643      sources += metal_tests_sources
2644      cflags_objcc = [ "-fobjc-arc" ]
2645      frameworks += [ "MetalKit.framework" ]
2646    }
2647    if (skia_use_gl) {
2648      sources += gl_tests_sources
2649    }
2650    if (skia_enable_graphite) {
2651      sources += graphite_tests_sources
2652      if (skia_use_metal) {
2653        sources += graphite_metal_tests_sources
2654      }
2655    }
2656    if (!skia_enable_skgpu_v1) {
2657      sources -= skgpu_v1_tests_sources
2658    }
2659    deps = [
2660      ":flags",
2661      ":fontmgr_android_tests",
2662      ":fontmgr_fontconfig_tests",
2663      ":fontmgr_mac_ct_tests",
2664      ":skia",
2665      ":test",
2666      ":tool_utils",
2667      "${skia_third_party_dir}/libpng",
2668      "${skia_third_party_dir}/libwebp",
2669      "${skia_third_party_dir}/zlib",
2670      "experimental/skrive:tests",
2671      "experimental/sktext:tests",
2672      "modules/skottie:tests",
2673      "modules/skparagraph:tests",
2674      "modules/sksg:tests",
2675      "modules/skshaper",
2676      "modules/svg:tests",
2677    ]
2678    if (use_oh_skia) {
2679      deps -= [
2680        ":skia",
2681        "modules/skshaper",
2682      ]
2683      deps += [ ":skia_canvaskit" ]
2684    }
2685  }
2686
2687  import("gn/bench.gni")
2688  test_lib("bench") {
2689    sources = bench_sources
2690    if (skia_enable_graphite) {
2691      sources += graphite_bench_sources
2692    }
2693    if (!skia_enable_skgpu_v1) {
2694      sources -= skgpu_v1_bench_sources
2695    }
2696    deps = [
2697      ":flags",
2698      ":gm",
2699      ":gpu_tool_utils",
2700      ":skia",
2701      ":tool_utils",
2702      "modules/skparagraph:bench",
2703      "modules/skshaper",
2704    ]
2705  }
2706
2707  test_lib("experimental_xform") {
2708    sources = [
2709      "experimental/xform/SkShape.cpp",
2710      "experimental/xform/SkXform.cpp",
2711      "experimental/xform/XContext.cpp",
2712    ]
2713    deps = [ ":skia" ]
2714  }
2715
2716  if (is_linux || is_mac) {
2717    if (skia_enable_skottie) {
2718      test_app("skottie_tool") {
2719        deps = [ "modules/skottie:tool" ]
2720      }
2721    }
2722    test_app("svg_tool") {
2723      deps = [ "modules/svg:tool" ]
2724    }
2725  }
2726
2727  test_app("make_skqp_model") {
2728    sources = [ "tools/skqp/make_skqp_model.cpp" ]
2729    deps = [ ":skia" ]
2730  }
2731
2732  import("gn/samples.gni")
2733  test_lib("samples") {
2734    sources = samples_sources
2735    if (!skia_enable_skgpu_v1) {
2736      sources -= skgpu_v1_samples_sources
2737    }
2738    public_deps = [ ":tool_utils" ]
2739    deps = [
2740      ":flags",
2741      ":gpu_tool_utils",
2742      ":xml",
2743      "${skia_third_party_dir}/imgui",
2744      "experimental/sktext:samples",
2745      "modules/audioplayer",
2746      "modules/skparagraph:samples",
2747      "modules/skshaper",
2748      "modules/svg",
2749    ]
2750  }
2751  test_lib("hash_and_encode") {
2752    sources = [
2753      "tools/HashAndEncode.cpp",
2754      "tools/HashAndEncode.h",
2755    ]
2756    deps = [
2757      ":flags",
2758      ":skia",
2759      "${skia_third_party_dir}/libpng",
2760    ]
2761    if (use_oh_skia) {
2762      deps -= [ ":skia" ]
2763      deps += [ ":skia_canvaskit" ]
2764    }
2765  }
2766  if (target_cpu != "wasm") {
2767    test_app("convert-to-nia") {
2768      sources = [ "tools/convert-to-nia.cpp" ]
2769      deps = [ ":skia" ]
2770    }
2771    test_app("imgcvt") {
2772      sources = [ "tools/imgcvt.cpp" ]
2773      deps = [
2774        ":skcms",
2775        ":skia",
2776      ]
2777    }
2778    test_app("fm") {
2779      sources = [
2780        "dm/DMGpuTestProcs.cpp",  # blech
2781        "tools/fm/fm.cpp",
2782      ]
2783      deps = [
2784        ":common_flags_aa",
2785        ":common_flags_fontmgr",
2786        ":common_flags_gpu",
2787        ":flags",
2788        ":gm",
2789        ":gpu_tool_utils",
2790        ":hash_and_encode",
2791        ":skia",
2792        ":tests",
2793        ":tool_utils",
2794        ":trace",
2795        "modules/skottie",
2796        "modules/skottie:utils",
2797        "modules/svg",
2798      ]
2799    }
2800    test_app("dm") {
2801      sources = [
2802        "dm/DM.cpp",
2803        "dm/DMGpuTestProcs.cpp",
2804        "dm/DMJsonWriter.cpp",
2805        "dm/DMJsonWriter.h",
2806        "dm/DMSrcSink.cpp",
2807        "dm/DMSrcSink.h",
2808      ]
2809      deps = [
2810        ":common_flags_aa",
2811        ":common_flags_config",
2812        ":common_flags_fontmgr",
2813        ":common_flags_gpu",
2814        ":common_flags_images",
2815        ":flags",
2816        ":gm",
2817        ":gpu_tool_utils",
2818        ":hash_and_encode",
2819        ":skia",
2820        ":tests",
2821        ":tool_utils",
2822        ":trace",
2823        "experimental/skrive",
2824        "modules/skottie",
2825        "modules/skottie:utils",
2826        "modules/svg",
2827      ]
2828      if (use_oh_skia) {
2829        deps -= [
2830          ":skia",
2831          "modules/svg",
2832        ]
2833        deps += [ ":skia_canvaskit" ]
2834      }
2835      ldflags = [
2836        "--stdlib=libc++",
2837        "-lc++",
2838        "-lc++abi",
2839      ]
2840    }
2841    test_app("sorttoy") {
2842      sources = [
2843        "experimental/sorttoy/Cmds.cpp",
2844        "experimental/sorttoy/Cmds.h",
2845        "experimental/sorttoy/Fake.cpp",
2846        "experimental/sorttoy/Fake.h",
2847        "experimental/sorttoy/SortKey.h",
2848        "experimental/sorttoy/sorttoy.cpp",
2849        "experimental/sorttoy/sorttypes.h",
2850      ]
2851      deps = [
2852        ":flags",
2853        ":skia",
2854        ":tool_utils",
2855      ]
2856    }
2857
2858    # optional separate library to dlopen when running CanvasStateTests.
2859    skia_shared_library("canvas_state_lib") {
2860      sources = [
2861        "tests/CanvasStateHelpers.cpp",
2862        "tests/CanvasStateHelpers.h",
2863      ]
2864      deps = [ ":skia" ]
2865    }
2866  }
2867
2868  if (!is_win) {
2869    test_app("remote_demo") {
2870      sources = [ "tools/remote_demo.cpp" ]
2871      deps = [ ":skia" ]
2872    }
2873  }
2874
2875  if (!is_win) {
2876    test_app("blob_cache_sim") {
2877      sources = [ "tools/blob_cache_sim.cpp" ]
2878      deps = [ ":skia" ]
2879    }
2880  }
2881
2882  test_app("nanobench") {
2883    sources = [ "bench/nanobench.cpp" ]
2884    deps = [
2885      ":bench",
2886      ":common_flags_aa",
2887      ":common_flags_config",
2888      ":common_flags_gpu",
2889      ":common_flags_images",
2890      ":flags",
2891      ":gm",
2892      ":gpu_tool_utils",
2893      ":skia",
2894      ":tool_utils",
2895      ":trace",
2896      "modules/skparagraph",
2897      "modules/skshaper",
2898      "modules/svg",
2899    ]
2900  }
2901
2902  test_app("skpinfo") {
2903    sources = [ "tools/skpinfo.cpp" ]
2904    configs = [ ":our_vulkan_headers" ]
2905    deps = [
2906      ":flags",
2907      ":skia",
2908    ]
2909  }
2910
2911  if (skia_use_ffmpeg) {
2912    test_app("skottie2movie") {
2913      sources = [ "tools/skottie2movie.cpp" ]
2914      deps = [
2915        ":flags",
2916        ":gpu_tool_utils",
2917        ":skia",
2918        "experimental/ffmpeg:video_encoder",
2919        "modules/skottie",
2920        "modules/skottie:utils",
2921      ]
2922    }
2923  }
2924
2925  test_app("skpbench") {
2926    sources = [
2927      "bench/BigPath.cpp",
2928      "tools/skpbench/skpbench.cpp",
2929    ]
2930    deps = [
2931      ":common_flags_config",
2932      ":common_flags_gpu",
2933      ":flags",
2934      ":gpu_tool_utils",
2935      ":skia",
2936      ":tool_utils",
2937    ]
2938  }
2939
2940  test_app("sktexttopdf") {
2941    sources = [ "tools/using_skia_and_harfbuzz.cpp" ]
2942    deps = [
2943      ":skia",
2944      "modules/skshaper",
2945    ]
2946  }
2947
2948  test_app("create_test_font") {
2949    sources = [ "tools/fonts/create_test_font.cpp" ]
2950    deps = [ ":skia" ]
2951    assert_no_deps = [
2952      # tool_utils requires the output of this app.
2953      ":tool_utils",
2954    ]
2955  }
2956
2957  if (skia_use_expat) {
2958    test_app("create_test_font_color") {
2959      sources = [ "tools/fonts/create_test_font_color.cpp" ]
2960      deps = [
2961        ":flags",
2962        ":skia",
2963        ":tool_utils",
2964      ]
2965    }
2966  }
2967
2968  test_app("get_images_from_skps") {
2969    sources = [ "tools/get_images_from_skps.cpp" ]
2970    deps = [
2971      ":flags",
2972      ":skia",
2973    ]
2974  }
2975
2976  if (!is_ios && target_cpu != "wasm" && !(is_win && target_cpu == "arm64")) {
2977    test_app("skiaserve") {
2978      sources = [
2979        "tools/skiaserve/Request.cpp",
2980        "tools/skiaserve/Response.cpp",
2981        "tools/skiaserve/skiaserve.cpp",
2982        "tools/skiaserve/urlhandlers/BreakHandler.cpp",
2983        "tools/skiaserve/urlhandlers/ClipAlphaHandler.cpp",
2984        "tools/skiaserve/urlhandlers/CmdHandler.cpp",
2985        "tools/skiaserve/urlhandlers/ColorModeHandler.cpp",
2986        "tools/skiaserve/urlhandlers/DataHandler.cpp",
2987        "tools/skiaserve/urlhandlers/DownloadHandler.cpp",
2988        "tools/skiaserve/urlhandlers/EnableGPUHandler.cpp",
2989        "tools/skiaserve/urlhandlers/ImgHandler.cpp",
2990        "tools/skiaserve/urlhandlers/InfoHandler.cpp",
2991        "tools/skiaserve/urlhandlers/OpBoundsHandler.cpp",
2992        "tools/skiaserve/urlhandlers/OpsHandler.cpp",
2993        "tools/skiaserve/urlhandlers/OverdrawHandler.cpp",
2994        "tools/skiaserve/urlhandlers/PostHandler.cpp",
2995        "tools/skiaserve/urlhandlers/QuitHandler.cpp",
2996        "tools/skiaserve/urlhandlers/RootHandler.cpp",
2997      ]
2998      deps = [
2999        ":flags",
3000        ":gpu_tool_utils",
3001        ":skia",
3002        ":tool_utils",
3003        "${skia_third_party_dir}/libmicrohttpd",
3004      ]
3005    }
3006  }
3007
3008  test_app("fuzz") {
3009    sources = [
3010      "fuzz/Fuzz.cpp",
3011      "fuzz/Fuzz.h",
3012      "fuzz/FuzzCanvas.cpp",
3013      "fuzz/FuzzCommon.cpp",
3014      "fuzz/FuzzCommon.h",
3015      "fuzz/FuzzCreateDDL.cpp",
3016      "fuzz/FuzzDDLThreading.cpp",
3017      "fuzz/FuzzDrawFunctions.cpp",
3018      "fuzz/FuzzEncoders.cpp",
3019      "fuzz/FuzzGradients.cpp",
3020      "fuzz/FuzzMain.cpp",
3021      "fuzz/FuzzParsePath.cpp",
3022      "fuzz/FuzzPathMeasure.cpp",
3023      "fuzz/FuzzPathop.cpp",
3024      "fuzz/FuzzPolyUtils.cpp",
3025      "fuzz/FuzzRegionOp.cpp",
3026      "fuzz/FuzzSkParagraph.cpp",
3027      "fuzz/FuzzTriangulation.cpp",
3028      "fuzz/oss_fuzz/FuzzAndroidCodec.cpp",
3029      "fuzz/oss_fuzz/FuzzAnimatedImage.cpp",
3030      "fuzz/oss_fuzz/FuzzImage.cpp",
3031      "fuzz/oss_fuzz/FuzzImageFilterDeserialize.cpp",
3032      "fuzz/oss_fuzz/FuzzIncrementalImage.cpp",
3033      "fuzz/oss_fuzz/FuzzJSON.cpp",
3034      "fuzz/oss_fuzz/FuzzPathDeserialize.cpp",
3035      "fuzz/oss_fuzz/FuzzRegionDeserialize.cpp",
3036      "fuzz/oss_fuzz/FuzzRegionSetPath.cpp",
3037      "fuzz/oss_fuzz/FuzzSKP.cpp",
3038      "fuzz/oss_fuzz/FuzzSKSL2GLSL.cpp",
3039      "fuzz/oss_fuzz/FuzzSKSL2Metal.cpp",
3040      "fuzz/oss_fuzz/FuzzSKSL2Pipeline.cpp",
3041      "fuzz/oss_fuzz/FuzzSKSL2SPIRV.cpp",
3042      "fuzz/oss_fuzz/FuzzSVG.cpp",
3043      "fuzz/oss_fuzz/FuzzSkDescriptorDeserialize.cpp",
3044      "fuzz/oss_fuzz/FuzzSkParagraph.cpp",
3045      "fuzz/oss_fuzz/FuzzSkRuntimeEffect.cpp",
3046      "fuzz/oss_fuzz/FuzzTextBlobDeserialize.cpp",
3047      "tools/UrlDataManager.cpp",
3048      "tools/debugger/DebugCanvas.cpp",
3049      "tools/debugger/DebugLayerManager.cpp",
3050      "tools/debugger/DrawCommand.cpp",
3051      "tools/debugger/JsonWriteBuffer.cpp",
3052    ]
3053    deps = [
3054      ":flags",
3055      ":gpu_tool_utils",
3056      ":skia",
3057      "modules/skottie:fuzz",
3058      "modules/skparagraph",
3059    ]
3060  }
3061
3062  test_app("pathops_unittest") {
3063    sources = pathops_tests_sources + [
3064                rebase_path("tests/skia_test.cpp"),
3065                rebase_path("tests/Test.cpp"),
3066              ]
3067    deps = [
3068      ":flags",
3069      ":gpu_tool_utils",
3070      ":skia",
3071      ":tool_utils",
3072    ]
3073  }
3074
3075  test_app("dump_record") {
3076    sources = [ "tools/dump_record.cpp" ]
3077    deps = [
3078      ":flags",
3079      ":skia",
3080    ]
3081  }
3082
3083  test_app("skdiff") {
3084    sources = [
3085      "tools/skdiff/skdiff.cpp",
3086      "tools/skdiff/skdiff_html.cpp",
3087      "tools/skdiff/skdiff_main.cpp",
3088      "tools/skdiff/skdiff_utils.cpp",
3089    ]
3090    deps = [
3091      ":skia",
3092      ":tool_utils",
3093    ]
3094  }
3095
3096  test_app("skp_parser") {
3097    sources = [ "tools/skp_parser.cpp" ]
3098    deps = [
3099      ":skia",
3100      ":tool_utils",
3101    ]
3102  }
3103
3104  if (!is_win) {
3105    source_set("skqp_lib") {  # Not a skia_source_set
3106      check_includes = false
3107      testonly = true
3108      public_configs = [ ":skia_private" ]
3109      defines =
3110          [ "SK_SKQP_GLOBAL_ERROR_TOLERANCE=$skia_skqp_global_error_tolerance" ]
3111      sources = [
3112        "dm/DMGpuTestProcs.cpp",
3113        "tools/skqp/src/skqp.cpp",
3114        "tools/skqp/src/skqp_model.cpp",
3115      ]
3116      deps = [
3117        ":gm",
3118        ":skia",
3119        ":tests",
3120        ":tool_utils",
3121      ]
3122    }
3123    test_app("skqp") {
3124      sources = [ "tools/skqp/src/skqp_main.cpp" ]
3125      include_dirs = [ "${skia_root_dir}/" ]
3126      lib_dirs = []
3127      deps = [ ":skqp_lib" ]
3128    }
3129    test_app("jitter_gms") {
3130      sources = [ "tools/skqp/jitter_gms.cpp" ]
3131      deps = [
3132        ":gm",
3133        ":skia",
3134        ":skqp_lib",
3135      ]
3136    }
3137  }
3138  if (is_fuchsia) {
3139    # Build a package repository for skqp on Fuchsia.
3140    group("skqp_repo") {
3141      testonly = true
3142      deps = [ "${skia_root_dir}/build/fuchsia/skqp:skqp_repo" ]
3143    }
3144  }
3145  if (is_android) {
3146    shared_library("libskqp_app") {  # Not a skia_shared_library
3147      configs += [ ":skia_private" ]
3148      testonly = true
3149      sources = [ "tools/skqp/src/jni_skqp.cpp" ]
3150      deps = [
3151        ":skia",
3152        ":skqp_lib",
3153        ":tool_utils",
3154      ]
3155      libs = [ "android" ]
3156    }
3157  }
3158  if (is_android && skia_use_gl) {
3159    test_app("skottie_android") {
3160      is_shared_library = true
3161
3162      sources = [ "platform_tools/android/apps/skottie/skottielib/src/main/cpp/native-lib.cpp" ]
3163      libs = []
3164
3165      deps = [
3166        ":skia",
3167        "modules/skottie",
3168      ]
3169    }
3170
3171    test_app("androidkit") {
3172      is_shared_library = true
3173
3174      sources = [
3175        "modules/androidkit/src/AndroidKit.cpp",
3176        "modules/androidkit/src/Canvas.cpp",
3177        "modules/androidkit/src/ColorFilters.cpp",
3178        "modules/androidkit/src/Font.cpp",
3179        "modules/androidkit/src/FontChainAdapter.cpp",
3180        "modules/androidkit/src/Gradients.cpp",
3181        "modules/androidkit/src/Image.cpp",
3182        "modules/androidkit/src/ImageFilter.cpp",
3183        "modules/androidkit/src/Matrix.cpp",
3184        "modules/androidkit/src/Paint.cpp",
3185        "modules/androidkit/src/Path.cpp",
3186        "modules/androidkit/src/PathBuilder.cpp",
3187        "modules/androidkit/src/RuntimeShaderBuilder.cpp",
3188        "modules/androidkit/src/Shader.cpp",
3189        "modules/androidkit/src/SkottieAnimation.cpp",
3190        "modules/androidkit/src/Surface.cpp",
3191        "modules/androidkit/src/Surface.h",
3192        "modules/androidkit/src/SurfaceThread.cpp",
3193        "modules/androidkit/src/SurfaceThread.h",
3194        "modules/androidkit/src/Text.cpp",
3195        "modules/androidkit/src/Utils.cpp",
3196      ]
3197      libs = [
3198        "android",
3199        "jnigraphics",
3200      ]
3201
3202      deps = [
3203        ":sk_app",
3204        ":skia",
3205        "experimental/sktext:sktext",
3206        "modules/skottie:skottie",
3207      ]
3208    }
3209  }
3210
3211  test_app("list_gms") {
3212    sources = [ "tools/list_gms.cpp" ]
3213    deps = [
3214      ":gm",
3215      ":skia",
3216    ]
3217  }
3218  test_app("list_gpu_unit_tests") {
3219    sources = [
3220      "dm/DMGpuTestProcs.cpp",
3221      "tools/list_gpu_unit_tests.cpp",
3222    ]
3223    deps = [
3224      ":skia",
3225      ":tests",
3226    ]
3227  }
3228
3229  test_lib("sk_app") {
3230    public_deps = [
3231      ":gpu_tool_utils",
3232      ":skia",
3233    ]
3234    sources = [
3235      "tools/sk_app/Application.h",
3236      "tools/sk_app/CommandSet.cpp",
3237      "tools/sk_app/CommandSet.h",
3238      "tools/sk_app/DisplayParams.h",
3239      "tools/sk_app/RasterWindowContext.h",
3240      "tools/sk_app/Window.cpp",
3241      "tools/sk_app/Window.h",
3242      "tools/sk_app/WindowContext.cpp",
3243      "tools/sk_app/WindowContext.h",
3244    ]
3245    libs = []
3246    frameworks = []
3247
3248    if (is_android) {
3249      sources += [
3250        "tools/sk_app/android/RasterWindowContext_android.cpp",
3251        "tools/sk_app/android/WindowContextFactory_android.h",
3252        "tools/sk_app/android/Window_android.cpp",
3253        "tools/sk_app/android/Window_android.h",
3254        "tools/sk_app/android/main_android.cpp",
3255        "tools/sk_app/android/surface_glue_android.cpp",
3256        "tools/sk_app/android/surface_glue_android.h",
3257      ]
3258      libs += [ "android" ]
3259    } else if (is_linux) {
3260      sources += [
3261        "tools/sk_app/unix/RasterWindowContext_unix.cpp",
3262        "tools/sk_app/unix/WindowContextFactory_unix.h",
3263        "tools/sk_app/unix/Window_unix.cpp",
3264        "tools/sk_app/unix/Window_unix.h",
3265        "tools/sk_app/unix/keysym2ucs.c",
3266        "tools/sk_app/unix/keysym2ucs.h",
3267        "tools/sk_app/unix/main_unix.cpp",
3268      ]
3269      libs += [
3270        "GL",  # Used by raster window context, so cannot be behind skia_use_gl.
3271        "X11",
3272      ]
3273    } else if (is_win) {
3274      sources += [
3275        "tools/sk_app/win/RasterWindowContext_win.cpp",
3276        "tools/sk_app/win/WindowContextFactory_win.h",
3277        "tools/sk_app/win/Window_win.cpp",
3278        "tools/sk_app/win/Window_win.h",
3279        "tools/sk_app/win/main_win.cpp",
3280      ]
3281    } else if (is_mac) {
3282      sources += [
3283        "tools/sk_app/mac/WindowContextFactory_mac.h",
3284        "tools/sk_app/mac/Window_mac.h",
3285        "tools/sk_app/mac/Window_mac.mm",
3286        "tools/sk_app/mac/main_mac.mm",
3287      ]
3288      frameworks += [
3289        "QuartzCore.framework",
3290        "Cocoa.framework",
3291        "Foundation.framework",
3292      ]
3293    } else if (is_ios) {
3294      sources += [
3295        "tools/sk_app/ios/WindowContextFactory_ios.h",
3296        "tools/sk_app/ios/Window_ios.h",
3297        "tools/sk_app/ios/Window_ios.mm",
3298        "tools/sk_app/ios/main_ios.mm",
3299      ]
3300      frameworks += [ "QuartzCore.framework" ]
3301    }
3302
3303    if (skia_use_gl) {
3304      sources += [ "tools/sk_app/GLWindowContext.cpp" ]
3305      sources += [ "tools/sk_app/GLWindowContext.h" ]
3306      if (is_android) {
3307        sources += [ "tools/sk_app/android/GLWindowContext_android.cpp" ]
3308      } else if (is_linux) {
3309        sources += [ "tools/sk_app/unix/GLWindowContext_unix.cpp" ]
3310      } else if (is_win) {
3311        sources += [ "tools/sk_app/win/GLWindowContext_win.cpp" ]
3312        if (skia_use_angle) {
3313          sources += [ "tools/sk_app/win/ANGLEWindowContext_win.cpp" ]
3314        }
3315      } else if (is_mac) {
3316        sources += [
3317          "tools/sk_app/mac/GLWindowContext_mac.mm",
3318          "tools/sk_app/mac/RasterWindowContext_mac.mm",
3319        ]
3320      } else if (is_ios) {
3321        sources += [
3322          "tools/sk_app/ios/GLWindowContext_ios.mm",
3323          "tools/sk_app/ios/RasterWindowContext_ios.mm",
3324        ]
3325      }
3326    }
3327
3328    if (skia_use_vulkan) {
3329      sources += [ "tools/sk_app/VulkanWindowContext.cpp" ]
3330      sources += [ "tools/sk_app/VulkanWindowContext.h" ]
3331      if (is_android) {
3332        sources += [ "tools/sk_app/android/VulkanWindowContext_android.cpp" ]
3333      } else if (is_linux) {
3334        sources += [ "tools/sk_app/unix/VulkanWindowContext_unix.cpp" ]
3335        libs += [ "X11-xcb" ]
3336      } else if (is_win) {
3337        sources += [ "tools/sk_app/win/VulkanWindowContext_win.cpp" ]
3338      }
3339    }
3340
3341    if (skia_use_metal) {
3342      sources += [ "tools/sk_app/MetalWindowContext.mm" ]
3343      sources += [ "tools/sk_app/MetalWindowContext.h" ]
3344      if (skia_enable_graphite) {
3345        sources += [ "tools/sk_app/GraphiteMetalWindowContext.mm" ]
3346        sources += [ "tools/sk_app/GraphiteMetalWindowContext.h" ]
3347      }
3348      if (is_mac) {
3349        sources += [ "tools/sk_app/mac/MetalWindowContext_mac.mm" ]
3350        if (skia_enable_graphite) {
3351          sources += [ "tools/sk_app/mac/GraphiteMetalWindowContext_mac.mm" ]
3352        }
3353      } else if (is_ios) {
3354        sources += [ "tools/sk_app/ios/MetalWindowContext_ios.mm" ]
3355      }
3356    }
3357
3358    if (skia_use_direct3d) {
3359      sources += [ "tools/sk_app/win/D3D12WindowContext_win.cpp" ]
3360    }
3361
3362    if (skia_use_dawn) {
3363      sources += [ "tools/sk_app/DawnWindowContext.cpp" ]
3364      sources += [ "tools/sk_app/DawnWindowContext.h" ]
3365      if (is_linux) {
3366        if (dawn_enable_vulkan) {
3367          sources += [ "tools/sk_app/unix/DawnVulkanWindowContext_unix.cpp" ]
3368          defines = [ "VK_USE_PLATFORM_XCB_KHR" ]
3369          libs += [ "X11-xcb" ]
3370        }
3371      } else if (is_win) {
3372        if (dawn_enable_d3d12) {
3373          sources += [ "tools/sk_app/win/DawnD3D12WindowContext_win.cpp" ]
3374        }
3375      } else if (is_mac) {
3376        if (dawn_enable_metal) {
3377          sources += [ "tools/sk_app/mac/DawnMTLWindowContext_mac.mm" ]
3378        }
3379      }
3380    }
3381
3382    deps = [ ":tool_utils" ]
3383    if (is_android) {
3384      deps += [ "${skia_third_party_dir}/native_app_glue" ]
3385    }
3386    if (skia_use_gl && skia_use_angle) {
3387      deps += [ "${skia_third_party_dir}/angle2" ]
3388    }
3389  }
3390
3391  if (!skia_use_vulkan && (is_mac || is_linux || is_win)) {
3392    test_app("fiddle_examples") {
3393      sources = [
3394        "tools/fiddle/all_examples.cpp",
3395        "tools/fiddle/examples.cpp",
3396        "tools/fiddle/examples.h",
3397      ]
3398      if (is_win && !is_mingw) {
3399        cflags = [
3400          "/wd4756",  # Overflow in constant arithmetic
3401          "/wd4305",  # truncation from 'double' to 'float'
3402        ]
3403      }
3404      deps = [
3405        ":skia",
3406        ":skia.h",
3407        "modules/particles",
3408        "modules/skottie",
3409        "modules/skparagraph",
3410        "modules/skshaper",
3411        "modules/svg",
3412      ]
3413    }
3414  }
3415
3416  # sk_app can work without GL but viewer always runs raster through a GL window context.
3417  if (skia_use_gl) {
3418    test_app("viewer") {
3419      is_shared_library = is_android
3420      sources = [
3421        "tools/viewer/AnimTimer.h",
3422        "tools/viewer/BisectSlide.cpp",
3423        "tools/viewer/BisectSlide.h",
3424        "tools/viewer/GMSlide.cpp",
3425        "tools/viewer/GMSlide.h",
3426        "tools/viewer/ImGuiLayer.cpp",
3427        "tools/viewer/ImGuiLayer.h",
3428        "tools/viewer/ImageSlide.cpp",
3429        "tools/viewer/ImageSlide.h",
3430        "tools/viewer/MSKPSlide.cpp",
3431        "tools/viewer/MSKPSlide.h",
3432        "tools/viewer/ParticlesSlide.cpp",
3433        "tools/viewer/ParticlesSlide.h",
3434        "tools/viewer/SKPSlide.cpp",
3435        "tools/viewer/SKPSlide.h",
3436        "tools/viewer/SampleSlide.cpp",
3437        "tools/viewer/SampleSlide.h",
3438        "tools/viewer/SkRiveSlide.cpp",
3439        "tools/viewer/SkRiveSlide.h",
3440        "tools/viewer/SkSLSlide.cpp",
3441        "tools/viewer/SkSLSlide.h",
3442        "tools/viewer/SkottieSlide.cpp",
3443        "tools/viewer/SkottieSlide.h",
3444        "tools/viewer/Slide.h",
3445        "tools/viewer/SlideDir.cpp",
3446        "tools/viewer/SlideDir.h",
3447        "tools/viewer/StatsLayer.cpp",
3448        "tools/viewer/StatsLayer.h",
3449        "tools/viewer/SvgSlide.cpp",
3450        "tools/viewer/SvgSlide.h",
3451        "tools/viewer/TouchGesture.cpp",
3452        "tools/viewer/TouchGesture.h",
3453        "tools/viewer/Viewer.cpp",
3454        "tools/viewer/Viewer.h",
3455      ]
3456      libs = []
3457
3458      deps = [
3459        ":common_flags_fontmgr",
3460        ":common_flags_gpu",
3461        ":flags",
3462        ":gm",
3463        ":gpu_tool_utils",
3464        ":samples",
3465        ":sk_app",
3466        ":skia",
3467        ":tool_utils",
3468        ":trace",
3469        "${skia_third_party_dir}/imgui",
3470        "experimental/skrive",
3471        "experimental/sktext",
3472        "modules/audioplayer",
3473        "modules/particles",
3474        "modules/skottie",
3475        "modules/skottie:utils",
3476        "modules/sksg:samples",
3477        "modules/svg",
3478      ]
3479      if (skia_use_experimental_xform) {
3480        deps += [ ":experimental_xform" ]
3481        sources += [ "gm/xform.cpp" ]
3482      }
3483      if (skia_use_vulkan) {
3484        deps += [
3485          "${skia_third_party_dir}/externals/spirv-tools:spvtools",
3486
3487          #spvtools depends on this but doesn't deps it in.
3488          "${skia_third_party_dir}/externals/spirv-tools:spvtools_val",
3489        ]
3490      }
3491    }
3492  }
3493
3494  if (skia_use_gl && !skia_use_angle && (is_linux || is_win || is_mac)) {
3495    test_app("HelloWorld") {
3496      sources = [ "example/HelloWorld.cpp" ]
3497      libs = []
3498
3499      deps = [
3500        ":flags",
3501        ":gpu_tool_utils",
3502        ":sk_app",
3503        ":skia",
3504        ":tool_utils",
3505      ]
3506    }
3507  }
3508
3509  if (skia_qt_path != "" && (is_win || is_linux || is_mac)) {
3510    action_foreach("generate_mocs") {
3511      script = "gn/call.py"
3512      sources = [ "tools/mdbviz/MainWindow.h" ]
3513      outputs = [ "$target_gen_dir/mdbviz/{{source_name_part}}_moc.cpp" ]
3514      args = [
3515        "$skia_qt_path" + "/bin/moc",
3516        "{{source}}",
3517        "-o",
3518        "gen/mdbviz/{{source_name_part}}_moc.cpp",
3519      ]
3520    }
3521    action_foreach("generate_resources") {
3522      script = "gn/call.py"
3523      sources = [ "tools/mdbviz/resources.qrc" ]
3524      outputs = [ "$target_gen_dir/mdbviz/{{source_name_part}}_res.cpp" ]
3525      args = [
3526        "$skia_qt_path" + "/bin/rcc",
3527        "{{source}}",
3528        "-o",
3529        "gen/mdbviz/{{source_name_part}}_res.cpp",
3530      ]
3531    }
3532    test_app("mdbviz") {
3533      if (is_win && !is_mingw) {
3534        # on Windows we need to disable some exception handling warnings due to the Qt headers
3535        cflags = [ "/Wv:18" ]  # 18 -> VS2013, 19 -> VS2015, 1910 -> VS2017
3536      }
3537      sources = [
3538        "tools/UrlDataManager.cpp",
3539        "tools/debugger/DebugCanvas.cpp",
3540        "tools/debugger/DebugLayerManager.cpp",
3541        "tools/debugger/DrawCommand.cpp",
3542        "tools/debugger/JsonWriteBuffer.cpp",
3543        "tools/mdbviz/MainWindow.cpp",
3544        "tools/mdbviz/Model.cpp",
3545        "tools/mdbviz/main.cpp",
3546
3547        # generated files
3548        "$target_gen_dir/mdbviz/MainWindow_moc.cpp",
3549        "$target_gen_dir/mdbviz/resources_res.cpp",
3550      ]
3551      lib_dirs = [ "$skia_qt_path/lib" ]
3552      libs = [
3553        "Qt5Core.lib",
3554        "Qt5Gui.lib",
3555        "Qt5Widgets.lib",
3556      ]
3557      include_dirs = [
3558        "$skia_qt_path/include",
3559        "$skia_qt_path/include/QtCore",
3560        "$skia_qt_path/include/QtWidgets",
3561      ]
3562      deps = [
3563        ":generate_mocs",
3564        ":generate_resources",
3565        ":skia",
3566      ]
3567    }
3568  }
3569
3570  if (is_android && defined(ndk) && ndk != "") {
3571    copy("gdbserver") {
3572      sources = [ "$ndk/$ndk_gdbserver" ]
3573      outputs = [ "$root_out_dir/gdbserver" ]
3574    }
3575  }
3576
3577  skia_executable("cpu_modules") {
3578    sources = [ "tools/cpu_modules.cpp" ]
3579    deps = [
3580      ":skia",
3581      "modules/particles",
3582    ]
3583  }
3584
3585  if (skia_use_icu && skia_use_harfbuzz) {
3586    test_app("editor") {
3587      is_shared_library = is_android
3588      deps = [ "modules/skplaintexteditor:editor_app" ]
3589    }
3590    test_app("text_editor") {
3591      is_shared_library = is_android
3592      deps = [ "experimental/sktext:text_editor" ]
3593    }
3594  }
3595
3596  skia_executable("image_diff_metric") {
3597    sources = [ "tools/image_diff_metric.cpp" ]
3598    deps = [ ":skia" ]
3599  }
3600
3601  group("modules_testonly") {
3602    testonly = true
3603    deps = []
3604    if (target_cpu == "wasm") {
3605      deps += [ "modules/canvaskit:viewer_wasm" ]
3606    }
3607  }
3608
3609  if (skia_build_fuzzers) {
3610    template("libfuzzer_app") {
3611      skia_executable(target_name) {
3612        output_dir = root_build_dir
3613        check_includes = false
3614        forward_variables_from(invoker, "*", [ "is_shared_library" ])
3615        if (!defined(configs)) {
3616          configs = []
3617        }
3618        configs += [ ":skia_private" ]
3619        sources += [
3620          "fuzz/Fuzz.cpp",
3621          "fuzz/FuzzCommon.cpp",
3622        ]
3623        deps += [
3624          ":flags",
3625          ":gpu_tool_utils",
3626          ":skia",
3627        ]
3628        defines = [ "SK_BUILD_FOR_LIBFUZZER" ]
3629        if (skia_use_libfuzzer_defaults) {
3630          cflags = [ "-fsanitize=fuzzer" ]
3631          ldflags = [ "-fsanitize=fuzzer" ]
3632        }
3633        testonly = true
3634      }
3635    }
3636
3637    libfuzzer_app("region_deserialize") {
3638      sources = [ "fuzz/oss_fuzz/FuzzRegionDeserialize.cpp" ]
3639      deps = []
3640    }
3641
3642    libfuzzer_app("image_filter_deserialize") {
3643      include_dirs = [
3644        "tools",
3645        "tools/fonts",
3646      ]
3647      sources = [
3648        "fuzz/oss_fuzz/FuzzImageFilterDeserialize.cpp",
3649        "tools/Resources.cpp",
3650        "tools/fonts/TestFontMgr.cpp",
3651        "tools/fonts/TestSVGTypeface.cpp",
3652        "tools/fonts/TestTypeface.cpp",
3653      ]
3654      deps = [ "modules/svg" ]
3655    }
3656
3657    libfuzzer_app("region_set_path") {
3658      sources = [ "fuzz/oss_fuzz/FuzzRegionSetPath.cpp" ]
3659      deps = []
3660    }
3661
3662    libfuzzer_app("textblob_deserialize") {
3663      include_dirs = [
3664        "tools",
3665        "tools/fonts",
3666      ]
3667      sources = [
3668        "fuzz/oss_fuzz/FuzzTextBlobDeserialize.cpp",
3669        "tools/Resources.cpp",
3670        "tools/fonts/TestFontMgr.cpp",
3671        "tools/fonts/TestSVGTypeface.cpp",
3672        "tools/fonts/TestTypeface.cpp",
3673      ]
3674      deps = [ "modules/svg" ]
3675    }
3676
3677    libfuzzer_app("path_deserialize") {
3678      sources = [ "fuzz/oss_fuzz/FuzzPathDeserialize.cpp" ]
3679      deps = []
3680    }
3681
3682    libfuzzer_app("image_decode") {
3683      sources = [ "fuzz/oss_fuzz/FuzzImage.cpp" ]
3684      deps = []
3685    }
3686
3687    libfuzzer_app("animated_image_decode") {
3688      sources = [ "fuzz/oss_fuzz/FuzzAnimatedImage.cpp" ]
3689      deps = []
3690    }
3691
3692    libfuzzer_app("api_create_ddl") {
3693      include_dirs = [
3694        "include",
3695        "include/gpu",
3696      ]
3697      sources = [
3698        "fuzz/FuzzCreateDDL.cpp",
3699        "fuzz/oss_fuzz/FuzzAPICreateDDL.cpp",
3700        "tools/Resources.cpp",
3701        "tools/UrlDataManager.cpp",
3702        "tools/debugger/DebugCanvas.cpp",
3703        "tools/debugger/DebugLayerManager.cpp",
3704        "tools/debugger/DrawCommand.cpp",
3705        "tools/debugger/JsonWriteBuffer.cpp",
3706        "tools/fonts/TestFontMgr.cpp",
3707        "tools/fonts/TestSVGTypeface.cpp",
3708        "tools/fonts/TestTypeface.cpp",
3709      ]
3710      deps = [
3711        "${skia_third_party_dir}/libpng",
3712        "modules/svg",
3713      ]
3714    }
3715
3716    libfuzzer_app("api_draw_functions") {
3717      sources = [
3718        "fuzz/FuzzDrawFunctions.cpp",
3719        "fuzz/oss_fuzz/FuzzDrawFunctions.cpp",
3720      ]
3721      deps = []
3722    }
3723
3724    libfuzzer_app("api_ddl_threading") {
3725      sources = [
3726        "fuzz/FuzzDDLThreading.cpp",
3727        "fuzz/oss_fuzz/FuzzDDLThreading.cpp",
3728      ]
3729      deps = []
3730    }
3731
3732    libfuzzer_app("api_gradients") {
3733      sources = [
3734        "fuzz/FuzzGradients.cpp",
3735        "fuzz/oss_fuzz/FuzzGradients.cpp",
3736      ]
3737      deps = []
3738    }
3739
3740    libfuzzer_app("api_image_filter") {
3741      include_dirs = [
3742        "tools",
3743        "tools/debugger",
3744      ]
3745      sources = [
3746        "fuzz/FuzzCanvas.cpp",
3747        "fuzz/oss_fuzz/FuzzAPIImageFilter.cpp",
3748        "tools/UrlDataManager.cpp",
3749        "tools/debugger/DebugCanvas.cpp",
3750        "tools/debugger/DebugLayerManager.cpp",
3751        "tools/debugger/DrawCommand.cpp",
3752        "tools/debugger/JsonWriteBuffer.cpp",
3753      ]
3754      deps = [ "${skia_third_party_dir}/libpng" ]
3755    }
3756
3757    libfuzzer_app("api_path_measure") {
3758      sources = [
3759        "fuzz/FuzzPathMeasure.cpp",
3760        "fuzz/oss_fuzz/FuzzPathMeasure.cpp",
3761      ]
3762      deps = []
3763    }
3764
3765    libfuzzer_app("api_pathop") {
3766      sources = [
3767        "fuzz/FuzzPathop.cpp",
3768        "fuzz/oss_fuzz/FuzzPathop.cpp",
3769      ]
3770      deps = []
3771    }
3772
3773    libfuzzer_app("api_triangulation") {
3774      sources = [
3775        "fuzz/FuzzTriangulation.cpp",
3776        "fuzz/oss_fuzz/FuzzTriangulation.cpp",
3777      ]
3778      deps = []
3779    }
3780
3781    libfuzzer_app("api_raster_n32_canvas") {
3782      include_dirs = [
3783        "tools",
3784        "tools/debugger",
3785        "tools/fonts",
3786      ]
3787      sources = [
3788        "fuzz/FuzzCanvas.cpp",
3789        "fuzz/oss_fuzz/FuzzRasterN32Canvas.cpp",
3790        "tools/Resources.cpp",
3791        "tools/UrlDataManager.cpp",
3792        "tools/debugger/DebugCanvas.cpp",
3793        "tools/debugger/DebugLayerManager.cpp",
3794        "tools/debugger/DrawCommand.cpp",
3795        "tools/debugger/JsonWriteBuffer.cpp",
3796        "tools/fonts/TestFontMgr.cpp",
3797        "tools/fonts/TestSVGTypeface.cpp",
3798        "tools/fonts/TestTypeface.cpp",
3799      ]
3800      deps = [
3801        "${skia_third_party_dir}/libpng",
3802        "modules/svg",
3803      ]
3804    }
3805
3806    libfuzzer_app("api_regionop") {
3807      sources = [
3808        "fuzz/FuzzRegionOp.cpp",
3809        "fuzz/oss_fuzz/FuzzRegionOp.cpp",
3810      ]
3811      deps = []
3812    }
3813
3814    if (skia_use_gl) {
3815      libfuzzer_app("api_mock_gpu_canvas") {
3816        include_dirs = [
3817          "tools",
3818          "tools/debugger",
3819          "tools/fonts",
3820        ]
3821        sources = [
3822          "fuzz/FuzzCanvas.cpp",
3823          "fuzz/oss_fuzz/FuzzMockGPUCanvas.cpp",
3824          "tools/LsanSuppressions.cpp",
3825          "tools/Resources.cpp",
3826          "tools/UrlDataManager.cpp",
3827          "tools/debugger/DebugCanvas.cpp",
3828          "tools/debugger/DebugLayerManager.cpp",
3829          "tools/debugger/DrawCommand.cpp",
3830          "tools/debugger/JsonWriteBuffer.cpp",
3831          "tools/fonts/TestFontMgr.cpp",
3832          "tools/fonts/TestSVGTypeface.cpp",
3833          "tools/fonts/TestTypeface.cpp",
3834        ]
3835        deps = [
3836          "${skia_third_party_dir}/libpng",
3837          "modules/svg",
3838        ]
3839      }
3840    }
3841
3842    libfuzzer_app("api_null_canvas") {
3843      include_dirs = [
3844        "tools",
3845        "tools/debugger",
3846        "tools/fonts",
3847      ]
3848      sources = [
3849        "fuzz/FuzzCanvas.cpp",
3850        "fuzz/oss_fuzz/FuzzNullCanvas.cpp",
3851        "tools/Resources.cpp",
3852        "tools/UrlDataManager.cpp",
3853        "tools/debugger/DebugCanvas.cpp",
3854        "tools/debugger/DebugLayerManager.cpp",
3855        "tools/debugger/DrawCommand.cpp",
3856        "tools/debugger/JsonWriteBuffer.cpp",
3857        "tools/fonts/TestFontMgr.cpp",
3858        "tools/fonts/TestSVGTypeface.cpp",
3859        "tools/fonts/TestTypeface.cpp",
3860      ]
3861      deps = [
3862        "${skia_third_party_dir}/libpng",
3863        "modules/svg",
3864      ]
3865    }
3866
3867    libfuzzer_app("api_skparagraph") {
3868      sources = [
3869        "fuzz/FuzzSkParagraph.cpp",
3870        "fuzz/oss_fuzz/FuzzSkParagraph.cpp",
3871        "tools/Resources.cpp",
3872      ]
3873      deps = [ "modules/skparagraph" ]
3874    }
3875
3876    libfuzzer_app("api_svg_canvas") {
3877      include_dirs = [
3878        "include",
3879        "include/svg",
3880      ]
3881      sources = [
3882        "fuzz/FuzzCanvas.cpp",
3883        "fuzz/oss_fuzz/FuzzAPISVGCanvas.cpp",
3884        "tools/Resources.cpp",
3885        "tools/UrlDataManager.cpp",
3886        "tools/debugger/DebugCanvas.cpp",
3887        "tools/debugger/DebugLayerManager.cpp",
3888        "tools/debugger/DrawCommand.cpp",
3889        "tools/debugger/JsonWriteBuffer.cpp",
3890        "tools/fonts/TestFontMgr.cpp",
3891        "tools/fonts/TestSVGTypeface.cpp",
3892        "tools/fonts/TestTypeface.cpp",
3893      ]
3894      deps = [
3895        "${skia_third_party_dir}/libpng",
3896        "modules/svg",
3897      ]
3898    }
3899
3900    libfuzzer_app("png_encoder") {
3901      sources = [
3902        "fuzz/FuzzEncoders.cpp",
3903        "fuzz/oss_fuzz/FuzzPNGEncoder.cpp",
3904      ]
3905      deps = []
3906    }
3907
3908    libfuzzer_app("jpeg_encoder") {
3909      sources = [
3910        "fuzz/FuzzEncoders.cpp",
3911        "fuzz/oss_fuzz/FuzzJPEGEncoder.cpp",
3912      ]
3913      deps = []
3914    }
3915
3916    libfuzzer_app("webp_encoder") {
3917      sources = [
3918        "fuzz/FuzzEncoders.cpp",
3919        "fuzz/oss_fuzz/FuzzWEBPEncoder.cpp",
3920      ]
3921      deps = []
3922    }
3923
3924    libfuzzer_app("skottie_json") {
3925      sources = [
3926        "modules/skottie/fuzz/FuzzSkottieJSON.cpp",
3927        "tools/Resources.cpp",
3928        "tools/fonts/TestFontMgr.cpp",
3929        "tools/fonts/TestSVGTypeface.cpp",
3930        "tools/fonts/TestTypeface.cpp",
3931      ]
3932      deps = [
3933        "modules/skottie:skottie",
3934        "modules/svg",
3935      ]
3936    }
3937
3938    libfuzzer_app("skjson") {
3939      sources = [ "fuzz/oss_fuzz/FuzzJSON.cpp" ]
3940      deps = []
3941    }
3942
3943    libfuzzer_app("api_polyutils") {
3944      sources = [
3945        "fuzz/FuzzPolyUtils.cpp",
3946        "fuzz/oss_fuzz/FuzzPolyUtils.cpp",
3947      ]
3948      deps = [ ":skia" ]
3949    }
3950
3951    libfuzzer_app("android_codec") {
3952      sources = [ "fuzz/oss_fuzz/FuzzAndroidCodec.cpp" ]
3953      deps = []
3954    }
3955
3956    libfuzzer_app("image_decode_incremental") {
3957      sources = [ "fuzz/oss_fuzz/FuzzIncrementalImage.cpp" ]
3958      deps = []
3959    }
3960
3961    libfuzzer_app("sksl2glsl") {
3962      sources = [ "fuzz/oss_fuzz/FuzzSKSL2GLSL.cpp" ]
3963      deps = []
3964    }
3965
3966    libfuzzer_app("sksl2spirv") {
3967      sources = [ "fuzz/oss_fuzz/FuzzSKSL2SPIRV.cpp" ]
3968      deps = []
3969    }
3970
3971    libfuzzer_app("sksl2metal") {
3972      sources = [ "fuzz/oss_fuzz/FuzzSKSL2Metal.cpp" ]
3973      deps = []
3974    }
3975
3976    libfuzzer_app("sksl2pipeline") {
3977      sources = [ "fuzz/oss_fuzz/FuzzSKSL2Pipeline.cpp" ]
3978      deps = []
3979    }
3980
3981    libfuzzer_app("skdescriptor_deserialize") {
3982      sources = [ "fuzz/oss_fuzz/FuzzSkDescriptorDeserialize.cpp" ]
3983      deps = []
3984    }
3985
3986    libfuzzer_app("svg_dom") {
3987      sources = [ "fuzz/oss_fuzz/FuzzSVG.cpp" ]
3988      deps = [ "modules/svg" ]
3989    }
3990
3991    libfuzzer_app("skruntimeeffect") {
3992      sources = [ "fuzz/oss_fuzz/FuzzSkRuntimeEffect.cpp" ]
3993      deps = []
3994    }
3995
3996    libfuzzer_app("skp") {
3997      sources = [ "fuzz/oss_fuzz/FuzzSKP.cpp" ]
3998      deps = []
3999    }
4000  }
4001}
4002
4003if (is_ios && skia_use_metal && skia_enable_gpu &&
4004    !skia_enable_flutter_defines) {
4005  group("minimal_ios_mtl_skia_app") {
4006    deps = [ "experimental/minimal_ios_mtl_skia_app" ]
4007  }
4008}
4009
4010if (is_ios && skia_enable_skottie && !skia_enable_flutter_defines) {
4011  group("skottie_ios") {
4012    deps = [ "tools/skottie_ios_app" ]
4013  }
4014}
4015
4016skia_executable("skia_c_api_example") {
4017  sources = [ "experimental/c-api-example/skia-c-example.c" ]
4018  include_dirs = [ "." ]
4019  deps = [ ":skia" ]
4020}
4021