1#!/usr/bin/env python 2 3import json 4import os 5import sys 6 7PRINT_ORIGINAL_FULL = False 8 9# This flags are augmented with flags added to the json files but not present in .gn or .gni files 10IGNORED_FLAGS = [ 11 '-D_DEBUG', 12 '-Werror', 13 '-Xclang' 14 ] 15DEFAULT_CFLAGS = [ 16 '-DHAVE_ARM64_CRC32C=0', 17 '-DUSE_AURA=1', 18 '-DUSE_GLIB=1', 19 '-DUSE_NSS_CERTS=1', 20 '-DUSE_UDEV', 21 '-DUSE_X11=1', 22 '-DWEBRTC_ANDROID_PLATFORM_BUILD=1', 23 '-DWEBRTC_APM_DEBUG_DUMP=0', 24 '-D_FILE_OFFSET_BITS=64', 25 '-D_GNU_SOURCE', 26 '-D_LARGEFILE64_SOURCE', 27 '-D_LARGEFILE_SOURCE', 28 '-Wno-all', 29 '-Wno-error', 30 '-Wno-everything', 31 '-Wno-implicit-const-int-float-conversion', 32 '-Wno-missing-field-initializers', 33 '-Wno-unreachable-code-aggressive', 34 '-Wno-unreachable-code-break', 35] 36 37DEFAULT_CFLAGS_BY_ARCH = { 38 'x86': ['-mavx2', '-mfma', '-msse2', '-msse3'], 39 'x64': ['-mavx2', '-mfma', '-msse2', '-msse3'], 40 'arm': ['-mthumb'], 41 'arm64': [], 42 'riscv64': [], 43 } 44 45FLAGS = ['cflags', 'cflags_c', 'cflags_cc', 'asmflags'] 46FLAG_NAME_MAP = { 47 'cflags': 'cflags', 48 'asmflags': 'asflags', 49 'cflags_cc': 'cppflags', 50 'cflags_c': 'conlyflags', 51} 52 53ARCH_NAME_MAP = {n: n for n in DEFAULT_CFLAGS_BY_ARCH.keys()} 54ARCH_NAME_MAP['x64'] = 'x86_64' 55 56ARCHS = sorted(ARCH_NAME_MAP.keys()) 57 58def FormatList(l): 59 return json.dumps(sorted(list(l))) 60 61def IsInclude(name): 62 return name.endswith('.h') or name.endswith('.inc') 63 64def FilterIncludes(l): 65 return filter(lambda x: not IsInclude(x), l) 66 67def PrintOrigin(target): 68 print('/* From target:') 69 if PRINT_ORIGINAL_FULL: 70 print(json.dumps(target, sort_keys = True, indent = 4)) 71 else: 72 print(target['original_name']) 73 print('*/') 74 75def MakeRelatives(l): 76 return map(lambda x: x.split('//').pop(), l) 77 78def FormatName(name): 79 return 'webrtc_' + name.split('/').pop().replace(':', '__') 80 81def FormatNames(target): 82 target['original_name'] = target['name'] 83 target['name'] = FormatName(target['name']) 84 target['deps'] = sorted([FormatName(d) for d in target['deps']]) 85 target['sources'] = list(map(lambda s: (':' + FormatName(s[1:])) if s.startswith(':') else s, target['sources'])) 86 return target 87 88def FilterFlags(flags, to_skip = set()): 89 skipped_opts = set(IGNORED_FLAGS).union(to_skip) 90 return [x for x in flags if not any([x.startswith(y) for y in skipped_opts])] 91 92def PrintHeader(): 93 print('package {') 94 print(' default_applicable_licenses: ["external_webrtc_license"],') 95 print('}') 96 print('') 97 print('// Added automatically by a large-scale-change that took the approach of') 98 print('// \'apply every license found to every target\'. While this makes sure we respect') 99 print('// every license restriction, it may not be entirely correct.') 100 print('//') 101 print('// e.g. GPL in an MIT project might only apply to the contrib/ directory.') 102 print('//') 103 print('// Please consider splitting the single license below into multiple licenses,') 104 print('// taking care not to lose any license_kind information, and overriding the') 105 print('// default license using the \'licenses: [...]\' property on targets as needed.') 106 print('//') 107 print('// For unused files, consider creating a \'fileGroup\' with "//visibility:private"') 108 print('// to attach the license to, and including a comment whether the files may be') 109 print('// used in the current project.') 110 print('//') 111 print('// large-scale-change included anything that looked like it might be a license') 112 print('// text as a license_text. e.g. LICENSE, NOTICE, COPYING etc.') 113 print('//') 114 print('// Please consider removing redundant or irrelevant files from \'license_text:\'.') 115 print('// See: http://go/android-license-faq') 116 print('') 117 print('///////////////////////////////////////////////////////////////////////////////') 118 print('// Do not edit this file directly, it\'s automatically generated by a script. //') 119 print('// Modify android_tools/generate_android_bp.py and run that instead. //') 120 print('///////////////////////////////////////////////////////////////////////////////') 121 print('') 122 print('license {') 123 print(' name: "external_webrtc_license",') 124 print(' visibility: [":__subpackages__"],') 125 print(' license_kinds: [') 126 print(' "SPDX-license-identifier-Apache-2.0",') 127 print(' "SPDX-license-identifier-BSD",') 128 print(' "SPDX-license-identifier-MIT",') 129 print(' "SPDX-license-identifier-Zlib",') 130 print(' "legacy_notice",') 131 print(' "legacy_unencumbered",') 132 print(' ],') 133 print(' license_text: [') 134 print(' "LICENSE",') 135 print(' "PATENTS",') 136 print(' "license_template.txt",') 137 print(' ],') 138 print('}') 139 140 141 142def GatherDefaultFlags(targets_by_arch): 143 # Iterate through all of the targets for each architecture collecting the flags that 144 # are the same for all targets in that architecture. Use a list instead of a set 145 # to maintain the flag ordering, which may be significant (e.g. -Wno-shadow has to 146 # come after -Wshadow). 147 arch_default_flags = {} 148 for arch, targets in targets_by_arch.items(): 149 arch_default_flags[arch] = {} 150 for target in targets.values(): 151 typ = target['type'] 152 if typ != 'static_library': 153 continue 154 for flag_type in FLAGS: 155 if not flag_type in arch_default_flags: 156 arch_default_flags[arch][flag_type] = target[flag_type] 157 else: 158 target_flags = set(target[flag_type]) 159 flags = arch_default_flags[arch][flag_type] 160 flags[:] = [ x for x in flags if x in target_flags ] 161 for flag_type, flags in arch_default_flags[arch].items(): 162 arch_default_flags[arch][flag_type] = FilterFlags(flags) 163 # Add in the hardcoded extra default cflags 164 arch_default_flags[arch]['cflags'] += DEFAULT_CFLAGS_BY_ARCH.get(arch, []) 165 166 # Iterate through all of the architectures collecting the flags that are the same 167 # for all targets in all architectures. 168 default_flags = {} 169 for arch, flagset in arch_default_flags.items(): 170 for flag_type, arch_flags in flagset.items(): 171 if not flag_type in default_flags: 172 default_flags[flag_type] = arch_flags.copy() 173 else: 174 flags = default_flags[flag_type] 175 flags[:] = [ x for x in flags if x in arch_flags ] 176 # Add in the hardcoded extra default cflags 177 default_flags['cflags'] += DEFAULT_CFLAGS 178 179 # Remove the global default flags from the per-architecture default flags 180 for arch, flagset in arch_default_flags.items(): 181 for flag_type in flagset.keys(): 182 flags = flagset[flag_type] 183 flags[:] = [ x for x in flags if x not in default_flags[flag_type] ] 184 185 default_flags['arch'] = arch_default_flags 186 return default_flags 187 188def GenerateDefault(targets_by_arch): 189 in_default = GatherDefaultFlags(targets_by_arch) 190 print('cc_defaults {') 191 print(' name: "webrtc_defaults",') 192 print(' local_include_dirs: [') 193 print(' ".",') 194 print(' "webrtc",') 195 print(' "third_party/crc32c/src/include",') 196 print(' ],') 197 for typ in sorted(in_default.keys() - {'arch'}): 198 flags = in_default[typ] 199 if len(flags) > 0: 200 print(' {0}: ['.format(FLAG_NAME_MAP[typ])) 201 for flag in flags: 202 print(' "{0}",'.format(flag.replace('"', '\\"'))) 203 print(' ],') 204 print(' header_libs: [') 205 print(' "libwebrtc_absl_headers",') 206 print(' ],') 207 print(' static_libs: [') 208 print(' "libaom",') 209 print(' "libevent",') 210 print(' "libopus",') 211 print(' "libsrtp2",') 212 print(' "libvpx",') 213 print(' "libyuv",') 214 print(' "libpffft",') 215 print(' "rnnoise_rnn_vad",') 216 print(' ],') 217 print(' shared_libs: [') 218 print(' "libcrypto",') 219 print(' "libprotobuf-cpp-full",') 220 print(' "libprotobuf-cpp-lite",') 221 print(' "libssl",') 222 print(' ],') 223 print(' host_supported: true,') 224 print(' // vendor needed for libpreprocessing effects.') 225 print(' vendor: true,') 226 print(' target: {') 227 print(' darwin: {') 228 print(' enabled: false,') 229 print(' },') 230 print(' },') 231 print(' arch: {') 232 for a in ARCHS: 233 print(' {0}: {{'.format(ARCH_NAME_MAP[a])) 234 for typ in FLAGS: 235 flags = in_default['arch'].get(a, {}).get(typ, []) 236 if len(flags) > 0: 237 print(' {0}: ['.format(FLAG_NAME_MAP[typ])) 238 for flag in flags: 239 print(' "{0}",'.format(flag.replace('"', '\\"'))) 240 print(' ],') 241 print(' },') 242 print(' },') 243 print(' visibility: [') 244 print(' "//frameworks/av/media/libeffects/preprocessing:__subpackages__",') 245 print(' "//device/google/cuttlefish/host/frontend/webrtc:__subpackages__",') 246 print(' ],') 247 print('}') 248 249 # The flags in the default entry can be safely removed from the targets 250 for arch, targets in targets_by_arch.items(): 251 for flag_type in FLAGS: 252 default_flags = set(in_default[flag_type]) | set(in_default['arch'][arch][flag_type]) 253 for target in targets.values(): 254 target[flag_type] = FilterFlags(target.get(flag_type, []), default_flags) 255 if len(target[flag_type]) == 0: 256 target.pop(flag_type) 257 258 return in_default 259 260 261def TransitiveDependencies(name, dep_type, targets): 262 target = targets[name] 263 field = 'transitive_' + dep_type 264 if field in target.keys(): 265 return target[field] 266 target[field] = {'global': set()} 267 for a in ARCHS: 268 target[field][a] = set() 269 if target['type'] == dep_type: 270 target[field]['global'].add(name) 271 for d in target.get('deps', []): 272 if targets[d]['type'] == dep_type: 273 target[field]['global'].add(d) 274 tDeps = TransitiveDependencies(d, dep_type, targets) 275 target[field]['global'] |= tDeps['global'] 276 for a in ARCHS: 277 target[field][a] |= tDeps[a] 278 if 'arch' in target: 279 for a, x in target['arch'].items(): 280 for d in x.get('deps', []): 281 tDeps = TransitiveDependencies(d, dep_type, targets) 282 target[field][a] |= tDeps['global'] | tDeps[a] 283 target[field][a] -= target[field]['global'] 284 285 return target[field] 286 287def GenerateGroup(target): 288 # PrintOrigin(target) 289 pass 290 291def GenerateSourceSet(target): 292 sources = target.get('sources', []) 293 # arch is not defined for filegroups so put all the sources in the top level, 294 # the static libraries that depend on the filegroup will add it in the 295 # appropriate arch. 296 for arch in target.get('arch', {}).values(): 297 sources += arch.get('sources', []) 298 if len(sources) == 0: 299 return '' 300 PrintOrigin(target) 301 302 name = target['name'] 303 print('filegroup {') 304 print(' name: "{0}",'.format(name)) 305 print(' srcs: {0},'.format(FormatList(sources))) 306 print('}') 307 return name 308 309def GenerateStaticLib(target, targets): 310 PrintOrigin(target) 311 name = target['name'] 312 print('cc_library_static {') 313 print(' name: "{0}",'.format(name)) 314 print(' defaults: ["webrtc_defaults"],') 315 sources = target.get('sources', []) 316 print(' srcs: {0},'.format(FormatList(sources))) 317 print(' host_supported: true,') 318 if 'asmflags' in target.keys(): 319 asmflags = target['asmflags'] 320 if len(asmflags) > 0: 321 print(' asflags: {0},'.format(FormatList(asmflags))) 322 if 'cflags' in target.keys(): 323 cflags = target['cflags'] 324 print(' cflags: {0},'.format(FormatList(cflags))) 325 if 'cflags_c' in target.keys(): 326 cflags_c = target['cflags_c'] 327 if len(cflags_c) > 0: 328 print(' conlyflags: {0},'.format(FormatList(cflags_c))) 329 if 'cflags_cc' in target.keys(): 330 cflags_cc = target['cflags_cc'] 331 if len(cflags_cc) > 0: 332 print(' cppflags: {0},'.format(FormatList(cflags_cc))) 333 static_libs = sorted([d for d in target.get('deps', []) if targets[d]['type'] == 'static_library']) 334 if len(static_libs) > 0: 335 print(' static_libs: {0},'.format(FormatList(static_libs))) 336 if 'arch' in target: 337 print(' arch: {') 338 for arch_name in ARCHS: 339 if arch_name not in target['arch'].keys(): 340 continue 341 arch = target['arch'][arch_name] 342 print(' ' + ARCH_NAME_MAP[arch_name] + ': {') 343 if 'cflags' in arch.keys(): 344 cflags = arch['cflags'] 345 print(' cflags: {0},'.format(FormatList(cflags))) 346 if 'cflags_c' in arch.keys(): 347 cflags_c = arch['cflags_c'] 348 if len(cflags_c) > 0: 349 print(' conlyflags: {0},'.format(FormatList(cflags_c))) 350 if 'cflags_cc' in arch.keys(): 351 cflags_cc = arch['cflags_cc'] 352 if len(cflags_cc) > 0: 353 print(' cppflags: {0},'.format(FormatList(cflags_cc))) 354 if 'deps' in arch: 355 static_libs = [d for d in arch['deps'] if targets[d]['type'] == 'static_library'] 356 print(' static_libs: {0},'.format(FormatList(static_libs))) 357 if 'sources' in arch: 358 sources = arch['sources'] 359 print(' srcs: {0},'.format(FormatList(sources))) 360 if 'enabled' in arch: 361 print(' enabled: {0},'.format(arch['enabled'])) 362 print(' },') 363 print(' },') 364 print('}') 365 return name 366 367def DFS(seed, targets): 368 visited = set() 369 stack = [seed] 370 while len(stack) > 0: 371 nxt = stack.pop() 372 if nxt in visited: 373 continue 374 visited.add(nxt) 375 stack += targets[nxt]['deps'] 376 stack += [s[1:] for s in targets[nxt]['sources'] if s.startswith(':')] 377 if 'arch' not in targets[nxt]: 378 continue 379 for arch in targets[nxt]['arch']: 380 if 'deps' in arch: 381 stack += arch['deps'] 382 if 'sources' in arch: 383 stack += [s[1:] for s in arch['sources'] if s.startswith(':')] 384 return visited 385 386def Preprocess(project): 387 targets = {} 388 for name, target in project['targets'].items(): 389 target['name'] = name 390 targets[name] = target 391 if target['type'] == 'shared_library': 392 # Don't bother creating shared libraries 393 target['type'] = 'static_library' 394 if 'defines' in target: 395 target['cflags'] = target.get('cflags', []) + ['-D{0}'.format(d) for d in target['defines']] 396 target.pop('defines') 397 if 'sources' not in target: 398 continue 399 sources = list(MakeRelatives(FilterIncludes(target['sources']))) 400 if len(sources) > 0: 401 target['sources'] = sources 402 else: 403 target.pop('sources') 404 405 # These dependencies are provided by aosp 406 ignored_targets = { 407 '//third_party/libaom:libaom', 408 '//third_party/libevent:libevent', 409 '//third_party/opus:opus', 410 '//third_party/libsrtp:libsrtp', 411 '//third_party/libvpx:libvpx', 412 '//third_party/libyuv:libyuv', 413 '//third_party/pffft:pffft', 414 '//third_party/rnnoise:rnn_vad', 415 '//third_party/boringssl:boringssl', 416 '//third_party/android_ndk:cpu_features', 417 '//buildtools/third_party/libunwind:libunwind', 418 '//buildtools/third_party/libc++:libc++', 419 } 420 for name, target in targets.items(): 421 # Skip all "action" targets 422 if target['type'] in {'action', 'action_foreach'}: 423 ignored_targets.add(name) 424 targets = {name: target for name, target in targets.items() if name not in ignored_targets} 425 426 for target in targets.values(): 427 # Don't depend on ignored targets 428 target['deps'] = [d for d in target['deps'] if d not in ignored_targets] 429 430 # filegroups can't have dependencies, so put their dependencies in the static libraries that 431 # depend on them. 432 for target in targets.values(): 433 if target['type'] == 'static_library': 434 source_sets = TransitiveDependencies(target['name'], 'source_set', targets) 435 source_sets_deps = {} 436 for a in ['global'] + ARCHS: 437 deps = set() 438 if a == 'global': 439 for ss in [targets[n].get('deps', []) for n in source_sets[a]]: 440 deps |= set(ss) 441 else: 442 for ss in [targets[n].get('arch', {}).get(a, {}).get('deps') for n in source_sets[a]]: 443 deps |= set(ss) 444 source_sets_deps[a] = deps 445 target['deps'] = sorted(set(target['deps']) | source_sets['global'] | source_sets_deps['global']) 446 for a in ARCHS: 447 deps = source_sets[a] | source_sets_deps[a] 448 if len(deps) == 0: 449 continue 450 if 'arch' not in target: 451 target['arch'] = {} 452 if a not in target['arch']: 453 target['arch'][a] = {} 454 if 'deps' not in target['arch'][a]: 455 target['arch'][a]['deps'] = [] 456 deps |= set(target['arch'][a]['deps']) 457 target['arch'][a]['deps'] = sorted(deps) 458 459 # Ignore empty source sets 460 empty_sets = set() 461 for name, target in targets.items(): 462 if target['type'] == 'source_set' and 'sources' not in target: 463 empty_sets.add(name) 464 for s in empty_sets: 465 targets.pop(s) 466 for target in targets.values(): 467 target['deps'] = [d for d in target['deps'] if d not in empty_sets] 468 469 # Move source_set dependencies to the sources fields of static libs 470 for target in targets.values(): 471 if 'sources' not in target: 472 target['sources'] = [] 473 if target['type'] != 'static_library': 474 continue 475 source_sets = {d for d in target['deps'] if targets[d]['type'] == 'source_set'} 476 target['deps'] = sorted(list(set(target['deps']) - source_sets)) 477 target['sources'] += [':' + ss for ss in source_sets] 478 target['sources'] = sorted(target['sources']) 479 if 'arch' in target: 480 for arch in target['arch'].values(): 481 if 'deps' in arch: 482 source_sets = {d for d in arch['deps'] if targets[d]['type'] == 'source_set'} 483 if len(source_sets) == 0: 484 continue; 485 arch['deps'] = sorted(list(set(arch['deps']) - source_sets)) 486 arch['sources'] = sorted(arch.get('sources', []) + [':' + ss for ss in source_sets]) 487 488 # Select libwebrtc, libaudio_processing and its dependencies 489 selected = set() 490 selected |= DFS('//:webrtc', targets) 491 selected |= DFS('//modules/audio_processing:audio_processing', targets) 492 return {FormatName(n): FormatNames(targets[n]) for n in selected} 493 494def NonNoneFrom(l): 495 for a in l: 496 if a is not None: 497 return a 498 return None 499 500def MergeListField(target, f, target_by_arch): 501 set_by_arch = {} 502 for a, t in target_by_arch.items(): 503 if len(t) == 0: 504 # We only care about enabled archs 505 continue 506 set_by_arch[a] = set(t.get(f, [])) 507 508 union = set() 509 for _, s in set_by_arch.items(): 510 union |= s 511 512 common = union 513 for a, s in set_by_arch.items(): 514 common &= s 515 516 not_common = {a: s - common for a,s in set_by_arch.items()} 517 518 if len(common) > 0: 519 target[f] = list(common) 520 for a, s in not_common.items(): 521 if len(s) > 0: 522 target['arch'][a][f] = sorted(list(s)) 523 524def Merge(target_by_arch): 525 # The new target shouldn't have the transitive dependencies memoization fields 526 # or have the union of those fields from all 4 input targets. 527 target = {} 528 for f in ['original_name', 'name', 'type']: 529 target[f] = NonNoneFrom([t.get(f) for _,t in target_by_arch.items()]) 530 531 target['arch'] = {} 532 for a, t in target_by_arch.items(): 533 target['arch'][a] = {} 534 if len(t) == 0: 535 target['arch'][a]['enabled'] = 'false' 536 537 list_fields = ['sources', 538 'deps', 539 'cflags', 540 'cflags_c', 541 'cflags_cc', 542 'asmflags'] 543 for lf in list_fields: 544 MergeListField(target, lf, target_by_arch) 545 546 # Static libraries should be depended on at the root level and disabled for 547 # the corresponding architectures. 548 for arch in target['arch'].values(): 549 if 'deps' not in arch: 550 continue 551 deps = arch['deps'] 552 if 'deps' not in target: 553 target['deps'] = [] 554 target['deps'] += deps 555 arch.pop('deps') 556 if 'deps' in target: 557 target['deps'] = sorted(target['deps']) 558 559 # Remove empty sets 560 for a in ARCHS: 561 if len(target['arch'][a]) == 0: 562 target['arch'].pop(a) 563 if len(target['arch']) == 0: 564 target.pop('arch') 565 566 return target 567 568def DisabledArchs4Target(target): 569 ret = set() 570 for a in ARCHS: 571 if a not in target.get('arch', {}): 572 continue 573 if target['arch'][a].get('enabled', 'true') == 'false': 574 ret.add(a) 575 return ret 576 577 578def HandleDisabledArchs(targets): 579 for n, t in targets.items(): 580 if 'arch' not in t: 581 continue 582 disabledArchs = DisabledArchs4Target(t) 583 if len(disabledArchs) == 0: 584 continue 585 # Fix targets that depend on this one 586 for t in targets.values(): 587 if DisabledArchs4Target(t) == disabledArchs: 588 # With the same disabled archs there is no need to move dependencies 589 continue 590 if 'deps' in t and n in t['deps']: 591 # Remove the dependency from the high level list 592 t['deps'] = sorted(set(t['deps']) - {n}) 593 if 'arch' not in t: 594 t['arch'] = {} 595 for a in ARCHS: 596 if a in disabledArchs: 597 continue 598 if a not in t['arch']: 599 t['arch'][a] = {} 600 if 'deps' not in t['arch'][a]: 601 t['arch'][a]['deps'] = [] 602 t['arch'][a]['deps'] += [n] 603 604def MergeAll(targets_by_arch): 605 names = set() 606 for t in targets_by_arch.values(): 607 names |= t.keys() 608 targets = {} 609 for name in names: 610 targets[name] = Merge({a: t.get(name, {}) for a,t in targets_by_arch.items()}) 611 612 HandleDisabledArchs(targets) 613 614 return targets 615 616def GatherAllFlags(obj): 617 if type(obj) != type({}): 618 # not a dictionary 619 return set() 620 ret = set() 621 for f in FLAGS: 622 ret |= set(obj.get(f, [])) 623 for v in obj.values(): 624 ret |= GatherAllFlags(v) 625 return ret 626 627def FilterFlagsInUse(flags, directory): 628 unused = [] 629 for f in flags: 630 nf = f 631 if nf.startswith("-D"): 632 nf = nf[2:] 633 i = nf.find('=') 634 if i > 0: 635 nf = nf[:i] 636 c = os.system(f"find {directory} -name '*.gn*' | xargs grep -q -s -e '{nf}'") 637 if c != 0: 638 # couldn't find the flag in *.gn or *.gni 639 unused.append(f) 640 return unused 641 642if len(sys.argv) != 2: 643 print('wrong number of arguments', file = sys.stderr) 644 exit(1) 645 646dir = sys.argv[1] 647 648targets_by_arch = {} 649flags = set() 650for arch in ARCHS: 651 path = "{0}/project_{1}.json".format(dir, arch) 652 json_file = open(path, 'r') 653 targets_by_arch[arch] = Preprocess(json.load(json_file)) 654 flags |= GatherAllFlags(targets_by_arch[arch]) 655 656unusedFlags = FilterFlagsInUse(flags, f"{dir}/..") 657IGNORED_FLAGS = sorted(set(IGNORED_FLAGS) | set(unusedFlags)) 658 659PrintHeader() 660 661GenerateDefault(targets_by_arch) 662 663targets = MergeAll(targets_by_arch) 664 665print('\n\n') 666 667for name, target in sorted(targets.items()): 668 typ = target['type'] 669 if typ == 'static_library': 670 GenerateStaticLib(target, targets) 671 elif typ == 'source_set': 672 GenerateSourceSet(target) 673 elif typ == 'group': 674 GenerateGroup(target) 675 else: 676 print('Unknown type: {0} ({1})'.format(typ, target['name']), file = sys.stderr) 677 exit(1) 678 print('\n\n') 679 680webrtc_libs = TransitiveDependencies(FormatName('//:webrtc'), 'static_library', targets) 681print('cc_library_static {') 682print(' name: "libwebrtc",') 683print(' defaults: ["webrtc_defaults"],') 684print(' export_include_dirs: ["."],') 685print(' whole_static_libs: {0},'.format(FormatList(sorted(webrtc_libs['global']) + ['libpffft', 'rnnoise_rnn_vad']))) 686print(' arch: {') 687for a in ARCHS: 688 if len(webrtc_libs[a]) > 0: 689 print(' {0}: {{'.format(ARCH_NAME_MAP[a])) 690 print(' whole_static_libs: {0},'.format(FormatList(sorted(webrtc_libs[a])))) 691 print(' },') 692print(' },') 693print('}') 694 695print('\n\n') 696 697audio_proc_libs = TransitiveDependencies(FormatName('//modules/audio_processing:audio_processing'), 'static_library', targets) 698print('cc_library_static {') 699print(' name: "webrtc_audio_processing",') 700print(' defaults: ["webrtc_defaults"],') 701print(' export_include_dirs: [') 702print(' ".",') 703print(' "modules/include",') 704print(' "modules/audio_processing/include",') 705print(' ],') 706print(' whole_static_libs: {0},'.format(FormatList(sorted(audio_proc_libs['global']) + ['libpffft', 'rnnoise_rnn_vad']))) 707print(' arch: {') 708for a in ARCHS: 709 if len(audio_proc_libs[a]) > 0: 710 print(' {0}: {{'.format(ARCH_NAME_MAP[a])) 711 print(' whole_static_libs: {0},'.format(FormatList(sorted(audio_proc_libs[a])))) 712 print(' },') 713print(' },') 714print('}') 715