使用此頁面中的信息為您的設備和產品創建 makefile。
每個新的 Android 模塊都必須有一個配置文件,以使用模塊元數據、編譯時依賴項和打包指令來指導構建系統。 Android 使用Soong 構建系統。有關 Android 構建系統的更多信息,請參閱構建 Android 。
了解構建層
構建層次結構包括與設備的物理構成相對應的抽象層。這些層在下表中描述。每一層都以一對多的關係與它上面的一層相關。例如,一個架構可以有多個板,每個板可以有多個產品。您可以將給定層中的元素定義為同一層中元素的特化,這消除了複製並簡化了維護。
層 | 例子 | 描述 |
---|---|---|
產品 | myProduct, myProduct_eu, myProduct_eu_fr, j2, sdk | 產品層定義了運輸產品的功能規範,例如要構建的模塊、支持的語言環境以及各種語言環境的配置。換句話說,這是整個產品的名稱。產品特定變量在產品定義生成文件中定義。一個產品可以從其他產品定義繼承,這簡化了維護。一種常見的方法是創建一個包含適用於所有產品的功能的基礎產品,然後基於該基礎產品創建產品變體。例如,兩種僅在無線電方面不同的產品(CDMA 與 GSM)可以繼承自未定義無線電的相同基礎產品。 |
板/設備 | 馬林魚, blueline, 珊瑚 | 板/器件層代表器件上塑料的物理層(即器件的工業設計)。該層還代表了產品的裸示意圖。其中包括板上的外圍設備及其配置。使用的名稱只是不同板/設備配置的代碼。 |
拱 | 手臂,x86,手臂64,x86_64 | 架構層描述了板上運行的處理器配置和應用程序二進制接口 (ABI)。 |
使用構建變體
在為特定產品構建時,對最終版本構建進行細微更改很有用。在模塊定義中,模塊可以使用LOCAL_MODULE_TAGS
指定標籤,標籤可以是optional
(默認)、 debug
和eng
的一個或多個值。
如果模塊未指定標籤(通過LOCAL_MODULE_TAGS
),則其標籤默認為optional
。僅當使用PRODUCT_PACKAGES
的產品配置需要時才安裝可選模塊。
這些是當前定義的構建變體。
變體 | 描述 |
---|---|
eng | 這是默認風味。
|
user | 該變體旨在成為最終版本。
|
userdebug | 與user 相同,但有以下例外:
|
用戶調試指南
在測試中運行 userdebug 構建有助於設備開發人員了解開發中版本的性能和功能。為了保持 user 和 userdebug 構建之間的一致性,並在用於調試的構建中實現可靠的指標,設備開發人員應遵循以下準則:
- userdebug 被定義為啟用 root 訪問的用戶構建,除了:
- 僅由用戶按需運行的 userdebug-only 應用程序
- 僅在空閒維護期間運行的操作(在充電器上/充滿電),例如使用
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
的主要設備配置實現。從此設備配置中,使用產品定義生成文件創建產品,該文件聲明有關設備的產品特定信息,例如名稱和型號。您可以查看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 的其他產品特定變量,請參閱設置產品定義變量。
- 創建指向產品生成文件的
AndroidProducts.mk
文件。在此示例中,只需要產品定義生成文件。下面的示例來自device/google/marlin/AndroidProducts.mk
(其中包含 marlin,Pixel 和sails,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
生成文件。例如,請參閱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 通過在PRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub
的密鑰目錄中添加一個Android.mk
文件來做到這一點,這有助於確保我們記住為每個操作系統版本生成一個新的密鑰對。
這是 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
如果尚未設置)。