Android Building System 分析

Android Building System 分析
by thinker
關鍵字: 
想要了解一個系統,我常會從makefile或是building system下手,以瞭解系統組成元素爲何?目錄結構爲何?對於Android,我也不例外。透過了解building system ,我們能知道如何新增、修改、刪除程式,並保有完整性,順利編譯出結果。

設定檔

Android building system包括幾種重要的設定檔,

  • Android .mk
  • AndroidProducts.mk
  • target_<os>-.mk, host_-.mk and -.mk
  • BoardConfig.mk
  • buildspec.mk

Android .mk是module和package的設定檔,每個module/package的目錄下都會有一個Android.mk。所謂的module是指系統的native code ,相對於用Java寫成的Android application稱爲package。

AndroidProducts.mk 則設定product 配置。product 即特定系統版本,透過編譯不同product ,產生不同軟體配置內容,安裝不同的application。Product 可視爲特定專案,產生特定規格系統。

BoardConfig.mk 是爲product 主板做設定,像是driver 選擇、 設定。*-.mk 則是針對選擇的作業系統和CPU 架構,進行相關設定。

buildspec.mk 是位於source 根目錄下,爲進行編譯者所做之額外設定。例如,可在此選擇要產生的product 、平臺、額外的module/package 等。

參數

build/envsetup.sh實作一個mm指令,以編譯單一module,不需編譯整個source tree。ONE_SHOT_MAKEFILE這個makefile變數/參數就是用以實作這個功能。使用方法是在執行make時,將該變數指定爲module的Android .mk。

  • make ONE_SHOT_MAKEFILE=

透過定義CREATE_MODULE_INFO_FILE , building system 會將所有module 資訊列在$(PRODUCT_OUT)/module-info.txt 檔案裏。

  • make CREATE_MODULE_INFO_FILE=true

設定BUILD_TINY_ANDROID=true , building system 產生一個簡單的image , 以測試硬體的可用度。此功能用於移植的早期階段,以快速bring up 。

HOST_BUILD_TYPE 和TARGET_BUILD_TYPE 指定building system 產生binary 的目的爲debug 或release 。透過設定此二變數,能產生包含debug information 的binry 。

  • debug
  • release

這些參數,也可設於buildspec.mk 裏,以避免開發過程不斷的重新指定。

Goals

一般編輯整個Android系統,就是使用droid這個goal。droid會產生一個完整的系統,包括bootloader、kernel、系統程式、模組和應用程式。

showcommands 和droid 功能相同,但droid 在編譯過程不顯示所使用的指令。透過showcommands 這個goal, building system 顯示過程中每一個步驟的詳細指令。

Makefile 的流程

  • 初始化相關變數
  • 偵測編譯環境和目標環境
  • 決定目標product
  • 讀取product 的設定
  • 讀取product 所指定之目標平臺架構設定
    • 選擇toolchain
    • 指定編譯參數(*-.mk)
  • 清除輸出目錄
  • 設定/檢查版本編號
  • 讀取所有BoardConfig.mk 檔案
  • 讀取所有module 的設定
  • 根據設定,產生必需的rule
  • 產生image

以上的主要流程都是由build/core/main.mk 所安排。

初始化和偵測

由build/core/config.mk 所進行。build/core/envsetup.mk 檢查developer 的設定(buildspec.mk) , 並檢查執行環境,以決定輸出目錄、項目。

build/core/config.mk 本身還依據參數,決定解譯時的相關參數。像是compiler 的路徑、flags, lex 、yacc 的路徑參數等。

關於product 的相關設定,則是由build/core/product_config.mk 所處理, 使用build/core/product.mk 提供之macro 載入。根據AndroidProduct.mk 的內容, product_config.mk 決定了

  • PRODUCT_TAGS
  • OTA_PUBLIC_KEYS
  • PRODUCT_POLICY
  • ......

Product 設定的讀取

Android product的設定來自於build/target/product/AndroidProduct.mk和vendor子目錄下的AndroidProduct.mk 。building system透過find指令,找出所有可能的AndroidProduct.mk。AndroidProduct.mk裏定義PRODUCT_MAKEFILES變數,列舉所有實際定義product的makefile。這些makefile各自定義獨立的product 。product相關參數,存成PRODUCTS..形式的變數。並將makefile 路徑存在PRODUCTS 變數。因此,透過PRODUCTS 能取得所有的product 路徑/名稱, 並透過PRODUCTS.. 形式的變數取得內容。

Module 設定的讀取

Module是指native code的軟體元件,而Java application則被稱爲package。build/core/definitions.mk定義module/package相關macro ,讀取、檢查module/package定義檔;分散source tree各處的Android .mk檔案。build/core/main.mk使用find指令,在這些子目錄下找出所有Android .mk ,並將路徑存在subdir_makefiles變數裏。最後,include這些檔案。

這些Android .mk會include定義成變數BUILD_SHARED_LIBRARY 、BUILD_PACKAGE等,和其目的相配的makefile。這些makefile會變Android .mk定義之內容,存成ALL_MODULES.<path of="" Android.mk>.形式。例如, Android .mk定義了LOCAL_MODULE_SUFFIX ,變會存成ALL_MODULES.<path of="" Android.mk>.LOCAL_MODULE_SUFFIX 。Android .mk路徑,當樣會存於ALL_MODULES變數裏。

Search Android .mk的路徑,基本上會是整個source tree 。但會依特定的goal ,選擇性只找尋特定目錄。例如SDK只需特定目錄下的Android .mk 。

Board Level 設定

和目標平臺主板相關之設定,例如使用了什麼裝置、driver 等,或是是否需要編譯bootloader 、 kernel 等,都是在BoardConfig.mk 裏設定。同樣,每張主板可以有不同設定,存在不同目錄下的BoardConfig.mk ,以find 尋找如下檔案:

  • build/target/board/$(TARGET_DEVICE)/BoardConfig.mk
  • vendor/*/$(TARGET_DEVICE)/BoardConfig.mk
TARGET_DEVICE 是product 所定義,因此同一個BoardConfig.mk 可被多個product 所使用。一個TARGET_DEVICE ,通常只有一個BoardConfig.mk 。BoardConfig.mk 會被直接include 到building system 的name space 裏。因此,一些module 的enable/disable ,可以在BoardConfig.mk 以對映不同的主板。

Rules

在module的定義檔Android .mk裏,可定義module的tag, LOCAL_MODULE_TAGS,以分類這些module。每一個product可以指定需要的tag (PRODUCT_TAGS),使building system只編譯標示這些tag的module。在build/core/main.mk裏,所有標示特定tag的module收集爲ALL_DEFAULT_INSTALLED_MODULES ,並include build/core/Makefile處理。

build/core/Makefile 爲這些module 產生rule ,並使產生image 的goal depend on 這些rule ,使這些module 被編譯。

結論

Android的building system其實不是那麼複雜。在瞭解之後,也不是那麼難修改。但, GNU make的一些語法,所building system使用一些不是那麼直覺的用法,使的building system較難了解。但,花點心思就能克服。

發佈了7 篇原創文章 · 獲贊 4 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章