準備編譯環境
安裝套件
根據官方的說明文件,最適合編譯 Android 的開發環境為 Ubuntu 12.04 (x86_64)。以下文章我們假設大家的環境都是 Ubuntu 12.04。首先在開始之前,我們必須要安裝一些必要的套件:
$ sudo apt-get install git gnupg flex bison gperf build-essential \
zip curl libc6-dev libncurses5-dev:i386 x11proto-core-dev \
libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-glx:i386 \
libgl1-mesa-dev g++-multilib gcc-multilib mingw32 tofrodos \
python-markdown libxml2-utils xsltproc zlib1g-dev:i386
另外為了可以讓 Build System 找得到 Mesa3d 函式庫,我們必須為他建立一個 Soft Link:
$ sudo ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so
如果你在 apt-get install 時,遇到類似下面的錯誤(沒有遇到可以直接跳到 Java 的段落):
E: Unable to locate package mingw32
E: Package 'python-markdown' has no installation candidate
這是因為你的 APT 沒有開啟 Universe 來源(也就是第三方維護的自由軟體)。我們要先把他加進 Ubuntu 軟體來源,然後再更新套件資訊。
$ sudo vim /etc/apt/sources.list
# 找到 "deb http://archive.ubuntu.com/ubuntu precise main" 在後面加上 universe
$ sudo apt-get update
等到 apt-get update 執行完,再從頭開始執行應該就不會有問題了。
安裝 OpenJDK 7 JDK
如果要編譯最新的 Android,你會需要 Java 7。你可以用以下指令安裝 OpenJDK 7:
$ sudo apt-get install openjdk-7-jdk
之後如果我們要編譯 Android 之前,我們必須記得:
$ export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
$ export PATH=$JAVA_HOME/bin:$PATH
安裝 Java SE 6 JDK
如果你是要編譯較舊的 Android,你會需要 Java SE 6 JDK,如果你是要編譯最新的 Android,可以跳過這一節。我們必需到 Oracle 網站取得 Java SE Development Kit 6u45 (Java SE 6 JDK)。因為我們的環境是 Ubuntu,所以我們要下載的是 jdk-6u45-linux-x64.bin。下載之後,就依下述指令安裝:
$ chmod +x ./jdk-6u45-linux-x64.bin
$ ./jdk-6u45-linux-x64.bin
$ mv jdk1.6.0_45 /opt
之後如果我們要編譯 Android 之前,我們必須記得:
$ export JAVA_HOME=/opt/jdk1.6.0_45
$ export PATH=$JAVA_HOME/bin:$PATH
取得 repo 管理工具
因為 Android 是一個很大的專案,由數百個 Git 版本庫所構成。為了管理這些版本庫,Google 開發了 repo 這個 Git 管理工具。透過 repo 我們可以一次下載整個 Android 原始碼樹。我們必須先取得 repo:
$ mkdir ~/bin
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$ chmod +x ~/bin/repo
$ export PATH=~/bin:$PATH
取得原始碼與 Prebuilt Binaries
下載 Android 原始碼
和先前那篇一樣,我們現在可以下載 AOSP 的原始碼了!我們先建立一個資料夾,再使用 repo init 取得 Android Source Tree 的設定檔。最後使用 repo sync 把所有 Git 版本庫抓到本地端。
$ mkdir ~/android-src
$ cd ~/android-src
$ repo init -u https://android.googlesource.com/platform/manifest
$ repo sync -j2
下載 Prebuilt Binaries
如果要刷手機,我們還需要一些來自廠商的驅動程式或 Prebuilt Binaries。我們可以到 Binaries for Nexus Devices 找到 Nexus 系列所需的驅動程式。下載之後(以 broadcom-maguro-jdq39-8edbeae8.tgz 為例),我們先把壓縮檔放在 ~/android-src,然後:
$ cd ~/android-src
$ tar zxvf broadcom-maguro-jdq39-8edbeae8.tgz
$ ./extract-broadcom-maguro.sh
# 按下 Enter,再按下 q,輸入 "I ACCEPT" 之後按下 Enter 即可。
編譯 Android 原始碼
取得所有程式碼之後我們就可以開始編譯整個 Android。首先我們必需先設定好環境變數:
$ cd ~/android-src
$ export JAVA_HOME=/opt/jdk1.6.0_45
$ export PATH=$JAVA_HOME/bin:$PATH
$ source build/envsetup.sh
選取你想要編譯的目標。一般來說 full-eng 就可以滿足所需。如果你要刷手機,可能要從 Building for Devices 頁面找到合適的目標。
$ lunch full-eng
接下來我們就可以開始編譯了!
$ make -j16
(...中略...)
Install system fs image: out/target/product/generic/system.img
out/target/product/generic/system.img+ maxsize=588791808 blocksize=2112 total=576716800 reserve=5947392
經過漫長的等待,如果你可以在最後看到類似上面的訊息,那整個 Android 就成功完成編譯工作,我們可以打開模擬器或刷手機了。
開啟模擬器
開啟模擬器的方法非常容易,只要輸入以下指令:
$ ./out/host/linux-x86/bin/emulator
- 根據我的測試,有些目標例如 full_maguro-eng 沒辦法使用模擬器。如果要使用模擬器要改用 lunch full-eng。
- 如果你之後要使用模擬器,但是看到:
emulator: ERROR: You did not specify a virtual device name, and the system directory could not be found.
那是因為你忘記 lunch full-eng 了。我們必需 lunch full-eng 模擬器才能找到對應的 System Image。
刷手機
在刷手機之前,最好先上網尋找有沒有成功的案例。因為刷機一定會違反保固條款失去保固。其次,如果指令錯誤更有可能讓你的手機變成磚塊。一般來說,Google 推出的 Nexus 系列都沒有什麼大問題。但是因為不同的手機有不同的狀況,本文僅供參考,不為後果負責。
首先我們先看 adb 能不能抓到你的手機:
$ adb devices
- 如果看不到你的裝置,有可能是 udev 設定檔沒有設好。可以參考 Configuring USB Access,建立 /etc/udev/rules.d/51-android.rules。
- 如果你有看到裝置,但是在 offline 的狀態。這有可能是因為你沒有開啟手機的開發者選項。你可以拿起手機,進入「Setting/About Phone/Build Number」,連續點 7 下。之後在「Developer Options」頁面勾選「USB Debugging」。
接下來我們要開機進入刷機模式:
$ adb reboot bootloader
這時我們可以看到手機進入 Bootloader,我們可以用 fastboot devices 尋找手機:
$ fastboot devices
如果你還沒有 Unlock 手機,這時我們就可以 Unlock 他。注意:這一步會讓保固失效!
$ fastboot oem unlock
最後,我們來刷手機。刷手機的過程絕對不能拔手機線。
$ fastboot flashall
除了把新的映象檔刷進手機,我們還要清空所有 User Data 與 Cache。否則 Android 有一定的機會一直停留在開機畫面。
$ fastboot erase userdata
$ fastboot erase cache
最後我們就可以重新開機!
$ fastboot reboot
我們可以用 adb logcat 觀察開機過程。有時候會遇到一直開不了機的情況。這時可以先試著清空 User Data 與 Cache。如果還是有問題,有時候是 AOSP 有問題,可以先刷回官方的映象檔。
結語
本文簡單的介紹怎麼編譯 Android Open Source Project 與刷機的基本流程。 希望大家看完之後有能力自己 Hack Android。Happy hacking!