xref: /aosp_15_r20/external/skia/gn/gn_to_bp.py (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1#!/usr/bin/env python3
2#
3# Copyright 2016 Google Inc.
4#
5# Use of this source code is governed by a BSD-style license that can be
6# found in the LICENSE file.
7
8# Generate Android.bp for Skia from GN configuration.
9
10from __future__ import print_function
11
12import os
13import pprint
14import shutil
15import string
16import subprocess
17import tempfile
18
19import skqp_gn_args
20import gn_to_bp_utils
21
22# First we start off with a template for Android.bp,
23# with holes for source lists and include directories.
24bp = string.Template('''// This file is autogenerated by gn_to_bp.py.
25// To make changes to this file, follow the instructions on skia.org for
26// downloading Skia and submitting changes. Modify gn_to_bp.py (or the build
27// files it uses) and submit to skia-review.googlesource.com, NOT to AOSP or
28// Android Internal. The autoroller will then create the updated Android.bp
29// and submit it to Android Internal, which will eventually merge to AOSP.
30// You can also ask a Skia engineer for help.
31
32package {
33    default_applicable_licenses: ["external_skia_license"],
34}
35
36// Added automatically by a large-scale-change that took the approach of
37// 'apply every license found to every target'. While this makes sure we respect
38// every license restriction, it may not be entirely correct.
39//
40// e.g. GPL in an MIT project might only apply to the contrib/ directory.
41//
42// Please consider splitting the single license below into multiple licenses,
43// taking care not to lose any license_kind information, and overriding the
44// default license using the 'licenses: [...]' property on targets as needed.
45//
46// For unused files, consider creating a 'fileGroup' with "//visibility:private"
47// to attach the license to, and including a comment whether the files may be
48// used in the current project.
49//
50// large-scale-change included anything that looked like it might be a license
51// text as a license_text. e.g. LICENSE, NOTICE, COPYING etc.
52//
53// Please consider removing redundant or irrelevant files from 'license_text:'.
54//
55// large-scale-change filtered out the below license kinds as false-positives:
56//   SPDX-license-identifier-CC-BY-NC
57//   SPDX-license-identifier-GPL-2.0
58//   SPDX-license-identifier-LGPL-2.1
59//   SPDX-license-identifier-OFL:by_exception_only
60// See: http://go/android-license-faq
61license {
62    name: "external_skia_license",
63    visibility: [":__subpackages__"],
64    license_kinds: [
65        "SPDX-license-identifier-Apache-2.0",
66        "SPDX-license-identifier-BSD",
67        "SPDX-license-identifier-CC0-1.0",
68        "SPDX-license-identifier-FTL",
69        "SPDX-license-identifier-MIT",
70        "legacy_unencumbered",
71    ],
72    license_text: [
73        "LICENSE",
74        "NOTICE",
75    ],
76}
77
78cc_defaults {
79    name: "skia_arch_defaults",
80    cpp_std: "gnu++17",
81    arch: {
82        arm: {
83            srcs: [],
84        },
85
86        arm64: {
87            srcs: [],
88        },
89
90        x86: {
91            srcs: [
92                $x86_srcs
93            ],
94        },
95
96        x86_64: {
97            srcs: [
98                $x86_srcs
99            ],
100        },
101    },
102
103    target: {
104      android: {
105        srcs: [
106          "src/gpu/vk/vulkanmemoryallocator/VulkanMemoryAllocatorWrapper.cpp",
107        ],
108        local_include_dirs: [
109          "src/gpu/vk/vulkanmemoryallocator",
110          "vma_android/include",
111        ],
112      },
113    },
114}
115
116cc_defaults {
117    name: "skia_defaults",
118    defaults: ["skia_arch_defaults"],
119    cflags: [
120        $cflags
121    ],
122
123    cppflags:[
124        $cflags_cc
125    ],
126
127    export_include_dirs: [
128        $export_includes
129    ],
130
131    local_include_dirs: [
132        $local_includes
133    ]
134}
135
136cc_library_static {
137    // Smaller version of Skia, without e.g. codecs, intended for use by RenderEngine.
138    name: "libskia_renderengine",
139    defaults: ["skia_defaults",
140               "skia_renderengine_deps"],
141    srcs: [
142        $renderengine_srcs
143    ],
144    local_include_dirs: [
145        "renderengine",
146    ],
147    export_include_dirs: [
148        "renderengine",
149    ],
150}
151
152cc_library_static {
153    name: "libskia",
154    host_supported: true,
155    cppflags:[
156        // Exceptions are necessary for SkRawCodec.
157        // FIXME: Should we split SkRawCodec into a separate target so the rest
158        // of Skia need not be compiled with exceptions?
159        "-fexceptions",
160    ],
161
162    srcs: [
163        $srcs
164    ],
165
166    target: {
167      android: {
168        srcs: [
169          $android_srcs
170        ],
171        local_include_dirs: [
172          "android",
173        ],
174        export_include_dirs: [
175          "android",
176        ],
177      },
178      host_linux: {
179        srcs: [
180          $linux_srcs
181        ],
182        local_include_dirs: [
183          "linux",
184        ],
185        export_include_dirs: [
186          "linux",
187        ],
188      },
189      darwin: {
190        srcs: [
191          $mac_srcs
192        ],
193        local_include_dirs: [
194          "mac",
195        ],
196        export_include_dirs: [
197          "mac",
198        ],
199      },
200      windows: {
201        enabled: true,
202        cflags: [
203          "-Wno-unknown-pragmas",
204        ],
205        srcs: [
206          $win_srcs
207        ],
208        local_include_dirs: [
209          "win",
210        ],
211        export_include_dirs: [
212          "win",
213        ],
214      },
215    },
216
217    defaults: ["skia_deps",
218               "skia_defaults",
219    ],
220}
221
222cc_defaults {
223    // Subset of the larger "skia_deps", which includes only the dependencies
224    // needed for libskia_renderengine. Note that it includes libpng and libz
225    // for the purposes of MSKP captures, but we could instead leave it up to
226    // RenderEngine to provide its own SkSerializerProcs if another client
227    // wants an even smaller version of libskia.
228    name: "skia_renderengine_deps",
229    shared_libs: [
230        "libcutils",
231        "liblog",
232        "libpng",
233        "libz",
234    ],
235    static_libs: [
236        "libarect",
237    ],
238    target: {
239      android: {
240        shared_libs: [
241            "libEGL",
242            "libGLESv2",
243            "libvulkan",
244            "libnativewindow",
245        ],
246        static_libs: [
247            "libperfetto_client_experimental",
248        ],
249        export_shared_lib_headers: [
250            "libvulkan",
251        ],
252      },
253    },
254}
255
256cc_defaults {
257    name: "skia_deps",
258    defaults: ["skia_renderengine_deps"],
259    shared_libs: [
260        "libdng_sdk",
261        "libjpeg",
262        "libpiex",
263        "libexpat",
264        "libft2",
265        "libharfbuzz_subset",
266    ],
267    static_libs: [
268        "libwebp-decode",
269        "libwebp-encode",
270        "libwuffs_mirror_release_c",
271    ],
272    cflags: [
273        "-DSK_PDF_USE_HARFBUZZ_SUBSET",
274    ],
275    target: {
276      android: {
277        shared_libs: [
278            "libheif",
279            "libmediandk", // Needed to link libcrabbyavif_ffi in some configurations.
280        ],
281        whole_static_libs: [
282            "libcrabbyavif_ffi",
283        ],
284      },
285      darwin: {
286        host_ldlibs: [
287            "-framework AppKit",
288        ],
289      },
290      windows: {
291        host_ldlibs: [
292            "-lgdi32",
293            "-loleaut32",
294            "-lole32",
295            "-lopengl32",
296            "-luuid",
297            "-lwindowscodecs",
298        ],
299      },
300    },
301}
302
303cc_defaults {
304    name: "skia_tool_deps",
305    defaults: [
306        "skia_deps",
307    ],
308    shared_libs: [
309        "libicu",
310        "libharfbuzz_ng",
311    ],
312    static_libs: [
313        "libskia",
314    ],
315    cflags: [
316        "-DSK_SHAPER_HARFBUZZ_AVAILABLE",
317        "-DSK_SHAPER_UNICODE_AVAILABLE",
318        "-DSK_UNICODE_AVAILABLE",
319        "-DSK_UNICODE_ICU_IMPLEMENTATION",
320        "-Wno-implicit-fallthrough",
321        "-Wno-unused-parameter",
322        "-Wno-unused-variable",
323    ],
324    target: {
325      windows: {
326        enabled: true,
327      },
328    },
329
330    data: [
331        "resources/**/*",
332    ],
333}
334
335cc_defaults {
336    name: "skia_gm_srcs",
337    local_include_dirs: [
338        $gm_includes
339    ],
340
341    srcs: [
342        $gm_srcs
343    ],
344}
345
346cc_defaults {
347    name: "skia_test_minus_gm_srcs",
348    local_include_dirs: [
349        $test_minus_gm_includes
350    ],
351
352    srcs: [
353        $test_minus_gm_srcs
354    ],
355}
356
357cc_library_shared {
358    name: "libskqp_jni",
359    sdk_version: "$skqp_sdk_version",
360    stl: "libc++_static",
361    compile_multilib: "both",
362
363    defaults: [
364        "skia_arch_defaults",
365    ],
366
367    cflags: [
368        $skqp_cflags
369        "-Wno-unused-parameter",
370        "-Wno-unused-variable",
371    ],
372
373    cppflags:[
374        $skqp_cflags_cc
375    ],
376
377    local_include_dirs: [
378        "skqp",
379        $skqp_includes
380    ],
381
382    export_include_dirs: [
383        "skqp",
384    ],
385
386    srcs: [
387        $skqp_srcs
388    ],
389
390    header_libs: ["jni_headers"],
391
392    shared_libs: [
393          "libandroid",
394          "libEGL",
395          "libGLESv2",
396          "liblog",
397          "libvulkan",
398          "libz",
399    ],
400    static_libs: [
401          "libexpat",
402          "libjpeg_static_ndk",
403          "libpng_ndk",
404          "libwebp-decode",
405          "libwebp-encode",
406          "libwuffs_mirror_release_c",
407    ]
408}
409
410android_test {
411    name: "CtsSkQPTestCases",
412    team: "trendy_team_android_core_graphics_stack",
413    defaults: ["cts_defaults"],
414    test_suites: [
415        "general-tests",
416        "cts",
417    ],
418
419    libs: ["android.test.runner.stubs"],
420    jni_libs: ["libskqp_jni"],
421    compile_multilib: "both",
422
423    static_libs: [
424        "android-support-design",
425        "ctstestrunner-axt",
426    ],
427    manifest: "platform_tools/android/apps/skqp/src/main/AndroidManifest.xml",
428    test_config: "platform_tools/android/apps/skqp/src/main/AndroidTest.xml",
429
430    asset_dirs: ["platform_tools/android/apps/skqp/src/main/assets", "resources"],
431    resource_dirs: ["platform_tools/android/apps/skqp/src/main/res"],
432    srcs: ["platform_tools/android/apps/skqp/src/main/java/**/*.java"],
433
434    sdk_version: "test_current",
435
436}
437''')
438
439# We'll run GN to get the main source lists and include directories for Skia.
440def generate_args(target_os, enable_gpu, renderengine = False):
441  d = {
442    'is_official_build':                    'true',
443
444    # gn_to_bp_utils' GetArchSources will take care of architecture-specific
445    # files.
446    'target_cpu':                           '"none"',
447
448    # Use the custom FontMgr, as the framework will handle fonts.
449    'skia_enable_fontmgr_custom_directory': 'false',
450    'skia_enable_fontmgr_custom_embedded':  'false',
451    'skia_enable_fontmgr_android':          'false',
452    'skia_enable_fontmgr_win':              'false',
453    'skia_enable_fontmgr_win_gdi':          'false',
454    'skia_use_fonthost_mac':                'false',
455
456    'skia_use_system_harfbuzz':             'false',
457    'skia_pdf_subset_harfbuzz':             'true',
458
459    # enable features used in skia_nanobench
460    'skia_tools_require_resources':         'true',
461
462    'skia_use_fontconfig':                  'false',
463    'skia_include_multiframe_procs':        'true',
464
465    # Tracing-related flags:
466    'skia_disable_tracing':                 'false',
467    # The two Perfetto integrations are currently mutually exclusive due to
468    # complexity.
469    'skia_use_perfetto':                    'false',
470  }
471  d['target_os'] = target_os
472  if target_os == '"android"':
473    d['skia_enable_tools'] = 'true'
474    # Only enable for actual Android framework builds targeting Android devices.
475    # (E.g. disabled for host builds and SkQP)
476    d['skia_android_framework_use_perfetto'] = 'true'
477
478  if enable_gpu:
479    d['skia_use_vulkan']    = 'true'
480    d['skia_enable_ganesh'] = 'true'
481    if renderengine:
482      d['skia_enable_graphite'] = 'true'
483  else:
484    d['skia_use_vulkan']      = 'false'
485    d['skia_enable_ganesh']   = 'false'
486    d['skia_enable_graphite'] = 'false'
487
488  if target_os == '"win"':
489    # The Android Windows build system does not provide FontSub.h
490    d['skia_use_xps'] = 'false'
491
492    # BUILDCONFIG.gn expects these to be set when building for Windows, but
493    # we're just creating Android.bp, so we don't need them. Populate with
494    # some placeholder values.
495    d['win_vc'] = '"placeholder_version"'
496    d['win_sdk_version'] = '"placeholder_version"'
497    d['win_toolchain_version'] = '"placeholder_version"'
498
499  if target_os == '"android"' and not renderengine:
500    d['skia_use_libheif']  = 'true'
501    d['skia_use_crabbyavif'] = 'true'
502    d['skia_use_jpeg_gainmaps'] = 'true'
503  else:
504    d['skia_use_libheif']  = 'false'
505    d['skia_use_crabbyavif'] = 'false'
506
507  if renderengine:
508    d['skia_use_libpng_decode'] = 'false'
509    d['skia_use_libjpeg_turbo_decode'] = 'false'
510    d['skia_use_libjpeg_turbo_encode'] = 'false'
511    d['skia_use_libwebp_decode'] = 'false'
512    d['skia_use_libwebp_encode'] = 'false'
513    d['skia_use_wuffs'] = 'false'
514    d['skia_enable_pdf'] = 'false'
515    d['skia_use_freetype'] = 'false'
516    d['skia_use_fixed_gamma_text'] = 'false'
517    d['skia_use_expat'] = 'false'
518    d['skia_enable_fontmgr_custom_empty'] = 'false'
519  else:
520    d['skia_enable_android_utils'] = 'true'
521    d['skia_use_freetype'] = 'true'
522    d['skia_use_fixed_gamma_text'] = 'true'
523    d['skia_enable_fontmgr_custom_empty'] = 'true'
524    d['skia_use_wuffs'] = 'true'
525
526  return d
527
528gn_args       = generate_args('"android"', True)
529gn_args_linux = generate_args('"linux"',   False)
530gn_args_mac   = generate_args('"mac"',     False)
531gn_args_win   = generate_args('"win"',     False)
532gn_args_renderengine  = generate_args('"android"', True, True)
533
534js = gn_to_bp_utils.GenerateJSONFromGN(gn_args)
535
536def strip_slashes(lst):
537  return {str(p.lstrip('/')) for p in lst}
538
539android_srcs    = strip_slashes(js['targets']['//:skia']['sources'])
540cflags          = strip_slashes(js['targets']['//:skia']['cflags'])
541cflags_cc       = strip_slashes(js['targets']['//:skia']['cflags_cc'])
542local_includes  = strip_slashes(js['targets']['//:skia']['include_dirs'])
543export_includes = strip_slashes(js['targets']['//:public']['include_dirs'])
544
545gm_srcs         = strip_slashes(js['targets']['//:gm']['sources'])
546gm_includes     = strip_slashes(js['targets']['//:gm']['include_dirs'])
547
548test_srcs         = strip_slashes(js['targets']['//:tests']['sources'])
549test_includes     = strip_slashes(js['targets']['//:tests']['include_dirs'])
550
551dm_srcs         = strip_slashes(js['targets']['//:dm']['sources'])
552dm_includes     = strip_slashes(js['targets']['//:dm']['include_dirs'])
553
554nanobench_target = js['targets']['//:nanobench']
555nanobench_srcs     = strip_slashes(nanobench_target['sources'])
556nanobench_includes = strip_slashes(nanobench_target['include_dirs'])
557
558
559gn_to_bp_utils.GrabDependentValues(js, '//:gm', 'sources', gm_srcs, '//:skia')
560gn_to_bp_utils.GrabDependentValues(js, '//:tests', 'sources', test_srcs, '//:skia')
561gn_to_bp_utils.GrabDependentValues(js, '//:dm', 'sources',
562                                   dm_srcs, ['//:skia', '//:gm', '//:tests'])
563gn_to_bp_utils.GrabDependentValues(js, '//:nanobench', 'sources',
564                                   nanobench_srcs, ['//:skia', '//:gm'])
565
566# skcms is a little special, kind of a second-party library.
567local_includes.add("modules/skcms")
568gm_includes   .add("modules/skcms")
569
570# Android's build (soong) will break if we list anything other than these file
571# types in `srcs` (e.g. all header extensions must be excluded).
572def strip_non_srcs(sources):
573  src_extensions = ['.s', '.S', '.c', '.cpp', '.cc', '.cxx', '.mm']
574  return {s for s in sources if os.path.splitext(s)[1] in src_extensions}
575
576VMA_DEP = "//src/gpu/vk/vulkanmemoryallocator:vulkanmemoryallocator"
577
578gn_to_bp_utils.GrabDependentValues(js, '//:skia', 'sources', android_srcs, VMA_DEP)
579android_srcs    = strip_non_srcs(android_srcs)
580
581js_linux        = gn_to_bp_utils.GenerateJSONFromGN(gn_args_linux)
582linux_srcs      = strip_slashes(js_linux['targets']['//:skia']['sources'])
583gn_to_bp_utils.GrabDependentValues(js_linux, '//:skia', 'sources', linux_srcs,
584                                   None)
585linux_srcs      = strip_non_srcs(linux_srcs)
586
587js_mac          = gn_to_bp_utils.GenerateJSONFromGN(gn_args_mac)
588mac_srcs        = strip_slashes(js_mac['targets']['//:skia']['sources'])
589gn_to_bp_utils.GrabDependentValues(js_mac, '//:skia', 'sources', mac_srcs,
590                                   None)
591mac_srcs        = strip_non_srcs(mac_srcs)
592
593js_win          = gn_to_bp_utils.GenerateJSONFromGN(gn_args_win)
594win_srcs        = strip_slashes(js_win['targets']['//:skia']['sources'])
595gn_to_bp_utils.GrabDependentValues(js_win, '//:skia', 'sources', win_srcs,
596                                   None)
597win_srcs        = strip_non_srcs(win_srcs)
598
599srcs = android_srcs.intersection(linux_srcs).intersection(mac_srcs)
600srcs = srcs.intersection(win_srcs)
601
602android_srcs    = android_srcs.difference(srcs)
603linux_srcs      =   linux_srcs.difference(srcs)
604mac_srcs        =     mac_srcs.difference(srcs)
605win_srcs        =     win_srcs.difference(srcs)
606
607gm_srcs         = strip_non_srcs(gm_srcs)
608test_srcs       = strip_non_srcs(test_srcs)
609dm_srcs         = strip_non_srcs(dm_srcs).difference(gm_srcs).difference(test_srcs)
610nanobench_srcs  = strip_non_srcs(nanobench_srcs).difference(gm_srcs)
611
612test_minus_gm_includes = test_includes.difference(gm_includes)
613test_minus_gm_srcs = test_srcs.difference(gm_srcs)
614
615cflags = gn_to_bp_utils.CleanupCFlags(cflags)
616cflags_cc = gn_to_bp_utils.CleanupCCFlags(cflags_cc)
617
618# Execute GN for specialized RenderEngine target
619js_renderengine   = gn_to_bp_utils.GenerateJSONFromGN(gn_args_renderengine)
620renderengine_srcs = strip_slashes(
621    js_renderengine['targets']['//:skia']['sources'])
622gn_to_bp_utils.GrabDependentValues(js_renderengine, '//:skia', 'sources',
623                                   renderengine_srcs, VMA_DEP)
624renderengine_srcs = strip_non_srcs(renderengine_srcs)
625
626# Execute GN for specialized SkQP target
627skqp_sdk_version = 26
628js_skqp = gn_to_bp_utils.GenerateJSONFromGN(skqp_gn_args.GetGNArgs(api_level=skqp_sdk_version,
629                                                                   debug=False,
630                                                                   is_android_bp=True))
631skqp_srcs      = strip_slashes(js_skqp['targets']['//:libskqp_jni']['sources'])
632skqp_includes  = strip_slashes(js_skqp['targets']['//:libskqp_jni']['include_dirs'])
633skqp_cflags    = strip_slashes(js_skqp['targets']['//:libskqp_jni']['cflags'])
634skqp_cflags_cc = strip_slashes(js_skqp['targets']['//:libskqp_jni']['cflags_cc'])
635skqp_defines   = strip_slashes(js_skqp['targets']['//:libskqp_jni']['defines'])
636
637skqp_includes.update(strip_slashes(js_skqp['targets']['//:public']['include_dirs']))
638
639gn_to_bp_utils.GrabDependentValues(js_skqp, '//:libskqp_jni', 'sources',
640                                   skqp_srcs, VMA_DEP)
641# We are exlcuding gpu here to get rid of the includes that are being added from
642# vulkanmemoryallocator. This does not seem to remove any other incldues from gpu so things
643# should work out fine for now
644gn_to_bp_utils.GrabDependentValues(js_skqp, '//:libskqp_jni', 'include_dirs',
645                                   skqp_includes, ['//:gif', '//:gpu'])
646gn_to_bp_utils.GrabDependentValues(js_skqp, '//:libskqp_jni', 'cflags',
647                                   skqp_cflags, None)
648gn_to_bp_utils.GrabDependentValues(js_skqp, '//:libskqp_jni', 'cflags_cc',
649                                   skqp_cflags_cc, None)
650gn_to_bp_utils.GrabDependentValues(js_skqp, '//:libskqp_jni', 'defines',
651                                   skqp_defines, None)
652
653skqp_defines.add("GPU_TEST_UTILS=1")
654skqp_defines.add("SK_ALLOW_STATIC_GLOBAL_INITIALIZERS=1")
655skqp_defines.add("SK_BUILD_FOR_SKQP")
656skqp_defines.add("SK_ENABLE_DUMP_GPU")
657skqp_defines.remove("SK_USE_INTERNAL_VULKAN_HEADERS")
658skqp_defines.remove("SK_USE_PERFETTO")
659
660skqp_srcs = strip_non_srcs(skqp_srcs)
661skqp_cflags = gn_to_bp_utils.CleanupCFlags(skqp_cflags)
662skqp_cflags_cc = gn_to_bp_utils.CleanupCCFlags(skqp_cflags_cc)
663
664here = os.path.dirname(__file__)
665defs = gn_to_bp_utils.GetArchSources(os.path.join(here, 'opts.gni'))
666
667def get_defines(json):
668  return {str(d) for d in json['targets']['//:skia']['defines']}
669android_defines      = get_defines(js)
670linux_defines        = get_defines(js_linux)
671mac_defines          = get_defines(js_mac)
672win_defines          = get_defines(js_win)
673renderengine_defines = get_defines(js_renderengine)
674renderengine_defines.add('SK_IN_RENDERENGINE')
675
676def mkdir_if_not_exists(path):
677  if not os.path.exists(path):
678    os.makedirs(path)
679mkdir_if_not_exists('android/include/config/')
680mkdir_if_not_exists('linux/include/config/')
681mkdir_if_not_exists('mac/include/config/')
682mkdir_if_not_exists('win/include/config/')
683mkdir_if_not_exists('renderengine/include/config/')
684mkdir_if_not_exists('skqp/include/config/')
685mkdir_if_not_exists('vma_android/include')
686
687shutil.copy('third_party/externals/vulkanmemoryallocator/include/vk_mem_alloc.h',
688            'vma_android/include')
689shutil.copy('third_party/externals/vulkanmemoryallocator/LICENSE.txt', 'vma_android/')
690
691platforms = { 'IOS', 'MAC', 'WIN', 'ANDROID', 'UNIX' }
692
693def disallow_platforms(config, desired):
694  with open(config, 'a') as f:
695    p = sorted(platforms.difference({ desired }))
696    s = '#if '
697    for i in range(len(p)):
698      s = s + 'defined(SK_BUILD_FOR_%s)' % p[i]
699      if i < len(p) - 1:
700        s += ' || '
701        if i % 2 == 1:
702          s += '\\\n    '
703    print(s, file=f)
704    print('    #error "Only SK_BUILD_FOR_%s should be defined!"' % desired, file=f)
705    print('#endif', file=f)
706
707def append_to_file(config, s):
708  with open(config, 'a') as f:
709    print(s, file=f)
710
711def write_android_config(config_path, defines, isNDKConfig = False):
712  gn_to_bp_utils.WriteUserConfig(config_path, defines)
713  append_to_file(config_path, '''
714#ifndef SK_BUILD_FOR_ANDROID
715    #error "SK_BUILD_FOR_ANDROID must be defined!"
716#endif''')
717  disallow_platforms(config_path, 'ANDROID')
718
719  if isNDKConfig:
720    append_to_file(config_path, '''
721#undef SK_BUILD_FOR_ANDROID_FRAMEWORK''')
722
723write_android_config('android/include/config/SkUserConfig.h', android_defines)
724write_android_config('renderengine/include/config/SkUserConfig.h', renderengine_defines)
725write_android_config('skqp/include/config/SkUserConfig.h', skqp_defines, True)
726
727def write_config(config_path, defines, platform):
728  gn_to_bp_utils.WriteUserConfig(config_path, defines)
729  append_to_file(config_path, '''
730// Correct SK_BUILD_FOR flags that may have been set by
731// SkTypes.h/Android.bp
732#ifndef SK_BUILD_FOR_%s
733    #define SK_BUILD_FOR_%s
734#endif
735#ifdef SK_BUILD_FOR_ANDROID
736    #undef SK_BUILD_FOR_ANDROID
737#endif''' % (platform, platform))
738  disallow_platforms(config_path, platform)
739
740write_config('linux/include/config/SkUserConfig.h', linux_defines, 'UNIX')
741write_config('mac/include/config/SkUserConfig.h',   mac_defines, 'MAC')
742write_config('win/include/config/SkUserConfig.h',   win_defines, 'WIN')
743
744# Turn a list of strings into the style bpfmt outputs.
745def bpfmt(indent, lst, sort=True):
746  if sort:
747    lst = sorted(lst)
748  return ('\n' + ' '*indent).join('"%s",' % v for v in lst)
749
750# OK!  We have everything to fill in Android.bp...
751with open('Android.bp', 'w') as Android_bp:
752  print(bp.substitute({
753    'export_includes': bpfmt(8, export_includes),
754    'local_includes':  bpfmt(8, local_includes),
755    'srcs':            bpfmt(8, srcs),
756    'cflags':          bpfmt(8, cflags, False),
757    'cflags_cc':       bpfmt(8, cflags_cc),
758
759    'x86_srcs':      bpfmt(16, strip_non_srcs(defs['hsw'] +
760                                             defs['skx'])),
761
762    'gm_includes'       : bpfmt(8, gm_includes),
763    'gm_srcs'           : bpfmt(8, gm_srcs),
764
765    'test_minus_gm_includes' : bpfmt(8, test_minus_gm_includes),
766    'test_minus_gm_srcs'     : bpfmt(8, test_minus_gm_srcs),
767
768    'dm_includes'       : bpfmt(8, dm_includes),
769    'dm_srcs'           : bpfmt(8, dm_srcs),
770
771    'nanobench_includes'    : bpfmt(8, nanobench_includes),
772    'nanobench_srcs'        : bpfmt(8, nanobench_srcs),
773
774    'skqp_sdk_version': skqp_sdk_version,
775    'skqp_includes':    bpfmt(8, skqp_includes),
776    'skqp_srcs':        bpfmt(8, skqp_srcs),
777    'skqp_cflags':      bpfmt(8, skqp_cflags, False),
778    'skqp_cflags_cc':   bpfmt(8, skqp_cflags_cc),
779
780    'android_srcs':  bpfmt(10, android_srcs),
781    'linux_srcs':    bpfmt(10, linux_srcs),
782    'mac_srcs':      bpfmt(10, mac_srcs),
783    'win_srcs':      bpfmt(10, win_srcs),
784
785    'renderengine_srcs': bpfmt(8, renderengine_srcs),
786  }), file=Android_bp)
787