blob: f0a28a8941246f866850fe9d1080f2cd8face42a [file] [log] [blame]
Mike Klein308b5ac2016-12-06 16:03:52 -05001#!/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 json
11import os
12import pprint
13import string
14import subprocess
Mike Klein308b5ac2016-12-06 16:03:52 -050015import tempfile
16
17# First we start off with a template for Android.bp,
18# with holes for source lists and include directories.
19bp = string.Template('''// This file is autogenerated by gn_to_bp.py.
20
Derek Sollenberger5a932162017-09-21 14:25:14 -040021cc_library_static {
Mike Kleinee43f6f2016-12-12 14:09:38 -050022 name: "libskia",
23 cflags: [
24 "-fexceptions",
Derek Sollenberger5a932162017-09-21 14:25:14 -040025 "-fvisibility=hidden",
Mike Kleinee43f6f2016-12-12 14:09:38 -050026 "-Wno-unused-parameter",
27 "-U_FORTIFY_SOURCE",
28 "-D_FORTIFY_SOURCE=1",
Derek Sollenberger5a932162017-09-21 14:25:14 -040029 "-DSKIA_DLL",
Mike Kleinee43f6f2016-12-12 14:09:38 -050030 "-DSKIA_IMPLEMENTATION=1",
Derek Sollenberger488f0d62017-03-03 15:48:33 -050031 "-DATRACE_TAG=ATRACE_TAG_VIEW",
Mike Kleinee43f6f2016-12-12 14:09:38 -050032 ],
Mike Klein308b5ac2016-12-06 16:03:52 -050033
Mike Kleinee43f6f2016-12-12 14:09:38 -050034 export_include_dirs: [
35 $export_includes
36 ],
Mike Klein27eb22b2016-12-07 12:27:56 -050037
Mike Kleinee43f6f2016-12-12 14:09:38 -050038 local_include_dirs: [
39 $local_includes
40 ],
Mike Klein27eb22b2016-12-07 12:27:56 -050041
Mike Kleinee43f6f2016-12-12 14:09:38 -050042 srcs: [
43 $srcs
44 ],
Mike Klein308b5ac2016-12-06 16:03:52 -050045
Mike Kleinee43f6f2016-12-12 14:09:38 -050046 arch: {
47 arm: {
48 srcs: [
49 $arm_srcs
50 ],
Mike Klein27eb22b2016-12-07 12:27:56 -050051
Leon Scroggins IIIf7332d32017-08-10 09:09:54 -040052 neon: {
Mike Kleinee43f6f2016-12-12 14:09:38 -050053 srcs: [
54 $arm_neon_srcs
55 ],
56 },
57 },
58
59 arm64: {
60 srcs: [
61 $arm64_srcs
62 ],
63 },
64
65 mips: {
66 srcs: [
Mike Klein40a82bd2016-12-20 17:34:29 -050067 $none_srcs
Mike Kleinee43f6f2016-12-12 14:09:38 -050068 ],
69 },
70
71 mips64: {
72 srcs: [
Mike Klein40a82bd2016-12-20 17:34:29 -050073 $none_srcs
Mike Kleinee43f6f2016-12-12 14:09:38 -050074 ],
75 },
76
77 x86: {
78 srcs: [
79 $x86_srcs
80 ],
81 },
82
83 x86_64: {
84 srcs: [
85 $x86_srcs
86 ],
87 },
Mike Klein308b5ac2016-12-06 16:03:52 -050088 },
Mike Klein27eb22b2016-12-07 12:27:56 -050089
Derek Sollenberger5a932162017-09-21 14:25:14 -040090 defaults: ["skia_deps"],
91}
92
93cc_defaults {
94 name: "skia_deps",
Mike Kleinee43f6f2016-12-12 14:09:38 -050095 shared_libs: [
96 "libEGL",
97 "libGLESv2",
98 "libdng_sdk",
99 "libexpat",
100 "libft2",
Leon Scroggins III04be2b52017-08-17 15:13:20 -0400101 "libheif",
Mike Kleinee43f6f2016-12-12 14:09:38 -0500102 "libicui18n",
103 "libicuuc",
104 "libjpeg",
105 "liblog",
106 "libpiex",
107 "libpng",
108 "libvulkan",
109 "libz",
Derek Sollenberger488f0d62017-03-03 15:48:33 -0500110 "libcutils",
Stan Iliev7e910df2017-06-02 10:29:21 -0400111 "libnativewindow",
Mike Kleinee43f6f2016-12-12 14:09:38 -0500112 ],
113 static_libs: [
Matt Saretta3091092017-02-20 12:50:52 -0500114 "libarect",
Mike Kleinee43f6f2016-12-12 14:09:38 -0500115 "libsfntly",
116 "libwebp-decode",
117 "libwebp-encode",
118 ],
Derek Sollenberger5a932162017-09-21 14:25:14 -0400119 group_static_libs: true,
120}
121
122cc_defaults {
123 name: "skia_tool_deps",
124 defaults: [
125 "skia_deps"
126 ],
127 static_libs: [
128 "libjsoncpp",
129 "libskia",
130 ],
131 cflags: [
132 "-Wno-unused-parameter"
133 ],
Leon Scroggins III6ccd2ca2017-01-26 17:21:27 -0500134}
135
136cc_test {
137 name: "skia_dm",
138
Derek Sollenberger5a932162017-09-21 14:25:14 -0400139 defaults: [
140 "skia_tool_deps"
Leon Scroggins III6ccd2ca2017-01-26 17:21:27 -0500141 ],
142
143 local_include_dirs: [
144 $dm_includes
145 ],
146
147 srcs: [
148 $dm_srcs
149 ],
Leon Scroggins III6ccd2ca2017-01-26 17:21:27 -0500150}
151
152cc_test {
153 name: "skia_nanobench",
154
Derek Sollenberger5a932162017-09-21 14:25:14 -0400155 defaults: [
156 "skia_tool_deps"
Leon Scroggins III6ccd2ca2017-01-26 17:21:27 -0500157 ],
158
159 local_include_dirs: [
160 $nanobench_includes
161 ],
162
163 srcs: [
164 $nanobench_srcs
165 ],
Mike Kleinee43f6f2016-12-12 14:09:38 -0500166}''')
Mike Klein308b5ac2016-12-06 16:03:52 -0500167
168# We'll run GN to get the main source lists and include directories for Skia.
169gn_args = {
Mike Kleine459afd2017-03-03 09:21:30 -0500170 'is_official_build': 'true',
Mike Kleine459afd2017-03-03 09:21:30 -0500171 'skia_enable_tools': 'true',
Leon Scroggins III04be2b52017-08-17 15:13:20 -0400172 'skia_use_libheif': 'true',
Mike Kleine459afd2017-03-03 09:21:30 -0500173 'skia_use_vulkan': 'true',
174 'target_cpu': '"none"',
175 'target_os': '"android"',
Mike Klein308b5ac2016-12-06 16:03:52 -0500176}
177gn_args = ' '.join(sorted('%s=%s' % (k,v) for (k,v) in gn_args.iteritems()))
178
179tmp = tempfile.mkdtemp()
180subprocess.check_call(['gn', 'gen', tmp, '--args=%s' % gn_args, '--ide=json'])
181
182js = json.load(open(os.path.join(tmp, 'project.json')))
183
184def strip_slashes(lst):
Ben Wagnere1275232017-02-23 18:00:06 -0500185 return {str(p.lstrip('/')) for p in lst}
Mike Klein27eb22b2016-12-07 12:27:56 -0500186
Mike Klein308b5ac2016-12-06 16:03:52 -0500187srcs = strip_slashes(js['targets']['//:skia']['sources'])
188local_includes = strip_slashes(js['targets']['//:skia']['include_dirs'])
189export_includes = strip_slashes(js['targets']['//:public']['include_dirs'])
190
Leon Scroggins III6ccd2ca2017-01-26 17:21:27 -0500191dm_srcs = strip_slashes(js['targets']['//:dm']['sources'])
192dm_includes = strip_slashes(js['targets']['//:dm']['include_dirs'])
193
194nanobench_target = js['targets']['//:nanobench']
195nanobench_srcs = strip_slashes(nanobench_target['sources'])
196nanobench_includes = strip_slashes(nanobench_target['include_dirs'])
197
198def GrabDependentSrcs(name, srcs_to_extend, exclude):
199 # Grab the sources from other targets that $name depends on (e.g. optional
200 # Skia components, gms, tests, etc).
201 for dep in js['targets'][name]['deps']:
202 if 'third_party' in dep:
203 continue # We've handled all third-party DEPS as static or shared_libs.
204 if 'none' in dep:
205 continue # We'll handle all cpu-specific sources manually later.
206 if exclude and exclude in dep:
207 continue
Ben Wagnere1275232017-02-23 18:00:06 -0500208 srcs_to_extend.update(strip_slashes(js['targets'][dep].get('sources', [])))
209 GrabDependentSrcs(dep, srcs_to_extend, exclude)
Leon Scroggins III6ccd2ca2017-01-26 17:21:27 -0500210
211GrabDependentSrcs('//:skia', srcs, None)
212GrabDependentSrcs('//:dm', dm_srcs, 'skia')
213GrabDependentSrcs('//:nanobench', nanobench_srcs, 'skia')
Mike Klein27eb22b2016-12-07 12:27:56 -0500214
215# No need to list headers.
Ben Wagnere1275232017-02-23 18:00:06 -0500216srcs = {s for s in srcs if not s.endswith('.h')}
217dm_srcs = {s for s in dm_srcs if not s.endswith('.h')}
218nanobench_srcs = {s for s in nanobench_srcs if not s.endswith('.h')}
Mike Klein27eb22b2016-12-07 12:27:56 -0500219
Mike Klein308b5ac2016-12-06 16:03:52 -0500220# Most defines go into SkUserConfig.h, where they're seen by Skia and its users.
Mike Klein308b5ac2016-12-06 16:03:52 -0500221defines = [str(d) for d in js['targets']['//:skia']['defines']]
Mike Kleine459afd2017-03-03 09:21:30 -0500222defines.remove('NDEBUG') # Let the Android build control this.
Mike Klein308b5ac2016-12-06 16:03:52 -0500223defines.remove('SKIA_IMPLEMENTATION=1') # Only libskia should have this define.
Mike Klein308b5ac2016-12-06 16:03:52 -0500224
225# For architecture specific files, it's easier to just read the same source
226# that GN does (opts.gni) rather than re-run GN once for each architecture.
227
228# This .gni file we want to read is close enough to Python syntax
229# that we can use execfile() if we supply definitions for GN builtins.
Mike Klein308b5ac2016-12-06 16:03:52 -0500230
231def get_path_info(path, kind):
232 assert kind == "abspath"
233 # While we want absolute paths in GN, relative paths work best here.
234 return path
235
236builtins = { 'get_path_info': get_path_info }
237defs = {}
Leon Scroggins III4f8a4672016-12-19 09:32:21 -0500238here = os.path.dirname(__file__)
Mike Klein308b5ac2016-12-06 16:03:52 -0500239execfile(os.path.join(here, 'opts.gni'), builtins, defs)
Mike Klein308b5ac2016-12-06 16:03:52 -0500240
Mike Klein27eb22b2016-12-07 12:27:56 -0500241# Turn paths from opts.gni into paths relative to external/skia.
Mike Klein308b5ac2016-12-06 16:03:52 -0500242def scrub(lst):
243 # Perform any string substitutions.
244 for var in defs:
245 if type(defs[var]) is str:
246 lst = [ p.replace('$'+var, defs[var]) for p in lst ]
247 # Relativize paths to top-level skia/ directory.
248 return [os.path.relpath(p, '..') for p in lst]
249
Mike Kleinee43f6f2016-12-12 14:09:38 -0500250# Turn a list of strings into the style bpfmt outputs.
Leon Scroggins III6ccd2ca2017-01-26 17:21:27 -0500251def bpfmt(indent, lst, sort=True):
252 if sort:
253 lst = sorted(lst)
254 return ('\n' + ' '*indent).join('"%s",' % v for v in lst)
Mike Klein308b5ac2016-12-06 16:03:52 -0500255
256# OK! We have everything to fill in Android.bp...
257with open('Android.bp', 'w') as f:
258 print >>f, bp.substitute({
Mike Kleinee43f6f2016-12-12 14:09:38 -0500259 'export_includes': bpfmt(8, export_includes),
260 'local_includes': bpfmt(8, local_includes),
261 'srcs': bpfmt(8, srcs),
Mike Klein308b5ac2016-12-06 16:03:52 -0500262
Mike Kleinee43f6f2016-12-12 14:09:38 -0500263 'arm_srcs': bpfmt(16, scrub(defs['armv7'])),
264 'arm_neon_srcs': bpfmt(20, scrub(defs['neon'])),
265 'arm64_srcs': bpfmt(16, scrub(defs['arm64'] +
266 defs['crc32'])),
Mike Klein40a82bd2016-12-20 17:34:29 -0500267 'none_srcs': bpfmt(16, scrub(defs['none'])),
Mike Kleinee43f6f2016-12-12 14:09:38 -0500268 'x86_srcs': bpfmt(16, scrub(defs['sse2'] +
269 defs['ssse3'] +
270 defs['sse41'] +
271 defs['sse42'] +
Mike Reede32500f2017-07-19 17:20:37 -0400272 defs['avx' ])),
Leon Scroggins III6ccd2ca2017-01-26 17:21:27 -0500273
Leon Scroggins III6ccd2ca2017-01-26 17:21:27 -0500274 'dm_includes' : bpfmt(8, dm_includes),
275 'dm_srcs' : bpfmt(8, dm_srcs),
276
277 'nanobench_includes' : bpfmt(8, nanobench_includes),
278 'nanobench_srcs' : bpfmt(8, nanobench_srcs),
Mike Klein308b5ac2016-12-06 16:03:52 -0500279 })
280
281#... and all the #defines we want to put in SkUserConfig.h.
Mike Kleinc3083332016-12-12 09:03:56 -0500282with open('include/config/SkUserConfig.h', 'w') as f:
Leon Scroggins III51b2f1b2017-07-11 15:53:41 -0400283 print >>f, '// DO NOT MODIFY! This file is autogenerated by gn_to_bp.py.'
284 print >>f, '// If need to change a define, modify SkUserConfigManual.h'
Mike Klein308b5ac2016-12-06 16:03:52 -0500285 print >>f, '#ifndef SkUserConfig_DEFINED'
286 print >>f, '#define SkUserConfig_DEFINED'
Leon Scroggins III51b2f1b2017-07-11 15:53:41 -0400287 print >>f, '#include "SkUserConfigManual.h"'
Mike Klein27eb22b2016-12-07 12:27:56 -0500288 for define in sorted(defines):
Mike Kleinc3083332016-12-12 09:03:56 -0500289 print >>f, ' #define', define.replace('=', ' ')
Mike Klein308b5ac2016-12-06 16:03:52 -0500290 print >>f, '#endif//SkUserConfig_DEFINED'