Я пытаюсь превратить пример ovpncli ovpn3 в класс, производный от QObject. Я не могу превратить исходный файл в отдельный файл интерфейса (.h) и реализации (.cpp). Чтобы сделать MOC счастливым, я поставил #include "openvpn.moc"
в конце openvpn.cpp (исходный файл). Однако я получаю эту ошибку: :-1: error: No rule to make target 'openvpn.moc', needed by 'openvpnmanager.o'. Stop.
Я очистил каталог сборки, повторно запустил qmake и пересобрал его 1000 раз. Несмотря на это, он по-прежнему отказывается работать. Что я делаю неправильно?
мой проект.про:
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:
. . .
🤔 А знаете ли вы, что...
Язык C++ применяется в различных областях, включая разработку игр, системное программирование и встраиваемые системы.
Просто удалите папку build-xxx
и создайте заново!
Вам (почти) никогда не придется включать файл .moc
. Файлы Moc автоматически создаются компилятором moc
, компилируются и связываются в специальной единице перевода (то есть как любой файл .cpp
).
Единственным исключением является случай, когда ваш QObject
-класс объявлен в cpp
-файле (это ваш случай!), потому что .moc
-реализация по-прежнему потребует компиляции вашего определения класса. Как было предложено в комментариях, есть подробное объяснение здесь.
Что касается вашей конкретной проблемы, проблемы с файлами moc
могут возникать из-за:
Q_OBJECT
отсутствует (но оно у вас есть). Этот токен используется для запуска создания файла .moc
для этого конкретного класса. Без него большинство функций QObject отсутствуют.Q_OBJECT
и кэширован как класс, отличный от QObject. В этом случае вам просто нужно вручную удалить папку сборки (или запустить qmake
вручную), чтобы снова определить, какие классы должны быть moc
ed.moc
ed. Правильное название обычно
moc_filename.cpp
когда ваш класс объявлен в заголовочном файлеfilename.moc
когда ваш класс объявлен в исходном файлеqmake
на самом деле не анализирует ваш .cpp
файл. Это может быть в том случае, если ваш файл .pro
не включает его в переменную SOURCES
или если вы просто никогда не запускаете qmake
(конкретная настройка и т. д.).Вы можете дважды проверить, что ваши moc
файлы имеют соответствующие правила в Makefile своего проекта. Ниже приведен образец части 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