手把手 AOSP 編譯入門,使用 Windows 環境操作。
(可選) 移動 Ubuntu 至其他硬碟
Linux 子系統預設安裝在主硬碟裡,編譯 AOSP 需要至少 200G 的空間,可能會發生主硬碟空間不足的問題,如果不會可跳過此步驟。
1.安裝 choco
使用 PowerShell 輸入以下指令
| 1 | Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString(‘https://chocolatey.org/install.ps1') | 
2.安裝 LxRunOffline
使用 PowerShell 輸入以下指令
| 1 | choco install lxrunoffline | 
3.在另一個硬碟建資料夾並設置權限
在 D 槽建立 wsl 資料夾,接著使用 PowerShell 輸入以下指令,來查看你的使用者名稱,例如我的輸出為 usermark-pc\mike。
| 1 | whoami | 
使用以下指令來開啟 D:\wsl 資料夾權限
| 1 | icacls D:\wsl /grant "usermark-pc\mike:(OI)(CI)(F)" | 
4.使用 LxRunOffline 來移動 Linux 子系統
使用 PowerShell 輸入以下指令,來查看 Linux 子系統的名稱,例如我的輸出為 Ubuntu。
| 1 | wsl -l | 
使用以下指令移動
| 1 | lxrunoffline move -n Ubuntu -d D:\wsl\installed\Ubuntu | 
移動過程需要一些時間,完成後可用以下指令確認,輸出訊息會是 d:\wsl\installed\Ubuntu
| 1 | lxrunoffline get-dir -n Ubuntu | 
設置編譯環境
1.安装 JDK
使用 bash 輸入以下指令,參考https://source.android.com/setup/build/older-versions#for-ubuntu-15-04
| 1 | sudo apt-get update | 
2.安裝工具包
使用 bash 輸入以下指令,參考https://source.android.com/setup/build/initializing#installing-required-packages-ubuntu-1804
| 1 | sudo apt-get install git-core gnupg flex bison build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 libncurses5 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig | 
3.開啟大小寫敏感
使用 PowerShell 輸入以下指令
| 1 | fsutil.exe file setCaseSensitiveInfo D:\wsl enable | 
下載 AOSP
1.安裝 Repo
參考https://source.android.com/setup/develop#installing-repo
| 1 | mkdir ~/bin | 
2.初始化 Repo
參考https://source.android.com/setup/build/downloading#initializing-a-repo-client
| 1 | 建立資料夾,名稱自定,這裡命名為android | 
選定 AOSP 版本和分支,如下圖這裡選擇的是 android-7.1.0_r7,參考https://source.android.com/setup/start/build-numbers#source-code-tags-and-builds
Repo 要用 python3 運行,但系統預設為 python2,有解法是採用以下方案,將 python 指令指向 python3 指令
| 1 | sudo ln -s /usr/bin/python3 /usr/bin/python | 
repo sync 時可以,但編譯時還是需要用到 python2,就會出現該錯誤
| 1 | SyntaxError: Missing parentheses in call to 'print'. | 
因此透過 python3 去呼叫 repo 較合適,系統預設則不去動。
sync 同步到本地,過程需要一些時間。
| 1 | python3 ~/bin/repo init -u https://android.googlesource.com/platform/manifest -b android-7.1.0_r7 | 
3.(可選) 清空輸出資料夾
清空 out 目錄
| 1 | m clean | 
編譯 AOSP
1.初始化相關指令
每次重開指令視窗都要先呼叫,否則會找不到指令 m 和 emulator。
| 1 | source build/envsetup.sh | 
2.選擇編譯目標
參考https://source.android.com/setup/build/building#choose-a-target
| 1 | lunch aosp_arm-eng | 
3.讓 bash 支持 32 位元運行
安裝 qemu 並設置 binfmt
| 1 | sudo apt install qemu-user-static | 
啟動服務
| 1 | sudo service binfmt-support start | 
每次重開指令視窗都要先呼叫,否則會出現以下錯誤。
| 1 | prebuilts/misc/linux-x86/bison/bison: cannot execute binary file: Exec format error | 
4.開始編譯
使用 m -jN 指令來編譯,此處的 N 一般建議設置為 cpu 核心數的 1-2 倍,參考https://source.android.com/setup/build/building#build-the-code
| 1 | m -j8 | 
在編譯期間,將防毒軟體關閉,可以增進檔案系統的效能。
5.錯誤處理
報錯: ftruncate(fd_out, GetSize()): Invalid argument
| 1 | cd build/tools/ijar | 
修改 zip.cc,註解 935 行如下:
| 1 | int OutputZipFile::Finish() { | 
保存並編譯產生 ijar
| 1 | g++ -o ijar classfile.cc zip.cc ijar.cc -lz | 
強制替換 ijar
| 1 | cp -f ijar ../../../out/host/linux-x86/bin/ijar | 
報錯: dex2oat did not finish after 2850 seconds
修改 build/core 資料夾下的文件,$(DEX2OAT)後加上-j1 參數
dex_preopt_libart.mk
| 1 | $(hide) ANDROID_LOG_TAGS="*:e" $(DEX2OAT) -j1 \ | 
dex_preopt_libart_boot.mk
| 1 | $(hide) ANDROID_LOG_TAGS="*:e" $(DEX2OAT) -j1 --runtime-arg -Xms$(DEX2OAT_IMAGE_XMS) \ | 
報錯: SSL error when connecting to the Jack server. Try ‘jack-diagnose’
修改/etc/java-8-openjdk/security/java.security,找到 jdk.tls.disabledAlgorithms,取消 TLSv1, TLSv1.1
| 1 | jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, \ | 
重啟 jack 服務
| 1 | ./prebuilts/sdk/tools/jack-admin kill-server | 
報錯: GC overhead limit exceeded. Try increasing heap size with java option ‘-Xmx‘. 
運行 jack-server 編譯 AOSP 需要 3G 的記憶體配置,若電腦總記憶體小於 16G,會產生該錯誤,可使用以下指令查看可配置的記憶體大小。
| 1 | java -XshowSettings 2>&1 | grep Heap | 
例如在總記憶體 8G 的電腦輸出結果為 1.77G,參考https://2net.co.uk/blog/jack-server.html
| 1 | sudo vim ~/.bash_profile | 
重啟 jack 服務
| 1 | ./prebuilts/sdk/tools/jack-admin kill-server | 
運行模擬器
| 1 | emulator | 
因為 wsl 為指令模式,沒視窗可顯示,會出現下列錯誤。
| 1 | SDL init failure, reason is: No available video device | 
(可選) 重置 AOSP 異動
參考https://stackoverflow.com/questions/5012163/how-to-discard-changes-using-repo
| 1 | 重置異動 | 
參考資料