手把手 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 | 重置異動 |
參考資料