问题
I am trying to turn ovpn3's ovpncli example into a class that derives from QObject. I'm unable to turn the source file into a separate interface (.h) and implementation (.cpp) file. To make the MOC happy, I've put #include "openvpn.moc" at the end of openvpn.cpp (the source file). I am getting this error however: :-1: error: No rule to make target 'openvpn.moc', needed by 'openvpnmanager.o'. Stop. I've cleaned the build directory, re-ran qmake, and rebuilt it 1000 times. Despite this, it still refuses to work. What am I doing wrong?
myproject.pro:
QT += core widgets network
CONFIG += c++11
UI_SOURCES_DIR = src/gui
UI_HEADERS_DIR = include
. . .
SOURCES += \
src/main.cpp \
src/gui/loginwindow.cpp \
src/api/api.cpp \
src/openvpn/openvpn.cpp \
src/alert.cpp \
src/gui/vpn.cpp \
src/api/account.cpp \
src/crypto.cpp \
src/killswitch.cpp \
src/vpnstatus.cpp \
src/gui/logdialog.cpp \
src/logitem.cpp \
src/authenticationworker.cpp \
src/api/error.cpp \
src/openvpn/openvpnmanager.cpp \
src/api/server.cpp \
src/api/authenticationresponse.cpp
HEADERS += \
include/loginwindow.h \
include/api.h \
include/alert.h \
include/vpn.h \
include/account.h \
include/crypto.h \
include/killswitch.h \
include/configtype.h \
include/vpnstatus.h \
include/connectionstatus.h \
include/loglevel.h \
include/logdialog.h \
include/logitem.h \
include/authenticationworker.h \
include/error.h \
include/openvpnmanager.h \
include/server.h \
include/authenticationresponse.h \
FORMS += \
src/gui/loginwindow.ui \
src/gui/vpn.ui \
src/gui/logdialog.ui
RESOURCES += \
src/resources.qrc
DISTFILES +=
openvpn.cpp:
class Client : public QObject, public ClientAPI::OpenVPNClient {
Q_OBJECT
public:
. . .
回答1:
TL;DR
Simply delete your build-xxx folder, and rebuild from scratch!
Context
You (almost) never have to include a .moc file. Moc files are created automatically by the mocompiler and compiled and linked in a dedicated translation unit (i.e. like any .cpp file).
The only exception is when your QObject class is declared in a cpp file (which happens to be your case!), because the .moc implementation will still require your class definition to compile. As suggested in the comments, there is a detailed explanation here.
Potential issues
Regarding your specific issue, moc file issues can originate from:
- the
Q_OBJECTkeyword is missing (but you have it). This token is used to trigger the generation of a.mocfile for that specific class. Without it, most QObject features are missing. - the class was parsed/compiled previously without the
Q_OBJECTkeyword, and cached as a non-QObject class. In that case, you just have to manually delete your build folder (or runqmakemanually), to force identifying again which classes should bemoced. - You are using the wrong filename for your
moced file. The correct name is typicallymoc_filename.cppwhen your class is declared in a header filefilename.mocwhen your class is declared in a source file
qmakedoes not actually parses your.cppfile. This can be the case if your.profile doesn't include it in theSOURCESvariable, or if you are just never runningqmake(specific setup, etc.)
Sample Makefile
You can double check it your moc files has appropriate rules in the Makefile of its project. Below is a sample portion of a Makefile:
compiler_moc_source_make_all: mysourcefile.moc
compiler_moc_source_clean:
-$(DEL_FILE) mysourcefile.moc
mysourcefile.moc: /home/aleravat/Qt/5.9.7/gcc_64/include/QtCore/QCoreApplication \
/home/aleravat/Qt/5.9.7/gcc_64/include/QtCore/qcoreapplication.h \
/home/aleravat/Qt/5.9.7/gcc_64/include/QtCore/qglobal.h \
/home/aleravat/Qt/5.9.7/gcc_64/include/QtCore/qconfig-bootstrapped.h \
# [...] more includes
/home/aleravat/Qt/5.9.7/gcc_64/bin/moc $(DEFINES) --include ./moc_predefs.h [...] mysourcefile.cpp -o mysourcefile.moc
来源:https://stackoverflow.com/questions/55369520/no-rule-needed-to-make-target-moc