Adieu qmake, bienvenue qbs !

Outil ô combien utile à tout développeur Qt… et pourtant ô combien détesté ! Il fonctionne bien, mais n’est pas la partie la plus maintenable de Qt. On a déjà exploré ce que tout remplaçant potentiel de qmake doit être à même de faire (et une liste de commentaires et questions à ce sujet). Notamment, toute une série d’outils actuellement disponibles ont été étudiés, aucun ne remplissait totalement ce cahier des charges (la discussion a bien continué pour Qt 5 sur la mailing list). C’est pourquoi un projet interne à l’équipe de développement de Qt a été lancé pour tester l’une ou l’autre idée, d’où un tout nouvel outil : la Qt Build Suite, qbs, à prononcer cubes.

C’est tout sauf qmake : pas de lien à la version de Qt, génération d’un graphe de compilation propre à partir de la description de haut niveau du projet, plus de génération de Makefile suivi d’un appel à make/nmake/gmake ou autre. En lieu et place, qbs agit comme un make parallèle, il appelle directement le compilateur, l’éditeur de liens et tout autre outil utile à la compilation du projet (à la manière de SCons ou Ant).

C’est un nouveau langage déclaratif : après QML, l’environnement Qt semble se mettre à la mode déclarative. En réalité, le langage utilisé par qbs est une version allégée de QML. Il fournit une représentation facile à utiliser pour l’EDI, tout en laissant la liberté d’écrire des expressions JavaScript. L’éditeur de fichier de projet devrait gérer lui-même toutes les listes de chaînes littérales et, pour les constructions plus compliquées, n’agir qu’en tant qu’éditeur de texte (ces expressions n’étant requises que si l’on a besoin de plus de puissance… et laissant alors littéralement tout faire, au vu de l’extensibilité). Par exemple :

files: ["foo.h", "foo.cpp", "main.cpp"]              // éditable par l'EDI automatiquement 
files: generateFileList().concat(['extra.cpp'])      // éditable uniquement à la main

Un premier exemple complet, l’habituel Hello World :

import qbs.base 1.0
 
CppApplication {
     name: "HelloWorld"
     files: "main.cpp"
}

Une description complète du langage est disponible dans la documentation.

C’est extensible : alors qu’on cherche à tout prix à éviter avec qmake de générer du code ou de compiler des ressources, qbs fournit une syntaxe pour écrire des règles de transformation de fichier d’un certain type en un autre. On peut appeler des programmes pour le faire (comme rcc) ou exécuter directement la transformation en JavaScript. L’exemple simplifié qui suit montre comment transformer des fichiers .pluginspec.in en .pluginspec (comme ceux utilisés pour Qt Creator) :

Rule {
    ...
    prepare: {
        var cmd = new JavaScriptCommand();
        cmd.description = "generating " + FileInfo.fileName(output.fileName);
        cmd.qtcreator_version = product.module.qtcreator_version;
        cmd.sourceCode = function() {
            var inf = new TextFile(input.fileName);
            var all = inf.readAll();
            all = all.replace(new RegExp('\\\$\\\$QTCREATOR_VERSION(?!\w)', 'g'), qtcreator_version);
            var file = new TextFile(output.fileName, TextFile.WriteOnly);
            file.write(all);
            file.close();
        }
        return cmd;
    }
}

C’est rapide pour des compilations incrémentales : qbs voit le projet de loin, comme un seul bloc, il ne doit pas se forker pour les sous-dossiers. Même si seulement une partie du projet est déjà compilée, le graphe complet de compilation est pris en considération, il n’y a plus d’appel récursif (qui devrait absolument être évité). Cela a pour effet secondaire de rendre les compilations incrémentales très rapides.

En modifiant un script de benchmarking pour supporter qbs, on peut comparer make et qbs, respectivement, pour une compilation incrémentale :

real 0m4.076s
 user 0m2.556s
 sys 0m1.952s
real 0m0.843s
 user 0m0.724s
 sys 0m0.112s

Vous voulez déjà tester ? Les sources sont d’ores et déjà disponibles sur Gitorious. Actuellement, le projet est au stade expérimental, un terrain d’expérimentation pour de nouveaux concepts. qmake va encore résister un certain temps, personne ne sera forcé à abandonner qmake (bien que Qt va fort probablement passer à qbs dès que possible). Un point crucial reste à implémenter : l’adaptation à l’environnement de compilation (aussi appelée processus de configuration). Pour le moment, la seule manière de procéder est d’utiliser un outil externe qui génère un fichier JSON qui sera chargé par qbs. La solution envisagée actuellement est de rendre les tests de configuration utilisables par les modules (une implémentation qui ne sera donc plus entièrement déclarative, mais qui contiendra une bonne proportion de JavaScript).

Source : Qt Labs.

Laisser un commentaire