【轉】編譯Android系統原始碼和核心原始碼

weixin_33816946發表於2015-02-28

原文網址:http://blog.csdn.net/jiangwei0910410003/article/details/37988637

好長時間沒有寫blog了,之所以沒有寫,主要還是工作上的事,發現最近的腦子不夠用了,今天寫點什麼呢?就把我之前編譯Android系統原始碼和核心原始碼的過程記錄一下,因為這個過程真的是受益匪淺,看重的不是結果,主要是過程,在這個過程中,我感覺最大的收穫就是學習的耐心和毅力,因為在這個過程中那個問題就像是雨點似的天天打在你的臉上,雖然現在網上有很多文章介紹怎麼去操作,但是我說句真心話,那些只能提供參考,因為你的工作環境畢竟和他不一樣,所以等你按照他的步驟去操作的時候還是會遇到很多問題,當然我寫這篇文章也不是說我的方法就是一定可以的,我只能說我是成功了,所以我只是想記錄一下,以後可以進行翻閱檢視,主要的還是要看自己的毅力和解決問題的能力了,好了不多說了,說正事吧~~

 

首先我們來看一下編譯Android系統原始碼

第一:我們知道Android系統是基於Linux開發的,所以我們想編譯Android系統原始碼的話,就必須有一個Linux系統,這裡我使用了Ubuntu 64位的系統,這個映象檔案的下載地址是:

http://pan.baidu.com/s/1c0eUSYc

安裝Ubuntu系統不用說了吧,這種問題網上的資料多得很,因為篇幅可能很長,所以如果真的需要的話,請留言~~

 

問題一:至於我為什麼要使用64位系統,因為在後面我會遇到一個問題,就是我第一次安裝的是32位的系統,結果在編譯的過程中遇到一個問題就是:

ERROR: prebuilts/tools/gcc-sdk/../../gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6/bin/x86_64-linux-ar only run on 64-bit linux

編譯不通過的,我就在網上找答案,下面的這篇文章就是說怎麼解決上的問題,主要就是修改一些指定的檔案

http://blog.sina.com.cn/s/blog_76dbbd7e01018cm5.html

但是很悲劇的是:我按照他的方法操作,並沒有成功,那怎麼辦呢?我最後選擇了重灌了一個64位的系統,但是這次就沒有用虛擬機器了,直接安裝到電腦中的。

 

問題二:安裝的時候我先後解除安裝在安裝系統有好幾次,主要原因是第一次編譯沒經驗,開始的時候就分配了20G的空間,結果編譯的時候傻了,完全不夠,所以我直截了當將電腦的200G的空間都分配出去了

 

那麼安裝系統完之後,還有一個問題,當我再去使用同一個方式去下載Android原始碼的時候,發現總是連線不上了,感覺Google退出中國了,原始碼也很難下到了,中間只有大約一個月的時間,就不可以下載了,好假,嘗試過各種方法,我還買VPN,結果還是不行,那麼怎麼辦呢?之前是有原始碼的,但是在虛擬機器中,這時候就需要將虛擬機器中的原始碼拷貝出來了,那麼怎麼從虛擬機器中拷貝檔案呢?這個很簡單的,我用的VM的,他能夠設定共享資料夾(具體方法可以搜尋一下),但是又有一個問題來了,當時在虛擬機器中下載的是Android4.4原始碼,大約有18G,我就嘗試拷貝了,結果發現電腦最好拷貝當機了,主要是因為小檔案太多了,大約有60萬個,電腦配置也不好,所以嘗試了幾次都是當機了,那拷貝不出來怎麼辦呢?問題都是得解決的,突然想到了壓縮一下在拷貝:

http://blog.csdn.net/jiangwei0910410003/article/details/37997899

通過上面的一篇文章中,壓縮拷貝,結果發現效果很不錯,而且壓縮也是很快的,這下拷貝就順利了

至此我們解決了系統問題和原始碼問題

 

注意:這裡所說的原始碼問題不是指下載原始碼的問題,我會在最後面說一下現在如何能夠得到相應的Android原始碼,反正從google上去下載我是不相信了。所以我提供了我已經下載好並且打成壓縮包的連線,

http://pan.baidu.com/s/1mgoNVGs


只需要進行解壓即可,關於解壓縮Linux檔案的話,可以檢視另外一篇blog:

http://blog.csdn.net/jiangwei0910410003/article/details/37997899

 

上面的前奏都做好了,下面就來進行編譯操作

第一步:在此之前還需要安裝一些輔助工具,防止在安裝的時候提示錯誤,當然我們可以現在不安裝,等到安裝的時候會提示相應的錯誤,到時候我只需要針對性的去安裝,但是那樣在編譯的過程中會很不爽的,所以我還是先把這些工作做了

首先需要安裝JDK,請轉戰另外的一篇Blog:

http://blog.csdn.net/jiangwei0910410003/article/details/37996723

 

當JDK安裝完畢之後,下面就需要來安裝一下編譯庫了:

sudo apt-get install gnupg flex bison gperf libsdl1.2-dev libesd0-dev 
sudo apt-get install libwxgtk2.6-dev squashfs-tools build-essential  
sudo apt-get install zlib1g-dev pngcrush schedtool ia32-libs libncurses5-dev

當然這些是必須要安裝的,但是不是一定在編譯的時候就沒有問題,所以我們在編譯的時候遇到什麼問題的時候我們再去進行解決

 

今天在Ubuntu11.04(64位)編譯Android2.3原始碼時,遇到各種各樣的問題。不是缺這個,就是少那個。現把這些問題和解決方法羅列出來,供大家參考

普遍錯誤:
1.錯誤:
/usr/include/gnu/stubs.h:7:27: error: gnu/stubs-32.h: No such file or directory
make: *** [out/host/linux-x86/obj/EXECUTABLES/acp_intermediates/acp.o] 錯誤 1
解決:
sudo apt-get install libc6-dev-i386 

2.錯誤:
make: *** [out/host/linux-x86/obj/EXECUTABLES/acp_intermediates/acp] error 1
解決:
sudo apt-get install g++-multilib 

3.錯誤:
external/clearsilver/cgi/cgi.c:22: fatal error: zlib.h: No such file or directory
compilation terminated.
make: *** [out/host/linux-x86/obj/SHARED_LIBRARIES/libneo_cgi_intermediates/cgi.o] Error 1
解決:
sudo apt-get install zlib1g-dev

4.錯誤:
/usr/bin/ld: cannot find -lz
collect2: ld returned 1 exit status
make: *** [out/host/linux-x86/obj/EXECUTABLES/aapt_intermediates/aapt] Error 1
解決:
sudo apt-get install lib32z1-dev

5.錯誤:
bison -d  -o out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/aidl_language_y.cpp frameworks/base/tools/aidl/aidl_language_y.y
/bin/bash: bison: command not found
make: *** [out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/aidl_language_y.cpp] Error 127
解決:
sudo apt-get install bison

6.錯誤:
Lex: aidl <= frameworks/base/tools/aidl/aidl_language_l.l
/bin/bash: flex: command not found
make: *** [out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/aidl_language_l.cpp] Error 127
解決:
sudo apt-get install flex

7.錯誤:
/usr/bin/ld: cannot find -lncurses
collect2: ld returned 1 exit status
make: *** [out/host/linux-x86/obj/EXECUTABLES/adb_intermediates/adb] Error 1
解決:
sudo apt-get install lib32ncurses5-dev

8.錯誤:
prebuilt/linux-x86/sdl/include/SDL/SDL_syswm.h:55: fatal error: X11/Xlib.h: No such file or directory
compilation terminated.
make: *** [out/host/linux-x86/obj/EXECUTABLES/emulator_intermediates/android/main-common.o] Error 1
解決:
sudo apt-get install libx11-dev 

9.錯誤:
sh: gperf: not found
calling gperf failed: 32512 at ./makeprop.pl line 96.
make: *** [out/target/product/generic/obj/STATIC_LIBRARIES/libwebcore_intermediates/WebCore/css/CSSPropertyNames.h] Error 25
make: *** Deleting file out/target/product/generic/obj/STATIC_LIBRARIES/libwebcore_intermediates/WebCore/css/CSSPropertyNames.h'
解決:
sudo apt-get install gperf
From:http://blog.csdn.net/offbye/article/details/6834285

以上的錯誤總結參考:
http://www.360doc.com/content/12/0602/16/6828497_215429231.shtml

 

致命錯誤: bits/predefs.h:沒有那個檔案或目錄 編譯中斷

解決方法:
sudo apt-get install gcc-multilib

參考:
http://blog.sina.com.cn/s/blog_6340cd9c0101e42h.html

還有一個原因:

Ubuntu 11.10以上的gcc版本是4.6.1,版本太高,編譯android時出錯,要把gcc版本改為4.4.3

sudo apt-get install gcc-4.4
sudo apt-get install g++-4.4

參考:http://blog.163.com/zhaolin53636848@126/blog/static/4908666820121993234837/

 

總結錯誤:

1.錯誤

host Executable: aapt (out/host/linux-x86/obj/EXECUTABLES/aapt_intermediates/aapt)
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../libz.so when searching for -lz
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../libz.a when searching for -lz
/usr/bin/ld: skipping incompatible //usr/lib/libz.so when searching for -lz
/usr/bin/ld: skipping incompatible //usr/lib/libz.a when searching for -lz
/usr/bin/ld: cannot find -lz
collect2: ld returned 1 exit status
make: *** [out/host/linux-x86/obj/EXECUTABLES/aapt_intermediates/aapt] Error 1

解決辦法:

缺少lib32z1-dev,安裝即可:apt-get install lib32z1-dev

2.錯誤
編譯時出現 /usr/include/gnu/stubs.h:7: fatal error: gnu/stubs-32.h: No such file or directory 錯誤資訊
/usr/include/gnu/stubs.h:7: fatal error: gnu/stubs-32.h: No such file or directory
compilation terminated.
make: *** [out/host/linux-x86/obj/EXECUTABLES/acp_intermediates/acp.o] Error 1
解決辦法:

缺少libc開發包,安裝即可: apt-get install libc6-dev-i386

3.錯誤
Android編譯遇到錯誤/usr/bin/ld: cannot find -lstdc++的解決
解決辦法:

缺少g++-multilib庫,安裝即可: apt-get install g++-multilib  

參考:http://www.mobiletrain.org/lecture/doc/android/2011-04/389.html

 

最後發現的一個錯誤:

make android 時的 libwebcore.so error

解決辦法:增加檔案swap

參考:
http://blog.csdn.net/zhoukejun/article/details/4211108

http://blog.163.com/tod_zhang/blog/static/1025522142013225112338311/

 

好吧在這上面的工作都做完了,錯誤也都解決了,編譯也完成了,我是在晚上進行編譯的,第二天好了,當看到結果的時候真的很開心:

 

Target system fs image:    out/target/product/generic/obj/PACKAGING/systemimage_intermediates/system.img
 
Install system fs image: out/target/product/generic/system.img
Target ram disk: out/target/product/generic/ramdisk.img
Target userdata fs image: out/target/product/generic/userdata.img
Installed file list: out/target/product/generic/installed-files.txt 

 

 

那麼下面就執行一下編譯的結果吧:

1. 設定環境變數:
USER-NAME@MACHINE-NAME:~/Android$ export PATH=$PATH:~/Android/out/host/linux-x86/bin  
USER-NAME@MACHINE-NAME:~/Android$ export ANDROID_PRODUCT_OUT=~/Android/out/target/product/generic

其中,~/Android/out/host/linux-x86/bin有我們要執行的emulator命令,而~/Android/out/target/product/generic是Android映象存放目錄,下面執行emulator命令時會用到。
2. 執行模擬器。
USER-NAME@MACHINE-NAME:~/Android$ emulator
模擬器執行需要四個檔案,分別是Linux Kernel映象zImage和Android映象檔案system.img、userdata.img和ramdisk.img。執行emulator命令時,如果不帶任何引數,則Linux Kernel映象預設使用~/Android/prebuilt/android-arm/kernel目錄下的kernel-qemu檔案,而Android映象檔案則預設使用ANDROID_PRODUCT_OUT目錄下的system.img、userdata.img和ramdisk.img,也就是我們剛剛編譯出來的映象問題。
當然,我們也可以以指定的映象檔案來執行模擬器,即執行emulator時,即:
USER-NAME@MACHINE-NAME:~/Android$ emulator -kernel ./prebuilt/android-arm/kernel/kernel-qemu -sysdir ./out/target/product/generic -system system.img -data userdata.img -ramdisk ramdisk.img

 

但是又來了一個錯誤:

emulator: ERROR: You did not specify a virtual device name, and the system
directory could not be found.
If you are an Android SDK user, please use '@<name>' or '-avd <name>'
to start a given virtual device (see -help-avd for details).
Otherwise, follow the instructions in -help-disk-images to start the emulator

解決方法:

進入到Android原始碼目錄中執行:

 

source build/envsetup.sh 

lunch sdk-eng

然後再執行:

emulator

可以啟動模擬器

參考:http://blog.csdn.net/yf210yf/article/details/9206269

 

再次執行,好吧有結果了:

 

編譯完Android原始碼之後,寫還得再來看看如何編譯Android核心原始碼,為什麼要編譯Android核心原始碼呢?這個是為了後續的工作做準備,後面會說到的,其實我們上面編譯的Android原始碼他的核心原始碼Google已經編譯好了,存放在:源目錄/prebuilt/android-arm/kernel/kernel-qemu;

 

下面我們就來看看如何編譯核心原始碼吧,同樣如此,想編譯核心原始碼的話,我們需要核心原始碼,又是一件痛疼的事,網上有很多資源都是說使用goldfish版本的,然後就去:git clone http://android.googlesource.com/kernel/goldfish.git
反正我是下載失敗,原因和下載原始碼是一樣的,google伺服器連線失敗,那怎麼辦呢?
當時我是沒有辦法了,就去各種搜尋,結果有人說goldfish是連線不上了,有人將核心原始碼放到github上了,地址如下:
https://github.com/android/kernel_common

如果下載失敗的話,我已經下載好了,可以去以下的連線去下載:

http://pan.baidu.com/s/1pQzPs

 

我就去下載了,大約幾百M吧,下載下來之後,就進行編譯吧,在編譯之前我們需要修改點東西:

修改資料夾中的Makefile檔案中的編譯環境

ARCH ?= (SUBARCH)
CROSS_COMPILE ?= 

修改成
ARCH ?= arm
CROSS_COMPILE ?= arm-eabi- 

如圖:

採用的是arm體系結構,交叉編譯使用的是arm-eabi-XXX工具,這個值只是個字首

下面我們就來編譯吧,進入到資料夾中進行編譯結果發現,說找不到指定的arm-eabi-gcc工具(這個錯誤發生在我編譯Android4.4版本的時候,因為這個版本的原始碼中找不到指定的prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin目錄,但是最後編譯Android2.3.7版本的話就有了,所以針對於4.4版本沒有的話,我們怎麼辦呢,那還得去網上搜尋這個工具,下載地址:
http://download.csdn.net/download/storeage/4036993),下載下來之後一般是存放到/usr/lib目錄中,然後修改一下環境變數,這個可以參考前面配置JDK環境變數的方法

 

首先需要:make goldfish_defconfig

但是找不到指定檔案,發現這個檔案只在goldfish版本中,而我們下載的是kernel_common,這時候我們可以:

make menuconfig

然後選擇對應的配置,但是問題又來了,哪些選項是必選的,哪些是不需要選的,反正最後編譯總是失敗,搞傷的了,所以還是得去找goldfish版本的(我上面之所以介紹了kernel_common版本的,就是記錄一下我操作的過程,雖然最後失敗了),不過運氣挺好的,最後還真的被我找到了,具體的地址我記得不太清楚了,但是我放到網盤了,裡面有相應的說明,goldfish下載地址:

http://pan.baidu.com/s/1qW0TkkO

 

下載下來之後,可以編譯了,

make goldfish_defconfig

然後

make

這個編譯的過程很快,不到一個小時吧

OBJCOPY arch/arm/boot/zImage
Kernel: arch/arm/boot/zImage is ready

這樣就編譯成功了,那麼我就是用這個核心映象來啟動模擬器吧:


1. 在啟動模擬器之前,先設定模擬器的目錄到環境變數$PATH中去:
USER-NAME@MACHINE-NAME:~/Android$ export PATH=$PATH:~/Android/out/host/linux-x86/bin
2. 設定ANDROID_PRODUCT_OUT環境變數:
USER-NAME@MACHINE-NAME:~/Android$ export ANDROID_PRODUCT_OUT=~/Android/out/target/product/generic
3. 在後臺中指定核心檔案啟動模擬器:
USER-NAME@MACHINE-NAME:~/Android$  emulator -kernel ./kernel/common/arch/arm/boot/zImage &

 

不幸的是模擬器是可以啟動但是總是黑屏,而且是用adb shell也連線不上裝置,這可怎麼辦,都快成功了,然後就去網上再次找答案,找到了:原因是我的原始碼是4.4版本的,2.3版本以後的體系架構是用的是armv7了,所以不是:

make goldfish_defconfig

而是

make goldfish_armv7_defconfig

再次編譯,成功再次是用映象檔案啟動模擬器,草,傻眼了,結果還是失敗太蛋疼了,然後各種搜尋,原因上面的解答,但是我已經修改了,還是不行(這個問題糾結了兩個禮拜,我差點就放棄了),最後想是不是原始碼的問題,也只能這麼想了,所以又去晚上找2.3.7的原始碼,別說著了一天,真是不負有心人呀,還真的被我找到了,而且找到很多個版本,都是壓縮包的形式,在這裡我真心的要感謝這個人,懂得資源分享,

Android2.3.7原始碼下載地址:

http://pan.baidu.com/s/1eQ9YT6i

然後我就很興奮的重新編譯了Android2.3.7版本的原始碼(其實我當時有點擔心,因為我現在的系統是64位的,不知道這個原始碼是多少位的,但是最後編譯成功了,這個版本是64位的,也就不需要重新換系統了),因為有了之前的編譯過程,好多問題都提前解決了,編譯過程中是很順利的,也是在晚上編譯的結果也是成功了,這次我們在通過上面的方式來編譯核心,然後啟動模擬器,擦,結果可以了:

成功了,這次是真的成功了,好感動,好激動呀,兩次挫折兩次激動~~

 

總結:其實我們可以回顧一下上面的過程,個人感覺沒有任何技術可言,我遇到的最大的問題就是資源獲取不到的問題,所以我將使用到的資源都給出了下載連結,同時感覺遇到問題不可以膽怯,要勇敢面對~~

PS:上面的過程是我成功之後的感想和操作,如果親們按照我這種方式不成功的話,請留言~~我會幫助看看~~

注:這篇文章其實沒什麼內容,但是裡面有很多相關資源的下載連線,這個真的很有價值的~~

相關文章