Qt and CMAKE linker error
-
Yesterday, I was working on a small project using Qt and CMake. I have always used the target_include_directories() method in CMake to include the headers and build my libraries using only .cpp files, but this time the linker didn't like it.
It seems that if a class uses signals and slots, I need to include the header file (.h) when building a CMake library (using add_library()). Does anyone know why?
Thanks!
-
Hi and welcome to devnet,
What exactly is it not liking ?
Are you properly triggering moc on your QObject based classes ?
Are you including the moc generated file in the corresponding class implementation ? -
Hi, I'm getting the following errors:
/usr/bin/ld: ../lib/libCONTROLLER_LIB.so: undefined reference toTaskManagerMenu::staticMetaObject' /usr/bin/ld: ../lib/libVIEW_LIB.so: undefined reference to
vtable for TaskManagerMenu'
/usr/bin/ld: ../lib/libCONTROLLER_LIB.so: undefined reference to `TaskManagerMenu::acceptTask()'
collect2: error: ld returned 1 exit status
make[2]: *** [app/CMakeFiles/MyTasks.dir/build.make:122: bin/MyTasks] Error 1
make[1]: *** [CMakeFiles/Makefile2:1525: app/CMakeFiles/MyTasks.dir/all] Error 2
make: *** [Makefile:136: all] Error 2The .ui and .cpp files are in the same folder, but the header files are in an include folder. Below is the relevant CMake code:
file(GLOB_RECURSE VIEW_FILES "${CMAKE_CURRENT_SOURCE_DIR}/.cpp")
file(GLOB_RECURSE UI_FILES "${CMAKE_CURRENT_SOURCE_DIR}/.ui")
#file(GLOB_RECURSE HEADER_FILES "${PROJECT_SOURCE_DIR}/include/view/*.h") # Commented to force the erroradd_library(VIEW_LIB ${VIEW_FILES} ${UI_FILES} ${HEADER_FILES})
target_link_libraries(VIEW_LIB PUBLIC Qt6::Core Qt6::Widgets)
target_include_directories(VIEW_LIB PUBLIC
"${PROJECT_SOURCE_DIR}/include/view"
)This CMake script is included in another script where I call the function qt_standard_project_setup().
I was able to resolve the error by including the .h files in the add_library command, but when working without Qt, I could just use the .cpp files and then use target_include_directories to include the headers. I’m wondering why this issue occurs with Qt.
-
If you have classes derived from QObject you have to run moc on them which generates code, this generated code then needs to be included into the build of your library. Take a look at https://cmake.org/cmake/help/latest/prop_tgt/AUTOMOC.html