Neues Gerät hinzufügen

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.
  • Hiermit werden Module installiert, die mit eng oder debug getaggt sind.
  • Installiert zusätzlich zu getaggten Modulen Module gemäß den Produktdefinitionsdateien.
  • ro.secure=0
  • ro.debuggable=1
  • ro.kernel.android.checkjni=1
  • adb ist standardmäßig aktiviert.
user Die Variante, die die endgültigen Release-Bits enthalten soll.
  • Hiermit werden Module installiert, die mit user getaggt sind.
  • Installiert zusätzlich zu getaggten Modulen Module gemäß den Produktdefinitionsdateien.
  • ro.secure=1
  • ro.debuggable=0
  • adb ist standardmäßig deaktiviert.
userdebug Entspricht user mit folgenden Ausnahmen:
  • Es werden auch Module installiert, die mit debug getaggt sind.
  • ro.debuggable=1
  • adb ist standardmäßig aktiviert.

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

  1. 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.
  2. Erstellen Sie ein device.mk-Makefile, in dem die für das Gerät erforderlichen Dateien und Module deklariert werden. Ein Beispiel findest du unter device/google/marlin/device-marlin.mk.
  3. 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 Dateien device/google/marlin/device-marlin.mk und vendor/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.

  4. 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 aus device/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
    
  5. Erstellen Sie ein BoardConfig.mk-Makefile mit bordspezifischen Konfigurationen. Ein Beispiel findest du unter device/google/marlin/BoardConfig.mk.
  6. 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
    
  7. 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 Variablen PRODUCT_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.

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:

  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. Prüfen Sie die Schlüsselpaare irgendwo im Stammbaum der Quelle. 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. Dazu fügt Google im Schlüsselverzeichnis eine Android.mk-Datei mit dem Namen PRODUCT_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.