12

I've got a relatively simple Qt 5.0 project that uses CMake 2.8.9:

CMakeLists.txt:

cmake_minimum_required(VERSION 2.8.9)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
project(hello-world)

find_package(Qt5Widgets REQUIRED)
qt5_wrap_ui(hello-world_UI MainWindow.ui)

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

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

    public:

        MainWindow();
        virtual ~MainWindow();

    private:

        Ui::MainWindow * const ui;
};

#endif // CMAINWINDOW_H

MainWindow.cpp:

#include "MainWindow.h"
#include "ui_MainWindow.h"

MainWindow::MainWindow()
    : ui(new Ui::MainWindow)
{
}

MainWindow::~MainWindow()
{
    delete ui;
}

main.cpp:

#include <QApplication>
#include "MainWindow.h"

int main(int argc, char * argv[])
{
    QApplication app(argc, argv);

    MainWindow win;
    win.show();

    return app.exec();
}

The project also includes a .ui file created with Qt Creator 2.6.1 (MainWindow.ui).

When I attempt to build the file with g++ on Linux, I receive the following errors:

CMakeFiles/hello-world.dir/MainWindow.cpp.o: In function `MainWindow::MainWindow()':
MainWindow.cpp:(.text+0x3b): undefined reference to `vtable for MainWindow'
MainWindow.cpp:(.text+0x4d): undefined reference to `vtable for MainWindow'
CMakeFiles/hello-world.dir/MainWindow.cpp.o: In function `MainWindow::~MainWindow()':
MainWindow.cpp:(.text+0xaf): undefined reference to `vtable for MainWindow'
MainWindow.cpp:(.text+0xc1): undefined reference to `vtable for MainWindow'
collect2: error: ld returned 1 exit status

What could possibly be causing this sort of error? I recently switched to CMake from qmake and I never remember running into this much trouble getting a trivial example to compile. What am I doing wrong?


Edit: here is the command being used to link everything:

/usr/bin/c++ CMakeFiles/hello-world.dir/MainWindow.cpp.o
CMakeFiles/hello-world.dir/main.cpp.o -o hello-world -rdynamic
/usr/local/Qt-5.0.0/lib/libQt5Widgets.so.5.0.0
/usr/local/Qt-5.0.0/lib/libQt5Gui.so.5.0.0
/usr/local/Qt-5.0.0/lib/libQt5Core.so.5.0.0 
-Wl,-rpath,/usr/local/Qt-5.0.0/lib
Nathan Osman
  • 71,149
  • 71
  • 256
  • 361

3 Answers3

21

Turns out I forgot:

set(CMAKE_AUTOMOC ON)

At the top of the CMakeLists.txt file.

Nathan Osman
  • 71,149
  • 71
  • 256
  • 361
  • 2
    I do have set(CMAKE_AUTOMOC ON) but I still see the same error as you were seeing. Also, my link command is the same as yours. Can you please help? – Vaibhav Desai Jan 15 '13 at 20:14
  • 1
    Also, the moc file "nova_app_automoc.cpp" generated for the target "nova_app" has this in it: /* This file is autogenerated, do not edit*/ enum some_compilers { need_more_than_nothing }; – Vaibhav Desai Jan 15 '13 at 20:18
  • 8
    I'm having almost the exact same problem, yet I have set(CMAKE_AUTOMOC ON) already in my CMakeLists.txt and yet I still get the problem!! – Adam Miller Jul 11 '13 at 22:48
  • 1
    @AdamMiller I know this is old but in case somebody else is having the same issue, cmake needs to know where to find the headers. Before I GLOBed all my headers in with my sources, I was getting the issue you had. By verbose building I could see automoc was generating nothing. – regomodo Dec 01 '20 at 21:19
  • 1
    @regomodo, You are a lifesaver! I forgot to add my header files to the CMake `add_library` function. Thank you. – Saeed Masoomi Oct 23 '22 at 18:56
5

I struggled with this for a long time using all the hints published here:

http://doc.qt.io/qt-5/cmake-manual.html

And here

https://www.kdab.com/using-cmake-with-qt-5/

What I had to do was specify things in the right order. For example, the following is the top of my CMakeLists.txt. Note that the two CMAKE set directives come before add_executable. Once I did this, I was able to link without undefined symbols and vtable references. I just thought I'd post this for the benefit of others.

cmake_minimum_required (VERSION 2.8)

set (CMAKE_AUTOMOC ON)
set (CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(FHSpectrumSensor wideband_seq_spectrum_sensor.cpp sensor.cpp   gui.cpp ${gui_SRC})

Later in the CMakeLists.txt I have the following:

 find_package(Qt5Widgets REQUIRED)
 find_package(Qt5Charts REQUIRED)
 find_package(Qt5Core REQUIRED)

 qt5_use_modules(FHSpectrumSensor Widgets Charts)
 qt5_wrap_cpp(gui_SRC gui.h gui.cpp)

That did the trick.

  • 1
    Worked for me thanks ! the problem was solved with `qt5_wrap_cpp(gui_SRC gui.h gui.cpp)`. actually instead of gui.cpp I added .h files and that was the problem, now I changed them to .cpp files and problem solved thank you. – SdSaati Sep 23 '18 at 17:10
3

I also ran into this problem yesterday and the above mentioned answers did't help. I already used set (CMAKE_AUTOMOC ON) and also qt5_wrap_cpp.

I tried to remember what I did, because I had a working version but it stopped working after "some" changes. I finally remembered that I tried to split the include files into a separate directory hierarchy. After reverting that and putting the include files back into the CMakeLists.txt it worked again. I sure don't know why, and I would like to know what went wrong, but I settled now for keeping the includes near the cpp files.

set(SOURCES
    buffer.h
    ITVSet.h
    MainWindow.h
    MainWindow.cpp
    TVSet.h
    TVSet.cpp
)
Devolus
  • 21,661
  • 13
  • 66
  • 113
  • 1
    when you added `MainWindow.h` to SOURCES or you can split to project_HEADERS , then the header is included in the build and moc files are generated for that header – Mohammad Kanan Jul 05 '22 at 12:23