Convertir de Make en Soong

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

Pour cette raison, les développeurs de plates-formes doivent passer de "Make" à "Soong" dès que possible. Envoyez vos questions au groupe Google android-building pour obtenir de l'aide.

Qu'est-ce que Soong ?

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

Consultez la description Android Make Build System dans le projet Android Open Source (AOSP) pour obtenir des instructions générales et consultez la section Build System Changes for Android.mk Writers (Modifier le système de compilation pour les rédacteurs Android.mk) pour en savoir plus sur les modifications nécessaires pour passer de Make à Soong.

Pour connaître la définition des termes clés, consultez les entrées liées à la compilation dans le glossaire, et les fichiers de référence Soong pour en savoir plus.

Comparaison entre Make et Soong

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

Créer 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 Soong

cc_library_shared {
     name: "libxmlrpc++",

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

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

Pour obtenir des exemples de configuration Soong spécifiques aux tests, consultez la section Simple Build Configuration (Configuration de compilation simple).

Pour en savoir plus sur les champs d'un fichier Android.bp, consultez la section Format de fichier Android.bp.

Modules spéciaux

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

Modules par défaut

Un module de valeurs par défaut permet de répéter les mêmes propriétés dans plusieurs modules. 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édéfinis

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'un cc_binary du même nom existe déjà. Les développeurs peuvent ainsi choisir la version à inclure dans leur produit final. Si une configuration de compilation contient les deux versions, la valeur de l'indicateur prefer dans la définition du module précompilé détermine la version prioritaire. Notez que certains modules prédéfinis ont des noms qui ne commencent pas par prebuilt, tels que android_app_import.

Modules d'espace de noms

Tant qu'Android ne passe pas 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 un espace que Soong exporte vers Make pour être compilée par la commande m. Une fois la conversion d'Android en Soong terminée, les détails de l'activation des espaces de noms peuvent 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 suit:

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

Notez qu'un espace de noms ne possède pas de propriété de nom. Son chemin d'accès est automatiquement attribué comme nom.

Un espace de noms est attribué à chaque module Soong en fonction de son emplacement dans l'arborescence. Chaque module Soong est considéré comme appartenant à 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 parent le plus proche. Si aucun tel module soong_namespace n'est trouvé, le module est considéré comme appartenant à 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, etc.

  1. Si D est un nom complet au format //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, etc.
  4. Enfin, Soong examine l'espace de noms racine.