URL: https://linuxfr.org/news/alire-le-package-manager-d-ada Title: Alire, le package manager d'Ada Authors: Blackknight Xavier Teyssier, Pierre Jarillon, Benoît Sibaud et Ysabeau Date: 2022-05-26T17:36:47+02:00 License: CC By-SA Tags: ada Score: 3 Dans [un précédent journal](https://linuxfr.org/users/blackknight/journaux/retour-sur-une-annee-d-apprentissage-d-ada-par-un-dev-c), il m’a été demandé de présenter [Alire](https://alire.ada.dev/) sous la forme [d’une dépêche](https://linuxfr.org/users/blackknight/journaux/retour-sur-une-annee-d-apprentissage-d-ada-par-un-dev-c#comment-1887855). Voilà, j’ai fini par prendre le temps et j’ai choisi la façon de le présenter. Je vous propose donc une sorte de pas-à-pas plutôt qu’une explication un peu brutale Le but ====== Nous allons donc créer des _crates Alire_ (les Rustistes auront reconnu le terme). J’ai bien dit _des_ car cela va permettre de voir les deux types, _lib_ ou _bin_ que l’on peut créer. Le projet ===== Le but n’étant pas d’écrire du code Ada, on va prendre un de mes projets préférés qui n’a, au moment de l’écriture de ces lignes, pas de _crate_ associée. J’ai nommé le [_Corporate Bullshit Generator_](http://cbsg.sf.net/), logiciel ô combien indispensable, source inépuisable d’études en scalabilité ([autopromotion](https://archive.fosdem.org/2019/schedule/event/ada_distribution/)). Ce magnifique projet est l’œuvre de Gautier de Montmollin qui produit aussi des choses beaucoup plus sérieuses comme [Zip-Ada](https://unzip-ada.sourceforge.io/), une _lib_ pour gérer les archives zip, [Ada PDF Writer](https://apdf.sourceforge.io/) ou [HAC](https://hacadacompiler.sourceforge.io/), un compilateur Ada partiel. Évidemment, tout est codé en pur Ada. Bon assez causé, on y va direct car c’est NOTRE PROJEEEEETTTT :) ---- [Alire](https://alire.ada.dev) [Releases d'Alire](https://github.com/alire-project/alire/releases) [Corporate bullshit Generator Live](http://cbsg.sf.net/) [La liste des crates](https://alire.ada.dev/crates.html) ---- C’est parti avec les prérequis ===== Installation d’Alire ----------- Je ne vais pas paraphraser totalement [la doc](https://alire.ada.dev/docs/#installation) mais il vous faut installer un compilateur Ada sur votre distribution, histoire d’avoir les bibliothèques du langage dans votre système. Ensuite, on télécharge le binaire et on le met dans son _PATH_ pour être tranquille. Les courageux pourront construire à partir des sources. Premiers pas ------- Là, encore, je vais faire plus court que [la doc officielle](https://alire.ada.dev/docs/#first-steps). On va juste vérifier que notre installation fonctionne bien. ``` fred@tatooine:~/Dev/Ada$ alr get hello ⓘ Deploying release hello=1.0.1... -=O=- # # # # ⓘ Deploying release libhello=1.0.0... ############################################################################################################################################################ 100,0% hello=1.0.1 successfully retrieved. Dependencies were solved as follows: + libhello 1.0.0 (new) ``` On va ensuite dans le répertoire créé (aujourd’hui, _hello_1.0.1_dcc36a2f_) et on exécute : ``` fred@tatooine:~/Dev/Ada$ alr run Welcome to the toolchain selection assistant In this assistant you can set up the default toolchain to be used with any crate that does not specify its own top-level dependency on a version of gnat or gprbuild. If you choose "None", Alire will use whatever version is found in the environment. ⓘ gnat is currently not configured. (alr will use the version found in the environment.) Please select the gnat version for use with this configuration 1. gnat_native=11.2.4 2. None 3. gnat_external=2021.0.0 [Detected at /opt/gnat/2021/bin/gnat] 4. gnat_arm_elf=11.2.4 5. gnat_avr_elf=11.2.4 6. gnat_riscv64_elf=11.2.4 7. gnat_arm_elf=11.2.3 8. gnat_native=11.2.3 9. gnat_riscv64_elf=11.2.3 0. gnat_arm_elf=11.2.2 a. (See more choices...) Enter your choice index (first is default): > 3 ⓘ Selected tool version gnat_external=2021.0.0 ⓘ Choices for the following tool are narrowed down to releases compatible with just selected gnat_external=2021.0.0 ⓘ gprbuild is currently not configured. (alr will use the version found in the environment.) Please select the gprbuild version for use with this configuration 1. gprbuild=2021.0.0 [Detected at /opt/gnat/2021/bin/gprbuild] 2. None Enter your choice index (first is default): > 1 ⓘ Selected tool version gprbuild=2021.0.0 Setup [mkdir] object directory for project Libhello [mkdir] library directory for project Libhello [mkdir] object directory for project Hello Compile [Ada] hello.adb [Ada] libhello.adb Build Libraries [gprlib] hello.lexch [archive] libhello.a [index] libhello.a Bind [gprbind] hello.bexch [Ada] hello.ali Link [link] hello.adb Hello, world! ``` Mais alors, il s’est passé quoi ? Normalement, si c’est votre première installation, comme ci-dessus, _Alire_ va vous demander de choisir votre _toolchain_ en fonction de ce qui se trouve dans votre système. Personnellement, j’ai, entre autres, la version 2021 du compilateur fourni par Adacore dans _/opt/gnat_. Ensuite, le binaire n’étant pas encore créé, on passe par un _build_ puis une exécution. Qu’on se rassure, le processus de choix de la _toolchain_ ne se fait qu’une fois, mais il est possible de changer en cours de route via les commandes _alr toolchain_. De manière générale, à l’instar de beaucoup d’autres outils, on peut utiliser l’aide en ligne via _alr help_ comme _alr help toolchain_. Maintenant que l’on voit que cela fonctionne, on passe aux choses sérieuses. Récupération du code du CBSG sur SF ---- Le code du _Corporate Bullshit Generator_ (_CBSG_ pour les intimes) est disponible sur Sourceforge et possède un miroir sur Github On récupère soit via ``` svn checkout https://svn.code.sf.net/p/cbsg/code/ cbsg-code ``` soit via ``` git clone https://github.com/zertovitch/cbsg.git cbsg-code ``` L’un ou l’autre ne pose aucun problème, cela ne servira qu’à piocher dans le code source. Préparons maintenant notre première _crate_, une _lib_. Notre première crate, une bibliothèque ===== On commence par créer un patron de _crate_ ``` fred@tatooine:~/Dev/Ada$ alr init --lib cbsg ``` Cela donne la hiérarchie suivante: ``` cbsg ├── alire.toml ├── cbsg.gpr ├── config │   ├── cbsg_config.ads │   ├── cbsg_config.gpr │   └── cbsg_config.h └── src └── cbsg.ads ``` Quand on analyse le code du _Corporate Bullshit Generator_, on voit qu’un package fournit la fonctionnalité que l’on veut exposer. En effet, _corporate_bullshit_ est le package générique donnant les fonctions retournant les phrases tant attendues. ```ada generic Paragraph_Mark : String; Paragraph_End_Mark : String; Dialog_Mark : String; package Corporate_Bullshit is function Sentence return String; function Workshop return String; function Short_Workshop return String; function Short_Meeting return String; function Financial_Report return String; end Corporate_Bullshit; ``` On incorporera donc le fichier de spécification _corporate_bullshit.ads_ ainsi que le corps du package, _corporate_bullshit.adb_. Il manque encore une chose. En regardant le début du fichier _corporate_bullshit.adb_, on voit deux packages en inclusion, _Ada.Characters.Handling_ et _Delirium_. ```ada with Ada.Characters.Handling; use Ada.Characters.Handling; with Delirium; use Delirium; ``` [Ada.Characters.Handling](http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-A-3-2.html) est un package standard Ada permettant la transformation majuscule/minuscule, les tests d’appartenance d’un caractère à une classe (alphanumérique, numérique…) entre autres choses. Delirium est un package du _CBSG_. D’après les commentaires, il permet de gérer la grammaire des phrases générées. Ce n’est pas le plus clair des codes que j’ai vu mais ça fonctionne et comme on ne s’en sert pas directement… Par contre, cela veut dire qu’il doit faire partie de notre _lib_. On copie donc les fichiers ad[sb] de _delirium_ et _corporate_bullshit_. Finalement, le fichier généré _cbsg.ads_ ne nous servant pas, on le retire. Au final, on obtient cela : ``` cbsg ├── alire.toml ├── cbsg.gpr ├── config │   ├── cbsg_config.ads │   ├── cbsg_config.gpr │   └── cbsg_config.h └── src ├── corporate_bullshit.adb ├── corporate_bullshit.ads ├── delirium.adb └── delirium.ads ``` On vérifie que tout se passe bien avec un petit _alr build_ dans le répertoire ``` Setup [mkdir] object directory for project Cbsg [mkdir] library directory for project Cbsg Compile [Ada] delirium.adb [Ada] corporate_bullshit.adb Build Libraries [gprlib] Cbsg.lexch [archive] libCbsg.a [index] libCbsg.a ``` Pour tester tout ça, on va passer à la deuxième partie, la _crate_ d’exemples. Création d’un crate d’exemples === Maintenant que notre bibliothèque est prête, nous allons créer une _crate_ avec un exemple simple. Cette fois-ci, on utilisera la commande dans un répertoire au même niveau que le répertoire _cbsg_. Cela n’a rien d’obligatoire au final mais là, ce sera plus facile mais stop au suspense, on embraye. ``` fred@tatooine:~/Dev/Ada$ alr init --bin cbsg_examples ``` Cela donne la hiérarchie suivante: ``` cbsg_examples ├── alire │   └── alire.lock ├── alire.toml ├── cbsg_examples.gpr ├── config │   └── cbsg_examples_config.gpr └── src └── cbsg_examples.adb ``` Pour exemple, nous prendrons le plus simple qui soit dans le code du _CBSG_, _produce_corporate_bullshit.adb_. On copie donc ce fichier dans le répertoire _src_. Le fichier _cbsg_examples.adb_ ne nous sert pas, on le retire… Sauf que le projet s’attend à ce que l’exécutable de notre _crate_ soit _cbsg_examples_. Cela étant déclaré dans le fichier _cbsg_examples.gpr_, on modifie cela. Ce fichier est un fichier au format [GPRBuild](https://docs.adacore.com/gprbuild-docs/html/gprbuild_ug.html). GPRBuild, c’est un outil fourni par Adacore qui est un peu le _make_ sur-vitaminé de GNAT, ce dernier disposant déjà de _gnatmake_. La syntaxe se veut très Ada, mais il n’est pas compliqué dans notre cas de modifier celui généré pour changer l’exécutable. Ainsi, il suffit de trouver la ligne ```ada for Main use ("cbsg_examples.adb"); ``` et de la transformer en ```ada for Main use ("produce_corporate_bullshit.adb"); ``` Au final, on obtient l’arbre suivant : ``` cbsg_examples/ ├── alire │   ├── alire.lock ├── alire.toml ├── cbsg_examples.gpr ├── config │   ├── cbsg_examples_config.ads │   ├── cbsg_examples_config.gpr │   └── cbsg_examples_config.h └── src └── produce_corporate_bullshit.adb ``` So far so good… sauf que l’on n’a précisé nulle part la dépendance à _cbsg_ !!! Pour cela, on utilisera la commande ``` fred@tatoiine:~/Dev/Ada/cbsg_examples$ alr with cbsg ``` Dans un cas normal, cela suffirait si la crate _cbsg_ était déjà publiée mais ce n’est pas notre cas. Edition du fichier TOML ---- Le fichier généré par Alire est au format [TOML](https://fr.wikipedia.org/wiki/TOML) (pour ceux qui n’auraient pas vu) et contient maintenant ceci: ```toml name = "cbsg_examples" description = "Corporate bullshit generator examples" version = "0.0.1" authors = ["Gautier de Montmollin"] maintainers = ["Frédéric Praca "] maintainers-logins = ["FredPraca"] executables = ["cbsg_examples"] [[depends-on]] # Added by alr cbsg = "*" # Added by alr ``` C’est bien mais pas complétement, on voit une première erreur. Les exécutables produits sont faux. On ne génère plus cet exécutable, _cbsg_examples_, mais _produce_corporate_bullshit_… Simple à modifier. L’autre chose, c’est que l’on voit bien la dépendance vers la _crate cbsg_ avec n’importe quelle version (le "*"). Pour plus d’informations, il faut aller voir [la doc d’Alire sur les informations du TOML](https://alire.ada.dev/docs/#release-information) (ça fait du _semver_ pour la sélection des versions de _crate_). On est en dev, on n’a rien publié ---- Dans notre cas, comme la _crate cbsg_ n’a pas été publiée, on fait un [_override_](https://alire.ada.dev/docs/#work-in-progress-dependency-overrides), on va donc ajouter un petit morceau à notre TOML pour préciser où trouver notre dépendance. ```toml [[pins]] cbsg = { path = "../cbsg" } # Overridden by local version ``` Et voilà, on a ajouté une épingle sur la version à utiliser, il s’agira de celle se trouvant dans le répertoire _cbsg_. Le fichier complet devient donc : ```toml name = "cbsg_examples" description = "Corporate bullshit generator examples" version = "0.0.1" authors = ["Gautier de Montmollin"] maintainers = ["Frédéric Praca "] maintainers-logins = ["FredPraca"] executables = ["produce_corporate_bullshit"] [[depends-on]] # Added by alr cbsg = "*" # Added by alr [[pins]] cbsg = { path = "../cbsg" } # Overridden by the latest sources ``` On teste --- ``` fred@tatooine:~/Dev/Ada/cbsg_examples$ alr run ``` Si cela n’a pas déjà été contsruit, on a l’étape de construction et le lancement de l’exécutable. ``` Compile [Ada] produce_corporate_bullshit.adb [Ada] delirium.adb [Ada] corporate_bullshit.adb Build Libraries [gprlib] Cbsg.lexch [archive] libCbsg.a [index] libCbsg.a Bind [gprbind] produce_corporate_bullshit.bexch [Ada] produce_corporate_bullshit.ali Link [link] produce_corporate_bullshit.adb New corporate bullshit is in bullshit.html. Enjoy. Use switch -h for help about options. ``` Le programme écrit par défaut un fichier HTML que vous pouvez ouvrir avec votre navigateur préféré pour obtenir une belle série de bullshits :) Si on ne veut pas de fichier HTML: ``` fred@tatooine:~/Dev/Ada/cbsg_examples$ bin/produce_corporate_bullshit --one Roles and responsibilities consistently engage goals-based and cloud-based timelines. ``` Conclusion === Le but de cet article était de présenter _Alire_ de façon un peu plus ludique que la documentation officielle en fournissant un premier exemple. Cela a permis de montrer toutefois le _pinning_ de version que l’on peut considérer comme une utilisation avancée. Alire est un outil en cours de développement et les _crates_ ne sont pas encore nombreuses, on n’en compte que 243 à ce jour, mais tout cela est d’ores et déjà utilisable. _Alire_ contient des _crates_ diverses et variées qui peuvent couvrir le développement standard tout comme le développement embarqué [_bare metal_](https://fr.wikipedia.org/wiki/Bare_metal) ou le développement [_Spark_](https://en.wikipedia.org/wiki/SPARK_(programming_language)). D’ailleurs, si cela n’a été qu’effleurer, _Alire_ permet la gestion des _toolchains_ au sein des _crates_, permettant ainsi de préciser une dépendance à un compilateur particulier. Ainsi, certaines _crates_ tirent une dépendance vers le compilateur croisé [ARM](https://fr.wikipedia.org/wiki/Architecture_ARM) Si Alire, tout comme _pip_, _cargo_ ou _npm_ rentre en collision avec le gestionnaire de paquets de votre distribution, cela reste toutefois un bon moyen de développer rapidement du code Ada. Cherry on the cake, si vous avez [_GnatStudio_](https://en.wikipedia.org/wiki/GNAT_Programming_Studio) d’installé, la commande _alr edit_ ouvrira le projet dans celui-ci :) Amusez-vous bien !