ubuntu18.04編譯webrtc_android庫
webrtc 是谷歌提供的音視訊通訊方案, 能夠很好的解決音視訊互聯互通的場景. 本文基於 Ubuntu 18.04 編譯 android 版本的過程, 其它平臺也可以參考, 基本都大同小異.
編譯環境要求
- 磁碟預留空間不小於 30GB.
- 編譯過程需要確保你能正常訪問 google 相關服務, 如有條件可以在命令列使用代理訪問.
```shell
export http_proxy=http://ip:port export https_proxy=http://ip:port export all_proxy=http://ip:port
```
- 由於專案太大, 建議使用固態硬碟的電腦, 加快同步時間, 減少超時等出錯機率.
- 以下過程是基於 Ubuntu 18.04 編譯.
- Python3 >= 3.7 版本
編譯webrtc android
安裝 depot_tools 工具
depot_tools 工具包包含了谷歌 gclient, gcl, git-cl, repo 等工具, 用於管理專案原始碼, 分發及編譯等. 安裝方式如下:
```shell
使用 git clone 到本地
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
``` 在環境變數PATH 中加入路徑, 以便方便使用命令. 根據自己使用的 shell 加到不同的啟動檔案中. ( .bashrc 或 .zshrc)
```shell
指定自己 depot_tools 的具體路徑
export PATH=/path/to/depot_tools:$PATH
```
同步程式碼
同步程式碼我們主要使用的是 gclient 工具, 這是一個 python 指令碼檔案, 可以對於多模組依賴的專案原始碼進行管理, 可以根據不同系統同步所有所依賴模組的程式碼版本.
- 建立工作目錄
mkdir webrtc-checkout
- 使用 fetch 下載 webrtc android 程式碼. (如果 fetch 執行出錯的話, 也可以繼續使用 gclient --with_branch_heads 同步下來 webrtc 原始碼).
```shell cd webrtc-checkout fetch --nohooks webrtc_android
``` - 使用 gclient 同步依賴專案原始碼及工具, 同步時間較長, 幾個小時肯定要的.
```shell gclient sync
```
NOTE:
- 如果 fetch 沒有出錯的話, webrtc 原始碼通過 git branch -av
是可以看到所有的 branch-heads 的分支.
- 如果 fetch 出錯後, 是通過 gclient 不帶引數同步下來的 webrtc 原始碼. 就只能看到 master、infra/config 以及 lkgr 幾個分支.
我們可以修改倉庫的 .git/config 檔案,在 [remote "origin"] 節中新增以下內容:
fetch = +refs/branch-heads/*:refs/remotes/origin/*
安裝編譯環境依賴庫
``` cd webrtc-checkout/src ./build/install-build-deps-android.sh
```
選擇原始碼版本
可以通過官方網站檢視到所有的 webrtc 版本, 儘量優先選擇穩定版本分支 checkout. https://chromiumdash.appspot.com/branches
我這裡是使用 M108
分支進行編譯.
使用 gn 編譯
- 使用 gn 設定編譯目錄及引數. gn 可以指定編譯目錄及引數, 因此相對於其它編譯工具, 可以同時並行多個編譯版本.
```shell cd src gn gen out/my_build --args='target_cpu="arm" target_os="android" android32_ndk_api_level=18'
```
target_os 引數可使用的值可以通過以下命令檢視:
```shell gn help target_os
# output Possible values
- "android"
- "chromeos"
- "ios"
- "linux"
- "nacl"
- "mac"
- "win"
```
target_cpu 引數可使用的值可以通過以下命令檢視:
```shell gn help target_cpu
# output Possible values
- "x86"
- "x64"
- "arm"
- "arm64"
- "mipsel"
- "mips64el"
- "s390x"
- "ppc64"
- "riscv32"
- "riscv64"
- "e2k"
- "loong64"
```
- 使用 gn 執行編譯.
ninja -C out/my_build
. ( 這個是增量編譯, 第一次時間較長)
編譯時間較長, 有 1w 多個目錄需要編譯, 估計得 1~2 小時吧.
- 清除編譯生成但留下編譯配置.
gn clean out/my_build
FAQ
- 編譯依賴元件 ffmpeg 出現如下錯誤:
../../third_party/ffmpeg/libavutil/arm/cpu.c:58:25: error: call to undeclared function 'getauxval'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] unsigned long ret = getauxval(AT_HWCAP); ^ ../../third_party/ffmpeg/libavutil/arm/cpu.c:58:25: note: did you mean 'get_auxval'? ../../third_party/ffmpeg/libavutil/arm/cpu.c:55:12: note: 'get_auxval' declared here static int get_auxval(uint32_t *hwcap) ^ 1 error generated. [3264/9167] ASM obj/third_party/ffmpeg/ffmpeg_internal/fft_vfp.o ninja: build stopped: subcommand failed.
Answer:
查看了 third_party/ffmpeg/libavutil/arm/cpu.c
原始碼, getauxval
函式是在以下這個標頭檔案中定義.
c
#if HAVE_GETAUXVAL
#include <sys/auxv.h>
#endif
auxv.h 是定義在 android 交叉編譯 third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/sys/auxv.h
中, 宣告函式時會限制 API 版本為 18 及以上.
```c
#if ANDROID_API >= 18 unsigned long int getauxval(unsigned long int __type) __INTRODUCED_IN(18); #endif / ANDROID_API >= 18 /
``
而我在編譯時指定的引數是
--args='target_cpu="arm" target_os="android" ...' 是 32 位版本, 在
src/.gn` 檔案中能看到對於 32 位版本的 API 預設 16:
```shell # The SDK API level, in contrast, is set by build/android/AndroidManifest.xml. android32_ndk_api_level = 16 android64_ndk_api_level = 21
``
所以如果編譯 32 位版本, 解決這個問題的方式就是在編譯時指定下
android32_ndk_api_level` 的版本為 18 即可. 如:
```shell gn gen out/my_build --args='target_cpu="arm" target_os="android" android32_ndk_api_level=18'
``
對於編譯所有的引數, 可以使用
gn args --list out/my_build` 具體檢視.
- 編譯出現
ModuleNotFoundError: No module named 'dataclasses'
錯誤.
Answer:
通過相關資料瞭解 dataclasses 模組至少需要 python3.7 才支援的, 需要升級 python3 版本. 我看了下自己 ubuntu 18.04 還是 3.6 的版本, 通過 apt-get install 安裝 3.8 版本.
為了切換方便, 可以通過 update-alternatives 進行管理, 相關的執行命令如下:
```shell # 安裝 3.8 版本 sudo apt-get install python3.8
# 為 python3 安裝可切換的管理版本 sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 1 sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.8 2
# 切換python3 使用的版本, 根據提示選擇使用的版本編號 sudo update-alternatives --config python3
```