天天看點

Android源碼分析(一):android原生源碼編譯期間執行的流程

        最近在開發與修改過程中一直是按着别人寫好的文檔去操作的,配置開發環境與編譯及部署應用都是知道怎麼去做,而不知道背後執行的過程是什麼,尤其是原生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,如需轉載請自行聯系原作者

繼續閱讀