blob: 91fec4c28862632eabb4fc7ca0c227516bb9f4c7 [file] [log] [blame]
Derek Sollenberger5d3f7702018-02-01 09:22:53 -05001#!/usr/bin/env python
2#
3# Copyright 2018 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
10import argparse
11import json
12import os
13import pprint
14import string
15import subprocess
16import tempfile
17
18parser = argparse.ArgumentParser(description='Process some cmdline flags.')
19parser.add_argument('--gn', dest='gn_cmd', default='gn')
20args = parser.parse_args()
21
22def GenerateJSONFromGN(gn_args):
23 gn_args = ' '.join(sorted('%s=%s' % (k,v) for (k,v) in gn_args.iteritems()))
24 tmp = tempfile.mkdtemp()
25 subprocess.check_call([args.gn_cmd, 'gen', tmp, '--args=%s' % gn_args,
26 '--ide=json'])
27 return json.load(open(os.path.join(tmp, 'project.json')))
28
29def _strip_slash(lst):
30 return {str(p.lstrip('/')) for p in lst}
31
32def GrabDependentValues(js, name, value_type, list_to_extend, exclude):
33 # Grab the values from other targets that $name depends on (e.g. optional
34 # Skia components, gms, tests, etc).
35 for dep in js['targets'][name]['deps']:
Florin Malita46fbf8c2018-06-10 01:18:28 -040036 if 'modules' in dep:
37 continue # Modules require special handling -- skip for now.
Derek Sollenberger5d3f7702018-02-01 09:22:53 -050038 if 'third_party' in dep:
39 continue # We've handled all third-party DEPS as static or shared_libs.
40 if 'none' in dep:
41 continue # We'll handle all cpu-specific sources manually later.
42 if exclude and exclude in dep:
43 continue
44 list_to_extend.update(_strip_slash(js['targets'][dep].get(value_type, [])))
45 GrabDependentValues(js, dep, value_type, list_to_extend, exclude)
46
47def CleanupCFlags(cflags):
48 # Only use the generated flags related to warnings.
49 cflags = {s for s in cflags if s.startswith('-W')}
Greg Daniel18dbfd02018-05-29 10:46:51 -040050 # Add additional warning suppressions so we can build
51 # third_party/vulkanmemoryallocator
52 cflags = cflags.union([
53 "-Wno-thread-safety-analysis",
54 "-Wno-missing-field-initializers",
55 "-Wno-unused-variable",
56 ])
Derek Sollenberger5d3f7702018-02-01 09:22:53 -050057 # Add the rest of the flags we want.
58 cflags = cflags.union([
59 "-fvisibility=hidden",
60 "-D_FORTIFY_SOURCE=1",
61 "-DSKIA_DLL",
62 "-DSKIA_IMPLEMENTATION=1",
63 "-DATRACE_TAG=ATRACE_TAG_VIEW",
Derek Sollenberger5d3f7702018-02-01 09:22:53 -050064 "-DSK_PRINT_CODEC_MESSAGES",
65 ])
66
67 # We need to undefine FORTIFY_SOURCE before we define it. Insert it at the
68 # beginning after sorting.
69 cflags = sorted(cflags)
70 cflags.insert(0, "-U_FORTIFY_SOURCE")
71 return cflags
72
73def CleanupCCFlags(cflags_cc):
74 # Only use the generated flags related to warnings.
75 cflags_cc = {s for s in cflags_cc if s.startswith('-W')}
76 # Add the rest of the flags we want.
77 cflags_cc.add("-fexceptions")
78 return cflags_cc
79
80def _get_path_info(path, kind):
81 assert path == "../src"
82 assert kind == "abspath"
83 # While we want absolute paths in GN, relative paths work best here.
84 return "src"
85
86def GetArchSources(opts_file):
87 # For architecture specific files, it's easier to just read the same source
88 # that GN does (opts.gni) rather than re-run GN once for each architecture.
89
90 # This .gni file we want to read is close enough to Python syntax
91 # that we can use execfile() if we supply definitions for GN builtins.
92 builtins = { 'get_path_info': _get_path_info }
93 defs = {}
94 execfile(opts_file, builtins, defs)
95
96 # Perform any string substitutions.
97 for arch in defs:
98 defs[arch] = [ p.replace('$_src', 'src') for p in defs[arch]]
99
100 return defs
101
102def WriteUserConfig(userConfigPath, defines):
103 # Most defines go into SkUserConfig.h
104 defines.remove('NDEBUG') # Controlled by the Android build
105 defines.remove('SKIA_IMPLEMENTATION=1') # don't export this define.
106
107 #... and all the #defines we want to put in SkUserConfig.h.
108 with open(userConfigPath, 'w') as f:
109 print >>f, '// DO NOT MODIFY! This file is autogenerated by gn_to_bp.py.'
110 print >>f, '// If need to change a define, modify SkUserConfigManual.h'
111 print >>f, '#ifndef SkUserConfig_DEFINED'
112 print >>f, '#define SkUserConfig_DEFINED'
113 print >>f, '#include "SkUserConfigManual.h"'
114 for define in sorted(defines):
115 print >>f, ' #define', define.replace('=', ' ')
116 print >>f, '#endif//SkUserConfig_DEFINED'