Для создания целевого .moc не требуется никаких правил

Я пытаюсь превратить пример 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++ применяется в различных областях, включая разработку игр, системное программирование и встраиваемые системы.


1
1 491
1

Ответ:

TL;DR

Просто удалите папку build-xxx и создайте заново!

Контекст

Вам (почти) никогда не придется включать файл .moc. Файлы Moc автоматически создаются компилятором moc, компилируются и связываются в специальной единице перевода (то есть как любой файл .cpp).

Единственным исключением является случай, когда ваш QObject-класс объявлен в cpp-файле (это ваш случай!), потому что .moc-реализация по-прежнему потребует компиляции вашего определения класса. Как было предложено в комментариях, есть подробное объяснение здесь.

Возможные проблемы

Что касается вашей конкретной проблемы, проблемы с файлами moc могут возникать из-за:

  • ключевое слово Q_OBJECT отсутствует (но оно у вас есть). Этот токен используется для запуска создания файла .moc для этого конкретного класса. Без него большинство функций QObject отсутствуют.
  • класс был проанализирован/скомпилирован ранее без ключевого слова Q_OBJECT и кэширован как класс, отличный от QObject. В этом случае вам просто нужно вручную удалить папку сборки (или запустить qmake вручную), чтобы снова определить, какие классы должны быть moced.
  • Вы используете неправильное имя файла для вашего файла moced. Правильное название обычно
    • moc_filename.cpp когда ваш класс объявлен в заголовочном файле
    • filename.moc когда ваш класс объявлен в исходном файле
  • qmake на самом деле не анализирует ваш .cpp файл. Это может быть в том случае, если ваш файл .pro не включает его в переменную SOURCES или если вы просто никогда не запускаете qmake (конкретная настройка и т. д.).

Пример Makefile

Вы можете дважды проверить, что ваши 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