Ein neues Gerät hinzufügen

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 werden.

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.
  • Installiert Module, die mit eng oder debug gekennzeichnet sind.
  • Installiert Module gemäß den Produktdefinitionsdateien zusätzlich zu getaggten Modulen.
  • ro.secure=0
  • ro.debuggable=1
  • ro.kernel.android.checkjni=1
  • adb ist standardmäßig aktiviert.
user Die Variante soll die endgültige Version sein.
  • Installiert Module mit dem Tag user .
  • Installiert Module gemäß den Produktdefinitionsdateien zusätzlich zu getaggten Modulen.
  • ro.secure=1
  • ro.debuggable=0
  • adb ist standardmäßig deaktiviert.
userdebug Das Gleiche wie user , mit diesen Ausnahmen:
  • Installiert auch mit debug markierte Module.
  • ro.debuggable=1
  • adb ist standardmäßig aktiviert.

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 zu dex2oat 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:

  1. 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.
  2. Erstellen Sie ein device.mk Makefile, das die für das Gerät benötigten Dateien und Module deklariert. Ein Beispiel finden Sie unter device/google/marlin/device-marlin.mk .
  3. 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 Dateien device/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.

  4. 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 aus device/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
    
  5. Erstellen Sie ein BoardConfig.mk Makefile, das platinenspezifische Konfigurationen enthält. Ein Beispiel finden Sie unter device/google/marlin/BoardConfig.mk .
  6. 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
    
  7. 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 verschiedene 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 Variablen PRODUCT_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.

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 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 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:

  1. Generieren Sie ein Schlüsselpaar mit adb keygen . Für Google-Geräte generiert Google für jede neue Betriebssystemversion ein neues Schlüsselpaar.
  2. Checken Sie die Schlüsselpaare irgendwo im Quellbaum ein. Google speichert sie beispielsweise in vendor/google/security/adb/ .
  3. 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 eine Android.mk Datei mit der Aufschrift PRODUCT_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.