blob: 2056c4274f5b22692f291524caadec2644f4cbf8 [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
Leon Scroggins III6ccd2ca2017-01-26 17:21:27 -050017tool_cflags = [
18 '-Wno-unused-parameter',
19]
20
21# It's easier to maintain one list instead of separate lists.
22tool_shared_libs = [
23 'liblog',
24 'libGLESv2',
25 'libEGL',
26 'libvulkan',
27 'libz',
28 'libjpeg',
29 'libpng',
30 'libicuuc',
31 'libicui18n',
32 'libexpat',
33 'libft2',
34 'libdng_sdk',
35 'libpiex',
Derek Sollenberger488f0d62017-03-03 15:48:33 -050036 'libcutils',
Stan Iliev7e910df2017-06-02 10:29:21 -040037 'libnativewindow',
Leon Scroggins III6ccd2ca2017-01-26 17:21:27 -050038]
39
40# The ordering here is important: libsfntly needs to come after libskia.
41tool_static_libs = [
Matt Sarettaf7bbc82017-02-20 10:41:39 -050042 'libarect',
Leon Scroggins III6ccd2ca2017-01-26 17:21:27 -050043 'libjsoncpp',
44 'libskia',
45 'libsfntly',
46 'libwebp-decode',
47 'libwebp-encode',
48]
49
Mike Klein308b5ac2016-12-06 16:03:52 -050050# First we start off with a template for Android.bp,
51# with holes for source lists and include directories.
52bp = string.Template('''// This file is autogenerated by gn_to_bp.py.
53
54cc_library {
Mike Kleinee43f6f2016-12-12 14:09:38 -050055 name: "libskia",
56 cflags: [
57 "-fexceptions",
58 "-Wno-unused-parameter",
59 "-U_FORTIFY_SOURCE",
60 "-D_FORTIFY_SOURCE=1",
61 "-DSKIA_IMPLEMENTATION=1",
Derek Sollenberger488f0d62017-03-03 15:48:33 -050062 "-DATRACE_TAG=ATRACE_TAG_VIEW",
Mike Kleinee43f6f2016-12-12 14:09:38 -050063 ],
Mike Klein308b5ac2016-12-06 16:03:52 -050064
Mike Kleinee43f6f2016-12-12 14:09:38 -050065 export_include_dirs: [
66 $export_includes
67 ],
Mike Klein27eb22b2016-12-07 12:27:56 -050068
Mike Kleinee43f6f2016-12-12 14:09:38 -050069 local_include_dirs: [
70 $local_includes
71 ],
Mike Klein27eb22b2016-12-07 12:27:56 -050072
Mike Kleinee43f6f2016-12-12 14:09:38 -050073 srcs: [
74 $srcs
75 ],
Mike Klein308b5ac2016-12-06 16:03:52 -050076
Mike Kleinee43f6f2016-12-12 14:09:38 -050077 arch: {
78 arm: {
79 srcs: [
80 $arm_srcs
81 ],
Mike Klein27eb22b2016-12-07 12:27:56 -050082
Mike Kleinee43f6f2016-12-12 14:09:38 -050083 armv7_a_neon: {
84 srcs: [
85 $arm_neon_srcs
86 ],
87 },
88 },
89
90 arm64: {
91 srcs: [
92 $arm64_srcs
93 ],
94 },
95
96 mips: {
97 srcs: [
Mike Klein40a82bd2016-12-20 17:34:29 -050098 $none_srcs
Mike Kleinee43f6f2016-12-12 14:09:38 -050099 ],
100 },
101
102 mips64: {
103 srcs: [
Mike Klein40a82bd2016-12-20 17:34:29 -0500104 $none_srcs
Mike Kleinee43f6f2016-12-12 14:09:38 -0500105 ],
106 },
107
108 x86: {
109 srcs: [
110 $x86_srcs
111 ],
112 },
113
114 x86_64: {
115 srcs: [
116 $x86_srcs
117 ],
118 },
Mike Klein308b5ac2016-12-06 16:03:52 -0500119 },
Mike Klein27eb22b2016-12-07 12:27:56 -0500120
Mike Kleinee43f6f2016-12-12 14:09:38 -0500121 shared_libs: [
122 "libEGL",
123 "libGLESv2",
124 "libdng_sdk",
125 "libexpat",
126 "libft2",
127 "libicui18n",
128 "libicuuc",
129 "libjpeg",
130 "liblog",
131 "libpiex",
132 "libpng",
133 "libvulkan",
134 "libz",
Derek Sollenberger488f0d62017-03-03 15:48:33 -0500135 "libcutils",
Stan Iliev7e910df2017-06-02 10:29:21 -0400136 "libnativewindow",
Mike Kleinee43f6f2016-12-12 14:09:38 -0500137 ],
138 static_libs: [
Matt Saretta3091092017-02-20 12:50:52 -0500139 "libarect",
Mike Kleinee43f6f2016-12-12 14:09:38 -0500140 "libsfntly",
141 "libwebp-decode",
142 "libwebp-encode",
143 ],
Leon Scroggins III6ccd2ca2017-01-26 17:21:27 -0500144}
145
146cc_test {
147 name: "skia_dm",
148
149 cflags: [
150 $tool_cflags
151 ],
152
153 local_include_dirs: [
154 $dm_includes
155 ],
156
157 srcs: [
158 $dm_srcs
159 ],
160
161 shared_libs: [
162 $tool_shared_libs
163 ],
164
165 static_libs: [
166 $tool_static_libs
167 ],
168}
169
170cc_test {
171 name: "skia_nanobench",
172
173 cflags: [
174 $tool_cflags
175 ],
176
177 local_include_dirs: [
178 $nanobench_includes
179 ],
180
181 srcs: [
182 $nanobench_srcs
183 ],
184
185 shared_libs: [
186 $tool_shared_libs
187 ],
188
189 static_libs: [
190 $tool_static_libs
191 ],
Mike Kleinee43f6f2016-12-12 14:09:38 -0500192}''')
Mike Klein308b5ac2016-12-06 16:03:52 -0500193
194# We'll run GN to get the main source lists and include directories for Skia.
195gn_args = {
Mike Kleine459afd2017-03-03 09:21:30 -0500196 'is_official_build': 'true',
Mike Kleine459afd2017-03-03 09:21:30 -0500197 'skia_enable_tools': 'true',
198 'skia_use_vulkan': 'true',
199 'target_cpu': '"none"',
200 'target_os': '"android"',
Mike Klein308b5ac2016-12-06 16:03:52 -0500201}
202gn_args = ' '.join(sorted('%s=%s' % (k,v) for (k,v) in gn_args.iteritems()))
203
204tmp = tempfile.mkdtemp()
205subprocess.check_call(['gn', 'gen', tmp, '--args=%s' % gn_args, '--ide=json'])
206
207js = json.load(open(os.path.join(tmp, 'project.json')))
208
209def strip_slashes(lst):
Ben Wagnere1275232017-02-23 18:00:06 -0500210 return {str(p.lstrip('/')) for p in lst}
Mike Klein27eb22b2016-12-07 12:27:56 -0500211
Mike Klein308b5ac2016-12-06 16:03:52 -0500212srcs = strip_slashes(js['targets']['//:skia']['sources'])
213local_includes = strip_slashes(js['targets']['//:skia']['include_dirs'])
214export_includes = strip_slashes(js['targets']['//:public']['include_dirs'])
215
Leon Scroggins III6ccd2ca2017-01-26 17:21:27 -0500216dm_srcs = strip_slashes(js['targets']['//:dm']['sources'])
217dm_includes = strip_slashes(js['targets']['//:dm']['include_dirs'])
218
219nanobench_target = js['targets']['//:nanobench']
220nanobench_srcs = strip_slashes(nanobench_target['sources'])
221nanobench_includes = strip_slashes(nanobench_target['include_dirs'])
222
223def GrabDependentSrcs(name, srcs_to_extend, exclude):
224 # Grab the sources from other targets that $name depends on (e.g. optional
225 # Skia components, gms, tests, etc).
226 for dep in js['targets'][name]['deps']:
227 if 'third_party' in dep:
228 continue # We've handled all third-party DEPS as static or shared_libs.
229 if 'none' in dep:
230 continue # We'll handle all cpu-specific sources manually later.
231 if exclude and exclude in dep:
232 continue
Ben Wagnere1275232017-02-23 18:00:06 -0500233 srcs_to_extend.update(strip_slashes(js['targets'][dep].get('sources', [])))
234 GrabDependentSrcs(dep, srcs_to_extend, exclude)
Leon Scroggins III6ccd2ca2017-01-26 17:21:27 -0500235
236GrabDependentSrcs('//:skia', srcs, None)
237GrabDependentSrcs('//:dm', dm_srcs, 'skia')
238GrabDependentSrcs('//:nanobench', nanobench_srcs, 'skia')
Mike Klein27eb22b2016-12-07 12:27:56 -0500239
240# No need to list headers.
Ben Wagnere1275232017-02-23 18:00:06 -0500241srcs = {s for s in srcs if not s.endswith('.h')}
242dm_srcs = {s for s in dm_srcs if not s.endswith('.h')}
243nanobench_srcs = {s for s in nanobench_srcs if not s.endswith('.h')}
Mike Klein27eb22b2016-12-07 12:27:56 -0500244
Mike Klein308b5ac2016-12-06 16:03:52 -0500245# Most defines go into SkUserConfig.h, where they're seen by Skia and its users.
Mike Klein308b5ac2016-12-06 16:03:52 -0500246defines = [str(d) for d in js['targets']['//:skia']['defines']]
Mike Kleine459afd2017-03-03 09:21:30 -0500247defines.remove('NDEBUG') # Let the Android build control this.
Mike Klein308b5ac2016-12-06 16:03:52 -0500248defines.remove('SKIA_IMPLEMENTATION=1') # Only libskia should have this define.
Mike Klein308b5ac2016-12-06 16:03:52 -0500249
250# For architecture specific files, it's easier to just read the same source
251# that GN does (opts.gni) rather than re-run GN once for each architecture.
252
253# This .gni file we want to read is close enough to Python syntax
254# that we can use execfile() if we supply definitions for GN builtins.
Mike Klein308b5ac2016-12-06 16:03:52 -0500255
256def get_path_info(path, kind):
257 assert kind == "abspath"
258 # While we want absolute paths in GN, relative paths work best here.
259 return path
260
261builtins = { 'get_path_info': get_path_info }
262defs = {}
Leon Scroggins III4f8a4672016-12-19 09:32:21 -0500263here = os.path.dirname(__file__)
Mike Klein308b5ac2016-12-06 16:03:52 -0500264execfile(os.path.join(here, 'opts.gni'), builtins, defs)
Mike Klein308b5ac2016-12-06 16:03:52 -0500265
Mike Klein27eb22b2016-12-07 12:27:56 -0500266# Turn paths from opts.gni into paths relative to external/skia.
Mike Klein308b5ac2016-12-06 16:03:52 -0500267def scrub(lst):
268 # Perform any string substitutions.
269 for var in defs:
270 if type(defs[var]) is str:
271 lst = [ p.replace('$'+var, defs[var]) for p in lst ]
272 # Relativize paths to top-level skia/ directory.
273 return [os.path.relpath(p, '..') for p in lst]
274
Mike Kleinee43f6f2016-12-12 14:09:38 -0500275# Turn a list of strings into the style bpfmt outputs.
Leon Scroggins III6ccd2ca2017-01-26 17:21:27 -0500276def bpfmt(indent, lst, sort=True):
277 if sort:
278 lst = sorted(lst)
279 return ('\n' + ' '*indent).join('"%s",' % v for v in lst)
Mike Klein308b5ac2016-12-06 16:03:52 -0500280
281# OK! We have everything to fill in Android.bp...
282with open('Android.bp', 'w') as f:
283 print >>f, bp.substitute({
Mike Kleinee43f6f2016-12-12 14:09:38 -0500284 'export_includes': bpfmt(8, export_includes),
285 'local_includes': bpfmt(8, local_includes),
286 'srcs': bpfmt(8, srcs),
Mike Klein308b5ac2016-12-06 16:03:52 -0500287
Mike Kleinee43f6f2016-12-12 14:09:38 -0500288 'arm_srcs': bpfmt(16, scrub(defs['armv7'])),
289 'arm_neon_srcs': bpfmt(20, scrub(defs['neon'])),
290 'arm64_srcs': bpfmt(16, scrub(defs['arm64'] +
291 defs['crc32'])),
Mike Klein40a82bd2016-12-20 17:34:29 -0500292 'none_srcs': bpfmt(16, scrub(defs['none'])),
Mike Kleinee43f6f2016-12-12 14:09:38 -0500293 'x86_srcs': bpfmt(16, scrub(defs['sse2'] +
294 defs['ssse3'] +
295 defs['sse41'] +
296 defs['sse42'] +
Mike Reede32500f2017-07-19 17:20:37 -0400297 defs['avx' ])),
Leon Scroggins III6ccd2ca2017-01-26 17:21:27 -0500298
299 'tool_cflags' : bpfmt(8, tool_cflags),
300 'tool_shared_libs' : bpfmt(8, tool_shared_libs),
301 'tool_static_libs' : bpfmt(8, tool_static_libs, False),
302
303 'dm_includes' : bpfmt(8, dm_includes),
304 'dm_srcs' : bpfmt(8, dm_srcs),
305
306 'nanobench_includes' : bpfmt(8, nanobench_includes),
307 'nanobench_srcs' : bpfmt(8, nanobench_srcs),
Mike Klein308b5ac2016-12-06 16:03:52 -0500308 })
309
310#... and all the #defines we want to put in SkUserConfig.h.
Mike Kleinc3083332016-12-12 09:03:56 -0500311with open('include/config/SkUserConfig.h', 'w') as f:
Leon Scroggins III51b2f1b2017-07-11 15:53:41 -0400312 print >>f, '// DO NOT MODIFY! This file is autogenerated by gn_to_bp.py.'
313 print >>f, '// If need to change a define, modify SkUserConfigManual.h'
Mike Klein308b5ac2016-12-06 16:03:52 -0500314 print >>f, '#ifndef SkUserConfig_DEFINED'
315 print >>f, '#define SkUserConfig_DEFINED'
Leon Scroggins III51b2f1b2017-07-11 15:53:41 -0400316 print >>f, '#include "SkUserConfigManual.h"'
Mike Klein27eb22b2016-12-07 12:27:56 -0500317 for define in sorted(defines):
Mike Kleinc3083332016-12-12 09:03:56 -0500318 print >>f, ' #define', define.replace('=', ' ')
Mike Klein308b5ac2016-12-06 16:03:52 -0500319 print >>f, '#endif//SkUserConfig_DEFINED'