使用Vmware虛擬Ubuntu 16.04 LTS 成功編譯 Android 6.0 源碼

1、引言

經過3天半的奮戰,本人終於在VMware虛擬的Ubuntu 16.04 LTS 上成功編譯出了Android 6.0源碼。期間走了很多彎路,也爬過了很多坑,中間想過放棄,但最終還是咬牙堅持了下來,現總結出來,有需要的夥伴可以用來參考,以後少走彎路。
開始編譯前,我本機剛好有一個VMware虛擬的Ubuntu 16.04 LTS系統,因此決定在其上面來進行幹活。於是找到了Google官方網站源碼編譯指南—https://source.android.com/source/initializing
如下圖所示,

注意需要翻牆。

從圖中可以看到,裏面詳細介紹了源碼如何下載源碼,如何進行編譯等。
這裏寫的比較官方和正式,但是我從其他各種渠道瞭解到,光從這裏得到的信息進行編譯還是不夠的,因爲它沒有指出各版本源碼在編譯過程中的注意事項,就是所謂的坑。於是在將這些官方文檔逐個瀏覽了一遍後,開始到網上找一些踩過坑的實戰文章。經過篩選,還真找到一篇和自己編譯環境 相仿的文章–http://blog.csdn.net/fuchaosz/article/details/51487585,其中介紹了各種採坑過程,源碼下載地址,注意事項等,我能編譯成功,多半也是這篇文章幫的忙,所以在這裏對這篇文章的作者表示感謝。

2、編譯準備

(1)、編譯系統–VMware WorkStation Pro 12虛擬的Ubuntu 16.04 LTS

  • 源碼–Android 6.0 r1
  • JDK–Open JDK 7

(2)、搭建編譯系統

我本機是Win7,然後安裝了一個VMware WorkStation Pro 12,虛擬的Ubuntu 16.04 LTS的版本。具體怎樣安裝以及虛擬系統,這裏不做過多多敘述了,大家可以百度,有很多資料可以參考。
有的博客建議直接將Ubuntu 系統裝到電腦上,而不是虛擬機上,這樣編譯速度快一些。這個可以視個人情況而定,如果硬件足夠好,cpu內核多,內存也足夠大,在虛擬機上編譯也不是問題。本人電腦是公司的,裝的是win7,客觀情況不允許直接替換成ubuntu,所以只能虛擬一個。我的電腦的硬件配置是Inter i5,4核,8G內存,我算了一下如果編譯過程中排除查錯,重編的耗時,整個編譯過程應該在5個小時左右,我感覺還是可以接受的。

這裏有個主意事項是,虛擬Ubuntu 系統時,留給系統的磁盤一樣要足夠大,不要選擇默認的20G,這點空間連存放源碼的解壓縮後的文件都不夠,根本無法再編譯,本人開始就吃了這個虧,後來重新又虛擬的系統,建議留120G左右。

(3)、下載Android 6.0源碼

我們可以到官方網站去下載,但往往很難成功,而且需要翻牆,速度也比較慢,可以到下面地址去下載Android 6.0源碼.
Androdi 6.0源碼下載地址: http://pan.baidu.com/s/1o6N86a2
感謝下面這位博主上傳源碼,我也是從他的博客下載的源碼:
http://blog.csdn.net/ilittleone/article/details/6823441

注意:下載的源碼存放路徑不能有中文,否則編譯時會報錯,還有存放的路徑不建議太深,最好在盤符的根目錄。

(4)、解壓源碼,合併文件

下載完畢後,在系統的終端使用下面命令合併:

cat Android6_r1_*>Android6_r1.tgz

合併完後,使用下面命令可以校驗hash,判斷文件有沒有損壞:
md5sum Android6_r1.tgz
將顯示的字符串結果和下載的文件裏面的hash.txt中的內容作比較,如果相等,說明沒有損壞,反之,需要重新下載。一般都不會有問題。
壓縮包大概有6.6GB

(5)、解壓縮源碼

使用如下命令解碼,

tar -zxvf Android6_r1.tgz

解壓時間會很長,解壓完成後最後幾行顯示這樣的結果,

mydroid/prebuilts/qemu-kernel/arm/2.6/kernel-qemu
mydroid/prebuilts/qemu-kernel/arm/2.6/vmlinux-qemu
mydroid/prebuilts/qemu-kernel/arm/vmlinux-qemu

解壓的所有文件我看了一下屬性,大概有13個G多一些。

(6)、安裝依賴包。

這個主要參考了http://blog.csdn.net/fuchaosz/article/details/51487585的博客。
如下所示,

sudo apt-get install -y git flex bison gperf build-essential libncurses5-dev:i386 
sudo apt-get install libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-dev g++-multilib 
sudo apt-get install tofrodos python-markdown libxml2-utils xsltproc zlib1g-dev:i386 
sudo apt-get install dpkg-dev libsdl1.2-dev libesd0-dev
sudo apt-get install git-core gnupg flex bison gperf build-essential  
sudo apt-get install zip curl zlib1g-dev gcc-multilib g++-multilib 
sudo apt-get install libc6-dev-i386 
sudo apt-get install lib32ncurses5-dev x11proto-core-dev libx11-dev 
sudo apt-get install lib32z-dev ccache
sudo apt-get install libgl1-mesa-dev libxml2-utils xsltproc unzip m4

本人沒有更改軟件源,因爲發現這樣直接下載速度還是很快的,所以就沒有必要修改軟件源。Ubuntu 16.04請務必使用上面的依賴,Ubuntu 16.04需要的依賴和Ubuntu 14.04所需要的依賴是不同的,不然會踩到很多的坑,具體什麼樣的坑本人倒是沒有踩到,只是看到很多博客都這樣說。

(7)、安裝JDK

從Android 6.0開始Android源碼的編譯需要安裝OpenJDK,不能使用Oracle JDK,而且Android 6.0只能使用OpenJDK7,這個官網的文檔描述的有點模糊,如下圖所示,

官方建議使用openjdk-8-jdk,但是對於 Android 6.0使用OpenJDK7就可以了。
由於Ubuntu 16.04沒有OpenJDK7的源,因此在16.04上安裝OpenJDK7需要執行下面的命令:

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

然後打開/etc/profile文件,進行環境變量的配置:

sudo gedit /etc/profile

然後可以使用如下命令檢查Java版本是否正確安裝,

java -version

如果結果正確,如下所示,

(8)、修改已知的坑

修改 mydroid/art/build/Android.common_build.mk 文件,定位到75行,將下面的代碼:

ifneq ($(WITHOUT_HOST_CLANG),true)

改爲:

ifeq ($(WITHOUT_HOST_CLANG),false)

據說,如果不修改這裏,會遇到一個比較棘手的編譯錯誤,修改的目的是把CLANG這個編譯選項關掉,如果不修改遇到錯誤,百度搜狗都無解,這個錯誤只會在Ubuntu16.04上遇到,Ubuntu14.04則不存在這個問題。

3、編譯

編譯之前,需要做一些設置工作,如下所示,

(1)、在 .bashrc文件末尾添加:export USE_CCACHE = 1

在終端運行如下命令,

echo export USE_CCACHE=1 >> ~/.bashrc

(2)、 爲了提高編譯效率,設置編譯器高速緩存爲50G

在終端輸入如下命令,

prebuilts/misc/linux-x86/ccache/ccache -M 50G

(3)、然後導入編譯Android源碼所需的環境變量和其它參數

source build/envsetup.sh

(4)、運行lunch命令選擇編譯目標

lunch

選擇1:

(5)、開始編譯

執行

make -j8

8爲同時編譯的線程數,google推薦這個數字爲2倍的cpu個數再加上2,比如4核,就是10。
這裏需要注意,這裏的cpu個數要根據虛擬機中設置的cpu個數相符,我設置成了4核,所以可以使用-j8或者-j10,如果只有兩個cpu使用,可以使用-j4或者-j6。
如下所示,

我使用的是
make -j8
然後正式開始編譯。因爲我參考了很多博客,所以,踩得坑要相對少一些。

4、編譯排錯

首先說一下我沒有遇到過的坑

(1)、中文目錄問題

因爲已經瞭解,不止一人在說編譯路徑不能有中文,所以這個問題從解壓縮源碼時就避免了。快檢查一下吧,如果當前編譯路徑帶有中文字符,儘快停止重新編譯。

(2)、JDK的問題

在Android6.0上 編譯源碼不能再使用Oracle JDK了,需要切換到Open JDK。所以這個坑也避免跳進去了。

(3)、編譯過程報錯的問題也通過

修改文件mydroid/art/build/Android.common_build.mk,

ifneq ($(WITHOUT_HOST_CLANG),true)

改爲:

ifeq ($(WITHOUT_HOST_CLANG),false)

提前避免了。

以上是已知的坑,下面說一下自己遇到的坑,

(1)、源碼壓縮包解壓遇到的問題

將源碼下載拼接後,爲了節省空間,所以把壓縮包放到了windows和ubuntu的共享區域,接着在ubuntu中使用

tar -zxvf Android6_r1.tgz 

命令進行解壓,結果報了一堆錯誤,解壓停止,
報錯如下所示:

經過查資料,參考
http://blog.sina.com.cn/s/blog_68eb8fa50102vfab.html,原文這樣說的,
“在用Vmware裝Linux進行嵌入式開發的過程中,爲了方便linux與windows進行快速的文件共享,常常會安裝vmware工具進行文件夾共享。但這會造成linux下連接特別是符號連接的問題,上面問題的原因就在於此,最好的解決方式就是講.tgz壓縮包拷貝到linux的文件系統中,然後解壓。”
於是將共享區域的壓縮包拷貝出來放到了ubuntu獨有的目錄中進行解壓。

(2)、空間不足的問題

在解壓快完成時,突然報錯了,提示系統空間不足,後來一看,原來自己的系統只有20G,這下鬱悶了。沒辦法,接着想辦法進行解決,想到兩個方法,一是擴容,二是重新虛擬一個系統。爲了省事,我選擇了前者,而選擇前者又剛好相反,走了彎路。
對原有系統進行了擴充到120G,主要參考如下兩個鏈接:

http://blog.csdn.net/ygm_linux/article/details/19157781
http://blog.csdn.net/q1302182594/article/details/51658229

然後從頭開始重新編譯,編譯3個小時候,又報控件不足了,這次是主分區sda1空間不足,而我編譯是在新擴充的sda4上編譯的啊,爲什麼sda1會空間不足,於是開始查各種資料,因爲這種問題也不太好提煉關鍵字進行搜索,到最後也沒有找到好的解決方案。於是在經過2,3個小時的排查後,果斷放棄,決定重新虛擬一個大空間的系統。

5、編譯成功

重新搭建了一個ubuntu系統,這次將系統空間直接預留了120G,按照以上步驟重新搭建了編譯環境,接着將源碼從共享空間拷貝到/home目錄,然後解壓縮,在mydroid目錄下繼續編譯。經過一晚上(4小時左右,公司規定下班需要關閉電腦),第二天接着1個多小時的編譯,最後終於編譯成功。
看到如下界面,真的是小激動了一下,

6、模擬器運行

爲了驗證編譯結果是否正確,決定跑一下模擬器。
直接在命令框中輸入emulator是無法啓動模擬器的,於是查詢資料,主要參考了

http://blog.csdn.net/pcsxk/article/details/52016739

所說的方式,
首先確保開啓了硬件虛擬化,使用指令,

egrep -c '(vmx|svm)' /proc/cpuinfo

執行的結果不爲0表示開啓成功。
然後重新配置一下環境變量,

source build/envsetup.sh

最後輸入,

lunch

執行後依然選擇我們編譯時候選擇的build target,這樣emulator就可以啓動起來。

7、總結

Android系統源碼的編譯就是不斷和各種“坑”打交道,不斷掉坑,然後從坑爬出來,繼續掉坑,爬坑的過程。而如果提前獲取到足夠多的坑信息,那就可以避免不必要的爬坑,從而節省我們的時間,願本文能夠讓你少掉坑,少爬坑,一步到位,編譯成功!


歡迎您掃一掃上面的微信公衆號,訂閱我的個人公衆號!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章