简体   繁体   English

将qmake项目转换为cmake时,Q_OBJECT没有命名类型

[英]Q_OBJECT does not name a type when converting a qmake project to cmake

I am trying to transition a shared library that uses Qt 5 and Q_OBJECT from QMake to CMake 3.2. 我正在尝试将使用Qt 5和Q_OBJECT的共享库从QMake过渡到CMake 3.2。 Here is the current CMakeLists.txt file: 这是当前的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)

With this CMakeLists.txt file, I can run cmake and it runs without any errors or warnings. 有了这个CMakeLists.txt文件,我可以运行cmake ,它可以运行而不会出现任何错误或警告。 However, when I run make I get an error: 但是,当我运行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
  ^
  ...

As you can see, the MOC is run, but it seems like the original header files with the Q_OBJECT macro are passed as is to gcc and it naturally has no clue what Q_OBJECT is and therefore fails. 如您所见,MOC已运行,但似乎带有Q_OBJECT宏的原始头文件按原样传递给了gcc,它自然不知道Q_OBJECT是什么,因此失败了。 Perhaps the old build, QMake generated new header files and used those instead of the original ones, or avoided this issue in some other way. 也许是旧版本QMake生成了新的头文件并使用了这些头文件来代替原始头文件,或者以其他方式避免了此问题。

Any ideas how to resolve this issue? 任何想法如何解决这个问题? I looked on-line but didn't find a definitive answer and I feel like there should be a straight-forward solution. 我在线上看,但没有找到明确的答案,我觉得应该有一个简单的解决方案。 Hopefully I don't have to modify any source code as this is just a small part of a bigger project. 希望我不必修改任何源代码,因为这只是较大项目的一小部分。

I found the issue and it was quite silly, but I want to explain it just in case someone else runs into a similar problem while converting from QMake. 我发现了这个问题,这很愚蠢,但是我想解释一下,以防其他人从QMake转换时遇到类似的问题。

Since my code compiled just fine using QMake I didn't look inside the actual source file EnvisionWindow.h that gcc complained about, thinking that it must be a build issue. 由于我的代码使用QMake编译得很好,因此我没有查看gcc抱怨的实际源文件EnvisionWindow.h ,认为这一定是构建问题。 When I finally had a look, I saw that this file contains no includes, which is why the compiler couldn't find a definition for Q_OBJECT . 当我最后看一看时,发现该文件包含include,这就是为什么编译器找不到Q_OBJECT的定义的原因。

The reason it worked with QMake is because that build uses a precompiled header with the -include flag used for each source file, thus injecting all necessary definitions. 它与QMake一起使用的原因是,该构建使用了预编译的标头,并在每个源文件中使用了-include标志,从而注入了所有必需的定义。 This is the behavior one gets automatically when using PRECOMPILED_HEADER = precompiled_header_name.h in a QMake .pro file. 这是在QMake .pro文件中使用PRECOMPILED_HEADER = precompiled_header_name.h时自动获得的行为。 I wish QMake didn't do this, since all files in my project are supposed to explicitly include the precompiled header. 我希望QMake不会这样做,因为我项目中的所有文件都应该明确包含预编译的头文件。

Anyway, the solution was trivial: include the precompiled header in EnvisionWindow.h and everything compiles just fine now. 无论如何,解决方案都是微不足道的:在EnvisionWindow.h包含预编译的头,现在一切都可以编译了。

Lesson learned: take the compiler error more literally. 经验教训:从字面上看编译器错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM