目录

一、qt程序编译时调用moc

二、qmake组装makefile中的moc_*.cpp生成规则

三、通过qt工程文件向moc传入参数


一、qt程序编译时调用moc

qtcreator对qt程序的编译过程是先“qmake” ,然后“构建(等价于make)”。

qtcreator右键点击项目 出现的 “执行qmake”和“构建” 两个选项其实就是运行 项目-》build->构建步骤 中的“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博客

二、qmake组装makefile中的moc_*.cpp生成规则

qmake 组装makefile中的moc_*.cpp生成规则的调用堆栈如下:

qmake组装moc_*.cpp生成规则调用堆栈
//E:\workspace\QtWork\qmake\generators\makefile.cpp
QString
MakefileGenerator::replaceExtraCompilerVariables(const QString &orig_var, const QStringList &in, const QStringList &out, ReplaceFor forShell)
{
......if(val.isEmpty() && var.startsWith(QLatin1String("QMAKE_FUNC_"))) {const ProKey funcname = var.mid(11).toKey();val += project->expand(funcname, QList<ProStringList>() << ProStringList(in) << ProStringList(out));}
......-----------------------------------------------
//E:\workspace\QtWork\qmake\project.cpp
QStringList QMakeProject::expand(const ProKey &func, const QList<ProStringList> &args)
{
......QHash<ProKey, ProFunctionDef>::ConstIterator it =m_functionDefs.replaceFunctions.constFind(func);if (it != m_functionDefs.replaceFunctions.constEnd()) {ProStringList ret;if (evaluateFunction(*it, args, &ret) == QMakeProject::ReturnError)exit(3);return ret.toQStringList();}
....
}
.....-------------------------
//E:\workspace\QtWork\qmake\library\qmakeevaluator.cpp
......
QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFunction(const ProFunctionDef &func, const QList<ProStringList> &argumentsList, ProStringList *ret)
{VisitReturn vr;if (m_valuemapStack.count() >= 100) {evalError(fL1S("Ran into infinite recursion (depth > 100)."));vr = ReturnFalse;} else {m_valuemapStack.push(ProValueMap());m_locationStack.push(m_current);ProStringList args;for (int i = 0; i < argumentsList.count(); ++i) {args += argumentsList[i];m_valuemapStack.top()[ProKey(QString::number(i+1))] = argumentsList[i];}m_valuemapStack.top()[statics.strARGS] = args;m_valuemapStack.top()[statics.strARGC] = ProStringList(ProString(QString::number(argumentsList.count())));vr = visitProBlock(func.pro(), func.tokPtr());if (vr == ReturnReturn)vr = ReturnTrue;if (vr == ReturnTrue)*ret = m_returnValue;m_returnValue.clear();m_current = m_locationStack.pop();m_valuemapStack.pop();}return vr;
}
.......

调用的部分代码如上:replaceExtraCompilerVariables()中传入expand函数的变量funcname值为:mocCmdBase,expand内部调用evaluateFunction,该函数作用是调用 用qmake language写的replace函数。也就是说断点处的目的是调用qmake language写的函数mocCmdBase()。

找到配置文件中的mocCmdBase()函数代码如下:

//QtInstallDir\Qt5.12.0\5.12.0\msvc2015_64\mkspecs\features\moc.prf
.......
defineReplace(mocCmdBase) {!isEmpty(WIN_INCLUDETEMP) {incvar = @$$shell_quote($$WIN_INCLUDETEMP)} else {incvar =for (inc, MOC_INCLUDEPATH): \incvar += -I$$shell_quote($$inc)incvar += $$QMAKE_FRAMEWORKPATH_FLAGS}RET = $$QMAKE_MOC $(DEFINES)msvc: RET += --compiler-flavor=msvcisEmpty(MOC_PREDEF_FILE): RET += $$join(QMAKE_COMPILER_DEFINES, " -D", -D)else: RET += --include $$shell_quote($$absolute_path($$moc_predefs.output, $$OUT_PWD))RET += $$incvar $$QMAKE_MOC_OPTIONSreturn($$RET)
}
.......

可以将上面的mocCmdBase中的RET与下面具体的moc_*.cpp生成规则做一下对照,QMAKE_MOC_OPTIONS是在某个prf或pri或conf配置文件中用qmake language预定义全局变量,表示传递给moc的参数,在pro中可以使用:

 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工程(pro)文件向moc传入参数

知道了moc的调用和组装规则,及相应逻辑,通过pro文件对moc传入参数就变得很显而易见了
直接在pro文件中加入如下代码:

QMAKE_MOC_OPTIONS = "-M yy=ttet"

通过pro文件对moc传递参数

pro文件设置moc参数后会写入到生成的makefile.debug中

最终生成的qt_pluginMetaData[]会变成如下:

//moc_*.cpp
QT_PLUGIN_METADATA_SECTION
static constexpr unsigned char qt_pluginMetaData[] = {'Q', 'T', 'M', 'E', 'T', 'A', 'D', 'A', 'T', 'A', ' ', '!',// metadata version, Qt version, architectural requirements0, QT_VERSION_MAJOR, QT_VERSION_MINOR, qPluginArchRequirements(),0xbf, // "IID"0x02,  0x78,  0x1c,  'E',  'x',  'a',  'm',  'p', 'l',  'e',  's',  '.',  'P',  'l',  'u',  'g', 'i',  'n',  '.',  'C',  'a',  'l',  'I',  'n', 't',  'e',  'r',  'f',  'a',  'c',  'e', // "className"0x03,  0x69,  'C',  'a',  'l',  'P',  'l',  'u', 'g',  'i',  'n', // "MetaData"0x04,  0xa2,  0x62,  'i',  'd',  0x78,  0x1c,  'E', 'x',  'a',  'm',  'p',  'l',  'e',  's',  '.', 'P',  'l',  'u',  'g',  'i',  'n',  '.',  'C', 'a',  'l',  'I',  'n',  't',  'e',  'r',  'f', 'a',  'c',  'e',  0x64,  'n',  'a',  'm',  'e', 0x69,  'C',  'a',  'l',  'P',  'l',  'u',  'g', 'i',  'n', // command-line "yy"0x62,  'y',  'y',  0x81,  0x64,  't',  't',  'e', 't', 0xff,
};
QT_MOC_EXPORT_PLUGIN(CalPlugin, CalPlugin)

另外还可以通过Q_PLUGIN_METADATA所绑定的json文件传递meta内容到qt_pluginMetaData中参考如下:

Q_PLUGIN_METADATA Q_INTERFACE Q_DECLARE_INTERFACE qt_pluginMetaData_丘上人的博客-CSDN博客_q_plugin_metadata

moc所支持的参数

qtcreator编译qt程序是如何调用moc的,如何通过pro文件向moc传入参数相关推荐

  1. Qt开发 — 使用脚本自动编译Qt程序

    Qt开发 - 使用脚本自动编译Qt程序 Mac OS 1.编译之前我们先打开Qt Create 点击重编译工程.注意观看 控制台 了解重新编译的过程 根据提示可以知道重新编译经过一下过程: 1./us ...

  2. Ubuntu下编译qt程序libQtWebEngineCore报错

    最近在Ubuntu下编译qt程序时, 报如下错误 libQt5WebEngineCore.so: .dynsym local symbol at index 3 (>= sh_info of 3 ...

  3. 命令行编译Qt程序(qmake+jom/Nmake/mingW)

    命令行编译Qt程序(qmake+jom/Nmake/mingW) 一.创建工程,生成以下几个文件 二.命令行编译 创建三个bat文件,分别使用以下三种方式编译 1.qmake+jom编译,使用wind ...

  4. UOS20编译Qt程序:搭环境、解决bug

    一.开发环境搭建 1.UOS专业版操作系统 系统:UOS20 处理器架构:X86_64 UOS系统下载链接:见此文 2.Qt库.QtCreator工具的安装 由于Qt支持跨平台,处理器架构均可以兼容, ...

  5. linux qt编译命令,linux下使用命令模式去编译Qt程序

    1.打开终端输入,qmake -v ,如果提示版本信息正,就可以编译程序了. 2.当前目录切换到程序源代码目录,cd /home/likewei/untitled2 3.生成untitled2.pro ...

  6. 中标麒麟linux卸载qt,国产化 银河麒麟编译Qt程序的问题汇总 | 阿拉灯

    Run in terminal 莫名奇妙软件无法在QtCreator中运行或者调试,main函数都无法进入,QtCreator中一运行就崩溃,并跳到汇编界面,这多半和代码没什么关系,我这里是将项目-& ...

  7. linux编译器 如何处理函数,在linux系统中,编译c程序,如何调用fmod函数

    1. 编译指示指令 C和C++的每个实现对它的主机或操作系统都支持一些独有的特征.例如,某些程序须对存放数据的存储器区域进行精确的控制,或必须控制特定函数接受参量的方式.#pragma指令对每个编译器 ...

  8. TX2下编译qt程序步骤

    1. 将~/aarch64-qt_5.15.1.tar.bz2  解压到/opt 2. 在 ~/.bashrc 添加qt的库和路进 art@art-desktop:/opt$ cat ~/.bashr ...

  9. CMake编译Widget UI Qt程序

    自从CMake被引入到KDE项目的编译系统中后,CMake的使用者日益增多,Qt也不例外,除了使用QMAKE编译Qt程序外,也可以使用CMake来编译Qt程序,并且CMake在使用上更灵活,特别是大型 ...

  10. Qt入门01 创建第一个Qt程序

    一.安装Qt及Qt Creator 1.Qt下载地址 常用的工具也在这些地方可以找到,当然也可以直接官网下载,考入到网速因素,国内的镜像源网站还是要更快一些.Qt 5.15 之后已经不提供离线安装包了 ...

最新文章

  1. python selenium unittest_python+selenium+unittest——ui自动化的轻量级选择
  2. 在git下搭建个人博客
  3. 内存首地址为1000h_C++虚继承,菱形继承,内存分布
  4. 与数学实验第二版艾冬梅_吉林省实验繁荣新初一师资大起底,快来看看娃的老师长啥样?...
  5. Google 节日徽标全集 (1999-2009) (下)
  6. 芯唐语音识别_大联大品佳推出基于新唐科技ISD9160+Cyberon算法的语音识别方案
  7. 信息学奥赛C++语言:石头剪子布
  8. 物联网领域的新贵LoRa
  9. jeecg字典表-系统字典
  10. Linux驱动基础知识(一)
  11. 特征选择-相关系数法F检验
  12. 134安装教程_最新市政造价教程
  13. NLP炼丹技巧:标签平滑label smoothing
  14. 如何打开usb计算机连接打印机驱动,打印机USB连接安装设置及常见问题处理
  15. PV(访问量)、UV(独立访客)、IP(独立IP) (转)
  16. 哈尔滨理工大学21级新生程序设计竞赛(同步赛)Jay的小迷弟(快速幂)
  17. WebApp最佳实践用户体验篇之如何针对多种屏幕尺寸设计合理的移动应用
  18. FTDI通用转USB芯片简述
  19. xdoj 238 数组鞍点 二维数组 循环
  20. IDEA 各种疑难杂症

热门文章

  1. 乔治城大学计算机科学硕士2019,乔治城大学2019THE世界大学排名最新排名第109
  2. 想考华为认证HCIP-RoutingSwitching,应该看什么书?
  3. QInputDialog,QTextEdit,QLineEdit,Qt右键菜单英文转中文问题
  4. ffmpeg -progress读取进度
  5. 一个系统同时装office2007和2019时遇到的问题及解决方案
  6. matlab分析地形,matlab绘制地形图
  7. 计算机网页设计与制作论文,网页设计与制作毕业论文
  8. 安装vue-cli脚手架使用swiper
  9. 如何一键关闭win安全中心(Windows Defender )
  10. linux两台电脑共享文件夹怎么设置,快速几步完美实现两台电脑共享上网的设置...