从cmake生成QT5的MOC文件中的错误 [英] Errors in generated MOC files for QT5 from cmake
问题描述
我使用
为QT5生成了moc文件 设置(CMAKE_AUTOMOC ON)
设置(CMAKE_INCLUDE_CURRENT_DIR ON)
然后我使用
<$>将moc文件添加到SRC p $ p>
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:错误:VideoWidget尚未声明
/ other / workspace / perception /somestuff/moc/moc_video_widget.cpp:62:19:错误:'VideoWidget'尚未声明
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:68:20:错误:'VideoWidget'没有被声明
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:68:46:错误:非成员函数'const QMetaObject * metaObject()'不能有cv-qualifier
/other/Qt5.0.1/5.0.1/gcc_64/include/QtCore/qobject.h:在函数'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:错误:在此上下文中
/other/Qt5.0.1/5.0.1/ gcc_64 / include / QtCore / qobject.h:401:33:错误:无效使用非静态数据成员'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:错误:在此上下文中
/other/Qt5.0.1/5.0.1/ gcc_64 / include / QtCore / qobject.h:401:33:错误:无效使用非静态数据成员'QObject :: d_ptr'
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:70 :50:错误:从这个位置
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:在全局范围:
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp: 73:7:错误:'VideoWidget'尚未声明
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:在函数'void * qt_metacast(const char *)':
/其他/ workspace / perception / somestuff / moc / moc_video_widget.cpp:77:47:错误:VideoWidget之前的预期类型说明
/other/workspace/perception/somestuff/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'
/其他/ workspace / perception / somestuff / moc / moc_video_widget.cpp:77:47:错误:VideoWidget未在此范围内声明
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:77: 59:错误:'>'令牌之前的预期主表达式
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:77:61:错误:在非成员函数中无效使用this
/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:错误:无法调用成员函数'virtual void * QWidget :: qt_metacast(const char *)'没有对象
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:在全局范围:
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:81:5:错误:VideoWidget尚未声明
/ other / workspace / perception / somestuff / moc / moc_video_widget .cpp:在函数'int qt_metacall(QMetaObject :: Call,int,void **)':
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:83:43:error:can not call member function'virtual int QWidget :: qt_metacall(QMetaObject :: Call,int,void **)'无对象
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:在函数'void * qt_metacast char *)':
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:79:1:warning:控制到达非void函数的结束[-Wreturn-type]
/ other /workspace/perception/somestuff/moc/moc_video_widget.cpp:在函数'const QMetaObject * metaObject()':
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:71:1:warning:control到达结束非空函数[-Wreturn-type]
make [2]:*** [CMakeFiles / somestuff.dir / moc / moc_video_widget.cpp.o]错误1
make [1] :*** [CMakeFiles / somestuff.dir / all]错误2
make:*** [all]错误2
我的理解是,在创建的moc文件中有一些错误。但我没有任何控制如何创建。现在我该如何解决这个错误?
CMake文档不是那么糟,不要忽略阅读。您误解 AUTOMOC 的概念:
AUTOMOC是一个布尔值,指定CMake是否会自动处理Qt
moc
即不必使用QT4_WRAP_CPP()
宏。目前支持Qt4。当此属性设置为TRUE
时,CMake将在构建时扫描源文件,并相应地调用moc
。如果找到#include
语句,如#includemoc_foo.cpp
,则Q_OBJECT
类声明预期在头中,moc
在头文件上运行。如果发现#include
语句,如#includefoo.moc
,则在当前源文件中需要Q_OBJECT
,并且在文件本身上运行moc
。此外,所有头文件都会被解析为Q_OBJECT
宏,如果找到,还会对这些文件执行moc
/ p>
因此,首先,您应该不添加生成的 moc
显式地将文件推送到源代码,并将其推入可执行编译。换句话说,你只推你的来源:
SET(SRC
src / main.cpp
src / video_widget_surface.cpp
src / video_widget.cpp
src / video_player.cpp)
和 moc
由CMake自动处理。
其次,如文档中所述: p>
-
如果
Q_OBJECT
位于foo.h
(即
QObject
在头文件中声明),
然后在相应的foo.cpp
不要忘记添加#includemoc_foo.cpp
,最好在文件的末尾
; p> -
如果
li>Q_OBJECT
位于foo.cpp
(即QObject
在源文件中声明),
然后再次在foo.cpp
本身
不要忘记添加#includefoo.moc
,最好在文件的结尾
。
I generated moc files for QT5 using
set (CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
Then I add the moc files into SRC using
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
Finally I add the executable using
add_executable(somegui ${SRC})
But I get errors in moc files saying :
/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
My understanding is that there is some error in the moc files that are created. But I don't have any control over how that is created. Now how do I solve this bug ?
CMake documentation is not that bad, do not neglect reading it. You misunderstood the concept of AUTOMOC:
AUTOMOC is a boolean specifying whether CMake will handle the Qt
moc
preprocessor automatically, i.e. without having to use theQT4_WRAP_CPP()
macro. Currently Qt4 is supported. When this property is set toTRUE
, CMake will scan the source files at build time and invokemoc
accordingly. If an#include
statement like#include "moc_foo.cpp"
is found, theQ_OBJECT
class declaration is expected in the header, andmoc
is run on the header file. If an#include
statement like#include "foo.moc"
is found, then aQ_OBJECT
is expected in the current source file andmoc
is run on the file itself. Additionally, all header files are parsed forQ_OBJECT
macros, and if found,moc
is also executed on those files.
So, first of all, you should not add generated moc
files explicitly to sources and push them into executable compilation. In other words, you only push your sources:
SET(SRC
src/main.cpp
src/video_widget_surface.cpp
src/video_widget.cpp
src/video_player.cpp)
and moc
ones are handled automatically by CMake.
Secondly, as stated in the documentation:
If
Q_OBJECT
is in thefoo.h
(i.e.QObject
is declared in the header file), then in the correspondingfoo.cpp
don't forget to add#include "moc_foo.cpp"
, preferably at the end of the file;If
Q_OBJECT
is in thefoo.cpp
(i.e.QObject
is declared in the source file), then, again, in thefoo.cpp
itself don't forget to add#include "foo.moc"
, preferably at the end of the file.
这篇关于从cmake生成QT5的MOC文件中的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!