Android編譯系統詳解(三)
++++++++++++++++++++++++++++++++++++++++++
本文系本站原創,歡迎轉載! 轉載請註明出處:
++++++++++++++++++++++++++++++++++++++++++
前面兩節講解了自定義Android編譯項和建立Product產品配置檔案,除了編譯和定義產品相關環境變數外,還需要定義Board相關環境變數。
1. build/core/config.mk
109 # --------------------------------------------------------------- 110 # Define most of the global variables. These are the ones that 111 # are specific to the user's build configuration. 112 include $(BUILD_SYSTEM)/envsetup.mk 113 114 # Boards may be defined under $(SRC_TARGET_DIR)/board/$(TARGET_DEVICE) 115 # or under vendor/*/$(TARGET_DEVICE). Search in both places, but 116 # make sure only one exists. 117 # Real boards should always be associated with an OEM vendor. 118 board_config_mk := \ 119 $(strip $(wildcard \ 120 $(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk \ 121 vendor/*/$(TARGET_DEVICE)/BoardConfig.mk \ 122 )) 123 ifeq ($(board_config_mk),) 124 $(error No config file found for TARGET_DEVICE $(TARGET_DEVICE)) 125 endif 126 ifneq ($(words $(board_config_mk)),1) 127 $(error Multiple board config files for TARGET_DEVICE $(TARGET_DEVICE): $(board_config_mk)) 128 endif 129 include $(board_config_mk) 130 TARGET_DEVICE_DIR := $(patsubst %/,%,$(dir $(board_config_mk))) 131 board_config_mk :=
上述程式碼在上一節已經見到過,只是分析了112行的envsetup.mk,根據上一節內容可知,envsetup.mk設定了很多OUT變數,最終在build/core/product_config.mk檔案裡,設定了TARGET_DEVICE = fs100。
我們從114行繼續分析。
- 從114~117行解釋大意可知:
Board相關配置檔案會存在於$(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/或vendor/*/$(TARGET_DEVICE)/目錄中,一個Vendor廠商只能有一個對應的Board配置檔案。
- 118行,定義board_config_mk變數:
$(wildcard xxx)函式就是找到與xxx的匹配項放到空格列表裡,前面定義TARGET_DEVICE變數 = fs100,所以$(SRC_TARGET_DIR)/board/fs100/BoardConfig.mk不存在,必須要存在vendor/*/fs1 00/BoardConfig.mk檔案來定義開發板配置資訊。
- 129行,通過include將vendor/*/fs100/BoardConfig.mk包含進來,
- 130行,TARGET_DEVICE_DIR為board_config_mk的路徑,即:vendor/*/fs100
總結:
一個vendor廠商必須要有一個對應的Board配置檔案,即:vendor/*/fs100/BoardConfig.mk
定義TARGET_DEVICE_DIR變數,為board_config_mk的路徑,即:vendor/*/fs100
指定board 相關特性,一定要包含:
TARGET_CPU_ABI := armeabi/...
其他屬性參見其他board樣例.(build/target/board/XXX
2. build/core/main.mk
141 # Bring in standard build system definitions.
142 include $(BUILD_SYSTEM)/definitions.mk
...
347 ifeq ($(SDK_ONLY),true)
348
349 # ----- SDK for Windows ------
350 # These configure the build targets that are available for the SDK under Cygwin.
351 # The first section defines all the C/C++ tools that can be compiled under Cygwin,
352 # the second section defines all the Java ones (assuming javac is available.)
353
354 subdirs := \
355 prebuilt \
356 build/libs/host \
357 build/tools/zipalign \
...
382 # The following can only be built if "javac" is available.
383 # This check is used when building parts of the SDK under Cygwin.
384 ifneq (,$(shell which javac 2>/dev/null))
385 $(warning sdk-only: javac available.)
386 subdirs += \
387 build/tools/signapk \
388 dalvik/dx \
389 dalvik/libcore \
...
414 else # !SDK_ONLY
415 ifeq ($(BUILD_TINY_ANDROID), true)
416
417 # TINY_ANDROID is a super-minimal build configuration, handy for board
418 # bringup and very low level debugging
419
420 subdirs := \
421 bionic \
422 system/core \
423 build/libs \
424 build/target \
...
433 else # !BUILD_TINY_ANDROID
434
435 #
436 # Typical build; include any Android.mk files we can find.
437 #
438 subdirs := $(TOP)
439
440 FULL_BUILD := true
441
442 endif # !BUILD_TINY_ANDROID
443
444 endif # !SDK_ONLY
...
464 #
465 # Include all of the makefiles in the system
466 #
467
468 # Can't use first-makefiles-under here because
469 # --mindepth=2 makes the prunes not work.
470 subdir_makefiles := \
471 $(shell build/tools/findleaves.py --prune=out --prune=.repo --prune=.git $(subdirs) Android.mk)
472
473 include $(subdir_makefiles)
上一節只是講了main.mk第49行中包含了config.mk,我們繼續分析。
142行包含了:build/core/definitions.mk,該檔案定義了很多全域性變數與函式。
如下列常見函式:
my-dir:返回當前路徑
all-java-files-under:獲得指定目錄及子目錄一所有java檔案
all-subdir-c-files:獲得當前目錄下及子目錄下所有c檔案
354~444行,定義了subdirs變數,依據不同的使用者編譯條件,而包含Android原始碼中不同的目錄。
470行,定義了subdir_makefile變數,其值為subdirs定義的目錄中的Android.mk檔案。
473行,將所有編譯目錄中的Android.mk檔案包含進來。
3. build/target/board/Android.mk
26 ifeq (,$(wildcard $(TARGET_DEVICE_DIR)/AndroidBoard.mk))
27 ifeq (,$(wildcard $(TARGET_DEVICE_DIR)/Android.mk))
28 $(error Missing "$(TARGET_DEVICE_DIR)/AndroidBoard.mk")
29 else
30 # TODO: Remove this check after people have had a chance to switch,
31 # after April 2009.
32 $(error Please rename "$(TARGET_DEVICE_DIR)/Android.mk" to "$(TARGET_DEVICE_DIR)/AndroidBoard.mk")
33 endif
34 endif
35 include $(TARGET_DEVICE_DIR)/AndroidBoard.mk
由於將所有目錄中Android.mk檔案include進來,build/target/board/Android.mk自然被包含進來,根據前面分析,TARGET_DEVICE_DIR = vendor/*/fs100,其中26~35行用來判斷對應的產品目錄下是否存在AndrodiBoard.mk,如果不存在,提示出錯退出,如果存在,將其包含到編譯指令碼中。由此可見:我們必須要在產品目錄下建立AndrodiBoard.mk檔案,來描述開發板相關配置項,我們可以借鑑:build/target/board/generic/AndroidBoard.mk內容,同時根據前面所分析,還要建立BoardConfig.mk檔案。
$ cp build/target/board/generic/AndroidBoard.mk build/target/board/generic/BoardConfig.mk vendor/farsight/fs100/
至此,自定義Android編譯選項基本步驟已經分部分析完,細節還需要針對不同開發板具體分析。
總結:
build/core/main.mk包含了config.mk,它主要定義了編譯全部程式碼的依賴關係
build/core/config.mk 定義了大量的編譯指令碼命令,編譯時用到的環境變數,引入了envsetup.mk 檔案,載入board相關配置檔案。
build/core/envsetup.mk 定義了編譯時用到的大量OUT輸出目錄,載入product_config.mk檔案
build/core/product_config.mk 定義了Vendor目錄下Product相關配置檔案解析指令碼,讀取AndrodProducts.mk生成TARGET_DEVICE變數
build/target/product product config
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結合的編譯器和編譯選項。
1. 在vendor目錄下建立自己公司目錄,然後在公司目錄下建立一個新的vendorsetup.sh,在裡面新增上自己的產品編譯項
$ mkdir vendor/farsight/
$ touch vendor/farsight/vendorsetup.sh
$ echo "add_lunch_combo fs100-eng" > vendor/farsight/vendorsetup.sh
2. 仿著Android示例程式碼,在公司目錄下建立products目錄
$ mkdir -p vendor/farsight/products
3. 仿著Android示例程式碼,在products目錄下建立兩個mk檔案
$ touch vendor/farsight/products/AndroidProduct.mk vendor/farsight/products/fs100.mk
在AndroidProduct.mk裡新增如下內容:
PRODUCT_MAKEFILES := $(LOCAL_DIR)/fs100.mk
在產品配置檔案裡新增最基本資訊
$(call inherit-product, build/target/product/generic.mk)
# Overrides
PRODUCT_MANUFACTURER := farsight
PRODUCT_NAME := fs100
PRODUCT_DEVICE := fs100
4. 借鑑build/target/board/generic/AndroidBoard.mk和BoardConfig.mk,建立對應檔案。
$ cp build/target/board/generic/AndroidBoard.mk build/target/board/generic/BoardConfig.mk vendor/farsight/fs100/