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 on a besoin de plus de puissance... et laissant alors littéralement tout faire, au vu de l'extensibilité). Par exemple :
Code : | Sélectionner tout |
1 2 | files: ["foo.h", "foo.cpp", "main.cpp"] // éditable par l'EDI automatiquement files: generateFileList().concat(['extra.cpp']) // éditable uniquement à la main |
Code : | Sélectionner tout |
1 2 3 4 5 6 | import qbs.base 1.0 CppApplication { name: "HelloWorld" files: "main.cpp" } |
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) :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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; } } |
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.