1*c8dee2aaSAndroid Build Coastguard Worker#!/usr/bin/env python 2*c8dee2aaSAndroid Build Coastguard Worker# 3*c8dee2aaSAndroid Build Coastguard Worker# Copyright 2018 Google Inc. 4*c8dee2aaSAndroid Build Coastguard Worker# 5*c8dee2aaSAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 6*c8dee2aaSAndroid Build Coastguard Worker# found in the LICENSE file. 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker# Generate Android.bp for Skia from GN configuration. 9*c8dee2aaSAndroid Build Coastguard Worker 10*c8dee2aaSAndroid Build Coastguard Workerfrom __future__ import print_function 11*c8dee2aaSAndroid Build Coastguard Worker 12*c8dee2aaSAndroid Build Coastguard Workerimport argparse 13*c8dee2aaSAndroid Build Coastguard Workerimport json 14*c8dee2aaSAndroid Build Coastguard Workerimport os 15*c8dee2aaSAndroid Build Coastguard Workerimport pprint 16*c8dee2aaSAndroid Build Coastguard Workerimport string 17*c8dee2aaSAndroid Build Coastguard Workerimport subprocess 18*c8dee2aaSAndroid Build Coastguard Workerimport tempfile 19*c8dee2aaSAndroid Build Coastguard Worker 20*c8dee2aaSAndroid Build Coastguard Workerparser = argparse.ArgumentParser(description='Process some cmdline flags.') 21*c8dee2aaSAndroid Build Coastguard Workerparser.add_argument('--gn', dest='gn_cmd', default='gn') 22*c8dee2aaSAndroid Build Coastguard Workerargs = parser.parse_args() 23*c8dee2aaSAndroid Build Coastguard Worker 24*c8dee2aaSAndroid Build Coastguard Workerdef GenerateJSONFromGN(gn_args): 25*c8dee2aaSAndroid Build Coastguard Worker gn_args = ' '.join(sorted('%s=%s' % (k,v) for (k,v) in iter(gn_args.items()))) 26*c8dee2aaSAndroid Build Coastguard Worker tmp = tempfile.mkdtemp() 27*c8dee2aaSAndroid Build Coastguard Worker subprocess.check_call([args.gn_cmd, 'gen', tmp, '--args=%s' % gn_args, 28*c8dee2aaSAndroid Build Coastguard Worker '--ide=json']) 29*c8dee2aaSAndroid Build Coastguard Worker return json.load(open(os.path.join(tmp, 'project.json'))) 30*c8dee2aaSAndroid Build Coastguard Worker 31*c8dee2aaSAndroid Build Coastguard Workerdef _strip_slash(lst): 32*c8dee2aaSAndroid Build Coastguard Worker return {str(p.lstrip('/')) for p in lst} 33*c8dee2aaSAndroid Build Coastguard Worker 34*c8dee2aaSAndroid Build Coastguard Workerdef GrabDependentValues(js, name, value_type, list_to_extend, exclude): 35*c8dee2aaSAndroid Build Coastguard Worker # Grab the values from other targets that $name depends on (e.g. optional 36*c8dee2aaSAndroid Build Coastguard Worker # Skia components, gms, tests, etc). 37*c8dee2aaSAndroid Build Coastguard Worker for dep in js['targets'][name]['deps']: 38*c8dee2aaSAndroid Build Coastguard Worker if 'third_party' in dep: 39*c8dee2aaSAndroid Build Coastguard Worker continue # We've handled all third-party DEPS as static or shared_libs. 40*c8dee2aaSAndroid Build Coastguard Worker if 'none' in dep: 41*c8dee2aaSAndroid Build Coastguard Worker continue # We'll handle all cpu-specific sources manually later. 42*c8dee2aaSAndroid Build Coastguard Worker if exclude and isinstance(exclude, str) and exclude == dep: 43*c8dee2aaSAndroid Build Coastguard Worker continue 44*c8dee2aaSAndroid Build Coastguard Worker if exclude and isinstance(exclude, list) and dep in exclude: 45*c8dee2aaSAndroid Build Coastguard Worker continue 46*c8dee2aaSAndroid Build Coastguard Worker 47*c8dee2aaSAndroid Build Coastguard Worker list_to_extend.update(_strip_slash(js['targets'][dep].get(value_type, []))) 48*c8dee2aaSAndroid Build Coastguard Worker GrabDependentValues(js, dep, value_type, list_to_extend, exclude) 49*c8dee2aaSAndroid Build Coastguard Worker 50*c8dee2aaSAndroid Build Coastguard Workerdef CleanupCFlags(cflags): 51*c8dee2aaSAndroid Build Coastguard Worker # Only use the generated flags related to warnings. 52*c8dee2aaSAndroid Build Coastguard Worker cflags = {s for s in cflags if s.startswith('-W')} 53*c8dee2aaSAndroid Build Coastguard Worker # Add additional warning suppressions 54*c8dee2aaSAndroid Build Coastguard Worker # Some for third_party/vulkanmemoryallocator 55*c8dee2aaSAndroid Build Coastguard Worker # Some for Android's '-Wall -Werror' 56*c8dee2aaSAndroid Build Coastguard Worker cflags = cflags.union([ 57*c8dee2aaSAndroid Build Coastguard Worker "-Wno-implicit-fallthrough", 58*c8dee2aaSAndroid Build Coastguard Worker "-Wno-missing-field-initializers", 59*c8dee2aaSAndroid Build Coastguard Worker "-Wno-sign-conversion", 60*c8dee2aaSAndroid Build Coastguard Worker "-Wno-thread-safety-analysis", 61*c8dee2aaSAndroid Build Coastguard Worker "-Wno-unknown-warning-option", 62*c8dee2aaSAndroid Build Coastguard Worker "-Wno-unused-parameter", 63*c8dee2aaSAndroid Build Coastguard Worker "-Wno-unused-variable", 64*c8dee2aaSAndroid Build Coastguard Worker ]) 65*c8dee2aaSAndroid Build Coastguard Worker # Add the rest of the flags we want. 66*c8dee2aaSAndroid Build Coastguard Worker cflags = cflags.union([ 67*c8dee2aaSAndroid Build Coastguard Worker "-fvisibility=hidden", 68*c8dee2aaSAndroid Build Coastguard Worker "-D_FORTIFY_SOURCE=1", 69*c8dee2aaSAndroid Build Coastguard Worker "-DSKIA_DLL", 70*c8dee2aaSAndroid Build Coastguard Worker "-DSKIA_IMPLEMENTATION=1", 71*c8dee2aaSAndroid Build Coastguard Worker "-DATRACE_TAG=ATRACE_TAG_VIEW", 72*c8dee2aaSAndroid Build Coastguard Worker ]) 73*c8dee2aaSAndroid Build Coastguard Worker 74*c8dee2aaSAndroid Build Coastguard Worker # Android does not want -Weverything set, it blocks toolchain updates. 75*c8dee2aaSAndroid Build Coastguard Worker if "-Weverything" in cflags: 76*c8dee2aaSAndroid Build Coastguard Worker cflags.remove("-Weverything") 77*c8dee2aaSAndroid Build Coastguard Worker 78*c8dee2aaSAndroid Build Coastguard Worker # We need to undefine FORTIFY_SOURCE before we define it. Insert it at the 79*c8dee2aaSAndroid Build Coastguard Worker # beginning after sorting. 80*c8dee2aaSAndroid Build Coastguard Worker cflags = sorted(cflags) 81*c8dee2aaSAndroid Build Coastguard Worker cflags.insert(0, "-U_FORTIFY_SOURCE") 82*c8dee2aaSAndroid Build Coastguard Worker return cflags 83*c8dee2aaSAndroid Build Coastguard Worker 84*c8dee2aaSAndroid Build Coastguard Workerdef CleanupCCFlags(cflags_cc): 85*c8dee2aaSAndroid Build Coastguard Worker # Android does not want -Weverything set, it blocks toolchain updates. 86*c8dee2aaSAndroid Build Coastguard Worker if "-Weverything" in cflags_cc: 87*c8dee2aaSAndroid Build Coastguard Worker cflags_cc.remove("-Weverything") 88*c8dee2aaSAndroid Build Coastguard Worker 89*c8dee2aaSAndroid Build Coastguard Worker # Only use the generated flags related to warnings. 90*c8dee2aaSAndroid Build Coastguard Worker return {s for s in cflags_cc if s.startswith('-W')} 91*c8dee2aaSAndroid Build Coastguard Worker 92*c8dee2aaSAndroid Build Coastguard Workerdef _get_path_info(path, kind): 93*c8dee2aaSAndroid Build Coastguard Worker assert path == "../src" 94*c8dee2aaSAndroid Build Coastguard Worker assert kind == "abspath" 95*c8dee2aaSAndroid Build Coastguard Worker # While we want absolute paths in GN, relative paths work best here. 96*c8dee2aaSAndroid Build Coastguard Worker return "src" 97*c8dee2aaSAndroid Build Coastguard Worker 98*c8dee2aaSAndroid Build Coastguard Workerdef GetArchSources(opts_file): 99*c8dee2aaSAndroid Build Coastguard Worker # For architecture specific files, it's easier to just read the same source 100*c8dee2aaSAndroid Build Coastguard Worker # that GN does (opts.gni) rather than re-run GN once for each architecture. 101*c8dee2aaSAndroid Build Coastguard Worker 102*c8dee2aaSAndroid Build Coastguard Worker # This .gni file we want to read is close enough to Python syntax 103*c8dee2aaSAndroid Build Coastguard Worker # that we can use execfile() if we supply definitions for GN builtins. 104*c8dee2aaSAndroid Build Coastguard Worker builtins = { 'get_path_info': _get_path_info } 105*c8dee2aaSAndroid Build Coastguard Worker defs = {} 106*c8dee2aaSAndroid Build Coastguard Worker with open(opts_file) as f: 107*c8dee2aaSAndroid Build Coastguard Worker code = compile(f.read(), opts_file, 'exec') 108*c8dee2aaSAndroid Build Coastguard Worker exec(code, builtins, defs) 109*c8dee2aaSAndroid Build Coastguard Worker 110*c8dee2aaSAndroid Build Coastguard Worker # Perform any string substitutions. 111*c8dee2aaSAndroid Build Coastguard Worker for arch in defs: 112*c8dee2aaSAndroid Build Coastguard Worker defs[arch] = [ p.replace('$_src', 'src') for p in defs[arch]] 113*c8dee2aaSAndroid Build Coastguard Worker 114*c8dee2aaSAndroid Build Coastguard Worker return defs 115*c8dee2aaSAndroid Build Coastguard Worker 116*c8dee2aaSAndroid Build Coastguard Workerdef WriteUserConfig(userConfigPath, defines): 117*c8dee2aaSAndroid Build Coastguard Worker # Most defines go into SkUserConfig.h 118*c8dee2aaSAndroid Build Coastguard Worker defines.remove('NDEBUG') # Controlled by the Android build 119*c8dee2aaSAndroid Build Coastguard Worker defines.remove('SKIA_IMPLEMENTATION=1') # don't export this define. 120*c8dee2aaSAndroid Build Coastguard Worker if 'WIN32_LEAN_AND_MEAN' in defines: # Controlled by the Android build 121*c8dee2aaSAndroid Build Coastguard Worker defines.remove('WIN32_LEAN_AND_MEAN') 122*c8dee2aaSAndroid Build Coastguard Worker if '_HAS_EXCEPTIONS=0' in defines: # Controlled by the Android build 123*c8dee2aaSAndroid Build Coastguard Worker defines.remove('_HAS_EXCEPTIONS=0') 124*c8dee2aaSAndroid Build Coastguard Worker 125*c8dee2aaSAndroid Build Coastguard Worker #... and all the #defines we want to put in SkUserConfig.h. 126*c8dee2aaSAndroid Build Coastguard Worker with open(userConfigPath, 'w') as f: 127*c8dee2aaSAndroid Build Coastguard Worker print('// DO NOT MODIFY! This file is autogenerated by gn_to_bp.py.', file=f) 128*c8dee2aaSAndroid Build Coastguard Worker print('// If need to change a define, modify SkUserConfigManual.h', file=f) 129*c8dee2aaSAndroid Build Coastguard Worker print('#pragma once', file=f) 130*c8dee2aaSAndroid Build Coastguard Worker print('#include "SkUserConfigManual.h"', file=f) 131*c8dee2aaSAndroid Build Coastguard Worker 132*c8dee2aaSAndroid Build Coastguard Worker for define in sorted(defines): 133*c8dee2aaSAndroid Build Coastguard Worker print('', file=f) 134*c8dee2aaSAndroid Build Coastguard Worker print('#ifndef', define.split('=')[0], file=f) 135*c8dee2aaSAndroid Build Coastguard Worker print('#define', define.replace('=', ' ', 1), file=f) 136*c8dee2aaSAndroid Build Coastguard Worker print('#endif', file=f) 137