1#!/usr/bin/env python
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
10import argparse
11import json
12import os
13import pprint
14import string
15import subprocess
16import sys
17import tempfile
18
19root_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)),
20                        os.pardir, os.pardir)
21skia_gn_dir = os.path.join(root_dir, 'gn')
22sys.path.insert(0, skia_gn_dir)
23
24import gn_to_bp_utils
25
26from skqp_gn_args import SkqpGnArgs
27
28# First we start off with a template for Android.bp,
29# with holes for source lists and include directories.
30bp = string.Template('''// This file is autogenerated by tools/skqp/gn_to_bp.py.
31
32cc_library_shared {
33    name: "libskqp_app",
34    sdk_version: "26",
35    stl: "libc++_static",
36    compile_multilib: "both",
37
38    cflags: [
39        $cflags
40        "-Wno-unused-parameter",
41        "-Wno-unused-variable",
42    ],
43
44    cppflags:[
45        $cflags_cc
46    ],
47
48    local_include_dirs: [
49        $local_includes
50    ],
51
52    srcs: [
53        "third_party/vulkanmemoryallocator/GrVulkanMemoryAllocator.cpp",
54        $srcs
55    ],
56
57    arch: {
58        arm: {
59            srcs: [
60                $arm_srcs
61            ],
62
63            neon: {
64                srcs: [
65                    $arm_neon_srcs
66                ],
67            },
68        },
69
70        arm64: {
71            srcs: [
72                $arm64_srcs
73            ],
74        },
75
76        mips: {
77            srcs: [
78                $none_srcs
79            ],
80        },
81
82        mips64: {
83            srcs: [
84                $none_srcs
85            ],
86        },
87
88        x86: {
89            srcs: [
90                $x86_srcs
91            ],
92        },
93
94        x86_64: {
95            srcs: [
96                $x86_srcs
97            ],
98        },
99    },
100
101    shared_libs: [
102          "libandroid",
103          "libEGL",
104          "libGLESv2",
105          "liblog",
106          "libvulkan",
107          "libz",
108    ],
109    static_libs: [
110          "libexpat",
111          "libjpeg_static_ndk",
112          "libpng_ndk",
113          "libwebp-decode",
114          "libwebp-encode",
115    ]
116}''')
117
118# We'll run GN to get the main source lists and include directories for Skia.
119gn_args = {
120  'target_cpu': '"none"',
121  'target_os':  '"android"',
122
123  # setup skqp
124  'is_debug':   'false',
125  'ndk_api':    '26',
126
127  # specify that the Android.bp will supply the necessary components
128  'skia_use_system_expat':         'true', # removed this when gn is fixed
129  'skia_use_system_libpng':        'true',
130  'skia_use_system_libwebp':       'true',
131  'skia_use_system_libjpeg_turbo': 'true',
132  'skia_use_system_zlib':          'true',
133}
134
135for k, v in SkqpGnArgs.iteritems():
136    gn_args[k] = v
137
138js = gn_to_bp_utils.GenerateJSONFromGN(gn_args)
139
140def strip_slashes(lst):
141  return {str(p.lstrip('/')) for p in lst}
142
143srcs            = strip_slashes(js['targets']['//:libskqp_app']['sources'])
144cflags          = strip_slashes(js['targets']['//:libskqp_app']['cflags'])
145cflags_cc       = strip_slashes(js['targets']['//:libskqp_app']['cflags_cc'])
146local_includes  = strip_slashes(js['targets']['//:libskqp_app']['include_dirs'])
147defines      = {str(d) for d in js['targets']['//:libskqp_app']['defines']}
148
149defines.update(["SK_ENABLE_DUMP_GPU", "SK_BUILD_FOR_SKQP"])
150cflags_cc.update(['-Wno-extra-semi-stmt'])
151
152# Android does not want -Weverything set, it blocks toolchain updates.
153assert '-Weverything' not in cflags
154
155gn_to_bp_utils.GrabDependentValues(js, '//:libskqp_app', 'sources', srcs, None)
156gn_to_bp_utils.GrabDependentValues(js, '//:libskqp_app', 'include_dirs',
157                                   local_includes, 'freetype')
158gn_to_bp_utils.GrabDependentValues(js, '//:libskqp_app', 'defines',
159                                   defines, None)
160
161# No need to list headers or other extra flags.
162srcs = {s for s in srcs           if not s.endswith('.h')}
163cflags = gn_to_bp_utils.CleanupCFlags(cflags)
164cflags_cc = gn_to_bp_utils.CleanupCCFlags(cflags_cc)
165
166# We need to add the include path to the vulkan defines and header file set in
167# then skia_vulkan_header gn arg that is used for framework builds.
168local_includes.add("platform_tools/android/vulkan")
169
170# Get architecture specific source files
171defs = gn_to_bp_utils.GetArchSources(os.path.join(skia_gn_dir, 'opts.gni'))
172
173# Add source file until fix lands in
174# https://skia-review.googlesource.com/c/skia/+/101820
175srcs.add("src/ports/SkFontMgr_empty_factory.cpp")
176
177# Turn a list of strings into the style bpfmt outputs.
178def bpfmt(indent, lst, sort=True):
179  if sort:
180    lst = sorted(lst)
181  return ('\n' + ' '*indent).join('"%s",' % v for v in lst)
182
183# Most defines go into SkUserConfig.h, where they're seen by Skia and its users.
184gn_to_bp_utils.WriteUserConfig('include/config/SkUserConfig.h', defines)
185
186# OK!  We have everything to fill in Android.bp...
187with open('Android.bp', 'w') as f:
188  print >>f, bp.substitute({
189    'local_includes': bpfmt(8, local_includes),
190    'srcs':           bpfmt(8, srcs),
191    'cflags':         bpfmt(8, cflags, False),
192    'cflags_cc':      bpfmt(8, cflags_cc),
193
194    'arm_srcs':       bpfmt(16, defs['armv7']),
195    'arm_neon_srcs':  bpfmt(20, defs['neon']),
196    'arm64_srcs':     bpfmt(16, defs['arm64'] +
197                                defs['crc32']),
198    'none_srcs':      bpfmt(16, defs['none']),
199    'x86_srcs':       bpfmt(16, defs['sse2'] +
200                                defs['ssse3'] +
201                                defs['sse41'] +
202                                defs['sse42'] +
203                                defs['avx'] +
204                                defs['hsw']),
205  })
206
207