无需规则即可将目标设为 .moc

No rule needed to make target .moc

本文关键字:目标 moc 规则      更新时间:2023-10-16

我正在尝试将ovpn3的ovpncli示例转换为派生自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次。尽管如此,它仍然拒绝工作。我做错了什么?

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:
. . .

TL;博士

只需删除您的build-xxx文件夹,然后从头开始重建!

上下文

您(几乎)永远不必包含.moc文件。Moc 文件由mocompiler 自动创建,并在专用的翻译单元中编译和链接(即与任何.cpp文件一样)。

唯一的例外是在cpp文件中声明QObject类时(恰好是这种情况!),因为.moc实现仍然需要类定义来编译。正如评论中所建议的,这里有一个详细的解释。

潜在问题

关于您的特定问题,moc文件问题可能源于:

  • 缺少Q_OBJECT关键字(但您有它)。此令牌用于触发该特定类的.moc文件的生成。没有它,大多数QObject功能都会丢失。
  • 该类以前在没有Q_OBJECT关键字的情况下被解析/编译,并缓存为非 QObject 类。在这种情况下,您只需手动删除构建文件夹(或手动运行qmake),即可再次强制识别应moc哪些类。
  • 您对moced 文件使用了错误的文件名。正确的名称通常是
    • moc_filename.cpp在头文件中声明类时
    • filename.moc在源文件中声明类的时间
  • qmake实际上不会解析您的.cpp文件。如果您的.pro文件未将其包含在SOURCES变量中,或者您只是从未运行过qmake(特定设置等),则可能会出现这种情况。

示例生成文件

您可以仔细检查您的moc文件在其项目的 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