http://blog.bihe0832.com/macOS-AOSP.html
背景
背景簡介
最近因為項目需要,要研究Android系統中應用安裝的詳細過程。在這種場景下,最好的辦法就是Read the Fucking Source Code。之前都是在線看,這次因為看的內容比較多,而且看的比較細,因此打算在本地checkout一份。這篇文章就主要記錄本人使用macOS(Sierra 10.12.1)在本地checkout出AOSP(7.1.1)並編譯導入Android Studio的完整過程
。
參考內容
關於如果checkout源碼,其實網上已經有很詳細的內容,個人在checkout的過程中主要參考了以下內容,也可直接按照他們的建議嘗試:
-
Google官方關於checkout的指引:
-
清華大學Android鏡像關於checkout的指引:
-
中國科學技術大學AOSP(Android) 鏡像使用幫助:
-
Android源碼的下載、編譯與導入到Android Studio:
checkout時推薦使用清華大學的鏡像,checkout過程中有交替切換測試,發現清華大學的鏡像會比VPN的效果相對好一點(也可能是個人的VPN不夠快)。
系統環境
在完成下面的准備工作相關的內容以后,本機的系統環境如下:
- macOS Sierra 10.12.1
- JDK 1.8.0_77
- Xcode 8.2.1
- 本地源碼地址:/Volumes/Document/android (對應分區存儲空間450G)
- shell:bash
准備工作
創建分區
由於macOS默認的文件系統是大小寫不敏感的,如果不做處理,編譯過程會引起下面的異常
Checking build tools versions... build/core/main.mk:159: ************************************************************ build/core/main.mk:160: You are building on a case-insensitive filesystem. build/core/main.mk:161: Please move your source tree to a case-sensitive filesystem. build/core/main.mk:162: ************************************************************ build/core/main.mk:163: *** Case-insensitive filesystems not supported. make: *** [out/build-aosp_arm.ninja] Error 1
為了避免該異常,我們要首先在macOS里面創建一個支持大小寫敏感的文件系統。具體的方法可以參考下面兩篇文章:
- Android官網的Setting up a Mac OS build environment:https://source.android.com/source/initializing.html#setting-up-a-mac-os-x-build-environment
- 個人博客的macOS中設置大小寫敏感的分區並切換:http://blog.bihe0832.com/mac-disk-utility.html
本人選擇checkout的源碼是android-7.1.1_r6,下載完占用空間22.12 GB,編譯完占用空間 67.4G,因此建議分區的時候,Android源碼至少使用 80G
創建目錄
在新的分區磁盤創建你放保存源碼的目錄,例如我直接放在新建分區(Document)根目錄的android文件夾。
$ mkdir /Volumes/Document/android
然后進入對應目錄繼續開始接下來的工作
$ cd /Volumes/Document/android
切換shell
由於Android的相關編譯只能是使用bash,因此如果是使用zsh等其余的shell,請先切換shell到bash。切換方法
-
用如下命令切換shell:
$ chsh -s /bin/bash
-
重啟終端。只有重啟終端shell切換才會生效。可以使用下面的命令檢查當前的shell:
$ echo $0 -bash
安裝軟件
下面的軟件是在編譯源碼過程中需要使用到的軟件,建議提前下載好。最好是按照下面的順序來下載,部分軟件間有一定的依賴關系。
Xcode
- 使用場景:在編譯源碼是使用,我直接下載了最新版
- 下載地址:https://itunes.apple.com/us/app/xcode/id497799835?ls=1&mt=12
MacOSX-SDK
- 使用場景:在編譯源碼是使用,macOS10.12.SDK棄用了編譯源碼需要的syscall,因此需要單獨下載更早版本的macOS的SDK
- 下載地址:https://github.com/phracker/MacOSX-SDKs
- 暫時下載准備好即可,會在后文中具體介紹怎么使用。另外由於整個github項目也不大,可以直接全部下載下來,這樣比較方便。
JDK
- 使用場景:在編譯源碼是使用,我使用的版本是:jdk1.8.0_77
- 下載地址:http://www.oracle.com/technetwork/java/javase/downloads/java-archive-javase8-2177648.html#jdk-8u45-oth-JPR
MacPorts
- 使用場景:用來下載其余編譯源碼需要的軟件,我使用的版本是macOS Sierra v10.12對應的版本
- 下載地址:https://www.macports.org/install.php
其他軟件
- 使用場景:用來下載其余編譯源碼需要的軟件,可以使用MacPorts來安裝
-
安裝方法:在MacPorts安裝好以后運行下面的命令即可安裝gmake等編譯工具
$ POSIXLY_CORRECT=1 sudo port install gmake libsdl git gnupg
- 備注:
-
如果這里報錯
port: command not found
,說找不到port命令,就需要在命令行運行下面的命令:$ export PATH=/opt/local/bin:$PATH
-
如果在這里報錯
Port gmake not found
,那就在安裝之前需要先執行下面的命令。$ sudo port -d sync
然后就可以再執行上面的命令安裝相關的工具了
-
概覽
在上述內容都安裝完畢以后,本機的系統環境如下:
- macOS Sierra 10.12.1
- JDK 1.8.0_77
- Xcode 8.2.1
- shell:bash
下載
下載Repo
Repo is a tool that makes it easier to work with Git in the context of Android.簡單理解,Repo就是一個方便你checkout Android相關源碼的工具。官方、清華和中科大鏡像都提供了對應的Repo的下載。
備注:下載Repo之前,官方提示需要創建一個bin文件,並且將路徑寫入到path中,下面是官方給出的操作步驟:
$ mkdir ~/bin $ PATH=~/bin:$PATH
我沒有設置環境變量,直接跳轉到上一步創建的目錄下,然后在命令行中輸入下面的命令,下載Repo,並且修改屬性。建議直接你使用的鏡像提供的Repo。本人是直接下載了官方提供的鏡像。
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ./repo $ chmod a+x ~/bin/repo
下面是官方給出的三個版本的Repo的sha。
-
For version 1.21, the SHA-1 checksum for repo is b8bd1804f432ecf1bab730949c82b93b0fc5fede
-
For version 1.22, the SHA-1 checksum for repo is da0514e484f74648a890c0467d61ca415379f791
-
For version 1.23, the SHA-1 checksum for repo is ac9d646f6d699f6822a6bc787d3e7338ae7ab6ed
初始化Repo
繼續在根目錄,初始化Repo,主要是設置你使用的鏡像以及想要checkout的Android的版本。例如使用官方的鏡像,下載android-7.1.1_r6的源碼,運行下面的命令
$ repo init -u https://android.googlesource.com/platform/manifest -b android-7.1.1_r6
如果是使用清華的鏡像,運行
$ repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-7.1.1_r6
關於源碼和tag的對應關系,可以在官網查看,Source Code Tags and Builds:https://source.android.com/source/build-numbers.html#source-code-tags-and-builds
下載源碼
完成上面的初始化任務以后,就可以開始調用下面的命令來下載源碼,repo同步是支持斷點續傳。因此如果下載過程中終端以后,繼續執行下面的命令就可以接着下載,並不會從頭開始:
$ repo sync -j4
命令最后的j4的意思是同時發起四個並發請求,之所以選擇4是因為清華的鏡像的並發請求的限制的上限就是4個。
由於下載時間太長,中途可能會出現鏈接斷開的情況,尤其是很多人會選擇半夜下載,如果鏈接斷開了沒能繼續就白白浪費了一個晚上,湫水長天的博客里面提供了一個自己寫的簡單的shell腳本可以參考,本人略做了修改。
#!/bin/bash repo sync -j4 while [ $? = 1 ]; do echo "================sync failed, re-sync again =====" sleep 3 repo sync done
將上面的代碼保存成repo_sync.sh,放在下載源碼的根目錄,例如我的/Volumes/Document/android,然后在命令行運行
/bin/bash ./get_android.sh
源碼的下載時間會非常長,因此建議選擇晚上下載。由於macOS默認的節能設置,為了防止mac在長時間無操作以后休眠,因此建議修改macOS中關於節能相關的配置。修改路徑為:系統偏好設置-》節能。下圖為本人修改后的效果:
編譯
當源碼全部下載完成以后,就進入了源碼編譯環節。
編譯前准備
切換shell
在准備工作中已經提醒,為防止有人遺忘,再次提示一次。由於Android的相關編譯只能是使用bash,因此如果是使用zsh等其余的shell,請先切換shell到bash。切換方法:
-
用如下命令切換shell:
$ chsh -s /bin/bash
-
重啟終端。只有重啟終端shell切換才會生效。
設置文件描述符限制
在macOS中,默認限制的同時打開的文件數量很少,不能滿足編譯過程中的高並發需要,因此需要在shell中運行命令:
$ ulimit -S -n 1024
編譯源碼
環境設置
在源碼根目錄(/Volumes/Document/android)下調用下面的命令:
$ source build/envsetup.sh
選擇設備
在命令行輸入下面的命令選擇打算編譯的源碼類型
$ lunch You're building on Darwin Lunch menu... pick a combo: 1. aosp_arm-eng 2. aosp_arm64-eng 3. aosp_mips-eng 4. aosp_mips64-eng 5. aosp_x86-eng 6. aosp_x86_64-eng 7. full_fugu-userdebug 8. aosp_fugu-userdebug 9. mini_emulator_arm64-userdebug 10. m_e_arm-userdebug 11. m_e_mips-userdebug 12. m_e_mips64-eng 13. mini_emulator_x86-userdebug 14. mini_emulator_x86_64-userdebug 15. aosp_dragon-userdebug 16. aosp_dragon-eng 17. aosp_marlin-userdebug 18. aosp_sailfish-userdebug 19. aosp_flounder-userdebug 20. aosp_angler-userdebug 21. aosp_bullhead-userdebug 22. hikey-userdebug 23. aosp_shamu-userdebug Which would you like? [aosp_arm-eng]
根據后綴可以判斷出使用的場景如下:
類型 | 用途 |
---|---|
user | 權限少,用於刷機使用 |
userdebug | 和“user”類似,但可以root,並且可以調試 |
eng | 具有開發配置,並且有額外的調試工具 |
根據需要選擇對應的類型,比如我選擇 “1”
Which would you like? [aosp_arm-eng] 1 ============================================ PLATFORM_VERSION_CODENAME=REL PLATFORM_VERSION=7.1.1 TARGET_PRODUCT=aosp_arm TARGET_BUILD_VARIANT=eng TARGET_BUILD_TYPE=release TARGET_BUILD_APPS= TARGET_ARCH=arm TARGET_ARCH_VARIANT=armv7-a TARGET_CPU_VARIANT=generic TARGET_2ND_ARCH= TARGET_2ND_ARCH_VARIANT= TARGET_2ND_CPU_VARIANT= HOST_ARCH=x86_64 HOST_2ND_ARCH=x86 HOST_OS=darwin HOST_OS_EXTRA=Darwin-16.1.0-x86_64-i386-64bit HOST_CROSS_OS= HOST_CROSS_ARCH= HOST_CROSS_2ND_ARCH= HOST_BUILD_TYPE=release BUILD_ID=NMF26Q OUT_DIR=out ============================================
開始編譯
為了加快編譯的速度,我們最好並發來編譯,首先查看下本機CPU的內核數與線程數:
$ sysctl machdep.cpu machdep.cpu.tsc_ccc.denominator: 0 machdep.cpu.tsc_ccc.numerator: 0 machdep.cpu.thread_count: 8 machdep.cpu.core_count: 4
可以看到線程數為8,因此我們執行下面的命令開始源碼相關的編譯
$ make -j16
參數-jN中的數字N,即為根據電腦線程數量設置的並發值,一般為線程數的1~2倍。之后就會開啟漫長的一到兩個小時的編譯過程。編譯過程可能出錯,出錯以后繼續運行命令編輯即可。
編譯結束以后,會顯示下面的日志
#### make completed successfully (01:28:02 (hh:mm:ss)) ####
編譯異常解決
在啟動編譯的過程中,比較常見的遇到的問題主要有:
-
文件分區不支持大小寫
-
錯誤現象
Checking build tools versions... build/core/main.mk:159: ************************************************************ build/core/main.mk:160: You are building on a case-insensitive filesystem. build/core/main.mk:161: Please move your source tree to a case-sensitive filesystem. build/core/main.mk:162: ************************************************************ build/core/main.mk:163: *** Case-insensitive filesystems not supported. make: *** [out/build-aosp_arm.ninja] Error 1
-
解決方案
查看文章最開始准備工作中關於macOS分區配置的說明
-
-
could not find jdk tools.jar
-
錯誤現象
$ make -j16 build/core/config.mk:600: *** Error: could not find jdk tools.jar at /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/../lib/tools.jar, please check if your JDK was installed correctly. Stop.
-
解決方案
主要是因為環境變量沒有設置
ANDROID_JAVA_HOME
導致的,添加對應的環境變量即可,輸入下面的命令:export ANDROID_JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
-
-
‘syscall’ is deprecated:
-
錯誤現象:
編譯過程中直接報錯,看編譯報類似下文的錯誤:
system/core/libcutils/threads.c:38:10: error: 'syscall' is deprecated: first deprecated in OS X 10.12 - syscall(2) is unsupported; please switch to a supported interface. For SYS_kdebug_trace use kdebug_signpost(). [-Werror,-Wdeprecated-declarations] return syscall(SYS_thread_selfid);
-
解決方案
這是因為最新的macOS的調整引起的,個人下載的最新版的源碼也沒有解決這個問題,最終采用的方法是使用更早版本的macOS的SDK,下載地址參考前面准備工作中的說明。解壓(也會用時比較久)zip包以后將
MacOSX10.11.sdk
拷貝到/Applications/XCode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs
。為了避免下次升級的時候再被刪除,建議拷貝到自定義目錄,然后建立軟鏈接。例如我放在~/lib目錄下,再給它創建一個軟鏈接:$ sudo ln -s ~/lib/MacOSX10.11.sdk /Applications/XCode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk
-
參考博客:解決macOSX10.12.SDK下編譯Android Open Source Project出錯的問題:http://palanceli.com/2016/09/25/2016/0925AOSPOnMac/
-
-
Jack server installation not found:
-
錯誤現象:
FAILED: /bin/bash -c "(prebuilts/sdk/tools/jack-admin install-server prebuilts/sdk/tools/jack-launcher.jar prebuilts/sdk/tools/jack-server-4.8.ALPHA.jar 2>&1 || (exit 0) ) && (JACK_SERVER_VM_ARGUMENTS=\"-Dfile.encoding=UTF-8 -XX:+TieredCompilation\" prebuilts/sdk/tools/jack-admin start-server 2>&1 || exit 0 ) && (prebuilts/sdk/tools/jack-admin update server prebuilts/sdk/tools/jack-server-4.8.ALPHA.jar 4.8.ALPHA 2>&1 || exit 0 ) && (prebuilts/sdk/tools/jack-admin update jack prebuilts/sdk/tools/jacks/jack-2.28.RELEASE.jar 2.28.RELEASE || exit 47; prebuilts/sdk/tools/jack-admin update jack prebuilts/sdk/tools/jacks/jack-3.36.CANDIDATE.jar 3.36.CANDIDATE || exit 47; prebuilts/sdk/tools/jack-admin update jack prebuilts/sdk/tools/jacks/jack-4.7.BETA.jar 4.7.BETA || exit 47 )" Unsupported curl, please use a curl not based on SecureTransport Jack server installation not found Unsupported curl, please use a curl not based on SecureTransport Unsupported curl, please use a curl not based on SecureTransport …… make: *** [ninja_wrapper] Error 1
-
解決方案
這是因為Jack需要基於OpenSSL的CURL,系統默認的並不是,因此選擇用Homebrew重新安裝一個。在命令行敲命令:
$ brew install curl --with-openssl
安裝好以后執行下面的命令修改環境變量,覆蓋系統自帶版本:
$ export PATH=$(brew --prefix curl)/bin:$PATH
-
導入
至此源碼已經編譯OK,為了方便導入到Android Studio,我們還需要做一些准備工作。具體如下:
生成IDEA工程配置文件
首先是要編譯idegen模塊,在shell中執行如下命令:
$ mmm development/tools/idegen/
如果在編譯時得到了類似下面的錯誤信息
-bash: mmm: command not found
只需要在源碼目錄下執行下面的明明后重試即可
$ source build/envsetup.sh
在編譯結束以后會有下面的提示:
#### make completed successfully (46 seconds) ####
此時繼續運行下面的命令生成對應的android.ipr
、android.iml
IDEA工程配置文件
$ development/tools/idegen/idegen.sh Read excludes: 17ms Traversed tree: 218013ms
17s以后就完成了編譯,在源碼根目錄下生成android.ipr
和android.iml
。
導入源碼
啟動Android Studio,然后選擇打開一個已存在的Android Studio工程,選擇源碼根目錄的android.ipr
,經過漫長(我首次導入用了20分鍾)
的加載過程以后,Android 源碼就已經成功的加載到了Android Studio中。
OK,至此我們就完成了在macOS(Sierra 10.12.1)上checkout出AOSP(7.1.1)並編譯導入Android Studio的完整過程。
其他
- 整個過程會非常長,耗時耗力,而且上面所有步驟間有互相依賴,建議嚴格按照順序執行。
- 個人在第一次分區時忘記修改文件系統為大小寫敏感,重新分區時選擇把下載的內容拷貝出去,重新分區,拷貝回來的方法,結果在編譯時各種報錯,最后選擇刪除根目錄下除
repo、get_android.sh、.repo
以外的其余所有文件后重新運行repo init 和repo sync后重新checkout,再次編譯就沒有任何異常。因此一定記得要建立正確的文件分區並選擇正確的文件系統類型。 - 下載編譯的時間都會很久,建議選擇晚上進行。