Android源碼體積很是龐大,由Dalvik虛擬機、Linux內核、編譯系統、框架代碼、Android定製C庫、測試套件、系統應用程序等部分組成,在編譯Android源碼以前,必需要先掌握Android源碼的組成。linux
在Android源碼中,按照不一樣功能代碼被放在不一樣的目錄下:android
目錄web |
描述sql |
bionicshell |
針對Android系統定製的仿生標準C庫、連接器等所在目錄,Android系統並無使用Linux的glibc庫,bioinc C庫針對嵌入式系統作了優化,添加了一些Android特定的函數API同時大大減小庫的體積,也避免了LGPL版權的問題。數據庫 |
bootableapache |
Android系統引導啓動代碼,用來引導系統、更新系統、恢復系統。windows |
build瀏覽器 |
Android的編譯系統目錄,裏面包含大量的Makefile,用來編譯目標系統、Host主機開發環境等。bash |
cts |
兼容性測試工具目錄。 |
dalvik |
Dalvik虛擬機,Android系統得以運行的虛擬執行環境。 |
development |
程序開發所須要的模板和工具。 |
external |
Android系統使用的其它開源代碼目錄,如jpeg圖片解碼開源庫、opencore開源代碼等。 |
frameworks |
框架層代碼,frameworks/base目錄下存放目標系統的框架庫,frameworks/policies/base下存放應用程序框架代碼。 |
hardware |
HAL(Hardware Abstraction Layer)硬件抽象層代碼。 |
kernel |
Linux內核目錄,默認下載的Android源碼裏沒有,需單獨下載。 |
packages
|
Android系統級應用程序源碼目錄,如攝像應用、電話應用等。 |
prebuilt |
主機編譯工具目錄,如arm-linux-gcc交叉系統工具鏈等。 |
sdk |
SDK及模擬器。 |
system |
init進程、藍牙、無線WIFI工具、uevent進程目錄。 |
devices |
廠商設備配置目錄,針對不一樣設備,由不一樣的子目錄來分別管理,用來裁剪實現不一樣設備上Android目標系統。 |
在external目錄下存放着大量的外部開源代碼:
外部開源項目 |
描述 |
外部開源項目 |
描述 |
aes |
AES加密 |
libxml2 |
xml解析庫 |
apache-http |
網頁服務器 |
make |
|
asm |
|
netbeans-visual |
|
bluez |
藍牙相關、協議棧 |
netcat |
simple Unix utility which reads and writes dataacross network connections |
ccache |
|
netperf |
網絡性能測量工具 |
clearsilver |
|
neven |
看代碼和JNI相關 |
dbus |
低延時、低開銷、高可用性的IPC機制 |
opencore |
多媒體框架 |
dhcpcd |
DHCP服務 |
openssl |
SSL加密相關 |
dropbear |
SSH2的server |
oprofile |
OProfile是Linux內核支持的一種性能分析機制 |
eclipse |
|
ppp |
pppd撥號命令,好像尚未chat |
elfcopy |
複製ELF的工具 |
protobuf |
a flexible, efficient, automated mechanism for serializing structured data |
elfutils |
ELF工具 |
qemu |
arm模擬器 |
embunit |
Embedded Unit Project |
safe-iop |
functions for performing safe integer operations |
emma |
Java代碼覆蓋率統計工具 |
sdl |
|
esd |
Enlightened Sound Daemon,將多種音頻流混合在一個設備上播放 |
skia |
skia圖形引擎 |
expat |
Expat is a stream-oriented XML parser |
sonivox |
sole MIDI solution for Google Android Mobile Phone Platform |
fdlibm |
FDLIBM (Freely Distributable LIBM) |
sqlite |
數據庫 |
Flex |
|
srec |
Nuance 公司提供的開源連續非特定人語音識別 |
freetype |
字體庫 |
strace |
trace工具 |
gdata |
google的無線數據相關 |
swing-worker |
|
diflib |
|
swt |
|
googleclient |
google用戶庫 |
tagsoup |
TagSoup是一個Java開發符合SAX的HTML解析器 |
icu4c |
ICU(International Component for Unicode)在C/C++下的版本 |
tcpdump |
抓TCP包的軟件 |
iptables |
防火牆 |
tinyxml |
TinyXml is a simple, small, C++ XML parser |
Jdiff |
generate a report describing the difference between two public Java APIs |
toolchain |
|
jfreechart |
|
tremor |
I stream and file decoder provides an embeddable,integer-only library |
jpeg |
jpeg庫 |
webkit |
瀏覽器核心 |
kxml2 |
|
wpa_supplicant |
無線網卡管理 |
libffi |
libffi is a foreign function interface library. |
yaffs2 |
yaffs文件系統 |
libpcap |
網絡數據包捕獲函數 |
zlib |
a general purpose data compression library |
在packages/app目錄下存放着大量系統級應用程序,咱們能夠拿到這些應用程序代碼分析、理解,編寫出效率更高,性能更好的應用:
系統應用程序 |
描述 |
AlarmClock |
鬧鐘 |
Browser |
瀏覽器 |
Calculator |
計算器 |
Calendar |
日曆 |
Camera |
攝像頭 |
Contacts |
聯繫人 |
|
郵件 |
GoogleSearch |
Google搜索 |
HTML Viewer |
瀏覽器附屬界面,被瀏覽器應用調用,同時提供存儲記錄功能 |
IM |
即時通信,爲手機提供信號發送、接收、通訊的服務 |
Launcher |
Android的桌面 |
Mms |
彩信業務 |
Music |
音樂播放器 |
PackageInstaller |
應用程序安裝、卸載器 |
Phone |
電話應用 |
Settings |
系統設置 |
SoundRecorder |
錄音機 |
Stk |
短信接收和發送 |
Sync |
同步數據 |
Updater |
更新 |
VoiceDialer |
語音識別通話 |
在package/providers目錄下存放的是系統級內容提供器(Content Provider):
系統內容提供器 |
描述 |
CalendarProvider |
日曆提供器 |
ContactsProvider |
聯繫人提供器 |
DownloadProvider |
下載管理提供器 |
DrmProvider |
DRM受保護數據存儲服務,建立和更新數據庫時調用 |
GoogleContactsProvider |
谷歌聯繫人提供器 |
GoogleSubscribedFeedsProvider |
Google同步功能 |
ImProvider |
即時通信提供器 |
MediaProvider |
媒體提供器、提供存儲數據 |
SettingsProvider |
系統設置提供器 |
SubscribedFeedsProvider |
|
TelephonyProvider |
彩信提供器 |
按照Android官方網站給出的步驟,編譯Android源碼過程以下:
Ø 初始化編譯環境
在編譯Android以前,編譯系統須要加載一些編譯腳本命令到環境變量中,經過下面的指令來初始化編譯環境:
在執行完上述命令後,能夠經過執行help命令來查看全部加載的命令。
經常使用腳本命令:
腳本命令 |
描述 |
Help |
幫助信息,打印全部命令 |
add_lunch_combo |
添加新目標編譯項 |
print_lunch_menu |
打印全部目標編譯項 |
lunch |
選擇目標編譯項 |
m |
從源碼樹頂級目錄向下編譯源碼,至關於執行make |
mm |
從當前目錄向下編譯源碼 |
mmm |
從指定目錄向下編譯源碼,一般用來編譯某個模塊 |
cgrep |
從全部的C,C++文件裏查找指定字符串 |
jgrep |
從全部的Java文件裏查找指定字符串 |
Ø 選擇編譯選項
因爲Android源碼是一個開源的系統,然要匹配不少設備產品,也就是說一個版本的Android源碼,能夠編譯出針對不一樣產品的系統。經過選擇一個目標編譯項,來決定編譯出針對哪一個產品的系統,咱們能夠經過執行下面的命令來選擇要編譯的目標系統:
經過lunch命令可知,讓用戶輸入目標編譯項,咱們能夠選擇編譯項前的數字,也能夠直接輸入編譯項的名字。
…接前面終端輸出信息
由上面結果可知,當用戶輸入:1或generic-eng時,會打印出上面的信息,這些信息是Android的編譯系統必須依賴的環境變量,只有設置了這些變量,才能決定Android系統如何編譯,編譯成什麼平臺,編譯成什麼版本。
目標編譯項格式:產品名-版本變量名,目標編譯項能夠由用戶添加(見xxx章節),產品名是目標設備的產品名,由廠商本身定義,generic產品是通用產品,它是Android默認設備的產品名,它包含了經常使用的手機的全部功能,本身定義的產品能夠繼承generic,並重寫它的功能,達到定製產品的目的(見xxx章節)。
版本變量名由如下幾個組成:
其中,eng版本產品其實就是手機行業的工程機,它不是最終銷售的產品,而是產品在定型下線以前放出的一些測試用機器,用於檢測和標準的認證,這些工程機上安裝的系統爲eng版本,user是最終用戶機發行版本,userdebug是調試版本,它比用戶機添加了一些調試功能,如adb調試默認打開等,tests測試版本,該版本會安裝一些測試程序,用於測試系統。
上述四種版本的分類做用,其一:用於區分目標系統裏的全部的應用程序、庫、測試程序等,將它們打上對應的Tags,當選擇一個版本編譯時,擁有對應Tags及低級別的Tags的程序會被編譯安裝到目標設備上,應用程序Tags的包含關係以下圖:。其二:根據不一樣的版本,系統會有不一樣的設置,如adbd在用戶版本里是關閉的,在其它版本中是默認打開的,ro.secure屬性用戶版本值爲1,其它版本爲0。
Ø 編譯源碼
執行完前面的命令後,咱們能夠輸入make指令開始編譯目標系統:
編譯的時長與機器的硬件配置有關係,當第一次編譯時通常須要數小時以上。後續編譯,相對快多了,編譯完的效果以下圖所示:
經過上面的輸出信息可知,Android系統編譯完後,在out/target/product/generic/目錄下產出了三個文件:system.img、ramdisk.img、userdata.img。
其實,Android手機的ROM包(一般爲update.zip文件),就是主要由上述三個映像文件構成的:
ROM包文件 |
說明 |
android-info.txt |
ROM版本及刷寫配置信息 |
boot.img |
Linux內核zImage、ramdisk.img |
system.img |
Android系統映像 |
userdata.img |
用戶數據映像 |
… |
其它映像 |
只要咱們拿到手機的源碼,就能夠本身編譯出本身的ROM,不過,通常手機廠商不會開源本身產品源碼,都是第三方愛好者本身下載,修改編譯的,如:業界著名的CM團隊:http://www.cyanogenmod.com/。
因爲徹底編譯Android系統耗時很長,而且Android源碼由不少模塊組成,咱們能夠經過下面一些編譯命令來減小編譯時間:
編譯命令 |
說明 |
make snod |
打包生成system.img,不檢查依賴關係 |
make bootimage |
打包生成ramdisk.img |
mmm |
指定編譯某個目錄下的模塊 |
上述三個命令常常在咱們源碼開發時使用,但願你們記住。
Android使用Linux內核,在源碼級開發過程當中,有時要修改內核代碼,一般內核代碼是和目標設備相關的,咱們使用的是模擬器的內核,即便沒有硬件設備也能夠完成實驗。
編譯Android的內核,須要用到交叉編譯器,咱們能夠直接使用Android源碼裏自帶的arm-eabi-gcc編譯器,爲了編譯出針對模擬器的內核(模擬器的CPU爲Goldfish),還要配置內核(若是不知道如何配置內核,請讀者閱讀內核裁剪相關資料),爲了方便咱們編譯Goldfish內核,咱們編寫了以下腳本,方便編譯。
添加以下內容:
@ /home/linux/android/android_source/kernel/goldfish/build_kernel.sh
注:當Andorid源碼目錄發生改變時,要修改PATH的路徑,讓它指向對應的交叉編譯器。
給腳本加上可執行權限,而後執行該腳本:
內核編譯完成如圖x-x所示:
圖 內核編譯結果