1#!/usr/bin/env python
2
3import json
4import sys
5
6# Set this to True to generate a default entry with all the flags and defines
7# common to all the modules that needs to be curated by hand after it's
8# generated. When set to False it prints the last curated version of the
9# default, which could be incomplete.
10GENERATE_FULL_DEFAULT = False
11PRINT_ORIGINALS = False
12GENERATE_ALL_FLAGS = False
13
14if len(sys.argv) != 2:
15    print('wrong number of arguments')
16    exit()
17
18def FormatList(l):
19    return json.dumps(l)
20
21def FilterHeaders(l):
22    return [x for x in l if not x.endswith('.h')]
23
24def PrintOriginCommentedOut(target):
25    if PRINT_ORIGINALS:
26        print('/* From target:')
27        print(json.dumps(target, sort_keys = True, indent = 4))
28        print('*/')
29
30def MakeRelatives(l):
31    return [x.split('//').pop() for x in l]
32
33def FormatName(name):
34    return 'webrtc_' + name.split('/').pop().replace(':', '__')# .replace('/', '_').replace(':', '_')
35
36def FilterFlags(flags, to_skip = set([])):
37    if GENERATE_ALL_FLAGS:
38        skip = set([
39            '-L',
40            '-isystem',
41            '-Xclang',
42            '-B',
43            '--sysroot',
44            '-fcrash-diagnostics-dir',
45            '.',
46            '-fdebug-compilation-dir',
47            '-instcombine-lower-dbg-declare=0',
48            '-Wno-non-c-typedef-for-linkage',
49            '-Werror',
50            '-fcomplete-member-pointers',
51            '-m64',
52            '-march=x86-64'
53            ]).union(to_skip)
54        return [x for x in flags if not any([x.startswith(y) for y in skip])]
55    else:
56        return [x for x in flags if x == '-msse2']
57
58def GenerateDefault(targets):
59    in_default = {
60            'cflags' : [],
61            'cflags_c' : [],
62            'cflags_cc' : [],
63            'ldflags' : [],
64            'asmflags' : [],
65            'defines' : []
66    }
67    first = True
68    for target in targets:
69        typ = target['type']
70        if typ == 'static_library':
71            if first:
72                first = False
73                # Add all the flags to the default, we'll remove some later
74                for flag_type in in_default.keys():
75                    in_default[flag_type] = []
76                    for flag in target[flag_type]:
77                        in_default[flag_type].append(flag)
78            else:
79                for flag_type in in_default.keys():
80                    flags_to_remove = []
81                    for flag in in_default[flag_type]:
82                        if flag not in target[flag_type]:
83                            flags_to_remove.append[flag_type]
84                    for flag in flags_to_remove:
85                        in_default[flag_type].remove(flag)
86    defines = in_default['defines']
87    in_default.pop('defines')
88    in_default['cflags'].extend(['-D{0}'.format(x) for x in defines])
89    if GENERATE_FULL_DEFAULT:
90        print('cc_defaults {')
91        print('    name: "webrtc_defaults",')
92        print('    local_include_dirs: ["."],')
93        for typ in in_default.keys():
94            print('    {0}: ['.format(typ.replace('asmflags', 'asflags')
95                .replace('cflags_cc', 'cppflags')
96                .replace('cflags_c', 'conlyflags')))
97            for flag in FilterFlags(in_default[typ]):
98                print('        "{0}",'.format(flag.replace('"', '\\"')))
99            print('    ],')
100        print('}')
101    else:
102        print('cc_defaults {')
103        print('    name: "webrtc_defaults",')
104        print('    local_include_dirs: [')
105        print('      ".",')
106        print('    ],')
107        print('    cflags: [')
108        print('        "-Wno-unused-parameter",')
109        print('        "-Wno-missing-field-initializers",')
110        print('        "-DUSE_UDEV",')
111        print('        "-DUSE_AURA=1",')
112        print('        "-DUSE_GLIB=1",')
113        print('        "-DUSE_NSS_CERTS=1",')
114        print('        "-DUSE_X11=1",')
115        print('        "-D_FILE_OFFSET_BITS=64",')
116        print('        "-D_LARGEFILE_SOURCE",')
117        print('        "-D_LARGEFILE64_SOURCE",')
118        print('        "-D_GNU_SOURCE",')
119        print('        "-DWEBRTC_ENABLE_PROTOBUF=0",')
120        print('        "-DWEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE",')
121        print('        "-DRTC_ENABLE_VP9",')
122        print('        "-DHAVE_SCTP",')
123        print('        "-DWEBRTC_LIBRARY_IMPL",')
124        print('        "-DWEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS=1",')
125        print('        "-DWEBRTC_POSIX",')
126        print('        "-DWEBRTC_LINUX",')
127        print('    ],')
128        print('    header_libs: [')
129        print('      "libwebrtc_absl_headers",')
130        print('    ],')
131        print('    static_libs: [')
132        print('        "libaom",')
133        print('        "libevent",')
134        print('        "libopus",')
135        print('        "libsrtp2",')
136        print('        "libvpx",')
137        print('        "libyuv",')
138        print('        "libpffft",')
139        print('        "rnnoise_rnn_vad",')
140        print('        "usrsctplib",')
141        print('    ],')
142        print('    shared_libs: [')
143        print('        "libcrypto",')
144        print('        "libssl",')
145        print('    ],')
146        print('    host_supported: true,')
147        print('    device_supported: false,')
148        print('    arch: {')
149        print('        arm: {')
150        print('            enabled: false,')
151        print('        },')
152        print('    },')
153        print('    target: {')
154        print('        darwin: {')
155        print('            enabled: false,')
156        print('        },')
157        print('    },')
158        print('}')
159    in_default['cflags'].extend([
160        "-Wno-unused-parameter",
161        "-Wno-missing-field-initializers",
162        "-DUSE_UDEV",
163        "-DUSE_AURA=1",
164        "-DUSE_GLIB=1",
165        "-DUSE_NSS_CERTS=1",
166        "-DUSE_X11=1",
167        "-D_FILE_OFFSET_BITS=64",
168        "-D_LARGEFILE_SOURCE",
169        "-D_LARGEFILE64_SOURCE",
170        "-D_GNU_SOURCE",
171        "-DWEBRTC_ENABLE_PROTOBUF=0",
172        "-DWEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE",
173        "-DRTC_ENABLE_VP9",
174        "-DHAVE_SCTP",
175        "-DWEBRTC_LIBRARY_IMPL",
176        "-DWEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS=1",
177        "-DWEBRTC_POSIX",
178        "-DWEBRTC_LINUX"
179        ])
180    return in_default
181
182def GenerateGroup(target):
183    PrintOriginCommentedOut(target)
184
185def GenerateSourceSet(target):
186    PrintOriginCommentedOut(target)
187    if target.has_key('sources'):
188        name = FormatName(target['name'])
189        print('filegroup {')
190        print('    name: "{0}",'.format(name))
191        print('    srcs: {0},'.format(FormatList(MakeRelatives(FilterHeaders(target['sources'])))))
192        print('}')
193        return name
194    return ""
195
196def GenerateStaticLib(target, targets, flags_in_default):
197    PrintOriginCommentedOut(target)
198    name = FormatName(target['name'])
199    print('cc_library_static {')
200    print('    name: "{0}",'.format(name))
201    print('    defaults: ["webrtc_defaults"],')
202    sources = []
203    sources.extend(MakeRelatives(FilterHeaders(target['sources'])))
204    for trg in targets:
205        if trg['type'] == 'source_set' and trg['name'] in target['deps']:
206            sources.append(':' + FormatName(trg['name']))
207    print('    srcs: {0},'.format(FormatList(sources)))
208    print('    host_supported: true,')
209    if target.has_key('asmflags'):
210        asmflags = FilterFlags(target['asmflags'], set(flags_in_default['asmflags']))
211        if len(asmflags) > 0:
212            print('    asflags: {0},'.format(FormatList(asmflags)))
213    cflags = []
214    if target.has_key('cflags'):
215        cflags.extend(target['cflags'])
216    cflags = FilterFlags(cflags, set(flags_in_default['cflags']))
217    if target.has_key('defines'):
218        cflags.extend(['-D' + x for x in target['defines']])
219    cflags = [x for x in cflags if x not in flags_in_default['cflags']]
220    if len(cflags) > 0:
221        print('    cflags: {0},'.format(FormatList(cflags)))
222    if target.has_key('cflags_c'):
223        cflags_c = FilterFlags(target['cflags_c'], set(flags_in_default['cflags_c']))
224        if len(cflags_c) > 0:
225            print('    conlyflags: {0},'.format(FormatList(cflags_c)))
226    if target.has_key('cflags_cc'):
227        cflags_cc = FilterFlags(target['cflags_cc'], set(flags_in_default['cflags_cc']))
228        if len(cflags_cc) > 0:
229            print('    cppflags: {0},'.format(FormatList(cflags_cc)))
230    if target.has_key('ldflags'):
231        ldflags = FilterFlags(target['ldflags'], set(flags_in_default['ldflags']))
232        if len(ldflags) > 0:
233            print('    ldflags: {0},'.format(FormatList(ldflags)))
234    static_libs = []
235    for trg in targets:
236        if trg['type'] == 'static_library' and target['deps'].count(trg['name']) > 0:
237            static_libs.append(FormatName(trg['name']))
238    if len(static_libs) > 0:
239        print('    static_libs: {0},'.format(FormatList(static_libs)))
240    for dep in target['deps']:
241        if FormatName(dep) not in static_libs:
242            #print('    // omitted dep: {0}'.format(dep))
243            pass
244    print('}')
245    return name
246
247json_file = open(sys.argv[1], "r")
248targets = json.load(json_file)
249
250flags_in_default = GenerateDefault(targets)
251print("\n\n")
252
253static_libs = []
254file_groups = []
255
256for target in targets:
257    typ = target['type']
258    if typ == 'static_library':
259        lib_name = GenerateStaticLib(target, targets, flags_in_default)
260        static_libs.append(lib_name)
261    elif typ == 'source_set':
262        group_name = GenerateSourceSet(target)
263        if len(group_name) > 0:
264          file_groups.append(group_name)
265    elif typ == 'group':
266        GenerateGroup(target)
267    else:
268        print('Unknown type: {0}'.format(typ))
269    print("\n\n")
270
271print('cc_library_static {')
272print('    name: "libwebrtc",')
273print('    defaults: ["webrtc_defaults"],')
274print('    export_include_dirs: ["."],')
275print('    whole_static_libs: {0},'.format(FormatList(static_libs + ['libpffft', 'rnnoise_rnn_vad', 'usrsctplib'])))
276print('    srcs: {0},').format(FormatList([':{0}'.format(x) for x in file_groups]))
277print('}')
278