#!/usr/bin/env bash set -euo pipefail # Reproducible custom WebRTC xcframework build for Rosetta iOS. # Applies the same E2EE timestamp patch as the Android custom build. # # Requirements: # - macOS with Xcode (Command Line Tools) # - depot_tools in PATH (run bootstrap_depot_tools.sh first if needed) # - python3, git # # Usage: # cd /path/to/Rosetta/tools/webrtc-custom-ios # ./build_custom_webrtc_ios.sh SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROSETTA_DIR="$(cd "${SCRIPT_DIR}/../.." && pwd)" PATCH_FILE="${SCRIPT_DIR}/patches/0001-audio-e2ee-pass-rtp-timestamp-as-additional-data.patch" # Default: WebRTC M125 family — same as Android (branch-heads/6422). WEBRTC_BRANCH="${WEBRTC_BRANCH:-branch-heads/6422}" WEBRTC_TAG="${WEBRTC_TAG:-}" # Source checkout root (contains src/). WEBRTC_ROOT="${WEBRTC_ROOT:-$HOME/webrtc_ios}" WEBRTC_SRC="${WEBRTC_SRC:-${WEBRTC_ROOT}/src}" # Output framework consumed by Xcode project. OUT_FRAMEWORK="${OUT_FRAMEWORK:-${ROSETTA_DIR}/Frameworks/WebRTC.xcframework}" # Sync tuning (chromium.googlesource rate limits). SYNC_JOBS="${SYNC_JOBS:-1}" SYNC_RETRIES="${SYNC_RETRIES:-8}" SYNC_RETRY_BASE_SEC="${SYNC_RETRY_BASE_SEC:-20}" echo "[webrtc-ios] root: ${WEBRTC_ROOT}" echo "[webrtc-ios] src: ${WEBRTC_SRC}" echo "[webrtc-ios] out: ${OUT_FRAMEWORK}" echo "[webrtc-ios] sync jobs: ${SYNC_JOBS}, retries: ${SYNC_RETRIES}" export DEPOT_TOOLS_UPDATE=0 retry_cmd() { local max_attempts="$1" shift local attempt=1 local backoff="${SYNC_RETRY_BASE_SEC}" while true; do if "$@"; then return 0 fi if (( attempt >= max_attempts )); then return 1 fi echo "[webrtc-ios] attempt ${attempt}/${max_attempts} failed, retrying in ${backoff}s: $*" sleep "${backoff}" backoff=$(( backoff * 2 )) if (( backoff > 300 )); then backoff=300 fi attempt=$(( attempt + 1 )) done } sync_with_retry() { local attempt=1 while true; do if gclient sync -D --jobs "${SYNC_JOBS}"; then return 0 fi if (( attempt >= SYNC_RETRIES )); then echo "[webrtc-ios] ERROR: gclient sync failed after ${SYNC_RETRIES} attempts" return 1 fi local wait_sec=$(( SYNC_RETRY_BASE_SEC * attempt )) if (( wait_sec > 300 )); then wait_sec=300 fi echo "[webrtc-ios] gclient sync failed (attempt ${attempt}/${SYNC_RETRIES}), sleeping ${wait_sec}s..." sleep "${wait_sec}" attempt=$(( attempt + 1 )) done } if ! command -v fetch >/dev/null 2>&1; then echo "[webrtc-ios] ERROR: depot_tools 'fetch' not found in PATH" echo "[webrtc-ios] Run: git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git" echo "[webrtc-ios] Then: export PATH=\$PATH:/path/to/depot_tools" exit 1 fi # Step 1: Checkout WebRTC source for iOS if [[ ! -d "${WEBRTC_SRC}/.git" ]]; then echo "[webrtc-ios] checkout not found, fetching webrtc_ios..." mkdir -p "${WEBRTC_ROOT}" pushd "${WEBRTC_ROOT}" >/dev/null retry_cmd "${SYNC_RETRIES}" fetch --nohooks --no-history webrtc_ios sync_with_retry popd >/dev/null fi pushd "${WEBRTC_SRC}" >/dev/null # Step 2: Sync to target branch echo "[webrtc-ios] syncing source..." retry_cmd "${SYNC_RETRIES}" git fetch --all --tags if [[ -n "${WEBRTC_TAG}" ]]; then retry_cmd "${SYNC_RETRIES}" git checkout "${WEBRTC_TAG}" else if git show-ref --verify --quiet "refs/remotes/origin/${WEBRTC_BRANCH}"; then retry_cmd "${SYNC_RETRIES}" git checkout -B "${WEBRTC_BRANCH}" "origin/${WEBRTC_BRANCH}" else retry_cmd "${SYNC_RETRIES}" git checkout "${WEBRTC_BRANCH}" fi if git rev-parse --abbrev-ref --symbolic-full-name '@{u}' >/dev/null 2>&1; then retry_cmd "${SYNC_RETRIES}" git pull --ff-only fi fi sync_with_retry # Step 3: Apply E2EE patch echo "[webrtc-ios] applying Rosetta E2EE patch..." git reset --hard echo "[webrtc-ios] apply $(basename "${PATCH_FILE}")" git apply --check "${PATCH_FILE}" git apply "${PATCH_FILE}" echo "[webrtc-ios] patch applied successfully" # Step 4: Build iOS framework echo "[webrtc-ios] building xcframework (this takes 30-60 minutes)..." mkdir -p "$(dirname "${OUT_FRAMEWORK}")" # Remove previous build if exists rm -rf "${OUT_FRAMEWORK}" python3 tools_webrtc/ios/build_ios_libs.py \ --build-dir out_rosetta_ios \ --output-dir "$(dirname "${OUT_FRAMEWORK}")" \ --arch arm64 x86_64 \ --extra-gn-args "is_debug=false is_component_build=false rtc_include_tests=false rtc_build_examples=false" echo "[webrtc-ios] done" echo "[webrtc-ios] framework: ${OUT_FRAMEWORK}" echo "" echo "Next steps:" echo " 1. Remove stasel/WebRTC SPM dependency from Xcode" echo " 2. Add ${OUT_FRAMEWORK} as Embedded Framework" echo " 3. Build and verify: logs should show ad=8 (not ad=0)" popd >/dev/null