Anhand der Informationen auf dieser Seite können Sie die Makefiles für Ihr Gerät und Ihr Produkt erstellen.
Jedes neue Android-Modul muss eine Konfigurationsdatei haben, um das Build-System mit Modulmetadaten, Compile-time-Abhängigkeiten und Verpackungsanweisungen zu versorgen. Android verwendet das Soong-Build-System. Weitere Informationen zum Android-Build-System finden Sie unter Android erstellen.
Build-Ebenen verstehen
Die Build-Hierarchie umfasst die Abstraktionsebenen, die der physischen Zusammensetzung eines Geräts entsprechen. Diese Ebenen werden in der Tabelle unten beschrieben. Jede Ebene steht in einer 1:n-Beziehung zur Ebene darüber. Eine Architektur kann beispielsweise mehrere Boards haben und jedes Board kann mehrere Produkte 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 | Beispiel | Beschreibung |
|---|---|---|
| Produkt | myProduct, myProduct_eu, myProduct_eu_fr, j2, sdk | Die Produktebene definiert die Funktionsspezifikation eines Versandprodukts, z. B. die zu erstellenden Module, die unterstützten Gebietsschemata und die Konfiguration für verschiedene Gebietsschemata. Mit anderen Worten: Das ist der Name des Gesamtprodukts. Produktspezifische Variablen werden in Makefiles für die Produktdefinition definiert. Ein Produkt kann von anderen Produktdefinitionen abgeleitet werden, was die Wartung vereinfacht. Eine gängige Methode ist, ein Basisprodukt mit Funktionen zu erstellen, die für alle Produkte gelten, und dann Produktvarianten auf Grundlage dieses Basisprodukts zu erstellen. Beispielsweise können zwei Produkte, die sich nur durch ihre Funkschnittstellen (CDMA im Vergleich zu GSM) unterscheiden, vom selben Basisprodukt abgeleitet werden, in dem keine Funkschnittstelle definiert ist. |
| Board/Gerät | Marlin, Blueline, Coral | Die Board-/Geräteschicht repräsentiert die physische Kunststoffschicht auf dem Gerät, also das Industriedesign des Geräts. Diese Ebene stellt auch die bloßen Schemata 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 Architekturschicht beschreibt die Prozessorkonfiguration und die Binärschnittstelle (Application Binary Interface, ABI), die auf dem Board ausgeführt wird. |
Build-Varianten verwenden
Wenn Sie für ein bestimmtes Produkt entwickeln, sind geringfügige Abweichungen vom endgültigen Release-Build hilfreich. In einer Moduldefinition kann das Modul Tags mit LOCAL_MODULE_TAGS angeben. Das können ein oder mehrere Werte von optional (Standard), debug und eng sein.
Wenn für ein Modul kein Tag angegeben ist (über LOCAL_MODULE_TAGS), wird standardmäßig das Tag optional verwendet. Ein optionales Modul wird nur installiert, wenn es für die Produktkonfiguration mit PRODUCT_PACKAGES erforderlich ist.
Das sind die derzeit definierten Build-Varianten.
| Variante | Beschreibung |
|---|---|
eng
|
Dies ist die Standardvariante.
|
user
|
Die Variante, die als endgültiger Release vorgesehen ist.
|
userdebug
|
Identisch mit user, mit folgenden Ausnahmen:
|
Richtlinien für userdebug
Wenn Geräteentwickler Userdebug-Builds in Tests ausführen, können sie die Leistung und den Stromverbrauch von Releases in der Entwicklung besser nachvollziehen. Damit die Konsistenz zwischen User- und Userdebug-Builds gewahrt bleibt und zuverlässige Messwerte in Builds erzielt werden, die zum Debuggen verwendet werden, sollten Geräteentwickler die folgenden Richtlinien beachten:
- „userdebug“ ist als Nutzer-Build mit aktiviertem Root-Zugriff definiert, mit folgenden Ausnahmen:
- Apps, die nur für Nutzer mit dem Build-Typ „userdebug“ bestimmt sind und nur auf Anfrage des Nutzers ausgeführt werden
- Vorgänge, die nur während der Wartung im Leerlauf ausgeführt werden (am Ladegerät/vollständig aufgeladen), z. B. die Verwendung von
dex2oatdanstelle vondex2oatfür Hintergrundkompilierungen
- Fügen Sie keine Funktionen ein, die je nach Build-Typ standardmäßig aktiviert oder deaktiviert sind. Entwickler sollten keine Form der Protokollierung verwenden, die sich auf die Akkulaufzeit auswirkt, z. B. Debug-Protokollierung oder Heap-Dumping.
- Alle Debugging-Funktionen, die in userdebug standardmäßig aktiviert sind, müssen klar definiert und für alle Entwickler, die am Projekt arbeiten, freigegeben werden. Sie sollten Debugging-Funktionen nur für einen begrenzten Zeitraum aktivieren, bis das Problem, das Sie beheben möchten, behoben ist.
Build mit Ressourcen-Overlays anpassen
Das Android-Build-System verwendet Ressourcen-Overlays, um ein Produkt zur Build-Zeit anzupassen. Mit Ressourcen-Overlays werden Ressourcendateien angegeben, die zusätzlich zu den Standardeinstellungen angewendet werden. Wenn Sie Ressourcen-Overlays verwenden möchten, müssen Sie die Build-Datei des Projekts ändern, um PRODUCT_PACKAGE_OVERLAYS auf einen Pfad relativ zu Ihrem Verzeichnis auf oberster Ebene festzulegen. Dieser Pfad wird zu einem Schattenstammverzeichnis, das zusammen mit dem aktuellen Stammverzeichnis durchsucht wird, wenn das Build-System nach Ressourcen sucht.
Die am häufigsten angepassten Einstellungen sind in der Datei frameworks/base/core/res/res/values/config.xml enthalten.
Wenn Sie ein Ressourcen-Overlay für diese Datei einrichten möchten, fügen Sie dem Projekt-Buildfile eines der folgenden Elemente 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 Overlay-Datei config.xml ersetzen die in der Originaldatei.
Produkte entwickeln
Sie können die Quelldateien für Ihr Gerät auf viele verschiedene Arten organisieren. Hier ist eine kurze Beschreibung einer Möglichkeit, eine Pixel-Implementierung zu organisieren.
Pixel wird mit einer Hauptgerätekonfiguration namens marlin implementiert. Aus dieser Gerätekonfiguration wird ein Produkt mit einer Make-Datei für die Produktdefinition erstellt, in der produktspezifische Informationen zum Gerät wie Name und Modell deklariert werden. Im Verzeichnis device/google/marlin können Sie sehen, wie 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 des Codes. - Erstellen Sie eine
device.mk-Makefile, in der die für das Gerät erforderlichen Dateien und Module deklariert werden. Ein Beispiel finden Sie unterdevice/google/marlin/device-marlin.mk. - Erstellen Sie eine Produktdefinitions-Makefile, um ein bestimmtes Produkt basierend auf dem Gerät zu erstellen. Das folgende Makefile stammt aus
device/google/marlin/aosp_marlin.mk. Das Produkt erbt über die Make-Datei aus den Dateiendevice/google/marlin/device-marlin.mkundvendor/google/marlin/device-vendor-marlin.mkund deklariert gleichzeitig die produktspezifischen Informationen wie Name, Marke und Modell.# 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 \ WallpaperPickerUnter Variablen für die Produktdefinition festlegen finden Sie weitere produktspezifische Variablen, die Sie Ihren Makefiles hinzufügen können.
- 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, das Pixel, als auch Sailfish, das Pixel XL, enthält, die die meisten Konfigurationen gemeinsam nutzen):PRODUCT_MAKEFILES := \ $(LOCAL_DIR)/aosp_marlin.mk \ $(LOCAL_DIR)/aosp_sailfish.mk COMMON_LUNCH_CHOICES := \ aosp_marlin-userdebug \ aosp_sailfish-userdebug
- Erstellen Sie eine
BoardConfig.mk-Makefile-Datei, die boardspezifische Konfigurationen enthält. Ein Beispiel finden Sie unterdevice/google/marlin/BoardConfig.mk. - Nur für Android 9 und niedriger: Erstellen Sie eine
vendorsetup.sh-Datei, um Ihr Produkt (ein „Mittagsmenü“) zusammen mit einer Build-Variante, die durch einen Bindestrich getrennt ist, zum Build hinzuzufügen. Beispiel:add_lunch_combo <product-name>-userdebug
- An dieser Stelle können Sie weitere Produktvarianten auf Grundlage desselben Geräts erstellen.
Variablen für die Produktdefinition festlegen
Produktspezifische Variablen werden in der Make-Datei des Produkts definiert. Die Tabelle enthält einige der Variablen, die in einer Produktdefinitionsdatei verwaltet werden.
| Variable | Beschreibung | Beispiel |
|---|---|---|
PRODUCT_AAPT_CONFIG
|
aapt-Konfigurationen, die beim Erstellen von Paketen verwendet werden sollen.
|
|
PRODUCT_BRAND
|
Die Marke (z. B. Mobilfunkanbieter), für die die Software angepasst wurde. | |
PRODUCT_CHARACTERISTICS
|
aapt-Merkmale, um einem Paket variantenspezifische Ressourcen hinzuzufügen.
|
tablet, nosdcard
|
PRODUCT_COPY_FILES
|
Liste mit Wörtern wie source_path:destination_path. Die Datei im Quellpfad sollte beim Erstellen dieses Produkts in den Zielpfad kopiert werden. Die Regeln für die Kopierschritte sind in config/makefile definiert.
|
|
PRODUCT_DEVICE
|
Name des Designs. 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 mehrere Einstellungen für den Nutzer beschreiben, z. B. die Sprache der Benutzeroberfläche sowie die Formatierung von Uhrzeit, Datum und Währung. Die erste in PRODUCT_LOCALES aufgeführte Sprache 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 Gesamtprodukts. 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. Systemattribute 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 Gebietsschemafilter konfigurieren
Konfigurieren Sie damit den Filter für die Standardsprache und das Systemgebietsschema und aktivieren Sie dann den Gebietsschemafilter für einen neuen Gerätetyp.
Properties
Konfigurieren Sie sowohl die Standardsprache als auch den System-Locale-Filter mit dedizierten Systemeigenschaften:
ro.product.locale: zum Festlegen des Standardschemas. Dieser Wert wird anfangs auf das erste Gebietsschema in der VariablenPRODUCT_LOCALESfestgelegt. Sie können ihn aber überschreiben. Weitere Informationen finden Sie in der Tabelle Variablen für die Produktdefinition festlegen.ro.localization.locale_filter: zum Festlegen eines Gebietsschemafilters mit einem regulären Ausdruck, der auf Gebietsschemanamen angewendet wird. Beispiel:- Inklusiver Filter:
^(de-AT|de-DE|en|uk).*– lässt nur Deutsch (Varianten für Österreich und Deutschland), alle englischen Varianten und Ukrainisch zu. - Ausschlussfilter:
^(?!de-IT|es).*– schließt Deutsch (italienische Variante) und alle Varianten von Spanisch aus.
- Inklusiver Filter:
Sprachfilter aktivieren
Um den Filter zu aktivieren, legen Sie den Stringwert der Systemeigenschaft ro.localization.locale_filter fest.
Wenn Sie den Wert des Filterattributs und die Standardsprache über oem/oem.prop während der Werkskalibrierung 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 der Variablen PRODUCT_OEM_PROPERTIES wie unten angegeben 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 zu berücksichtigen. 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 Ersteinrichtung aussehen.
ADB_VENDOR_KEYS festlegen, um eine Verbindung über USB herzustellen
Mit der Umgebungsvariable 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 für jeden Clientcomputer einen eindeutigen RSA-Authentifizierungsschlüssel, der an alle verbundenen Geräte gesendet wird. Dies ist der RSA-Schlüssel, der im ADB-Autorisierungsdialogfeld angezeigt wird. Alternativ können Sie bekannte Schlüssel in das Systemimage einbauen und für den ADB-Client freigeben.
Das ist nützlich für die Betriebssystementwicklung und insbesondere für Tests, da die manuelle Interaktion mit dem ADB-Autorisierungsdialog vermieden wird.
So erstellen Sie Anbieterschlüssel:
- Generieren Sie mit
adb keygenein Schlüsselpaar. Für Google-Geräte generiert Google für jede neue Betriebssystemversion ein neues Schlüsselpaar. - Prüfen Sie die Schlüsselpaare im Quellbaum. Google speichert sie beispielsweise in
vendor/google/security/adb/. - Legen Sie die Build-Variable
PRODUCT_ADB_KEYSso fest, dass sie auf Ihr Schlüsselverzeichnis verweist. Google fügt dazu eineAndroid.mk-Datei in das Schlüsselverzeichnis ein, in derPRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pubsteht. So wird sichergestellt, dass für jede Betriebssystemversion ein neues Schlüsselpaar generiert wird.
Hier ist das Make-File, das Google in dem 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 auf das Verzeichnis festlegen, in dem die Schlüsselpaare gespeichert sind.
Dadurch wird adb angewiesen, diese kanonischen Schlüssel zuerst zu verwenden, bevor auf den generierten Hostschlüssel zurückgegriffen wird, für den eine manuelle Autorisierung erforderlich ist. Wenn adb keine Verbindung zu einem nicht autorisierten Gerät herstellen kann, wird in der Fehlermeldung vorgeschlagen, dass Sie ADB_VENDOR_KEYS festlegen, falls dies noch nicht geschehen ist.