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