From 06f6061e0587648c94c9c8a8aa99c3730ef2a248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B8=D1=82=D0=B0=D0=BB=D0=B8=D0=B9=20=D0=9D=D0=B8?= =?UTF-8?q?=D0=BA=D0=B8=D1=82=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Tue, 20 Jan 2026 13:42:56 +0700 Subject: [PATCH] first commit --- build_webrtc_multiabi.sh | 230 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 build_webrtc_multiabi.sh diff --git a/build_webrtc_multiabi.sh b/build_webrtc_multiabi.sh new file mode 100644 index 0000000..e1ba0fe --- /dev/null +++ b/build_webrtc_multiabi.sh @@ -0,0 +1,230 @@ +#!/bin/bash +# +# Этот скрипт автоматизирует подготовку окружения и сборку WebRTC libjingle_peerconnection_so с поддержкой H.265 +# и сборкой libstream-webrtc-1.3.9.aar от getstream под Android с собранными .so +# Что делает: +# 1) Ставит пакеты apt, которые нужны для сборки (git, curl, python, ninja, cmake, JDK и т.д.). +# 2) Качает набор инструментов depot_tools (fetch/gclient/gn) и добавляет его в PATH. +# 3) Загружает исходники WebRTC, переписывает .gclient так, чтобы сборка была под Android (target_os = ["android"]). +# 4) Подключает удалённый репозиторий GetStream, переходит на тег m137.0 (это версия, на которой собран их AAR 1.3.9), синхронизирует зависимости и запускает runhooks. +# 5) Создаёт вспомогательный Python‑скрипт build_multiabi_aar.py, который поочерёдно собирает AAR для каждой архитектуры и потом объединяет .so в один libstream-webrtc-1.3.9.aar. +# 6) Запускает сборку для arm64‑v8a, armeabi‑v7a, x86 и x86_64 с выключенным режимом отладки и включённым H.265. +# +# Итог: готовый libstream-webrtc-1.3.9.aar лежит в каталоге src, а промежуточные AAR‑файлы по ABI находятся в out/aar/_abi_aars и out/aar//. +# +# Запуск: запустите этот файл на Ubuntu (понадобятся sudo‑права для apt install). +# Скрипт пропустит шаги, если каталоги или удалённый уже существуют. +# +set -e + +echo "=== Шаг 1: Обновляем список пакетов и ставим зависимости ===" +sudo apt update +sudo apt install -y git curl python3 python3-venv python3-pip ninja-build \ + cmake default-jdk pkg-config + +echo "=== Шаг 2: Клонируем depot_tools и добавляем в PATH ===" +mkdir -p WEBRTC +cd WEBRTC + +if [ ! -d depot_tools ]; then + echo "Клонируем depot_tools..." + git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git +else + echo "Каталог depot_tools уже существует; пропускаем клонирование." +fi + +# Добавляем depot_tools в PATH только для этого скрипта. Это позволит пользоваться +# `fetch`, `gclient` и `gn`, не изменяя постоянные настройки пользователя. +export PATH="$PWD/depot_tools:$PATH" + +echo "=== Шаг 3: Качаем исходники WebRTC ===" +if [ ! -d src ]; then + # `fetch` создаст каталог `src` и файл .gclient. + fetch --nohooks webrtc +else + echo "Каталог src уже есть; пропускаем fetch." +fi + +echo "=== Шаг 4: Правим .gclient под Android ===" +# Перезаписываем .gclient и прописываем target_os = [ \"android\" ]. +cat > .gclient <<'EOF' +solutions = [ + { + "name": "src", + "url": "https://webrtc.googlesource.com/src.git", + "deps_file": "DEPS", + "managed": False, + "custom_deps": {}, + }, +] +target_os = [ "android" ] +EOF + +echo "=== Шаг 5: Checkout тега m137.0 и синхронизация зависимостей ===" +cd src + +# Добавляем удалённый репозиторий GetStream, если он ещё не добавлен. +if ! git remote | grep -q '^stream$'; then + echo "Добавляем удалённый репозиторий GetStream..." + git remote add stream https://github.com/GetStream/webrtc.git +else + echo "Удалённый GetStream уже есть; пропускаем добавление." +fi + +git fetch stream --tags # стягиваем теги, чтобы появился m137.0 + +git checkout tags/m137.0 # переключаемся на нужный тег + +echo "Запускаем gclient sync и gclient runhooks..." +gclient sync --jobs 1 -D +gclient runhooks + +echo "=== Шаг 6: Создаём обёрточный build_multiabi_aar.py ===" +# Записываем вспомогательный скрипт в tools_webrtc/android/build_multiabi_aar.py. Он собирает AAR для каждой архитектуры, а потом склеивает их JNI‑библиотеки в единый libstream-webrtc-1.3.9.aar. +cat > tools_webrtc/android/build_multiabi_aar.py <<'PY' +#!/usr/bin/env python3 +""" +Обёртка для сборки libwebrtc.aar сразу под несколько ABI. + +Оригинальный скрипт tools_webrtc/android/build_aar.py за один запуск собирает только одну архитектуру, +а итоговый libwebrtc.aar иногда содержит только последнюю собранную архитектуру. Этот скрипт решает +проблему: он собирает AAR для каждого ABI по отдельности, потом извлекает из каждого файл +jni//libjingle_peerconnection_so.so и собирает их в один архив. + +Аргумент --arch может повторяться для перечисления нужных ABI (arm64-v8a, armeabi-v7a, x86, x86_64). +Дополнительные параметры GN передаются через --extra-gn-args, например чтобы включить H.265. + +Пример запуска: + python3 build_multiabi_aar.py \ + --build-dir=out/aar \ + --arch=arm64-v8a --arch=armeabi-v7a --arch=x86 --arch=x86_64 \ + --extra-gn-args='is_debug=false rtc_include_tests=false rtc_build_examples=false rtc_use_h265=true' \ + --final-out=./libwebrtc.aar + +Итоговый AAR будет записан в файл, указанный параметром --final-out. +""" +import argparse +import os +import shutil +import subprocess +import zipfile +import tempfile +import sys + +# Compute the absolute repository root from this script's location. +ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) + +def run(cmd): + """Выполняет команду в корне репозитория и выводит её в терминал.""" + print(">>", " ".join(cmd)) + subprocess.check_call(cmd, cwd=ROOT) + +def find_built_aar(build_dir): + """Возвращает путь к AAR, собранному build_aar.py, если он существует.""" + cand1 = os.path.join(build_dir, "libwebrtc.aar") + cand2 = os.path.join(ROOT, "libwebrtc.aar") + for c in (cand1, cand2): + if os.path.exists(c): + return c + return None + +def unzip_member(zpath, member, dest_dir): + """Извлекает один файл из ZIP‑архива в указанную директорию.""" + with zipfile.ZipFile(zpath, "r") as zf: + zf.extract(member, dest_dir) + +def main(): + parser = argparse.ArgumentParser(description="Собрать libwebrtc.aar под несколько ABI") + parser.add_argument("--build-dir", default="out/aar", help="Каталог, который использует build_aar.py") + parser.add_argument("--arch", action="append", required=True, help="ABI для сборки; повторяйте для нескольких") + parser.add_argument("--extra-gn-args", dest="extra_gn_args", default="", help="Дополнительные параметры GN, передаваемые build_aar.py") + parser.add_argument("--final-out", default=os.path.join(ROOT, "libwebrtc.aar"), help="Путь к итоговому AAR") + args = parser.parse_args() + + build_dir = os.path.join(ROOT, args.build_dir) + os.makedirs(build_dir, exist_ok=True) + + # A directory to store per‑ABI AARs + stash_dir = os.path.join(build_dir, "_abi_aars") + os.makedirs(stash_dir, exist_ok=True) + + built = [] + for abi in args.arch: + # Construct the command to build the AAR for this ABI + cmd = [sys.executable, + os.path.join(ROOT, "tools_webrtc", "android", "build_aar.py"), + "--build-dir=" + args.build_dir, + "--arch=" + abi] + if args.extra_gn_args: + cmd.append("--extra-gn-args=" + args.extra_gn_args) + run(cmd) + + produced = find_built_aar(build_dir) + if not produced: + raise RuntimeError(f"libwebrtc.aar not found after building {abi}") + abi_aar = os.path.join(stash_dir, f"{abi}.aar") + shutil.copy2(produced, abi_aar) + print(f"[OK] Stored {abi} AAR -> {abi_aar}") + built.append((abi, abi_aar)) + + # Use first ABI AAR as the base for non‑JNI files + base_abi, base_aar = built[0] + stage = tempfile.mkdtemp(prefix="webrtc_aar_") + with zipfile.ZipFile(base_aar, "r") as zf: + zf.extractall(stage) + + # Replace or create the jni directory with combined libs + jni_dir = os.path.join(stage, "jni") + shutil.rmtree(jni_dir, ignore_errors=True) + os.makedirs(jni_dir, exist_ok=True) + + for abi, abi_aar in built: + tmp = tempfile.mkdtemp(prefix="webrtc_abi_") + try: + member = f"jni/{abi}/libjingle_peerconnection_so.so" + unzip_member(abi_aar, member, tmp) + abi_dir = os.path.join(jni_dir, abi) + os.makedirs(abi_dir, exist_ok=True) + shutil.move(os.path.join(tmp, member), os.path.join(abi_dir, "libjingle_peerconnection_so.so")) + finally: + shutil.rmtree(tmp, ignore_errors=True) + + # Write final AAR + final_aar = args.final_out + if os.path.exists(final_aar): + os.remove(final_aar) + with zipfile.ZipFile(final_aar, "w", zipfile.ZIP_DEFLATED) as zf: + for root, dirs, files in os.walk(stage): + for f in files: + full = os.path.join(root, f) + rel = os.path.relpath(full, stage) + zf.write(full, rel) + + print("\n[OK] Создан многоплатформенный AAR:", final_aar) + with zipfile.ZipFile(final_aar, "r") as zf: + for n in zf.namelist(): + if n.startswith("jni/") and n.endswith(".so"): + print(" ", n) + +if __name__ == "__main__": + main() +PY + +# Make the helper script executable +chmod +x tools_webrtc/android/build_multiabi_aar.py + +echo "=== Шаг 7: Сборка libstream-webrtc-1.3.9.aar для нескольких ABI c H.265 ===" +# Запускаем вспомогательный скрипт, передавая необходимые архитектуры и параметры GN. +# Итоговый AAR будет записан в /libstream-webrtc-1.3.9.aar. +python3 tools_webrtc/android/build_multiabi_aar.py \ + --build-dir=out/aar \ + --arch=arm64-v8a \ + --arch=armeabi-v7a \ + --arch=x86 \ + --arch=x86_64 \ + --extra-gn-args='is_debug=false rtc_include_tests=false rtc_build_examples=false rtc_use_h265=true' \ + --final-out="$(pwd)/libstream-webrtc-1.3.9.aar" + +echo "Всё готово!" +echo "Готовый libstream-webrtc-1.3.9.aar находится в: $(pwd)/libstream-webrtc-1.3.9.aar" +echo "Промежуточные AAR‑файлы по архитектурам лежат в директории out/aar/_abi_aars"