最近在開發與修改過程中一直是按着别人寫好的文檔去操作的,配置開發環境與編譯及部署應用都是知道怎麼去做,而不知道背後執行的過程是什麼,尤其是原生android源碼還有MTK源碼及各大公司自己制定的源碼都有很多不一樣的地方,當我們已經習慣敲幾個指令去執行編譯的時候,可能很少會去思考它背後的原理。當然,這本身并沒有什麼問題,因為說到底這些編譯腳本和指令,隻是一堆工具。而對我們目前工作真正有幫助的是熟練掌握這些工具的使用,而不是去了解它的原理。如果我們隻是做純粹的應用軟體,上述觀點已經足夠。但是如果我們做系統級的開發,針對整個系統進行移植和開發,了解些Android的編譯系統方面的知識,還是很有幫助的。一下是自己通過看書和查找相關資料得到的一些學習心得,通過部落格以後友善自己檢視。
一.Android系統概覽
1. Android 源碼結構
<a href="http://blog.51cto.com/attachment/201212/155952764.jpg" target="_blank"></a>
Android架構那張圖檔我以前看了很多遍,一直沒了解,最近深入學習才慢慢了解一點點,這裡就貼圖了,由于在公司電腦上有源碼,自己電腦沒有,圖檔來自網上整體差不多,先看看android執行的流程.
<a href="http://blog.51cto.com/attachment/201212/160152119.jpg" target="_blank"></a>
.Android源碼編譯流程關于編譯android源碼環境配置過程我就不說了,網上一堆,一開始我自己配了兩天,現在隻要幾個小時就可以了(熟悉了就好)。
源碼下載下傳好,如第一張圖,進入指令行在工程根目錄下執行make指令 (對于原生的來說,對于第三方公司不一樣)。在源碼下有一個Makefile檔案,執行make指令,等同于執行make Makefile 指令。Makefile檔案的内容:
### DO NOT EDIT THIS FILE ###
include build/core/main.mk
所有的流程控制都在mian.mk檔案中,是以mian.mk是編譯的開始檔案。
在build/core/main.mk裡主要完成以下内容:
1.初始化相關參數設定(buildspec.mk、envsetup.mk、config.mk)
2.檢測編譯環境和目标環境是否符合要求
3.決定目标product名稱
4.讀取product的配置資訊及目标平台資訊
5.清除輸出目錄
6.檢查相關編譯工具版本号
7.讀取Board的配置
8.讀取所有Module的配置
9.根據配置産生必要的規則(build/core/Makefile)
10.生成image鏡像
Main.mk檔案按照下面的次序包含個mk檔案(建議簡單看一下檔案中的内容)
1. config.mk
2. cleanbuild.mk
3. version_checked.mk
4. definitions.mk
config.mk檔案按照下面的次序包含各個mk檔案
1. buildspec.mk
2. envsetup.mk
3. vendor/qcom-proprietary/common/build/define.mk
4. boardconfig.mk
boardconfig.mk會在兩個目錄中尋找
1. build/target/$targetdevice/boardconfig.mk
2. vender/*/$ targetdevice/boardconfig.mk
envsetup.mk中包含下面的mk檔案
1. version_default.mk
下圖簡要介紹了Android build system的配置部分的主要構成及互相關系。
在build/core/main.mk檔案中,簡單設定了幾個環境變量後,就引入了config.mk檔案。
include $(BUILD_SYSTEM)/config.mk該檔案定義一些編譯子產品的生成規則,每一個本地
子產品最後都會include其中的一種來生成目标子產品。指令變量其實是對應的mk檔案名,所有的Android.mk檔案裡基本上都包含上述指令變量,如:CLEAR_VARS:用來清除之前定義的環境變量,BUILD_SHARED_LIBRARY:用來指定編譯動态庫過程。
config.mk下面幾個重要的編譯指令:
通過依次查找mk檔案,執行其中編譯指令進行了整個源碼的編譯,編譯完成之後會在源碼目錄下生成一個out目錄(自己筆記本無法上圖,後面會有的)。
後面會繼續記錄各個mk檔案的内容及含義,以及 Android.mk的了解.
手寫部落格内容真痛苦,最後上一個out目錄結構。
Android 編譯完成後,将在根目錄中生成一個out 檔案夾,所有生成的内容均放置在這個檔案夾中。out 檔案夾如下所示:
out/
|-- CaseCheck.txt
|-- casecheck.txt
|-- host
| |-- common
| `-- linux-x86
`-- target
|-- common
`-- product
主要的兩個目錄為host 和target,前者表示在主機(x86)生成的工具,後者表示目标機(模認
為ARMv5)運作的内容。
host 目錄的結構如下所示:
out/host/
| `-- obj (JAVA 庫)
`-- linux-x86
|-- bin (二進制程式)
|-- framework (JAVA 庫,*.jar 檔案)
|-- lib (共享庫*.so)
`-- obj (中間生成的目标檔案)
host 目錄是一些在主機上用的工具,有一些是二進制程式,有一些是JAVA 的程式。
target 目錄的結構如下所示:
out/target/
| |-- R (資源檔案)
| |-- docs
| `-- obj (目标檔案)
`-- generic
其中common 目錄表示通用的内容,product 中則是針對産品的内容。
在common 目錄的obj 中,包含兩個重要的目錄:
APPS 中包含了JAVA 應用程式生成的目标,每個應用程式對應其中一個子目錄,将結合每個應
用程式的原始檔案生成Android 應用程式的APK 包。
JAVA_LIBRARIES 中包含了JAVA 的庫,每個庫對應其中一個子目錄。
在預設的情況下,Android 編譯将生成generic 目錄,如果標明産品還可以生成其他的目錄。
generic 包含了以下内容:
out/target/product/generic/
|-- android-info.txt
|-- clean_steps.mk
|-- data
|-- obj
|-- ramdisk.img
|-- root
|-- symbols
|-- system
|-- system.img
|-- userdata-qemu.img
`-- userdata.img
在generic/obj/APPS 目錄中包含了各種JAVA 應用,與common/APPS 相對應,但是已經打成
了APK 包。
system 目錄是主要的檔案系統,data 目錄是存放資料的檔案系統。
obj/SHARED_LIBRARIES 中存放所有動态庫。
obj/STATIC_LIBRARIES 中存放所有靜态庫。
幾個以img 為結尾的檔案是幾個目标映像檔案,其中ramdisk 是作為記憶體盤的根檔案系統映像,
system.img 是主要檔案系統的映像,這是一個比較大的檔案,data.img 是資料内容映像。這幾個
image 檔案是運作時真正需要的檔案。
本文轉自 646676684 51CTO部落格,原文連結:http://blog.51cto.com/2402766/1076503,如需轉載請自行聯系原作者