3

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 ?

Alexander Shukaev
  • 16,674
  • 8
  • 70
  • 85
navderm
  • 799
  • 2
  • 11
  • 33

1 Answers1

10

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 the QT4_WRAP_CPP() macro. Currently Qt4 is supported. When this property is set to TRUE, CMake will scan the source files at build time and invoke moc accordingly. If an #include statement like #include "moc_foo.cpp" is found, the Q_OBJECT class declaration is expected in the header, and moc is run on the header file. If an #include statement like #include "foo.moc" is found, then a Q_OBJECT is expected in the current source file and moc is run on the file itself. Additionally, all header files are parsed for Q_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 the foo.h (i.e. QObject is declared in the header file), then in the corresponding foo.cpp don't forget to add #include "moc_foo.cpp", preferably at the end of the file;

  • If Q_OBJECT is in the foo.cpp (i.e. QObject is declared in the source file), then, again, in the foo.cpp itself don't forget to add #include "foo.moc", preferably at the end of the file.

Alexander Shukaev
  • 16,674
  • 8
  • 70
  • 85
  • Thanks for this. My Q_OBJECT is in foo.h. When I add the "moc_foo.cpp" at the end of the file it gives an AUTOMOC error saying the header file which is being included in moc_foo.cpp was not found in either ./src or ./src/moc. I am assuming I need to change some setting for it to look in different directory. My include path includes the folder where the header file is. What can I do to make the automoc point to ./include/project – navderm May 10 '13 at 16:44
  • Is `set(CMAKE_INCLUDE_CURRENT_DIR ON)` there? What is `src/moc`? `moc` files should be generated into the build directory (with which you should **not** mess), and therefore adding `set(CMAKE_INCLUDE_CURRENT_DIR ON)` should do the trick, as the build directory will be added into the include path automatically too. – Alexander Shukaev May 10 '13 at 17:21
  • yeah it is on. but it still gives me the error. I tried tinkering around with AUTOMOC_MOC_OPTIONS but to no avail. – navderm May 10 '13 at 17:49
  • Where the `moc_foo.cpp` is generated? – Alexander Shukaev May 10 '13 at 17:50
  • it is generated in moc folder in the main folder. at the same level as src and include – navderm May 10 '13 at 17:50
  • Why? Did you configure it to do so? – Alexander Shukaev May 10 '13 at 17:51
  • i expected the .cpp files to be in the build dir but thats not the case with mine. i can send you the cmakelist.txt if you'd like to take a look at it – navderm May 10 '13 at 17:51
  • No. I simply told it set(cmake_automoc on) and set(cmake_include_current_dir on) – navderm May 10 '13 at 17:51
  • Hey. sorry i asked the guy who had worked on the qt project and he said the moc folder was generated by qmake. we are trying to add cmake and qmake both to the project. Here is a link to the cmakelist.txt http://pastebin.com/gZXw68En – navderm May 10 '13 at 18:00
  • It might have old piece of code. I had stashed before pasting – navderm May 10 '13 at 18:03
  • That's really bad, you should not mix these build systems. In fact, QMake is inferior to CMake, and I suggest that you abandon it completely. Do the build of your project with pure CMake and report the results, once again `moc` files should be generated in the build directory. They should not exist in the source tree of your project at all. – Alexander Shukaev May 10 '13 at 18:10
  • I'm sorry, but then you'd have to arrange all these preferences with your team, and I can't help you any further. Now your problem has nothing to do with CMake, but only with your strange supervisor. My answer is absolutely correct and would work if your team wouldn't mess up with mixing 2 build systems (which is incredibly weird and useless from my point of view). By the way, next time, you should include such information into your question to avoid further confusion among answerers. – Alexander Shukaev May 10 '13 at 18:33
  • 1
    Of course you can do `include_directories("directory where MOC files are generated")` to solve this problem. But in general what your team does in terms of build system, is just so bad. – Alexander Shukaev May 10 '13 at 18:37