一、編譯源碼的背景環境
Android源碼編譯有什么困難
- AOSP 非常龐大,需要下載,但是他是Google家的,和大陸開發者之間隔著一個GFW
- 官方文檔 推薦使用Ubuntu 14.04進行編譯。我用的是MacOS,官網也給了Mac下的編譯方式,不過看起來還是挺麻煩的。而且我怕搞亂我的電腦。
針對上面的兩點,以前有這么兩種解決方式,以前有這么幾種解決方式
- 至于下載慢,可以使用國內鏡像清華鏡像 和 科大鏡像,好像現在google的開發者網站部分不用梯子就可以訪問了[當前時間2017-04]
- 有人使用虛擬機,然后安裝Ubuntu,然后編譯源碼。這方式也可以,但是Mac下三種虛擬機,免費的那個還不好用。而且編譯本身就比較消耗資源,再裝個虛擬機就更麻煩了
后來有人提出用Docker
而且這個人搞了一份Docker鏡像出來 kylemanna/docker-aosp,后來有人針對Docker以及天朝的網絡環境做了一部分修改,fork了一份國產的 tiann/docker-aosp。主要是修改了shell腳本中的下載源。但是這個東西在MAC OS上有bugissues 19所以我就沒用成功。
有一點題外話需要說一下,這個Docker安裝后會開機默認啟動,默認啟動倒是也沒問題,有問題的是他不可以和Android虛擬機同時運行,就是AndroidStudio自帶的那個虛擬機。
二、搭建Mac編譯環境
修改文件描述符限制
在~/.bash_profile
中添加以下內容
#set the number of open files to be 1024
ulimit -S -n 1024
開發環境要求
1、 Mac OS v10.10 (Yosemite) 或以上,安裝了 Xcode 4.5.2或以上,安裝了Command Line Tools。
2、安裝JDK 7。
3、安裝了python 2.7
4、GNU Make 3.81或3.82
5、Git
我本機環境
- Mac OS v10.12.4
- xcode v8.0
- git version 2.8.4 (Apple Git-73)
- GNU Make 3.81
- 為了編譯不同版本的Android源碼,同時安裝了JDK7 & JDK8,通過配置
.bash_profile
來切換 - Python 2.7.11
- 之前我電腦還安裝了homebrew
磁盤分區
為什么在Mac上編譯會很麻煩呢,因為Mac的文件系統默認不區分大小寫,但是Android源碼編譯系統的要求區分大小寫,這時候我們可以創建個區分大小寫的磁盤空間(磁盤映像)。方法如下:
- 打開
磁盤工具
(在Launchpad中直接搜索就行) - 如下圖操作(磁盤映像命名為AOSP,磁盤映像大小為100G,磁盤格式一定要選擇區分大小寫) 首先選中
Macintosh HD
然后Comand + N
(或者 菜單欄選擇 --> 文件-->新建映像-->空白映像)
磁盤映像
注意:這個磁盤映像的名字后面要用到,磁盤大小好像官網推薦70G,以防不夠還是大點吧,格式一定要選
區分大小寫
。對應磁盤的映像使用,有人為了節省Mac上的硬盤,也為了防止搞壞系統,用了外接硬盤的方式然后操作這個外接硬盤的分區。如果是使用移動硬盤可以直接把硬盤格式化成 Mac OS 擴展(區分大小寫,日志式)
下載Android源碼
下面是科大的源也可以用清華的參考文獻,我下載的是Android6.0的源碼,最終編譯的時候選擇的是x86_64
- 下載 repo 工具:
mkdir ~/bin
PATH=~/bin:$PATH
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
- 建立工作目錄:
cd /Volumes/AOSP/
mkdir WORKING_DIRECTORY
cd WORKING_DIRECTORY
- 初始化倉庫
repo init -u git://mirrors.ustc.edu.cn/aosp/platform/manifest
## 如果提示無法連接到 gerrit.googlesource.com,可以編輯 ~/bin/repo,把 REPO_URL 一行替換成下面的:
## REPO_URL = 'https://gerrit-googlesource.proxy.ustclug.org/git-repo'
如果需要某個特定的 Android 版本(Android 版本列表),可以通過下面的方式指定版本號,如果不指定則代碼下載當前最新的代碼。
repo init -u git://mirrors.ustc.edu.cn/aosp/platform/manifest -b android-6.0.1_r46
注:在mac上運行這行可能會報錯,GnuPG 這玩意不可用,解決方式看最后錯解決
- 同步源碼樹(以后只需執行這條命令來同步)如果中途出現網絡錯誤,可以停止后在執行下面的命令:
repo sync
注意:科大的鏡像服務器限制了并發數,“由于硬盤 I/O 資源有限,Git 服務器每 IP 限制 5 個并發連接。repo sync 命令默認使用 4 個并發連接,請勿使用 -j 參數增加并發連接數。”
然后就等著吧0_0
編譯源碼
如果想把編譯后的img刷入真機的話,需要下載驅動,下載對應版本的驅動文件,依次解壓,將其置于源碼根目錄中,再依次執行這些腳本,執行操作前,它會讓你閱讀相關協議,協議比較多有8項,最后輸入 I ACCEPT 即可。執行完成以后會在源碼的主目錄生成一個vendor目錄。注意執行shell的順序。
- 清空緩存
$ make clobber
注:如果運行這行命令出錯看文章最后錯誤處理
- 配置編譯環境
$ 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. hikey960-userdebug
24. aosp_shamu-userdebug
Which would you like? [aosp_arm-eng]
然后直接輸入上面選項的序號就好了這里,我選擇第一個,至于上面那些名字的含義是啥看下面解釋:
官網說根據上面名字的后綴可以判斷要編譯那種類型的:
- user: limited access; suited for production(有限的訪問權限,一般用于發布版)
- userdebug: 這個和user類似,但是可以獲取root權限,并且能夠調試
- eng: 具有開發配置,并且有額外的調試工具(注:工程師模式engineer)
lunch
命令也可以直接這么用 $ lunch aosp_arm-eng
- 開始編譯
make -j16
這里指定的開啟幾個并行task
來進行編譯,官網建議j后面的數字根據你電腦的線程數量的1~2倍來設置,比如電腦是雙核CPU,每個CPU為雙核心四線程,那么就有8個線程。所以我配置的數量為16。
然后就是漫長的等待ing...
啟動模擬器
$ source build/envsetup.sh
-
$ lunch
(選擇剛才你設置的目標版本,我編譯的是x86_64-eng的那個) -
$ emulator
模擬器啟動,這個命令有很多復雜用法,具體可參考官網。
燒錄鏡像到機器中
這個燒錄過程我沒有測試,官網是這么寫的。
- 進入fastboot模式
$ adb reboot bootloader
- 把img文件刷進去
$ fastboot flashall -w
這個-w
是為了wipes the /data partition
擦除/data
分區
如果編譯前沒有下載驅動,即使刷入,還是無法進入系統,此時,只需要重新下載驅動,再次執行編譯命令。
AndroidStudio中查看源碼
在android源碼中有這么一個目錄development/tools/idegen。
顧名思義,是生成ide的project文件,主要是生成intellij的project文件,可用于AndroidStudio。
- 在整個Android源碼全編成功之后,然后編譯idegen模塊,用以生成Android studio的工程配置文件,編譯成功之后就生成了idegen.jar(out/host/darwin-x86/framework/idegen.jar),運行如下命令:
$ mmm development/tools/idegen/
注:如果剛才編譯AOSP的那個命令行窗口關閉了,必須要在執行
source build/envsetup.sh
一次,用了初始化編譯環境。
- 在源碼根目錄生成對應的android.ipr、android.iml IEDA工程配置文件。以便于AndroidStudio可以打開項目
$ . development/tools/idegen/idegen.sh
- 打開Android studio,點擊File --> Open,選擇剛剛生成的android.ipr就好了。
三、錯誤處理
執行repo init
的錯誤
錯誤1描述
warning: gpg (GnuPG) is not available.
warning: Installing it is strongly encouraged.
解決方法:
原因是GnuPG for osx沒有安裝,去https://www.gnupg.org/download/下載安裝即可。
我用homebrew安裝的brew install gnupg
執行make clobber
的錯誤
錯誤1描述:
build/core/config.mk:660: error: Error: could not find jdk tools.jar at /System/Library/Frameworks/JavaVM.framework/Versions/A/Commands/../lib/tools.jar, please check if your JDK was installed correctly.
17:29:26 ckati failed with: exit status 1
解決方式:
在~/.bash_profile
添加如下代碼
export JAVA_8_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home
export JAVA_HOME=$JAVA_8_HOME
##上面是jdk的配置,主要是添加下面這一行
export ANDROID_JAVA_HOME=$JAVA_HOME
錯誤2描述
build/core/combo/mac_version.mk:38: *****************************************************
build/core/combo/mac_version.mk:39: * Can not find SDK 10.6 at /Developer/SDKs/MacOSX10.6.sdk
build/core/combo/mac_version.mk:40: *****************************************************
build/core/combo/mac_version.mk:41: *** Stop.. Stop.
解決方法:
出現這個錯誤是因為xcode的版本不對,首先查看本機安裝xcode的版本,
$ cd /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/
然后修改build/core/combo/mac_version.mk
這個文件中的下面這行,把本機的版本號添加到下面,我的是10.12 添加后如下:
mac_sdk_versions_supported := 10.6 10.7 10.8 10.9 10.12
錯誤3描述:
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);
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/unistd.h:733:6: note: 'syscall' has been explicitly marked deprecated here
int syscall(int, ...);
^
1 error generated.
解決方式:
這個錯誤3歸根到底是因為錯誤2引起的,再歸根下是xcode版本引起的,(為啥說在mac上編譯麻煩,這個xcode版本會出這么多破事),沒辦法這個我們上面用的mac sdk 10.12 版本太高了,這個版本廢棄了某些方法導致編譯不可用,那就去下個低版本的吧傳送門,壓縮包在這然后下載那個10.11。理論上來說,下載后把目錄放到這個路徑下/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/
和這個MacOSX10.12.sdk
目錄平級就行了,然后把錯誤2中添加到build/core/combo/mac_version.mk
中的那個10.12改成10.11就好了。但是這個東西貌似在下次xcode升級的時候會被刪掉。
a oh so? 弄個軟連接:
$ mkdir ~/lib
然后把下載的壓縮包解壓到~/lib
下
$ sudo ln -s ~/lib/MacOSX10.11.sdk /Applications/XCode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk