moc file not found
-
Using Qt Creator 12.0.1, plodding along just fine until all of a sudden, moc files are no longer getting created. This was working before, but now I get an error saying that the moc file cannot be found. How do I get this working again? I have reduced my code to the following. Why is this not compiling?
#include <QCoreApplication> #include <QTest> class TestQString: public QObject { Q_OBJECT private slots: void toUpper() { QString str = "Hello"; QVERIFY(str.toUpper() == "HELLO"); } }; QTEST_MAIN(TestQString) #include "testqstring.moc" -
Using Qt Creator 12.0.1, plodding along just fine until all of a sudden, moc files are no longer getting created. This was working before, but now I get an error saying that the moc file cannot be found. How do I get this working again? I have reduced my code to the following. Why is this not compiling?
#include <QCoreApplication> #include <QTest> class TestQString: public QObject { Q_OBJECT private slots: void toUpper() { QString str = "Hello"; QVERIFY(str.toUpper() == "HELLO"); } }; QTEST_MAIN(TestQString) #include "testqstring.moc"Please show your CMakeLists.txt
-
Please show your CMakeLists.txt
@Christian-Ehrlicher Thanks. I don't see that file. I'm using qmake. There is a generated makefile that is too large to attach.
-
@Christian-Ehrlicher Thanks. I don't see that file. I'm using qmake. There is a generated makefile that is too large to attach.
-
@jsulm Here is the pro file:
QT = core testlib CONFIG += c++17 cmdline # You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ tests.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target -
@jsulm Here is the pro file:
QT = core testlib CONFIG += c++17 cmdline # You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ tests.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += targetWhy do you include testqstring.moc when your source file is tests.cpp?
-
Why do you include testqstring.moc when your source file is tests.cpp?
@Christian-Ehrlicher Beat me to it.
The qmake "magic" that generates a Makefile rule for
mocwhen it sees this style of include requires that it matches on the base name of the source file concerned. -
@Christian-Ehrlicher Beat me to it.
The qmake "magic" that generates a Makefile rule for
mocwhen it sees this style of include requires that it matches on the base name of the source file concerned.The mismatch is due to my attempt to simplify before posting. This is my actual main file, named tests.cpp. And yes, both
TestOneToOneandTestOneToManyhave theQ_OBJECTmacro.#include <QCoreApplication> #include <QTest> #include "TestOneToOne.h" #include "TestOneToMany.h" int main(int argc, char *argv[]) { int status = 0; status |= QTest::qExec(new TestOneToOne, argc, argv); status |= QTest::qExec(new TestOneToMany, argc, argv); return status; } #include "TestOneToOne.moc" #include "TestOneToMany.moc" -
The mismatch is due to my attempt to simplify before posting. This is my actual main file, named tests.cpp. And yes, both
TestOneToOneandTestOneToManyhave theQ_OBJECTmacro.#include <QCoreApplication> #include <QTest> #include "TestOneToOne.h" #include "TestOneToMany.h" int main(int argc, char *argv[]) { int status = 0; status |= QTest::qExec(new TestOneToOne, argc, argv); status |= QTest::qExec(new TestOneToMany, argc, argv); return status; } #include "TestOneToOne.moc" #include "TestOneToMany.moc"There is no need for foo.moc files when it's in a header. Then qmake/cmake automatically creates and adds moc_foo.cpp files.
-
There is no need for foo.moc files when it's in a header. Then qmake/cmake automatically creates and adds moc_foo.cpp files.
@Christian-Ehrlicher Without the moc files, I get:
ld: Undefined symbols: vtable for TestOneToOne, referenced from: _main in tests.o vtable for TestOneToMany, referenced from: _main in tests.oWith the moc files, it was working until this afternoon. Somehow I broke something, but I don't know what.
-
@Christian-Ehrlicher Without the moc files, I get:
ld: Undefined symbols: vtable for TestOneToOne, referenced from: _main in tests.o vtable for TestOneToMany, referenced from: _main in tests.oWith the moc files, it was working until this afternoon. Somehow I broke something, but I don't know what.
Please show a minmal, compileable example and move code into source files and not in headers. qmake will not generate a moc_foo.cpp when there is no corresponding source file.
-
@Christian-Ehrlicher Without the moc files, I get:
ld: Undefined symbols: vtable for TestOneToOne, referenced from: _main in tests.o vtable for TestOneToMany, referenced from: _main in tests.oWith the moc files, it was working until this afternoon. Somehow I broke something, but I don't know what.
The headers need to be listed in the PRO file:
HEADERS += TestOneToOne.h TestOneToMany.hand
qmakere-run. The magic moc includes are not required.Edit: Maybe @Christian-Ehrlicher has a point: a one-to-one header-source relationship.
-
The headers need to be listed in the PRO file:
HEADERS += TestOneToOne.h TestOneToMany.hand
qmakere-run. The magic moc includes are not required.Edit: Maybe @Christian-Ehrlicher has a point: a one-to-one header-source relationship.
@ChrisW67 said in moc file not found:
Edit: Maybe @Christian-Ehrlicher has a point: a one-to-one header-source relationship
I'm not completely sure since I don't use qmake since 15 years or so but how else should qmake know that it has to moc those files.
-
Hi,
You can see in this thread a way to put together multiple tests.
That said, it will break the output. You should really keep the one class per test file.
@Christian-Ehrlicher the moc file include is standard when you define classes in the implementation file. It has some other benefits.
This blog article gives a pretty good summary about them.
-
Hi,
You can see in this thread a way to put together multiple tests.
That said, it will break the output. You should really keep the one class per test file.
@Christian-Ehrlicher the moc file include is standard when you define classes in the implementation file. It has some other benefits.
This blog article gives a pretty good summary about them.
Minimal code. First
main.cpp#include <QCoreApplication> #include <QTest> QTEST_MAIN(TestQString)And
qteststring.h:#pragma once #include <QObject> class TestQString: public QObject { Q_OBJECT private slots: void toUpper(); };And
qteststring.cpp:#include <QTest> #include "testqstring.h" void TestQString::toUpper() { QString str = "Hello"; QCOMPARE(str.toUpper(), QString("HELLO")); } #include "testqstring.moc"Finally the auto-generated
.profile:QT = core CONFIG += c++17 cmdline # You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ main.cpp \ testqstring.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target HEADERS += \ testqstring.hResulting output:
make: *** No rule to make target `testqstring.moc', needed by `testqstring.o'. Stop. make: *** Waiting for unfinished jobs.... ../Test_with_qmake/main.cpp:2:10: fatal error: 'QTest' file not found #include <QTest> ^~~~~~~ 1 error generated. make: *** [main.o] Error 1 14:28:39: The process "/usr/bin/make" exited with code 2. Error while building/deploying project Test_with_qmake (kit: Qt 6.6.1 for macOS) When executing step "Make"BTW I have never seen a
moc_*.cpp, only a*.moc, and then only until yesterday afternoon, when it stopped working altogether.
Should I be usingcmake? I have no preference. I'm usingqmakeonly because it was the default. -
Minimal code. First
main.cpp#include <QCoreApplication> #include <QTest> QTEST_MAIN(TestQString)And
qteststring.h:#pragma once #include <QObject> class TestQString: public QObject { Q_OBJECT private slots: void toUpper(); };And
qteststring.cpp:#include <QTest> #include "testqstring.h" void TestQString::toUpper() { QString str = "Hello"; QCOMPARE(str.toUpper(), QString("HELLO")); } #include "testqstring.moc"Finally the auto-generated
.profile:QT = core CONFIG += c++17 cmdline # You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ main.cpp \ testqstring.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target HEADERS += \ testqstring.hResulting output:
make: *** No rule to make target `testqstring.moc', needed by `testqstring.o'. Stop. make: *** Waiting for unfinished jobs.... ../Test_with_qmake/main.cpp:2:10: fatal error: 'QTest' file not found #include <QTest> ^~~~~~~ 1 error generated. make: *** [main.o] Error 1 14:28:39: The process "/usr/bin/make" exited with code 2. Error while building/deploying project Test_with_qmake (kit: Qt 6.6.1 for macOS) When executing step "Make"BTW I have never seen a
moc_*.cpp, only a*.moc, and then only until yesterday afternoon, when it stopped working altogether.
Should I be usingcmake? I have no preference. I'm usingqmakeonly because it was the default.@rpieket said in moc file not found:
#include <QTest>
Then you should also add the correct qmake command as written in the documentation.
-
Minimal code. First
main.cpp#include <QCoreApplication> #include <QTest> QTEST_MAIN(TestQString)And
qteststring.h:#pragma once #include <QObject> class TestQString: public QObject { Q_OBJECT private slots: void toUpper(); };And
qteststring.cpp:#include <QTest> #include "testqstring.h" void TestQString::toUpper() { QString str = "Hello"; QCOMPARE(str.toUpper(), QString("HELLO")); } #include "testqstring.moc"Finally the auto-generated
.profile:QT = core CONFIG += c++17 cmdline # You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ main.cpp \ testqstring.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target HEADERS += \ testqstring.hResulting output:
make: *** No rule to make target `testqstring.moc', needed by `testqstring.o'. Stop. make: *** Waiting for unfinished jobs.... ../Test_with_qmake/main.cpp:2:10: fatal error: 'QTest' file not found #include <QTest> ^~~~~~~ 1 error generated. make: *** [main.o] Error 1 14:28:39: The process "/usr/bin/make" exited with code 2. Error while building/deploying project Test_with_qmake (kit: Qt 6.6.1 for macOS) When executing step "Make"BTW I have never seen a
moc_*.cpp, only a*.moc, and then only until yesterday afternoon, when it stopped working altogether.
Should I be usingcmake? I have no preference. I'm usingqmakeonly because it was the default.@rpieket
The file names in the PRO file do not match those in your post.Simple fix so that qmake now finds files.
A Qt test is just another Qt program, following all the same rules. It is just that the Test Lib writes main() for you to allow it to provide a lot of plumbing for you behind the scenes.
If you have the test class declaration in a separate header, as in this case, then that header should be listed in the PRO file HEADERS variable and not in the source file as an#include "blah.moc".No longer get:
make: *** No rule to make target `testqstring.moc', needed by `testqstring.o'. StopThe QT variable in the PRO file needs
QT += testlibso that the test Lib elements are included at compile and link time.
Rerun qmake after changing the PRO fileNo longer get:
./Test_with_qmake/main.cpp:2:10: fatal error: 'QTest' file not foundRemaining problems are to do with the construction of the sources and not qmake.
main.cpp needs to#include "qteststring.h"so that the QTEST_MAIN macro expansion, which references TestString, knows what the class looks like.Test compiles