blob: 834dd4b1767c332eab6224d7d8238fc6bb9093b4 [file] [log] [blame]
Erwin Jansenf96db3c2018-10-25 23:28:54 -07001#!/bin/python
2import argparse
3import json
4import logging
5import os
6import sys
7
8
9def cleanup_json(data):
10 """Cleans up the json structure by removing empty "", and empty key value
11 pairs."""
12 if (isinstance(data, unicode)):
13 copy = data.strip()
14 return None if len(copy) == 0 else copy
15
16 if (isinstance(data, dict)):
17 copy = {}
18 for key, value in data.iteritems():
19 rem = cleanup_json(value)
20 if (rem is not None):
21 copy[key] = rem
22 return None if len(copy) == 0 else copy
23
24 if (isinstance(data, list)):
25 copy = []
26 for elem in data:
27 rem = cleanup_json(elem)
28 if (rem is not None):
29 if rem not in copy:
30 copy.append(rem)
31
32 if len(copy) == 0:
33 return None
34 return copy
35
36
37class AttrDict(dict):
38 def __init__(self, *args, **kwargs):
39 super(AttrDict, self).__init__(*args, **kwargs)
40 self.__dict__ = self
41
42 def as_list(self, name):
43 v = self.get(name, [])
44 if (isinstance(v, list)):
45 return v
46
47 return [v]
48
49
50def remove_lib_prefix(module):
51 """Removes the lib prefix, as we are not using them in CMake."""
52 if module.startswith('lib'):
53 return module[3:]
54 else:
55 return module
56
57
58def escape(msg):
59 """Escapes the "."""
60 return '"' + msg.replace('"', '\\"') + '"'
61
62
63def header():
64 """The auto generate header."""
65 return [
66 '# This is an autogenerated file! Do not edit!',
67 '# instead run make from .../device/generic/goldfish-opengl',
68 '# which will re-generate this file.'
69 ]
70
71
72def generate_module(module):
73 """Generates a cmake module."""
74 name = remove_lib_prefix(module['module'])
75 make = header()
76 make.append('set(%s_src %s)' % (name, ' '.join(module['src'])))
77 if module['type'] == 'SHARED_LIBRARY':
78 make.append('android_add_shared_library(%s)' % name)
Lingfeng Yangd7447042018-10-25 11:09:18 -070079 elif module['type'] == 'STATIC_LIBRARY':
80 make.append('android_add_library(%s)' % name)
Erwin Jansenf96db3c2018-10-25 23:28:54 -070081 else:
82 raise ValueError('Unexpected module type: %s' % module['type'])
83
84 # Fix up the includes.
85 includes = ['${GOLDFISH_DEVICE_ROOT}/' + s for s in module['includes']]
86 make.append('target_include_directories(%s PRIVATE %s)' %
87 (name, ' '.join(includes)))
88
89 # filter out definitions
90 defs = [escape(d) for d in module['cflags'] if d.startswith('-D')]
91
92 # And the remaining flags.
93 flags = [escape(d) for d in module['cflags'] if not d.startswith('-D')]
94
95 # Make sure we remove the lib prefix from all our dependencies.
96 libs = [remove_lib_prefix(l) for l in module['libs']]
Lingfeng Yangf4d77ef2018-11-02 23:21:37 -070097 staticlibs = [remove_lib_prefix(l) for l in
98 module.get('staticlibs', [])
99 if l != "libandroidemu"]
Erwin Jansenf96db3c2018-10-25 23:28:54 -0700100
101 # Configure the target.
102 make.append('target_compile_definitions(%s PRIVATE %s)' %
103 (name, ' '.join(defs)))
104 make.append('target_compile_options(%s PRIVATE %s)' %
105 (name, ' '.join(flags)))
Lingfeng Yangf4d77ef2018-11-02 23:21:37 -0700106
107 if len(staticlibs) > 0:
108 make.append('target_link_libraries(%s PRIVATE %s PRIVATE %s)' %
109 (name, ' '.join(libs), " ".join(staticlibs)))
110 else:
111 make.append('target_link_libraries(%s PRIVATE %s)' %
112 (name, ' '.join(libs)))
Erwin Jansenf96db3c2018-10-25 23:28:54 -0700113 return make
114
115
116def main(argv=None):
117 parser = argparse.ArgumentParser(
118 description='Generates a set of cmake files'
119 'based up the js representation.'
120 'Use this to generate cmake files that can be consumed by the emulator build')
121 parser.add_argument('-i', '--input', dest='input', type=str, required=True,
122 help='json file containing the build tree')
123 parser.add_argument('-v', '--verbose',
124 action='store_const', dest='loglevel',
125 const=logging.INFO, default=logging.ERROR,
126 help='Log what is happening')
127 parser.add_argument('-o', '--output',
128 dest='outdir', type=str, default=None,
129 help='Output directory for create CMakefile.txt')
130 parser.add_argument('-c', '--clean', dest='output', type=str,
131 default=None,
132 help='Write out the cleaned up js')
133 args = parser.parse_args()
134
135 logging.basicConfig(level=args.loglevel)
136
137 with open(args.input) as data_file:
138 data = json.load(data_file)
139
140 modules = cleanup_json(data)
141
142 # Write out cleaned up json, mainly useful for debugging etc.
143 if (args.output is not None):
144 with open(args.output, 'w') as out_file:
145 out_file.write(json.dumps(modules, indent=2))
146
147 # Location --> CMakeLists.txt
148 cmake = {}
149
150 # The root, it will basically just include all the generated files.
151 root = os.path.join(args.outdir, 'CMakeLists.txt')
152 cmake[root] = header()
153 cmake[root].append('set(GOLDFISH_DEVICE_ROOT ${CMAKE_CURRENT_SOURCE_DIR})')
154
155 # Generate the modules.
156 for module in modules:
157 location = os.path.join(args.outdir, module['path'], 'CMakeLists.txt')
158
159 # Make sure we handle the case where we have >2 modules in the same dir.
160 if location not in cmake:
161 cmake[root].append('add_subdirectory(%s)' % module['path'])
162 cmake[location] = []
163 cmake[location].extend(generate_module(module))
164
165 # Write them to disk.
166 for (loc, cmklist) in cmake.iteritems():
167 logging.info('Writing to %s', loc)
168 with open(loc, 'w') as fn:
169 fn.write('\n'.join(cmklist))
170
171
172if __name__ == '__main__':
173 sys.exit(main())