Android
以模塊的形式來組織各個系統中的部件,
Eng
專業點的詞彙就是
Module
,就是各位在幾乎每一個目錄下都
能看到的
Android.mk
。能夠簡單地把
Android
全部的
Make
文件分爲
4
種:
1
、
For config
這類文件主要來配置
product
,
board
,以及根據你的
Host
和
Target
選擇相應的工具以及設定相應的通用編譯選項:
build/core/config.mk summary ofconfig
build/core/envsetup.mk generate dir config and so on
build/target/product productconfig
build/target/board board config
build/core/combo build flags config
這裏解釋下這裏的
board
和
product
。
borad
主要是設計到硬件芯片的配置,好比是否提供硬件的某些功能,好比說
GPU
等等,或者芯片支持浮點
運算等等。
product
是指針對當前的芯片配置定義你將要生產產品的個性配置,主要是指
APK
方面的配置,哪些
APK
會包含在哪一個
product
中,哪
些
APK
在當前
product
中是不提供的。
config.mk
是一個總括性的東西,它裏面定義了各類
module
編譯所須要使用的
HOST
工具以及如何來編譯各類模塊,好比說
BUILT_PREBUILT
就定義瞭如何來編譯預編譯模塊。
envsetup.mk
主要會讀取由
envsetup.sh
寫入環境變量中的一些變量來配置
編譯過程當中的輸出目錄,
combo
裏面主要定義了各類
Host
和
Target
結合的編譯器和編譯選項。
2
、
Module Compile
這類文件主要定義瞭如何來處理
Module
的
Android.mk
,以及採用何種方式來生成目標模塊,這些模塊生成規則都定義在
config.mk
裏面,
咱們能夠看看:
CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk
BUILD_HOST_STATIC_LIBRARY:=$(BUILD_SYSTEM)/host_static_library.mk
BUILD_HOST_SHARED_LIBRARY:=$(BUILD_SYSTEM)/host_shared_library.mk
BUILD_STATIC_LIBRARY:=$(BUILD_SYSTEM)/static_library.mk
BUILD_RAW_STATIC_LIBRARY :=$(BUILD_SYSTEM)/raw_static_library.mk
BUILD_SHARED_LIBRARY:=$(BUILD_SYSTEM)/shared_library.mk
BUILD_EXECUTABLE:= $(BUILD_SYSTEM)/executable.mk
BUILD_RAW_EXECUTABLE:=$(BUILD_SYSTEM)/raw_executable.mk
BUILD_HOST_EXECUTABLE:=$(BUILD_SYSTEM)/host_executable.mk
BUILD_PACKAGE:= $(BUILD_SYSTEM)/package.mk
BUILD_HOST_PREBUILT:=$(BUILD_SYSTEM)/host_prebuilt.mk
BUILD_PREBUILT:= $(BUILD_SYSTEM)/prebuilt.mk
BUILD_MULTI_PREBUILT:=$(BUILD_SYSTEM)/multi_prebuilt.mk
BUILD_JAVA_LIBRARY:= $(BUILD_SYSTEM)/java_library.mk
BUILD_STATIC_JAVA_LIBRARY:=$(BUILD_SYSTEM)/static_java_library.mk
BUILD_HOST_JAVA_LIBRARY:=$(BUILD_SYSTEM)/host_java_library.mk
BUILD_DROIDDOC:= $(BUILD_SYSTEM)/droiddoc.mk
BUILD_COPY_HEADERS := $(BUILD_SYSTEM)/copy_headers.mk
BUILD_KEY_CHAR_MAP :=$(BUILD_SYSTEM)/key_char_map.mk
除了
CLEAR_VARS
是清楚本地變量以外,其餘全部的都對應了一種模塊的生成規則,每個本地模塊最後都會
include
其中的一種來生成目標模塊。
大部分上面的
.mk
都會包含
base_rules.mk
,這是對模塊進行處理的基礎文件,建議要寫本地模塊的都去看看,看明白了爲何
Android.mk
要這麼寫就會大體明白了。
3
、
Local Module
本地模塊的
Makefile
文件就是咱們在
Android
裏面幾乎上隨處可見的
Android.mk
。
Android
進行編譯的時候會經過下面的函數來遍
歷全部子目錄中的
Android.mk
,一旦找到就不會再往層子目錄繼續尋找
(
全部你的模塊定義的頂層
Android.mk
必須包含本身定義的子目錄中的
Android.mk)
。
subdir_makefiles += \
$(shellbuild/tools/findleaves.sh --prune="./out" $(subdirs) Android.mk)
不一樣類型的本地模塊具備不一樣的語法,但基本上是相通的,只有個別變量的不一樣,如何添加模塊在前面的帖子已經說過了,你們能夠參考。
Android
經過
LOCAL_MODULE_TAGS
來決定哪些本地模塊會不會編譯進系統,經過
PRODUCT
和
LOCAL_MODULE_TAGS
來
決定哪些應用包會編譯進系統,若是用戶不指定
LOCAL_MODULE_TAGS
,默認它的值是
user
。此外用戶能夠經過
buildspec.mk
來指
定你須要編譯進系統的模塊。
用戶也能夠經過
mm
來編譯指定模塊,或者經過
make clean-module_name
來刪除指定模塊。
4
、
Package
這主要指的是
build/core/Makefile
這個文件,它定義了生成各類
img
的方式,包括
ramdisk.img userdata.img system.img update.zip recover.img
等。咱們能夠看看這些
img
都是如何生成的,對應着咱們經常使用的幾個
make goals.
在實際的過程當中,咱們也能夠本身編輯
out
目錄下的生成文件,而後手工打包相應生成
相應的
img
,最經常使用的是加入一些須要集成進的
prebuilt file
。
全部的
Makefile
都經過
build/core/main.mk
這個文件組織在一塊兒,它定義了一個默認
goals
:
droid
,當咱們在
TOP
目錄下
敲
Make
實際上就等同於咱們執行
make droid
。當
Make include
全部的文件,完成對全部
make
我文件的解析之後就會尋找生成
droid
的規則,依次生成它的依賴,直到全部知足的模塊被編譯好,而後使用
相應的工具打包成相應的
img
。
基本上
Android building system
就是以這樣一種方式組織在一塊兒的了,下面說一點閒散的東西。首先是如何來加快
Android
的編譯過程,由於每次
Android
都要遍歷全部
的
Android.mk
,不論是編譯整個工程仍是隻編譯某個模塊。因此能夠將遍歷的結果保存下來,下次直接從文件讀就行了,可是這裏容易出錯,因此必定要
確認是否正確包含了全部的
.mk
,當新加入文件的時候確認將原來保存的文件刪除。下面是我寫的加快編譯的一個
makefile
,將下面的語句替換掉
main.mk
中的相應部分就能夠了:
FROM
:
subdir_makefiles += \
$(shellbuild/tools/findleaves.sh --prune="./out" $(subdirs) Android.mk)
TO
:
ifneq ($(ONE_SHOT_MAKEFILE),)
else
ifneq ($(CASH_MK),true)
subdir_makefiles += \
$(shell build/tools/findleaves.sh--prune="./out" $(subdirs) Android.mk)
else
subdir-makefiles-cash := $(shell catbuild/subdir_mk_cash)
ifeq ($(subdir-makefiles-cash),)
$(warning No .mk cash ,create now !)
subdir_makefiles += \
$(shellbuild/tools/findleaves.sh --prune="./out" $(subdirs) Android.mk)
mk-to-file := $(shell echo $(subdir_makefiles) >build/subdir_mk_cash)
else
$(warning Using cash mk !)
subdir_makefiles := $(shell cat build/subdir_mk_cash)
endif
endif
endif
經過CASH_MK=true來打開快速編譯的功能,由於沒有對錯誤進行檢測的操做,因此使用的時候必定要特別當心。java
每一個應用模塊都會有個Android.mk文件,在這個文件裏都會定義LOCAL_MODULE_TAGS和LOCAL_PACKAGE_NAME,若是想把這個應用編譯進去的話,就須要在generic.mk裏面的PRODUCT這個變量後面加上這個應用的 LOCAL_PACKAGE_NAME,LOCAL_MODULE_TAGS通常是user ,debug,eng這幾個選擇一個
舉個例子:PRODUCT+=Music // LOCAL_PACKAGE_NAMEshell