MacOS X 編譯Android原始碼
- 本篇文章已授權微信公眾號 guolin_blog (郭霖)獨家釋出
由於在工作中遇到了很多關於android內部實現的問題,雖然後面都解決了,有些是看了原始碼實現,有些原始碼看不了只能去google,百度。這就導致了對於很多的問題其實是知其然不知其所以然,所以從現在開始我下定決心開始學習Android的原始碼。那說到原始碼就必須提到編譯原始碼這件事情。 最開始是在我的MBP上面安裝了linux的雙系統準備在ubuntu上面來安裝編譯原始碼,不過這個方法有個弊端就是檢視原始碼的過程真是爽翻天啊,所以開始搗鼓再mac上面編譯原始碼
在google了一些方法之後發現比較混亂以至於難以完成,所以這次使用官方的方法來完成原始碼的編譯。
那麼現在開始了:
1. 系統要求
Mac OS (Intel/x86)
- Android 6.0 (Marshmallow) - AOSP master:Mac OS v10.10 (Yosemite) 或更高版本,具有 Xcode 4.5.2 和命令列工具
- Android 5.x (Lollipop):Mac OS v10.8 (Mountain Lion),具有 Xcode 4.5.2 和命令列工具
- Android 4.1.x-4.3.x (Jelly Bean) - Android 4.4.x (KitKat):Mac OS v10.6 (Snow Leopard) 或 Mac OS X v10.7 (Lion),以及 Xcode 4.2(Apple 的開發者工具)
- Android 1.5 (Cupcake) - Android 4.0.x (Ice Cream Sandwich):Mac OS v10.5 (Leopard) 或 Mac OS X v10.6 (Snow Leopard),以及 Mac OS X v10.5 SDK
2. JDK
這裡會需要註冊一個 甲骨文的賬號
- AOSP 中 Android 的 master 分支:Mac OS - jdk 8u45 或更高版本
- Android 5.x (Lollipop) - Android 6.0 (Marshmallow):Mac OS - jdk-7u71-macosx-x64.dmg
- Android 2.3.x (Gingerbread) - Android 4.4.x (KitKat):Mac OS - Java JDK 6
3. 主要程式包
- python
- gmake
- git
gmake 後面會下載的,你只需要安裝好python2.7 然而一般python是安裝好的
##4. 搭建編譯環境
4.1. 建立區分大小寫的磁碟映像
您可以使用磁碟映像在現有的 Mac OS 環境中建立區分大小寫的檔案系統。要建立磁碟映像,請啟動磁碟工具,然後選擇“新建映像”。完成編譯至少需要 25GB 空間;更大的空間能夠更好地滿足未來的需求。使用稀疏映像有助於節省空間,而且以後可以隨著需求的增加進行擴充套件。請務必選擇“Case sensitive, Journaled”儲存卷格式。
我推薦使用這種方式來建立磁碟映像
您也可以通過 shell 使用以下命令建立磁碟映像:
# hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size 40g ~/android.dmg
這將建立一個 .dmg(也可能是 .dmg.sparseimage)檔案,該檔案在裝載後可用作具有 Android 開發所需格式的儲存卷。 如果您以後需要更大的儲存卷,還可以使用以下命令來調整稀疏映像的大小:# hdiutil resize -size <new-size-you-want>g ~/android.dmg.sparseimage
對於儲存在主目錄下的名為 android.dmg 的磁碟映像,您可以向 ~/.bash_profile 中新增輔助函式: 要在執行 mountAndroid 時裝載磁碟映像,請執行以下命令:# mount the android file image
function mountAndroid { hdiutil attach ~/android.dmg -mountpoint /Volumes/android; }
注意:如果系統建立的是 .dmg.sparseimage 檔案,請將 ~/android.dmg 替換成 ~/android.dmg.sparseimage。 要在執行 umountAndroid 時解除安裝磁碟映像,請執行以下命令:# unmount the android file image
function umountAndroid() { hdiutil detach /Volumes/android; }
裝載 android 儲存卷後,您將在其中開展所有工作。您可以像對待外接式儲存盤一樣將其彈出(解除安裝)。
4.2. 安裝Xcode
你只需要在AppStore 裡面安裝Xcode就可以了。 之後需要執行一下命令
$ xcode-select --install
或者你也可以選擇位元組執行命令,不過我不推薦,下個xcode有好處的哦
4.3. 安裝MacPorts
下載連結 根據自己的系統來選擇
- 編輯.bash_profile,如果沒有就新建(不用特意操作,vi可以自動生成的)
vi ~/.bash_profile
vi的小提示,按i切換到insert模式就是編輯模式,按esc退出編輯模式,按:wq 儲存退出 複製
export PATH=/opt/local/bin:$PATH
到檔案中。
輸入source ~/.bash_profile
使命令生效
4.4. 通過 MacPorts 獲取 Make、Git 和 GPG 程式包
POSIXLY_CORRECT=1 sudo port install gmake libsdl git gnupg
如果您使用 Mac OS X v10.4,還需要安裝 bison:
POSIXLY_CORRECT=1 sudo port install bison
在 Mac OS 中,可同時開啟的檔案描述符的預設數量上限太低,在高度並行的編譯流程中,可能會超出此上限。要提高此上限,請將下列行新增到 ~/.bash_profile 中:
ulimit -S -n 1024
4.5. 設定ccache
- 在原始碼的根目錄下執行以下命令
export USE_CCACHE=1
export CCACHE_DIR=/<path_of_your_choice>/.ccache
5. 下載原始碼
5.1. 安裝repo
- 確保主目錄下有一個 bin/ 目錄,並且該目錄包含在路徑中
mkdir ~/bin
PATH=~/bin:$PATH
- (要在~/.bash_profile中新增;輸入
source ~/.bash_profile
使命令生效)
- 下載 Repo 工具,並確保它可執行
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
5.2. 初始化repo客戶端
- 必須使用之前建立的區分大小寫的檔案系統,一般掛載的新的盤是在/Volumes/ 路徑下的 我分出來的區分大小寫的檔案系統名字是Android 所以我cd進去就ok了
- 建立一個目錄
mkdir XXX
(XXX 是你自己取得名字) cd XXX
如果遇到repo: command not found 問題 請在初始工作目錄輸入
echo 'export PATH=$PATH:$HOME/bin' >> ~/.bashrc
export PATH=$PATH:$HOME/bin
5.3. 配置git資訊
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
5.4. 初始化repo
repo init -u https://android.googlesource.com/platform/manifest
- P.S. 此時需要科學上網,如果不能科學上網沒有關係,我們可以通過其他的映象來完成這一步操作
5.5. 清華映象下載
清華映象 首先我們可以看到
2016-06-24 : 關閉 git:// 協議,僅支援 HTTPS
所以我們是無法使用repo來同步程式碼的,所以我們要這麼做:
- 下載mirrors.tuna.tsinghua.edu.cn/aosp-monthl…
- 然後~~等(這個包有31個G,我用迅雷慢慢下載中)
- 將下載完的包放在之前建立的工作目錄上
tar xf aosp-latest.tar
解壓的目錄cd aosp
repo sync
(需要將下載的tar檔案刪除掉,不然空間有可能不夠) 此後,每次只需執行 repo sync 即可保持同步。 我們強烈建議您保持每天同步,並儘量選擇凌晨等低峰時間
5.6.科大映象下載
科大映象沒有去掉git協議,所以我們可以順暢的完成下載按照頁面提示的操作即可
##6. 編譯準備工作
- 點選source.android.com/source/requ…進行檔案下載
對於執行帶標記的 AOSP 版本分支的受支援裝置,您可以從 Google 的 Nexus 驅動程式頁面下載相關的官方二進位制檔案。有了這些二進位制檔案,您將有權使用採用非開放原始碼的其他硬體功能。要編譯 AOSP 的 master 分支,請使用 Nexus 裝置的二進位制檔案預覽。在針對某種裝置編譯 master 分支時,請使用適用於最新編號版本的二進位制檔案或具有最新日期的二進位制檔案。
- 解壓縮下載的檔案將會得到一個sh的檔案通過終端
sh xxx.sh
執行
此處需要agree使用者協議,你只需要按住向下鍵,就可以劃到最後輸入 I ACCEPT 就可以了。
- sh執行完成之後會得到一個vendor資料夾,將其複製到原始碼的根目錄下
- 清理 為了確保新安裝的二進位制檔案在解壓後會被適當考慮在內,請使用以下命令刪除所有以前編譯操作的已有輸出:
make clobber
6.1. 設定環境
- 使用 envsetup.sh 指令碼初始化環境
source build/envsetup.sh
6.2. 選擇目標
- 使用 lunch 選擇要編譯的目標。
lunch
然後會出現對應的列表選擇其中某個數字即可
該命令表示針對模擬器進行完整編譯,並且所有除錯功能均處於啟用狀態。 如果您沒有提供任何引數就執行命令,lunch 將提示您從選單中選擇一個目標。 所有編譯目標都採用 BUILD-BUILDTYPE 形式,其中 BUILD 是表示特定功能組合的代號。 BUILDTYPE 是以下型別之一
編譯型別 | 使用情況 |
---|---|
user | 許可權受限;適用於生產環境 |
userdebug | 與“user”類似,但具有 root 許可權和可除錯性;是進行除錯時的首選編譯型別 |
eng | 具有額外除錯工具的開發配置 |
- 由於本人有一個nexus 5x 的手機 ,所以準備在nexus5x 的手機上執行自己編譯的程式碼,所以我選擇的編譯命令為
aosp_bullhead-userdebug
如果想要針對真機除錯,請參閱執行版本進行命令選擇。我在這裡不建議初次接觸原始碼編譯的人進行真機除錯,刷磚了就gg了。
6.3. 編譯程式碼
您可以使用 make 編譯任何程式碼。GNU Make 可以藉助 -jN 引數處理並行任務,通常使用的任務數 N 介於編譯時所用計算機上硬體執行緒數的 1-2 倍之間。例如,在一臺雙核 E5520 計算機(2 個 CPU,每個 CPU 4 個核心,每個核心 2 個執行緒)上,要實現最快的編譯速度,可以使用介於 make -j16 到 make -j32 之間的命令。
make -j17
- 請注意,本部分只是一個摘要,用於確保設定已完成。如需關於編譯 Android 的詳細說明,請參閱執行編譯系統。
編譯過程中遇到的問題
- xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance Answer:
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
- build/core/combo/mac_version.mk:26: none of the installed SDKs (wifi-serviceac_sdk_versions_installed) match supported versions (10.8 10.9 10.10 10.11), trying 10.8 原因boxen的版本太低了需要更新
https://github.com/boxen/our-boxen 根據此處進行更新
- no SDK 10.8 at /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk, trying legacy dir build/core/combo/mac_version.mk:40: ***************************************************** build/core/combo/mac_version.mk:41: * Can not find SDK 10.8 at /Developer/SDKs/MacOSX10.8.sdk build/core/combo/mac_version.mk:42: *****************************************************
通過檢視build/core/combo/mac_version.mk檔案我們可以看到我們需要下載一個MacOSX10.11.sdk放到這個目錄中。因為10.12這個版本的sdk中syscall這個方法被棄用了,所以我們需要換回11這個版本的sdkmac_sdk_versions_supported := 10.8 10.9 10.10 10.11
而我電腦是10.12版本的所以我加了個10.12在這句話之後 就可以了
- 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.
在~/.bash_profile 中新增
export ANDROID_JAVA_HOME=$JAVA_HOME
- 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]
我們需要下載一個MacOSX10.11.sdk解壓後放到這個目錄中Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/
- external/doclava/src/com/google/doclava/Converter.java:407: 錯誤: 找不到符號 m.isAbstract(), m.isSynchronized(), m.isNative(), m.isDefault(), true, ^ 符號: 方法 isDefault() 位置: 型別為AnnotationTypeElementDoc的變數 m
應該是jdk版本不對 你需要檢視你在安裝過程中哪裡使用了1.7版本的jdk 可以通過檢視
java -version
和javac -version
來檢視
- Communication error with Jack server (52). Try 'jack-diagnose'
export JACK_SERVER_VM_ARGUMENTS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4g"
./prebuilts/sdk/tools/jack-admin kill-server
./prebuilts/sdk/tools/jack-admin start-server
- Out of memory error (version 1.2-rc4 'Carnac' (298900 f95d7bdecfceb327f9d201a1348397ed8a843843 by android-jack-team@googl
修改檔案 prebuilts/sdk/tools/jack-admin 修改這個語句加上
-Xmx4096m
---->JACK_SERVER_COMMAND="java -XX:MaxJavaStackTraceDepth=-1 -Djava.io.tmpdir=$TMPDIR $JACK_SERVER_VM_ARGUMENTS -Xmx4096m -cp $LAUNCHER_JAR $LAUNCHER_NAME"
7.0 刷機
終於build完成了 真是歷經千幸萬苦啊。
首先第一步 在原始碼的更目錄下輸入
sudo adb reboot bootloader
(如果發現沒有成功請重新輸入6.1和6.2的步驟) 然後你就會到達這個介面
fastboot oem unlock
輸入這個命令 然後通過音量鍵選擇yes 通過待機鍵確認
再然後輸入
fastboot flashall -w
- 出現錯誤error: could not load android-info.txt: No such file or directory
export ANDROID_PRODUCT_OUT=/Volumes/android/android-7.1.1_r24/out/target/product/generic
(請替換你自己的目錄)
- 出現錯誤error: could not load boot.img
你會發現沒有boot.img 這個檔案 這時候你只需要
make bootimage
就會生成對應的檔案
另外本人的父母是養蜂的,家裡有很多優質的純天然的洋槐蜜和益母草的蜂蜜,如果有需要的話可以新增我的微信bokmark_honey。價格肯定會比在超市裡賣的蜂蜜要來的好而且便宜,良心保證絕對沒有新增任何新增劑,都是純天然的蜜。另外還有蜂王漿和花粉有售,不過可能不多了,需要的話可以找我問問。