将qmake项目转换为cmake时,Q_OBJECT不会命名类型

时间:2015-11-04 21:45:54

标签: c++ qt cmake qmake qobject

我正在尝试将使用Qt 5和Q_OBJECT的共享库从QMake转换为CMake 3.2。这是当前的CMakeLists.txt文件:

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)

使用此CMakeLists.txt文件,我可以运行cmake并运行时没有任何错误或警告。但是,当我运行make时出现错误:

$ 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
  ^
  ...

正如您所看到的,MOC已运行,但似乎原始头文件与Q_OBJECT宏一起传递给gcc,它自然不知道Q_OBJECT是什么,因此失败。也许是旧版本,QMake生成了新的头文件并使用了那些而不是原始文件,或者以其他方式避免了这个问题。

有任何想法如何解决此问题?我在线查看但没有找到明确的答案,我觉得应该有一个直截了当的解决方案。希望我不必修改任何源代码,因为这只是一个更大项目的一小部分。

1 个答案:

答案 0 :(得分:2)

我发现了这个问题而且非常愚蠢,但我想解释一下,以防其他人在转换QMake时遇到类似的问题。

由于我的代码使用QMake编译得很好,我没有查看gcc抱怨的实际源文件EnvisionWindow.h,认为它必须是构建问题。当我终于看一看时,我看到这个文件包含 no includes,这就是为什么编译器找不到Q_OBJECT的定义。

它与QMake一起使用的原因是因为该构建使用预编译头,每个源文件使用-include标志,从而注入所有必要的定义。这是在QMake PRECOMPILED_HEADER = precompiled_header_name.h文件中使用.pro时自动获取的行为。我希望QMake没有这样做,因为我的项目中的所有文件都应该明确包含预编译的头文件。

无论如何,解决方案是微不足道的:在EnvisionWindow.h中包含预编译的头文件,现在一切都编译得很好。

获得的经验:更确切地说是编译器错误。