Files
build-webrtc-multiabi/build_webrtc_multiabi.sh
Виталий Никитенко 06f6061e05 first commit
2026-01-20 13:42:56 +07:00

231 lines
11 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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) Запускает сборку для arm64v8a, armeabiv7a, x86 и x86_64 с выключенным режимом отладки и включённым H.265.
#
# Итог: готовый libstream-webrtc-1.3.9.aar лежит в каталоге src, а промежуточные AARфайлы по ABI находятся в out/aar/_abi_aars и out/aar/<abi>/.
#
# Запуск: запустите этот файл на 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/<abi>/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 perABI 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 nonJNI 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 будет записан в <src>/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"