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 10 import json 11 import os 12 import pprint 13 import string 14 import subprocess 15 import tempfile 16 17 import gn_to_bp_utils 18 19 # First we start off with a template for Android.bp, 20 # with holes for source lists and include directories. 21 bp = string.Template('''// This file is autogenerated by gn_to_bp.py. 22 23 cc_library_static { 24 name: "libskia", 25 cflags: [ 26 $cflags 27 ], 28 29 cppflags:[ 30 $cflags_cc 31 ], 32 33 export_include_dirs: [ 34 $export_includes 35 ], 36 37 local_include_dirs: [ 38 $local_includes 39 ], 40 41 srcs: [ 42 $srcs 43 ], 44 45 arch: { 46 arm: { 47 srcs: [ 48 $arm_srcs 49 ], 50 51 neon: { 52 srcs: [ 53 $arm_neon_srcs 54 ], 55 }, 56 }, 57 58 arm64: { 59 srcs: [ 60 $arm64_srcs 61 ], 62 }, 63 64 mips: { 65 srcs: [ 66 $none_srcs 67 ], 68 }, 69 70 mips64: { 71 srcs: [ 72 $none_srcs 73 ], 74 }, 75 76 x86: { 77 srcs: [ 78 $x86_srcs 79 ], 80 cflags: [ 81 // Clang seems to think new/malloc will only be 4-byte aligned 82 // on x86 Android. We're pretty sure it's actually 8-byte 83 // alignment. tests/OverAlignedTest.cpp has more information, 84 // and should fail if we're wrong. 85 "-Wno-over-aligned" 86 ], 87 }, 88 89 x86_64: { 90 srcs: [ 91 $x86_srcs 92 ], 93 }, 94 }, 95 96 defaults: ["skia_deps", 97 "skia_pgo", 98 ], 99 } 100 101 // Build libskia with PGO by default. 102 // Location of PGO profile data is defined in build/soong/cc/pgo.go 103 // and is separate from skia. 104 // To turn it off, set ANDROID_PGO_NO_PROFILE_USE environment variable 105 // or set enable_profile_use property to false. 106 cc_defaults { 107 name: "skia_pgo", 108 pgo: { 109 instrumentation: true, 110 profile_file: "hwui/hwui.profdata", 111 benchmarks: ["hwui", "skia"], 112 enable_profile_use: true, 113 }, 114 } 115 116 // "defaults" property to disable profile use for Skia tools and benchmarks. 117 cc_defaults { 118 name: "skia_pgo_no_profile_use", 119 defaults: [ 120 "skia_pgo", 121 ], 122 pgo: { 123 enable_profile_use: false, 124 }, 125 } 126 127 cc_defaults { 128 name: "skia_deps", 129 shared_libs: [ 130 "libEGL", 131 "libGLESv2", 132 "libdng_sdk", 133 "libexpat", 134 "libft2", 135 "libheif", 136 "libicui18n", 137 "libicuuc", 138 "libjpeg", 139 "liblog", 140 "libpiex", 141 "libpng", 142 "libvulkan", 143 "libz", 144 "libcutils", 145 "libnativewindow", 146 ], 147 static_libs: [ 148 "libarect", 149 "libsfntly", 150 "libwebp-decode", 151 "libwebp-encode", 152 ], 153 group_static_libs: true, 154 } 155 156 cc_defaults { 157 name: "skia_tool_deps", 158 defaults: [ 159 "skia_deps", 160 "skia_pgo_no_profile_use" 161 ], 162 static_libs: [ 163 "libjsoncpp", 164 "libskia", 165 ], 166 cflags: [ 167 "-Wno-unused-parameter", 168 "-Wno-unused-variable", 169 ], 170 } 171 172 cc_test { 173 name: "skia_dm", 174 175 defaults: [ 176 "skia_tool_deps" 177 ], 178 179 local_include_dirs: [ 180 $dm_includes 181 ], 182 183 srcs: [ 184 $dm_srcs 185 ], 186 187 shared_libs: [ 188 "libbinder", 189 "libutils", 190 ], 191 } 192 193 cc_test { 194 name: "skia_nanobench", 195 196 defaults: [ 197 "skia_tool_deps" 198 ], 199 200 local_include_dirs: [ 201 $nanobench_includes 202 ], 203 204 srcs: [ 205 $nanobench_srcs 206 ], 207 208 data: [ 209 "resources/*", 210 ], 211 }''') 212 213 # We'll run GN to get the main source lists and include directories for Skia. 214 gn_args = { 215 'is_official_build': 'true', 216 'skia_enable_tools': 'true', 217 'skia_use_libheif': 'true', 218 'skia_use_vulkan': 'true', 219 'target_cpu': '"none"', 220 'target_os': '"android"', 221 'skia_vulkan_header': '"Skia_Vulkan_Android.h"', 222 } 223 224 js = gn_to_bp_utils.GenerateJSONFromGN(gn_args) 225 226 def strip_slashes(lst): 227 return {str(p.lstrip('/')) for p in lst} 228 229 srcs = strip_slashes(js['targets']['//:skia']['sources']) 230 cflags = strip_slashes(js['targets']['//:skia']['cflags']) 231 cflags_cc = strip_slashes(js['targets']['//:skia']['cflags_cc']) 232 local_includes = strip_slashes(js['targets']['//:skia']['include_dirs']) 233 export_includes = strip_slashes(js['targets']['//:public']['include_dirs']) 234 defines = [str(d) for d in js['targets']['//:skia']['defines']] 235 236 dm_srcs = strip_slashes(js['targets']['//:dm']['sources']) 237 dm_includes = strip_slashes(js['targets']['//:dm']['include_dirs']) 238 239 nanobench_target = js['targets']['//:nanobench'] 240 nanobench_srcs = strip_slashes(nanobench_target['sources']) 241 nanobench_includes = strip_slashes(nanobench_target['include_dirs']) 242 243 gn_to_bp_utils.GrabDependentValues(js, '//:skia', 'sources', srcs, None) 244 gn_to_bp_utils.GrabDependentValues(js, '//:dm', 'sources', dm_srcs, 'skia') 245 gn_to_bp_utils.GrabDependentValues(js, '//:nanobench', 'sources', 246 nanobench_srcs, 'skia') 247 248 # No need to list headers. 249 srcs = {s for s in srcs if not s.endswith('.h')} 250 dm_srcs = {s for s in dm_srcs if not s.endswith('.h')} 251 nanobench_srcs = {s for s in nanobench_srcs if not s.endswith('.h')} 252 253 cflags = gn_to_bp_utils.CleanupCFlags(cflags) 254 cflags_cc = gn_to_bp_utils.CleanupCCFlags(cflags_cc) 255 256 # We need to add the include path to the vulkan defines and header file set in 257 # then skia_vulkan_header gn arg that is used for framework builds. 258 local_includes.add("platform_tools/android/vulkan") 259 export_includes.add("platform_tools/android/vulkan") 260 261 here = os.path.dirname(__file__) 262 defs = gn_to_bp_utils.GetArchSources(os.path.join(here, 'opts.gni')) 263 264 gn_to_bp_utils.WriteUserConfig('include/config/SkUserConfig.h', defines) 265 266 # Turn a list of strings into the style bpfmt outputs. 267 def bpfmt(indent, lst, sort=True): 268 if sort: 269 lst = sorted(lst) 270 return ('\n' + ' '*indent).join('"%s",' % v for v in lst) 271 272 # OK! We have everything to fill in Android.bp... 273 with open('Android.bp', 'w') as f: 274 print >>f, bp.substitute({ 275 'export_includes': bpfmt(8, export_includes), 276 'local_includes': bpfmt(8, local_includes), 277 'srcs': bpfmt(8, srcs), 278 'cflags': bpfmt(8, cflags, False), 279 'cflags_cc': bpfmt(8, cflags_cc), 280 281 'arm_srcs': bpfmt(16, defs['armv7']), 282 'arm_neon_srcs': bpfmt(20, defs['neon']), 283 'arm64_srcs': bpfmt(16, defs['arm64'] + 284 defs['crc32']), 285 'none_srcs': bpfmt(16, defs['none']), 286 'x86_srcs': bpfmt(16, defs['sse2'] + 287 defs['ssse3'] + 288 defs['sse41'] + 289 defs['sse42'] + 290 defs['avx' ]), 291 292 'dm_includes' : bpfmt(8, dm_includes), 293 'dm_srcs' : bpfmt(8, dm_srcs), 294 295 'nanobench_includes' : bpfmt(8, nanobench_includes), 296 'nanobench_srcs' : bpfmt(8, nanobench_srcs), 297 }) 298