項(xiàng)目里面用到了 WebRTC 某些模塊,以前是源碼拷貝集成的。這樣不僅需要處理平臺的宏(WebRTC Native 跨平臺),而且升級版本也會涉及依賴等問題,所以探索了一下怎么用編碼編譯出可用的靜態(tài)庫。
網(wǎng)上相關(guān)的資料很少,且大部分都是 Android 平臺編譯單獨(dú)的 apm(Audio Processing Module)進(jìn)行使用,但我想找到更通用的方法。
WebRTC 編譯流程
要編譯單獨(dú)的模塊,首先要了解完整的 WebRTC 源碼是如何編譯的。根據(jù) 官網(wǎng)教程,WebRTC 項(xiàng)目出自于 Chromium,所以使用的工具和流程基本都一致。
- 安裝 Chromium depot tools,這是 Chromium 特有的工具集,包含 git 管理,編譯工具等
- 使用該工具下載源碼(Android 依賴 Linux 環(huán)境)
- 使用 GN 命令生成編譯配置
- 使用 ninja 進(jìn)行編譯
Ninja
Ninja 是一個(gè)小型輕量的 C++ 構(gòu)建系統(tǒng),使用 build.ninja (類似 Makefile)來進(jìn)行編譯。而一般需要用工具來生成這個(gè)描述文件,而不是手動(dòng)編寫。而官方采用的就是 GN(Generate Ninja)工具。
GN
GN 是專門用于創(chuàng)建 Ninja 描述文件的工具??梢詫?xiàng)目多個(gè)模塊分別編寫 BUILD.gn 文件,對模塊描述依賴,編譯文件,頭文件,可見性,命名空間等。算是一種 DSL,用于描述模塊,和 Cocoapods 里的 Podspec 文件作用差不多。
單獨(dú)編譯
雖然可以進(jìn)行整體編譯了,但是單獨(dú)編譯有沒有辦法呢?先查看 Ninja 官方文檔 發(fā)現(xiàn) ninja 命令是可以帶上編譯目標(biāo)的。編譯目標(biāo)的名字,是用 GN 生成的。查看 BUILD.gn 文件,發(fā)現(xiàn)基本都有 rtc_static_library。這個(gè)模版被定義在 webrtc.gni 文件里。
template("rtc_static_library") {
static_library(target_name) {
forward_variables_from(invoker,
"*",
[
"configs",
"public_configs",
"suppressed_configs",
"visibility",
])
forward_variables_from(invoker, [ "visibility" ])
// ...
}
}
看來這個(gè)就是要找的 target_name。比如需要單獨(dú)編譯 modules/audio_processing 模塊,查看 modules/audio_processing/BUILD.gn,發(fā)現(xiàn)里面定義了
rtc_static_library("audio_processing")
嘗試使用在 gn 執(zhí)行后使用
ninja -C out/Default audio_processing
可以看到,在 out/Default/obj/modules/audio_processing 目錄下生成了 libaudio_processing.a。
但這樣編譯出來的靜態(tài)庫大小不大,懷疑是沒有包含依賴的編譯產(chǎn)物的。使用命令 nm 查看
nm -u libaudio_processing.a
發(fā)現(xiàn)有未定義的符號,聯(lián)想 ninja 是個(gè)輕量構(gòu)建系統(tǒng),感覺很合理。只能再翻翻文檔,最后在 GN 文檔 中發(fā)現(xiàn),BUILD.gn 定義了 complete_static_lib 參數(shù),可以用來設(shè)置在編譯時(shí)是否鏈接依賴產(chǎn)物。在 BUILD.gn 中 rtc_static_library 中加上 omplete_static_lib = true,再次嘗試,發(fā)現(xiàn)正常了。
提取頭文件
WebRTC 的頭文件有文件層次結(jié)構(gòu),C++ 依賴頭文件的路徑,所以按照原始文件目錄層次提出頭文件就是必要的。Linux 系統(tǒng)可以是用 cp --parents 來進(jìn)行保留文件目錄的拷貝,但 Mac 上的 cp 命令并不支持 --parents 參數(shù),只有 ditto 命令代替。
最后
筆者寫了一個(gè) 腳本,包含編譯,提取頭文件,合并架構(gòu)來完成這整個(gè)流程。歡迎使用~