音視頻開發(fā)之旅(57) -如何方便的查看AndroidNative源碼

目錄

  1. 背景
  2. Android源碼下載
  3. 源碼編譯及遇到的問(wèn)題
  4. 使用CLion 導(dǎo)入
  5. 資料
  6. 收獲

一、背景

對(duì)Framework層的了解學(xué)習(xí)是我們進(jìn)階的一個(gè)重要階段。通過(guò) AS 查看 Framework 代碼體驗(yàn)非常好,無(wú)論是索引還是界面都讓人很滿意,但是當(dāng)你跟蹤代碼,發(fā)現(xiàn)進(jìn)入 native 邏輯時(shí),就會(huì)發(fā)現(xiàn) Android Studio 對(duì) native 代碼的支持非常不好,不能索引不支持符號(hào)搜索不能跳轉(zhuǎn)等。

網(wǎng)頁(yè)上可以通過(guò)cs.android.com 或者 http://androidxref.com/ 比較方便的查看源碼。但是還是不夠,因?yàn)槲覀內(nèi)绻胂到y(tǒng)的追蹤分析流程,往往會(huì)需要跳來(lái)跳去,有時(shí)候還會(huì)加些注釋。這時(shí)候網(wǎng)頁(yè)端的就不太方便。如果能在本地端方便的實(shí)現(xiàn)上述功能,可定是一個(gè)比較高效率而有愉悅的事情。

Source Insight可以比較方便的進(jìn)行跳轉(zhuǎn),但是只是在window支持(雖然Mac上可以通過(guò)Parallels 方便的安裝window環(huán)境;Ubuntu上也可以win的方式使用Source Insight但是總是不太方便)。

那么有沒有其他的工具或者方式,比較方便的查看native代碼吶?

可以通過(guò)CLion導(dǎo)入,但是需要有對(duì)應(yīng)的cmakelist,這就需要對(duì)下載源碼,然后進(jìn)行編譯,然后再用CLion導(dǎo)入。下面我們來(lái)看下具體的實(shí)踐。

二、Android源碼下載

查看官方文檔
主要分為3步,

  1. 下載安裝repo 啟動(dòng)器
  2. 下載mainfest
  3. 開始sync下載: repo sync -c -j8
    其中第2步配置manifest時(shí)需要注意,如果直接使用epo init -u https://android.googlesource.com/platform/manifest -b master 因?yàn)榫W(wǎng)絡(luò)原因會(huì)比較難下載成功。 我們可以使用清華的鏡像來(lái)配置 `repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b master
    即將 https://android.googlesource.com/ 全部使用 https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/ 代替即可

清華大學(xué)-Android 鏡像使用幫助

還有一點(diǎn)需要注意,如果沒有特殊的要求,可以根據(jù)需要下載對(duì)應(yīng)的分支,比如上面第2步中配置的是 master分支,這樣只會(huì)同步master最新分支,保證代碼的最新和下載的量比較小比較快。

如果是linux系統(tǒng)就可以直接進(jìn)入編譯階段。但是如果是mac上如果只是按照上面的操作進(jìn)入編譯,就會(huì)遇到問(wèn)題。我們?cè)诰幾g階段來(lái)一起看下,怎么處理。

三、源碼編譯及遇到的問(wèn)題

3.1 配置和編譯命令

  1. 編譯前配置下生成cmakelist文件這樣后面才可以使用CLion導(dǎo)入
export SOONG_GEN_CMAKEFILES=1
export SOONG_GEN_CMAKEFILES_DEBUG=1
  1. 然后執(zhí)行envsetup.sh腳本 進(jìn)行配置
. envsetup.sh
  1. 再執(zhí)行 choosecombo ,這個(gè)命令用阿里選擇編譯目標(biāo),比如硬件平臺(tái)、開發(fā)者還是使用者等,一般默認(rèn)配置就好。

  2. 最后開始make。 make -j8

Android平臺(tái)提供了三個(gè)命令用于編譯,它們分別是make、mmm和mm
make 用于編譯整個(gè)系統(tǒng),時(shí)間比較長(zhǎng),
make xxx:用于編譯某個(gè)模塊,比如編譯framework。 make framework即可
mmm xxx:用于編譯指定目錄下的模塊,不會(huì)編譯它依賴的模塊
mm xxx: 該命令和mmm差不多,區(qū)別在于它會(huì)先cd到xxx目錄然后在編譯。

在具體的編譯中遇到了很多問(wèn)題,匯總?cè)缦隆?/p>

3.2 編譯中遇到的問(wèn)題

問(wèn)題1: Mac make時(shí)報(bào)如下錯(cuò)誤

% make -j16 frameworks

19:44:38 You are building on a case-insensitive filesystem.
19:44:38 Please move your source tree to a case-sensitive filesystem.
19:44:38 ************************************************************
19:44:38 Case-insensitive filesystems not supported
#### failed to build some targets (1 seconds) ####

這個(gè)問(wèn)題就是上面提到的,如果是linux系統(tǒng)可以直接編譯,但是如果是mac系統(tǒng)編譯就會(huì)遇到這個(gè)問(wèn)題。
問(wèn)題的原因是

在默認(rèn)安裝過(guò)程中,Mac OS 會(huì)在一個(gè)保留大小寫但不區(qū)分大小寫的文件系統(tǒng)中運(yùn)行。Git 并不支持此類文件系統(tǒng),而且此類文件系統(tǒng)會(huì)導(dǎo)致某些 Git 命令(例如 git status)的行為出現(xiàn)異常
參考: https://source.android.com/source/initializing#setting-up-a-mac-os-x-build-environmentMove Android source into case-sensitive image

那么該如何解決吶?

上面鏈接給出的建議始終在區(qū)分大小寫的文件系統(tǒng)中對(duì) AOSP 源文件進(jìn)行操作
有了適當(dāng)?shù)奈募到y(tǒng),在新型 Mac OS 環(huán)境中編譯 master 分支就會(huì)變得非常簡(jiǎn)單

但是我代碼已經(jīng)下載好了。。。。,

所以只能在創(chuàng)建下區(qū)分大小寫的文件系統(tǒng),然后把代碼copy過(guò)去。

Mac上建立區(qū)分大小的文件系統(tǒng)

hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size 40g ~/android.dmg

然后進(jìn)行掛載

hdiutil attach ~/android.dmg.sparseimage -mountpoint /Volumes/android;

對(duì)應(yīng)的detach命令如下:

hdiutil detach /Volumes/android;

如果以后需要更大的存儲(chǔ)卷,還可以使用以下命令來(lái)調(diào)整稀疏映像的大小:

hdiutil resize -size <new-size-you-want>g ~/android.dmg.sparseimage

需要注意的時(shí),:如果系統(tǒng)創(chuàng)建的是 .dmg.sparseimage 文件,請(qǐng)將 ~/android.dmg 替換成 ~/android.dmg.sparseimage。

解決方案來(lái)源:Building Android O with a Mac

問(wèn)題2 : copy過(guò)去之后不再報(bào)上面的錯(cuò)誤了,但是出現(xiàn)如下錯(cuò)誤

error: external/kotlinx.atomicfu/Android.bp:13:1: module "external_kotlinx.atomicfu_license": glob: stat /Volumes/android/androidsource/external/kotlinx.atomicfu/NOTICE: no such file or directory
error: external/kotlinx.coroutines/Android.bp:24:1: module "external_kotlinx.coroutines_license": module source path "external/kotlinx.coroutines/LICENSE" does not exist
20:50:19 soong bootstrap failed with: exit status 1
ninja: build stopped: subcommand failed.

#### failed to build some targets (16 seconds) ####

在網(wǎng)上搜了下也有人遇到同樣的問(wèn)題但是沒有解決方案。。。

我的處理方案是 修改bp腳本,把上面的NOTICE和LICENSE依賴給去掉,然后就編譯過(guò)去了。

問(wèn)題3: 提示文件描述超過(guò)了上限(具體錯(cuò)誤信息忘記保存了)

# set the number of open files to be 1024
ulimit -S -n 1024
設(shè)置文件描述符數(shù)量上限
在 Mac OS 中,可同時(shí)打開的文件描述符的默認(rèn)數(shù)量上限太低,在高度并行的編譯流程中,可能會(huì)超出此上限。

要提高此上限,請(qǐng)將下列行添加到 ~/.bash_profile 中:

調(diào)大了文件描述符數(shù)量,同時(shí) 把并行的線程從16減4(這個(gè)是關(guān)鍵),不報(bào)上面的錯(cuò)誤了,但是又有如下錯(cuò)誤

問(wèn)題4: ninja: build stopped: subcommand failed

error: bionic/libc/Android.bp:1860:1: module "libc_llndk_headers" variant "android_recovery_arm_armv7-a-neon": glob failed: &fs.PathError{Op:"fcntl", Path:"/Volumes/android/androidsource/bionic/libc/kernel/uapi/asm-arm", Err:0x18}
21:17:37 soong bootstrap failed with: exit status 1
ninja: build stopped: subcommand failed.

---》重新運(yùn)行了了 make -j4 framework, 上嗎的編譯又通過(guò)了,不知道為什么。
本來(lái)還想在降低并發(fā)的線程數(shù)量到2. make -j2

經(jīng)過(guò)15分鐘左右終于編譯完成。哈哈哈

#### build completed successfully (14:16 (mm:ss)) ####

此時(shí)可以在/Volumes/android/androidsource/out/development/ide/clion/frameworks 路徑下看到各個(gè)子文件夾下都有CMakeLists.txt生成,但是卻是分散在各個(gè)子文件夾下面的。
編譯出來(lái)的是各個(gè)模塊單獨(dú)的CMakeLists.txt,一個(gè)CMakeLists.txt表示一個(gè)CLion工程,所以不能直接導(dǎo)入全部的工程。
那該怎么辦吶?
可以新建一個(gè)總的/Volumes/android/androidsource/out/development/ide/clion/frameworks/CMakeLists.txt然后可以先add一個(gè)工程,導(dǎo)入到CLion后再add其他工程

當(dāng)導(dǎo)入時(shí),有些cmakelist找不到。懷疑時(shí)沒有全編譯引起的?于是索性 make -j4來(lái)個(gè)全編譯,
下面是全編譯遇到的問(wèn)題

問(wèn)題5: fatal error: 'linux/netfilter/xt_DSCP.h'

external/iptables/include/linux/netfilter_ipv4/ipt_ECN.h:13:10: fatal error: 'linux/netfilter/xt_DSCP.h' file not found
#include <linux/netfilter/xt_DSCP.h>
1 error generated.
09:04:41 ninja failed with: exit status 1
#### failed to build some targets (01:34:26 (hh:mm:ss)) ####

Building Android O with a Mac這里找了個(gè)解決方案

---> In this case create a symbolic name xt_dscp.h for the original file xt_DSCP.h with the following command lines:

cd external/iptables/extensions/../include/linux/netfilter
ln -s xt_dscp.h xt_DSCP.h

按照上面的修改,但是沒什么用還是報(bào)相應(yīng)的錯(cuò)誤
于是手動(dòng)的找到對(duì)應(yīng)的文件,external/iptables/include/linux/netfilter/xt_dscp.h -->對(duì)其進(jìn)行重命名為xt_DSCP.h,解決掉這個(gè)問(wèn)題。

問(wèn)題6: 漫長(zhǎng)的編譯過(guò)程 出現(xiàn)了main.go:171:9: undefined: syscall.Sysinfo

build/soong/cmd/multiproduct_kati/main.go:170:11: undefined: syscall.Sysinfo_t
build/soong/cmd/multiproduct_kati/main.go:171:9: undefined: syscall.Sysinfo
10:27:57 ninja failed with: exit status 1

網(wǎng)上搜了下也沒有找到相關(guān)的解決方案。于是找對(duì)對(duì)應(yīng)的文件,把修改相關(guān)的代碼(把對(duì)應(yīng)的代碼注釋掉),繼續(xù)編譯

經(jīng)過(guò)上述折騰終于編譯完了,哈哈哈。

[100% 19269/19269] Target vbmeta image: out/target/product

#### build completed successfully  ####

四、使用CLion 導(dǎo)入

具體步驟如下

  1. 打開CLion
  2. 選擇「New CMake Project from Sources」
  3. 指定包含 CMakeLists.txt 的目錄out/development/ide/clion
  4. 選擇「Open Existing Project」
    然后就可以很愉快的進(jìn)行Android Native源碼的跳轉(zhuǎn)查看。

其中在 androidsource/out/development/ide/clion/CMakeLists.txt如下(目前主要是看 av相關(guān)的代碼,所有只加了相關(guān)的子路徑)


五、資料

  1. 搭建編譯環(huán)境
  2. https://source.android.com/source/initializing#setting-up-a-mac-os-x-build-environment
  3. Move Android source into case-sensitive image
  4. 清華大學(xué) android source 鏡像站
  5. http://blog.hanschen.site/2019/10/11/aosp-native-ide/
  6. 自己動(dòng)手調(diào)試Android源碼
  7. Android Opensource Project build error FAILED: out/soong/build.ninja
  8. CLion調(diào)試Android 11 Native代碼
  9. AOSP Native代碼導(dǎo)入IDE(CLion)

六、收獲

  1. 源碼的下載、編譯以及通過(guò)CLion導(dǎo)入方便的查看Native源碼
  2. 解決編譯中遇到的各種問(wèn)題

感謝你的閱讀
下一篇我們分析學(xué)習(xí)H264的編碼技術(shù)之幀內(nèi)預(yù)測(cè),歡迎關(guān)注公眾號(hào)“音視頻開發(fā)之旅”,一起學(xué)習(xí)成長(zhǎng)。
歡迎交流

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容