blob: 517324626c990a9decd54861fb945d14a2fafdbd [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
21cc_library {
Mike Kleinee43f6f2016-12-12 14:09:38 -050022 name: "libskia",
23 cflags: [
24 "-fexceptions",
25 "-Wno-unused-parameter",
26 "-U_FORTIFY_SOURCE",
27 "-D_FORTIFY_SOURCE=1",
28 "-DSKIA_IMPLEMENTATION=1",
29 ],
Mike Klein308b5ac2016-12-06 16:03:52 -050030
Mike Kleinee43f6f2016-12-12 14:09:38 -050031 export_include_dirs: [
32 $export_includes
33 ],
Mike Klein27eb22b2016-12-07 12:27:56 -050034
Mike Kleinee43f6f2016-12-12 14:09:38 -050035 local_include_dirs: [
36 $local_includes
37 ],
Mike Klein27eb22b2016-12-07 12:27:56 -050038
Mike Kleinee43f6f2016-12-12 14:09:38 -050039 srcs: [
40 $srcs
41 ],
Mike Klein308b5ac2016-12-06 16:03:52 -050042
Mike Kleinee43f6f2016-12-12 14:09:38 -050043 arch: {
44 arm: {
45 srcs: [
46 $arm_srcs
47 ],
Mike Klein27eb22b2016-12-07 12:27:56 -050048
Mike Kleinee43f6f2016-12-12 14:09:38 -050049 armv7_a_neon: {
50 srcs: [
51 $arm_neon_srcs
52 ],
53 },
54 },
55
56 arm64: {
57 srcs: [
58 $arm64_srcs
59 ],
60 },
61
62 mips: {
63 srcs: [
Mike Klein40a82bd2016-12-20 17:34:29 -050064 $none_srcs
Mike Kleinee43f6f2016-12-12 14:09:38 -050065 ],
66 },
67
68 mips64: {
69 srcs: [
Mike Klein40a82bd2016-12-20 17:34:29 -050070 $none_srcs
Mike Kleinee43f6f2016-12-12 14:09:38 -050071 ],
72 },
73
74 x86: {
75 srcs: [
76 $x86_srcs
77 ],
78 },
79
80 x86_64: {
81 srcs: [
82 $x86_srcs
83 ],
84 },
Mike Klein308b5ac2016-12-06 16:03:52 -050085 },
Mike Klein27eb22b2016-12-07 12:27:56 -050086
Mike Kleinee43f6f2016-12-12 14:09:38 -050087 shared_libs: [
88 "libEGL",
89 "libGLESv2",
90 "libdng_sdk",
91 "libexpat",
92 "libft2",
93 "libicui18n",
94 "libicuuc",
95 "libjpeg",
96 "liblog",
97 "libpiex",
98 "libpng",
99 "libvulkan",
100 "libz",
101 ],
102 static_libs: [
103 "libsfntly",
104 "libwebp-decode",
105 "libwebp-encode",
106 ],
107}''')
Mike Klein308b5ac2016-12-06 16:03:52 -0500108
109# We'll run GN to get the main source lists and include directories for Skia.
110gn_args = {
Mike Klein1c471872017-01-13 15:27:45 -0500111 'skia_enable_splicer': 'false',
Mike Klein308b5ac2016-12-06 16:03:52 -0500112 'skia_enable_vulkan_debug_layers': 'false',
Mike Kleinc3083332016-12-12 09:03:56 -0500113 'skia_use_system_expat': 'true',
Mike Klein308b5ac2016-12-06 16:03:52 -0500114 'skia_use_vulkan': 'true',
Mike Klein27eb22b2016-12-07 12:27:56 -0500115 'target_cpu': '"none"',
Mike Klein308b5ac2016-12-06 16:03:52 -0500116 'target_os': '"android"',
117}
118gn_args = ' '.join(sorted('%s=%s' % (k,v) for (k,v) in gn_args.iteritems()))
119
120tmp = tempfile.mkdtemp()
121subprocess.check_call(['gn', 'gen', tmp, '--args=%s' % gn_args, '--ide=json'])
122
123js = json.load(open(os.path.join(tmp, 'project.json')))
124
125def strip_slashes(lst):
Mike Klein27eb22b2016-12-07 12:27:56 -0500126 return [str(p.lstrip('/')) for p in lst]
127
Mike Klein308b5ac2016-12-06 16:03:52 -0500128srcs = strip_slashes(js['targets']['//:skia']['sources'])
129local_includes = strip_slashes(js['targets']['//:skia']['include_dirs'])
130export_includes = strip_slashes(js['targets']['//:public']['include_dirs'])
131
Mike Klein27eb22b2016-12-07 12:27:56 -0500132# Grab the sources from targets :skia depends on (optional Skia components).
133for dep in js['targets']['//:skia']['deps']:
134 if 'third_party' in dep:
135 continue # We've handled all third-party DEPS as static or shared_libs.
Mike Kleinc3083332016-12-12 09:03:56 -0500136 if 'none' in dep:
137 continue # We'll handle all cpu-specific sources manually later.
Mike Klein27eb22b2016-12-07 12:27:56 -0500138 srcs.extend(strip_slashes(js['targets'][dep].get('sources', [])))
139
140# No need to list headers.
141srcs = [s for s in srcs if not s.endswith('.h')]
142
Mike Klein308b5ac2016-12-06 16:03:52 -0500143# Most defines go into SkUserConfig.h, where they're seen by Skia and its users.
144# Start with the defines :skia uses, minus a couple. We'll add more in a bit.
145defines = [str(d) for d in js['targets']['//:skia']['defines']]
146defines.remove('SKIA_IMPLEMENTATION=1') # Only libskia should have this define.
Mike Klein308b5ac2016-12-06 16:03:52 -0500147
148# For architecture specific files, it's easier to just read the same source
149# that GN does (opts.gni) rather than re-run GN once for each architecture.
150
151# This .gni file we want to read is close enough to Python syntax
152# that we can use execfile() if we supply definitions for GN builtins.
153# While we're at it, grab defines specific to Android Framework the same way.
154
155def get_path_info(path, kind):
156 assert kind == "abspath"
157 # While we want absolute paths in GN, relative paths work best here.
158 return path
159
160builtins = { 'get_path_info': get_path_info }
161defs = {}
Leon Scroggins III4f8a4672016-12-19 09:32:21 -0500162here = os.path.dirname(__file__)
Mike Klein308b5ac2016-12-06 16:03:52 -0500163execfile(os.path.join(here, 'opts.gni'), builtins, defs)
164execfile(os.path.join(here, 'android_framework_defines.gni'), builtins, defs)
165
166# This should finish off the defines.
167defines += defs['android_framework_defines']
168defines.extend([
169 'GR_GL_CUSTOM_SETUP_HEADER "gl/GrGLConfig_chrome.h"',
170 'SKIA_DLL',
171 'SK_BUILD_FOR_ANDROID_FRAMEWORK',
172 'SK_DEFAULT_FONT_CACHE_LIMIT (768 * 1024)',
173 'SK_DEFAULT_GLOBAL_DISCARDABLE_MEMORY_POOL_SIZE (512 * 1024)',
174 'SK_IGNORE_ETC1_SUPPORT',
175 'SK_USE_FREETYPE_EMBOLDEN',
176])
Mike Klein27eb22b2016-12-07 12:27:56 -0500177# TODO: move these all to android_framework_defines.gni?
Mike Klein308b5ac2016-12-06 16:03:52 -0500178
Mike Klein27eb22b2016-12-07 12:27:56 -0500179# Turn paths from opts.gni into paths relative to external/skia.
Mike Klein308b5ac2016-12-06 16:03:52 -0500180def scrub(lst):
181 # Perform any string substitutions.
182 for var in defs:
183 if type(defs[var]) is str:
184 lst = [ p.replace('$'+var, defs[var]) for p in lst ]
185 # Relativize paths to top-level skia/ directory.
186 return [os.path.relpath(p, '..') for p in lst]
187
Mike Kleinee43f6f2016-12-12 14:09:38 -0500188# Turn a list of strings into the style bpfmt outputs.
189def bpfmt(indent, lst):
190 return ('\n' + ' '*indent).join('"%s",' % v for v in sorted(lst))
Mike Klein308b5ac2016-12-06 16:03:52 -0500191
192# OK! We have everything to fill in Android.bp...
193with open('Android.bp', 'w') as f:
194 print >>f, bp.substitute({
Mike Kleinee43f6f2016-12-12 14:09:38 -0500195 'export_includes': bpfmt(8, export_includes),
196 'local_includes': bpfmt(8, local_includes),
197 'srcs': bpfmt(8, srcs),
Mike Klein308b5ac2016-12-06 16:03:52 -0500198
Mike Kleinee43f6f2016-12-12 14:09:38 -0500199 'arm_srcs': bpfmt(16, scrub(defs['armv7'])),
200 'arm_neon_srcs': bpfmt(20, scrub(defs['neon'])),
201 'arm64_srcs': bpfmt(16, scrub(defs['arm64'] +
202 defs['crc32'])),
Mike Klein40a82bd2016-12-20 17:34:29 -0500203 'none_srcs': bpfmt(16, scrub(defs['none'])),
Mike Kleinee43f6f2016-12-12 14:09:38 -0500204 'x86_srcs': bpfmt(16, scrub(defs['sse2'] +
205 defs['ssse3'] +
206 defs['sse41'] +
207 defs['sse42'] +
208 defs['avx' ] +
209 defs['hsw' ]))
Mike Klein308b5ac2016-12-06 16:03:52 -0500210 })
211
212#... and all the #defines we want to put in SkUserConfig.h.
Mike Kleinc3083332016-12-12 09:03:56 -0500213with open('include/config/SkUserConfig.h', 'w') as f:
Mike Klein308b5ac2016-12-06 16:03:52 -0500214 print >>f, '// This file is autogenerated by gn_to_bp.py.'
215 print >>f, '#ifndef SkUserConfig_DEFINED'
216 print >>f, '#define SkUserConfig_DEFINED'
Mike Klein27eb22b2016-12-07 12:27:56 -0500217 for define in sorted(defines):
Mike Kleinc3083332016-12-12 09:03:56 -0500218 print >>f, ' #define', define.replace('=', ' ')
Mike Klein308b5ac2016-12-06 16:03:52 -0500219 print >>f, '#endif//SkUserConfig_DEFINED'