用qt 编译qt moc

使用windows下qt版本5.12.0

目的:为更好的理解qt特性、meta系统的细节、moc工作的原理,去查看和调试moc代码。

注意:qtcreator对qt程序的编译过程是先qmake然后构建(等价于make)。从项目->build->构建步骤可以看出,构建过程中先用qmake生成makefile,make过程用jom和前面产生的makefile生成目标程序的exe。jom按makefile规则的运行过程中根据依赖会先调用moc.exe生成moc_*.cpp文件,然后是按正常C++编译过程进行C++预编译(宏替换),再然后是C++编译。也就是说moc生成moc_*.cpp代码是在C++编译器进行预编译之前!jom具体如何调用moc的过程请参考:qt 工程构建过程 默认构建路径设置 通过Dos窗口运行命令编译qt工程_丘上人的博客-CSDN博客_qt执行dos命令

 将qt moc的工程从源码中拷贝到工作目录中。将moc.pro的内容替换成如下,操作只有添加“QT+=core-private”  和注释 “#load(qt_tool)”

option(host_build)
QT+=core-private
CONFIG += force_bootstrap

DEFINES += \
    QT_MOC \
    QT_NO_CAST_FROM_ASCII \
    QT_NO_CAST_FROM_BYTEARRAY \
    QT_NO_COMPRESS \
    QT_NO_FOREACH

include(moc.pri)
HEADERS += qdatetime_p.h
SOURCES += main.cpp

QMAKE_TARGET_DESCRIPTION = "Qt Meta Object Compiler"
#load(qt_tool)

base.h 

#ifndef BASE_H
#define BASE_H

#include <QObject>
class CalInterface
{
public:
    virtual ~CalInterface() {}
    virtual int add(int a,int b) = 0;
};


#define CalInterface_iid "Examples.Plugin.CalInterface"

QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(CalInterface,CalInterface_iid)
QT_END_NAMESPACE


class CalPlugin : public QObject,public CalInterface
{
    Q_OBJECT
    Q_INTERFACES(CalInterface)
    Q_PLUGIN_METADATA(IID CalInterface_iid FILE "calplugin.json")

public:
    explicit CalPlugin(QObject *parent = nullptr);
    int add(int a,int b);
};
#endif // BASE_H

 calplugin.json

{
    "name": "CalPlugin",
	"id":"Examples.Plugin.CalInterface"
}

将base.h和calplugin.json 放到moc.exe文件所在路径下,命令行运行
moc.exe base.h -o moc_base.cpp

就能生成moc文件了。

这是qt工程执行qmake后自动生成的makefile.debug中生成moc_*.cpp的命令(关于qmake具体如何组装该条命令可以查看下面的链接):

D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\bin\moc.exe $(DEFINES) --compiler-flavor=msvc --include E:/workspace/QtWork/build-plugandpaint-Desktop_Qt_5_12_0_MSVC2015_64bit-Debug/plugins/extrafilters/debug/moc_predefs.h -ID:/Qt/Qt5.12.0/5.12.0/msvc2015_64/mkspecs/win32-msvc -IE:/workspace/QtWork/plugandpaint/plugins/extrafilters -IE:/workspace/QtWork/plugandpaint/app -ID:/Qt/Qt5.12.0/5.12.0/msvc2015_64/include -ID:/Qt/Qt5.12.0/5.12.0/msvc2015_64/include/QtWidgets -ID:/Qt/Qt5.12.0/5.12.0/msvc2015_64/include/QtGui -ID:/Qt/Qt5.12.0/5.12.0/msvc2015_64/include/QtANGLE -ID:/Qt/Qt5.12.0/5.12.0/msvc2015_64/include/QtCore -I. -I"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE" -I"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.14393.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.14393.0\shared" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.14393.0\um" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.14393.0\winrt" -M yy=ttet ..\..\..\plugandpaint\plugins\extrafilters\extrafiltersplugin.h -o debug\moc_extrafiltersplugin.cpp

题外:

qt工程的moc代码的生成是在make(运行jom,qt的默认make工具是jom.exe)的时候,在Makefile.Debug中可以看到生成的exe对moc_*.obj有依赖,而moc_*.obj又对moc_*.cpp有依赖,而moc_*.cpp由下面的规则进行生成。

//Makefile.Debug
.....
debug\moc_base.cpp: D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\QObject \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qobject.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qobjectdefs.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qnamespace.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qglobal.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qconfig-bootstrapped.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qconfig.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qtcore-config.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qsystemdetection.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qprocessordetection.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qcompilerdetection.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qtypeinfo.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qsysinfo.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qlogging.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qflags.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qatomic.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qbasicatomic.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qatomic_bootstrap.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qgenericatomic.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qatomic_cxx11.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qatomic_msvc.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qglobalstatic.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qmutex.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qnumeric.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qversiontagging.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qobjectdefs_impl.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qstring.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qchar.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qbytearray.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qrefcount.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qarraydata.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qstringliteral.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qstringalgorithms.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qstringview.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qstringbuilder.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qlist.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qalgorithms.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qiterator.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qhashfunctions.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qpair.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qbytearraylist.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qstringlist.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qregexp.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qstringmatcher.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qcoreevent.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qscopedpointer.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qmetatype.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qvarlengtharray.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qcontainerfwd.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qobject_impl.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\QTimer \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qtimer.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\include\QtCore\qbasictimer.h \
		..\testEmpty\base.h \
		debug\moc_predefs.h \
		D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\bin\moc.exe
	D:\Qt\Qt5.12.0\5.12.0\msvc2015_64\bin\moc.exe $(DEFINES) --compiler-flavor=msvc --include E:/workspace/QtWork/build-testEmpty-Desktop_Qt_5_12_0_MSVC2015_64bit/debug/moc_predefs.h -ID:/Qt/Qt5.12.0/5.12.0/msvc2015_64/mkspecs/win32-msvc -IE:/workspace/QtWork/testEmpty -ID:/Qt/Qt5.12.0/5.12.0/msvc2015_64/include -ID:/Qt/Qt5.12.0/5.12.0/msvc2015_64/include/QtWidgets -ID:/Qt/Qt5.12.0/5.12.0/msvc2015_64/include/QtGui -ID:/Qt/Qt5.12.0/5.12.0/msvc2015_64/include/QtANGLE -ID:/Qt/Qt5.12.0/5.12.0/msvc2015_64/include/QtNetwork -ID:/Qt/Qt5.12.0/5.12.0/msvc2015_64/include/QtCore -I. -I"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE" -I"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.14393.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.14393.0\shared" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.14393.0\um" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.14393.0\winrt" ..\testEmpty\base.h -o debug\moc_base.cpp

qtcreator编译qt程序是如何调用moc,如何通过pro文件向moc传入参数_丘上人的博客-CSDN博客

makefile的规则_如来fo的博客-CSDN博客_makefile规则

qt 工程构建过程 默认构建路径设置 通过Dos窗口运行命令编译qt工程_丘上人的博客-CSDN博客_qt路径配置

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值