Google is committed to advancing racial equity for Black communities. See how.
Cette page a été traduite par l'API Cloud Translation.
Switch to English

Système de construction Soong

Avant la sortie d'Android 7.0, Android utilisait exclusivement GNU Make pour décrire et exécuter ses règles de construction. Le système de construction Make est largement pris en charge et utilisé, mais à l'échelle d'Android, il est devenu lent, sujet aux erreurs, non évolutif et difficile à tester. Le système de construction Soong offre la flexibilité requise pour les versions Android.

Pour cette raison, les développeurs de plates-formes devraient passer de Make et adopter Soong dès que possible. Envoyez des questions au groupe Google chargé de la création d' Android pour bénéficier d'une assistance.

Qu'est-ce que Soong?

Le système de construction Soong a été introduit dans Android 7.0 (Nougat) pour remplacer Make. Il exploite l'outil de clonage Kati GNU Make et le composant système de construction Ninja pour accélérer les versions d'Android.

Consultez la description du système Android Make Build dans le projet Android Open Source (AOSP) pour obtenir des instructions générales et des modifications du système de construction pour les rédacteurs Android.mk pour en savoir plus sur les modifications nécessaires pour s'adapter de Make à Soong.

Voir les entrées relatives à la construction dans le glossaire pour les définitions des termes clés et les fichiers de référence Soong pour des détails complets.

Comparaison Make et Soong

Voici une comparaison de la configuration de Make avec Soong accomplissant la même chose dans un fichier de configuration Soong (Blueprint ou .bp ).

Faire un exemple

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)

Exemple de Soong

cc_library_shared {
     name: “libxmlrpc++”,

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

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

Voir Configuration de construction simple pour des exemples de configuration Soong spécifiques au test.

Format de fichier Android.bp

De par leur conception, les fichiers Android.bp sont simples. Ils ne contiennent pas de conditions ou d'instructions de flux de contrôle; toute la complexité est gérée par la logique de construction écrite en Go. Lorsque cela est possible, la syntaxe et la sémantique des fichiers Android.bp sont similaires aux fichiers Bazel BUILD .

Modules

Un module dans un fichier Android.bp commence par un type de module suivi d'un ensemble de propriétés dans le name: "value", format:

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

Chaque module doit avoir une propriété de name et la valeur doit être unique dans tous les fichiers Android.bp , à l'exception des valeurs de propriété de name dans les espaces de noms et les modules prédéfinis, qui peuvent se répéter.

La propriété srcs spécifie les fichiers source utilisés pour créer le module, sous la forme d'une liste de chaînes. Vous pouvez faire référence à la sortie d'autres modules qui produisent des fichiers source, comme genrule ou filegroup de ":<module-name>" filegroup , en utilisant la syntaxe de référence du module ":<module-name>" .

Pour obtenir la liste des types de modules valides et leurs propriétés, consultez la référence des modules Soong .

Les types

Les variables et les propriétés sont fortement typées, avec des variables basées dynamiquement sur la première affectation et des propriétés définies statiquement par le type de module. Les types pris en charge sont:

  • Booléens ( true ou false )
  • Entiers ( int )
  • Chaînes ( "string" )
  • Listes de chaînes ( ["string1", "string2"] )
  • Cartes ( {key1: "value1", key2: ["value2"]} )

Les cartes peuvent contenir des valeurs de tout type, y compris des cartes imbriquées. Les listes et les cartes peuvent avoir des virgules après la dernière valeur.

Globs

Les propriétés qui prennent une liste de fichiers, tels que srcs , peuvent également prendre des modèles glob. Les modèles globaux peuvent contenir le caractère générique UNIX normal * , par exemple *.java . Les modèles globaux peuvent également contenir un seul caractère générique ** comme élément de chemin, qui correspond à zéro ou plusieurs éléments de chemin. Par exemple, java/**/*.java correspond aux java/Main.java et java/com/android/Main.java .

Variables

Un fichier Android.bp peut contenir des affectations de variables de niveau supérieur:

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

Les variables sont étendues au reste du fichier dans lequel elles sont déclarées, ainsi qu'à tous les fichiers Blueprint enfants. Les variables sont immuables à une exception près: elles peuvent être ajoutées avec une affectation += , mais seulement avant d'être référencées.

commentaires

Android.bp fichiers Android.bp peuvent contenir des commentaires sur une seule ligne // style C /* */ et C ++.

Les opérateurs

Les chaînes, les listes de chaînes et les cartes peuvent être ajoutées à l'aide de l'opérateur +. Les entiers peuvent être additionnés à l'aide de l'opérateur + . L'ajout d'une carte produit l'union des clés dans les deux cartes, en ajoutant les valeurs de toutes les clés présentes dans les deux cartes.

Conditionnels

Soong ne prend pas en charge les conditions dans les fichiers Android.bp . Au lieu de cela, la complexité des règles de construction qui nécessiteraient des conditions est gérée dans Go, où des fonctionnalités de langage de haut niveau peuvent être utilisées, et les dépendances implicites introduites par des conditions peuvent être suivies. La plupart des conditions sont converties en propriété de carte, où l'une des valeurs de la carte est sélectionnée et ajoutée aux propriétés de niveau supérieur.

Par exemple, pour prendre en charge les fichiers spécifiques à l'architecture:

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

Formateur

Soong inclut un formateur canonique pour les fichiers Blueprint, similaire à gofmt . Pour reformater de manière récursive tous les fichiers Android.bp dans le répertoire actuel, exécutez:

bpfmt -w .

Le format canonique comprend des retraits de quatre espaces, de nouvelles lignes après chaque élément d'une liste à plusieurs éléments et une virgule de fin dans les listes et les cartes.

Modules spéciaux

Certains groupes de modules spéciaux ont des caractéristiques uniques.

Modules par défaut

Un module par défaut peut être utilisé pour répéter les mêmes propriétés dans plusieurs modules. Par exemple:

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

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

Modules préconstruits

Certains types de modules prédéfinis permettent à un module d'avoir le même nom que ses homologues basés sur la source. Par exemple, il peut y avoir un cc_prebuilt_binary nommé foo alors qu'il y a déjà un cc_binary avec le même nom. Cela donne aux développeurs la possibilité de choisir la version à inclure dans leur produit final. Si une configuration de construction contient les deux versions, la valeur de l'indicateur de prefer dans la définition de module prédéfinie détermine la version qui a la priorité. Notez que certains modules prédéfinis ont des noms qui ne commencent pas par des modules prebuilt , tels que android_app_import .

Modules d'espace de noms

Jusqu'à ce qu'Android convertisse complètement de Make à Soong, la configuration du produit Make doit spécifier une valeur PRODUCT_SOONG_NAMESPACES . Sa valeur doit être une liste d'espaces de noms séparés par des espaces que Soong exporte vers Make pour être construits par la commande m . Une fois la conversion d'Android en Soong terminée, les détails de l'activation des espaces de noms pourraient changer.

Soong permet aux modules de différents répertoires de spécifier le même nom, à condition que chaque module soit déclaré dans un espace de noms distinct. Un espace de noms peut être déclaré comme ceci:

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

Notez qu'un espace de noms n'a pas de propriété de nom; son chemin est automatiquement assigné comme son nom.

Chaque module Soong se voit attribuer un espace de noms en fonction de son emplacement dans l'arborescence. Chaque module Soong est considéré comme se trouvant dans l'espace de noms défini par le soong_namespace trouvé dans un fichier Android.bp dans le répertoire actuel ou le répertoire de l'ancêtre le plus proche. Si aucun module soong_namespace n'est trouvé, le module est considéré comme étant dans l'espace de noms racine implicite.

Voici un exemple: Soong tente de résoudre la dépendance D déclarée par le module M dans l'espace de noms N qui importe les espaces de noms I1, I2, I3…

  1. Ensuite, si D est un nom complet de la forme //namespace:module , seul l'espace de noms spécifié est recherché pour le nom de module spécifié.
  2. Sinon, Soong recherche d'abord un module nommé D déclaré dans l'espace de noms N.
  3. Si ce module n'existe pas, Soong recherche un module nommé D dans les espaces de noms I1, I2, I3…
  4. Enfin, Soong regarde dans l'espace de noms racine.