Song-Build-System

Vor der Veröffentlichung von Android 7.0 verwendete Android ausschließlich GNU Make , um seine Build-Regeln zu beschreiben und auszuführen. Das Make-Build-System wird weitgehend unterstützt und verwendet, wurde aber in der Größenordnung von Android langsam, fehleranfällig, nicht skalierbar und schwer zu testen. Das Soong-Build-System bietet die für Android-Builds erforderliche Flexibilität.

Aus diesem Grund wird von Plattformentwicklern erwartet, dass sie so schnell wie möglich von Make wechseln und Soong übernehmen. Senden Sie Fragen an die Android-Building Google Group, um Unterstützung zu erhalten.

Was ist Song?

Das Soong-Build-System wurde in Android 7.0 (Nougat) eingeführt, um Make zu ersetzen. Es nutzt das Kati GNU Make Clone-Tool und die Ninja -Build-Systemkomponente, um Builds von Android zu beschleunigen.

Siehe die Android Make Build System- Beschreibung im Android Open Source Project (AOSP) für allgemeine Anweisungen und Build System Changes for Android.mk Writers , um mehr über Änderungen zu erfahren, die für die Anpassung von Make an Soong erforderlich sind.

Siehe die Build-bezogenen Einträge im Glossar für Definitionen von Schlüsselbegriffen und die Soong-Referenzdateien für vollständige Details.

Machen Sie einen Soong-Vergleich

Hier ist ein Vergleich der Make-Konfiguration mit Soong, der dasselbe in einer Soong-Konfigurationsdatei (Blueprint oder .bp ) erreicht.

Beispiel machen

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := libxmlrpc++
LOCAL_MODULE_HOST_OS := linux

LOCAL_RTTI_FLAG := -frtti
LOCAL_CPPFLAGS := -Wall -Werror -fexceptions
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/src

LOCAL_SRC_FILES := $(call \
     all-cpp-files-under,src)
include $(BUILD_SHARED_LIBRARY)

Kurzes Beispiel

cc_library_shared {
     name: “libxmlrpc++”,

     rtti: true,
     cppflags: [
           “-Wall”,
           “-Werror”,
           “-fexceptions”,
     ],
     export_include_dirs: [“src”],
     srcs: [“src/**/*.cpp”],

     target: {
           darwin: {
                enabled: false,
           },
     },
}

Siehe Simple Build Configuration für testspezifische Song-Konfigurationsbeispiele.

Android.bp-Dateiformat

Android.bp Dateien sind von Natur aus einfach. Sie enthalten keine Bedingungen oder Ablaufsteuerungsanweisungen; Die gesamte Komplexität wird durch die in Go geschriebene Build-Logik gehandhabt. Wenn möglich, ähneln Syntax und Semantik von Android.bp Dateien denen von Bazel BUILD-Dateien .

Module

Ein Modul in einer Android.bp -Datei beginnt mit einem Modultyp, gefolgt von einer Reihe von Eigenschaften im name: "value", Format:

cc_binary {
    name: "gzip",
    srcs: ["src/test/minigzip.c"],
    shared_libs: ["libz"],
    stl: "none",
}

Jedes Modul muss über eine name verfügen, und der Wert muss in allen Android.bp Dateien eindeutig sein, mit Ausnahme der name in Namespaces und vorgefertigten Modulen, die sich wiederholen können.

Die Eigenschaft srcs gibt die zum Erstellen des Moduls verwendeten Quelldateien als Liste von Zeichenfolgen an. Sie können auf die Ausgabe anderer Module verweisen, die Quelldateien erzeugen, wie genrule oder filegroup , indem Sie die Modulreferenzsyntax ":<module-name>" .

Eine Liste gültiger Modultypen und ihrer Eigenschaften finden Sie in der Soong Modules Reference .

Typen

Variablen und Eigenschaften sind stark typisiert, wobei Variablen dynamisch auf der ersten Zuweisung basieren und Eigenschaften statisch durch den Modultyp festgelegt werden. Die unterstützten Typen sind:

  • Boolesche Werte ( true oder false )
  • Ganzzahlen ( int )
  • Zeichenfolgen ( "string" )
  • Listen von Strings ( ["string1", "string2"] )
  • Karten ( {key1: "value1", key2: ["value2"]} )

Maps können Werte jeden Typs enthalten, einschließlich verschachtelter Maps. Listen und Maps können nach dem letzten Wert Kommas haben.

Kugeln

Eigenschaften, die eine Liste von Dateien annehmen, wie z. B. srcs , können auch Glob-Muster annehmen. Glob-Muster können den normalen UNIX-Platzhalter * enthalten, zum Beispiel *.java . Glob-Muster können auch einen einzelnen Platzhalter ** als Pfadelement enthalten, der mit null oder mehr Pfadelementen übereinstimmt. Beispiel: java/**/*.java stimmt mit den Mustern java/Main.java und java/com/android/Main.java .

Variablen

Eine Android.bp -Datei kann Variablenzuweisungen der obersten Ebene enthalten:

gzip_srcs = ["src/test/minigzip.c"],
cc_binary {
    name: "gzip",
    srcs: gzip_srcs,
    shared_libs: ["libz"],
    stl: "none",
}

Variablen gelten für den Rest der Datei, in der sie deklariert sind, sowie für alle untergeordneten Blueprint-Dateien. Variablen sind mit einer Ausnahme unveränderlich: Sie können mit einer += -Zuweisung angehängt werden, aber nur, bevor sie referenziert wurden.

Bemerkungen

Android.bp -Dateien können mehrzeilige Kommentare im C-Stil /* */ und einzeilige // Kommentare im C++-Stil enthalten.

Betreiber

Strings, Listen von Strings und Maps können mit dem +-Operator angehängt werden. Ganze Zahlen können mit dem + -Operator summiert werden. Das Anhängen einer Map erzeugt die Vereinigung der Schlüssel in beiden Maps, wobei die Werte aller Schlüssel angehängt werden, die in beiden Maps vorhanden sind.

Bedingungen

Soong unterstützt keine Bedingungen in Android.bp Dateien. Stattdessen werden Komplexitäten in Build-Regeln, die Bedingungen erfordern würden, in Go gehandhabt, wo High-Level-Sprachfunktionen verwendet werden können und durch Bedingungen eingeführte implizite Abhängigkeiten nachverfolgt werden können. Die meisten Bedingungen werden in eine Zuordnungseigenschaft konvertiert, wobei einer der Werte in der Zuordnung ausgewählt und an die Eigenschaften der obersten Ebene angehängt wird.

Um beispielsweise architekturspezifische Dateien zu unterstützen:

cc_library {
    ...
    srcs: ["generic.cpp"],
    arch: {
        arm: {
            srcs: ["arm.cpp"],
        },
        x86: {
            srcs: ["x86.cpp"],
        },
    },
}

Formatierer

Soong enthält einen kanonischen Formatierer für Blueprint-Dateien, ähnlich wie gofmt . Führen Sie Folgendes aus, um alle Android.bp Dateien im aktuellen Verzeichnis rekursiv neu zu formatieren:

bpfmt -w .

Das kanonische Format umfasst Einrückungen mit vier Leerzeichen, neue Zeilen nach jedem Element einer Liste mit mehreren Elementen und ein nachgestelltes Komma in Listen und Karten.

Sondermodule

Einige spezielle Modulgruppen haben einzigartige Eigenschaften.

Standardmodule

Ein Standardmodul kann verwendet werden, um dieselben Eigenschaften in mehreren Modulen zu wiederholen. Beispielsweise:

cc_defaults {
    name: "gzip_defaults",
    shared_libs: ["libz"],
    stl: "none",
}

cc_binary {
    name: "gzip",
    defaults: ["gzip_defaults"],
    srcs: ["src/test/minigzip.c"],
}

Vorgefertigte Module

Bei einigen vorgefertigten Modultypen kann ein Modul denselben Namen wie seine quellbasierten Gegenstücke haben. Beispielsweise kann es eine cc_prebuilt_binary mit dem Namen foo geben, wenn es bereits eine cc_binary mit demselben Namen gibt. Dies gibt Entwicklern die Flexibilität zu wählen, welche Version sie in ihr Endprodukt aufnehmen möchten. Wenn eine Build-Konfiguration beide Versionen enthält, bestimmt der Wert des prefer -Flags in der vordefinierten Moduldefinition, welche Version Priorität hat. Beachten Sie, dass einige vorgefertigte Module Namen haben, die nicht mit prebuilt beginnen, wie z. B. android_app_import .

Namespace-Module

Bis Android vollständig von Make zu Soong konvertiert ist, muss die Make-Produktkonfiguration einen PRODUCT_SOONG_NAMESPACES Wert angeben. Sein Wert sollte eine durch Leerzeichen getrennte Liste von Namespaces sein, die Soong nach Make exportiert, damit sie vom m -Befehl erstellt werden. Nachdem die Umstellung von Android auf Soong abgeschlossen ist, können sich die Details zum Aktivieren von Namespaces ändern.

Soong bietet Modulen in verschiedenen Verzeichnissen die Möglichkeit, denselben Namen anzugeben, solange jedes Modul in einem separaten Namensraum deklariert wird. Ein Namensraum kann wie folgt deklariert werden:

soong_namespace {
    imports: ["path/to/otherNamespace1", "path/to/otherNamespace2"],
}

Beachten Sie, dass ein Namensraum keine Namenseigenschaft hat; sein Pfad wird automatisch als Name zugewiesen.

Jedem Soong-Modul wird basierend auf seiner Position im Baum ein Namespace zugewiesen. Es wird davon ausgegangen, dass sich jedes Soong-Modul in dem Namespace befindet, der durch den soong_namespace definiert ist, der in einer Android.bp -Datei im aktuellen Verzeichnis oder dem nächstgelegenen Vorfahrenverzeichnis gefunden wird. Wenn kein solches soong_namespace -Modul gefunden wird, wird davon ausgegangen, dass sich das Modul im impliziten Root-Namensraum befindet.

Hier ist ein Beispiel: Soong versucht, die Abhängigkeit D aufzulösen, die von Modul M im Namensraum N deklariert wurde, der die Namensräume I1, I2, I3 importiert…

  1. Wenn D ein vollständig qualifizierter Name der Form //namespace:module ist, wird nur der angegebene Namespace nach dem angegebenen Modulnamen durchsucht.
  2. Andernfalls sucht Soong zuerst nach einem Modul namens D, das im Namespace N deklariert ist.
  3. Wenn dieses Modul nicht existiert, sucht Soong nach einem Modul namens D in den Namespaces I1, I2, I3…
  4. Zuletzt sucht Soong im Root-Namespace nach.