Google si impegna a promuovere l'equità razziale per le comunità nere. Vedi come.
Questa pagina è stata tradotta dall'API Cloud Translation.
Switch to English

Soong Build System

Prima della versione di Android 7.0, Android utilizzava GNU Make esclusivamente per descrivere ed eseguire le sue regole di costruzione. Il sistema Make build è ampiamente supportato e utilizzato, ma su scala Android è diventato lento, soggetto a errori, non scalabile e difficile da testare. Il sistema di compilazione Soong offre la flessibilità necessaria per le build Android.

Per questo motivo, gli sviluppatori di piattaforme dovrebbero passare da Make e adottare Soong il prima possibile. Invia domande al gruppo Google che costruisce Android per ricevere assistenza.

Che cos'è Soong?

Il sistema di compilazione Soong è stato introdotto in Android 7.0 (Nougat) per sostituire Make. Sfrutta lo strumento clone di Kati GNU Make e il componente del sistema di build Ninja per accelerare le build di Android.

Vedi la descrizione del sistema Android Build Build nel progetto Android Open Source (AOSP) per istruzioni generali e modifiche del sistema Build per i writer Android.mk per conoscere le modifiche necessarie per adattarsi da Make to Soong.

Vedere le voci relative alla build nel glossario per le definizioni dei termini chiave e i file di riferimento Soong per i dettagli completi.

Confronto tra Make e Soong

Ecco un confronto tra Crea configurazione con Soong ottenendo lo stesso in un file di configurazione Soong (Blueprint o .bp ).

Fai un 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)
 

Presto esempio

 cc_library_shared {
     name: “libxmlrpc++”,

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

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

Vedi Simple Build Configuration per esempi di configurazione Soong specifici del test.

Formato file Android.bp

In base alla progettazione, i file Android.bp 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 dei file Android.bp sono simili ai file BUILD di Bazel .

moduli

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

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

Ogni modulo deve avere una proprietà name e il valore deve essere univoco in tutti i file Android.bp , ad eccezione dei valori delle proprietà name negli spazi dei nomi e nei moduli predefiniti, che possono essere ripetuti.

La proprietà srcs specifica i file di origine utilizzati per srcs il modulo, come un elenco di stringhe. È possibile fare riferimento all'output 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 delle relative proprietà, consultare il riferimento ai moduli Soong .

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 )
  • Numeri interi ( int )
  • Stringhe ( "string" )
  • Elenchi 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 contenere virgole finali dopo l'ultimo valore.

globs

Le proprietà che accettano un elenco di file, come srcs , possono anche accettare modelli glob. I pattern globali possono contenere il normale jolly UNIX * , ad esempio *.java . I pattern glob possono anche contenere un singolo carattere jolly ** come elemento path, che corrisponde a zero o più elementi path. Ad esempio, java/**/*.java corrisponde a entrambi i java/Main.java e java/com/android/Main.java .

variabili

Un file Android.bp può contenere assegnazioni di variabili di livello superiore:

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

Le variabili hanno l'ambito per il resto del file in cui sono dichiarate, così come tutti i file Blueprint figlio. Le variabili sono immutabili con una sola eccezione: possono essere aggiunte con un'assegnazione += , ma solo prima che siano state referenziate.

Commenti

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

operatori

Stringhe, elenchi di stringhe e mappe possono essere aggiunti utilizzando l'operatore +. I numeri interi possono essere riassunti usando l'operatore + . L'aggiunta di una mappa produce l'unione di chiavi in ​​entrambe le mappe, aggiungendo i valori di tutte le chiavi presenti in entrambe le mappe.

Condizionali

Soong non supporta i condizionali nei file Android.bp . Invece, la complessità delle regole di compilazione che richiederebbero i condizionali viene gestita in Go, dove è possibile utilizzare funzionalità di linguaggio di alto livello e tenere traccia delle dipendenze implicite introdotte dai condizionali. 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 livello superiore.

Ad esempio, per supportare file specifici dell'architettura:

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

formatter

Soong include un formattatore canonico per i file Blueprint, simile a gofmt . Per riformattare in modo ricorsivo tutti i file Android.bp nella directory corrente, eseguire:

 bpfmt -w .
 

Il formato canonico include rientri di quattro spazi, nuove righe dopo ogni elemento di un elenco multielemento e una virgola finale in elenchi e 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 precompilati

Alcuni tipi di moduli predefiniti consentono a un modulo di avere lo stesso nome delle sue controparti basate sull'origine. Ad esempio, può esserci un cc_prebuilt_binary chiamato foo quando c'è già un cc_binary con lo stesso nome. Ciò offre agli sviluppatori la flessibilità di scegliere quale versione includere nel loro prodotto finale. Se una configurazione build contiene entrambe le versioni, il valore flag prefer nella definizione del modulo precompilato determina quale versione ha la priorità. Nota che alcuni moduli predefiniti hanno nomi che non iniziano con quelli prebuilt , come android_app_import .

Moduli dello spazio dei nomi

Fino a quando Android non si converte completamente da Make a Soong, la configurazione del prodotto Make deve specificare un valore PRODUCT_SOONG_NAMESPACES . Il suo valore dovrebbe essere un elenco separato da spazi di spazi dei nomi che Soong esporta in Make per essere creato dal comando m . Al termine della conversione di Android in Soong, i dettagli dell'abilitazione degli spazi dei nomi potrebbero cambiare.

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

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

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

A ciascun modulo Soong viene assegnato uno spazio dei nomi in base alla sua posizione nella struttura. Ogni modulo Soong è considerato nello spazio dei nomi definito dallo spazio dei nomi soong_namespace trovato in un file Android.bp nella directory corrente o nella directory degli antenati più vicina. Se non viene trovato tale modulo soong_namespace , il modulo viene considerato nello spazio dei nomi radice implicito.

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

  1. Quindi se D è un nome completo del form //namespace:module , viene cercato solo il namespace specificato per il nome del modulo specificato.
  2. Altrimenti, Soong prima cerca 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 guarda nello spazio dei nomi di root.