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 argparse 11 import json 12 import os 13 import pprint 14 import string 15 import subprocess 16 import sys 17 import tempfile 18 19 root_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 20 os.pardir, os.pardir) 21 skia_gn_dir = os.path.join(root_dir, 'gn') 22 sys.path.insert(0, skia_gn_dir) 23 24 import gn_to_bp_utils 25 26 # First we start off with a template for Android.bp, 27 # with holes for source lists and include directories. 28 bp = string.Template('''// This file is autogenerated by tools/skqp/gn_to_bp.py. 29 30 cc_library_shared { 31 name: "libskqp_app", 32 sdk_version: "26", 33 stl: "libc++_static", 34 tags: ["tests", "optional"], 35 36 cflags: [ 37 $cflags 38 "-Wno-unused-parameter", 39 "-Wno-unused-variable", 40 ], 41 42 cppflags:[ 43 $cflags_cc 44 ], 45 46 local_include_dirs: [ 47 $local_includes 48 ], 49 50 srcs: [ 51 $srcs 52 ], 53 54 arch: { 55 arm: { 56 srcs: [ 57 $arm_srcs 58 ], 59 60 neon: { 61 srcs: [ 62 $arm_neon_srcs 63 ], 64 }, 65 }, 66 67 arm64: { 68 srcs: [ 69 $arm64_srcs 70 ], 71 }, 72 73 mips: { 74 srcs: [ 75 $none_srcs 76 ], 77 }, 78 79 mips64: { 80 srcs: [ 81 $none_srcs 82 ], 83 }, 84 85 x86: { 86 srcs: [ 87 $x86_srcs 88 ], 89 cflags: [ 90 // Clang seems to think new/malloc will only be 4-byte aligned 91 // on x86 Android. We're pretty sure it's actually 8-byte 92 // alignment. tests/OverAlignedTest.cpp has more information, 93 // and should fail if we're wrong. 94 "-Wno-over-aligned" 95 ], 96 }, 97 98 x86_64: { 99 srcs: [ 100 $x86_srcs 101 ], 102 }, 103 }, 104 105 shared_libs: [ 106 "libandroid", 107 "libEGL", 108 "libGLESv2", 109 "liblog", 110 "libvulkan", 111 "libz", 112 ], 113 static_libs: [ 114 "libjpeg_static_ndk", 115 "libjsoncpp", 116 "libpng_ndk", 117 "libwebp-decode", 118 "libwebp-encode", 119 ] 120 }''') 121 122 # We'll run GN to get the main source lists and include directories for Skia. 123 gn_args = { 124 'target_cpu': '"none"', 125 'target_os': '"android"', 126 127 # setup skqp 128 'is_debug': 'false', 129 'ndk_api': '26', 130 'skia_skqp_global_error_tolerance': '4', 131 132 # setup vulkan 133 'skia_use_vulkan': 'true', 134 'skia_vulkan_header': '"Skia_Vulkan_Android.h"', 135 136 # enable/disable skia subsystems 137 'skia_enable_fontmgr_empty': 'true', 138 'skia_enable_pdf': 'false', 139 'skia_use_expat': 'false', 140 'skia_use_dng_sdk': 'false', 141 'skia_use_icu': 'false', 142 'skia_use_lua': 'false', 143 'skia_use_piex': 'false', 144 'skia_use_skcms': 'false', 145 146 # specify that the Android.bp will supply the necessary components 147 'skia_use_system_expat': 'true', # removed this when gn is fixed 148 'skia_use_system_libpng': 'true', 149 'skia_use_system_jsoncpp': 'true', 150 'skia_use_system_libwebp': 'true', 151 'skia_use_system_libjpeg_turbo': 'true', 152 'skia_use_system_zlib': 'true', 153 } 154 155 js = gn_to_bp_utils.GenerateJSONFromGN(gn_args) 156 157 def strip_slashes(lst): 158 return {str(p.lstrip('/')) for p in lst} 159 160 srcs = strip_slashes(js['targets']['//:libskqp_app']['sources']) 161 cflags = strip_slashes(js['targets']['//:libskqp_app']['cflags']) 162 cflags_cc = strip_slashes(js['targets']['//:libskqp_app']['cflags_cc']) 163 local_includes = strip_slashes(js['targets']['//:libskqp_app']['include_dirs']) 164 defines = {str(d) for d in js['targets']['//:libskqp_app']['defines']} 165 166 gn_to_bp_utils.GrabDependentValues(js, '//:libskqp_app', 'sources', srcs, None) 167 gn_to_bp_utils.GrabDependentValues(js, '//:libskqp_app', 'include_dirs', 168 local_includes, 'freetype') 169 gn_to_bp_utils.GrabDependentValues(js, '//:libskqp_app', 'defines', 170 defines, None) 171 172 # No need to list headers or other extra flags. 173 srcs = {s for s in srcs if not s.endswith('.h')} 174 cflags = gn_to_bp_utils.CleanupCFlags(cflags) 175 cflags_cc = gn_to_bp_utils.CleanupCCFlags(cflags_cc) 176 177 # We need to add the include path to the vulkan defines and header file set in 178 # then skia_vulkan_header gn arg that is used for framework builds. 179 local_includes.add("platform_tools/android/vulkan") 180 181 # Get architecture specific source files 182 defs = gn_to_bp_utils.GetArchSources(os.path.join(skia_gn_dir, 'opts.gni')) 183 184 # Add source file until fix lands in 185 # https://skia-review.googlesource.com/c/skia/+/101820 186 srcs.add("src/ports/SkFontMgr_empty_factory.cpp") 187 188 # Turn a list of strings into the style bpfmt outputs. 189 def bpfmt(indent, lst, sort=True): 190 if sort: 191 lst = sorted(lst) 192 return ('\n' + ' '*indent).join('"%s",' % v for v in lst) 193 194 # Most defines go into SkUserConfig.h, where they're seen by Skia and its users. 195 gn_to_bp_utils.WriteUserConfig('include/config/SkUserConfig.h', defines) 196 197 # OK! We have everything to fill in Android.bp... 198 with open('Android.bp', 'w') as f: 199 print >>f, bp.substitute({ 200 'local_includes': bpfmt(8, local_includes), 201 'srcs': bpfmt(8, srcs), 202 'cflags': bpfmt(8, cflags, False), 203 'cflags_cc': bpfmt(8, cflags_cc), 204 205 'arm_srcs': bpfmt(16, defs['armv7']), 206 'arm_neon_srcs': bpfmt(20, defs['neon']), 207 'arm64_srcs': bpfmt(16, defs['arm64'] + 208 defs['crc32']), 209 'none_srcs': bpfmt(16, defs['none']), 210 'x86_srcs': bpfmt(16, defs['sse2'] + 211 defs['ssse3'] + 212 defs['sse41'] + 213 defs['sse42'] + 214 defs['avx' ]), 215 }) 216 217