ringrtc/bin/build-webrtc.py

229 lines
8.6 KiB
Python
Executable file

#!/usr/bin/env python3
#
# Copyright 2023 Signal Messenger, LLC
# SPDX-License-Identifier: AGPL-3.0-only
#
"""
This script builds webrtc artifacts for the specified target
"""
try:
import argparse
import logging
import platform
import subprocess
import os
except ImportError as e:
raise ImportError(str(e) + '- required module not found')
TARGET_PLATFORMS = ['android', 'ios', 'linux', 'mac', 'windows']
def parse_args():
parser = argparse.ArgumentParser(
description='Build webrtc')
parser.add_argument('--clean',
action='store_true',
help='Remove all the build products. Default is false')
parser.add_argument('--debug',
action='store_true',
help='Build a debug version. Default is both')
parser.add_argument('--dry-run',
action='store_true',
help='Dry Run: print what would happen, but do not actually do anything')
parser.add_argument('--target',
required=True,
help='build target: ' + ', '.join(TARGET_PLATFORMS))
parser.add_argument('--release',
action='store_true',
help='Build a release version. Default is both')
parser.add_argument('-v', '--verbose',
action='store_true',
help='Verbose output')
return parser.parse_args()
def run_cmd(dry_run, cmd, cwd=None, env=os.environ.copy()):
logging.debug('Running: {}'.format(cmd))
if dry_run is False:
subprocess.check_call(cmd, cwd=cwd, env=env)
def verify_build_host_platform(target_platform):
if target_platform == 'android' or target_platform == 'linux':
expected_os_major_version = 'Ubuntu 22'
actual_os = subprocess.check_output(['lsb_release', '--short', '--description']).decode('UTF-8')
if expected_os_major_version not in actual_os:
raise Exception(f"Invalid Host OS Major Version. Expected: {expected_os_major_version} Actual: {actual_os}")
elif target_platform == 'ios' or target_platform == 'mac':
expected_system = 'Darwin'
if platform.system() != expected_system:
raise Exception(f"Invalid Host OS. Expected: {expected_system} Actual: {platform.system()}")
expected_major_version = '12'
version = subprocess.check_output(['sw_vers', '-productVersion']).decode('UTF-8').rstrip()
major_version = version.split('.')[0]
if int(major_version) < int(expected_major_version):
raise Exception(f"Invalid Host OS version. Expected: {expected_major_version} Actual: {major_version}")
elif target_platform == 'windows':
expected_system = 'Windows'
if platform.system() != expected_system:
raise Exception(f"Invalid Host OS. Expected: {expected_system} Actual: {platform.system()}")
def main() -> None:
args = parse_args()
if args.dry_run is True:
args.verbose = True
if args.verbose is True:
log_level = logging.DEBUG
else:
log_level = logging.INFO
logging.basicConfig(level=log_level, format='%(levelname).1s:%(message)s')
build_types = []
if args.debug:
build_types.append("debug")
if args.release:
build_types.append("release")
if not args.debug and not args.release:
build_types.append("debug")
build_types.append("release")
logging.info('''
Target platform : {}
Build type : {}
'''.format(args.target, build_types))
verify_build_host_platform(args.target)
if args.clean is True:
run_cmd(args.dry_run, ['make', 'distclean'])
run_cmd(args.dry_run, ['rm', '-rf', 'out_arm'])
# Install Chromium depot tools
if not os.path.isdir('out/depot_tools'):
run_cmd(args.dry_run, ['mkdir', '-p', 'out'])
run_cmd(args.dry_run, ['git',
'clone',
'--depth',
'1',
'https://chromium.googlesource.com/chromium/tools/depot_tools.git',
'out/depot_tools'])
# Add depot tools to PATH environment variable
cwd = os.getcwd()
env = os.environ.copy()
env["PATH"] = f"{cwd}/out/depot_tools:{env['PATH']}"
if args.target == 'android' or args.target == 'linux':
# Install build dependencies
run_cmd(args.dry_run, ['sudo', 'apt', 'install', 'make', 'pkg-config'])
if args.target == 'android':
# Prepare workspace
run_cmd(args.dry_run, ['bin/prepare-workspace', 'android'], env=env)
# Build WebRTC for android
for build_type in build_types:
run_cmd(args.dry_run,
['bin/build-aar', '--webrtc-only', '--archive-webrtc', '--' + build_type],
env=env)
elif args.target == 'linux':
# Prepare workspace
run_cmd(args.dry_run, ['bin/prepare-workspace', 'unix'], env=env)
# Build WebRTC for x86_64
for build_type in build_types:
run_cmd(args.dry_run,
['bin/build-electron', '--webrtc-only', '--archive-webrtc', '--' + build_type],
env=env)
# Build WebRTC for arm64
run_cmd(args.dry_run,
['src/webrtc/src/build/linux/sysroot_scripts/install-sysroot.py', '--arch=arm64'],
env=env)
env['TARGET_ARCH'] = "arm64"
env['OUTPUT_DIR'] = "out_arm"
for build_type in build_types:
run_cmd(args.dry_run,
['bin/build-electron', '--webrtc-only', '--archive-webrtc', '--' + build_type],
env=env)
elif args.target == 'ios' or args.target == 'mac':
# Get grealpath
run_cmd(args.dry_run, ['brew', 'install', 'coreutils'])
# Set up Xcode (https://github.com/RobotsAndPencils/xcodes)
run_cmd(args.dry_run, ['brew', 'install', 'robotsandpencils/made/xcodes'])
# This step requires Apple credentials provided as environment variables XCODES_USERNAME and XCODES_PASSWORD
run_cmd(args.dry_run, ['xcodes', 'install', '14.0.1'])
run_cmd(args.dry_run, ['sudo', 'xcodes', 'select', '14.0.1'])
# Clear saved credentials
run_cmd(args.dry_run, ['xcodes', 'signout'])
# Accept the license
run_cmd(args.dry_run, ['sudo', 'xcodebuild', '-license', 'accept'])
# Install components
run_cmd(args.dry_run, ['sudo', 'xcodebuild', '-runFirstLaunch'])
if args.target == 'ios':
# Prepare workspace
run_cmd(args.dry_run, ['bin/prepare-workspace', 'ios'], env=env)
# Ensure this library path exists so that the build succeeds
run_cmd(args.dry_run, ['sudo', 'mkdir', '-p', '/usr/local/lib'])
for build_type in build_types:
run_cmd(args.dry_run,
['bin/build-ios', '--webrtc-only', '--archive-webrtc', '--' + build_type],
env=env)
elif args.target == 'mac':
# Prepare workspace
run_cmd(args.dry_run, ['bin/prepare-workspace', 'mac'], env=env)
for build_type in build_types:
run_cmd(args.dry_run,
['bin/build-electron', '--webrtc-only', '--archive-webrtc', '--' + build_type],
env=env)
env['TARGET_ARCH'] = "arm64"
env['OUTPUT_DIR'] = "out_arm"
for build_type in build_types:
run_cmd(args.dry_run,
['bin/build-electron', '--webrtc-only', '--archive-webrtc', '--' + build_type],
env=env)
elif args.target == 'windows':
bash = 'C:\\Program Files\\Git\\bin\\bash.exe'
# Prepare workspace
run_cmd(args.dry_run, [bash, 'bin/prepare-workspace', 'windows'], env=env)
for build_type in build_types:
run_cmd(args.dry_run,
[bash, 'bin/build-electron', '--webrtc-only', '--archive-webrtc', '--' + build_type],
env=env)
# Prepare workspace for arm
env['OUTPUT_DIR'] = "out_arm"
run_cmd(args.dry_run, [bash, 'bin/prepare-workspace', 'windows'], env=env)
env['TARGET_ARCH'] = "arm64"
for build_type in build_types:
run_cmd(args.dry_run,
[bash, 'bin/build-electron', '--webrtc-only', '--archive-webrtc', '--' + build_type],
env=env)
if __name__ == '__main__':
main()