Verwenden Sie die Informationen auf dieser Seite, um die Makefiles für Ihr Gerät und Ihr Produkt zu erstellen.
Jedes neue Android-Modul muss eine Konfigurationsdatei haben, um das Build-System mit Modulmetadaten, Abhängigkeiten zur Kompilierungszeit und Verpackungsanweisungen zu steuern. Android verwendet das Soong-Build-System. Weitere Informationen zum Android-Buildsystem finden Sie unter Android erstellen.
Build-Ebenen
Die Build-Hierarchie umfasst die Abstraktionsschichten, die der physischen Zusammensetzung eines Geräts entsprechen. Diese Ebenen werden in der folgenden Tabelle beschrieben. Jede Ebene steht in einer 1:n-Beziehung zur darüber liegenden Ebene. Eine Architektur kann beispielsweise mehr als ein Board haben und jedes Board kann mehr als ein Produkt haben. Sie können ein Element in einer bestimmten Ebene als Spezialisierung eines Elements in derselben Ebene definieren. Dadurch wird das Kopieren vermieden und die Wartung vereinfacht.
Ebene | Verwendungsbeispiele | Beschreibung |
---|---|---|
Produkt | myProduct, myProduct_eu, myProduct_eu_fr, j2, sdk | Auf der Produktebene wird die Funktionsspezifikation eines Versandprodukts definiert, z. B. die zu erstellenden Module, unterstützten Gebietsschemata und die Konfiguration für verschiedene Gebietsschemata. Mit anderen Worten: Dies ist der Name des gesamten Produkts. Produktspezifische Variablen werden in den Makefiles der Produktdefinition definiert. Ein Produkt kann von anderen Produktdefinitionen übernommen werden, was die Wartung vereinfacht. Eine gängige Methode besteht darin, ein Basisprodukt mit Funktionen zu erstellen, die für alle Produkte gelten, und dann anhand dieses Basisprodukts Produktvarianten zu erstellen. Beispielsweise können zwei Produkte, die sich nur durch ihre Funkschnittstellen (CDMA oder GSM) unterscheiden, von demselben Basisprodukt abgeleitet werden, für das keine Funkschnittstelle definiert ist. |
Board/Gerät | Marlin, Blueline, Koralle | Die Leiterplatten-/Geräteschicht stellt die physische Kunststoffschicht auf dem Gerät dar, also das Industriedesign des Geräts. Diese Ebene stellt auch die nackten Schaltpläne eines Produkts dar. Dazu gehören die Peripheriegeräte auf dem Board und ihre Konfiguration. Die verwendeten Namen sind lediglich Codes für verschiedene Board-/Gerätekonfigurationen. |
Bogen | arm, x86, arm64, x86_64 | Die Architekturebene beschreibt die Prozessorkonfiguration und die Anwendungs-Binärschnittstelle (Application Binary Interface, ABI), die auf dem Board ausgeführt wird. |
Build-Varianten verwenden
Wenn Sie ein bestimmtes Produkt entwickeln, ist es hilfreich, geringfügige Abweichungen vom endgültigen Release-Build zu haben. In einer Moduldefinition können Tags mit LOCAL_MODULE_TAGS
angegeben werden. Dabei kann es sich um einen oder mehrere Werte von optional
(Standard), debug
und eng
handeln.
Wenn für ein Modul kein Tag (LOCAL_MODULE_TAGS
) angegeben ist, wird standardmäßig optional
verwendet. Ein optionales Modul wird nur installiert, wenn es von der Produktkonfiguration mit PRODUCT_PACKAGES
benötigt wird.
Das sind die derzeit definierten Build-Varianten.
Variante | Beschreibung |
---|---|
eng
|
Dies ist die Standardvariante.
|
user
|
Die Variante, die die endgültigen Release-Bits enthalten soll.
|
userdebug
|
Entspricht user mit folgenden Ausnahmen:
|
Richtlinien für „userdebug“
Wenn Sie bei Tests Userdebug-Builds ausführen, können Geräteentwickler die Leistung und Leistungsfähigkeit von Releases in der Entwicklungsphase besser nachvollziehen. Um für Konsistenz zwischen Nutzer- und Nutzerdebug-Builds zu sorgen und zuverlässige Messwerte in Builds zu erzielen, die für das Debuggen verwendet werden, sollten Geräteentwickler die folgenden Richtlinien beachten:
- „userdebug“ ist ein Nutzerbuild mit aktiviertem Root-Zugriff, mit folgenden Ausnahmen:
- Nur für „userdebug“-Apps, die nur bei Bedarf vom Nutzer ausgeführt werden
- Vorgänge, die nur bei Inaktivität ausgeführt werden (an das Ladegerät angeschlossen/vollständig aufgeladen), z. B. die Verwendung von
dex2oatd
anstelle vondex2oat
für Hintergrundkompilierungen
- Fügen Sie keine Funktionen hinzu, die je nach Build-Typ standardmäßig aktiviert oder deaktiviert sind. Entwicklern wird empfohlen, keine Protokollierung zu verwenden, die sich auf die Akkulaufzeit auswirkt, z. B. Debug-Protokollierung oder Heap-Dumping.
- Alle Funktionen zur Fehlerbehebung, die standardmäßig in „userdebug“ aktiviert sind, sollten klar definiert und allen Entwicklern mitgeteilt werden, die am Projekt arbeiten. Sie sollten die Funktionen zur Fehlerbehebung nur für begrenzte Zeit aktivieren, bis das Problem behoben ist.
Build mit Ressourcen-Overlays anpassen
Das Android-Buildsystem verwendet Ressourcen-Overlays, um ein Produkt zum Zeitpunkt des Builds anzupassen. Mit Ressourcen-Overlays werden Ressourcendateien angegeben, die zusätzlich zu den Standardeinstellungen angewendet werden. Wenn Sie Ressourcen-Overlays verwenden möchten, ändern Sie die Builddatei des Projekts so, dass PRODUCT_PACKAGE_OVERLAYS
auf einen Pfad relativ zum Stammverzeichnis festgelegt ist. Dieser Pfad wird zu einem Schattenstamm, der zusammen mit dem aktuellen Stammverzeichnis durchsucht wird, wenn das Buildsystem nach Ressourcen sucht.
Die am häufigsten angepassten Einstellungen finden Sie in der Datei frameworks/base/core/res/res/values/config.xml.
Wenn Sie ein Ressourcen-Overlay für diese Datei einrichten möchten, fügen Sie das Overlay-Verzeichnis der Builddatei des Projekts mit einer der folgenden Methoden hinzu:
PRODUCT_PACKAGE_OVERLAYS := device/device-implementer/device-name/overlay
oder
PRODUCT_PACKAGE_OVERLAYS := vendor/vendor-name/overlay
Fügen Sie dem Verzeichnis dann eine Overlay-Datei hinzu, z. B.:
vendor/foobar/overlay/frameworks/base/core/res/res/values/config.xml
Alle Strings oder String-Arrays in der config.xml
-Datei des Overlays ersetzen die in der Originaldatei gefundenen Strings oder String-Arrays.
Produkt entwickeln
Sie können die Quelldateien für Ihr Gerät auf viele verschiedene Arten organisieren. Im Folgenden finden Sie eine kurze Beschreibung einer Möglichkeit, eine Pixel-Implementierung zu organisieren.
Google Pixel wird mit einer Hauptgerätekonfiguration namens marlin
implementiert. Anhand dieser Gerätekonfiguration wird ein Produkt mit einem Makefile für die Produktdefinition erstellt, das produktspezifische Informationen zum Gerät wie Name und Modell angibt. Im Verzeichnis device/google/marlin
sehen Sie, wie das alles eingerichtet ist.
Produkt-Makefiles schreiben
In den folgenden Schritten wird beschrieben, wie Sie Produkt-Makefiles ähnlich wie bei der Pixel-Produktlinie einrichten:
- Erstellen Sie ein
device/<company-name>/<device-name>
-Verzeichnis für Ihr Produkt. Beispiel:device/google/marlin
. Dieses Verzeichnis enthält den Quellcode für Ihr Gerät sowie die Makefiles zum Erstellen. - Erstellen Sie ein
device.mk
-Makefile, in dem die für das Gerät erforderlichen Dateien und Module deklariert werden. Ein Beispiel findest du unterdevice/google/marlin/device-marlin.mk
. - Erstellen Sie ein Makefile für die Produktdefinition, um ein bestimmtes Produkt basierend auf dem Gerät zu erstellen. Das folgende Makefile stammt als Beispiel aus
device/google/marlin/aosp_marlin.mk
. Beachten Sie, dass das Produkt über das Makefile von den Dateiendevice/google/marlin/device-marlin.mk
undvendor/google/marlin/device-vendor-marlin.mk
erbt und gleichzeitig die produktspezifischen Informationen wie Name, Marke und Modell deklariert.# 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
Weitere produktspezifische Variablen, die Sie Ihren Makefiles hinzufügen können, finden Sie unter Variablen für Produktdefinitionen festlegen.
- Erstellen Sie eine
AndroidProducts.mk
-Datei, die auf die Makefiles des Produkts verweist. In diesem Beispiel ist nur das Makefile für die Produktdefinition erforderlich. Das folgende Beispiel stammt ausdevice/google/marlin/AndroidProducts.mk
, das sowohl marlin (Pixel) als auch sailfish (Pixel XL) enthält, die die meisten Konfigurationen gemeinsam haben:PRODUCT_MAKEFILES := \ $(LOCAL_DIR)/aosp_marlin.mk \ $(LOCAL_DIR)/aosp_sailfish.mk COMMON_LUNCH_CHOICES := \ aosp_marlin-userdebug \ aosp_sailfish-userdebug
- Erstellen Sie ein
BoardConfig.mk
-Makefile mit bordspezifischen Konfigurationen. Ein Beispiel findest du unterdevice/google/marlin/BoardConfig.mk
. - Erstellen Sie nur für Android 9 und niedriger eine
vendorsetup.sh
-Datei, um Ihrem Build Ihr Produkt (ein „Mittagsmenü“) und eine Buildvariante hinzuzufügen, die durch einen Bindestrich getrennt sind. Beispiel:add_lunch_combo <product-name>-userdebug
- Jetzt können Sie weitere Produktvarianten auf Grundlage desselben Geräts erstellen.
Variablen für Produktdefinitionen festlegen
Produktspezifische Variablen werden im Makefile des Produkts definiert. In der Tabelle sind einige der Variablen aufgeführt, die in einer Produktdefinitiondatei verwaltet werden.
Variable | Beschreibung | Verwendungsbeispiele |
---|---|---|
PRODUCT_AAPT_CONFIG
|
aapt -Konfigurationen, die beim Erstellen von Paketen verwendet werden sollen.
|
|
PRODUCT_BRAND
|
Die Marke (z. B. ein Mobilfunkanbieter), für die die Software angepasst ist. | |
PRODUCT_CHARACTERISTICS
|
aapt -Attribute, mit denen einem Paket variantenspezifische Ressourcen hinzugefügt werden können.
|
tablet , nosdcard
|
PRODUCT_COPY_FILES
|
Liste mit Wörtern wie source_path:destination_path . Die Datei am Quellpfad sollte beim Erstellen dieses Produkts in den Zielpfad kopiert werden. Die Regeln für die Kopierschritte sind unter config/makefile definiert.
|
|
PRODUCT_DEVICE
|
Name des Industriedesigns. Dies ist auch der Name des Boards. Das Build-System verwendet ihn, um BoardConfig.mk zu finden.
|
tuna
|
PRODUCT_LOCALES
|
Eine durch Leerzeichen getrennte Liste von Paaren aus zweistelligem Sprachcode und zweistelligem Ländercode, die verschiedene Einstellungen für den Nutzer beschreiben, z. B. die Sprache der Benutzeroberfläche sowie die Formatierung von Uhrzeit, Datum und Währung. Die erste Sprache in PRODUCT_LOCALES wird als Standardsprache des Produkts verwendet.
|
en_GB , de_DE , es_ES , fr_CA
|
PRODUCT_MANUFACTURER
|
Name des Herstellers. |
acme
|
PRODUCT_MODEL
|
Für Endnutzer sichtbarer Name des Endprodukts. | |
PRODUCT_NAME
|
Für Endnutzer sichtbarer Name des gesamten Produkts. Wird auf dem Bildschirm Einstellungen > Info angezeigt. | |
PRODUCT_OTA_PUBLIC_KEYS
|
Liste der öffentlichen OTA-Schlüssel (Over-the-Air) für das Produkt. | |
PRODUCT_PACKAGES
|
Liste der zu installierenden APKs und Module. | Kalenderkontakte |
PRODUCT_PACKAGE_OVERLAYS
|
Gibt an, ob Standardressourcen verwendet oder produktspezifische Overlays hinzugefügt werden sollen. |
vendor/acme/overlay
|
PRODUCT_SYSTEM_PROPERTIES
|
Liste der Zuweisungen von Systemeigenschaften im Format "key=value" für die Systempartition. Systemeigenschaften für andere Partitionen können über PRODUCT_<PARTITION>_PROPERTIES festgelegt werden, wie in PRODUCT_VENDOR_PROPERTIES für die Anbieterpartition. Unterstützte Partitionsnamen: SYSTEM , VENDOR , ODM , SYSTEM_EXT und PRODUCT .
|
Standardsystemsprache und -Standortfilter konfigurieren
Verwenden Sie diese Informationen, um den Standardfilter für Sprache und Systemsprache zu konfigurieren, und aktivieren Sie dann den Sprachfilter für einen neuen Gerätetyp.
Properties
Konfigurieren Sie sowohl die Standardsprache als auch den System-Standortfilter mithilfe spezieller Systemeigenschaften:
ro.product.locale
: zum Festlegen der Standard-Region. Dieser Wert ist standardmäßig auf das erste Gebietsschema in der VariablenPRODUCT_LOCALES
festgelegt. Sie können ihn überschreiben. Weitere Informationen finden Sie in der Tabelle Variablen für Produktdefinitionen festlegen.ro.localization.locale_filter
: zum Festlegen eines Sprachfilters mit einem regulären Ausdruck, der auf Sprachnamen angewendet wird. Beispiel:- Inklusiver Filter:
^(de-AT|de-DE|en|uk).*
– erlaubt nur Deutsch (Varianten für Deutschland und Österreich), alle Varianten des Englischen und Ukrainisch - Ausschlussfilter:
^(?!de-IT|es).*
– schließt Deutsch (Italienisch) und alle Varianten des Spanischen aus.
- Inklusiver Filter:
Sprachfilter aktivieren
Wenn Sie den Filter aktivieren möchten, müssen Sie den Stringwert der Systemeigenschaft ro.localization.locale_filter
festlegen.
Wenn Sie den Wert der Filtereigenschaft und die Standardsprache während der werksseitigen Kalibrierung über oem/oem.prop
festlegen, können Sie Einschränkungen konfigurieren, ohne den Filter in das System-Image einzubinden.
Sie sorgen dafür, dass diese Eigenschaften aus der OEM-Partition übernommen werden, indem Sie sie wie unten angegeben der Variablen PRODUCT_OEM_PROPERTIES
hinzufügen:
# Delegation for OEM customization
PRODUCT_OEM_PROPERTIES += \
ro.product.locale \
ro.localization.locale_filter
In der Produktion werden dann die tatsächlichen Werte in oem/oem.prop
geschrieben, um die Zielanforderungen widerzuspiegeln. Bei diesem Ansatz bleiben die Standardwerte beim Zurücksetzen auf die Werkseinstellungen erhalten, sodass die ursprünglichen Einstellungen für den Nutzer genau wie bei einer ersten Einrichtung aussehen.
ADB_VENDOR_KEYS für die Verbindung über USB festlegen
Mit der Umgebungsvariablen ADB_VENDOR_KEYS
können Gerätehersteller über ADB ohne manuelle Autorisierung auf debugfähige Builds (-userdebug und -eng, aber nicht -user) zugreifen.
Normalerweise generiert adb einen eindeutigen RSA-Authentifizierungsschlüssel für jeden Clientcomputer, der an jedes verbundene Gerät gesendet wird. Dies ist der RSA-Schlüssel, der im adb-Autorisierungsdialogfeld angezeigt wird. Alternativ können Sie bekannte Schlüssel in das Systemimage einbinden und sie für den adb-Client freigeben.
Das ist nützlich für die Betriebssystementwicklung und insbesondere für Tests, da Sie nicht manuell mit dem Autorisierungsdialogfeld von adb interagieren müssen.
Zum Erstellen von Anbieterschlüsseln muss eine Person (in der Regel ein Release Manager) Folgendes tun:
- Generieren Sie ein Schlüsselpaar mit
adb keygen
. Für Google-Geräte generiert Google für jede neue Betriebssystemversion ein neues Schlüsselpaar. - Prüfen Sie die Schlüsselpaare irgendwo im Stammbaum der Quelle. Google speichert sie beispielsweise in
vendor/google/security/adb/
. - Legen Sie die Build-Variable
PRODUCT_ADB_KEYS
so fest, dass sie auf Ihr Schlüsselverzeichnis verweist. Dazu fügt Google im Schlüsselverzeichnis eineAndroid.mk
-Datei mit dem NamenPRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub
hinzu. So wird sichergestellt, dass wir für jede Betriebssystemversion ein neues Schlüsselpaar generieren.
Hier ist das Makefile, das Google im Verzeichnis verwendet, in dem wir unsere eingecheckten Schlüsselpaare für jeden Release speichern:
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
Um diese Anbieterschlüssel zu verwenden, muss ein Entwickler nur die Umgebungsvariable ADB_VENDOR_KEYS
so festlegen, dass sie auf das Verzeichnis verweist, in dem die Schlüsselpaare gespeichert sind.
Dadurch wird adb
angewiesen, zuerst diese kanonischen Schlüssel zu versuchen, bevor auf den generierten Hostschlüssel zurückgegriffen wird, der eine manuelle Autorisierung erfordert. Wenn adb
keine Verbindung zu einem nicht autorisierten Gerät herstellen kann, wird in der Fehlermeldung empfohlen, ADB_VENDOR_KEYS
festzulegen, falls dies noch nicht geschehen ist.