官术网_书友最值得收藏!

2.3 Android編譯的板級支持

Android的開源代碼默認是支持仿真器的。如果需要使用Android的開源代碼支持一個特定的設備,除了具體的代碼實現之外,還需要對Android的編譯系統做出一些更改。這種編譯的板級支持可以作為附加的方式被添加到Android系統之中。

2.3.1 支持一個板的工作

從Android開源代碼到一個板(特定設備)的支持,變化的部分就是更改部分代碼和增加板級支持目錄。更改完成后,Android編譯系統按照一定的順序進行處理。

Android對特定板的支持的處理流程如圖2-1所示。

圖2-1 Android編譯的板級支持的處理流程

Android對特定板的編譯支持主要分成以下幾個步驟。

● Make的時候傳入TARGET_PRODUCT宏。

● Android的編譯系統根據TARGET_PRODUCT宏找到目標板的配置目錄。

● 在目標板配置目錄中的板級配置文件得到若干配置宏。

● (系統編譯流程)各個模塊根據配置宏進行編譯。

● 處理目標板中的其他特定配置文件。

Android編譯流程主要涉及以下的一些文件。

● buildspec.mk:根目錄中的文件,指定板名稱。

● vendersetup.sh:專用設置文件。

● BoardConfig.mk:板級全局配置。

● AndroidBoard.mk:當前板的特殊配置。

● AndroidProducts.mk:產品的配置。

buildspec.mk和vendersetup.sh兩個文件執行的是同一種功能,也就是目標產品名稱的定義,二者可以取其一(實際上也可以有其他定義方式)。

在make配置后,系統可以開始進行構建。構建的前面就是找到目標產品的配置目錄,并使用其中的幾個文件:BoardConfig.mk中定義的內容可以被系統的每一個部分使用(傳遞到每一個Android.mk);AndroidBoard.mk和AndroidProducts.mk是配置文件,可以引用默認的內容。板級的編譯支持目錄中也可以具有自己的Android.mk文件,與普通的用法類似。

2.3.2 buildspec.mk文件的作用

將buildspec.mk增加到源代碼TOP目錄,可以完成配置工作。Android在執行make的時候,將找到TOP目錄中的buildspec.mk,取出其中定義的內容進行配置。buildspec.mk的作用實際上就是為了定義幾個宏,作為Make第一步使用的環境變量。

一個buildspec.mk的寫法如下所示:

ifndef TARGET_PRODUCT
#TARGET_PRODUCT:=generic
Endif
ifndef TARGET_BUILD_VARIANT
#TARGET_BUILD_VARIANT:=user
#TARGET_BUILD_VARIANT:=userdebug
#TARGET_BUILD_VARIANT:=eng
endif

其中,最重要的一個宏是TARGET_PRODUCT,表示目標產品的名稱;TARGET_BUILD_VARIANT則表示編譯的類型,分成user(用戶模式)、userdebug(用戶調試模式)、eng(工程模式),這個宏將主要影響系統是否具有root權限等方面。

當編譯不進行定義時,或者TARGET_PRODUCT的數值本身就是“generic”,將使用“generic”板(也就是仿真器)的配置,其路徑為:build/target/product。

提示:Android的仿真器默認情況下也是ARM體系結構的目標,仿真器QEMU仿真執行了ARM代碼,因此generic目標和實際的產品差別并不大。

當TARGET_PRODUCT宏被正式定義時,將在自定義板的路徑找到名稱為其值的目錄,作為板級編譯支持目錄。可以使用的板級編譯支持目錄有以下兩個。

● device/*/<TARGET_PRODUCT>

● vendor/*/<TARGET_PRODUCT>

其含義為TOP目錄中的device或者vendor目錄中的某個子目錄中的下一級目錄作為板級編譯支持目錄。也就是說板級編譯支持目錄必須是Android三級子目錄,且必須在device或者vendor目錄中,二級子目錄沒有要求,一般是公司的名稱。

兩個產品的板級編譯支持目錄如下所示。

● device/htc/passion/:Nexus One手機(Google和HTC合作出品)。

● device/samsung/crespo/:Nexus S手機(Google和三星合作出品)。

2.3.3 vendersetup.sh和lunch命令

vendersetup.sh文件可以提供另外一種編譯配置方法,這也是較新版本的Android系統推薦的方法。其職能實際上也是配置幾個宏,作為Make時的環境變量。

在編譯之前,可以使用envsetup.sh腳本進行編譯的配置,配置的過程中,將會調用每一個板的vendersetup.sh文件,內容如下所示:

$ . build/envsetup.sh
including device/htc/passion/vendorsetup.sh
including device/samsung/crespo/vendorsetup.sh

此時的配置,實際是一個“遍歷”的過程,將會調用device/*/和vendor/*/目錄中每一個板的vendersetup.sh文件。只要板級支持目錄中有vendersetup.sh文件,就會被調用。調用后實際上將為增加系統可以選擇的目標產品,這個影響將在使用lunch命令進行選擇產品時有所體現,內容如下所示:

$ lunch
You're building on Linux
Lunch menu... pick a combo:
    1. generic-eng
    2. simulator
    3. full_passion-userdebug
    4. full_crespo-userdebug
Which would you like? [generic-eng] 1
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=2.3.4
TARGET_PRODUCT=generic
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=GRJ22
============================================

在lunch時出現的菜單項目(combo)中,出現了4個選項,可以使用數字進行選擇。從中可見,除了默認的generic-eng和simulator兩個選擇之外,full_passion-userdebug和full_crespo-userdebug就是來自于自定義板級支持的文件。

device/htc/passion/中的vendersetup.sh文件如下所示:

add_lunch_combo full_passion-userdebug

device/samsung/crespo/中的vendersetup.sh文件如下所示:

add_lunch_combo full_crespo-userdebug

其中full_passion和full_crespo也就是所定義的TARGET_PRODUCT宏的名稱。在lunch時選擇了數字后,實際上得到的結果也是設置TARGET_PRODUCT等宏。

2.3.4 BoardConfig.mk文件的作用

BoardConfig.mk文件是一個平臺全局配置的文件,這些配置的內容可以在各個工程的Android.mk文件中得到。BoardConfig.mk只是進行配置的定義,其中不能包含實際執行的命令。

例如,BoardConfig.mk文件可以進行定義:

BOARD_USES_GENERIC_AUDIO := false

BOARD_USES_GENERIC_AUDIO等宏的數值就可以在每一個編譯文件(Android.mk)中被讀出。

BoardConfig.mk文件中也可以使用-include包含其他的板級配置宏。

例如,device/samsung/crespo/中的BoardConfig.mk文件包含了如下的片斷:

-include vendor/samsung/crespo/BoardConfigVendor.mk
TARGET_CPU_ABI := armeabi-v7a               # CPU體系結構的二進制格式
BOARD_HAVE_BLUETOOTH := true                # 是否具有藍牙
TARGET_NO_BOOTLOADER := true                # 是否具有BootLoader
TARGET_NO_KERNEL := false                   # 是否具有Linux內核

BoardConfig.mk文件中既可以使用TARGET_CPU_ABI等編譯系統使用的宏,也可以定義自己使用的宏。

2.3.5 AndroidProducts.mk文件

AndroidProducts.mk為當前板的配置文件,其中可以使用一些宏定制最終在目標系統中需要的安裝內容。在實際的板級支持過程中,通常需要在AndroidProducts.mk中包含同類文件,進行大部分默認的定義,然后再對不同配置進行覆蓋(Override)定義。

AndroidProducts.mk需要定義幾個宏,用于表示當前產品的信息: PRODUCT_NAME(產品名稱),PRODUCT_DEVICE(產品設備)。

其中build/target/product/目錄中的AndroidProducts.mk是默認的產品配置文件,內容如下所示。

ifneq ($(TARGET_BUILD_APPS),)
PRODUCT_MAKEFILES := \
  $(LOCAL_DIR)/core.mk \
  $(LOCAL_DIR)/generic.mk
else
PRODUCT_MAKEFILES := \
  $(LOCAL_DIR)/core.mk \
  $(LOCAL_DIR)/generic.mk \
  $(LOCAL_DIR)/generic_x86.mk \
  $(LOCAL_DIR)/full.mk \
  $(LOCAL_DIR)/sdk.mk \
  $(LOCAL_DIR)/sim.mk
endif

其中指定的PRODUCT_MAKEFILES實際上就是被其包含的文件。full.mk也在build/target/product/目錄中,其中具有如下內容。

PRODUCT_NAME := full
PRODUCT_BRAND := generic
PRODUCT_DEVICE := generic
PRODUCT_MODEL := Full Android

這里的PRODUCT_NAME等宏的定義也就是產品名稱等信息,這里進行了定義后,在系統中通過部分的函數可以讀取這些信息,并可以提供給程序和用戶。

其中另一個功能是定義系統預安裝的包。例子如下所示:

PRODUCT_PACKAGES := \
  OpenWnn \
  PinyinIME \
  VoiceDialer \
  libWnnEngDic \
  libWnnJpnDic \
  libwnndict

在包被增加到PRODUCT_PACKAGES宏之后,這個包將會被預裝到系統中,作為系統映像的一部分。

系統預裝文件使用PRODUCT_COPY_FILES宏來定義。例子如下所示:

PRODUCT_COPY_FILES := \
  development/data/etc/apns-conf.xml:system/etc/apns-conf.xml \
  development/data/etc/vold.conf:system/etc/vold.conf

在PRODUCT_COPY_FILES的各項內容中,“:”前面的為源文件,“:”后面的為目標機的文件(為out/target/product/<產品名稱>目錄加上后面的路徑),編譯時將源文件復制為目標文件。如果目標文件的目錄沒有,也會進行自動創建。因此,這是另外一種像目標系統中預裝文件的方法。

另外一個可以定義的內容是系統語言區域的定義,在build/target/product/目錄中的languages_<XXX>.mk文件中進行定義,類似具有如下的內容:

PRODUCT_LOCALES := en_US en_GB fr_FR it_IT de_DE es_ES

這里使用的是ISO 639-1定義的語言碼和ISO 3166-1-alpha-2定義的區域碼。

例如,device/samsung/crespo/中的AndroidProducts.mk文件包含了同目錄的full_crespo.mk文件,full_crespo.mk的主要內容如下所示:

$(call inherit-product, $(SRC_TARGET_DIR)/product/languages_full.mk)
$(call inherit-product, device/samsung/crespo/device.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/full.mk)
PRODUCT_NAME := full_crespo
PRODUCT_DEVICE := crespo
PRODUCT_MODEL := Full Android on Crespo

此時除了PRODUCT_NAME等宏的定義之外,也可以包含其他的同類文件,包含的languages_full.mk和full.mk就是系統默認的文件,在這里被復用,而device.mk是當前目錄中的另外一個文件。

2.3.6 AndroidBoard.mk文件

AndroidBoard.mk用于板級一些編譯內容的定義,這個文件通常是可選的。AndroidBoard.mk的功能和語法類似一般的Android.mk文件。

例如,build/target/board/generic/中的AndroidBoard.mk文件如下所示:

LOCAL_PATH := $(call my-dir)
file := $(TARGET_OUT_KEYLAYOUT)/tuttle2.kl
ALL_PREBUILT += $(file)
$(file) : $(LOCAL_PATH)/tuttle2.kl | $(ACP)
    $(transform-prebuilt-to-target)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := tuttle2.kcm
include $(BUILD_KEY_CHAR_MAP)

這里進行了兩個工作:一個是將按鍵布局的文件tuttle2.kl復制到目標系統中,一個是調用BUILD_KEY_CHAR_MAP模板對按鍵字符映像的tuttle2.kcm文件進行編譯處理。由于每一個Android板的輸入設備通常都不同,因此在一個特定設備的構建過程中,按鍵相關的定制處理也是經常需要進行的工作。

AndroidBoard.mk不是必需的,例如,在crespo的配置目錄device/samsung/crespo/中,就沒有AndroidBoard.mk文件,而具有Android.mk文件。

2.3.7 編譯中的層疊加

在一個Android的板級構建過程中,有一種不更改源代碼文件,而實現構建出不同內容的方法,這就是通過編譯中層疊加(overlay)的機制來實現的。使用這種方式可以基于同樣的源代碼,為了不同的硬件或不同產品構建出不同的系統。

在板級配置目錄中,可以有一個名稱為overlay的子目錄,這個目錄表示的就是一個代碼疊加層。這個overlay目錄對應于Android源代碼的TOP目錄,在編譯的過程中將使用overlay目錄中的內容替換TOP目錄中的內容。

例如,在Nexus S(crespo)的板級配置的目錄device/samsung/crespo/overlay/下面的一個目錄結構如下所示:

device/samsung/crespo/overlay/frameworks/base/core/
`-- res
  `-- res
        |-- drawable-hdpi
        |   `-- default_wallpaper.jpg
        |-- values
        |   `-- config.xml
        `-- xml
            `-- power_profile.xml

此時,將把TOP目錄中的frameworks/base/core/res/res/drawable-hdpi中的default_wallpaper.jpg替換成overlay對應目錄的同名文件。這個文件實際上是系統默認的墻紙,由此,進行完如此的定義后,相當于crespo編譯的系統將替換默認的墻紙。

Android系統中很多模塊比較適合使用這種替換方式,例如應用程序包中的資源文件等。尤其值得注意的是,一旦使用overlay進行層替換,原有的源文件將不再起作用。

主站蜘蛛池模板: 藁城市| 汨罗市| 安陆市| 勃利县| 离岛区| 黎平县| 宜章县| 珲春市| 太保市| 东兰县| 桓台县| 新竹市| 中牟县| 周口市| 裕民县| 偏关县| 厦门市| 慈利县| 九寨沟县| 淮北市| 磐安县| 安阳县| 常州市| 随州市| 东兴市| 哈密市| 兴仁县| 若羌县| 小金县| 台东市| 伊宁县| 钟山县| 清水河县| 界首市| 建昌县| 和田县| 十堰市| 桐庐县| 嘉义市| 铜鼓县| 延川县|