5

I have a project which uses Qt5 and I have a CMakeLists.txt file that I use for creating the Visual Studio Solution.

This is an excerpt of my CMakeLists.txt

cmake_policy(SET CMP0020 NEW)
set(CMAKE_AUTOMOC ON)
find_package(Qt5 REQUIRED COMPONENTS core widgets)

set(COMMON_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/src)

include_directories( ${Boost_INCLUDE_DIRS}
    ${COMMON_INCLUDE_DIR}
)


file(GLOB_RECURSE COMMON_SOURCE "*.hpp" "*.cpp")
add_library(${PROJECT_NAME} ${COMMON_SOURCE})
qt5_use_modules(${PROJECT_NAME} Widgets)

When I try to compile the code it returns the following error:

>AUTOMOC : error : C:/Users/.../Projects/MyProject/build/MyProjects_automoc.cpp The file includes the moc file "moc_MyFile.cpp", but could not find header "MyFile{.h,.hh,.h++,.hm,.hpp,.hxx,.in,.txx}" in C:/Users/.../Projects/MyProject/build/

The moc file have been auto-generated and the header is not in the build folder, but in a folder locate in the src directory.

How is possible to fix this error?

Maverik
  • 2,358
  • 6
  • 34
  • 44
  • what version of CMake are you using? – Tab Nov 09 '13 at 05:13
  • is it working well if you put all files in dir where CMakeList.txt is located and INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} )` – Tab Nov 11 '13 at 09:19

1 Answers1

9

It is good to add:

set(CMAKE_INCLUDE_CURRENT_DIR ON)

when using the AUTOMOC feature. Furthermore, this

include_directories(
  ...
  ${QT_USE_FILE}
  ...
)

is a mistake. It should rather be:

include(${QT_USE_FILE})

Finally, you should only explicitly push sources to compilation, but not headers! 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.

Therefore, follow these recommendations and change

file(GLOB_RECURSE COMMON_SOURCE "*.hpp" "*.cpp")

to

file(GLOB_RECURSE COMMON_SOURCE "*.cpp")

You could also find my other answer helpful. Your question is very similar, so I'd recommend to search better before posting next time.

Good luck.

Community
  • 1
  • 1
Alexander Shukaev
  • 16,674
  • 8
  • 70
  • 85
  • 2
    Thanks, the first suggestion seems to work. Regarding the second I edited the question, I didn't include `${QT_USE_FILE}`, it was a copying error. Seems that `include(${QT_USE_FILE})` is also not necessary. `qt5_use_modules(${PROJECT_NAME} Widgets)` should take care of it. For the last suggestion I have to include all the sources, because I want to operate on them in Visual Studio. – Maverik Nov 14 '13 at 13:44
  • However, having Q_OBJECT in a header should be enough to create moc files. CMake will behave in this way, too, if the header files are in the same folders as the source files. qmake will behave in this way with out-of-source headers, as well... this is just something CMake does not seem to support (talking of 3.9) – IceFire Oct 31 '17 at 21:43
  • 2
    Adding moc_foo.cpp to every source you write seems WAY worse to me than adding header files as sources to CMake target. Ideally CMake should run AUTOMOC on files in include directories but this still does not seem to happen (CMake 3.15). – Jan Hošek Feb 18 '20 at 11:56
  • Agreed with @JanHošek. Although it would be better if CMake handled MOC for header files automatically, explicitly providing headers to the target is better than manually including moc sources. It seems CMAKE_INCLUDE_CURRENT_DIR has no effect in this method. – Burak Sep 13 '22 at 05:03