Android10.0 系統解析(02)——搭建Android原始碼編譯除錯環境

Android研習社發表於2020-05-25

1、前言

Android的編譯環境作為深入學習Android的基礎,不可或缺,能夠完整下載Android原始碼並編譯成功,對深入學習Android是非常關鍵和重要的一步。Android環境搭建比較繁瑣和枯燥,大家需要有足夠的耐心,去一步一步的解決問題,否則就很容易會編譯失敗或者沒有辦法在Google手機上除錯通過。

2、構建編譯環境

根據AOSP官網中關於“構建編譯環境”中描述,我們可以瞭解到目前只能使用Linux或者macOS進行原始碼級的開發。

路徑:https://source.android.google.cn/setup/build/initializing

構建編譯環境

本部分介紹瞭如何設定本地工作環境來編譯 Android 原始碼檔案。您必須使用 Linux 或 macOS;目前不支援在 Windows 環境下編譯。

2.1、虛擬機器選擇

如果您有Linux或者Mac作業系統的開發裝置,那麼部分就可以直接跳過。
如果您常用的開發裝置是Windows作業系統的話,那麼可以考慮用虛擬機器去學習或者研究Android原始碼。

目前市面上有兩款虛擬機器軟體,大家自行選擇其中一款即可。

2.1.1、下載VirtualBox及其擴充套件包

在VirtualBox的下載頁中下載最新的安裝包和擴充套件包,下載完成後將得到以下兩個檔案:

  • VirtualBox-6.1.8-137981-Win.exe
  • Oracle_VM_VirtualBox_Extension_Pack-6.1.8.vbox-extpack

2.1.2、安裝VirtualBox

雙擊可執行檔案 “VirtualBox-6.1.8-137981-Win.exe”,
這個部分只需要您做出肯定的回答就可以完成虛擬機器的安裝。

2.1.3、新增擴充套件包

按照以下的步驟,完成擴充套件工具包的新增。

  • 啟動VirtualBox,然後點選扳手圖示按鈕“全域性設定(P)”
  • 在左邊的Tab頁找到“擴充套件”選項卡,然後在右側中部點選“+”圖片按鈕。
  • 在彈出的檔案選擇對話方塊裡,選擇前面獲取到的擴充套件包“Oracle_VM_VirtualBox_Extension_Pack-6.1.8.vbox-extpack”。
  • 在"虛擬電腦控制檯 - 問題"畫面中,點選“安裝”按鈕。
  • 在"Virtual Box 許可" 畫面中,將許可證照滑動到最後,點選“我同意(A)”按鈕。
  • 完成擴充套件包的安裝。

2.2、安裝Ubuntu

那我們應該下載什麼版本的Ubuntu作業系統呢,根據AOSP官網的提示,64位的Ubuntu LTS (14.04) 風險小一些。

路徑:https://source.android.google.cn/setup/build/initializing

設定 Linux 編譯環境 以下說明適用於所有分支(包括 master)

我們會定期在 Ubuntu LTS (14.04) 和 Debian 測試版本中對 Android
編譯系統進行內部測試。其他大多數分發版本都應該具有所需的編譯工具。

如果是 Gingerbread (2.3.x) 及更高版本(包括 master 分支),需要使用 64 位環境。如果是較低的版本,則可以在 32 位系統中編譯

筆者對Ubuntu LTS (14.04)、Ubuntu LTS (18.04)以及Ubuntu LTS (20.04)進行了關於系統包安裝和原始碼的編譯進行了確認,其中Ubuntu LTS (14.04)和Ubuntu LTS (18.04)沒有問題。但是Ubuntu LTS (20.04)會有一些問題,後面會對這方面做出說明。

Ubuntu LTS (18.04)和Ubuntu LTS (20.04)的系統介面比Ubuntu LTS (14.04)要漂亮酷炫。Ubuntu LTS (20.04)系統介面跟Windows操作比較相似,美中不足的地方是介面更新會有卡頓和延遲,期待後面版本的改善。

綜上,筆者建議大家使用Ubuntu LTS (18.04)作為原始碼的編譯系統,減少為解決不相容而浪費的時間,雖然筆者為了嚐鮮使用了Ubuntu 20.04 LTS。

2.2.1、下載最新的Ubuntu桌面版(Ubuntu 20.04 LTS)

接下來我們需要下載最新版本的Ubuntu桌面版,建議使用載入工具,直接網頁下載速度非常的慢。
路徑:https://ubuntu.com/download/desktop

下載完成以後,您將獲得以下可執行檔案:

  • ubuntu-20.04-desktop-amd64.iso

2.2.2、Ubuntu安裝過程

(1)建立虛擬機器
  • 啟動VirtualBox,在管理器的右側的皮膚上,點選“新建(N)”圖片按鈕。
  • 在“新建虛擬電腦”畫面上,填寫一下資訊:
    • 名稱:Ubuntu 20.04 LTS(填入名稱以後,型別和版本會自動填寫,預設即可)
    • 資料夾:選擇空間足夠的磁碟存放
    • 型別:Linux
    • 版本:Ubuntu(64-bit)
  • 記憶體大小:筆者的膝上型電腦記憶體為16G,分配一半(8192M)給虛擬機器.點選“下一步(N)”按鈕。
  • 虛擬硬碟:填寫極限使用時的虛擬硬碟大小(比如256G),選擇“現在建立虛擬硬碟(C)”單選按鈕,然後點選“建立”按鈕。
  • 虛擬硬碟檔案型別:選擇"VDI(VirtualBox磁碟映像)"單選按鈕,點選“下一步(N)”按鈕。
  • 磁碟分配型別:選擇“動態分配(D)”單選鈕,點選“下一步(N)”按鈕。
  • 檔案位置和大小:選擇虛擬硬碟的儲存位置並設定虛擬硬碟大小,然後單擊“建立”按鈕。

完成虛擬機器的建立,選中虛擬機器後,單擊“設定”按鈕,在彈出的虛擬機器設定對話方塊中可以檢視並修改虛擬機器的各個引數。

(2)安裝Ubuntu 系統軟體
  • 管理器的右側的皮膚上,點選“啟動(T)”按鈕。
  • 在彈出的“選擇啟動盤”對話方塊中,單擊右側資料夾小圖示。
  • 選擇虛擬光碟檔案“ubuntu-20.04-desktop-amd64.iso”,單擊“啟動”。
  • 進入安裝介面。 選擇“中文簡體”,選擇“安裝Ubuntu”。
    • 鍵盤佈局:一般來說來說,我們的鍵盤佈局為英文鍵盤,選擇“English(US) -English(US) ”,選擇“繼續”。
    • 更新和其他軟體:選擇“最小安裝”和“安裝Ubuntu時下載更新”(網路狀況不好可以不選),選擇“繼續”。
    • 安裝型別:選擇“清除整個磁碟並安裝Ubuntu”,單擊“現在安裝(I)”按鈕,彈出警告框,選擇“繼續”。
    • 您在什麼地方:時區選擇,用滑鼠單擊地圖中的“中國”,就會選擇“上海”,單擊“繼續”。
    • 您是誰?:新建賬戶資訊,比如使用者名稱,密碼等資訊,單擊“繼續”。
  • 等待安裝完成。
(3)安裝增強功能

螢幕解析度較低,需要安裝增強功能:

  • 點選選單“裝置”
  • 點選“安裝增強功能”,在彈出的對話方塊裡,點選“執行” 。
  • 輸入登入系統的密碼,點選授權,就開始自動安裝。
  • 在系統的左側右擊光碟,選擇“彈出”光碟。
  • 重啟Ubuntu系統
  • 檢視–> 全屏模式,驗證螢幕解析度。
  • 完成安裝增強功能。

2.3、安裝OpenJDK

從Android 5.0 開始,使用OpenJDK編譯原始碼。

Android 版本JDK備註
Android 2.3.x ~ Android 4.4.xJDK 6
Android 5.x ~ Android 6.xOPenJDK 7
Android 7.x ~ Android 10.0OPenJDK 8

根據提示,無需另行安裝OpenJDK,那麼跳過此步驟。

路徑:https://source.android.google.cn/setup/build/requirements

AOSP 中的 Android master 分支帶有預編譯版本的 OpenJDK;因此無需另行安裝。

舊版 Android 需要單獨安裝 JDK。在 Ubuntu 上,請使用 OpenJDK。

如果想安裝可以執行以下命令:

sudo add-apt-repository ppa:openjdk-r/ppa
sudo apt-get update
sudo apt-get install openjdk-8-jdk

2.4、更改映象源

(1)先執行以下命令:

# 檢視系統版本
lsb_release -c
# 備份sources.list並修改檔案訪問許可權
sudo cp -v /etc/apt/sources.list /etc/apt/sources.list.backup
sudo chmod 777 /etc/apt/sources.list

(2)更改映象源
國內有很多映象源,比如有清華源和阿里雲源等,選擇其中一個就可以了。
筆者選擇了阿里雲源。

sudo apt-get install vim
vim /etc/apt/sources.list

# 把下載源替換為國內的映象源
deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse

(3)修改完軟體源後,更新軟體列表和軟體

sudo apt update
sudo apt upgrade

# 更新有失敗項的話,執行下面語句以後重複上面兩句命令
# sudo apt-get update
# sudo apt update
# sudo apt upgrade

2.5、Ubuntu系統工具包更新升級

安裝所需的軟體包
路徑:https://source.android.google.cn/setup/build/initializing

sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev libgl1-mesa-dev libxml2-utils xsltproc unzip

因為網路異常或者其他異常,這次工具包一次不能下載或者更新。
可以重複執行幾次,直到控制檯提示均已經安裝或者更新完畢。

下面是筆者對Ubuntu 14.04 LTS、Ubuntu 18.04 LTS以及Ubuntu 20.04 LTS系統工具包更新的進行了確認,供大家參考。

  • Ubuntu 14.04 LTS、Ubuntu 18.04 LTS能夠順利安裝和更新。
  • Ubuntu 20.04 LTS有三個包被替換了,"lib32ncurses5-dev"會導致編譯不通過。
vim /etc/apt/sources.list
# 新增Ubuntu 14.04 LTS的資源列表
deb http://us.archive.ubuntu.com/ubuntu/ xenial main universe
deb-src http://us.archive.ubuntu.com/ubuntu/ xenial main universe
# 另一種工具包安裝工具
sudo apt install aptitude
No.系統工具包確認執行命令確認結果問題解決方案
1git-core-ysudo apt-get install -y git-coreNGselecting ‘git’ instead of ‘git-core’sudo aptitude install git-core
2gnupgsudo apt-get install gnupgOK-
3flex-ysudo apt-get install -y flexOK-
4bison-ysudo apt-get install -y bisonOK-
5gperfsudo apt-get install gperfOK-
6build-essential-ysudo apt-get install -y build-essentialOK-
7zipsudo apt-get install zipOK-
8curl-ysudo apt-get install -y curlOK-
9zlib1g-devsudo apt-get install zlib1g-devOK-
10gcc-multilib-ysudo apt-get install -y gcc-multilibOK-
11g+±multilib-ysudo apt-get install -y g+±multilibOK-
12libc6-dev-i386sudo apt-get install libc6-dev-i386OK-
13lib32ncurses5-dev-ysudo apt-get install -y lib32ncurses5-devNGselecting ‘lib32ncurses-dev’ instead of ‘lib32ncurses5-dev’sudo aptitude install lib32ncurses5-dev
14x11proto-core-dev-ysudo apt-get install -y x11proto-core-devOK-
15libx11-dev-ysudo apt-get install -y libx11-devOK-
16lib32z-dev-ysudo apt-get install -y lib32z-devNGselecting ‘lib32z1-dev’ instead of ‘lib32z-dev’sudo aptitude install lib32z1-dev
17libgl1-mesa-dev-ysudo apt-get install -y libgl1-mesa-devOK-
18libxml2-utilssudo apt-get install libxml2-utilsOK-
19xsltprocsudo apt-get install xsltprocOK-
20unzipsudo apt-get install unzipOK

3、Android 原始碼下載及編譯過程

3.1 、原始碼下載

3.1.1 、安裝python

由於repo指令碼是Android專案編寫的Python指令碼,用來統一管理Android專案的程式碼倉庫,
所以首先要確保安裝了Python 2.7。

$ python
---
Command 'python' not found, did you mean:

  command 'python3' from deb python3
  command 'python' from deb python-is-python3
---
$ sudo apt-get install python
$ python
---
Python 2.7.18rc1 (default, Apr  7 2020, 12:05:55) 
[GCC 9.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
---

3.1.2 、安裝 Repo

Repo 是一款工具,可讓您在 Android 環境中更輕鬆地使用 Git。

  • 確保您的主目錄中有一個 bin/ 目錄,並且它包含在您的路徑中:
    mkdir ~/bin
    vim ~/.bashrc
    # 在檔案的最後新增下面一行程式碼,儲存退出
    PATH=~/bin:$PATH
    # 生效修改
    source ~/.bashrc
  • 下載 Repo 啟動器,並確保它可執行:
    # curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
    curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo > ~/bin/repo
    export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo'
    chmod a+x ~/bin/repo

3.1.3、工作目錄設定

建立一個空目錄來存放您的工作檔案。
為其提供一個您喜歡的任意名稱:

    mkdir WORKING_DIRECTORY # mkdir -p aosp/Android10
    cd WORKING_DIRECTORY # cd aosp/Android10

3.1.4、配置git個人資訊

配置git賬戶資訊,用於提交程式碼到Gerrit上,進行程式碼審查。

    git config --global user.name "Your Name"
    git config --global user.email "you@example.com"

    // 檢視配置的git資訊
    cat ~/.gitconfig
    ---
    [user]
        name = Your Name
        email = you@example.com
    ---

3.1.5、獲取原始碼分支

執行 repo init 以獲取最新版本的 Repo 及其最新的問題修復。您必須為清單指定一個網址,該清單用於指定 Android 原始碼中包含的各個程式碼庫將位於工作目錄中的什麼位置。

    # repo init -u https://android.googlesource.com/platform/manifest
    repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest

路徑:https://source.android.google.cn/setup/start/build-numbers#source-code-tags-and-builds

Build標記版本支援的裝置安全補丁程式級別
QQ2A.200501.001.B3android-10.0.0_r36Android10Pixel 2、Pixel 2 XL2020-05-05
6440158android-9.0.0_r56Pie2018-08-05

要檢出 master 之外的其他分支,請使用 -b 指定此分支。

    # repo init -u https://android.googlesource.com/platform/manifest -b android-10.0.0_r36
    repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-10.0.0_r36

同步原始碼:

#repo sync -jx (x:x為執行緒數,一般是CPU核心的2倍為佳)

# 根據清華映象網站的提示降低伺服器負載的要求,推薦執行緒數為4比較合適,
# 另外推薦錯峰下載,比如晚上下載)
repo sync -j4 --no-tags

# 支援續傳
# repo sync

3.1.6、常見問題

(1)虛擬機器儲存不足

關閉當前虛擬機器,回到VirtualBox管理頁面。這種調整方案將會導致一直黑屏啟動不了。
這種設定只有在虛擬機器建立完成後,作業系統還沒有安裝的情況下調整的。
在設定動態儲存空間的時候設定一個足夠的虛擬空間是很有必要的,要千萬注意。

介質(M)
–> 屬性(P)
–> 虛擬機器檔案選擇 --> 屬性(P)
–> 拖動滑塊,調整大小

(2)使用每月更新的初始化包

筆者下載原始碼使用了兩天三夜,才能下載完程式碼。
根據清華映象網站(注:參考文獻1)的提示,初次可以使用初始化包,還是非常的貼心,建議大家使用。

wget -c https://mirrors.tuna.tsinghua.edu.cn/aosp-monthly/aosp-latest.tar # 下載初始化包
tar xf aosp-latest.tar
cd AOSP   # 解壓得到的 AOSP 工程目錄
# 這時 ls 的話什麼也看不到,因為只有一個隱藏的 .repo 目錄
repo sync # 正常同步一遍即可得到完整目錄
# 或 repo sync -l 僅checkout程式碼
(3)gnutls_handshake() 錯誤解決方案

1)根據stackoverflow的提示:
error: gnutls_handshake() failed” when connecting to https servers

2)將gnutls替換成openssl,重新打包安裝。

$ sudo apt-get update
$ sudo apt-get install build-essential fakeroot dpkg-dev
$ sudo apt-get build-dep git
$ mkdir ~/git-openssl
$ cd ~/git-openssl
$ apt-get source git
# Remember to replace 2.25.1 with the actual version of git in your system.
$ sudo dpkg-source -x git_2.25.1-1ubuntu3.dsc
$ cd git-2.25.1
#  replace all instances of libcurl4-gnutls-dev with libcurl4-openssl-dev.
$ gedit debian/control
$ sudo apt-get install libcurl4-openssl-dev
$ sudo dpkg-buildpackage -rfakeroot -b

# if it's failing on test, you can remove the line TEST =test from the file debian/rules
$ gedit debian/rules
$ sudo dpkg-buildpackage -rfakeroot -b

# find the log:dpkg-deb: building package 'git' in '../git_2.25.1-1ubuntu3_amd64.deb'.
sudo dpkg -i  ../git_2.25.1-1ubuntu3_amd64.deb

3)重啟控制檯,再次執行同步。

repo sync -j1

當出現以下日誌資訊以後,代表您的程式碼終於下載成功了。
筆者認為學習AOSP就是一種修行,請多準備一些您的耐心。

...
Fetching projects: 100% (746/746), done.
Checking out projects: 100% (746/746), done.
repo sync has finished successfully.

3.2 、編譯原始碼

原始碼下載完成以後,就可以開始編譯原始碼。

  • 整體編譯:初次編譯的時候,需要整體編譯。初次編譯時間較長,筆者是編譯了一下午。
  • 模組編譯:區域性修改的時候,只需要編譯當前模組就可以了。

3.2.1、整體編譯

make:不帶任何引數,用於編譯整個系統,編譯時間比較長,除非是進行初次編譯否則不建議此種做法。

$ cd ~/aosp/Android10
$ source build/envsetup.sh(或者 . build/envsetup.sh)
$ lunch
...
# 筆者的測試裝置是Google Pixel所以輸入aosp_sailfish-userdebug或者前面的數字
Which would you like? [aosp_arm-eng] (輸入編譯的產品名字或者輸入前面的數字) 
$ make update-api -jx
$ make -jx(x為CPU核心的2倍為佳)

3.2.2、模組編譯

模組編譯分三種:make、mmm、mm
匯入編譯環境:

    cd ~/aosp/Android10
    source build/envsetup.sh
  • make module name:只知道目標模組的名稱,則可以在程式碼根目錄下執行 “make 模組名 ”的方式編譯目標模組。
    make SystemUI
  • mmm module path:該命令編譯指定目錄下的目標模組,而不編譯它所依賴其他模組。
    mmm frameworks\base\packages\SystemUI
  • mm: 進入對應的應用模組程式碼所在目錄執行mm命令,mm和mmm編譯的速度都很快。
    cd frameworks\base\packages\SystemUI
    mm

以上三個命令都可以用-B選項來重新編譯所有目標檔案。

雖然從編譯速度上mmm,mm都差不多,因為mmm不涉及目錄的切換,
所以建議使用 “make 模組名” 的方式分模組編譯。

4、參考文獻

  1. 清華大學開源軟體映象站
  2. AOSP設定
  3. Android原始碼下載與編譯 - 2019
  4. Android 9、10 -原始碼下載編譯

相關文章