first commit
This commit is contained in:
230
build_webrtc_multiabi.sh
Normal file
230
build_webrtc_multiabi.sh
Normal file
@@ -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/<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 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 будет записан в <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"
|
||||||
Reference in New Issue
Block a user