URL: https://linuxfr.org/news/petit-eventail-des-outils-de-construction-builder-libres Title: Petit éventail des outils de construction (« builder ») libres Authors: barmic Date: 2011年08月07日T13:51:54+02:00 License: CC By-SA Tags: make, génie_logiciel, builder, compilation, développement, construction et build Score: 43 Je vous propose dans cette dépêche de revenir sur la panoplie [d'outils de construction](http://fr.wikipedia.org/wiki/Moteur_de_production) qui s'offre à nous (c'est à dire les outils permettant d'automatiser les étapes de préprocessing, compilation, éditions des liens, etc). Je ne cherche pas à faire un comparatif, mais juste à les décrire pour en faire ressortir les avantages et inconvénients ainsi que les cas d'utilisation. Cette dépêche peut être vue comme un état de l'art allégé des outils de construction libres. Je tiens à remercier les contributeurs de cette dépêche : - GeneralZod - tiennou - NedFlanders - claudex Ce sont eux qui ont écrit la majeure partie de cette dépêche et qui l'ont améliorée et complétée grâce à leurs connaissances et au temps qu'ils y ont consacré. Cette dépêche a pour objectif de faire découvrir ou redécouvrir des outils de constructions. Si vous en connaissez d'autres n'hésitez pas à en parler en commentaire. ---- [OMake](http://omake.metaprl.org/index.html) [SCons](http://www.scons.org/) [Maven](http://maven.apache.org/) [Ninja sur github](https://github.com/martine/ninja) [Ant chez Apache](http://ant.apache.org/) [CMake](http://www.cmake.org/) [buildr chez Apache](http://buildr.apache.org/) [Apache Ivy](http://ant.apache.org/ivy/) [Gradle](http://www.gradle.org/) [GNU Make sur Wikipédia](http://fr.wikipedia.org/wiki/GNU_Make) ---- # Un « builder » ? # Nous avons dans nos dépôt un grands nombre d'outils qui ont chacun leur philosophie. Le reste de la dépêche s'attelle à en décrire un certains nombre parmi les plus connus. Un builder est un outil qui permet de construire un logiciel (et plus si affinité) à partir des sources. Il doit être le chef d'orchestre de la chaîne de fabrication du logiciel (le compilateur, l'éditeur de liens, etc). Les critères importants de ce genre d'outils sont la **facilité d'utilisation** : pour le développeur et pour l'utilisateur. La **performance** : lorsqu'un projet est gros, le temps de création du logiciel peu devenir très important et la vitesse du builder peut avoir un impact important. La **flexibilité** : peut-on en faire ce que l'on veut avant et après chaque étape ? Gère-t-il n'importe quel langage ? # Le vénérable Make # make est l'outil de base pour beaucoup. C'est un outil très vieux, mais encore beaucoup utilisé. Il est le seul outil de la liste de cette dépêche à faire partie de POSIX. Sous nos distributions GNU/Linux, c'est généralement GNU Make qui est utilisé. Make est une sorte de langage [Rule Based Programming](https://linuxfr.org/users/montaigne/journaux/des-paradigmes-alternatifs) quand lequel on spécifie des règles sous la forme : ```make cible: dépendance cmd ``` Avec : - **cible** : fichier ou pattern de fichier que l'on cherche construire - **dépendance** : liste des fichiers nécessaires pour construire la cible - **cmd** : commande pour produire la cible Les avantages de cette approche sont : - la **souplesse** : on utilise `make` pour tout et n'importe quoi aujourd'hui (créer un PDF, latex ou lout, compiler dans tout type de langage, etc.) - la **simplicité** : si vous savez construire à partir de votre ligne de commande vous saurez le faire avec make - **rapidité** : il construit un arbre de dépendance et éxecute une parallèle ce qui peut l'être (aujourd'hui tout les builders le font) En revanche, il possède aussi un certain nombre d'inconvénients : - **dépendances** : on doit gérer à la main les dépendances entre les fichiers, plus le projet devient gros plus ça devient lourd à gérer ; - **manque de portabilité** : on utilise des commandes, généralement on ne se gène pas pour utiliser les options GNU de nos outils favoris, il faut aussi que ces outils soient installés sur la machine, etc. ; - **manque de réutilisabilité** : quand on se met à beaucoup l'utiliser, on a tendance à recopier des blocs de Makefile car rien n'est mutualisé. Ce dernier point est tout de même à relativiser, GNU Make intègre beaucoup de règles par défaut qui simplifient son utilisation. Par exemple, si vous avez un simple fichier coucou.c que vous souhaitez compiler, il vous suffit de taper cette commande (sans avoir créé de Makefile au préalable) pour créer l'exécutable : ```sh $ make coucou cc coucou.c -o coucou ``` Si vous souhaitez passer des arguments au compilateur : ```sh $ export CFLAGS='-g' $ make coucou cc -g coucou.c -o coucou ``` # Le peu connu OMake # Il utilise une syntaxe similaire à Make mais offre quelques fonctionnalités supplémentaire : - La gestion du projet dans plusieurs répertoires ou dans une hiérarchie de répertoire ; - Une analyse automatique et rapide des dépendances, basée sur MD5 ; - Lorsqu'une cible est spécifiée dans la ligne de commande, elle est automatiquement considérée comme obsolète et reconstruite ; - Il est complètement scriptable et une bibliothèque est fournie pour les langages C, C++, OCaml, et LaTeX. Il est donc possible d'avoir une seule ligne pour le projet : ```text .DEFAULT: $(CProgram prog, foo bar baz) ``` Cette ligne suffit pour construire la cible prog à partir des fichier foo.c, bar.c et baz.c. OMake va aussi chercher les dépendances implicites comme les includes des fichiers C. - Les règles qui construisent plusieurs fichiers en une fois sont complètement prises en charge ; - Il fonctionne sur Linux, Windows, Cygwin et Mac OS ; - Des fonctions telles que grep, sed et awk sont directement incluses dans le programme, cela permet d'améliorer la portabilité sous Windows ; - Il est possible de surveiller le système de fichier en continu pour relancer la construction dès qu'un fichier est modifié ; - Il dispose d'un interpréteur de commande, `osh`, qui permet l'utilisation interactive. # Un challenger scons # Scons est écrit en python, et les scripts scons (fichiers SConstruct et SConscript) sont eux-même en python. Ceci lui procure une très grande souplesse. La contrepartie de cette souplesse est une certaine complexité, scons fait un peu moins "clef-en-main" que certains autres outils de construction. Avantages de scons : * **c'est du python** : c'est un vrai langage, pas un truc tout bancal, ça roxe * sait extraire out-of-the-box les **dépendances** des sources de nombreux langages (C, C++, Java, Fortran, etc.) * garantie d'avoir toujours des **constructions correctes**, ce qui est assez confortable. Scons garde trace du hash du contenu de chaque fichier apparaissant dans l'arbre de dépendances. * lance les compilations en **parallèle** * killer feature : scons **cache** le résultat chaque opération (compilation, liaison, etc.), un peu comme ccache, mais pour toutes les opérations et tous les langages. * gère de base les chaînes de compilation sur les systèmes d'exploitation majeurs (outils GNU sous Linux, Visual Studio sous Windows, XCode sous Mac OS X), tout ceci étant bien entendu totalement paramétrable. * range tous les produits de la compilation dans un "build directory", pratique pour séparer les choux et les carottes. Inconvénients : * relativement **complexe** à prendre en main, et plutôt bas niveau * plutôt **lent** par rapport à la concurrence, en partie à cause de python, et en partie à cause de la gestion très rigoureuse des dépendances. Une comparaison avec les autres outils est disponible sur [http://www.scons.org/wiki/SconsVsOtherBuildTools] Un dérivé de scons qui semble avoir le vent en poupe est [waf](http://code.google.com/p/waf/). Il comble les lacunes de scons (complexité et lenteur) en proposant des améliorations tel qu'une sortie en couleur et un meilleur support de la compilation parallèle. # Celui de Google : Ninja # Ninja est le moteur de production créé par l'équipe de développement de Google Chrome. Ceux-ci utilisaient Make mais trouvaient que la génération de l'arbre des dépendances était bien trop lent (le temps avant de commencer serait d'une minute). Ils ont choisi de développer leur propre outil (pourquoi donc patcher le logiciel existant ?). Celui-ci est plus simpliste que Make car il ne possède aucune logique interne liée aux langages (contrairement à make qui possède des règles prédéfinies). Néanmoins, il a une syntaxe qui est un peu plus flexible. L'utilisation de ninja passe par la création d'un fichier build.ninja. En voici un exemple tiré de la [documentation officielle](http://martine.github.com/ninja/manual.html) : ```sh cflags = -Wall rule cc command = gcc $cflags -c $in -o $out build foo.o: cc foo.c ``` ```cflags = -Wall rule cc command = gcc $cflags -c $in -o $out build foo.o: cc foo.c ``` Cet exemple, bien que simpliste permet de voir l'usage basique du logiciel. Voici une petite explication de la syntaxe : ```sh cflags = -Wall ``` Déclare une variable cflags. ```sh rule cc command = gcc $cflags -c $in -o $out ``` Déclare une règle cc : - $in corresponde aux fichiers d'entrée - $out au fichier de sortie ```sh build foo.o: cc foo.c ``` Ceci va invoquer la règle cc avec foo.c comme variable $in et foo.o comme variable $out. # L'univers Java # ## L'historique Apache Ant ## Le premier moteur de production orienté Java développé par la fondation Apache. Il repose sur la notion de tâches et a la particularité d'utiliser un format XML pour son fichier de configuration. On peut étendre les fonctionnalités d'Ant en écrivant des nouvelles tâches. Bien qu'écrit en Java, il est utilisable avec d'autres langages. Avantages : - une riche collection d'extensions via antcontrib ; - portable ; - excellente intégration aux outils Java existants (tests unitaires, qualité de code etc...). Inconvénients : - XML ? - Difficulté d'avoir un environnement standard (compilation, paquetages, etc) rapidement. On doit partir de zéro pour les tâches standards - Pas d'héritage sur les fichiers build.xml et la composition est fastidieuse. ## L'usine à build Apache Maven ## Maven est une plateforme moderne de construction de projet, développé également par la fondation Apache. Attaché à la devise « Convention plutôt que configuration », Maven impose sa manière d'organiser les fichiers et un cycle de construction en plusieurs phases (les principales étant clean, compile, test, package, install, deploy). L'intérêt de maven est qu'il impose de la rigueur dans l'infrastructure du projet, apportant par la suite énormément de confort puisqu'on est à peu près sûr de pouvoir reconstruire le projet sur un nouvel environnement. La gestion des dépendances est un point fort de maven. Chaque module est identifié par (au minimun) le triplet (groupId, artifactId, version). L'ajout d'une dépendance à un projet se fait donc juste en spécifiant le triplet correspondant. Maven se charge automatiquement de récupérer les dépendances sur les dépôts comme un gestionnaire de paquets le fait sur notre distribution GNU/Linux favorite. Maven est lui-même extrèmement modulaire et les nombreuses extensions disponibles seront résolues au besoin au moment de leur utilisation. Un projet maven est décrit dans un fichier pom.xml contenant l'identification du projet, des métadonnées optionnelles mais intéressantes (licence, page web, description...), la liste des dépendances, des dépôts additionnels, la liste des extensions supplémentaires utilisées. En résumé, les avantages : * description standardisée d'un projet * richesse des extensions disponibles * plateforme modulaire et autonome, garantissant une utilisation rapide dans un nouvel environnement Les inconvénients : * la résolution des dépendances peut s'avérer un peu longue * une connexion au dépôt de bibliothèques est nécessaire au moins pour la première fois, sinon le projet est inutilisable * une description plus détaillées des inconvénients se trouve sur le blog de Sonatype : [We're Used to the Axe Grinding](http://www.sonatype.com/people/2009/05/were-used-to-the-axe-grinding/) ## Les autres (buildr, gradle...) ## La communauté Java - et plus particulièrement la communauté Apache - est très productive ces derniers temps en terme de builder. En plus de Ant et Maven, Apache compte plusieurs projets intéressants. Quelques-uns sont à souligner : - **[Apache Ivy](http://ant.apache.org/ivy/)** est un sous-projet d'Ant. Il vise à ajouter la gestion des dépendances (compatibles Maven) dans des projet gérés par Ant. Cela permet de simplifier la gestion des dépendances à un projet qui était déjà géré par Ant. - **[Gradle](http://www.gradle.org/)** celui-ci gère les projet via un DSL à la place de fichier XML, il vise notamment à être plus indépendant du langage que Maven, ainsi il pourra plus facilement travailler sur des projet Groovy ou Scala. Il utilise, comme Maven, la convention plutôt que la configuration ce qui lui permet de simplifier son utilisation. Voici pour exemple le fichier minimal pour un projet Java : ```groovy apply plugin: 'java' ``` - **[Apache Buildr](http://buildr.apache.org/)** est fait pour être le plus simple possible. Il est aussi prévu pour gérer plus facilement Groovy et Scala. Voici un fichier montrant sa simplicité, il permet de compiler un projet my-app et de créer un jar : ```ruby define 'my-app' do project.version = '0.1.0' package :jar end ``` ```groovy # Du code avec coloration syntaxique class Ruby end ``` ```groovy apply plugin: 'java' ``` # Les surcouches # ## CMake ## Contrairement aux outils présentés auparavant, CMake est un générateur de "projets". Il génére un ou des fichier(s) recette(s) qui seront manipulés par un moteur de production bas-niveau (make, nmake, ...) ou pouvant être ouverts par un environnement de développement (eclipse, XCode, Visual Studio, KDevelop, ...). Depuis son adoption par KDE, il connait une grande popularité. CMake fournit un [[langage dédié]] et un jeu de macros permettant de gérer un projet complet. Il est ainsi capable de retrouver seul les bibliothèques ou les utilitaires installés sur le système et ainsi s'abstraire de la platforme de compilation. Plus généralement, CMake fait partie de la suite de processus logiciel qualité Kitware qui comporte également : - CTest : un outil de tests qui étend CMake. Il permet de récupérer le code source à partir d'un gestionnaire de version, de compiler ces sources, et d'exécuter les tests unitaires (CMake supporte GoogleTest, CXXTest, SQuish et s'intégre facilement aux autres systèmes). Il permet également de récupérer la couverture de code et d'exécuter les tests sous Valgrind. Il génère des rapports XML qui pourront être traités par un serveur d'intégration continue. - CDash : serveur web de tests, associé à CTest, il fournit une plateforme d'intégration continue flexible. - CPack : la boite à outils pour générer des paquets très simplement. Il supporte les formats suivants : dpkg, rpm, tarballs, installeurs Mac (dmg, drag'n'drop, etc.), NSIS, Cygwin. Avantages : - multiplateforme - permet de générer des projets pouvant être ouverts par un [IDE](http://fr.wikipedia.org/wiki/Environnement_de_d%C3%A9veloppement_int%C3%A9gr%C3%A9) - robuste - prise en charge de la compilation parallèle - une collection de modules qui s'enrichit régulièrement Inconvénients : - un langage de script relativement pauvre comparé à python ou lua - documentation éparse ## Les autotools ## Derrière la dénomination autotools se cache toute une famille d'outils GNU constituant un moteur de production complet mais également complexe : - **autoconf** : un générateur de scripts shell à partir de macros m4 permettant de configurer les sources d'un projet (ex: tester la version d'une bibliothèque, la présence ou non d'une fonction etc...). C'est lui qui est responsable de la génération du fameux "configure". - **automake** : générateur de makefile portables, il est écrit en perl. - **libtool** : abstrait la génération des bibliothèques dynamiques. - **gnu make** : bien évidemment le moteur GNU make pour exécuter le makefile résultant. Avantages : - facilite l'écriture de programmes multi-plateformes. - simplifie le processus de compilation par l'utilisateur (le célèbre triptyque : "./configure && make && make install") - système de construction robuste et extrêmement modulaire. - la plus large collection d'extensions parmi tout les moteurs de production de haut niveau présentés. Inconvénients : - complexe d'utilisation - dépendance à la présence d'un shell bourne (ou compatible), m4, et perl - relativement lent (même si il est possible d'améliorer ce point en passant par une construction non récursive, c'est-à-dire en utilisant un unique Makefile.am à la racine du projet) - les différentes versions d'automake sont incompatibles entre elles - re-générer le système de construction est une tâche relativement complexe, souvent laissé à la charge d'un script shell (autogen.sh)