2016-12-06 21:03:52 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
#
|
|
|
|
# Copyright 2016 Google Inc.
|
|
|
|
#
|
|
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
|
|
# found in the LICENSE file.
|
|
|
|
|
|
|
|
# Generate Android.bp for Skia from GN configuration.
|
|
|
|
|
|
|
|
import json
|
|
|
|
import os
|
|
|
|
import pprint
|
|
|
|
import string
|
|
|
|
import subprocess
|
|
|
|
import tempfile
|
|
|
|
|
|
|
|
# First we start off with a template for Android.bp,
|
|
|
|
# with holes for source lists and include directories.
|
|
|
|
bp = string.Template('''// This file is autogenerated by gn_to_bp.py.
|
|
|
|
|
2017-09-21 18:25:14 +00:00
|
|
|
cc_library_static {
|
2016-12-12 19:09:38 +00:00
|
|
|
name: "libskia",
|
|
|
|
cflags: [
|
2017-10-06 15:53:53 +00:00
|
|
|
$cflags
|
|
|
|
],
|
|
|
|
|
|
|
|
cppflags:[
|
|
|
|
$cflags_cc
|
2016-12-12 19:09:38 +00:00
|
|
|
],
|
|
|
|
|
|
|
|
export_include_dirs: [
|
|
|
|
$export_includes
|
|
|
|
],
|
|
|
|
|
|
|
|
local_include_dirs: [
|
|
|
|
$local_includes
|
|
|
|
],
|
|
|
|
|
|
|
|
srcs: [
|
|
|
|
$srcs
|
|
|
|
],
|
|
|
|
|
|
|
|
arch: {
|
|
|
|
arm: {
|
|
|
|
srcs: [
|
|
|
|
$arm_srcs
|
|
|
|
],
|
|
|
|
|
2017-08-10 13:09:54 +00:00
|
|
|
neon: {
|
2016-12-12 19:09:38 +00:00
|
|
|
srcs: [
|
|
|
|
$arm_neon_srcs
|
|
|
|
],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
arm64: {
|
|
|
|
srcs: [
|
|
|
|
$arm64_srcs
|
|
|
|
],
|
|
|
|
},
|
|
|
|
|
|
|
|
mips: {
|
|
|
|
srcs: [
|
2016-12-20 22:34:29 +00:00
|
|
|
$none_srcs
|
2016-12-12 19:09:38 +00:00
|
|
|
],
|
|
|
|
},
|
|
|
|
|
|
|
|
mips64: {
|
|
|
|
srcs: [
|
2016-12-20 22:34:29 +00:00
|
|
|
$none_srcs
|
2016-12-12 19:09:38 +00:00
|
|
|
],
|
|
|
|
},
|
|
|
|
|
|
|
|
x86: {
|
|
|
|
srcs: [
|
|
|
|
$x86_srcs
|
|
|
|
],
|
2017-11-30 19:42:58 +00:00
|
|
|
cflags: [
|
2017-12-01 14:48:10 +00:00
|
|
|
// Clang seems to think new/malloc will only be 4-byte aligned
|
|
|
|
// on x86 Android. We're pretty sure it's actually 8-byte
|
|
|
|
// alignment. tests/OverAlignedTest.cpp has more information,
|
|
|
|
// and should fail if we're wrong.
|
2017-11-30 19:42:58 +00:00
|
|
|
"-Wno-over-aligned"
|
|
|
|
],
|
2016-12-12 19:09:38 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
x86_64: {
|
|
|
|
srcs: [
|
|
|
|
$x86_srcs
|
|
|
|
],
|
|
|
|
},
|
2016-12-06 21:03:52 +00:00
|
|
|
},
|
|
|
|
|
2017-12-11 18:37:44 +00:00
|
|
|
defaults: ["skia_deps",
|
|
|
|
"skia_pgo",
|
|
|
|
],
|
|
|
|
}
|
|
|
|
|
|
|
|
// Build libskia with PGO by default.
|
|
|
|
// Location of PGO profile data is defined in build/soong/cc/pgo.go
|
|
|
|
// and is separate from skia.
|
|
|
|
// To turn it off, set ANDROID_PGO_NO_PROFILE_USE environment variable
|
|
|
|
// or set enable_profile_use property to false.
|
|
|
|
cc_defaults {
|
|
|
|
name: "skia_pgo",
|
|
|
|
pgo: {
|
|
|
|
instrumentation: true,
|
|
|
|
profile_file: "skia/skia.profdata",
|
|
|
|
benchmarks: ["hwui", "skia"],
|
|
|
|
enable_profile_use: true,
|
|
|
|
},
|
2017-09-21 18:25:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cc_defaults {
|
|
|
|
name: "skia_deps",
|
2016-12-12 19:09:38 +00:00
|
|
|
shared_libs: [
|
|
|
|
"libEGL",
|
|
|
|
"libGLESv2",
|
|
|
|
"libdng_sdk",
|
|
|
|
"libexpat",
|
|
|
|
"libft2",
|
2017-08-17 19:13:20 +00:00
|
|
|
"libheif",
|
2016-12-12 19:09:38 +00:00
|
|
|
"libicui18n",
|
|
|
|
"libicuuc",
|
|
|
|
"libjpeg",
|
|
|
|
"liblog",
|
|
|
|
"libpiex",
|
|
|
|
"libpng",
|
|
|
|
"libvulkan",
|
|
|
|
"libz",
|
2017-03-03 20:48:33 +00:00
|
|
|
"libcutils",
|
2017-06-02 14:29:21 +00:00
|
|
|
"libnativewindow",
|
2016-12-12 19:09:38 +00:00
|
|
|
],
|
|
|
|
static_libs: [
|
2017-02-20 17:50:52 +00:00
|
|
|
"libarect",
|
2016-12-12 19:09:38 +00:00
|
|
|
"libsfntly",
|
|
|
|
"libwebp-decode",
|
|
|
|
"libwebp-encode",
|
|
|
|
],
|
2017-09-21 18:25:14 +00:00
|
|
|
group_static_libs: true,
|
|
|
|
}
|
|
|
|
|
|
|
|
cc_defaults {
|
|
|
|
name: "skia_tool_deps",
|
|
|
|
defaults: [
|
|
|
|
"skia_deps"
|
|
|
|
],
|
|
|
|
static_libs: [
|
|
|
|
"libjsoncpp",
|
|
|
|
"libskia",
|
|
|
|
],
|
|
|
|
cflags: [
|
|
|
|
"-Wno-unused-parameter"
|
|
|
|
],
|
2017-01-26 22:21:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cc_test {
|
|
|
|
name: "skia_dm",
|
|
|
|
|
2017-09-21 18:25:14 +00:00
|
|
|
defaults: [
|
|
|
|
"skia_tool_deps"
|
2017-01-26 22:21:27 +00:00
|
|
|
],
|
|
|
|
|
|
|
|
local_include_dirs: [
|
|
|
|
$dm_includes
|
|
|
|
],
|
|
|
|
|
|
|
|
srcs: [
|
|
|
|
$dm_srcs
|
|
|
|
],
|
|
|
|
}
|
|
|
|
|
|
|
|
cc_test {
|
|
|
|
name: "skia_nanobench",
|
|
|
|
|
2017-09-21 18:25:14 +00:00
|
|
|
defaults: [
|
|
|
|
"skia_tool_deps"
|
2017-01-26 22:21:27 +00:00
|
|
|
],
|
|
|
|
|
|
|
|
local_include_dirs: [
|
|
|
|
$nanobench_includes
|
|
|
|
],
|
|
|
|
|
|
|
|
srcs: [
|
|
|
|
$nanobench_srcs
|
|
|
|
],
|
2016-12-12 19:09:38 +00:00
|
|
|
}''')
|
2016-12-06 21:03:52 +00:00
|
|
|
|
|
|
|
# We'll run GN to get the main source lists and include directories for Skia.
|
|
|
|
gn_args = {
|
2017-03-03 14:21:30 +00:00
|
|
|
'is_official_build': 'true',
|
|
|
|
'skia_enable_tools': 'true',
|
2017-08-17 19:13:20 +00:00
|
|
|
'skia_use_libheif': 'true',
|
2017-03-03 14:21:30 +00:00
|
|
|
'skia_use_vulkan': 'true',
|
|
|
|
'target_cpu': '"none"',
|
|
|
|
'target_os': '"android"',
|
2017-12-07 17:48:30 +00:00
|
|
|
'skia_vulkan_header': '"Skia_Vulkan_Android.h"',
|
2016-12-06 21:03:52 +00:00
|
|
|
}
|
|
|
|
gn_args = ' '.join(sorted('%s=%s' % (k,v) for (k,v) in gn_args.iteritems()))
|
|
|
|
|
|
|
|
tmp = tempfile.mkdtemp()
|
|
|
|
subprocess.check_call(['gn', 'gen', tmp, '--args=%s' % gn_args, '--ide=json'])
|
|
|
|
|
|
|
|
js = json.load(open(os.path.join(tmp, 'project.json')))
|
|
|
|
|
|
|
|
def strip_slashes(lst):
|
2017-02-23 23:00:06 +00:00
|
|
|
return {str(p.lstrip('/')) for p in lst}
|
2016-12-07 17:27:56 +00:00
|
|
|
|
2016-12-06 21:03:52 +00:00
|
|
|
srcs = strip_slashes(js['targets']['//:skia']['sources'])
|
2017-10-06 15:53:53 +00:00
|
|
|
cflags = strip_slashes(js['targets']['//:skia']['cflags'])
|
|
|
|
cflags_cc = strip_slashes(js['targets']['//:skia']['cflags_cc'])
|
2016-12-06 21:03:52 +00:00
|
|
|
local_includes = strip_slashes(js['targets']['//:skia']['include_dirs'])
|
|
|
|
export_includes = strip_slashes(js['targets']['//:public']['include_dirs'])
|
|
|
|
|
2017-01-26 22:21:27 +00:00
|
|
|
dm_srcs = strip_slashes(js['targets']['//:dm']['sources'])
|
|
|
|
dm_includes = strip_slashes(js['targets']['//:dm']['include_dirs'])
|
|
|
|
|
|
|
|
nanobench_target = js['targets']['//:nanobench']
|
|
|
|
nanobench_srcs = strip_slashes(nanobench_target['sources'])
|
|
|
|
nanobench_includes = strip_slashes(nanobench_target['include_dirs'])
|
|
|
|
|
|
|
|
def GrabDependentSrcs(name, srcs_to_extend, exclude):
|
|
|
|
# Grab the sources from other targets that $name depends on (e.g. optional
|
|
|
|
# Skia components, gms, tests, etc).
|
|
|
|
for dep in js['targets'][name]['deps']:
|
|
|
|
if 'third_party' in dep:
|
|
|
|
continue # We've handled all third-party DEPS as static or shared_libs.
|
|
|
|
if 'none' in dep:
|
|
|
|
continue # We'll handle all cpu-specific sources manually later.
|
|
|
|
if exclude and exclude in dep:
|
|
|
|
continue
|
2017-02-23 23:00:06 +00:00
|
|
|
srcs_to_extend.update(strip_slashes(js['targets'][dep].get('sources', [])))
|
|
|
|
GrabDependentSrcs(dep, srcs_to_extend, exclude)
|
2017-01-26 22:21:27 +00:00
|
|
|
|
|
|
|
GrabDependentSrcs('//:skia', srcs, None)
|
|
|
|
GrabDependentSrcs('//:dm', dm_srcs, 'skia')
|
|
|
|
GrabDependentSrcs('//:nanobench', nanobench_srcs, 'skia')
|
2016-12-07 17:27:56 +00:00
|
|
|
|
|
|
|
# No need to list headers.
|
2017-02-23 23:00:06 +00:00
|
|
|
srcs = {s for s in srcs if not s.endswith('.h')}
|
|
|
|
dm_srcs = {s for s in dm_srcs if not s.endswith('.h')}
|
|
|
|
nanobench_srcs = {s for s in nanobench_srcs if not s.endswith('.h')}
|
2016-12-07 17:27:56 +00:00
|
|
|
|
2017-10-06 15:53:53 +00:00
|
|
|
# Only use the generated flags related to warnings.
|
|
|
|
cflags = {s for s in cflags if s.startswith('-W')}
|
|
|
|
cflags_cc = {s for s in cflags_cc if s.startswith('-W')}
|
|
|
|
# Add the rest of the flags we want.
|
|
|
|
cflags = cflags.union([
|
|
|
|
"-fvisibility=hidden",
|
|
|
|
"-D_FORTIFY_SOURCE=1",
|
|
|
|
"-DSKIA_DLL",
|
|
|
|
"-DSKIA_IMPLEMENTATION=1",
|
|
|
|
"-DATRACE_TAG=ATRACE_TAG_VIEW",
|
|
|
|
])
|
|
|
|
cflags_cc.add("-fexceptions")
|
|
|
|
|
|
|
|
# We need to undefine FORTIFY_SOURCE before we define it. Insert it at the
|
|
|
|
# beginning after sorting.
|
|
|
|
cflags = sorted(cflags)
|
|
|
|
cflags.insert(0, "-U_FORTIFY_SOURCE")
|
|
|
|
|
2017-12-07 17:48:30 +00:00
|
|
|
# We need to add the include path to the vulkan defines and header file set in
|
|
|
|
# then skia_vulkan_header gn arg that is used for framework builds.
|
|
|
|
local_includes.add("platform_tools/android/vulkan")
|
|
|
|
export_includes.add("platform_tools/android/vulkan")
|
|
|
|
|
2016-12-06 21:03:52 +00:00
|
|
|
# Most defines go into SkUserConfig.h, where they're seen by Skia and its users.
|
|
|
|
defines = [str(d) for d in js['targets']['//:skia']['defines']]
|
2017-03-03 14:21:30 +00:00
|
|
|
defines.remove('NDEBUG') # Let the Android build control this.
|
2016-12-06 21:03:52 +00:00
|
|
|
defines.remove('SKIA_IMPLEMENTATION=1') # Only libskia should have this define.
|
|
|
|
|
|
|
|
# For architecture specific files, it's easier to just read the same source
|
|
|
|
# that GN does (opts.gni) rather than re-run GN once for each architecture.
|
|
|
|
|
|
|
|
# This .gni file we want to read is close enough to Python syntax
|
|
|
|
# that we can use execfile() if we supply definitions for GN builtins.
|
|
|
|
|
|
|
|
def get_path_info(path, kind):
|
|
|
|
assert kind == "abspath"
|
|
|
|
# While we want absolute paths in GN, relative paths work best here.
|
|
|
|
return path
|
|
|
|
|
|
|
|
builtins = { 'get_path_info': get_path_info }
|
|
|
|
defs = {}
|
2016-12-19 14:32:21 +00:00
|
|
|
here = os.path.dirname(__file__)
|
2016-12-06 21:03:52 +00:00
|
|
|
execfile(os.path.join(here, 'opts.gni'), builtins, defs)
|
|
|
|
|
2016-12-07 17:27:56 +00:00
|
|
|
# Turn paths from opts.gni into paths relative to external/skia.
|
2016-12-06 21:03:52 +00:00
|
|
|
def scrub(lst):
|
|
|
|
# Perform any string substitutions.
|
|
|
|
for var in defs:
|
|
|
|
if type(defs[var]) is str:
|
|
|
|
lst = [ p.replace('$'+var, defs[var]) for p in lst ]
|
|
|
|
# Relativize paths to top-level skia/ directory.
|
|
|
|
return [os.path.relpath(p, '..') for p in lst]
|
|
|
|
|
2016-12-12 19:09:38 +00:00
|
|
|
# Turn a list of strings into the style bpfmt outputs.
|
2017-01-26 22:21:27 +00:00
|
|
|
def bpfmt(indent, lst, sort=True):
|
|
|
|
if sort:
|
|
|
|
lst = sorted(lst)
|
|
|
|
return ('\n' + ' '*indent).join('"%s",' % v for v in lst)
|
2016-12-06 21:03:52 +00:00
|
|
|
|
|
|
|
# OK! We have everything to fill in Android.bp...
|
|
|
|
with open('Android.bp', 'w') as f:
|
|
|
|
print >>f, bp.substitute({
|
2016-12-12 19:09:38 +00:00
|
|
|
'export_includes': bpfmt(8, export_includes),
|
|
|
|
'local_includes': bpfmt(8, local_includes),
|
|
|
|
'srcs': bpfmt(8, srcs),
|
2017-10-06 15:53:53 +00:00
|
|
|
'cflags': bpfmt(8, cflags, False),
|
|
|
|
'cflags_cc': bpfmt(8, cflags_cc),
|
2016-12-12 19:09:38 +00:00
|
|
|
|
|
|
|
'arm_srcs': bpfmt(16, scrub(defs['armv7'])),
|
|
|
|
'arm_neon_srcs': bpfmt(20, scrub(defs['neon'])),
|
|
|
|
'arm64_srcs': bpfmt(16, scrub(defs['arm64'] +
|
|
|
|
defs['crc32'])),
|
2016-12-20 22:34:29 +00:00
|
|
|
'none_srcs': bpfmt(16, scrub(defs['none'])),
|
2016-12-12 19:09:38 +00:00
|
|
|
'x86_srcs': bpfmt(16, scrub(defs['sse2'] +
|
|
|
|
defs['ssse3'] +
|
|
|
|
defs['sse41'] +
|
|
|
|
defs['sse42'] +
|
2017-07-19 21:20:37 +00:00
|
|
|
defs['avx' ])),
|
2017-01-26 22:21:27 +00:00
|
|
|
|
|
|
|
'dm_includes' : bpfmt(8, dm_includes),
|
|
|
|
'dm_srcs' : bpfmt(8, dm_srcs),
|
|
|
|
|
|
|
|
'nanobench_includes' : bpfmt(8, nanobench_includes),
|
|
|
|
'nanobench_srcs' : bpfmt(8, nanobench_srcs),
|
2016-12-06 21:03:52 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
#... and all the #defines we want to put in SkUserConfig.h.
|
2016-12-12 14:03:56 +00:00
|
|
|
with open('include/config/SkUserConfig.h', 'w') as f:
|
Stop adding Android-specific defines to SkUserConfig
Remove #defines that lived in gn_to_bp.py and
android_framework_defines.gni. These have been moved into a new file
in Android, SkUserConfigManual.h, in https://googleplex-android-review.git.corp.google.com/#/c/2519600/
Update gn_to_bp.py to include SkUserConfigManual.h, so it will still
result in using the same #defines.
Lately, we've found it difficult to guard changes behind a flag. e.g.
a change to drawing causes a CTS failure in Android, so we have to do
the following:
- put the change behind a flag, and add it to gn_to_bp.py or
android_framework_defines.gni
- generate new images on Android (by running CTS with external/skia
modified to not define the flag)
- create a CL in CTS that uses the new images
- land a CL in Skia that stops defining the flag
- when the Skia change lands, wait for the auto-roller to create a CL
that includes the change, stop the auto-roller, add the topic to the CTS
CL so the two can land at the same time
- land both Android changes (with TreeHugger)
- restart the Android auto-roller
With SkUserConfigManual.h (which lives in Android), the process will
be similar to Chromium:
- land a CL in Android's external/skia that defines a flag e.g.
SK_SUPPORT_LEGACY_FEATURE. Land without TreeHugger because it isn't used
in Skia and does not do anything
- land a change in Skia that changes behavior unless
SK_SUPPORT_LEGACY_FEATURE is defined. This will safely go through the
Android roll and not change any behavior for Android
- create two Android CLs - one in CTS to use the new images, and one in
external/skia to delete SK_SUPPORT_LEGACY_FEATURE. Set them to the same
topic and land them with TreeHugger
In the new process, there is no need to mess with the Android roll.
A downside to the new process is that we cannot test the android
framework defines without checking in to Android. But given how much
we've progressed in automating Android testing, this is fine.
Bug: b/63429612
Change-Id: Idfbaef2f4cae641a75fb6e7bf70428733a441336
Reviewed-on: https://skia-review.googlesource.com/22072
Commit-Queue: Leon Scroggins <scroggo@google.com>
Reviewed-by: Eric Boren <borenet@google.com>
2017-07-11 19:53:41 +00:00
|
|
|
print >>f, '// DO NOT MODIFY! This file is autogenerated by gn_to_bp.py.'
|
|
|
|
print >>f, '// If need to change a define, modify SkUserConfigManual.h'
|
2016-12-06 21:03:52 +00:00
|
|
|
print >>f, '#ifndef SkUserConfig_DEFINED'
|
|
|
|
print >>f, '#define SkUserConfig_DEFINED'
|
Stop adding Android-specific defines to SkUserConfig
Remove #defines that lived in gn_to_bp.py and
android_framework_defines.gni. These have been moved into a new file
in Android, SkUserConfigManual.h, in https://googleplex-android-review.git.corp.google.com/#/c/2519600/
Update gn_to_bp.py to include SkUserConfigManual.h, so it will still
result in using the same #defines.
Lately, we've found it difficult to guard changes behind a flag. e.g.
a change to drawing causes a CTS failure in Android, so we have to do
the following:
- put the change behind a flag, and add it to gn_to_bp.py or
android_framework_defines.gni
- generate new images on Android (by running CTS with external/skia
modified to not define the flag)
- create a CL in CTS that uses the new images
- land a CL in Skia that stops defining the flag
- when the Skia change lands, wait for the auto-roller to create a CL
that includes the change, stop the auto-roller, add the topic to the CTS
CL so the two can land at the same time
- land both Android changes (with TreeHugger)
- restart the Android auto-roller
With SkUserConfigManual.h (which lives in Android), the process will
be similar to Chromium:
- land a CL in Android's external/skia that defines a flag e.g.
SK_SUPPORT_LEGACY_FEATURE. Land without TreeHugger because it isn't used
in Skia and does not do anything
- land a change in Skia that changes behavior unless
SK_SUPPORT_LEGACY_FEATURE is defined. This will safely go through the
Android roll and not change any behavior for Android
- create two Android CLs - one in CTS to use the new images, and one in
external/skia to delete SK_SUPPORT_LEGACY_FEATURE. Set them to the same
topic and land them with TreeHugger
In the new process, there is no need to mess with the Android roll.
A downside to the new process is that we cannot test the android
framework defines without checking in to Android. But given how much
we've progressed in automating Android testing, this is fine.
Bug: b/63429612
Change-Id: Idfbaef2f4cae641a75fb6e7bf70428733a441336
Reviewed-on: https://skia-review.googlesource.com/22072
Commit-Queue: Leon Scroggins <scroggo@google.com>
Reviewed-by: Eric Boren <borenet@google.com>
2017-07-11 19:53:41 +00:00
|
|
|
print >>f, '#include "SkUserConfigManual.h"'
|
2016-12-07 17:27:56 +00:00
|
|
|
for define in sorted(defines):
|
2016-12-12 14:03:56 +00:00
|
|
|
print >>f, ' #define', define.replace('=', ' ')
|
2016-12-06 21:03:52 +00:00
|
|
|
print >>f, '#endif//SkUserConfig_DEFINED'
|