Qt 5 cmake fails with undefined reference to vtable on hello world with inc & src as subdirs

As noted, moc is not processing MainWindow.h in your example. One way to force this to happen is to call qt_wrap_cpp() on it directly (instead of on MainWindow.cpp) and then include the resulting file in the call to add_executable().

Your top level CMakeLists.txt might look like:

cmake_minimum_required(VERSION 2.8.9)

#set(CMAKE_AUTOMOC ON)

set(CMAKE_PREFIX_PATH "/opt/Qt/5.1.1/gcc_64")
set(CMAKE_INCLUDE_CURRENT_DIR ON)

project(hello-world)

find_package(Qt5Widgets REQUIRED)

set(HW_HEADER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/inc)
set(HW_GUI_DIR ${CMAKE_CURRENT_SOURCE_DIR}/gui)

include_directories(${HW_HEADER_DIR})

subdirs(src)

and your src level one like:

qt5_wrap_cpp(hello-world_SRC ${HW_HEADER_DIR}/MainWindow.h)
qt5_wrap_ui(hello-world_UI ${HW_GUI_DIR}/MainWindow.ui)

add_executable(hello-world MainWindow.cpp main.cpp
               ${hello-world_UI} ${hello-world_SRC})
qt5_use_modules(hello-world Widgets)

Addendum:

  • This works in your example with and without AUTOMOC enabled. I don't know for sure if having it on will cause issues in the future. If you don't enable it you'll have to manually moc any other stuff... although it might all behave like MainWindow in which case you'll be manually mocing the headers regardless.
  • You don't have to set the directory variables in the top level CMakeLists.txt but I find it cleaner than doing qt5_wrap_cpp(hello-world_SRC ../inc/MainWindow.h)
  • There might be a better way of doing this.
  • For anybody else with similar issues, so far this solution has held up in the larger project that I initially encountered this in. I will update accordingly if it fails.

Well, maybe automoc does not work for you, I would guess it's because CMake does not find the corresponding files. Check the documentation here: http://www.cmake.org/cmake/help/v2.8.12/cmake.html#prop_tgt:AUTOMOC

In this case, you can always call the moc command manually for them in your CMakeLists.txt:

qt5_wrap_cpp(moc_sources src/MainWindow.cpp)
qt5_wrap_ui(uic_sources src/MainWindow.cpp)

list(APPEND library_sources ${moc_sources} ${uic_sources})

Note: you have to make sure you use the list command correctly yourself. This code example is from my project where I use a specific list of sources (library_sources).

It is just a guess but you should try without the automagic first to rule out one possible source of error.

Also make sure that you fully deleted the CMake cache after changing your directory structure.


I had the same problem and found a solution. As Eric Lemanissier commented in an issue on GitHub:

This error is not related to conan: you need to add your header files in add_executable, otherwise the moc won't parse them

The header files have to be added to the project using an add_executable or add_library statement. If this is not done, automoc won't parse the files.