2015-11-04 1 views
0

J'essaie de faire la transition d'une bibliothèque partagée qui utilise Qt 5 et Q_OBJECT de QMake à CMake 3.2. Voici le fichier CMakeLists.txt actuel:Q_OBJECT ne nomme pas un type lors de la conversion d'un projet qmake en cmake

cmake_minimum_required(VERSION 3.2.2) 

project(core) 

# Find includes in corresponding build directories 
set(CMAKE_INCLUDE_CURRENT_DIR ON) 
# Instruct CMake to run moc automatically when needed. 
set(CMAKE_AUTOMOC ON) 

find_package(Qt5Core REQUIRED) 
find_package(Qt5Gui REQUIRED) 
find_package(Qt5Widgets REQUIRED) 
find_package(Qt5Xml REQUIRED) 

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -pedantic-errors -Werror -Wextra -O2 -g -fno-omit-frame-pointer -Woverloaded-virtual") 

add_definitions(-DCORE_LIBRARY) 
add_definitions(-DQT_PLUGIN) 
add_definitions(-DQT_NO_DEBUG) 
add_definitions(-DQT_SHARED) 

add_library(core SHARED 
    src/reflect/TypeRegistry.h 
    src/Profiler.h 
    src/reflect/typeIdMacros.h 
    src/reflect/Reflect.h 
    src/AdapterManager.h 
    src/core_api.h 
    src/core.h 
    src/EnvisionApplication.h 
    src/EnvisionException.h 
    src/EnvisionManager.h 
    src/EnvisionPlugin.h 
    src/PluginInfo.h 
    src/global.h 
    src/precompiled.h 
    src/TestEvent.h 
    src/TestRunner.h 
    src/PluginManager.h 
    src/EnvisionWindow.h 
    src/reflect/TypeRegistry.cpp 
    src/Profiler.cpp 
    src/AdapterManager.cpp 
    src/EnvisionException.cpp 
    src/EnvisionManager.cpp 
    src/core.cpp 
    src/EnvisionApplication.cpp 
    src/TestEvent.cpp 
    src/TestRunner.cpp 
    src/PluginManager.cpp 
    src/EnvisionWindow.cpp 
    src/global.cpp) 

target_link_libraries(core Qt5::Core Qt5::Widgets Qt5::Xml Qt5::Gui) 

Avec ce fichier CMakeLists.txt, je peux courir cmake et il fonctionne sans erreur ou avertissements. Cependant, quand je lance make je reçois une erreur:

$ make 
[ 7%] Automatic moc for target core 
Generating moc_EnvisionApplication.cpp 
Generating moc_EnvisionWindow.cpp 
Generating moc_TestRunner.cpp 
[ 7%] Built target core_automoc 
Scanning dependencies of target core 
[ 14%] Building CXX object CMakeFiles/core.dir/src/reflect/TypeRegistry.cpp.o 
[ 21%] Building CXX object CMakeFiles/core.dir/src/Profiler.cpp.o 
[ 28%] Building CXX object CMakeFiles/core.dir/src/AdapterManager.cpp.o 
[ 35%] Building CXX object CMakeFiles/core.dir/src/EnvisionException.cpp.o 
[ 42%] Building CXX object CMakeFiles/core.dir/src/EnvisionManager.cpp.o 
[ 50%] Building CXX object CMakeFiles/core.dir/src/core.cpp.o 
In file included from /store/envision/envision/Core/src/core.cpp:27:0: 
/store/envision/envision/Core/src/EnvisionWindow.h:30:1: error: expected class-name before ‘{’ token 
{ 
^ 
/store/envision/envision/Core/src/EnvisionWindow.h:31:2: error: ‘Q_OBJECT’ does not name a type 
    Q_OBJECT 
^
    ... 

Comme vous pouvez le voir, le MOC est exécuté, mais il semble que les fichiers d'en-tête d'origine avec la macro Q_OBJECT sont passées en est à gcc et il a naturellement aucune idée de ce que Q_OBJECT est et échoue donc. Peut-être l'ancien build, QMake a généré de nouveaux fichiers d'en-tête et les a utilisés à la place des originaux, ou a évité ce problème d'une autre manière.

Des idées pour résoudre ce problème? J'ai regardé en ligne mais je n'ai pas trouvé de réponse définitive et j'ai l'impression qu'il devrait y avoir une solution simple. J'espère que je n'ai pas besoin de modifier le code source, car ce n'est qu'une petite partie d'un plus gros projet.

Répondre

1

J'ai trouvé le problème et c'était assez bête, mais je veux l'expliquer juste au cas où quelqu'un d'autre rencontre un problème similaire lors de la conversion de QMake. Comme mon code a bien été compilé en utilisant QMake, je n'ai pas regardé dans le fichier source réel EnvisionWindow.h que gcc se plaignait, pensant que cela devait être un problème de construction. Quand j'ai finalement jeté un coup d'oeil, j'ai vu que ce fichier contient aucun inclut, ce qui explique pourquoi le compilateur n'a pas pu trouver de définition pour Q_OBJECT.

La raison pour laquelle cela a fonctionné avec QMake est que cette construction utilise un en-tête précompilé avec l'indicateur -include utilisé pour chaque fichier source, injectant ainsi toutes les définitions nécessaires. C'est le comportement que l'on obtient automatiquement lors de l'utilisation de PRECOMPILED_HEADER = precompiled_header_name.h dans un fichier QMake .pro. Je souhaite que QMake ne le fasse pas, puisque tous les fichiers de mon projet sont censés inclure explicitement l'en-tête précompilé.

Quoi qu'il en soit, la solution était triviale: inclure l'en-tête précompilé dans EnvisionWindow.h et tout se compile bien maintenant.

Leçon apprise: prend l'erreur de compilateur plus littéralement.