【问题标题】:Errors in generated MOC files for QT5 from cmake从 cmake 为 QT5 生成的 MOC 文件中的错误
【发布时间】:2013-05-09 22:59:22
【问题描述】:

我使用

为 QT5 生成了 moc 文件
set (CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)

然后我使用

将 moc 文件添加到 SRC
SET(SRC
  src/main.cpp
  src/video_widget_surface.cpp
  src/video_widget.cpp
  src/video_player.cpp
#moc files
  moc/moc_video_player.cpp
  moc/moc_video_widget.cpp
  moc/moc_video_widget_surface.cpp

最后我使用添加可执行文件

add_executable(somegui ${SRC})

但我在 moc 文件中收到错误提示:

/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:54:6: error: 'VideoWidget' has not been declared
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:62:19: error: 'VideoWidget' has not been declared
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:68:20: error: 'VideoWidget' has not been declared
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:68:46: error: non-member function 'const QMetaObject* metaObject()' cannot have cv-qualifier
/other/Qt5.0.1/5.0.1/gcc_64/include/QtCore/qobject.h: In function 'const QMetaObject* metaObject()':
/other/Qt5.0.1/5.0.1/gcc_64/include/QtCore/qobject.h:401:33: error: 'QScopedPointer<QObjectData> QObject::d_ptr' is protected
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:70:21: error: within this context
/other/Qt5.0.1/5.0.1/gcc_64/include/QtCore/qobject.h:401:33: error: invalid use of non-static data member 'QObject::d_ptr'
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:70:21: error: from this location
/other/Qt5.0.1/5.0.1/gcc_64/include/QtCore/qobject.h:401:33: error: 'QScopedPointer<QObjectData> QObject::d_ptr' is protected
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:70:50: error: within this context
/other/Qt5.0.1/5.0.1/gcc_64/include/QtCore/qobject.h:401:33: error: invalid use of non-static data member 'QObject::d_ptr'
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:70:50: error: from this location
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp: At global scope:
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:73:7: error: 'VideoWidget' has not been declared
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp: In function 'void* qt_metacast(const char*)':
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:77:47: error: expected type-specifier before 'VideoWidget'
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:77:47: error: expected '>' before 'VideoWidget'
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:77:47: error: expected '(' before 'VideoWidget'
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:77:47: error: 'VideoWidget' was not declared in this scope
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:77:59: error: expected primary-expression before '>' token
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:77:61: error: invalid use of 'this' in non-member function
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:77:67: error: expected ')' before ';' token
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:78:40: error: cannot call member function 'virtual void* QWidget::qt_metacast(const char*)' without object
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp: At global scope:
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:81:5: error: 'VideoWidget' has not been declared
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp: In function 'int qt_metacall(QMetaObject::Call, int, void**)':
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:83:43: error: cannot call member function 'virtual int QWidget::qt_metacall(QMetaObject::Call, int, void**)' without object
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp: In function 'void* qt_metacast(const char*)':
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:79:1: warning: control reaches end of non-void function [-Wreturn-type]
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp: In function 'const QMetaObject* metaObject()':
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:71:1: warning: control reaches end of non-void function [-Wreturn-type]
make[2]: *** [CMakeFiles/somestuff.dir/moc/moc_video_widget.cpp.o] Error 1
make[1]: *** [CMakeFiles/somestuff.dir/all] Error 2
make: *** [all] Error 2

我的理解是创建的 moc 文件中存在一些错误。但我无法控制它的创建方式。现在我该如何解决这个错误?

【问题讨论】:

    标签: qt cmake qt5 moc


    【解决方案1】:

    CMake 文档还不错,不要忽视阅读它。你误解了AUTOMOC的概念:

    AUTOMOC 是一个布尔值,指定 CMake 是否会自动处理 Qt moc 预处理器,即无需使用 QT4_WRAP_CPP() 宏。目前支持 Qt4。当此属性设置为TRUE 时,CMake 将在构建时扫描源文件并相应地调用moc。如果找到类似#include "moc_foo.cpp"#include 语句,则应在标头中声明Q_OBJECT,并在标头文件中运行moc。如果找到了类似#include "foo.moc"#include 语句,则在当前源文件中需要Q_OBJECT,并且在文件本身上运行moc。此外,所有头文件都被解析为Q_OBJECT 宏,如果找到,moc 也会在这些文件上执行。

    因此,首先,您应该将生成的moc 文件显式添加到源并将它们推送到可执行编译中。换句话说,你只推送你的来源:

    SET(SRC
      src/main.cpp
      src/video_widget_surface.cpp
      src/video_widget.cpp
      src/video_player.cpp)
    

    moc 由 CMake 自动处理。

    其次,如文档所述:

    • 如果Q_OBJECTfoo.h中(即QObject在头文件中声明), 然后在对应的foo.cpp 不要忘记添加#include "moc_foo.cpp",最好在最后 文件;

    • 如果Q_OBJECTfoo.cpp 中(即QObject 在源文件中声明), 然后,再次,在foo.cpp 本身 别忘了加#include "foo.moc",最好在最后 文件。

    【讨论】:

    • 谢谢。我的 Q_OBJECT 在 foo.h 中。当我在文件末尾添加“moc_foo.cpp”时,它会给出一个 AUTOMOC 错误,指出在 ./src 或 ./src/moc 中都找不到包含在 moc_foo.cpp 中的头文件。我假设我需要更改一些设置才能在不同的目录中查看。我的包含路径包括头文件所在的文件夹。我该怎么做才能使 automoc 指向 ./include/project
    • set(CMAKE_INCLUDE_CURRENT_DIR ON) 在吗? src/moc 是什么? moc 文件应该生成到构建目录中(你应该混乱),因此添加 set(CMAKE_INCLUDE_CURRENT_DIR ON) 应该可以解决问题,因为构建目录将自动添加到包含路径中也是。
    • 是的,它已开启。但它仍然给我错误。我尝试修改 AUTOMOC_MOC_OPTIONS 但无济于事。
    • moc_foo.cpp 是在哪里生成的?
    • 当然可以include_directories("directory where MOC files are generated")来解决这个问题。但总的来说,您的团队在构建系统方面所做的工作实在是太糟糕了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 2014-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多