IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Verdigris, une bibliothèque pour utiliser Qt sans générateur de métaobjets
Elle n'exploite que des en-têtes et des fonctionnalités de C++11

Le , par dourouc05

0PARTAGES

9  0 
Le générateur de métaobjets de Qt, moc, est l’objet de recherches et de débats, ces derniers temps. L’année dernière, CopperSpice a été annoncé comme une bifurcation de Qt 4, l’objectif premier étant de se débarrasser du moc, en le remplaçant par des macros bien plus longues à écrire dans le code. Il y a peu, le mainteneur actuel du moc l’a défendu, en mettant en avant ses nombreux avantages par rapport à l’approche de CopperSpice, notamment pour l’écriture du code ou sa performance. Ce dernier revient à la charge : après avoir proposé une implémentation du moc basée sur des extensions du compilateur Clang ou la réflexion, il présente une autre approche qui exploite exclusivement les mécanismes de base des compilateurs C++ modernes.

Sous le nom de Verdigris se cache une implémentation du moc exclusivement à base de macros et d’expressions constantes de C++11 (entièrement compatible avec Qt 5). Il utilise une syntaxe très similaire à CopperSpice, mais, contrairement à ce dernier, génère toutes les données des métaobjets lors de la compilation (CopperSpice le fait à l’exécution du programme). Les avantages en performance sont multiples : lors de la compilation, un programme Verdigris prendra un peu moins de temps que son équivalent Qt direct… mais beaucoup moins que la version CopperSpice ! De plus, à l’exécution, tant Qt que Verdigris ont des surcoûts très faibles par rapport à CopperSpice, puisqu’ils ont généré l’entièreté des métaobjets à la compilation.




Ces différences d’implémentation ont également des impacts sur la compatibilité binaire, que tente de garantir Qt : l’approche suivie tant par Qt et Verdigris a cet objectif en tête (ce qui permet de changer la version des bibliothèques utilisées sans casser l’application), ce qui les empêche de réaliser certaines optimisations. Au contraire, CopperSpice cherche à optimiser certains appels de fonction et copie in extenso les données nécessaires à plusieurs endroits. Effectivement, CopperSpice est plus rapide pour certaines fonctionnalités, comme l’émission de signaux ; par contre, ces avantages sont contrebalancés par des fichiers exécutables bien plus gros et par un temps de chargement plus élevé.

Côté développeur, tant CopperSpice que Verdigris ont des syntaxes bien plus compliquées que celles permises par l’emploi d’un générateur de code : pour déclarer un dérivé de QObject, là où Qt se satisfait d’une macro Q_OBJECT, insérée dans la définition de la classe, CopperSpice impose une certaine redondance en donnant le nom de la classe en argument, Verdigris utilise même deux macros (l’une pour déclarer l’objet, l’autre pour générer le métaobjet correspondant).


Ces nouveaux développements montrent une fois de plus qu’il est possible de se passer du moc, mais en réalisant certains compromis, toujours défavorables en termes de syntaxe pour le moment. Ensuite, les détails d’implémentation montrent des résultats très différents en termes de compatibilité avec Qt (CopperSpice reste au niveau de fonctionnalités de Qt 4.8) et de performance.

Source : Verdigris: Qt without moc.
Voir aussi : les sources de Verdigris, le tutoriel.
Ce contenu a été publié dans Qt par dourouc05.

Une erreur dans cette actualité ? Signalez-nous-la !

Avatar de tbrezi
Nouveau Candidat au Club https://www.developpez.com
Le 28/05/2016 à 7:09
verdigri semble utiliser des fonctionnalités du c++14, notamment les variable templates.
0  0 
Avatar de renoo
Membre éprouvé https://www.developpez.com
Le 28/05/2016 à 23:23
La syntaxe ne parait pas si tordu que ça. Ca a l'air bien.
0  0 
Avatar de kiruahxh
Futur Membre du Club https://www.developpez.com
Le 25/05/2019 à 9:34
Citation Envoyé par Aurelien.Regat-Barrel Voir le message
Les projets VS sont en fait des fichiers MSBuild qui est le système de build de MS (VS est grosso modo un front end graphique pour MSBuild). Le souci c'est que par défaut, au niveau d'un même projet, les tâches de build ne sont pas parallélisées - les builds des projets le sont mais pas les tâches au sein des projets. L'exception à cela c'est les tâches de compilation car c'est le compilo qui se fork lui-même pour traiter les demandes en parallèle (et non MSBuild qui fait le boulot). Aussi pour des tâches genre moc, pas de parallélisation automatique. Et quand y'a des milliers de fichiers à moc'er, ben ça se sent! Pour s'en sortir il faut développer son propre outil qui va exécuter moc en parallèle et donc customiser la génération des projets au lieu de passer par qmake

Pour ne pas que le nombre de cpp à compiler double, la parade est de faire un include de son fichier moc depuis le code cpp. Ainsi qmake ne génère pas une step supplémentaire de build vu que le fichier généré est inclus dans le cpp d'origine. Ca marche pour toutes les plateformes, mais c'est un peu plus contraignant pour le programmeur. L'option plus "automatique" c'est de faire un unity build des fichiers moc générés pour les compiler tous d'un coup. Mais ça demande de développer un outil pour cela (il parait que CMake sait le faire).
J'ai développé un outil pour QMake pour faire automatiquement un unity build des CPP / MOC / MOC_CPP
Je crois que c'est toi qui m'a mis en tête que c'était possible de grouper les MOCS, j'ai testé et ça a marché
Les perfs sont top. https://github.com/nmoreaud/qmake-unity
Petit benchmark ici : https://github.com/nmoreaud/qmake-un...y#performances

Dans mon outil on peut soit grouper les fichiers moc_XXX.cpp (il reste X appels à MOC et 1 appel au compilo), soit grouper directement les classes à moccer (1 appel à MOC par groupe, et 1 appel au compilo).
Je sais que la première option marche nickel parce que je l'ai utilisé sur un gros projet pendant quelque temps ; la seconde option est à tester pour voir l'impact au quotidien...

Cela dit, je n'ai pas pris en charge MSVC (IDE), mais de souvenir ça marche bien pour MSBuild en ligne de commande.
Si quelqu'un veut développer la prise en charge de MSVC/XCode, je suis preneur : je ne travaillerai surement plus sur un gros projet C++ avant quelque temps...

Autre bonne nouvelle : d'après ce POST, Qt Visual Studio Tools >= 2.2 prend désormais en charge l'invocation en parallèle de MOC : https://blog.qt.io/blog/2018/02/26/q...-2-0-released/
0  0