Generate build files

For x86, x86_64, arm and arm64

Bug: 261600888
Test: build and run cuttlefish x86, x86_64 and arm64
Change-Id: I3ac4dad1ac9ec83b0e626e64715df450e8809b82
This commit is contained in:
Jorge E. Moreira
2022-12-07 15:15:30 -08:00
parent 344e5c70eb
commit b5b78192e1
17 changed files with 274074 additions and 199891 deletions

59877
Android.bp

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,20 @@
#!/bin/bash
set -o errexit
set -o xtrace
if [[ "${ANDROID_BUILD_TOP}" == "" ]]; then
echo "Run source build/envsetup.sh && lunch to be able to format Android.bp"
exit 2
fi
DIR=$(dirname $0)
"${DIR}"/generate_bp.py "${DIR}"/selected_targets.json | \
grep -v 'PACKAGE_VERSION' | \
grep -v 'PACKAGE_STRING' >"${DIR}"/../Android.bp
# The alsa device causes a double lock on a mutex, don't use it
sed -i -e 's/WEBRTC_ENABLE_LINUX_ALSA/WEBRTC_DUMMY_FILE_DEVICES/g' "${DIR}/../Android.bp"
source "${DIR}"/../../../build/envsetup.sh
PYTHONHASHSEED=31 "${DIR}"/generate_bp.py \
"${DIR}"/project_x64.json \
"${DIR}"/project_x86.json \
"${DIR}"/project_arm64.json \
"${DIR}"/project_arm.json \
>"${DIR}"/../Android.bp
bpfmt -w "${DIR}"/../Android.bp

View File

@ -3,275 +3,647 @@
import json
import sys
# Set this to True to generate a default entry with all the flags and defines
# common to all the modules that needs to be curated by hand after it's
# generated. When set to False it prints the last curated version of the
# default, which could be incomplete.
GENERATE_FULL_DEFAULT = False
PRINT_ORIGINALS = False
GENERATE_ALL_FLAGS = False
if len(sys.argv) != 2:
print('wrong number of arguments')
exit()
PRINT_ORIGINAL_FULL = False
def FormatList(l):
return json.dumps(l)
return json.dumps(list(l))
def FilterHeaders(l):
return [x for x in l if not x.endswith('.h')]
def IsInclude(name):
return name.endswith('.h') or name.endswith('.inc')
def PrintOriginCommentedOut(target):
if PRINT_ORIGINALS:
print('/* From target:')
def FilterIncludes(l):
return filter(lambda x: not IsInclude(x), l)
def PrintOrigin(target):
print('/* From target:')
if PRINT_ORIGINAL_FULL:
print(json.dumps(target, sort_keys = True, indent = 4))
print('*/')
else:
print(target['original_name'])
print('*/')
def MakeRelatives(l):
return [x.split('//').pop() for x in l]
return map(lambda x: x.split('//').pop(), l)
def FormatName(name):
return 'webrtc_' + name.split('/').pop().replace(':', '__')# .replace('/', '_').replace(':', '_')
return 'webrtc_' + name.split('/').pop().replace(':', '__')
def FilterFlags(flags, to_skip = set([])):
if GENERATE_ALL_FLAGS:
skip = set([
'-L',
'-isystem',
'-Xclang',
'-B',
'--sysroot',
'-fcrash-diagnostics-dir',
'.',
'-fdebug-compilation-dir',
'-instcombine-lower-dbg-declare=0',
'-Wno-non-c-typedef-for-linkage',
'-Werror',
'-fcomplete-member-pointers',
'-m64',
'-march=x86-64'
]).union(to_skip)
return [x for x in flags if not any([x.startswith(y) for y in skip])]
else:
return [x for x in flags if x == '-msse2']
def FormatNames(target):
target['original_name'] = target['name']
target['name'] = FormatName(target['name'])
target['deps'] = [FormatName(d) for d in target['deps']]
target['sources'] = list(map(lambda s: (':' + FormatName(s[1:])) if s.startswith(':') else s, target['sources']))
return target
def GenerateDefault(targets):
in_default = {
def FilterFlags(flags, to_skip = set()):
skipped_opts = set([
'-Wall',
'-Werror',
'-L',
'-isystem',
'-Xclang',
'-B',
'--sysroot',
'-fcrash-diagnostics-dir',
'.',
'-fdebug-compilation-dir',
'-instcombine-lower-dbg-declare=0',
'-Wno-non-c-typedef-for-linkage',
'-Werror',
'-fcomplete-member-pointers',
'-fno-stack-protector',
'--target=i686-linux-android16',
'--target=aarch64-linux-android21'
'--target=i686-linux-android16',
'--target=x86_64-linux-android21',
'--target=arm-linux-androideabi16',
'-m64',
'-m32',
'-march=x86-64',
'-march=armv8-a',
'-mllvm',
'-target-feature',
'+crypto',
'+crc',
'-fno-unique-section-names',
'-fno-short-enums',
'-fno-delete-null-pointer-checks',
'-ffile-compilation-dir=.',
'-Wno-unneeded-internal-declaration',
'-Wno-unreachable-code-aggressive',
'-Wno-unreachable-code-break',
'-fuse-ctor-homing',
'-fno-rtti',
]).union(to_skip)
return [x for x in flags if not any([x.startswith(y) for y in skipped_opts])]
def PrintHeader():
print('package {')
print(' default_applicable_licenses: ["external_webrtc_license"],')
print('}')
print('')
print('// Added automatically by a large-scale-change that took the approach of')
print('// \'apply every license found to every target\'. While this makes sure we respect')
print('// every license restriction, it may not be entirely correct.')
print('//')
print('// e.g. GPL in an MIT project might only apply to the contrib/ directory.')
print('//')
print('// Please consider splitting the single license below into multiple licenses,')
print('// taking care not to lose any license_kind information, and overriding the')
print('// default license using the \'licenses: [...]\' property on targets as needed.')
print('//')
print('// For unused files, consider creating a \'fileGroup\' with "//visibility:private"')
print('// to attach the license to, and including a comment whether the files may be')
print('// used in the current project.')
print('//')
print('// large-scale-change included anything that looked like it might be a license')
print('// text as a license_text. e.g. LICENSE, NOTICE, COPYING etc.')
print('//')
print('// Please consider removing redundant or irrelevant files from \'license_text:\'.')
print('// See: http://go/android-license-faq')
print('')
print('///////////////////////////////////////////////////////////////////////////////')
print('// Do not edit this file directly, it\'s automatically generated by a script. //')
print('// Modify android_tools/generate_android_bp.py and run that instead. //')
print('///////////////////////////////////////////////////////////////////////////////')
print('')
print('license {')
print(' name: "external_webrtc_license",')
print(' visibility: [":__subpackages__"],')
print(' license_kinds: [')
print(' "SPDX-license-identifier-Apache-2.0",')
print(' "SPDX-license-identifier-BSD",')
print(' "SPDX-license-identifier-MIT",')
print(' "SPDX-license-identifier-Zlib",')
print(' "legacy_notice",')
print(' "legacy_unencumbered",')
print(' ],')
print(' license_text: [')
print(' "LICENSE",')
print(' "PATENTS",')
print(' "license_template.txt",')
print(' ],')
print('}')
def GatherDefaultFlags(targets):
default = {
'cflags' : [],
'cflags_c' : [],
'cflags_cc' : [],
'ldflags' : [],
'asmflags' : [],
'defines' : []
}
arch = {
'x64': {},
'x86': {},
'arm64': {},
'arm': {},
}
first = True
for target in targets:
for target in targets.values():
typ = target['type']
if typ == 'static_library':
if first:
first = False
# Add all the flags to the default, we'll remove some later
for flag_type in in_default.keys():
in_default[flag_type] = []
for flag in target[flag_type]:
in_default[flag_type].append(flag)
else:
for flag_type in in_default.keys():
flags_to_remove = []
for flag in in_default[flag_type]:
if flag not in target[flag_type]:
flags_to_remove.append[flag_type]
for flag in flags_to_remove:
in_default[flag_type].remove(flag)
defines = in_default['defines']
in_default.pop('defines')
in_default['cflags'].extend(['-D{0}'.format(x) for x in defines])
if GENERATE_FULL_DEFAULT:
print('cc_defaults {')
print(' name: "webrtc_defaults",')
print(' local_include_dirs: ["."],')
if typ != 'static_library':
continue
if first:
first = False
# Add all the flags to the default, we'll remove some later
for flag_type in default.keys():
default[flag_type] = []
for flag in target[flag_type]:
default[flag_type].append(flag)
for a in arch.keys():
arch[a][flag_type] = []
for flag in target.get('arch', {}).get(a, {}).get(flag_type, []):
arch[a][flag_type].append(flag)
else:
for flag_type in default.keys():
if flag_type not in target:
target[flag_type] = []
default[flag_type] = list(set(default[flag_type]) & set(target[flag_type]))
for a in arch.keys():
arch[a][flag_type] = list(set(arch[a][flag_type]) | set(target.get('arch', {}).get(a, {}).get(flag_type, [])))
default['arch'] = arch
return default
def GenerateDefault(targets):
in_default = GatherDefaultFlags(targets)
print('cc_defaults {')
print(' name: "webrtc_defaults",')
print(' local_include_dirs: [')
print(' ".",')
print(' "webrtc",')
print(' "third_party/crc32c/src/include",')
print(' ],')
if PRINT_ORIGINAL_FULL:
for typ in in_default.keys():
print(' {0}: ['.format(typ.replace('asmflags', 'asflags')
print(' // {0}: ['.format(typ.replace('asmflags', 'asflags')
.replace('cflags_cc', 'cppflags')
.replace('cflags_c', 'conlyflags')))
for flag in FilterFlags(in_default[typ]):
print(' "{0}",'.format(flag.replace('"', '\\"')))
print(' ],')
print('}')
else:
print('cc_defaults {')
print(' name: "webrtc_defaults",')
print(' local_include_dirs: [')
print(' ".",')
print(' ],')
print(' cflags: [')
print(' "-Wno-unused-parameter",')
print(' "-Wno-missing-field-initializers",')
print(' "-DUSE_UDEV",')
print(' "-DUSE_AURA=1",')
print(' "-DUSE_GLIB=1",')
print(' "-DUSE_NSS_CERTS=1",')
print(' "-DUSE_X11=1",')
print(' "-D_FILE_OFFSET_BITS=64",')
print(' "-D_LARGEFILE_SOURCE",')
print(' "-D_LARGEFILE64_SOURCE",')
print(' "-D_GNU_SOURCE",')
print(' "-DWEBRTC_ENABLE_PROTOBUF=0",')
print(' "-DWEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE",')
print(' "-DRTC_ENABLE_VP9",')
print(' "-DHAVE_SCTP",')
print(' "-DWEBRTC_LIBRARY_IMPL",')
print(' "-DWEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS=1",')
print(' "-DWEBRTC_POSIX",')
print(' "-DWEBRTC_LINUX",')
print(' ],')
print(' header_libs: [')
print(' "libwebrtc_absl_headers",')
print(' ],')
print(' static_libs: [')
print(' "libaom",')
print(' "libevent",')
print(' "libopus",')
print(' "libsrtp2",')
print(' "libvpx",')
print(' "libyuv",')
print(' "libpffft",')
print(' "rnnoise_rnn_vad",')
print(' "usrsctplib",')
print(' ],')
print(' shared_libs: [')
print(' "libcrypto",')
print(' "libssl",')
print(' ],')
print(' host_supported: true,')
print(' device_supported: false,')
print(' arch: {')
print(' arm: {')
print(' enabled: false,')
print(' },')
print(' },')
print(' target: {')
print(' darwin: {')
print(' enabled: false,')
print(' },')
print(' },')
print('}')
in_default['cflags'].extend([
"-Wno-unused-parameter",
"-Wno-missing-field-initializers",
"-DUSE_UDEV",
"-DUSE_AURA=1",
"-DUSE_GLIB=1",
"-DUSE_NSS_CERTS=1",
"-DUSE_X11=1",
"-D_FILE_OFFSET_BITS=64",
"-D_LARGEFILE_SOURCE",
"-D_LARGEFILE64_SOURCE",
"-D_GNU_SOURCE",
"-DWEBRTC_ENABLE_PROTOBUF=0",
"-DWEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE",
"-DRTC_ENABLE_VP9",
"-DHAVE_SCTP",
"-DWEBRTC_LIBRARY_IMPL",
"-DWEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS=1",
"-DWEBRTC_POSIX",
"-DWEBRTC_LINUX"
])
print(' // "{0}",'.format(flag.replace('"', '\\"')))
print(' // ],')
selected_cflags = [
'-Wno-everything',
'-Wno-all',
'-Wno-error',
'-Wno-unreachable-code-aggressive',
'-Wno-unreachable-code-break',
'-Wno-unused-parameter',
'-Wno-missing-field-initializers',
'-Wno-implicit-const-int-float-conversion',
'-DUSE_UDEV',
'-DUSE_AURA=1',
'-DUSE_GLIB=1',
'-DUSE_NSS_CERTS=1',
'-DUSE_X11=1',
'-D_FILE_OFFSET_BITS=64',
'-D_LARGEFILE_SOURCE',
'-D_LARGEFILE64_SOURCE',
'-D_GNU_SOURCE',
'-DWEBRTC_ENABLE_PROTOBUF=0',
'-DWEBRTC_ANDROID_PLATFORM_BUILD=1',
'-DWEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE',
'-DRTC_ENABLE_VP9',
'-DWEBRTC_HAVE_SCTP',
'-DWEBRTC_LIBRARY_IMPL',
'-DWEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS=1',
'-DWEBRTC_POSIX',
'-DWEBRTC_LINUX',
'-DWEBRTC_STRICT_FIELD_TRIALS=0',
'-DWEBRTC_ENABLE_AVX2',
'-DABSL_ALLOCATOR_NOTHROW=1',
'-DWEBRTC_APM_DEBUG_DUMP=0',
'-msse3',
]
selected_cflags_x86 = ['-mavx2', '-mfma', '-DHAVE_ARM64_CRC32C=0']
selected_cflags_x64 = ['-msse2', '-mavx2', '-mfma', '-DHAVE_ARM64_CRC32C=0']
selected_cflags_arm = ['-DWEBRTC_HAS_NEON', '-DWEBRTC_ARCH_ARM_V7', '-DWEBRTC_ARCH_ARM', '-mfpu=neon', '-mthumb', '-DHAVE_ARM64_CRC32C=0']
selected_cflags_arm64 = ['-DWEBRTC_HAS_NEON', '-DWEBRTC_ARCH_ARM64', '-DHAVE_ARM64_CRC32C=0']
print(' cflags: {0},'.format(FormatList(selected_cflags)))
print(' header_libs: [')
print(' "libwebrtc_absl_headers",')
print(' ],')
print(' static_libs: [')
print(' "libaom",')
print(' "libevent",')
print(' "libopus",')
print(' "libsrtp2",')
print(' "libvpx",')
print(' "libyuv",')
print(' "libpffft",')
print(' "rnnoise_rnn_vad",')
print(' ],')
print(' shared_libs: [')
print(' "libcrypto",')
print(' "libprotobuf-cpp-full",')
print(' "libprotobuf-cpp-lite",')
print(' "libssl",')
print(' ],')
print(' host_supported: true,')
print(' // vendor needed for libpreprocessing effects.')
print(' vendor: true,')
print(' target: {')
print(' darwin: {')
print(' enabled: false,')
print(' },')
print(' },')
print(' arch: {')
print(' x86: {')
print(' cflags: {0}'.format(FormatList(selected_cflags_x86)))
print(' },')
print(' x86_64: {')
print(' cflags: {0}'.format(FormatList(selected_cflags_x64)))
print(' },')
print(' arm: {')
print(' cflags: {0}'.format(FormatList(selected_cflags_arm)))
print(' },')
print(' arm64: {')
print(' cflags: {0}'.format(FormatList(selected_cflags_arm64)))
print(' },')
print(' },')
print(' visibility: [')
print(' "//frameworks/av/media/libeffects/preprocessing:__subpackages__",')
print(' "//device/google/cuttlefish/host/frontend/webrtc:__subpackages__",')
print(' ],')
print('}')
in_default['cflags'].extend(selected_cflags)
in_default['arch']['x86']['cflags'].extend(selected_cflags_x86)
in_default['arch']['x64']['cflags'].extend(selected_cflags_x64)
in_default['arch']['arm']['cflags'].extend(selected_cflags_arm)
in_default['arch']['arm64']['cflags'].extend(selected_cflags_arm64)
# The flags in the default entry can be safely removed from the targets
for target in targets.values():
flag_types = in_default.keys() - {'arch'}
for flag_type in flag_types:
target[flag_type] = FilterFlags(target.get(flag_type, []), in_default[flag_type])
if len(target[flag_type]) == 0:
target.pop(flag_type)
if 'arch' not in target:
continue
for arch_name in in_default['arch'].keys():
if arch_name not in target['arch']:
continue
arch = target['arch'][arch_name]
if flag_type not in arch:
continue
arch[flag_type] = FilterFlags(arch[flag_type], in_default['arch'][arch_name][flag_type])
if len(arch[flag_type]) == 0:
arch.pop(flag_type)
if len(arch.keys()) == 0:
target['arch'].pop(arch_name)
if len(target['arch'].keys()) == 0:
target.pop('arch')
return in_default
def TransitiveDependencies(name, dep_type, targets):
target = targets[name]
field = 'transitive_' + dep_type
if field in target.keys():
return target[field]
target[field] = set()
if target['type'] == dep_type:
target[field].add(name)
for d in target.get('deps', []):
if targets[d]['type'] == dep_type:
target[field].add(d)
target[field] |= TransitiveDependencies(d, dep_type, targets)
return target[field]
def GenerateGroup(target):
PrintOriginCommentedOut(target)
# PrintOrigin(target)
pass
def GenerateSourceSet(target):
PrintOriginCommentedOut(target)
if target.has_key('sources'):
name = FormatName(target['name'])
print('filegroup {')
print(' name: "{0}",'.format(name))
print(' srcs: {0},'.format(FormatList(MakeRelatives(FilterHeaders(target['sources'])))))
print('}')
return name
return ""
sources = target.get('sources', [])
# arch is not defined for filegroups so put all the sources in the top level,
# the static libraries that depend on the filegroup will add it in the
# appropriate arch.
for arch in target.get('arch', {}).values():
sources += arch.get('sources', [])
if len(sources) == 0:
return ''
PrintOrigin(target)
def GenerateStaticLib(target, targets, flags_in_default):
PrintOriginCommentedOut(target)
name = FormatName(target['name'])
print('cc_library_static {')
name = target['name']
print('filegroup {')
print(' name: "{0}",'.format(name))
print(' defaults: ["webrtc_defaults"],')
sources = []
sources.extend(MakeRelatives(FilterHeaders(target['sources'])))
for trg in targets:
if trg['type'] == 'source_set' and trg['name'] in target['deps']:
sources.append(':' + FormatName(trg['name']))
print(' srcs: {0},'.format(FormatList(sources)))
print(' host_supported: true,')
if target.has_key('asmflags'):
asmflags = FilterFlags(target['asmflags'], set(flags_in_default['asmflags']))
if len(asmflags) > 0:
print(' asflags: {0},'.format(FormatList(asmflags)))
cflags = []
if target.has_key('cflags'):
cflags.extend(target['cflags'])
cflags = FilterFlags(cflags, set(flags_in_default['cflags']))
if target.has_key('defines'):
cflags.extend(['-D' + x for x in target['defines']])
cflags = [x for x in cflags if x not in flags_in_default['cflags']]
if len(cflags) > 0:
print(' cflags: {0},'.format(FormatList(cflags)))
if target.has_key('cflags_c'):
cflags_c = FilterFlags(target['cflags_c'], set(flags_in_default['cflags_c']))
if len(cflags_c) > 0:
print(' conlyflags: {0},'.format(FormatList(cflags_c)))
if target.has_key('cflags_cc'):
cflags_cc = FilterFlags(target['cflags_cc'], set(flags_in_default['cflags_cc']))
if len(cflags_cc) > 0:
print(' cppflags: {0},'.format(FormatList(cflags_cc)))
if target.has_key('ldflags'):
ldflags = FilterFlags(target['ldflags'], set(flags_in_default['ldflags']))
if len(ldflags) > 0:
print(' ldflags: {0},'.format(FormatList(ldflags)))
static_libs = []
for trg in targets:
if trg['type'] == 'static_library' and target['deps'].count(trg['name']) > 0:
static_libs.append(FormatName(trg['name']))
if len(static_libs) > 0:
print(' static_libs: {0},'.format(FormatList(static_libs)))
for dep in target['deps']:
if FormatName(dep) not in static_libs:
#print(' // omitted dep: {0}'.format(dep))
pass
print('}')
return name
json_file = open(sys.argv[1], "r")
targets = json.load(json_file)
def GenerateStaticLib(target, targets):
PrintOrigin(target)
name = target['name']
print('cc_library_static {')
print(' name: "{0}",'.format(name))
print(' defaults: ["webrtc_defaults"],')
sources = target.get('sources', [])
print(' srcs: {0},'.format(FormatList(sources)))
print(' host_supported: true,')
if 'asmflags' in target.keys():
asmflags = target['asmflags']
if len(asmflags) > 0:
print(' asflags: {0},'.format(FormatList(asmflags)))
if 'cflags' in target.keys():
cflags = target['cflags']
print(' cflags: {0},'.format(FormatList(cflags)))
if 'cflags_c' in target.keys():
cflags_c = target['cflags_c']
if len(cflags_c) > 0:
print(' conlyflags: {0},'.format(FormatList(cflags_c)))
if 'cflags_cc' in target.keys():
cflags_cc = target['cflags_cc']
if len(cflags_cc) > 0:
print(' cppflags: {0},'.format(FormatList(cflags_cc)))
static_libs = [d for d in target.get('deps', []) if targets[d]['type'] == 'static_library']
if len(static_libs) > 0:
print(' static_libs: {0},'.format(FormatList(static_libs)))
if 'arch' in target:
print(' arch: {')
arch_map = {'x86': 'x86','x64': 'x86_64','arm': 'arm','arm64': 'arm64'}
for arch_name, arch in target['arch'].items():
print(' ' + arch_map[arch_name] + ': {')
if 'cflags' in arch.keys():
cflags = arch['cflags']
print(' cflags: {0},'.format(FormatList(cflags)))
if 'cflags_c' in arch.keys():
cflags_c = arch['cflags_c']
if len(cflags_c) > 0:
print(' conlyflags: {0},'.format(FormatList(cflags_c)))
if 'cflags_cc' in arch.keys():
cflags_cc = arch['cflags_cc']
if len(cflags_cc) > 0:
print(' cppflags: {0},'.format(FormatList(cflags_cc)))
if 'deps' in arch:
static_libs = [d for d in arch['deps'] if targets[d]['type'] == 'static_library']
print(' static_libs: {0},'.format(FormatList(static_libs)))
if 'sources' in arch:
sources = arch['sources']
print(' srcs: {0},'.format(FormatList(sources)))
if 'enabled' in arch:
print(' enabled: {0},'.format(arch['enabled']))
print(' },')
print(' },')
print('}')
return name
flags_in_default = GenerateDefault(targets)
print("\n\n")
def DFS(seed, targets):
visited = set()
stack = [seed]
while len(stack) > 0:
nxt = stack.pop()
if nxt in visited:
continue
visited.add(nxt)
stack += targets[nxt]['deps']
stack += [s[1:] for s in targets[nxt]['sources'] if s.startswith(':')]
if 'arch' not in targets[nxt]:
continue
for arch in targets[nxt]['arch']:
if 'deps' in arch:
stack += arch['deps']
if 'sources' in arch:
stack += [s[1:] for s in arch['sources'] if s.startswith(':')]
return visited
static_libs = []
file_groups = []
def Preprocess(project):
targets = {}
for name, target in project['targets'].items():
target['name'] = name
targets[name] = target
if target['type'] == 'shared_library':
# Don't bother creating shared libraries
target['type'] = 'static_library'
if 'defines' in target:
target['cflags'] = target.get('cflags', []) + ['-D{0}'.format(d) for d in target['defines']]
target.pop('defines')
if 'sources' not in target:
continue
sources = list(MakeRelatives(FilterIncludes(target['sources'])))
if len(sources) > 0:
target['sources'] = sources
else:
target.pop('sources')
for target in targets:
# These dependencies are provided by aosp
ignored_targets = {
'//third_party/libaom:libaom',
'//third_party/libevent:libevent',
'//third_party/opus:opus',
'//third_party/libsrtp:libsrtp',
'//third_party/libvpx:libvpx',
'//third_party/libyuv:libyuv',
'//third_party/pffft:pffft',
'//third_party/rnnoise:rnn_vad',
'//third_party/boringssl:boringssl',
'//third_party/android_ndk:cpu_features',
'//buildtools/third_party/libunwind:libunwind',
'//buildtools/third_party/libc++:libc++',
}
for name, target in targets.items():
# Skip all "action" targets
if target['type'] in {'action', 'action_foreach'}:
ignored_targets.add(name)
targets = {name: target for name, target in targets.items() if name not in ignored_targets}
for target in targets.values():
# Don't depend on ignored targets
target['deps'] = [d for d in target['deps'] if d not in ignored_targets]
# filegroups can't have dependencies, so put their dependencies in the static libraries that
# depend on them.
for target in targets.values():
if target['type'] == 'static_library':
source_sets = TransitiveDependencies(target['name'], 'source_set', targets)
source_sets_deps = set()
for ss in source_sets:
source_sets_deps |= set(targets[ss]['deps'])
target['deps'] = list(set(target['deps']) | source_sets | source_sets_deps)
# Ignore empty source sets
empty_sets = set()
for name, target in targets.items():
if target['type'] == 'source_set' and 'sources' not in target:
empty_sets.add(name)
for s in empty_sets:
targets.pop(s)
for target in targets.values():
target['deps'] = [d for d in target['deps'] if d not in empty_sets]
# Move source_set dependencies to the sources fields of static libs
for target in targets.values():
if 'sources' not in target:
target['sources'] = []
if target['type'] != 'static_library':
continue
source_sets = {d for d in target['deps'] if targets[d]['type'] == 'source_set'}
target['deps'] = list(set(target['deps']) - source_sets)
target['sources'] += [':' + ss for ss in source_sets]
if 'arch' in target:
for arch in target.values():
if 'deps' in arch:
source_sets = {d for d in arch['deps'] if targets[d]['type'] == 'source_set'}
if len(source_sets) == 0:
continue;
arch['deps'] = list(set(arch['deps']) - source_sets)
arch['sources'] = arch.get('sources', []) + [':' + ss for ss in source_sets]
# Select libwebrtc, libaudio_processing and its dependencies
selected = set()
selected |= DFS('//:webrtc', targets)
selected |= DFS('//modules/audio_processing:audio_processing', targets)
return {FormatName(n): FormatNames(targets[n]) for n in selected}
def NonNoneFrom(*args):
for a in args:
if a is not None:
return a
return None
def MergeListField(target, f, x64_target, x86_target, arm64_target, arm_target):
x64_set = set(x64_target.get(f, []))
x86_set = set(x86_target.get(f, []))
arm64_set = set(arm64_target.get(f, []))
arm_set = set(arm_target.get(f, []))
common = x64_set & x86_set & arm64_set & arm_set
x64_only = x64_set - common
x86_only = x86_set - common
arm64_only = arm64_set - common
arm_only = arm_set - common
if len(common) > 0:
target[f] = list(common)
if len(x64_only) > 0:
target['arch']['x64'][f] = list(x64_only)
if len(x86_only) > 0:
target['arch']['x86'][f] = list(x86_only)
if len(arm64_only) > 0:
target['arch']['arm64'][f] = list(arm64_only)
if len(arm_only) > 0:
target['arch']['arm'][f] = list(arm_only)
def Merge(x64_target, x86_target, arm64_target, arm_target):
# The new target shouldn't have the transitive dependencies memoization fields
# or have the union of those fields from all 4 input targets.
target = {}
for f in ['original_name', 'name', 'type']:
target[f] = NonNoneFrom(x64_target.get(f),
x86_target.get(f),
arm64_target.get(f),
arm_target.get(f))
target['arch'] = {'x64': {}, 'x86': {}, 'arm64': {}, 'arm': {}}
if x64_target is None:
target['arch']['x64']['enabled'] = 'false'
if x86_target is None:
target['arch']['x86']['enabled'] = 'false'
if arm64_target is None:
target['arch']['arm64']['enabled'] = 'false'
if arm_target is None:
target['arch']['arm']['enabled'] = 'false'
list_fields = ['sources',
'deps',
'cflags',
'cflags_c',
'cflags_cc',
'asmflags']
for lf in list_fields:
MergeListField(target, lf, x64_target, x86_target, arm64_target, arm_target)
# Static libraries should be depended on at the root level and disabled for
# the corresponding architectures.
for arch in target['arch'].values():
if 'deps' not in arch:
continue
deps = arch['deps']
if 'deps' not in target:
target['deps'] = []
target['deps'] += deps
arch.pop('deps')
# Remove empty sets
if len(target['arch']['x64']) == 0:
target['arch'].pop('x64')
if len(target['arch']['x86']) == 0:
target['arch'].pop('x86')
if len(target['arch']['arm64']) == 0:
target['arch'].pop('arm64')
if len(target['arch']['arm']) == 0:
target['arch'].pop('arm')
if len(target['arch']) == 0:
target.pop('arch')
return target
def MergeAll(x64_targets, x86_targets, arm64_targets, arm_targets):
names = x64_targets.keys() | x86_targets.keys() | arm64_targets.keys() | arm_targets.keys()
targets = {}
for name in names:
targets[name] = Merge(x64_targets.get(name, {}),
x86_targets.get(name, {}),
arm64_targets.get(name, {}),
arm_targets.get(name, {}))
return targets
if len(sys.argv) != 5:
print('wrong number of arguments')
exit()
x64_json_file = open(sys.argv[1], 'r')
x64_targets = Preprocess(json.load(x64_json_file))
x86_json_file = open(sys.argv[2], 'r')
x86_targets = Preprocess(json.load(x86_json_file))
arm64_json_file = open(sys.argv[3], 'r')
arm64_targets = Preprocess(json.load(arm64_json_file))
arm_json_file = open(sys.argv[4], 'r')
arm_targets = Preprocess(json.load(arm_json_file))
targets = MergeAll(x64_targets, x86_targets, arm64_targets, arm_targets)
PrintHeader()
GenerateDefault(targets)
print('\n\n')
for target in targets.values():
typ = target['type']
if typ == 'static_library':
lib_name = GenerateStaticLib(target, targets, flags_in_default)
static_libs.append(lib_name)
GenerateStaticLib(target, targets)
elif typ == 'source_set':
group_name = GenerateSourceSet(target)
if len(group_name) > 0:
file_groups.append(group_name)
GenerateSourceSet(target)
elif typ == 'group':
GenerateGroup(target)
else:
print('Unknown type: {0}'.format(typ))
print("\n\n")
print('Unknown type: {0} ({1})'.format(typ, target['name']), file = sys.stderr)
exit(1)
print('\n\n')
webrtc_libs = [d for d in TransitiveDependencies(FormatName('//:webrtc'), 'static_library', targets)]
print('cc_library_static {')
print(' name: "libwebrtc",')
print(' defaults: ["webrtc_defaults"],')
print(' export_include_dirs: ["."],')
print(' whole_static_libs: {0},'.format(FormatList(static_libs + ['libpffft', 'rnnoise_rnn_vad', 'usrsctplib'])))
print(' srcs: {0},').format(FormatList([':{0}'.format(x) for x in file_groups]))
print(' whole_static_libs: {0},'.format(FormatList(webrtc_libs + ['libpffft', 'rnnoise_rnn_vad'])))
print('}')
print('\n\n')
audio_proc_libs = [d for d in TransitiveDependencies(FormatName('//modules/audio_processing:audio_processing'), 'static_library', targets)]
print('cc_library_static {')
print(' name: "webrtc_audio_processing",')
print(' defaults: ["webrtc_defaults"],')
print(' export_include_dirs: [')
print(' ".",')
print(' "modules/include",')
print(' "modules/audio_processing/include",')
print(' ],')
print(' whole_static_libs: {0},'.format(FormatList(audio_proc_libs + ['libpffft', 'rnnoise_rnn_vad'])))
print('}')

View File

@ -0,0 +1,21 @@
Follow the following steps to update this project:
1- Git merge aosp/upstream-main, resolving any conflicts, to obtain a recent enough version of the code.
2- Use an upstream checkout to generate the json files.
2.1 - Follow instructions to download and build upstream webrtc from https://webrtc.googlesource.com/src/+/main/docs/native-code/development/index.md.
2.2 - Generate the json files for each architecture.
2.2.1 - Disable libaom (search for enable_libaom in all .gni/.gn files and set it to false).
2.2.2 - Disable x11 (set rtc_use_x11 to false in webrtc.gni).
2.2.3 - Disable pipewire (rtc_use_pipewire to false in webrtc.gni).
2.2.4 - Enable dummy audio file (rtc_use_dummy_audio_file_devices to true in webrtc.gni).
2.2.5 - Disable dav1d decoder (rtc_include_dav1d_in_internal_decoder_factory to false in webrtc.gni).
2.2.6 - Disable protobuf (rtc_enable_protobuf to false in webrtc.gni).
2.2.7 - Run this command:
for arch in x64 x86 arm64 arm; do
gn gen out/Debug --args="target_os=\"linux\" target_cpu=\"${arch}\"" --json-file-name=project_${arch}.json --ide=json
done
2.3 Copy out/Debug/project_*.json into android_tools.
3- Run android_tools/generate_android_bp.sh.
4- Build cuttlefish and run it in all architectures to ensure webrtc is working correctly (connect to it, press a few buttons and make sure audio works).
5- The build in step number 4 likely failed, fix any errors. Make sure to not edit external/webrtc/Android.bp directly, but modify the generating script instead.
6- Update these instructions with any new steps needed.

File diff suppressed because one or more lines are too long

53106
android_tools/project_arm.json Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

54098
android_tools/project_x64.json Normal file

File diff suppressed because one or more lines are too long

54212
android_tools/project_x86.json Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,6 @@
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This is a stub. The preprocessor macros that are usually defined here are
// supplied by BUILD.gn instead.

1
third_party/libevent/event.h vendored Normal file
View File

@ -0,0 +1 @@
#include <event.h>

1
third_party/opus/src/include/opus.h vendored Normal file
View File

@ -0,0 +1 @@
#include <opus.h>

View File

@ -0,0 +1 @@
#include <opus_multistream.h>

View File

@ -0,0 +1,16 @@
// This file was automatically generated. Do not edit.
#ifndef GEN_REGISTERED_FIELD_TRIALS_H_
#define GEN_REGISTERED_FIELD_TRIALS_H_
#include "absl/strings/string_view.h"
namespace webrtc {
inline constexpr absl::string_view kRegisteredFieldTrials[] = {
"",
};
} // namespace webrtc
#endif // GEN_REGISTERED_FIELD_TRIALS_H_

File diff suppressed because it is too large Load Diff