Verwenden Sie die Informationen auf dieser Seite, um die Makefiles für Ihr Gerät und Produkt zu erstellen.
Jedes neue Android-Modul muss über eine Konfigurationsdatei verfügen, um das Build-System mit Modul-Metadaten, Abhängigkeiten zur Kompilierzeit und Verpackungsanweisungen zu steuern. Android verwendet das Song-Build-System . Weitere Informationen zum Android- Buildsystem finden Sie unter Erstellen von Android.
Build-Layer verstehen
Die Build-Hierarchie umfasst die Abstraktionsschichten, die dem physischen Aufbau eines Geräts entsprechen. Diese Schichten werden in der folgenden Tabelle beschrieben. Jede Schicht bezieht sich in einer Eins-zu-Viele-Beziehung auf die darüber liegende. Beispielsweise kann eine Architektur mehr als ein Board haben und jedes Board kann mehr als ein Produkt haben. Sie können ein Element in einer bestimmten Schicht als Spezialisierung eines Elements in derselben Schicht definieren, wodurch das Kopieren entfällt und die Wartung vereinfacht wird.
Schicht | Beispiel | Beschreibung |
---|---|---|
Produkt | meinProdukt, meinProdukt_eu, meinProdukt_eu_fr, j2, sdk | Die Produktebene definiert die Funktionsspezifikation eines Versandprodukts, wie z. B. die zu erstellenden Module, unterstützte Gebietsschemata und die Konfiguration für verschiedene Gebietsschemata. Mit anderen Worten, dies ist der Name des Gesamtprodukts. Produktspezifische Variablen werden in Produktdefinitions-Makefiles definiert. Ein Produkt kann von anderen Produktdefinitionen erben, was die Wartung vereinfacht. Eine gängige Methode besteht darin, ein Basisprodukt zu erstellen, das Funktionen enthält, die für alle Produkte gelten, und dann Produktvarianten basierend auf diesem Basisprodukt zu erstellen. Beispielsweise können zwei Produkte, die sich nur durch ihre Funkgeräte (CDMA versus GSM) unterscheiden, von demselben Basisprodukt erben, das kein Funkgerät definiert. |
Platine/Gerät | Marlin, Blueline, Koralle | Die Platinen-/Geräteschicht stellt die physische Kunststoffschicht auf dem Gerät dar (d. h. das industrielle Design des Geräts). Diese Ebene repräsentiert auch die bloßen Schaltpläne eines Produkts. Dazu gehören die Peripheriegeräte auf dem Board und deren Konfiguration. Die verwendeten Namen sind lediglich Codes für unterschiedliche Platinen-/Gerätekonfigurationen. |
Bogen | arm, x86, arm64, x86_64 | Die Architekturschicht beschreibt die Prozessorkonfiguration und die binäre Anwendungsschnittstelle (ABI), die auf der Platine ausgeführt werden. |
Verwenden von Build-Varianten
Beim Erstellen für ein bestimmtes Produkt ist es hilfreich, geringfügige Abweichungen vom endgültigen Release-Build zu haben. In einer Moduldefinition kann das Modul Tags mit LOCAL_MODULE_TAGS
angeben, die ein oder mehrere Werte von optional
(Standard), debug
und eng
sein können.
Wenn ein Modul kein Tag angibt (durch LOCAL_MODULE_TAGS
), ist sein Tag standardmäßig optional
. Ein optionales Modul wird nur installiert, wenn es von der Produktkonfiguration mit PRODUCT_PACKAGES
wird.
Dies sind die derzeit definierten Build-Varianten.
Variante | Beschreibung |
---|---|
eng | Dies ist der Standardgeschmack.
|
user | Die Variante soll die endgültigen Release-Bits sein.
|
userdebug | Dasselbe wie user , mit diesen Ausnahmen:
|
Richtlinien für Userdebug
Das Ausführen von Userdebug-Builds beim Testen hilft Geräteentwicklern, die Leistung und Leistungsfähigkeit von in der Entwicklung befindlichen Releases zu verstehen. Um die Konsistenz zwischen Benutzer- und Benutzer-Debug-Builds aufrechtzuerhalten und zuverlässige Metriken in Builds zu erhalten, die zum Debuggen verwendet werden, sollten Geräteentwickler diese Richtlinien befolgen:
- userdebug ist als Benutzer-Build mit aktiviertem Root-Zugriff definiert, außer:
- Userdebug-only-Apps, die nur bei Bedarf vom Benutzer ausgeführt werden
- Vorgänge, die nur während der Wartung im Leerlauf (auf dem Ladegerät/voll aufgeladen) ausgeführt werden, z. B. die Verwendung von
dex2oatd
im Vergleich zudex2oat
für Hintergrundkompilierungen
- Schließen Sie keine Funktionen ein, die basierend auf dem Build-Typ standardmäßig aktiviert/deaktiviert sind. Entwicklern wird davon abgeraten, irgendeine Form der Protokollierung zu verwenden, die sich auf die Batterielebensdauer auswirkt, wie z. B. Debug-Protokollierung oder Heap-Dumping.
- Alle Debugging-Funktionen, die standardmäßig in userdebug aktiviert sind, sollten klar definiert und mit allen Entwicklern geteilt werden, die an dem Projekt arbeiten. Sie sollten Debugging-Features nur zeitlich begrenzt aktivieren, bis das Problem, das Sie zu debuggen versuchen, behoben ist.
Anpassen des Builds mit Ressourcenüberlagerungen
Das Android-Build-System verwendet Ressourcen-Overlays, um ein Produkt zur Build-Zeit anzupassen. Ressourcenüberlagerungen geben Ressourcendateien an, die über den Standardeinstellungen angewendet werden. Um Ressourcenüberlagerungen zu verwenden, ändern Sie die Projekt-Builddatei, um PRODUCT_PACKAGE_OVERLAYS
auf einen Pfad relativ zu Ihrem Verzeichnis der obersten Ebene festzulegen. Dieser Pfad wird zu einem Schattenstamm, der zusammen mit dem aktuellen Stamm 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 .
Um ein Ressourcen-Overlay für diese Datei einzurichten, fügen Sie das Overlay-Verzeichnis mit einer der folgenden Methoden zur Projekt-Build-Datei hinzu:
PRODUCT_PACKAGE_OVERLAYS := device/device-implementer/device-name/overlay
oder
PRODUCT_PACKAGE_OVERLAYS := vendor/vendor-name/overlay
Fügen Sie dann dem Verzeichnis eine Overlay-Datei hinzu, zum Beispiel:
vendor/foobar/overlay/frameworks/base/core/res/res/values/config.xml
Alle Strings oder String-Arrays, die in der Overlay-Datei config.xml
gefunden werden, ersetzen die in der Originaldatei gefundenen.
Ein Produkt bauen
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 einem Produktdefinitions-Makefile erstellt, das produktspezifische Informationen über das Gerät wie Name und Modell deklariert. Sie können das Verzeichnis device/google/marlin
anzeigen, um zu sehen, wie all dies eingerichtet ist.
Schreiben von Produkt-Makefiles
Die folgenden Schritte beschreiben, wie Produkt-Makefiles ähnlich wie bei der Pixel-Produktlinie eingerichtet werden:
- Erstellen Sie für Ihr Produkt ein Verzeichnis
device/ <company-name> / <device-name>
. Beispiel:device/google/marlin
. Dieses Verzeichnis enthält den Quellcode für Ihr Gerät zusammen mit den Makefiles, um sie zu erstellen. - Erstellen Sie ein Makefile
device.mk
, das die für das Gerät erforderlichen Dateien und Module deklariert. Ein Beispiel finden Sie unterdevice/google/marlin/device-marlin.mk
. - Erstellen Sie ein Produktdefinitions-Makefile, um ein bestimmtes Produkt basierend auf dem Gerät zu erstellen. Das folgende Makefile ist als Beispiel aus
device/google/marlin/aosp_marlin.mk
. Beachten Sie, dass das Produkt von den Dateiendevice/google/marlin/device-marlin.mk
und „vendor/google/marlin/device-vendor-marlin.mk
über das Makefile erbt und 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 \ WallpaperPicker
Weitere produktspezifische Variablen, die Sie Ihren Makefiles hinzufügen können, finden Sie unter Festlegen von Produktdefinitionsvariablen .
- Erstellen Sie eine
AndroidProducts.mk
-Datei, die auf die Makefiles des Produkts verweist. In diesem Beispiel wird nur das Produktdefinitions-Makefile benötigt. Das folgende Beispiel stammt vondevice/google/marlin/AndroidProducts.mk
(das sowohl marlin, das Pixel, als auch sailfish, das Pixel XL, enthält, das die meisten Konfigurationen gemeinsam hat):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, das Board-spezifische Konfigurationen enthält. Ein Beispiel finden Sie unterdevice/google/marlin/BoardConfig.mk
. - Nur für Android 9 und niedriger : Erstellen Sie eine Datei "
vendorsetup.sh
", um Ihr Produkt (eine "Mittagessen-Kombination") zum Build hinzuzufügen, zusammen mit einer Build-Variante , die durch einen Bindestrich getrennt ist. Zum Beispiel:add_lunch_combo <product-name>-userdebug
- An dieser Stelle können Sie weitere Produktvarianten basierend auf demselben Gerät erstellen.
Festlegen von Produktdefinitionsvariablen
Produktspezifische Variablen werden im Makefile des Produkts definiert. Die Tabelle zeigt einige der Variablen, die in einer Produktdefinitionsdatei verwaltet werden.
Variable | Beschreibung | Beispiel |
---|---|---|
PRODUCT_AAPT_CONFIG | aapt Konfigurationen zur Verwendung beim Erstellen von Paketen. | |
PRODUCT_BRAND | Die Marke (z. B. Spediteur), für die die Software angepasst ist, falls vorhanden. | |
PRODUCT_CHARACTERISTICS | aapt Merkmale, um das Hinzufügen variantenspezifischer Ressourcen zu einem Paket zu ermöglichen. | tablet , nosdcard |
PRODUCT_COPY_FILES | Liste von 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 werden in config/makefile definiert. | |
PRODUCT_DEVICE | Name des Industriedesigns. Dies ist auch der Name des Boards, und das Build-System verwendet ihn, um BoardConfig.mk zu finden. | tuna |
PRODUCT_LOCALES | Eine durch Leerzeichen getrennte Liste von Paaren aus zwei Buchstaben Sprachcode und zwei Buchstaben Ländercode, die mehrere Einstellungen für den Benutzer beschreiben, wie z. B. die Sprache der Benutzeroberfläche und Uhrzeit, Datum und Währungsformatierung. Das erste in PRODUCT_LOCALES aufgeführte Gebietsschema wird als Standardgebietsschema des Produkts verwendet. | en_GB , de_DE , es_ES , fr_CA |
PRODUCT_MANUFACTURER | Name des Herstellers. | acme |
PRODUCT_MODEL | Für den Endbenutzer sichtbarer Name des Endprodukts. | |
PRODUCT_NAME | Für den Endbenutzer sichtbarer Name für das Gesamtprodukt. Erscheint im Bildschirm Einstellungen > Info . | |
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 Systemeigenschaftszuweisungen im Format "key=value" für die Systempartition. Systemeigenschaften für andere Partitionen können über PRODUCT_<PARTITION>_PROPERTIES wie in PRODUCT_VENDOR_PROPERTIES für die Herstellerpartition festgelegt werden. Unterstützte Partitionsnamen: SYSTEM , VENDOR , ODM , SYSTEM_EXT und PRODUCT . |
Konfigurieren der Standardsystemsprache und des Gebietsschemafilters
Verwenden Sie diese Informationen, um die Standardsprache und den Gebietsschemafilter des Systems zu konfigurieren, und aktivieren Sie dann den Gebietsschemafilter für einen neuen Gerätetyp.
Eigenschaften
Konfigurieren Sie sowohl die Standardsprache als auch den Gebietsschemafilter des Systems mithilfe dedizierter Systemeigenschaften:
-
ro.product.locale
: zum Festlegen des Standardgebietsschemas. Dies wird anfänglich auf das erste Gebietsschema in der VariablenPRODUCT_LOCALES
; Sie können diesen Wert überschreiben. (Weitere Informationen finden Sie in der Tabelle Produktdefinitionsvariablen festlegen .) -
ro.localization.locale_filter
: Zum Festlegen eines Gebietsschemafilters unter Verwendung eines regulären Ausdrucks, der auf Gebietsschemanamen angewendet wird. Zum Beispiel:- Inklusiver Filter:
^(de-AT|de-DE|en|uk).*
- erlaubt nur Deutsch (Varianten Österreich und Deutschland), alle englischen Varianten des Englischen und Ukrainisch - Exklusiver Filter:
^(?!de-IT|es).*
- schließt Deutsch (italienische Variante) und alle spanischen Varianten aus.
- Inklusiver Filter:
Aktivieren des Gebietsschemafilters
Um den Filter zu aktivieren, legen Sie den Zeichenfolgenwert der Systemeigenschaft ro.localization.locale_filter
fest.
Durch Festlegen des Filtereigenschaftswerts und der Standardsprache über oem/oem.prop
während der Werkskalibrierung können Sie Einschränkungen konfigurieren, ohne den Filter in das Systemabbild zu backen. Sie stellen sicher, dass diese Eigenschaften von der OEM-Partition übernommen werden, indem Sie sie wie unten angegeben zur 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 Ist-Werte nach oem/oem.prop
geschrieben, um die Soll-Anforderungen widerzuspiegeln. Bei diesem Ansatz bleiben die Standardwerte während des Zurücksetzens auf die Werkseinstellungen erhalten, sodass die anfänglichen Einstellungen für den Benutzer genau wie eine erste Einrichtung aussehen.
Einstellen von ADB_VENDOR_KEYS zum Verbinden über USB
Die Umgebungsvariable ADB_VENDOR_KEYS
ermöglicht Geräteherstellern den Zugriff auf debugfähige Builds (-userdebug und -eng, aber nicht -user) über adb ohne manuelle Autorisierung. Normalerweise generiert adb für jeden Client-Computer einen eindeutigen RSA-Authentifizierungsschlüssel, den es an jedes angeschlossene Gerät sendet. Dies ist der RSA-Schlüssel, der im adb-Autorisierungsdialog angezeigt wird. Alternativ können Sie bekannte Schlüssel in das Systemabbild einbauen und diese mit dem adb-Client teilen. Dies ist nützlich für die Betriebssystementwicklung und insbesondere zum Testen, da es die Notwendigkeit vermeidet, manuell mit dem ADB-Autorisierungsdialogfeld zu interagieren.
Um Lieferantenschlüssel zu erstellen, sollte eine Person (normalerweise 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. - Überprüfen Sie die Schlüsselpaare irgendwo im Quellbaum. Google speichert sie beispielsweise
vendor/google/security/adb/
. - Legen Sie die Build-Variable
PRODUCT_ADB_KEYS
so fest, dass sie auf Ihr Schlüsselverzeichnis zeigt. Google tut dies, indem es eineAndroid.mk
-Datei im Schlüsselverzeichnis hinzufügt, die besagtPRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub
, wodurch sichergestellt wird, dass wir daran denken, für jede Betriebssystemversion ein neues Schlüsselpaar zu generieren.
Hier ist das Makefile, das Google in dem Verzeichnis verwendet, in dem wir unsere eingecheckten Schlüsselpaare für jede Version 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 Herstellerschlüssel zu verwenden, muss ein Techniker nur die Umgebungsvariable ADB_VENDOR_KEYS
so einstellen, dass sie auf das Verzeichnis zeigt, in dem die Schlüsselpaare gespeichert sind. Dies weist adb
an, diese kanonischen Schlüssel zuerst auszuprobieren, 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, schlägt die Fehlermeldung vor, dass Sie ADB_VENDOR_KEYS
falls dies noch nicht geschehen ist.