Qt 5 cmake échoue avec undefined reference to vtable sur bonjour tout le monde, avec inc & src en tant que sous-dossiers
Mise à jour 2
Après déconner un peu (et de modification des Makefiles générés), ça ressemble à ce qui se passe est que le moc n'est pas correctement le traitement MainWindow.h
(inclus par main.cpp
et MainWindow.cpp
sauf si c'est dans le même dossier que les fichiers de la source qui l'a inclus.
Moc s'exécute sur MainWindow.cpp
, ne pas les inclure et n'a donc pas voir la macro q_object donc produit pour produire un vide de fichier de sortie. Je ne suis pas sûr de savoir si moc généralement de processus comprend ou si elle scanne le répertoire, mais de toute façon, les en-têtes qui ont besoin de mocing mais dans d'autres répertoires ne sont pas en cours de traitement!
Mise à jour
Le problème semble être lié à la sortie produite par le moc. Dans le premier cas (celui qui compile), hello-world_automoc.cpp
et moc_MainWindow.cpp
sont générés. hello-world_automoc.cpp
ressemble
/* This file is autogenerated, do not edit*/
#include "moc_MainWindow.cpp"
Dans le second cas, un hello-world_automoc.cpp
est produit qui ressemble à
/* This file is autogenerated, do not edit*/
enum some_compilers { need_more_than_nothing };
et il n'y a pas de moc_MainWindow.cpp
à tous. Si j'manuellement appel moc de cmake au lieu d'utiliser automoc dans le cassé cas, je ne reçois moc_MainWindow.cpp
mais il est vide.
État D'Origine
Tout d'abord, non, je n'ai pas oublié de set(CMAKE_AUTOMOC)
. Notez également que MainWindow
's le destructeur est déclaré et mis en œuvre.
Quand ma structure de répertoire ressemble à:
CMakeLists.txt |__ main.cpp |__ MainWindow.cpp |__ MainWindow.h |__ MainWindow.l'interface utilisateur
la compilation fonctionne très bien.
Cependant, quand il ressemble:
helloworld/ |__ CMakeLists.txt |__ src/ | |__ CMakeLists.txt | |__ main.cpp | |__ MainWindow.cpp | |__ inc/ | |__ MainWindow.h | | _ _ /l'interface utilisateur graphique |__ MainWindow.l'interface utilisateur
J'obtiens les erreurs de liaison:
Linking CXX executable hello-world
CMakeFiles/hello-world.dir/MainWindow.cpp.o: In function `MainWindow::MainWindow()':
MainWindow.cpp:(.text+0x3b): undefined reference to `vtable for MainWindow'
MainWindow.cpp:(.text+0x4d): undefined reference to `vtable for MainWindow'
CMakeFiles/hello-world.dir/MainWindow.cpp.o: In function `MainWindow::~MainWindow()':
MainWindow.cpp:(.text+0xaf): undefined reference to `vtable for MainWindow'
MainWindow.cpp:(.text+0xc1): undefined reference to `vtable for MainWindow'
collect2: error: ld returned 1 exit status
make[2]: *** [src/hello-world] Error 1
make[1]: *** [src/CMakeFiles/hello-world.dir/all] Error 2
Je voudrais vraiment avoir de mes sources et les en-têtes dans le bon sous-répertoires, mais je ne suis pas tout à fait sûr de savoir comment résoudre ce problème.
C'est en fait le plus simple identifiables cas d'une erreur à partir d'un projet de beaucoup plus grande, donc je ne suis vraiment pas tout ce que vif pour aplatir les répertoires de projet juste parce que je suis l'ajout d'un Qt GUI.
Je suis en ajoutant Qt soutien à moyennement grande application existante qui utilise cmake construire, je n'ai aucune envie d'avoir plus d'un système de construction impliquées, et je suis beaucoup plus familier avec cmake.
OK, je reçois le point! 🙂
OriginalL'auteur Iskar Jarak | 2013-11-04
Vous devez vous connecter pour publier un commentaire.
Comme l'a noté, le moc n'est pas le traitement
MainWindow.h
dans votre exemple. Un moyen de forcer cette situation est d'appelerqt_wrap_cpp()
directement (au lieu de surMainWindow.cpp
) et puis d'inclure le fichier résultant dans l'appel àadd_executable()
.De votre haut niveau CMakeLists.txt pourrait ressembler à:
et votre src niveau comme:
Addendum:
qt5_wrap_cpp(hello-world_SRC ../inc/MainWindow.h)
OriginalL'auteur Iskar Jarak
Bien, peut-être
automoc
ne fonctionne pas pour vous, je suppose que c'est parce que CMake ne trouve pas les fichiers correspondants. Consultez la documentation ici:http://www.cmake.org/cmake/help/v2.8.12/cmake.html#prop_tgt:AUTOMOC
Dans ce cas, vous pouvez toujours appeler le moc commande manuellement dans votre
CMakeLists.txt
:Remarque: vous devez vous assurer que vous utilisez la commande list correctement vous-même. Cet exemple de code est de mon projet où j'ai utiliser une liste de sources (
library_sources
).C'est juste une supposition, mais vous devriez essayer sans automagiques d'abord d'écarter une possible source d'erreur.
Aussi assurez-vous de bien supprimé le CMake cache après la modification de votre structure de répertoire.
Juste confirmant je reçois la même erreur quand manuellement appeler moc.
Pour être un peu plus clair, j'obtiens la même erreur quand manuellement appeler moc lorsque la structure de sous-répertoire est utilisé manuellement l'appel de moc fonctionne très bien dans le répertoire cas où automoc fonctionne très bien aussi.
C'est bizarre. J'ai utiliser des sous-répertoires en tant que bien, mais dans mon cas, les en-têtes sont toujours à la même place. Je voudrais faire un rapport de bogue avec le Qt project. Peut-être essayez ce simple exemple avec qmake d'abord pour voir si c'est encore liée à CMake.
J'ai des nouvelles. Je tardivement pensé à regarder à la moc des fichiers générés. Dans le cas où les choses pause et j'utilise automoc,
hello-world_automoc.cpp
ne contient qu'un enum (enum some_compilers { need_more_than_nothing };
) et rien d'autre, etmoc_MainWindow.cpp
n'est pas généré. Quand j'ai exécuter manuellement moc, j'ai un videmoc_MainWindow.cpp
. Dans le cas où il ne fonctionne pas,hello-world_automoc.cpp
contient#include "moc_MainWindow.cpp"
etmoc_MainWindow.cpp
contient la bonne méthodes générées.OriginalL'auteur ypnos