Soong Build System

Prima del rilascio di Android 7.0, Android utilizzato GNU make esclusivamente per descrivere ed eseguire le sue regole di compilazione. Il sistema di compilazione Make è ampiamente supportato e utilizzato, ma su scala Android è diventato lento, soggetto a errori, non scalabile e difficile da testare. Il sistema di compilazione Soong fornisce la flessibilità necessaria per Android costruisce.

Per questo motivo, ci si aspetta che gli sviluppatori della piattaforma passino da Make e adottino Soong il prima possibile. Invia le domande al Android-building gruppo Google per ricevere assistenza.

Cos'è Soong?

Il sistema di compilazione Soong è stato introdotto in Android 7.0 (Torrone) per sostituire Marchio. Essa sfrutta la Kati GNU strumento Crea clone e Ninja componente sistema di generazione per accelerare la build di Android.

Vedere l' Android make build del sistema descrizione nel progetto Open Source Android (AOSP) per generali istruzioni e costruire le modifiche di sistema per Android.mk scrittori per conoscere le modifiche necessarie per l'adeguamento da Fare a Soong.

Vedi le voci di build-correlata nel glossario per le definizioni dei termini chiave e le file di riferimento Soong per i dettagli completi.

Confronto Make and Soon

Ecco un confronto di configurazione fanno con Soong compiere lo stesso in una configurazione Soong (Blueprint o .bp file).

Fai l'esempio

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)

Un breve esempio

cc_library_shared {
     name: “libxmlrpc++”,

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

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

Vedere configurazione di generazione semplice per gli esempi di configurazione di test specifici Soong.

Formato file Android.bp

In base alla progettazione, Android.bp file sono semplici. Non contengono condizionali o istruzioni di flusso di controllo; tutta la complessità è gestita dalla logica di compilazione scritta in Go. Quando possibile, la sintassi e la semantica del Android.bp file sono simili ai file di generazione Bazel .

Moduli

Un modulo in un Android.bp file inizia con un tipo di modulo seguito da una serie di immobili a name: "value", formato:

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

Ogni modulo deve avere un name di proprietà, e il valore deve essere univoco in tutti i Android.bp file, tranne che per i name dei valori di proprietà in namespace e moduli predefiniti, che possono ripetere.

I srcs proprietà specifica il file di origine utilizzati per creare il modulo, come una lista di stringhe. È possibile fare riferimento l'uscita di altri moduli che producono file di origine, come genrule o filegroup , utilizzando la sintassi di riferimento del modulo ":<module-name>" .

Per un elenco dei tipi di moduli validi e le loro proprietà, vedere la Soong moduli di riferimento .

tipi

Le variabili e le proprietà sono fortemente tipizzate, con variabili basate dinamicamente sulla prima assegnazione e proprietà impostate staticamente dal tipo di modulo. I tipi supportati sono:

  • Booleani ( true o false )
  • I numeri interi ( int )
  • Strings ( "string" )
  • Liste di stringhe ( ["string1", "string2"] )
  • Mappe ( {key1: "value1", key2: ["value2"]} )

Le mappe possono contenere valori di qualsiasi tipo, comprese le mappe nidificate. Gli elenchi e le mappe possono avere virgole finali dopo l'ultimo valore.

globi

Le proprietà che assumono un elenco di file, come ad esempio srcs , possono anche prendere modelli glob. Modelli di glob possono contenere il normale UNIX jolly * , ad esempio *.java . Modelli glob possono anche contenere un singolo ** jolly come elemento del percorso, che corrisponde a zero o più elementi di percorso. Ad esempio, java/**/*.java corrisponde sia il java/Main.java e java/com/android/Main.java modelli.

Variabili

Un Android.bp file può contenere le assegnazioni delle variabili di primo livello:

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

Le variabili hanno come ambito il resto del file in cui sono dichiarate, così come qualsiasi file Blueprint figlio. Le variabili sono immutabili con una sola eccezione: possono essere aggiunti con un += assegnazione, ma solo prima che sono stati referenziati.

Commenti

Android.bp file possono contenere in stile C multilinea /* */ a linea singola e in stile C ++ // commenti.

operatori

È possibile aggiungere stringhe, elenchi di stringhe e mappe utilizzando l'operatore +. I numeri interi possono essere sintetizzati utilizzando il + operatore. L'aggiunta di una mappa produce l'unione delle chiavi in ​​entrambe le mappe, aggiungendo i valori di tutte le chiavi presenti in entrambe le mappe.

Condizionali

Soong non supporta condizionali in Android.bp file. Invece, la complessità nelle regole di compilazione che richiederebbero i condizionali viene gestita in Go, dove è possibile usare le funzionalità del linguaggio di alto livello e le dipendenze implicite introdotte dai condizionali possono essere monitorate. La maggior parte dei condizionali viene convertita in una proprietà della mappa, in cui uno dei valori nella mappa viene selezionato e aggiunto alle proprietà di primo livello.

Ad esempio, per supportare file specifici dell'architettura:

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

formattatore

Soong include un formattatore canonica per i file Blueprint, simili a gofmt . Per ricorsivamente riformattare tutti Android.bp i file nella directory corrente, eseguire:

bpfmt -w .

Il formato canonico include rientri di quattro spazi, nuove righe dopo ogni elemento di un elenco a più elementi e una virgola finale negli elenchi e nelle mappe.

Moduli speciali

Alcuni gruppi di moduli speciali hanno caratteristiche uniche.

Moduli predefiniti

Un modulo predefinito può essere utilizzato per ripetere le stesse proprietà in più moduli. Per esempio:

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

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

Moduli precostruiti

Alcuni tipi di moduli predefiniti consentono a un modulo di avere lo stesso nome delle sue controparti basate sul codice sorgente. Per esempio, ci può essere una cc_prebuilt_binary di nome foo quando c'è già un cc_binary con lo stesso nome. Ciò offre agli sviluppatori la flessibilità di scegliere quale versione includere nel prodotto finale. Se una configurazione build contiene entrambe le versioni, il prefer valore del flag nei dettami di definizione dei moduli precompilati quale versione ha la priorità. Si noti che alcuni moduli predefiniti hanno nomi che non iniziano con prebuilt , come android_app_import .

Moduli dello spazio dei nomi

Fino Android converte pienamente Fare a Soong, la configurazione del prodotto rende necessario specificare un PRODUCT_SOONG_NAMESPACES valore. Il suo valore dovrebbe essere un elenco separato da spazi di spazi dei nomi che le esportazioni di Soong di farsi costruito dal m comando. Una volta completata la conversione di Android in Soong, i dettagli sull'abilitazione degli spazi dei nomi potrebbero cambiare.

Soong offre la possibilità ai moduli in directory diverse di specificare lo stesso nome, purché ogni modulo sia dichiarato all'interno di uno spazio dei nomi separato. Uno spazio dei nomi può essere dichiarato in questo modo:

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

Nota che uno spazio dei nomi non ha una proprietà name; il suo percorso viene assegnato automaticamente come nome.

A ogni modulo Soong viene assegnato uno spazio dei nomi in base alla sua posizione nell'albero. Ogni modulo Soong è considerato nel namespace definito dal soong_namespace trovato in un Android.bp file nella directory corrente o la directory antenato più vicino. In assenza di tale soong_namespace viene trovato il modulo, il modulo è considerato nello spazio dei nomi radice implicita.

Ecco un esempio: Soong tenta di risolvere la dipendenza D dichiarata dal modulo M nello spazio dei nomi N che importa gli spazi dei nomi I1, I2, I3...

  1. Poi, se D è un nome completo del modulo //namespace:module , solo lo spazio dei nomi specificato viene cercato il nome del modulo specificato.
  2. Altrimenti, Soong cerca prima un modulo chiamato D dichiarato nello spazio dei nomi N.
  3. Se quel modulo non esiste, Soong cerca un modulo chiamato D negli spazi dei nomi I1, I2, I3...
  4. Infine, Soong cerca nello spazio dei nomi di root.