android_webrtc_build is a command-line tool that downloads, configures, and
builds an official WebRTC release branch for Android. It resolves Chromium
milestones at runtime through Chromium Dash, builds the AAR with WebRTC's own
tools_webrtc/android/build_aar.py, and exports both the AAR and its Java/JNI
artifacts.
The script is designed for interactive use and repeatable CI jobs. It never hard-codes a milestone-to-branch mapping and never discards an existing WebRTC checkout without an explicit choice.
- Runtime milestone discovery from
chromiumdash.appspot.com/fetch_milestones - Interactive version menu or non-interactive
--milestoneselection - Release and debug builds
- Selectable Android ABIs and optional Ninja job limit
- Configurable H.264 and H.265 GN flags
- Mandatory 16 KB ELF alignment checks for 64-bit Android libraries
- Isolated checkout per milestone with safe reuse/fresh behavior
- Official
libwebrtc.aarplus extractedclasses.jarand JNI libraries - Machine-readable build metadata
- Strict error handling, retrying network requests, and optional log capture
WebRTC Android development is supported on Linux. The build itself requires a Debian/Ubuntu-compatible environment when using automatic dependency installation.
Bootstrap commands required by the script are:
- Bash 4 or newer
curlgitpython3mktemp
The WebRTC dependency installer adds the remaining compiler, Android SDK/NDK,
and system packages when --install-deps is supplied. Without that flag, the
script checks its bootstrap requirements but assumes the full WebRTC build
toolchain is already installed.
WebRTC source checkouts and build outputs consume tens of gigabytes and a build can take hours. Use a machine with ample free disk space, memory, and cooling capacity.
Clone the repository and run the interactive workflow:
git clone https://github.com/rfazi/android_webrtc_build.git
cd android_webrtc_build
./entrypoint.sh --install-depsThe script downloads the current branch list, displays the latest 20 valid milestones, and asks which one to build.
For CI or unattended builds, provide the milestone explicitly:
./entrypoint.sh \
--milestone 150 \
--arch arm64-v8a \
--jobs 8 \
--build-type release \
--reuse \
--install-deps \
--log-file ./logs/webrtc-m150.log--milestone is still resolved and validated against Chromium Dash at runtime.
The numeric WebRTC branch returned by the service is used for checkout.
Show the latest 20 buildable milestones:
./entrypoint.sh --list-versionsShow a larger list or request all available historical entries:
./entrypoint.sh --list-versions --limit 50
./entrypoint.sh --list-versions --limit allEntries without a numeric webrtc_branch are excluded. Network errors,
unexpected HTTP responses, and malformed JSON stop the command with an
actionable error instead of falling back to stale data.
| Option | Description |
|---|---|
-m, --milestone M |
Select Chromium milestone M; required without an interactive terminal. |
--list-versions |
Print milestones and their WebRTC/Chromium branches, then exit. |
--limit N|all |
Limit menu/list results; defaults to 20. |
-a, --arch ABI[,ABI...] |
Select one or more ABIs. May be repeated. |
-j, --jobs N |
Pass a Ninja parallel-job limit when supported by the selected branch. |
--build-type release|debug |
Select the GN build type; defaults to release. |
--h264, --no-h264 |
Enable or disable H.264; enabled by default. |
--h265, --no-h265 |
Enable or disable H.265; disabled by default. |
-w, --work-dir PATH |
Workspace root; defaults to ./.webrtc-workspaces. |
-o, --output-dir PATH |
Artifact root; defaults to ./output. |
--install-deps |
Install bootstrap and WebRTC build packages on Debian/Ubuntu. |
--reuse |
Reuse an existing clean checkout for the selected milestone. |
--fresh |
Safely delete and recreate only the selected milestone workspace. |
--verbose |
Print invoked commands and enable upstream verbose logging. |
--log-file PATH |
Mirror stdout and stderr to a file and copy it into the final artifacts. |
-h, --help |
Print built-in help. |
Supported Android ABIs are:
armeabi-v7aarm64-v8ax86x86_64
All four are built when --arch is omitted. Multiple values can be comma
separated or supplied by repeating the option:
./entrypoint.sh --milestone 150 --arch armeabi-v7a,arm64-v8a --fresh
./entrypoint.sh --milestone 150 --arch arm64-v8a --arch x86_64 --freshThe default layout separates the shared Chromium tooling from milestone source checkouts:
.webrtc-workspaces/
├── depot_tools/
├── M150/
│ └── checkout/
│ └── src/
└── M151/
└── checkout/
└── src/
When a milestone workspace already exists:
- Interactive runs ask whether to reuse it, recreate it, or stop.
- Non-interactive runs require
--reuseor--fresh. --reuserefuses a checkout with tracked or untracked local changes.--freshvalidates that the target is exactly anM<number>child of the configured workspace root before removing it.
Source checkouts are never shared between milestones. Reusing a clean checkout does preserve its incremental build cache.
The selected WebRTC ref is fetched from
refs/branch-heads/<webrtc_branch>. Dependencies are synchronized with branch
heads and tags before running hooks and invoking the branch's official AAR
builder.
Artifacts are grouped by milestone and build configuration:
output/
└── M150/
└── release-h264-on-h265-off/
└── arm64-v8a/
├── libwebrtc.aar
├── classes.jar
├── jni/
│ └── arm64-v8a/
│ └── libjingle_peerconnection_so.so
├── LICENSE.md
├── build-info.json
└── build.log # only with --log-file
build-info.json records the milestone, resolved branches, exact WebRTC commit,
ABIs, build type, codec flags, verified 16 KB architectures, Chromium Dash
endpoint, and UTC build time.
The upstream builder interface changes over time. Before starting an expensive
build, the script inspects build_aar.py --help and verifies that required
options exist. If an older milestone cannot accept an explicit --jobs value,
the script asks you to omit that option and let Ninja select its own parallelism.
The default matches the previous project behavior:
proprietary_codecs=truertc_use_h264=truertc_use_h265=false
The proprietary-codec flag is disabled when both H.264 and H.265 are disabled. Codec availability, patents, licenses, and distribution requirements vary by country and product. Evaluate those requirements before distributing a custom WebRTC build.
Android 15 introduced support for devices using 16 KB memory pages. Native
libraries used on those devices need ELF LOAD segments aligned to at least
2**14. This project treats that as a build requirement for arm64-v8a and
x86_64, following the
Android 16 KB page-size guidance.
The script applies two safeguards:
- Before compilation, it rejects historical Chromium branches that explicitly force a 4 KB maximum page size for 64-bit Android targets.
- After the AAR is built, it runs the checked-out toolchain's
llvm-objdumpagainst every exported 64-bit JNI library. Every ELFLOADsegment must be aligned to at least 16 KB or the build fails before artifacts are published.
Recent Chromium branches configure 16 KB alignment in their Android toolchain.
The final binary inspection remains mandatory because it verifies the actual
output instead of assuming that a particular NDK or branch is compatible. The
checked ABIs are recorded under android_16kb_page_size in build-info.json.
The AAR check covers ELF alignment, not the packaging of the application that
consumes it. For the final APK or AAB, use Android Gradle Plugin 8.5.1 or newer,
Android SDK Build-Tools 35.0.0 or newer, verify the final APK with
zipalign -c -P 16 -v 4, and test on a 16 KB Android environment. Confirm the
test device with:
adb shell getconf PAGE_SIZEThe expected value is 16384.
Rerun with --install-deps on Debian/Ubuntu. On other Linux distributions,
install the equivalent WebRTC requirements manually.
Pass exactly one of --reuse or --fresh. Use --reuse for an incremental
build cache and --fresh when reproducibility requires a new checkout.
The script intentionally refuses to overwrite changes under
.webrtc-workspaces/M<version>/checkout/src. Preserve those changes elsewhere
or select --fresh when it is safe to remove the whole milestone workspace.
The tool does not use cached milestone mappings. Retry after connectivity or service availability is restored.
Some historical build_aar.py versions do not expose
--extra-ninja-switches. Omit --jobs; all other supported settings are still
passed to the upstream builder.
Choose a newer milestone. The script stops before compilation when the selected Chromium branch explicitly configures 4 KB alignment for a requested 64-bit ABI. Disabling this guard would produce a library that does not meet the project's Android 16 KB compatibility requirement.
The generated 64-bit .so contains an ELF LOAD segment aligned below
2**14, or the checked-out llvm-objdump could not inspect it. Keep the failed
workspace for diagnosis, inspect the upstream Android linker configuration, and
select a newer milestone if the release branch predates 16 KB support. No
unverified artifacts are copied to the configuration output directory.
rfazi/android_webrtc is a small
Android application demonstrating libraries produced by this project.
The original article, How to build WebRTC for Android, describes the motivation and earlier workflow.
This project is distributed under the MIT License. WebRTC and its third-party dependencies retain their respective licenses; the build output includes the license material generated by WebRTC's official AAR builder.
