2010-09-06 5 views
5

Je développe un grand projet en utilisant Qt 4.6, CMake 2.8 et Visual Studio 2008 pour la plate-forme Windows. Pour le système de construction, tout est standard: J'utilise la macro QT4_WRAP_CPP de CMake pour générer des fichiers moc à partir de fichiers d'en-tête, qui sont ensuite liés dans l'exécutable final de la commande add_executable. Tout fonctionne comme prévu.Qt, CMake, Visual Studio et Q_OBJECT dans les fichiers cpp

La seule restriction avec cette configuration est que je ne peux pas définir widgets ou helper en utilisant Q_OBJECT dans .cpp fichiers. Ce serait très pratique pour les petites classes d'aide spécifiques au contexte qui devraient apparaître juste à côté de l'endroit où elles sont utilisées.

J'ai essayé de passer la liste complète des fichiers sources (tant .h et Cpp) à QT4_WRAP_CPP, au lieu de simplement les fichiers d'en-tête, mais cela ne fonctionne pas (liaison échoue parce que certains moc liés les symboles sont indéfinis).

Je pense que le problème est que, pour une paire de fichiers foo.h et foo.cpp, la macro QT4_WRAP_CPP va générer le même fichier moc (moc_foo.cxx) dans le même répertoire, et évidemment cela signifie que le premier fichier sera écrasé par le second, et par conséquent les symboles seront manquants au moment de la liaison.

Existe-t-il un moyen de résoudre ce problème ou de contourner ce problème? Par exemple, j'ai essayé d'ajouter une règle spécifique pour foo.cpp de la forme

QT4_GENERATE_MOC(directory/foo.cpp directory/foo.moc) 

puis ajoutez

#include "foo.moc" 

à la fin de foo.cpp. Je pense que cela devrait fonctionner, mais hélas Visual Studio ne permet qu'une seule règle de construction par fichier, et .cpp fichiers ont déjà une règle de construction (compilation en fichier objet), donc cette approche ne fonctionne pas, au moins avec Visual Studio .

Une autre idée que je devais était de créer une nouvelle macro, par exemple QT4_WRAP_CPP_WITH_PREFIX, sur la base QT4_WRAP_CPP (qui est défini dans parts/cmake-2.8/modules/Qt4Macros.cmake), qui prendrait un argument préfixe supplémentaire et ajouterait ce préfixe aux fichiers moc générés. De cette façon, je voudrais appeler deux fois QT4_WRAP_CPP_WITH_PREFIX, une fois pour .h fichiers et une fois pour .cpp fichiers, avec des préfixes différents. Ce que je n'aime pas à propos de cette approche, c'est que je jouerais avec les composants internes du support Qt de CMake, au lieu d'utiliser l'API publique.

Une meilleure idée?

Cheerz, Franz

+0

Je ne suis pas sûr de comprendre ce bit: "La seule restriction avec cette configuration est que je ne peux pas définir de widgets ou d'aide en utilisant Q_OBJECT dans les fichiers .cpp." Vous ne devriez jamais avoir besoin d'exécuter MOC sur autre chose que des fichiers d'en-tête? –

+1

Je trouve pratique de définir occasionnellement une petite classe d'aide dans un fichier .cpp, et de ne pas l'exposer en dehors de ce fichier .cpp. Pour cela, je dois être capable d'exécuter MOC sur des fichiers .cpp. L'approche macro 'QT4_WRAP_CPP_WITH_PREFIX' décrite dans mon post fonctionne comme un charme. –

+0

@ FrançoisBeaune - avez-vous déjà trouvé une solution pour cela? Même pour quelque chose ce simple: #include #include #include classe MyClass: public QObject { Q_OBJECT }; int main (int, caractère * []) ​​ { MyClass myClass; return 0; } Je ne peux pas comprendre comment le MOC car il est dans un fichier cpp (et j'obtiens les erreurs de vtable en essayant de le construire normalement). –

Répondre

1

En se référant à la documentation "Utilisation du MOC" (http://doc.qt.nokia.com/4.1/moc.html), vous aviez seulement besoin d'importer « foo. moc "à la fin de votre fichier d'implémentation. Comme vous ne pouvez pas ajuster les règles de construction en conséquence, essayez d'exporter un fichier .pro et appliquez la règle de construction comme suggéré par le document nokia.

2

versions récentes de CMake ont "automoc" qui a fonctionné comme un charme pour moi: http://blogs.kde.org/2011/11/01/cool-new-stuff-cmake-286-automoc

ajouter simplement le CMakeLists.txt:

set(CMAKE_AUTOMOC TRUE) 

puis dans le cpp (par exemple, par exemple. cpp) file:

#include "example.moc" 

(le fichier * .moc doit correspondre au nom du fichier cpp).

Questions connexes