Roll chromium_revision 5350dd2460..d5c79b109a (1281218:1283550)

Change log: 5350dd2460..d5c79b109a
Full diff: 5350dd2460..d5c79b109a

Changed dependencies
* fuchsia_version: version:19.20240320.0.1..version:20.20240404.3.1
* src/base: 218e807167..dbb0eee8e8
* src/build: 04c884cbad..6d974542a0
* src/buildtools/linux64: git_revision:93ee9b91423c1f1f53fb5f6cba7b8eef6247a564..git_revision:415b3b19e094cd4b6982147693485df65037f942
* src/buildtools/mac: git_revision:93ee9b91423c1f1f53fb5f6cba7b8eef6247a564..git_revision:415b3b19e094cd4b6982147693485df65037f942
* src/buildtools/win: git_revision:93ee9b91423c1f1f53fb5f6cba7b8eef6247a564..git_revision:415b3b19e094cd4b6982147693485df65037f942
* src/ios: 77324ec269..0bf6089d48
* src/testing: 977e41b6f7..02d496a8fc
* src/third_party: d0b81aaaa6..2831ffa216
* src/third_party/android_build_tools/manifest_merger: HxnrwdWmIAhi90brIHiGZ4zmnmgKxP4PD0ZsJX6j-mUC..wtRWPCJVk_NA2GQp0fI-1i-JaPzYJwp6w3udjEhgni4C
* src/third_party/android_deps/libs/com_squareup_okio_okio_jvm: version:2@3.3.0.cr1..version:2@3.7.0.cr1
* src/third_party/android_deps/libs/com_squareup_wire_wire_runtime_jvm: version:2@4.7.0.cr1..version:2@4.9.7.cr1
* src/third_party/androidx: piz2tht912VQfctH5Z23YCOpLUBoypzE5ymRqB3vgLkC..1qBFaGY_bIR5f12dL7zKpePRlN4UxIDze8xDv_a0sQEC
* src/third_party/boringssl/src: https://boringssl.googlesource.com/boringssl.git/+log/368d0d87d0..f94f3ed396
* src/third_party/catapult: https://chromium.googlesource.com/catapult.git/+log/bb95c35019..0b9e7b8830
* src/third_party/depot_tools: e545830db2..246580c7b8
* src/third_party/ffmpeg: 52d8ef3799..bdcb0b447f
* src/third_party/googletest/src: 77afe8e014..f10e11fb27
* src/third_party/kotlinc/current: -kUQ1HWm0wwi5pXKSqIplyfSInHmtRS9cVUzg-2l-Y0C..Rr02Gf2EkaeSs3EhSUHhPqDHSd1AzimrM6cRYUJCPjQC
* src/third_party/libc++abi/src: 1317096ef8..932d253fed
* src/third_party/libvpx/source/libvpx: d790001fd5..6445da1b40
* src/third_party/perfetto: 6fd518058c..7609c6712c
* src/third_party/r8: eHemH-tzLR3jqxqGYiQu6AYGLAPyFYG7klrqbvu1mcQC..kPZJoj3X2XUBofNCeOoUj0P8XChVFgtiNQqMnTwhcOwC
* src/tools: 09b9b5615b..7dad49cbe0
* src/tools/luci-go: git_revision:a84377ac0800e2330d02c3dcbf7b4b74a06d6a5b..git_revision:06dc7a1f2eeb1d095f7876799458328a44438df1
* src/tools/luci-go: git_revision:a84377ac0800e2330d02c3dcbf7b4b74a06d6a5b..git_revision:06dc7a1f2eeb1d095f7876799458328a44438df1
Added dependencies
* src/third_party/android_deps/libs/com_squareup_moshi_moshi_adapters
* src/third_party/android_deps/libs/com_squareup_moshi_moshi
DEPS diff: 5350dd2460..d5c79b109a/DEPS

Clang version changed llvmorg-19-init-6501-g5b544b51:llvmorg-19-init-7229-g315c88c5
Details: 5350dd2460..d5c79b109a/tools/clang/scripts/update.py

BUG=None

Change-Id: I95eaf05240916eeeaa04f806e7e1523a31abab56
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/345960
Commit-Queue: Christoffer Dewerin <jansson@webrtc.org>
Reviewed-by: Jeremy Leconte <jleconte@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42010}
This commit is contained in:
Christoffer Dewerin 2024-04-08 09:26:41 +02:00 committed by WebRTC LUCI CQ
parent 4d598037a8
commit 81a9117fb7
6 changed files with 666 additions and 617 deletions

78
DEPS
View file

@ -10,7 +10,7 @@ vars = {
# chromium waterfalls. More info at: crbug.com/570091. # chromium waterfalls. More info at: crbug.com/570091.
'checkout_configuration': 'default', 'checkout_configuration': 'default',
'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"',
'chromium_revision': '5350dd2460b8cf103e701f7fd5d0adeb6eb45acd', 'chromium_revision': 'd5c79b109a2356e0e4b8883057224b0b2719eabf',
# Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to
# process the raw profiles produced by instrumented targets (built with # process the raw profiles produced by instrumented targets (built with
@ -27,7 +27,7 @@ vars = {
# By default, download the fuchsia sdk from the public sdk directory. # By default, download the fuchsia sdk from the public sdk directory.
'fuchsia_sdk_cipd_prefix': 'fuchsia/sdk/core/', 'fuchsia_sdk_cipd_prefix': 'fuchsia/sdk/core/',
'fuchsia_version': 'version:19.20240320.0.1', 'fuchsia_version': 'version:20.20240404.3.1',
# By default, download the fuchsia images from the fuchsia GCS bucket. # By default, download the fuchsia images from the fuchsia GCS bucket.
'fuchsia_images_bucket': 'fuchsia', 'fuchsia_images_bucket': 'fuchsia',
'checkout_fuchsia': False, 'checkout_fuchsia': False,
@ -52,9 +52,9 @@ vars = {
deps = { deps = {
# TODO(kjellander): Move this to be Android-only. # TODO(kjellander): Move this to be Android-only.
'src/base': 'src/base':
'https://chromium.googlesource.com/chromium/src/base@218e807167d2719d6caaf82d2df4c861d3372304', 'https://chromium.googlesource.com/chromium/src/base@dbb0eee8e8238195972062b68b7f46abc5a6f110',
'src/build': 'src/build':
'https://chromium.googlesource.com/chromium/src/build@04c884cbadf1489a7216cb4a43b77daa33442ce2', 'https://chromium.googlesource.com/chromium/src/build@6d974542a020b0ed31b0d9909b3fdc615066fbf0',
'src/buildtools': 'src/buildtools':
'https://chromium.googlesource.com/chromium/src/buildtools@8919328651a559f8a974641d40fe712062cc6718', 'https://chromium.googlesource.com/chromium/src/buildtools@8919328651a559f8a974641d40fe712062cc6718',
# Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC. # Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC.
@ -63,19 +63,19 @@ deps = {
'condition': 'checkout_android', 'condition': 'checkout_android',
}, },
'src/ios': { 'src/ios': {
'url': 'https://chromium.googlesource.com/chromium/src/ios@77324ec269e07ea82cd8c8a15ffb0dfcb3742d72', 'url': 'https://chromium.googlesource.com/chromium/src/ios@0bf6089d480e995951dc097c1aeaab5b562787a4',
'condition': 'checkout_ios', 'condition': 'checkout_ios',
}, },
'src/testing': 'src/testing':
'https://chromium.googlesource.com/chromium/src/testing@977e41b6f78f22f5f9507d8f86f23ddb5c57ae28', 'https://chromium.googlesource.com/chromium/src/testing@02d496a8fcd939b4a906808cbb0a5b4ae8496ea1',
'src/third_party': 'src/third_party':
'https://chromium.googlesource.com/chromium/src/third_party@d0b81aaaa6d9c29983762fa7d85c4b8d07870688', 'https://chromium.googlesource.com/chromium/src/third_party@2831ffa216574f0708fe777e50785a421f68b5ca',
'src/buildtools/linux64': { 'src/buildtools/linux64': {
'packages': [ 'packages': [
{ {
'package': 'gn/gn/linux-${{arch}}', 'package': 'gn/gn/linux-${{arch}}',
'version': 'git_revision:93ee9b91423c1f1f53fb5f6cba7b8eef6247a564', 'version': 'git_revision:415b3b19e094cd4b6982147693485df65037f942',
} }
], ],
'dep_type': 'cipd', 'dep_type': 'cipd',
@ -85,7 +85,7 @@ deps = {
'packages': [ 'packages': [
{ {
'package': 'gn/gn/mac-${{arch}}', 'package': 'gn/gn/mac-${{arch}}',
'version': 'git_revision:93ee9b91423c1f1f53fb5f6cba7b8eef6247a564', 'version': 'git_revision:415b3b19e094cd4b6982147693485df65037f942',
} }
], ],
'dep_type': 'cipd', 'dep_type': 'cipd',
@ -95,7 +95,7 @@ deps = {
'packages': [ 'packages': [
{ {
'package': 'gn/gn/windows-amd64', 'package': 'gn/gn/windows-amd64',
'version': 'git_revision:93ee9b91423c1f1f53fb5f6cba7b8eef6247a564', 'version': 'git_revision:415b3b19e094cd4b6982147693485df65037f942',
} }
], ],
'dep_type': 'cipd', 'dep_type': 'cipd',
@ -119,7 +119,7 @@ deps = {
'src/third_party/libc++/src': 'src/third_party/libc++/src':
'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@6ddb5cb9499f29383155d7ce6b31f7d1102e6ed9', 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@6ddb5cb9499f29383155d7ce6b31f7d1102e6ed9',
'src/third_party/libc++abi/src': 'src/third_party/libc++abi/src':
'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git@1317096ef8cf278e8d654b78fba7833237673ee1', 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git@932d253fedb390a08b17ec3a92469a4553934a6a',
'src/third_party/libunwind/src': 'src/third_party/libunwind/src':
'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libunwind.git@419b03c0b8f20d6da9ddcb0d661a94a97cdd7dad', 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libunwind.git@419b03c0b8f20d6da9ddcb0d661a94a97cdd7dad',
@ -187,11 +187,11 @@ deps = {
}, },
'src/third_party/boringssl/src': 'src/third_party/boringssl/src':
'https://boringssl.googlesource.com/boringssl.git@368d0d87d0bd00f8227f74ce18e8e4384eaf6afa', 'https://boringssl.googlesource.com/boringssl.git@f94f3ed3965ea033001fb9ae006084eee408b861',
'src/third_party/breakpad/breakpad': 'src/third_party/breakpad/breakpad':
'https://chromium.googlesource.com/breakpad/breakpad.git@76788faa4ef163081f82273bfca7fae8a734b971', 'https://chromium.googlesource.com/breakpad/breakpad.git@76788faa4ef163081f82273bfca7fae8a734b971',
'src/third_party/catapult': 'src/third_party/catapult':
'https://chromium.googlesource.com/catapult.git@bb95c350195ce0748de8029855bc71ca1336d5e6', 'https://chromium.googlesource.com/catapult.git@0b9e7b88303cc20347ca923ea45feeb11860c615',
'src/third_party/ced/src': { 'src/third_party/ced/src': {
'url': 'https://chromium.googlesource.com/external/github.com/google/compact_enc_det.git@ba412eaaacd3186085babcd901679a48863c7dd5', 'url': 'https://chromium.googlesource.com/external/github.com/google/compact_enc_det.git@ba412eaaacd3186085babcd901679a48863c7dd5',
}, },
@ -204,9 +204,9 @@ deps = {
'src/third_party/crc32c/src': 'src/third_party/crc32c/src':
'https://chromium.googlesource.com/external/github.com/google/crc32c.git@fa5ade41ee480003d9c5af6f43567ba22e4e17e6', 'https://chromium.googlesource.com/external/github.com/google/crc32c.git@fa5ade41ee480003d9c5af6f43567ba22e4e17e6',
'src/third_party/depot_tools': 'src/third_party/depot_tools':
'https://chromium.googlesource.com/chromium/tools/depot_tools.git@e545830db2fb823da1217b142cb5be10bf45d575', 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@246580c7b80617f291c257c0aa10c155574a7a05',
'src/third_party/ffmpeg': 'src/third_party/ffmpeg':
'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@52d8ef3799b2f16b66351dd0972bb0bcee1648ac', 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@bdcb0b447f433de3b69f0252732791b9f7e26f37',
'src/third_party/flatbuffers/src': 'src/third_party/flatbuffers/src':
'https://chromium.googlesource.com/external/github.com/google/flatbuffers.git@bcb9ef187628fe07514e57756d05e6a6296f7dc5', 'https://chromium.googlesource.com/external/github.com/google/flatbuffers.git@bcb9ef187628fe07514e57756d05e6a6296f7dc5',
'src/third_party/grpc/src': { 'src/third_party/grpc/src': {
@ -232,7 +232,7 @@ deps = {
'condition': 'checkout_android', 'condition': 'checkout_android',
}, },
'src/third_party/googletest/src': 'src/third_party/googletest/src':
'https://chromium.googlesource.com/external/github.com/google/googletest.git@77afe8e0149c207edd9561c28de6d2226673b51f', 'https://chromium.googlesource.com/external/github.com/google/googletest.git@f10e11fb27301fba21caa71030bb5024e67aa135',
'src/third_party/icu': { 'src/third_party/icu': {
'url': 'https://chromium.googlesource.com/chromium/deps/icu.git@364118a1d9da24bb5b770ac3d762ac144d6da5a4', 'url': 'https://chromium.googlesource.com/chromium/deps/icu.git@364118a1d9da24bb5b770ac3d762ac144d6da5a4',
}, },
@ -280,7 +280,7 @@ deps = {
'packages': [ 'packages': [
{ {
'package': 'chromium/third_party/kotlinc', 'package': 'chromium/third_party/kotlinc',
'version': '-kUQ1HWm0wwi5pXKSqIplyfSInHmtRS9cVUzg-2l-Y0C', 'version': 'Rr02Gf2EkaeSs3EhSUHhPqDHSd1AzimrM6cRYUJCPjQC',
}, },
], ],
'condition': 'checkout_android', 'condition': 'checkout_android',
@ -304,9 +304,11 @@ deps = {
'condition': 'checkout_android', 'condition': 'checkout_android',
}, },
'src/third_party/perfetto': 'src/third_party/perfetto':
'https://android.googlesource.com/platform/external/perfetto.git@6fd518058c5ce2c2ae99ddb591f7223a290f39ce', 'https://android.googlesource.com/platform/external/perfetto.git@7609c6712c3a3afc5f2f6b3e4dfe308ee6517f74',
'src/third_party/protobuf-javascript/src':
Var('chromium_git') + '/external/github.com/protocolbuffers/protobuf-javascript' + '@' + 'e34549db516f8712f678fcd4bc411613b5cc5295',
'src/third_party/libvpx/source/libvpx': 'src/third_party/libvpx/source/libvpx':
'https://chromium.googlesource.com/webm/libvpx.git@d790001fd56edbc39482d596868ed83ee7355368', 'https://chromium.googlesource.com/webm/libvpx.git@6445da1b40da7967ccaee23d1ac46d5c3981b89c',
'src/third_party/libyuv': 'src/third_party/libyuv':
'https://chromium.googlesource.com/libyuv/libyuv.git@a6a2ec654b1be1166b376476a7555c89eca0c275', 'https://chromium.googlesource.com/libyuv/libyuv.git@a6a2ec654b1be1166b376476a7555c89eca0c275',
'src/third_party/lss': { 'src/third_party/lss': {
@ -333,7 +335,7 @@ deps = {
'packages': [ 'packages': [
{ {
'package': 'chromium/third_party/r8', 'package': 'chromium/third_party/r8',
'version': 'eHemH-tzLR3jqxqGYiQu6AYGLAPyFYG7klrqbvu1mcQC', 'version': 'kPZJoj3X2XUBofNCeOoUj0P8XChVFgtiNQqMnTwhcOwC',
}, },
], ],
'condition': 'checkout_android', 'condition': 'checkout_android',
@ -357,7 +359,7 @@ deps = {
'condition': 'checkout_android', 'condition': 'checkout_android',
}, },
'src/tools': 'src/tools':
'https://chromium.googlesource.com/chromium/src/tools@09b9b5615bc591b4c8f08ed0c3e0826df769f045', 'https://chromium.googlesource.com/chromium/src/tools@7dad49cbe0ac07edc648e3671e044e16782652d6',
'src/third_party/espresso': { 'src/third_party/espresso': {
'packages': [ 'packages': [
@ -396,7 +398,7 @@ deps = {
'packages': [ 'packages': [
{ {
'package': 'chromium/third_party/androidx', 'package': 'chromium/third_party/androidx',
'version': 'piz2tht912VQfctH5Z23YCOpLUBoypzE5ymRqB3vgLkC', 'version': '1qBFaGY_bIR5f12dL7zKpePRlN4UxIDze8xDv_a0sQEC',
}, },
], ],
'condition': 'checkout_android', 'condition': 'checkout_android',
@ -407,7 +409,7 @@ deps = {
'packages': [ 'packages': [
{ {
'package': 'chromium/third_party/android_build_tools/manifest_merger', 'package': 'chromium/third_party/android_build_tools/manifest_merger',
'version': 'HxnrwdWmIAhi90brIHiGZ4zmnmgKxP4PD0ZsJX6j-mUC', 'version': 'wtRWPCJVk_NA2GQp0fI-1i-JaPzYJwp6w3udjEhgni4C',
}, },
], ],
'condition': 'checkout_android', 'condition': 'checkout_android',
@ -500,11 +502,11 @@ deps = {
'packages': [ 'packages': [
{ {
'package': 'infra/tools/luci/isolate/${{platform}}', 'package': 'infra/tools/luci/isolate/${{platform}}',
'version': 'git_revision:a84377ac0800e2330d02c3dcbf7b4b74a06d6a5b', 'version': 'git_revision:06dc7a1f2eeb1d095f7876799458328a44438df1',
}, },
{ {
'package': 'infra/tools/luci/swarming/${{platform}}', 'package': 'infra/tools/luci/swarming/${{platform}}',
'version': 'git_revision:a84377ac0800e2330d02c3dcbf7b4b74a06d6a5b', 'version': 'git_revision:06dc7a1f2eeb1d095f7876799458328a44438df1',
}, },
], ],
'dep_type': 'cipd', 'dep_type': 'cipd',
@ -1595,11 +1597,33 @@ deps = {
'dep_type': 'cipd', 'dep_type': 'cipd',
}, },
'src/third_party/android_deps/libs/com_squareup_moshi_moshi': {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/com_squareup_moshi_moshi',
'version': 'version:2@1.15.0.cr1',
},
],
'condition': 'checkout_android',
'dep_type': 'cipd',
},
'src/third_party/android_deps/libs/com_squareup_moshi_moshi_adapters': {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/com_squareup_moshi_moshi_adapters',
'version': 'version:2@1.15.0.cr1',
},
],
'condition': 'checkout_android',
'dep_type': 'cipd',
},
'src/third_party/android_deps/libs/com_squareup_okio_okio_jvm': { 'src/third_party/android_deps/libs/com_squareup_okio_okio_jvm': {
'packages': [ 'packages': [
{ {
'package': 'chromium/third_party/android_deps/libs/com_squareup_okio_okio_jvm', 'package': 'chromium/third_party/android_deps/libs/com_squareup_okio_okio_jvm',
'version': 'version:2@3.3.0.cr1', 'version': 'version:2@3.7.0.cr1',
}, },
], ],
'condition': 'checkout_android', 'condition': 'checkout_android',
@ -1610,7 +1634,7 @@ deps = {
'packages': [ 'packages': [
{ {
'package': 'chromium/third_party/android_deps/libs/com_squareup_wire_wire_runtime_jvm', 'package': 'chromium/third_party/android_deps/libs/com_squareup_wire_wire_runtime_jvm',
'version': 'version:2@4.7.0.cr1', 'version': 'version:2@4.9.7.cr1',
}, },
], ],
'condition': 'checkout_android', 'condition': 'checkout_android',

View file

@ -50,6 +50,8 @@ CPPLINT_EXCEPTIONS = [
PYLINT_OLD_STYLE = [ PYLINT_OLD_STYLE = [
"PRESUBMIT.py", "PRESUBMIT.py",
"tools_webrtc/autoroller/roll_deps.py", "tools_webrtc/autoroller/roll_deps.py",
"tools_webrtc/android/build_aar.py",
"tools_webrtc/ios/build_ios_libs.py",
] ]
# These filters will always be removed, even if the caller specifies a filter # These filters will always be removed, even if the caller specifies a filter

View file

@ -51,178 +51,180 @@ import find_depot_tools
def _ParseArgs(): def _ParseArgs():
parser = argparse.ArgumentParser(description='libwebrtc.aar generator.') parser = argparse.ArgumentParser(description='libwebrtc.aar generator.')
parser.add_argument( parser.add_argument(
'--build-dir', '--build-dir',
type=os.path.abspath, type=os.path.abspath,
help='Build dir. By default will create and use temporary dir.') help='Build dir. By default will create and use temporary dir.')
parser.add_argument('--output', parser.add_argument('--output',
default='libwebrtc.aar', default='libwebrtc.aar',
type=os.path.abspath, type=os.path.abspath,
help='Output file of the script.') help='Output file of the script.')
parser.add_argument('--arch', parser.add_argument(
default=DEFAULT_ARCHS, '--arch',
nargs='*', default=DEFAULT_ARCHS,
help='Architectures to build. Defaults to %(default)s.') nargs='*',
parser.add_argument('--use-goma', help='Architectures to build. Defaults to %(default)s.')
action='store_true', parser.add_argument('--use-goma',
default=False, action='store_true',
help='Use goma.') default=False,
parser.add_argument('--use-remoteexec', help='Use goma.')
action='store_true', parser.add_argument('--use-remoteexec',
default=False, action='store_true',
help='Use RBE.') default=False,
parser.add_argument('--use-unstripped-libs', help='Use RBE.')
action='store_true', parser.add_argument('--use-unstripped-libs',
default=False, action='store_true',
help='Use unstripped .so files within libwebrtc.aar') default=False,
parser.add_argument('--verbose', help='Use unstripped .so files within libwebrtc.aar')
action='store_true', parser.add_argument('--verbose',
default=False, action='store_true',
help='Debug logging.') default=False,
parser.add_argument( help='Debug logging.')
'--extra-gn-args', parser.add_argument(
default=[], '--extra-gn-args',
nargs='*', default=[],
help="""Additional GN arguments to be used during Ninja generation. nargs='*',
help="""Additional GN arguments to be used during Ninja generation.
These are passed to gn inside `--args` switch and These are passed to gn inside `--args` switch and
applied after any other arguments and will applied after any other arguments and will
override any values defined by the script. override any values defined by the script.
Example of building debug aar file: Example of building debug aar file:
build_aar.py --extra-gn-args='is_debug=true'""") build_aar.py --extra-gn-args='is_debug=true'""")
parser.add_argument( parser.add_argument(
'--extra-ninja-switches', '--extra-ninja-switches',
default=[], default=[],
nargs='*', nargs='*',
help="""Additional Ninja switches to be used during compilation. help="""Additional Ninja switches to be used during compilation.
These are applied after any other Ninja switches. These are applied after any other Ninja switches.
Example of enabling verbose Ninja output: Example of enabling verbose Ninja output:
build_aar.py --extra-ninja-switches='-v'""") build_aar.py --extra-ninja-switches='-v'""")
parser.add_argument( parser.add_argument(
'--extra-gn-switches', '--extra-gn-switches',
default=[], default=[],
nargs='*', nargs='*',
help="""Additional GN switches to be used during compilation. help="""Additional GN switches to be used during compilation.
These are applied after any other GN switches. These are applied after any other GN switches.
Example of enabling verbose GN output: Example of enabling verbose GN output:
build_aar.py --extra-gn-switches='-v'""") build_aar.py --extra-gn-switches='-v'""")
return parser.parse_args() return parser.parse_args()
def _RunGN(args): def _RunGN(args):
cmd = [ cmd = [
sys.executable, sys.executable,
os.path.join(find_depot_tools.DEPOT_TOOLS_PATH, 'gn.py') os.path.join(find_depot_tools.DEPOT_TOOLS_PATH, 'gn.py')
] ]
cmd.extend(args) cmd.extend(args)
logging.debug('Running: %r', cmd) logging.debug('Running: %r', cmd)
subprocess.check_call(cmd) subprocess.check_call(cmd)
def _RunNinja(output_directory, args): def _RunNinja(output_directory, args):
cmd = [ cmd = [
os.path.join(SRC_DIR, 'third_party', 'ninja', 'ninja'), '-C', os.path.join(SRC_DIR, 'third_party', 'ninja', 'ninja'), '-C',
output_directory output_directory
] ]
cmd.extend(args) cmd.extend(args)
logging.debug('Running: %r', cmd) logging.debug('Running: %r', cmd)
subprocess.check_call(cmd) subprocess.check_call(cmd)
def _EncodeForGN(value): def _EncodeForGN(value):
"""Encodes value as a GN literal.""" """Encodes value as a GN literal."""
if isinstance(value, str): if isinstance(value, str):
return '"' + value + '"' return '"' + value + '"'
if isinstance(value, bool): if isinstance(value, bool):
return repr(value).lower() return repr(value).lower()
return repr(value) return repr(value)
def _GetOutputDirectory(build_dir, arch): def _GetOutputDirectory(build_dir, arch):
"""Returns the GN output directory for the target architecture.""" """Returns the GN output directory for the target architecture."""
return os.path.join(build_dir, arch) return os.path.join(build_dir, arch)
def _GetTargetCpu(arch): def _GetTargetCpu(arch):
"""Returns target_cpu for the GN build with the given architecture.""" """Returns target_cpu for the GN build with the given architecture."""
if arch in ['armeabi', 'armeabi-v7a']: if arch in ['armeabi', 'armeabi-v7a']:
return 'arm' return 'arm'
if arch == 'arm64-v8a': if arch == 'arm64-v8a':
return 'arm64' return 'arm64'
if arch == 'x86': if arch == 'x86':
return 'x86' return 'x86'
if arch == 'x86_64': if arch == 'x86_64':
return 'x64' return 'x64'
raise Exception('Unknown arch: ' + arch) raise Exception('Unknown arch: ' + arch)
def _GetArmVersion(arch): def _GetArmVersion(arch):
"""Returns arm_version for the GN build with the given architecture.""" """Returns arm_version for the GN build with the given architecture."""
if arch == 'armeabi': if arch == 'armeabi':
return 6 return 6
if arch == 'armeabi-v7a': if arch == 'armeabi-v7a':
return 7 return 7
if arch in ['arm64-v8a', 'x86', 'x86_64']: if arch in ['arm64-v8a', 'x86', 'x86_64']:
return None return None
raise Exception('Unknown arch: ' + arch) raise Exception('Unknown arch: ' + arch)
def Build(build_dir, arch, use_goma, use_remoteexec, extra_gn_args, def Build(build_dir, arch, use_goma, use_remoteexec, extra_gn_args,
extra_gn_switches, extra_ninja_switches): extra_gn_switches, extra_ninja_switches):
"""Generates target architecture using GN and builds it using ninja.""" """Generates target architecture using GN and builds it using ninja."""
logging.info('Building: %s', arch) logging.info('Building: %s', arch)
output_directory = _GetOutputDirectory(build_dir, arch) output_directory = _GetOutputDirectory(build_dir, arch)
gn_args = { gn_args = {
'target_os': 'android', 'target_os': 'android',
'is_debug': False, 'is_debug': False,
'is_component_build': False, 'is_component_build': False,
'rtc_include_tests': False, 'rtc_include_tests': False,
'target_cpu': _GetTargetCpu(arch), 'target_cpu': _GetTargetCpu(arch),
'use_goma': use_goma, 'use_goma': use_goma,
'use_remoteexec': use_remoteexec, 'use_remoteexec': use_remoteexec,
} }
arm_version = _GetArmVersion(arch) arm_version = _GetArmVersion(arch)
if arm_version: if arm_version:
gn_args['arm_version'] = arm_version gn_args['arm_version'] = arm_version
gn_args_str = '--args=' + ' '.join( gn_args_str = '--args=' + ' '.join(
[k + '=' + _EncodeForGN(v) for k, v in gn_args.items()] + extra_gn_args) [k + '=' + _EncodeForGN(v)
for k, v in gn_args.items()] + extra_gn_args)
gn_args_list = ['gen', output_directory, gn_args_str] gn_args_list = ['gen', output_directory, gn_args_str]
gn_args_list.extend(extra_gn_switches) gn_args_list.extend(extra_gn_switches)
_RunGN(gn_args_list) _RunGN(gn_args_list)
ninja_args = TARGETS[:] ninja_args = TARGETS[:]
if use_goma or use_remoteexec: if use_goma or use_remoteexec:
ninja_args.extend(['-j', '200']) ninja_args.extend(['-j', '200'])
ninja_args.extend(extra_ninja_switches) ninja_args.extend(extra_ninja_switches)
_RunNinja(output_directory, ninja_args) _RunNinja(output_directory, ninja_args)
def CollectCommon(aar_file, build_dir, arch): def CollectCommon(aar_file, build_dir, arch):
"""Collects architecture independent files into the .aar-archive.""" """Collects architecture independent files into the .aar-archive."""
logging.info('Collecting common files.') logging.info('Collecting common files.')
output_directory = _GetOutputDirectory(build_dir, arch) output_directory = _GetOutputDirectory(build_dir, arch)
aar_file.write(MANIFEST_FILE, 'AndroidManifest.xml') aar_file.write(MANIFEST_FILE, 'AndroidManifest.xml')
aar_file.write(os.path.join(output_directory, JAR_FILE), 'classes.jar') aar_file.write(os.path.join(output_directory, JAR_FILE), 'classes.jar')
def Collect(aar_file, build_dir, arch, unstripped): def Collect(aar_file, build_dir, arch, unstripped):
"""Collects architecture specific files into the .aar-archive.""" """Collects architecture specific files into the .aar-archive."""
logging.info('Collecting: %s', arch) logging.info('Collecting: %s', arch)
output_directory = _GetOutputDirectory(build_dir, arch) output_directory = _GetOutputDirectory(build_dir, arch)
abi_dir = os.path.join('jni', arch) abi_dir = os.path.join('jni', arch)
for so_file in NEEDED_SO_FILES: for so_file in NEEDED_SO_FILES:
source_so_file = os.path.join("lib.unstripped", source_so_file = os.path.join("lib.unstripped",
so_file) if unstripped else so_file so_file) if unstripped else so_file
aar_file.write(os.path.join(output_directory, source_so_file), aar_file.write(os.path.join(output_directory, source_so_file),
os.path.join(abi_dir, so_file)) os.path.join(abi_dir, so_file))
def GenerateLicenses(output_dir, build_dir, archs): def GenerateLicenses(output_dir, build_dir, archs):
builder = LicenseBuilder( builder = LicenseBuilder(
[_GetOutputDirectory(build_dir, arch) for arch in archs], TARGETS) [_GetOutputDirectory(build_dir, arch) for arch in archs], TARGETS)
builder.GenerateLicenseText(output_dir) builder.generate_license_text(output_dir)
def BuildAar(archs, def BuildAar(archs,
@ -234,36 +236,36 @@ def BuildAar(archs,
extra_gn_switches=None, extra_gn_switches=None,
extra_ninja_switches=None, extra_ninja_switches=None,
unstripped=False): unstripped=False):
extra_gn_args = extra_gn_args or [] extra_gn_args = extra_gn_args or []
extra_gn_switches = extra_gn_switches or [] extra_gn_switches = extra_gn_switches or []
extra_ninja_switches = extra_ninja_switches or [] extra_ninja_switches = extra_ninja_switches or []
build_dir = ext_build_dir if ext_build_dir else tempfile.mkdtemp() build_dir = ext_build_dir if ext_build_dir else tempfile.mkdtemp()
for arch in archs:
Build(build_dir, arch, use_goma, use_remoteexec, extra_gn_args,
extra_gn_switches, extra_ninja_switches)
with zipfile.ZipFile(output_file, 'w') as aar_file:
# Architecture doesn't matter here, arbitrarily using the first one.
CollectCommon(aar_file, build_dir, archs[0])
for arch in archs: for arch in archs:
Collect(aar_file, build_dir, arch, unstripped) Build(build_dir, arch, use_goma, use_remoteexec, extra_gn_args,
extra_gn_switches, extra_ninja_switches)
license_dir = os.path.dirname(os.path.realpath(output_file)) with zipfile.ZipFile(output_file, 'w') as aar_file:
GenerateLicenses(license_dir, build_dir, archs) # Architecture doesn't matter here, arbitrarily using the first one.
CollectCommon(aar_file, build_dir, archs[0])
for arch in archs:
Collect(aar_file, build_dir, arch, unstripped)
if not ext_build_dir: license_dir = os.path.dirname(os.path.realpath(output_file))
shutil.rmtree(build_dir, True) GenerateLicenses(license_dir, build_dir, archs)
if not ext_build_dir:
shutil.rmtree(build_dir, True)
def main(): def main():
args = _ParseArgs() args = _ParseArgs()
logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO) logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO)
BuildAar(args.arch, args.output, args.use_goma, args.use_remoteexec, BuildAar(args.arch, args.output, args.use_goma, args.use_remoteexec,
args.extra_gn_args, args.build_dir, args.extra_gn_switches, args.extra_gn_args, args.build_dir, args.extra_gn_switches,
args.extra_ninja_switches, args.use_unstripped_libs) args.extra_ninja_switches, args.use_unstripped_libs)
if __name__ == '__main__': if __name__ == '__main__':
sys.exit(main()) sys.exit(main())

View file

@ -51,308 +51,315 @@ from generate_licenses import LicenseBuilder
def _ParseArgs(): def _ParseArgs():
parser = argparse.ArgumentParser(description=__doc__) parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--build_config', parser.add_argument('--build_config',
default='release', default='release',
choices=['debug', 'release'], choices=['debug', 'release'],
help='The build config. Can be "debug" or "release". ' help='The build config. Can be "debug" or "release". '
'Defaults to "release".') 'Defaults to "release".')
parser.add_argument('--arch', parser.add_argument(
nargs='+', '--arch',
default=DEFAULT_ARCHS, nargs='+',
choices=ENABLED_ARCHS, default=DEFAULT_ARCHS,
help='Architectures to build. Defaults to %(default)s.') choices=ENABLED_ARCHS,
parser.add_argument( help='Architectures to build. Defaults to %(default)s.')
'-c', parser.add_argument(
'--clean', '-c',
action='store_true', '--clean',
default=False, action='store_true',
help='Removes the previously generated build output, if any.') default=False,
parser.add_argument('-p', help='Removes the previously generated build output, if any.')
'--purify', parser.add_argument(
action='store_true', '-p',
default=False, '--purify',
help='Purifies the previously generated build output by ' action='store_true',
'removing the temporary results used when (re)building.') default=False,
parser.add_argument( help='Purifies the previously generated build output by '
'-o', 'removing the temporary results used when (re)building.')
'--output-dir', parser.add_argument(
type=os.path.abspath, '-o',
default=SDK_OUTPUT_DIR, '--output-dir',
help='Specifies a directory to output the build artifacts to. ' type=os.path.abspath,
'If specified together with -c, deletes the dir.') default=SDK_OUTPUT_DIR,
parser.add_argument( help='Specifies a directory to output the build artifacts to. '
'-r', 'If specified together with -c, deletes the dir.')
'--revision', parser.add_argument(
type=int, '-r',
default=0, '--revision',
help='Specifies a revision number to embed if building the framework.') type=int,
parser.add_argument('--verbose', default=0,
action='store_true', help='Specifies a revision number to embed if building the framework.')
default=False, parser.add_argument('--verbose',
help='Debug logging.') action='store_true',
parser.add_argument('--use-goma', default=False,
action='store_true', help='Debug logging.')
default=False, parser.add_argument('--use-goma',
help='Use goma to build.') action='store_true',
parser.add_argument('--use-remoteexec', default=False,
action='store_true', help='Use goma to build.')
default=False, parser.add_argument('--use-remoteexec',
help='Use RBE to build.') action='store_true',
parser.add_argument('--deployment-target', default=False,
default=IOS_MINIMUM_DEPLOYMENT_TARGET['device'], help='Use RBE to build.')
help='Raise the minimum deployment target to build for. ' parser.add_argument(
'Cannot be lowered below 12.0 for iOS/iPadOS ' '--deployment-target',
'and 14.0 for Catalyst.') default=IOS_MINIMUM_DEPLOYMENT_TARGET['device'],
parser.add_argument( help='Raise the minimum deployment target to build for. '
'--extra-gn-args', 'Cannot be lowered below 12.0 for iOS/iPadOS '
default=[], 'and 14.0 for Catalyst.')
nargs='*', parser.add_argument(
help='Additional GN args to be used during Ninja generation.') '--extra-gn-args',
default=[],
nargs='*',
help='Additional GN args to be used during Ninja generation.')
return parser.parse_args() return parser.parse_args()
def _RunCommand(cmd): def _RunCommand(cmd):
logging.debug('Running: %r', cmd) logging.debug('Running: %r', cmd)
subprocess.check_call(cmd, cwd=SRC_DIR) subprocess.check_call(cmd, cwd=SRC_DIR)
def _CleanArtifacts(output_dir): def _CleanArtifacts(output_dir):
if os.path.isdir(output_dir): if os.path.isdir(output_dir):
logging.info('Deleting %s', output_dir) logging.info('Deleting %s', output_dir)
shutil.rmtree(output_dir) shutil.rmtree(output_dir)
def _CleanTemporary(output_dir, architectures): def _CleanTemporary(output_dir, architectures):
if os.path.isdir(output_dir): if os.path.isdir(output_dir):
logging.info('Removing temporary build files.') logging.info('Removing temporary build files.')
for arch in architectures: for arch in architectures:
arch_lib_path = os.path.join(output_dir, arch) arch_lib_path = os.path.join(output_dir, arch)
if os.path.isdir(arch_lib_path): if os.path.isdir(arch_lib_path):
shutil.rmtree(arch_lib_path) shutil.rmtree(arch_lib_path)
def _ParseArchitecture(architectures): def _ParseArchitecture(architectures):
result = dict() result = dict()
for arch in architectures: for arch in architectures:
if ":" in arch: if ":" in arch:
target_environment, target_cpu = arch.split(":") target_environment, target_cpu = arch.split(":")
else: else:
logging.warning('The environment for build is not specified.') logging.warning('The environment for build is not specified.')
logging.warning('It is assumed based on cpu type.') logging.warning('It is assumed based on cpu type.')
logging.warning('See crbug.com/1138425 for more details.') logging.warning('See crbug.com/1138425 for more details.')
if arch == "x64": if arch == "x64":
target_environment = "simulator" target_environment = "simulator"
else: else:
target_environment = "device" target_environment = "device"
target_cpu = arch target_cpu = arch
archs = result.get(target_environment) archs = result.get(target_environment)
if archs is None: if archs is None:
result[target_environment] = {target_cpu} result[target_environment] = {target_cpu}
else: else:
archs.add(target_cpu) archs.add(target_cpu)
return result return result
def _VersionMax(*versions): def _VersionMax(*versions):
return max( return max(*versions,
*versions, key=lambda version:
key=lambda version: [int(component) for component in version.split('.')]) [int(component) for component in version.split('.')])
def BuildWebRTC(output_dir, target_environment, target_arch, flavor, def BuildWebRTC(output_dir, target_environment, target_arch, flavor,
gn_target_name, ios_deployment_target, libvpx_build_vp9, gn_target_name, ios_deployment_target, libvpx_build_vp9,
use_goma, use_remoteexec, extra_gn_args): use_goma, use_remoteexec, extra_gn_args):
gn_args = [ gn_args = [
'target_os="ios"', 'target_os="ios"',
'ios_enable_code_signing=false', 'ios_enable_code_signing=false',
'is_component_build=false', 'is_component_build=false',
'rtc_include_tests=false', 'rtc_include_tests=false',
] ]
# Add flavor option. # Add flavor option.
if flavor == 'debug': if flavor == 'debug':
gn_args.append('is_debug=true') gn_args.append('is_debug=true')
elif flavor == 'release': elif flavor == 'release':
gn_args.append('is_debug=false') gn_args.append('is_debug=false')
else: else:
raise ValueError('Unexpected flavor type: %s' % flavor) raise ValueError('Unexpected flavor type: %s' % flavor)
gn_args.append('target_environment="%s"' % target_environment) gn_args.append('target_environment="%s"' % target_environment)
gn_args.append('target_cpu="%s"' % target_arch) gn_args.append('target_cpu="%s"' % target_arch)
gn_args.append('ios_deployment_target="%s"' % ios_deployment_target) gn_args.append('ios_deployment_target="%s"' % ios_deployment_target)
gn_args.append('rtc_libvpx_build_vp9=' + gn_args.append('rtc_libvpx_build_vp9=' +
('true' if libvpx_build_vp9 else 'false')) ('true' if libvpx_build_vp9 else 'false'))
gn_args.append('use_lld=true') gn_args.append('use_lld=true')
gn_args.append('use_goma=' + ('true' if use_goma else 'false')) gn_args.append('use_goma=' + ('true' if use_goma else 'false'))
gn_args.append('use_remoteexec=' + ('true' if use_remoteexec else 'false')) gn_args.append('use_remoteexec=' + ('true' if use_remoteexec else 'false'))
gn_args.append('rtc_enable_objc_symbol_export=true') gn_args.append('rtc_enable_objc_symbol_export=true')
args_string = ' '.join(gn_args + extra_gn_args) args_string = ' '.join(gn_args + extra_gn_args)
logging.info('Building WebRTC with args: %s', args_string) logging.info('Building WebRTC with args: %s', args_string)
cmd = [ cmd = [
sys.executable, sys.executable,
os.path.join(find_depot_tools.DEPOT_TOOLS_PATH, 'gn.py'), os.path.join(find_depot_tools.DEPOT_TOOLS_PATH, 'gn.py'),
'gen', 'gen',
output_dir, output_dir,
'--args=' + args_string, '--args=' + args_string,
] ]
_RunCommand(cmd) _RunCommand(cmd)
logging.info('Building target: %s', gn_target_name) logging.info('Building target: %s', gn_target_name)
cmd = [ cmd = [
os.path.join(SRC_DIR, 'third_party', 'ninja', 'ninja'), os.path.join(SRC_DIR, 'third_party', 'ninja', 'ninja'),
'-C', '-C',
output_dir, output_dir,
gn_target_name, gn_target_name,
] ]
if use_goma or use_remoteexec: if use_goma or use_remoteexec:
cmd.extend(['-j', '200']) cmd.extend(['-j', '200'])
_RunCommand(cmd) _RunCommand(cmd)
def main(): def main():
args = _ParseArgs() args = _ParseArgs()
logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO) logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO)
if args.clean: if args.clean:
_CleanArtifacts(args.output_dir) _CleanArtifacts(args.output_dir)
return 0 return 0
# architectures is typed as Dict[str, Set[str]], # architectures is typed as Dict[str, Set[str]],
# where key is for the environment (device or simulator) # where key is for the environment (device or simulator)
# and value is for the cpu type. # and value is for the cpu type.
architectures = _ParseArchitecture(args.arch) architectures = _ParseArchitecture(args.arch)
gn_args = args.extra_gn_args gn_args = args.extra_gn_args
if args.purify: if args.purify:
_CleanTemporary(args.output_dir, list(architectures.keys())) _CleanTemporary(args.output_dir, list(architectures.keys()))
return 0 return 0
gn_target_name = 'framework_objc' gn_target_name = 'framework_objc'
gn_args.append('enable_dsyms=true') gn_args.append('enable_dsyms=true')
gn_args.append('enable_stripping=true') gn_args.append('enable_stripping=true')
# Build all architectures. # Build all architectures.
framework_paths = [] framework_paths = []
all_lib_paths = [] all_lib_paths = []
for (environment, archs) in list(architectures.items()): for (environment, archs) in list(architectures.items()):
ios_deployment_target = _VersionMax( ios_deployment_target = _VersionMax(
args.deployment_target, IOS_MINIMUM_DEPLOYMENT_TARGET[environment]) args.deployment_target, IOS_MINIMUM_DEPLOYMENT_TARGET[environment])
framework_path = os.path.join(args.output_dir, environment) framework_path = os.path.join(args.output_dir, environment)
framework_paths.append(framework_path) framework_paths.append(framework_path)
lib_paths = [] lib_paths = []
for arch in archs: for arch in archs:
lib_path = os.path.join(framework_path, arch + '_libs') lib_path = os.path.join(framework_path, arch + '_libs')
lib_paths.append(lib_path) lib_paths.append(lib_path)
BuildWebRTC(lib_path, environment, arch, args.build_config, BuildWebRTC(lib_path, environment, arch, args.build_config,
gn_target_name, ios_deployment_target, LIBVPX_BUILD_VP9, gn_target_name, ios_deployment_target,
args.use_goma, args.use_remoteexec, gn_args) LIBVPX_BUILD_VP9, args.use_goma, args.use_remoteexec,
all_lib_paths.extend(lib_paths) gn_args)
all_lib_paths.extend(lib_paths)
# Combine the slices.
dylib_path = os.path.join(SDK_FRAMEWORK_NAME, 'WebRTC')
# Dylibs will be combined, all other files are the same across archs.
shutil.rmtree(os.path.join(framework_path, SDK_FRAMEWORK_NAME),
ignore_errors=True)
shutil.copytree(os.path.join(lib_paths[0], SDK_FRAMEWORK_NAME),
os.path.join(framework_path, SDK_FRAMEWORK_NAME),
symlinks=True)
logging.info('Merging framework slices for %s.', environment)
dylib_paths = [os.path.join(path, dylib_path) for path in lib_paths]
out_dylib_path = os.path.join(framework_path, dylib_path)
if os.path.islink(out_dylib_path):
out_dylib_path = os.path.join(os.path.dirname(out_dylib_path),
os.readlink(out_dylib_path))
try:
os.remove(out_dylib_path)
except OSError:
pass
cmd = ['lipo'] + dylib_paths + ['-create', '-output', out_dylib_path]
_RunCommand(cmd)
# Merge the dSYM slices.
lib_dsym_dir_path = os.path.join(lib_paths[0], SDK_DSYM_NAME)
if os.path.isdir(lib_dsym_dir_path):
shutil.rmtree(os.path.join(framework_path, SDK_DSYM_NAME),
ignore_errors=True)
shutil.copytree(lib_dsym_dir_path,
os.path.join(framework_path, SDK_DSYM_NAME))
logging.info('Merging dSYM slices.')
dsym_path = os.path.join(SDK_DSYM_NAME, 'Contents', 'Resources',
'DWARF', 'WebRTC')
lib_dsym_paths = [
os.path.join(path, dsym_path) for path in lib_paths
]
out_dsym_path = os.path.join(framework_path, dsym_path)
try:
os.remove(out_dsym_path)
except OSError:
pass
cmd = ['lipo'
] + lib_dsym_paths + ['-create', '-output', out_dsym_path]
_RunCommand(cmd)
# Check for Mac-style WebRTC.framework/Resources/ (for Catalyst)...
resources_dir = os.path.join(framework_path, SDK_FRAMEWORK_NAME,
'Resources')
if not os.path.exists(resources_dir):
# ...then fall back to iOS-style WebRTC.framework/
resources_dir = os.path.dirname(resources_dir)
# Modify the version number.
# Format should be <Branch cut MXX>.<Hotfix #>.<Rev #>.
# e.g. 55.0.14986 means
# branch cut 55, no hotfixes, and revision 14986.
infoplist_path = os.path.join(resources_dir, 'Info.plist')
cmd = [
'PlistBuddy', '-c', 'Print :CFBundleShortVersionString',
infoplist_path
]
major_minor = subprocess.check_output(cmd).decode('utf-8').strip()
version_number = '%s.%s' % (major_minor, args.revision)
logging.info('Substituting revision number: %s', version_number)
cmd = [
'PlistBuddy', '-c', 'Set :CFBundleVersion ' + version_number,
infoplist_path
]
_RunCommand(cmd)
_RunCommand(['plutil', '-convert', 'binary1', infoplist_path])
xcframework_dir = os.path.join(args.output_dir, SDK_XCFRAMEWORK_NAME)
if os.path.isdir(xcframework_dir):
shutil.rmtree(xcframework_dir)
logging.info('Creating xcframework.')
cmd = ['xcodebuild', '-create-xcframework', '-output', xcframework_dir]
# Apparently, xcodebuild needs absolute paths for input arguments
for framework_path in framework_paths:
cmd += [
'-framework',
os.path.abspath(os.path.join(framework_path, SDK_FRAMEWORK_NAME)),
]
dsym_full_path = os.path.join(framework_path, SDK_DSYM_NAME)
if os.path.exists(dsym_full_path):
cmd += ['-debug-symbols', os.path.abspath(dsym_full_path)]
# Combine the slices.
dylib_path = os.path.join(SDK_FRAMEWORK_NAME, 'WebRTC')
# Dylibs will be combined, all other files are the same across archs.
shutil.rmtree(os.path.join(framework_path, SDK_FRAMEWORK_NAME),
ignore_errors=True)
shutil.copytree(os.path.join(lib_paths[0], SDK_FRAMEWORK_NAME),
os.path.join(framework_path, SDK_FRAMEWORK_NAME),
symlinks=True)
logging.info('Merging framework slices for %s.', environment)
dylib_paths = [os.path.join(path, dylib_path) for path in lib_paths]
out_dylib_path = os.path.join(framework_path, dylib_path)
if os.path.islink(out_dylib_path):
out_dylib_path = os.path.join(os.path.dirname(out_dylib_path),
os.readlink(out_dylib_path))
try:
os.remove(out_dylib_path)
except OSError:
pass
cmd = ['lipo'] + dylib_paths + ['-create', '-output', out_dylib_path]
_RunCommand(cmd) _RunCommand(cmd)
# Merge the dSYM slices. # Generate the license file.
lib_dsym_dir_path = os.path.join(lib_paths[0], SDK_DSYM_NAME) logging.info('Generate license file.')
if os.path.isdir(lib_dsym_dir_path): gn_target_full_name = '//sdk:' + gn_target_name
shutil.rmtree(os.path.join(framework_path, SDK_DSYM_NAME), builder = LicenseBuilder(all_lib_paths, [gn_target_full_name])
ignore_errors=True) builder.generate_license_text(
shutil.copytree(lib_dsym_dir_path, os.path.join(args.output_dir, SDK_XCFRAMEWORK_NAME))
os.path.join(framework_path, SDK_DSYM_NAME))
logging.info('Merging dSYM slices.')
dsym_path = os.path.join(SDK_DSYM_NAME, 'Contents', 'Resources', 'DWARF',
'WebRTC')
lib_dsym_paths = [os.path.join(path, dsym_path) for path in lib_paths]
out_dsym_path = os.path.join(framework_path, dsym_path)
try:
os.remove(out_dsym_path)
except OSError:
pass
cmd = ['lipo'] + lib_dsym_paths + ['-create', '-output', out_dsym_path]
_RunCommand(cmd)
# Check for Mac-style WebRTC.framework/Resources/ (for Catalyst)... logging.info('Done.')
resources_dir = os.path.join(framework_path, SDK_FRAMEWORK_NAME, return 0
'Resources')
if not os.path.exists(resources_dir):
# ...then fall back to iOS-style WebRTC.framework/
resources_dir = os.path.dirname(resources_dir)
# Modify the version number.
# Format should be <Branch cut MXX>.<Hotfix #>.<Rev #>.
# e.g. 55.0.14986 means
# branch cut 55, no hotfixes, and revision 14986.
infoplist_path = os.path.join(resources_dir, 'Info.plist')
cmd = [
'PlistBuddy', '-c', 'Print :CFBundleShortVersionString',
infoplist_path
]
major_minor = subprocess.check_output(cmd).decode('utf-8').strip()
version_number = '%s.%s' % (major_minor, args.revision)
logging.info('Substituting revision number: %s', version_number)
cmd = [
'PlistBuddy', '-c', 'Set :CFBundleVersion ' + version_number,
infoplist_path
]
_RunCommand(cmd)
_RunCommand(['plutil', '-convert', 'binary1', infoplist_path])
xcframework_dir = os.path.join(args.output_dir, SDK_XCFRAMEWORK_NAME)
if os.path.isdir(xcframework_dir):
shutil.rmtree(xcframework_dir)
logging.info('Creating xcframework.')
cmd = ['xcodebuild', '-create-xcframework', '-output', xcframework_dir]
# Apparently, xcodebuild needs absolute paths for input arguments
for framework_path in framework_paths:
cmd += [
'-framework',
os.path.abspath(os.path.join(framework_path, SDK_FRAMEWORK_NAME)),
]
dsym_full_path = os.path.join(framework_path, SDK_DSYM_NAME)
if os.path.exists(dsym_full_path):
cmd += ['-debug-symbols', os.path.abspath(dsym_full_path)]
_RunCommand(cmd)
# Generate the license file.
logging.info('Generate license file.')
gn_target_full_name = '//sdk:' + gn_target_name
builder = LicenseBuilder(all_lib_paths, [gn_target_full_name])
builder.GenerateLicenseText(
os.path.join(args.output_dir, SDK_XCFRAMEWORK_NAME))
logging.info('Done.')
return 0
if __name__ == '__main__': if __name__ == '__main__':
sys.exit(main()) sys.exit(main())

View file

@ -78,8 +78,9 @@ LIB_TO_LICENSES_DICT = {
'spl_sqrt_floor': ['common_audio/third_party/spl_sqrt_floor/LICENSE'], 'spl_sqrt_floor': ['common_audio/third_party/spl_sqrt_floor/LICENSE'],
'kotlin_stdlib': ['third_party/kotlin_stdlib/LICENSE'], 'kotlin_stdlib': ['third_party/kotlin_stdlib/LICENSE'],
'jni_zero': ['third_party/jni_zero/LICENSE'], 'jni_zero': ['third_party/jni_zero/LICENSE'],
'protobuf-javascript': ['third_party/protobuf-javascript/LICENSE'],
# TODO(bugs.webrtc.org/1110): Remove this hack. This is not a lib. # TODO(bugs.webrtc.org/1110): Remove this hack. This is not a lib.
# For some reason it is listed as so in _GetThirdPartyLibraries. # For some reason it is listed as so in _get_third_party_libraries.
'android_deps': [], 'android_deps': [],
# This is not a library but a collection of libraries. # This is not a library but a collection of libraries.
'androidx': [], 'androidx': [],
@ -97,7 +98,7 @@ LIB_REGEX_TO_LICENSES_DICT = {
'com_android_support_support_annotations/LICENSE' 'com_android_support_support_annotations/LICENSE'
], ],
# Internal dependencies, licenses are already included by other dependencies # Internal dependencies, licenses are already included by other deps.
'android_deps:com_android_support_support_annotations.*': [], 'android_deps:com_android_support_support_annotations.*': [],
} }
@ -111,7 +112,7 @@ SRC_DIR = os.path.dirname(os.path.dirname(SCRIPT_DIR))
# tools we need are *actually* in their build folder, thus we need to move up # tools we need are *actually* in their build folder, thus we need to move up
# to the *true* source root, when we're embedded like this. # to the *true* source root, when we're embedded like this.
if SRC_DIR.endswith(os.path.join('third_party', 'webrtc')): if SRC_DIR.endswith(os.path.join('third_party', 'webrtc')):
SRC_DIR = os.path.abspath(os.path.join(SRC_DIR, os.pardir, os.pardir)) SRC_DIR = os.path.abspath(os.path.join(SRC_DIR, os.pardir, os.pardir))
sys.path.append(os.path.join(SRC_DIR, 'build')) sys.path.append(os.path.join(SRC_DIR, 'build'))
import find_depot_tools import find_depot_tools
@ -120,28 +121,29 @@ THIRD_PARTY_LIB_REGEX_TEMPLATE = r'^.*/third_party/%s$'
class LicenseBuilder: class LicenseBuilder:
def __init__(self,
buildfile_dirs,
targets,
lib_to_licenses_dict=None,
lib_regex_to_licenses_dict=None):
if lib_to_licenses_dict is None:
lib_to_licenses_dict = LIB_TO_LICENSES_DICT
if lib_regex_to_licenses_dict is None: def __init__(self,
lib_regex_to_licenses_dict = LIB_REGEX_TO_LICENSES_DICT buildfile_dirs,
targets,
lib_to_licenses_dict=None,
lib_regex_to_licenses_dict=None):
if lib_to_licenses_dict is None:
lib_to_licenses_dict = LIB_TO_LICENSES_DICT
self.buildfile_dirs = buildfile_dirs if lib_regex_to_licenses_dict is None:
self.targets = targets lib_regex_to_licenses_dict = LIB_REGEX_TO_LICENSES_DICT
self.lib_to_licenses_dict = lib_to_licenses_dict
self.lib_regex_to_licenses_dict = lib_regex_to_licenses_dict
self.common_licenses_dict = self.lib_to_licenses_dict.copy() self.buildfile_dirs = buildfile_dirs
self.common_licenses_dict.update(self.lib_regex_to_licenses_dict) self.targets = targets
self.lib_to_licenses_dict = lib_to_licenses_dict
self.lib_regex_to_licenses_dict = lib_regex_to_licenses_dict
@staticmethod self.common_licenses_dict = self.lib_to_licenses_dict.copy()
def _ParseLibraryName(dep): self.common_licenses_dict.update(self.lib_regex_to_licenses_dict)
"""Returns library name after third_party
@staticmethod
def _parse_library_name(dep):
"""Returns library name after third_party
Input one of: Input one of:
//a/b/third_party/libname:c //a/b/third_party/libname:c
@ -150,11 +152,11 @@ class LicenseBuilder:
Outputs libname or None if this is not a third_party dependency. Outputs libname or None if this is not a third_party dependency.
""" """
groups = re.match(THIRD_PARTY_LIB_SIMPLE_NAME_REGEX, dep) groups = re.match(THIRD_PARTY_LIB_SIMPLE_NAME_REGEX, dep)
return groups.group(1) if groups else None return groups.group(1) if groups else None
def _ParseLibrary(self, dep): def _parse_library(self, dep):
"""Returns library simple or regex name that matches `dep` after third_party """Return library simple or regex name matching `dep` after third_party
This method matches `dep` dependency against simple names in This method matches `dep` dependency against simple names in
LIB_TO_LICENSES_DICT and regular expression names in LIB_TO_LICENSES_DICT and regular expression names in
@ -162,104 +164,110 @@ class LicenseBuilder:
Outputs matched dict key or None if this is not a third_party dependency. Outputs matched dict key or None if this is not a third_party dependency.
""" """
libname = LicenseBuilder._ParseLibraryName(dep) libname = LicenseBuilder._parse_library_name(dep)
for lib_regex in self.lib_regex_to_licenses_dict: for lib_regex in self.lib_regex_to_licenses_dict:
if re.match(THIRD_PARTY_LIB_REGEX_TEMPLATE % lib_regex, dep): if re.match(THIRD_PARTY_LIB_REGEX_TEMPLATE % lib_regex, dep):
return lib_regex return lib_regex
return libname return libname
@staticmethod @staticmethod
def _RunGN(buildfile_dir, target): def _run_gn(buildfile_dir, target):
cmd = [ cmd = [
sys.executable, sys.executable,
os.path.join(find_depot_tools.DEPOT_TOOLS_PATH, 'gn.py'), os.path.join(find_depot_tools.DEPOT_TOOLS_PATH, 'gn.py'),
'desc', 'desc',
'--all', '--all',
'--format=json', '--format=json',
os.path.abspath(buildfile_dir), os.path.abspath(buildfile_dir),
target, target,
] ]
logging.debug('Running: %r', cmd) logging.debug('Running: %r', cmd)
output_json = subprocess.check_output(cmd, cwd=WEBRTC_ROOT).decode('UTF-8') output_json = subprocess.check_output(cmd,
logging.debug('Output: %s', output_json) cwd=WEBRTC_ROOT).decode('UTF-8')
return output_json logging.debug('Output: %s', output_json)
return output_json
def _GetThirdPartyLibraries(self, buildfile_dir, target): def _get_third_party_libraries(self, buildfile_dir, target):
output = json.loads(LicenseBuilder._RunGN(buildfile_dir, target)) output = json.loads(LicenseBuilder._run_gn(buildfile_dir, target))
libraries = set() libraries = set()
for described_target in list(output.values()): for described_target in list(output.values()):
third_party_libs = (self._ParseLibrary(dep) third_party_libs = (self._parse_library(dep)
for dep in described_target['deps']) for dep in described_target['deps'])
libraries |= set(lib for lib in third_party_libs if lib) libraries |= set(lib for lib in third_party_libs if lib)
return libraries return libraries
def GenerateLicenseText(self, output_dir): def generate_license_text(self, output_dir):
# Get a list of third_party libs from gn. For fat libraries we must consider # Get a list of third_party libs from gn. For fat libraries we must
# all architectures, hence the multiple buildfile directories. # consider all architectures, hence the multiple buildfile directories.
third_party_libs = set() third_party_libs = set()
for buildfile in self.buildfile_dirs: for buildfile in self.buildfile_dirs:
for target in self.targets: for target in self.targets:
third_party_libs |= self._GetThirdPartyLibraries(buildfile, target) third_party_libs |= self._get_third_party_libraries(
assert len(third_party_libs) > 0 buildfile, target)
assert len(third_party_libs) > 0
missing_licenses = third_party_libs - set(self.common_licenses_dict.keys()) missing_licenses = third_party_libs - set(
if missing_licenses: self.common_licenses_dict.keys())
error_msg = 'Missing licenses for following third_party targets: %s' % \ if missing_licenses:
', '.join(sorted(missing_licenses)) error_msg = 'Missing licenses for third_party targets: %s' % \
logging.error(error_msg) ', '.join(sorted(missing_licenses))
raise Exception(error_msg) logging.error(error_msg)
raise Exception(error_msg)
# Put webrtc at the front of the list. # Put webrtc at the front of the list.
license_libs = sorted(third_party_libs) license_libs = sorted(third_party_libs)
license_libs.insert(0, 'webrtc') license_libs.insert(0, 'webrtc')
logging.info('List of licenses: %s', ', '.join(license_libs)) logging.info('List of licenses: %s', ', '.join(license_libs))
# Generate markdown. # Generate markdown.
output_license_file = open(os.path.join(output_dir, 'LICENSE.md'), 'w+') output_license_file = open(os.path.join(output_dir, 'LICENSE.md'),
for license_lib in license_libs: 'w+')
if len(self.common_licenses_dict[license_lib]) == 0: for license_lib in license_libs:
logging.info('Skipping compile time or internal dependency: %s', if len(self.common_licenses_dict[license_lib]) == 0:
license_lib) logging.info(
continue # Compile time dependency 'Skipping compile time or internal dependency: %s',
license_lib)
continue # Compile time dependency
output_license_file.write('# %s\n' % license_lib) output_license_file.write('# %s\n' % license_lib)
output_license_file.write('```\n') output_license_file.write('```\n')
for path in self.common_licenses_dict[license_lib]: for path in self.common_licenses_dict[license_lib]:
license_path = os.path.join(WEBRTC_ROOT, path) license_path = os.path.join(WEBRTC_ROOT, path)
with open(license_path, 'r') as license_file: with open(license_path, 'r') as license_file:
license_text = escape(license_file.read(), quote=True) license_text = escape(license_file.read(), quote=True)
output_license_file.write(license_text) output_license_file.write(license_text)
output_license_file.write('\n') output_license_file.write('\n')
output_license_file.write('```\n\n') output_license_file.write('```\n\n')
output_license_file.close() output_license_file.close()
def main(): def main():
parser = argparse.ArgumentParser(description='Generate WebRTC LICENSE.md') parser = argparse.ArgumentParser(description='Generate WebRTC LICENSE.md')
parser.add_argument('--verbose', parser.add_argument('--verbose',
action='store_true', action='store_true',
default=False, default=False,
help='Debug logging.') help='Debug logging.')
parser.add_argument('--target', parser.add_argument('--target',
required=True, required=True,
action='append', action='append',
default=[], default=[],
help='Name of the GN target to generate a license for') help='Name of the GN target to generate a license for')
parser.add_argument('output_dir', help='Directory to output LICENSE.md to.') parser.add_argument('output_dir',
parser.add_argument('buildfile_dirs', help='Directory to output LICENSE.md to.')
nargs='+', parser.add_argument('buildfile_dirs',
help='Directories containing gn generated ninja files') nargs='+',
args = parser.parse_args() help='Directories containing gn generated ninja files')
args = parser.parse_args()
logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO) logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO)
builder = LicenseBuilder(args.buildfile_dirs, args.target) builder = LicenseBuilder(args.buildfile_dirs, args.target)
builder.GenerateLicenseText(args.output_dir) builder.generate_license_text(args.output_dir)
if __name__ == '__main__': if __name__ == '__main__':
sys.exit(main()) sys.exit(main())

View file

@ -17,9 +17,10 @@ from generate_licenses import LicenseBuilder
class TestLicenseBuilder(unittest.TestCase): class TestLicenseBuilder(unittest.TestCase):
@staticmethod
def _FakeRunGN(buildfile_dir, target): @staticmethod
return """ def _fake_run_gn(buildfile_dir, target):
return """
{ {
"target1": { "target1": {
"deps": [ "deps": [
@ -32,89 +33,94 @@ class TestLicenseBuilder(unittest.TestCase):
} }
""" """
def testParseLibraryName(self): def test_parse_library_name(self):
self.assertEqual( self.assertEqual(
LicenseBuilder._ParseLibraryName('//a/b/third_party/libname1:c'), LicenseBuilder._parse_library_name('//a/b/third_party/libname1:c'),
'libname1') 'libname1')
self.assertEqual( self.assertEqual(
LicenseBuilder._ParseLibraryName('//a/b/third_party/libname2:c(d)'), LicenseBuilder._parse_library_name(
'libname2') '//a/b/third_party/libname2:c(d)'), 'libname2')
self.assertEqual( self.assertEqual(
LicenseBuilder._ParseLibraryName('//a/b/third_party/libname3/c:d(e)'), LicenseBuilder._parse_library_name(
'libname3') '//a/b/third_party/libname3/c:d(e)'), 'libname3')
self.assertEqual( self.assertEqual(
LicenseBuilder._ParseLibraryName('//a/b/not_third_party/c'), None) LicenseBuilder._parse_library_name('//a/b/not_third_party/c'),
None)
def testParseLibrarySimpleMatch(self): def test_parse_library_simple_match(self):
builder = LicenseBuilder([], [], {}, {}) builder = LicenseBuilder([], [], {}, {})
self.assertEqual(builder._ParseLibrary('//a/b/third_party/libname:c'), self.assertEqual(builder._parse_library('//a/b/third_party/libname:c'),
'libname') 'libname')
def testParseLibraryRegExNoMatchFallbacksToDefaultLibname(self): def test_parse_library_regex_no_match_fallbacks_to_default_libname(self):
lib_dict = { lib_dict = {
'libname:foo.*': ['path/to/LICENSE'], 'libname:foo.*': ['path/to/LICENSE'],
} }
builder = LicenseBuilder([], [], lib_dict, {}) builder = LicenseBuilder([], [], lib_dict, {})
self.assertEqual( self.assertEqual(
builder._ParseLibrary('//a/b/third_party/libname:bar_java'), 'libname') builder._parse_library('//a/b/third_party/libname:bar_java'),
'libname')
def testParseLibraryRegExMatch(self): def test_parse_library_regex_match(self):
lib_regex_dict = { lib_regex_dict = {
'libname:foo.*': ['path/to/LICENSE'], 'libname:foo.*': ['path/to/LICENSE'],
} }
builder = LicenseBuilder([], [], {}, lib_regex_dict) builder = LicenseBuilder([], [], {}, lib_regex_dict)
self.assertEqual( self.assertEqual(
builder._ParseLibrary('//a/b/third_party/libname:foo_bar_java'), builder._parse_library('//a/b/third_party/libname:foo_bar_java'),
'libname:foo.*') 'libname:foo.*')
def testParseLibraryRegExMatchWithSubDirectory(self): def test_parse_library_regex_match_with_sub_directory(self):
lib_regex_dict = { lib_regex_dict = {
'libname/foo:bar.*': ['path/to/LICENSE'], 'libname/foo:bar.*': ['path/to/LICENSE'],
} }
builder = LicenseBuilder([], [], {}, lib_regex_dict) builder = LicenseBuilder([], [], {}, lib_regex_dict)
self.assertEqual( self.assertEqual(
builder._ParseLibrary('//a/b/third_party/libname/foo:bar_java'), builder._parse_library('//a/b/third_party/libname/foo:bar_java'),
'libname/foo:bar.*') 'libname/foo:bar.*')
def testParseLibraryRegExMatchWithStarInside(self): def test_parse_library_regex_match_with_star_inside(self):
lib_regex_dict = { lib_regex_dict = {
'libname/foo.*bar.*': ['path/to/LICENSE'], 'libname/foo.*bar.*': ['path/to/LICENSE'],
} }
builder = LicenseBuilder([], [], {}, lib_regex_dict) builder = LicenseBuilder([], [], {}, lib_regex_dict)
self.assertEqual( self.assertEqual(
builder._ParseLibrary('//a/b/third_party/libname/fooHAHA:bar_java'), builder._parse_library(
'libname/foo.*bar.*') '//a/b/third_party/libname/fooHAHA:bar_java'),
'libname/foo.*bar.*')
@patch('generate_licenses.LicenseBuilder._RunGN', _FakeRunGN) @patch('generate_licenses.LicenseBuilder._run_gn', _fake_run_gn)
def testGetThirdPartyLibrariesWithoutRegex(self): def test_get_third_party_libraries_without_regex(self):
builder = LicenseBuilder([], [], {}, {}) builder = LicenseBuilder([], [], {}, {})
self.assertEqual(builder._GetThirdPartyLibraries('out/arm', 'target1'), self.assertEqual(
set(['libname1', 'libname2', 'libname3'])) builder._get_third_party_libraries('out/arm', 'target1'),
set(['libname1', 'libname2', 'libname3']))
@patch('generate_licenses.LicenseBuilder._RunGN', _FakeRunGN) @patch('generate_licenses.LicenseBuilder._run_gn', _fake_run_gn)
def testGetThirdPartyLibrariesWithRegex(self): def test_get_third_party_libraries_with_regex(self):
lib_regex_dict = { lib_regex_dict = {
'libname2:c.*': ['path/to/LICENSE'], 'libname2:c.*': ['path/to/LICENSE'],
} }
builder = LicenseBuilder([], [], {}, lib_regex_dict) builder = LicenseBuilder([], [], {}, lib_regex_dict)
self.assertEqual(builder._GetThirdPartyLibraries('out/arm', 'target1'), self.assertEqual(
set(['libname1', 'libname2:c.*', 'libname3'])) builder._get_third_party_libraries('out/arm', 'target1'),
set(['libname1', 'libname2:c.*', 'libname3']))
@patch('generate_licenses.LicenseBuilder._RunGN', _FakeRunGN) @patch('generate_licenses.LicenseBuilder._run_gn', _fake_run_gn)
def testGenerateLicenseTextFailIfUnknownLibrary(self): def test_generate_license_text_fail_if_unknown_library(self):
lib_dict = { lib_dict = {
'simple_library': ['path/to/LICENSE'], 'simple_library': ['path/to/LICENSE'],
} }
builder = LicenseBuilder(['dummy_dir'], ['dummy_target'], lib_dict, {}) builder = LicenseBuilder(['dummy_dir'], ['dummy_target'], lib_dict, {})
with self.assertRaises(Exception) as context: with self.assertRaises(Exception) as context:
builder.GenerateLicenseText('dummy/dir') builder.generate_license_text('dummy/dir')
self.assertEqual( self.assertEqual(
context.exception.args[0], context.exception.args[0],
'Missing licenses for following third_party targets: ' 'Missing licenses for third_party targets: '
'libname1, libname2, libname3') 'libname1, libname2, libname3')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()