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 Modulmetadaten, Abhängigkeiten zur Kompilierungszeit und Verpackungsanweisungen zu steuern. Android verwendet das Soong-Build-System . Weitere Informationen zum Android-Build-System finden Sie unter Android erstellen .
Build-Layer verstehen
Die Build-Hierarchie umfasst die Abstraktionsebenen, die dem physischen Aufbau eines Geräts entsprechen. Diese Schichten werden in der folgenden Tabelle beschrieben. Jede Ebene steht in einer Eins-zu-viele-Beziehung mit der darüber liegenden Ebene in Beziehung. Beispielsweise kann eine Architektur mehr als eine Platine haben und jede Platine kann mehr als ein Produkt haben. Sie können ein Element in einer bestimmten Ebene als Spezialisierung eines Elements in derselben Ebene definieren, wodurch das Kopieren entfällt und die Wartung vereinfacht wird.
Schicht | Beispiel | Beschreibung |
---|---|---|
Produkt | myProduct, myProduct_eu, myProduct_eu_fr, j2, sdk | Die Produktschicht definiert die Funktionsspezifikation eines Versandprodukts, z. B. die zu erstellenden Module, unterstützte Gebietsschemas und die Konfiguration für verschiedene Gebietsschemas. 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 Funkfunktionen unterscheiden (CDMA oder GSM), von demselben Basisprodukt erben, das keine Funkfunktion definiert. |
Platine/Gerät | Marlin, Blueline, Koralle | Die Platinen-/Geräteschicht stellt die physische Kunststoffschicht auf dem Gerät dar (d. h. das Industriedesign des Geräts). Diese Ebene stellt auch die bloßen Schaltpläne eines Produkts dar. Dazu gehören die Peripheriegeräte auf der Platine und deren Konfiguration. Bei den verwendeten Namen handelt es sich lediglich um Codes für unterschiedliche Platinen-/Gerätekonfigurationen. |
Bogen | Arm, x86, arm64, x86_64 | Die Architekturschicht beschreibt die Prozessorkonfiguration und die Anwendungsbinärschnittstelle (ABI), die auf dem Board ausgeführt wird. |
Verwendung von Build-Varianten
Beim Erstellen für ein bestimmtes Produkt ist es nützlich, geringfügige Abweichungen vom endgültigen Release-Build zu haben. In einer Moduldefinition kann das Modul Tags mit LOCAL_MODULE_TAGS
angeben, bei denen es sich um einen oder mehrere Werte von optional
(Standard), debug
und eng
handeln kann.
Wenn ein Modul kein Tag angibt (durch LOCAL_MODULE_TAGS
), ist sein Tag standardmäßig auf optional
gesetzt. Ein optionales Modul wird nur installiert, wenn es für die Produktkonfiguration mit PRODUCT_PACKAGES
erforderlich ist.
Dies sind die aktuell definierten Build-Varianten.
Variante | Beschreibung |
---|---|
eng | Dies ist die Standardvariante.
|
user | Die Variante soll die endgültige Version sein.
|
userdebug | Das Gleiche 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 Versionen zu verstehen. Um die Konsistenz zwischen Benutzer- und Userdebug-Builds aufrechtzuerhalten und zuverlässige Metriken in Builds zu erhalten, die zum Debuggen verwendet werden, sollten Geräteentwickler die folgenden Richtlinien befolgen:
- userdebug ist als Benutzer-Build mit aktiviertem Root-Zugriff definiert, außer:
- Userdebug-only-Apps, die nur bei Bedarf durch den Benutzer ausgeführt werden
- Vorgänge, die nur während der Leerlaufwartung (auf Ladegerät/voll aufgeladen) ausgeführt werden, z. B. die Verwendung
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, jede Form der Protokollierung zu verwenden, die sich auf die Akkulaufzeit auswirkt, z. B. Debug-Protokollierung oder Heap-Dumping.
- Alle Debugging-Funktionen, die standardmäßig in userdebug aktiviert sind, sollten klar definiert und allen Entwicklern, die am Projekt arbeiten, zur Verfügung gestellt werden. Sie sollten Debugging-Funktionen nur für einen begrenzten Zeitraum aktivieren, bis das Problem, das Sie debuggen möchten, behoben ist.
Anpassen des Builds mit Ressourcen-Overlays
Das Android-Build-System verwendet Ressourcen-Overlays, um ein Produkt zur Build-Zeit anzupassen. Ressourcenüberlagerungen geben Ressourcendateien an, die zusätzlich zu den Standardwerten angewendet werden. Um Ressourcen-Overlays 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-Builddatei 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 in der Overlay-Datei config.xml
gefundenen Zeichenfolgen oder Zeichenfolgenarrays ersetzen diejenigen in der Originaldatei.
Ein Produkt bauen
Sie können die Quelldateien für Ihr Gerät auf viele verschiedene Arten organisieren. Hier finden Sie 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 sich das Verzeichnis device/google/marlin
ansehen, um zu sehen, wie das alles eingerichtet ist.
Schreiben von Produkt-Makefiles
In den folgenden Schritten wird beschrieben, wie Sie Produkt-Makefiles ähnlich wie bei der Pixel-Produktlinie einrichten:
- Erstellen Sie ein Verzeichnis
device/ <company-name> / <device-name>
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, das die für das Gerät benötigten 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 stammt als Beispiel aus
device/google/marlin/aosp_marlin.mk
. Beachten Sie, dass das Produkt von den Dateiendevice/google/marlin/device-marlin.mk
undvendor/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 ausdevice/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 platinenspezifische 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 (eine „Mittagskombination“) zusammen mit einer durch einen Bindestrich getrennten Build-Variante zum Build hinzuzufügen. 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 in einer Produktdefinitionsdatei verwalteten Variablen.
Variable | Beschreibung | Beispiel |
---|---|---|
PRODUCT_AAPT_CONFIG | aapt Konfigurationen, die beim Erstellen von Paketen verwendet werden sollen. | |
PRODUCT_BRAND | Die Marke (z. B. Anbieter), für die die Software angepasst ist. | |
PRODUCT_CHARACTERISTICS | aapt Eigenschaften, um das Hinzufügen von variantenspezifischen 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 sind in config/makefile definiert. | |
PRODUCT_DEVICE | Name des Industriedesigns. Dies ist auch der Board-Name, und das Build-System verwendet ihn, um BoardConfig.mk zu finden. | tuna |
PRODUCT_LOCALES | Eine durch Leerzeichen getrennte Liste von zweibuchstabigen Sprachcode- und zweibuchstabigen Ländercodepaaren, die mehrere Einstellungen für den Benutzer beschreiben, wie z. B. die Sprache der Benutzeroberfläche sowie 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 für das Endprodukt. | |
PRODUCT_NAME | Für den Endbenutzer sichtbarer Name für das Gesamtprodukt. Erscheint im Bildschirm „Einstellungen“ > „Info“ . | |
PRODUCT_OTA_PUBLIC_KEYS | Liste der öffentlichen Over-the-Air-Schlüssel (OTA) 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 Systemeigenschaftenzuweisungen 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 Herstellerpartition. 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 Systemgebietsschemafilter zu konfigurieren und dann den Gebietsschemafilter für einen neuen Gerätetyp zu aktivieren.
Eigenschaften
Konfigurieren Sie sowohl die Standardsprache als auch den Systemgebietsschemafilter mithilfe dedizierter Systemeigenschaften:
-
ro.product.locale
: zum Festlegen des Standardgebietsschemas. Dies ist zunächst auf das erste Gebietsschema in der VariablenPRODUCT_LOCALES
eingestellt; 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:- Inklusivfilter:
^(de-AT|de-DE|en|uk).*
– erlaubt nur Deutsch (Varianten für Österreich und Deutschland), alle englischen Varianten von Englisch und Ukrainisch - Exklusiver Filter:
^(?!de-IT|es).*
– schließt Deutsch (italienische Variante) und alle Varianten des Spanischen aus.
- Inklusivfilter:
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 einzubinden. 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
Anschließend werden in der Produktion 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 Anfangseinstellungen für den Benutzer genau wie eine Ersteinrichtung aussehen.
Einstellung von ADB_VENDOR_KEYS für die Verbindung ü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 verbundene 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 für die Betriebssystementwicklung und insbesondere für Tests nützlich, da eine manuelle Interaktion mit dem ADB-Autorisierungsdialog entfällt.
Um Anbieterschlüssel zu erstellen, sollte 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. - Checken Sie die Schlüsselpaare irgendwo im Quellbaum ein. 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. Google tut dies, indem es im Schlüsselverzeichnis eineAndroid.mk
Datei mit der AufschriftPRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub
hinzufügt. Dadurch wird sichergestellt, 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 Veröffentlichung 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 lediglich die Umgebungsvariable ADB_VENDOR_KEYS
so festlegen, dass sie auf das Verzeichnis zeigt, in dem die Schlüsselpaare gespeichert sind. Dadurch wird adb
angewiesen, zunächst diese kanonischen Schlüssel 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
festlegen, sofern dies nicht bereits festgelegt ist.