13

It looks like Qt is not handling the Q_GADGET macro properly, because i am getting the error below. Anyone know why?

ERROR: undefined reference to `Exception::staticMetaObject'

EDIT: Later i found that the MOC doesn't generate moc_exception.cpp. Sometimes when i switch the compiler kit it compiles fine but than if i add another class that inherits Exception, it again doesn't work. The problem needs to be somewhere in MOC which ignores the Q_GADGET macro in some conditions?

I have Qt 5.5.0.

project.pro

CONFIG += c++11

QT += core
QT -= gui

SOURCES += \
    main.cpp

HEADERS += \
    nobject.h \
    exception.h

nobject.h

#ifndef NOBJECT_H
#define NOBJECT_H

#include <QObject>

class NObject
{

    Q_GADGET

public:
    NObject() {}
    virtual ~NObject() {}

};

#endif // NOBJECT_H

exception.h

#ifndef EXCEPTION_H
#define EXCEPTION_H

#include "nobject.h"

class Exception : public NObject
{

    Q_GADGET

public:
    Exception() {}
    virtual ~Exception() {}

};

#endif // EXCEPTION_H

main.cpp

#include <iostream>

#include "exception.h"

using namespace std;

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

    Exception nobject;

    std::cout << Exception::staticMetaObject.className() << std::endl;

    return 0;
}
Krab
  • 5,663
  • 5
  • 35
  • 73

2 Answers2

15

I suspect running qmake might solve your problem. Remember to re-run qmake every time you add or remove Q_GADGET or Q_OBJECT macro to get moc tool to re-generate code for meta data.

I didn't find any problem in your code by looking it so I copy-pasted the code to my machine and built and ran it. It built ok after I added implementation for NObject constructor. I built and ran it successfully on Qt5 and Qt4, and the program printed Exception on the console.

Qt 5:

> ~/temp/qgadgettest$ qmake --version
QMake version 3.0
Using Qt version 5.2.1 in /usr/lib/i386-linux-gnu

> /temp/qgadgettest$ ./qgadgettest 
Exception

Qt 4:

> ~/temp/qgadgettest$ qmake-qt4 --version
QMake version 2.01a
Using Qt version 4.8.6 in /usr/lib/i386-linux-gnu

> ~/temp/qgadgettest$ ./qgadgettest 
Exception
talamaki
  • 4,491
  • 1
  • 21
  • 37
  • 2
    This is one that catches me out regularly. By default, qmake adds a rule to make the Makefile when it's out of date from the project file. But it doesn't know it needs to be updated when you add one of MOC's macros to a file in `$HEADERS`. You should be able to `make -B Makefile` to force it. – Toby Speight Dec 09 '15 at 09:40
  • And what if I don't use qmake? – Hi-Angel Aug 06 '19 at 19:58
  • 1
    The beef here is to invoke moc to generate code for newly added meta object. You can run moc manually too. If you write your Makefile by hand you can check here how to automate moc running: https://doc.qt.io/qt-5/moc.html . In cmake you use specific commands in cmakelists file and re-run cmake to regenerate meta data: https://doc.qt.io/qt-5/cmake-manual.html – talamaki Aug 06 '19 at 20:28
1

In my environment, this code is correct. But I have added to the body of the constructor NObject.

Alex Gurkin
  • 99
  • 1
  • 2