Undefined reference to VTable when using cmake
-
When I attempt to compile a program, it causes a linker error, and the usual fixes aren't working.
CMakeFiles/aoeu.dir/src/reader.cc.obj:reader.cc:(.rdata$.refptr._ZTV6reader[.refptr._ZTV6reader]+0x0): undefined reference to `vtable for reader'
When I try to include
reader.moc
, I get an include error. When I move everything tomain.cc
, and compile it there, it works. I do intend to use slots and stuff in my class, so I do need to include Q_OBJECT.I'm using MSYS2, g++ and ld.
CMakeLists.txt
# Standards and versions cmake_minimum_required(VERSION 3.30.0) set(CMAKE_CXX_STANDARD_REQUIRED 17) # Metadata project(aoeu VERSION 0.0.0 LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR TRUE) set(CMAKE_AUTOMOC ON) # Packages find_package(Qt6 COMPONENTS Widgets REQUIRED) file(GLOB_RECURSE SOURCES ${PROJECT_SOURCE_DIR}/src/*.cc) add_executable(${PROJECT_NAME} ${SOURCES}) # Pch files target_precompile_headers(${PROJECT_NAME} PRIVATE <QtWidgets>) target_include_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/include") target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Widgets)
#include <QtWidgets> #include "reader.hh" int main(int argc, char **argv) { QApplication app(argc, argv); QWidget window; window.show(); // Placeholder for actual text previewing reader textBox("boeu", &window); return app.exec(); }
reader.hh
#if !defined(READER_HH) #define READER_HH #include <QPlainTextEdit> class reader : public QPlainTextEdit { Q_OBJECT public: reader(QString text, QWidget *parent = nullptr); virtual ~reader(); }; // `fatal error: reader.moc: No such file or directory` if uncommented // #include "reader.moc" #endif
#include "reader.hh" reader::reader(QString text, QWidget *parent) : QPlainTextEdit(text, parent) { setReadOnly(true); } reader::~reader() {}
-
The root cause of this problem is the separation of C++ source files from header files. The separation hides
reader.hh
from AUTOMOC and results in no generated code for this class.
Placing all of these sources and includes in the same directory links correctly.You can repair this by adding the header files to the
add_executable()
calls beside the SOURCES. There may be other/better ways to achieve this. -
@ChrisW67 said in Undefined reference to VTable when using cmake:
The root cause of this problem is the separation of C++ source files from header files. The separation hides
reader.hh
from AUTOMOC and results in no generated code for this class.
Placing all of these sources and includes in the same directory links correctly.You can repair this by adding the header files to the
add_executable()
calls beside the SOURCES. There may be other/better ways to achieve this.Sorry, this has not helped the issue. When including
reader.moc
, it still fails to run the moc. In addition, when removing thereader.moc
include, I had another linker error.multiple definition of `reader::staticMetaObject'; CMakeFiles/aoeu.dir/aoeu_autogen/mocs_compilation.cpp.obj:U:/repos/novelreader/build/aoeu_autogen/UVLADIE3JM/moc_reader.cpp:63: first defined here
-
You have to include the header, not the generated moc file
-
I see. I've managed to fix the issues.
Changes I've made to solve it:
- Added .hh files to sources.
- Removed
#include "reader.moc"
.
Just to clarify, when do you need to use
#include "file.moc"
? It's been suggested as a solution to the vtable include error by many people. -
-
You only have to include the moc file in the source file when you declared a qobject derived class in the source instead the header.
-
I see, thanks for explaining.