使用此頁面中的資訊為您的裝置和產品建立 makefile。
每個新的 Android 模組都必須有一個配置文件,以使用模組元資料、編譯時依賴項和打包指令來指導建置系統。 Android 使用Soong 建置系統。有關 Android 構建系統的更多信息,請參閱構建 Android 。
了解建構層
建構層次結構包括與設備的物理構成相對應的抽象層。下表描述了這些層。每一層都與它上面的一層以一對多的關係相關。例如,一個架構可以有多個板,每個板可以有多個產品。您可以將給定層中的元素定義為同一層中元素的特化,這消除了複製並簡化了維護。
層 | 例子 | 描述 |
---|---|---|
產品 | myProduct、myProduct_eu、myProduct_eu_fr、j2、sdk | 產品層定義了運輸產品的功能規範,例如要建置的模組、支援的區域設定以及各種區域設定的配置。換句話說,這是整個產品的名稱。產品特定的變數在產品定義 makefile 中定義。一個產品可以繼承其他產品的定義,從而簡化維護。常見的方法是建立包含適用於所有產品的功能的基礎產品,然後基於該基礎產品建立產品變體。例如,僅無線電功能不同(CDMA 與 GSM)的兩種產品可以繼承未定義無線電功能的相同基本產品。 |
闆卡/設備 | 馬林魚、藍線、珊瑚 | 板/設備層代表設備上塑膠的物理層(即設備的工業設計)。該層也代表產品的裸原理圖。其中包括板上的周邊設備及其配置。使用的名稱只是不同板/設備配置的代碼。 |
拱 | 臂、x86、arm64、x86_64 | 架構層描述了板上運行的處理器配置和應用程式二進位介面(ABI)。 |
使用構建變體
在針對特定產品進行建置時,對最終版本進行細微的修改很有用。在模組定義中,模組可以使用LOCAL_MODULE_TAGS
指定標籤,該標籤可以是optional
(預設)、 debug
和eng
中的一個或多個值。
如果模組未指定標籤(透過LOCAL_MODULE_TAGS
),則其標籤預設為optional
。只有當PRODUCT_PACKAGES
的產品配置需要時,才會安裝選用模組。
這些是當前定義的構建變體。
變體 | 描述 |
---|---|
eng | 這是預設的口味。
|
user | 該變體旨在成為最終版本。
|
userdebug | 與user 相同,但有以下例外:
|
用戶調試指南
在測試中執行 userdebug 建置可以幫助設備開發人員了解開發版本的效能和功能。為了保持使用者和 userdebug 版本之間的一致性,並在用於偵錯的版本中實現可靠的指標,設備開發人員應遵循以下準則:
- userdebug 被定義為啟用 root 存取權限的使用者構建,但以下情況除外:
- 僅由用戶按需運行的僅用於 userdebug 的應用程式
- 僅在空閒維護期間運行的操作(充電器上/充滿電),例如使用
dex2oatd
與dex2oat
進行後台編譯
- 不包括根據建置類型預設啟用/停用的功能。不鼓勵開發人員使用任何影響電池壽命的日誌記錄形式,例如偵錯日誌記錄或堆轉儲。
- 應明確定義 userdebug 中預設啟用的任何偵錯功能,並與參與專案的所有開發人員共用。您應該僅在有限的時間內啟用調試功能,直到您嘗試調試的問題得到解決。
使用資源覆蓋自訂構建
Android 建置系統使用資源覆蓋在建置時自訂產品。資源會覆寫指定在預設值之上套用的資源檔案。若要使用資源覆蓋,請修改專案建置檔案以將PRODUCT_PACKAGE_OVERLAYS
設定為相對於頂層目錄的路徑。當建立系統搜尋資源時,該路徑將成為與目前根一起搜尋的影子根。
最常見的自訂設定包含在檔案Frameworks/base/core/res/res/values/config.xml中。
若要在此檔案上設定資源覆蓋,請使用下列命令之一將覆蓋目錄新增至專案建置檔案:
PRODUCT_PACKAGE_OVERLAYS := device/device-implementer/device-name/overlay
或者
PRODUCT_PACKAGE_OVERLAYS := vendor/vendor-name/overlay
然後,在該目錄中新增一個覆蓋文件,例如:
vendor/foobar/overlay/frameworks/base/core/res/res/values/config.xml
在覆蓋config.xml
檔案中找到的任何字串或字串陣列都會替換在原始檔案中找到的字串或字串陣列。
建構一個產品
您可以透過多種不同的方式組織設備的來源檔案。以下是組織 Pixel 實現的一種方法的簡要描述。
Pixel 是透過名為marlin
主要設備配置來實現的。根據此設備配置,使用產品定義 makefile 建立產品,該文件聲明有關設備的產品特定信息,例如名稱和型號。您可以查看device/google/marlin
目錄以了解所有這些是如何設定的。
編寫產品 makefile
以下步驟說明如何以與 Pixel 產品線類似的方式設定產品 makefile:
- 為您的產品建立
device/ <company-name> / <device-name>
目錄。例如,device/google/marlin
。該目錄將包含您的裝置的原始程式碼以及建置它們的 makefile。 - 建立一個
device.mk
makefile,聲明裝置所需的檔案和模組。有關範例,請參閱device/google/marlin/device-marlin.mk
。 - 建立產品定義 makefile 以根據裝置建立特定產品。以下 makefile 取自
device/google/marlin/aosp_marlin.mk
作為範例。請注意,產品透過 makefile 繼承自device/google/marlin/device-marlin.mk
和vendor/google/marlin/device-vendor-marlin.mk
文件,同時也聲明了產品特定訊息,例如名稱、品牌、和模型。# Inherit from the common Open Source product configuration $(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk) $(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk) PRODUCT_NAME := aosp_marlin PRODUCT_DEVICE := marlin PRODUCT_BRAND := Android PRODUCT_MODEL := AOSP on msm8996 PRODUCT_MANUFACTURER := Google PRODUCT_RESTRICT_VENDOR_FILES := true PRODUCT_COPY_FILES += device/google/marlin/fstab.common:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.marlin $(call inherit-product, device/google/marlin/device-marlin.mk) $(call inherit-product-if-exists, vendor/google_devices/marlin/device-vendor-marlin.mk) PRODUCT_PACKAGES += \ Launcher3QuickStep \ WallpaperPicker
有關可以新增至 makefile 中的其他特定於產品的變量,請參閱設定產品定義變數。
- 建立指向產品 makefile 的
AndroidProducts.mk
檔案。在此範例中,僅需要產品定義 makefile。下面的範例來自device/google/marlin/AndroidProducts.mk
(其中包含 marlin、Pixel 和 sailfish、Pixel XL,它們共享大部分配置):PRODUCT_MAKEFILES := \ $(LOCAL_DIR)/aosp_marlin.mk \ $(LOCAL_DIR)/aosp_sailfish.mk COMMON_LUNCH_CHOICES := \ aosp_marlin-userdebug \ aosp_sailfish-userdebug
- 建立包含板特定配置的
BoardConfig.mk
makefile。有關範例,請參閱device/google/marlin/BoardConfig.mk
。 - 僅適用於 Android 9 及更低版本,創建一個
vendorsetup.sh
文件,將您的產品(“午餐組合”)以及由破折號分隔的構建變體添加到構建中。例如:add_lunch_combo <product-name>-userdebug
- 此時,您可以基於相同裝置建立更多產品變體。
設定產品定義變數
產品特定的變數在產品的 makefile 中定義。此表顯示了產品定義檔中維護的一些變數。
多變的 | 描述 | 例子 |
---|---|---|
PRODUCT_AAPT_CONFIG | 創建包時使用的aapt 配置。 | |
PRODUCT_BRAND | 軟體客製化的品牌(例如營運商)。 | |
PRODUCT_CHARACTERISTICS | aapt 特性允許將特定於變體的資源新增至套件。 | tablet nosdcard |
PRODUCT_COPY_FILES | 像source_path:destination_path 這樣的單字列表。建置此產品時,應將來源路徑中的檔案複製到目標路徑。複製步驟的規則在config/makefile 中定義。 | |
PRODUCT_DEVICE | 工業外觀設計名稱。這也是板名稱,建造系統使用它來定位BoardConfig.mk 。 | tuna |
PRODUCT_LOCALES | 以空格分隔的兩個字母語言代碼、兩個字母國家/地區代碼對的列表,描述使用者的多種設置,例如 UI 語言和時間、日期和貨幣格式。 PRODUCT_LOCALES 中列出的第一個區域設定用作產品的預設區域設定。 | en_GB 、 de_DE 、 es_ES 、 fr_CA |
PRODUCT_MANUFACTURER | 製造商名稱。 | acme |
PRODUCT_MODEL | 最終產品的最終使用者可見的名稱。 | |
PRODUCT_NAME | 整個產品的最終用戶可見的名稱。顯示在「設定」>「關於」畫面。 | |
PRODUCT_OTA_PUBLIC_KEYS | 產品的無線 (OTA) 公鑰清單。 | |
PRODUCT_PACKAGES | 要安裝的 APK 和模組的清單。 | 日曆聯絡人 |
PRODUCT_PACKAGE_OVERLAYS | 指示是否使用預設資源或新增任何特定於產品的覆蓋。 | vendor/acme/overlay |
PRODUCT_SYSTEM_PROPERTIES | 系統分區的系統屬性分配列表,格式為"key=value" 。其他分區的系統屬性可以透過PRODUCT_<PARTITION>_PROPERTIES 設置,就像供應商分區的PRODUCT_VENDOR_PROPERTIES 中一樣。支援的分區名稱: SYSTEM 、 VENDOR 、 ODM 、 SYSTEM_EXT 和PRODUCT 。 |
配置預設系統語言和區域設定過濾器
使用此資訊配置預設語言和系統區域設定過濾器,然後為新設備類型啟用區域設定過濾器。
特性
使用專用系統屬性配置預設語言和系統區域設定過濾器:
-
ro.product.locale
:用於設定預設區域設定。它最初設定為PRODUCT_LOCALES
變數中的第一個區域設定;您可以覆蓋該值。 (有關詳細信息,請參閱設定產品定義變數表。) -
ro.localization.locale_filter
:用於設定區域設定過濾器,使用套用於區域設定名稱的正規表示式。例如:- 包含過濾器:
^(de-AT|de-DE|en|uk).*
- 僅允許德語(奧地利和德國變體)、英語的所有英語變體和烏克蘭語 - 獨家過濾器:
^(?!de-IT|es).*
- 排除德語(義大利變體)和西班牙語的所有變體。
- 包含過濾器:
啟用區域設定過濾器
若要啟用過濾器,請設定ro.localization.locale_filter
系統屬性字串值。
透過在工廠校準期間透過oem/oem.prop
設定過濾器屬性值和預設語言,您可以配置限制,而無需將過濾器烘焙到系統映像中。您可以透過將這些屬性新增至PRODUCT_OEM_PROPERTIES
變數來確保從 OEM 分區取得這些屬性,如下所示:
# Delegation for OEM customization PRODUCT_OEM_PROPERTIES += \ ro.product.locale \ ro.localization.locale_filter
然後在生產中,實際值被寫入oem/oem.prop
,以反映目標要求。透過這種方法,在恢復出廠設定期間會保留預設值,因此初始設定對於使用者來說看起來與首次設定完全相同。
設定 ADB_VENDOR_KEYS 透過 USB 連接
ADB_VENDOR_KEYS
環境變數可讓裝置製造商透過 adb 存取可偵錯版本(-userdebug 和 -eng,但不是 -user),而無需手動授權。通常,adb 會為每台用戶端電腦產生唯一的 RSA 驗證金鑰,並將其傳送到任何已連接的裝置。這是 adb 授權對話方塊中顯示的 RSA 金鑰。作為替代方案,您可以將已知金鑰建置到系統映像中並與 adb 用戶端共用它們。這對於作業系統開發特別是測試很有用,因為它避免了手動與 adb 授權對話方塊互動的需要。
要建立供應商金鑰,一個人(通常是發布經理)應該:
- 使用
adb keygen
產生金鑰對。對於 Google 設備,Google 會為每個新作業系統版本產生一個新金鑰對。 - 檢查來源樹中某處的密鑰對。例如,Google 將它們儲存在
vendor/google/security/adb/
中。 - 將建置變數
PRODUCT_ADB_KEYS
設定為指向您的金鑰目錄。 Google 透過在金鑰目錄中新增一個Android.mk
檔案來實現此目的,其中包含PRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub
,這有助於確保我們記住為每個作業系統版本產生新的金鑰對。
這是 Google 在我們儲存每個版本的簽入金鑰對的目錄中使用的 makefile:
PRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub ifeq ($(wildcard $(PRODUCT_ADB_KEYS)),) $(warning ========================) $(warning The adb key for this release) $(warning ) $(warning $(PRODUCT_ADB_KEYS)) $(warning ) $(warning does not exist. Most likely PLATFORM_VERSION in build/core/version_defaults.mk) $(warning has changed and a new adb key needs to be generated.) $(warning ) $(warning Please run the following commands to create a new key:) $(warning ) $(warning make -j8 adb) $(warning LOGNAME=android-eng HOSTNAME=google.com adb keygen $(patsubst %.pub,%,$(PRODUCT_ADB_KEYS))) $(warning ) $(warning and upload/review/submit the changes) $(warning ========================) $(error done) endif
要使用這些供應商金鑰,工程師只需設定ADB_VENDOR_KEYS
環境變數以指向儲存密鑰對的目錄。這告訴adb
先嘗試這些規範金鑰,然後再回退到需要手動授權的產生的主機金鑰。當adb
無法連接到未經授權的裝置時,錯誤訊息將建議您設定ADB_VENDOR_KEYS
如果尚未設定)。