一个例子让你秒懂 Qt Creator 编译原理
小北师兄作品
首发于微信公众号 小北师兄
微信 ID: ncuneupa
由于排版原因,文章可能读起来不太清晰,如果想看更好的排版,可以来我的公众号:小北师兄
大家好,我是你们的小北师兄,由于工作原因,最近师兄在自学 Qt 相关知识,说起来师兄在校期间是研究算法的,一般都是纯 C++ 来实现
当时电脑环境以 Linux 发行版 Ubuntu 为主,到了工作中就转向了 Windows,刚开始确实有一些不太习惯,在 Windows 上配置环境一般比较繁琐,而且有些问题网上还不容易找到
下面进入正题,使用过 Qt 的都知道,我们一般建立一个 Qt 工程,都是在 Qt Creator 中根据向导进行建立,这样比较方便,师兄根据之前使用 CMake / Gcc 的经验,所以对 Qt 的编译过程感兴趣,这样以后出了问题,即使不上网,也可以根据自己的理解,找到问题所在
师兄在网上找到了一个参考资料“Qt Creator 快速入门”,(关注公众号,后台回复 "Qt" ,就可以获取这个资料的电子版及源码)。
这本书就简单介绍了这个编译过程,师兄根据资料上的说明,以及自己的试验过程,对这个问题有了一个更深的理解。
小伙伴们不要失望,师兄写这篇文章可不是直接照搬资料上的内容,相信小伙伴们通读下来绝对会有收获!
文章目录
1 Qt Creator 新建项目及编译过程
2 命令行编译:
1.1 用 Qt 自带环境进行编译
1.2 在 Cmd 终端中直接进行编译
1.3 拓展
本机环境:Windows10 企业版 64 位 + QT5.9.9 + MinGw 5.30 32 位
1 Qt Creator 新建项目及编译过
师兄这里拿出资料上的一个例子(没有 ui 文件的),我们在 Qt Creator 创建一个 Empty qmake project (空项目),然后自己添加 C++ 文件 main.cpp,该源文件内容如下:
#include <QApplication>#include <QDialog>
#include <QLabel>int main(int argc, char **argv) {
QApplication a(argc, argv);
QDialog w;
w.resize(400, 300);
QLabel label(&w);
label.move(120, 120);
label.setText(QObject::tr("Hello"));
w.show();
return a.exec();
}
编辑 .pro 文件,添加 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
即可,然后编译该程序,可以看到编译输出结果如下图 1 所示
图 1 Qt Creator 编译输出结果
小伙伴请对图片上红色框起来的内容 mingw32-make
留个印象,下面还会用到这个。编译完成后就可直接正常运行。
可以看到,用 Qt Creator 创建项目/编译运行项目非常简单,几步操作下来就可以运行一个程序。
2 命令行编译:
为了了解 Qt Creator 背后为大家做的工作,需要知道如何用命令行编译这个程序。我们先建立一个文件夹 2-2-2,然后将上面写好代码的 main.cpp 原封不动的拷贝到这个文件夹中,目前为止,准备工作完毕,接下来进入正题。
在 Windows 中,需要打开 cmd 这个终端程序(定位到 2-2-2 目录),然后按照如下命令即可编译 Qt 程序,主要步骤如下:
- 调用 qmake -project 生成 .pro 文件,在该文件中添加
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
这句话 - 调用 qmake 生成 Makefile 文件和 debug / release 目录等等,
- 调用 mingw32-make 读取 Makefile 然后对代码进行编译链接(内部调用的是 gcc/g++ 编译器),生成 .exe 文件到 release 目录,默认的是 release 版本,如果想要 debug 版本,可以使用
mingw32-make -f Makefile.Debug
这个命令来代替(下面会说如何知道的)
Note: 如果不知道到 qmake,以及 mingw32-make 都有哪些选项,可以使用 --help
参数来查看,比如 qmake --help
,就会列出该命令一些选项参数介绍。
下面以两种方法进行命令行编译
1.1 用 Qt 自带环境进行编译
在电脑的菜单栏中找到 Qt5.9.9(MinGw 5.3.0 32-bit) 这个终端程序(对应到你自己的 Qt 版本即可,这个是 Qt 的运行环境),然后跳转到你的工作目录中,使用上面的命令即可。
1)打开电脑开始界面选择 Qt5.9.9(MinGw 5.3.0 32-bit) 这个终端程序,如下图 2 所示
图 2 Qt 自带环境终端
2)按照下图 3,图 4 方法进行操作即可
图 3 终端运行命令及结果
这里有两点需要注意:
在使用
qmake -project
之后,需要在生成的.pro
文件中进行 Qt 库的包含,比如我这里就需要添加greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
这一行代码。黄色画线地方,在这个终端中,前面必须加上
/d
才能跳转到对应的文件夹中,然后再用 qmake -project 即可生成 .pro 文件
继续按照下图 4 方式操作
图 4 终端运行命令及结果
从参考资料上,只说了默认生成 .exe 在 release 文件夹中,没有说明如何生成 debug 版本的 .exe 文件,所以我特意观察了一下 mingw32-make 的输出信息,从上图的红横线部分可以看到 mingw32-make -f Makefile.Release
是读取 Makefile.Release 文件内容进行编译的,结果输出就会进入 release 目录,所以我查看了 mingw32-make 的选项参数,发现 -f 是指定哪个 Makefile 文件的,因此就得出mingw32-make -f Makefile.Debug
会输出到 debug 目录中,经过实验验证了。
之后通过键入如下命令 cd release &&``2-2-2.exe
就可以正常运行程序了
3)我们可以大致看一下 Makefile 内容,如下图 5 所示
图 5 Makefile 文件内容
可以看到 CC CXX 表示用了什么编译器,这里用了 gcc/g++,链接器使用了 g++,等等,从这里都可以看到编译程序需要哪些库以及编译选项
1.2 在 Cmd 终端中直接进行编译
在 Win + R
输入 cmd 进入终端,跳转到对应文件夹中,然后运行上述命令,但要注意,你必须要配置好系统的 PATH 环境变量才行,比如我自己配置的环境变量如下图 6 所示
图 6 本机系统环境变量配置信息
之后依次运行以下命令即可
qmake -project` 之后修改 .pro 文件,在运行下面命令,`qmake && mingw32-make
cd release && 2-2-2.exe
即可运行程序
**
**
1.3 拓展
如果按照上面的方法来做,相信大家肯定能够成功运行(师兄研究半天才得出的终极结论),但是师兄第一次实验就没有这么幸运了,走了好多弯路,下面师兄就把自己遇到的问题,中间思考过程以及最终结论一一说明
如果你们用过 Qt 开发过界面程序,那么肯定遇到过类似下图的问题:
图 7 遇到的问题
师兄做这个实验也遇到了这个问题,首先,师兄没有使用 Qt 自带的运行环境(哈哈 师兄当时可能是飘了,不过不飘就不会得出上面的终极结论分享给大家了,算了算还是不亏的),就直接打开了 cmd ,然后调用上面 qmake -project ,qmake,mingw32-make 直接一波操作操,心想,肯定可以直接运行了
没想到现实 pia pia pia~,运行 .exe 时就出现了上面的提示,师兄当时就蒙了, QT 自带环境也是在终端运行的啊,我也是在终端运行的啊,我在安装 Qt 的时候也设置了环境变量了,为什么会出现这个问题呢?
想必大家也是跟师兄有着同样的问题,先看一下这个问题,一般引起这个问题都是缺少相应的 dll 结尾的动态链接库,那么好办了,经过我这两天对 Qt 的了解,还真的有一个解决方法,那么就是用 Qt 自带的部署程序 windeployqt
,通过这个程序就可以将一些依赖自动复制到你的文件夹中了,然后在运行就会发现解决了,如图 8 所示
图 8 利用 windeployqt 程序运行结果
图 8 中红色框都是 windeployqt 部署程序生成的,会自动的把你的依赖全部拷贝过来,这种也是将自己的程序,放到没有 Qt 环境的计算机上运行的必备操作。
到这里你以为就完了,不不不,还远远没到,师兄觉得每次命令行编译完成后都要部署一下才能运行太麻烦,说明这个方案不适用于平常的开发,只是一种可选择方案,师兄觉得这个解决方案就用来发布程序就行了。
这又回到了问题的开始,还记得上面师兄说过这么一句,师兄不用 Qt 自带的环境,就在 cmd 命令行中直接键入相应的命令,之后才出现了问题,那咱们就顺藤摸瓜,这个 Qt 环境与我自己直接在命令行中键入命令有什么不一样吗?
打开计算机开始界面,找到 Qt 自带环境的应用程序,如下图 9 所示
图 9 Qt 自带环境探索结果
鼠标右键点击 Qt5.9.9(MinGw 5.3.0 32-bit) 之后点击“开文件位置”,得到如下图 10 所示
图 10 Qt 自带环境探索结果 2
可以看到,这里最终会调用一个 qtenv2.bat 的一个脚本文件,目标是:C:\Windows\System32\cmd.exe /A /Q /K D:\Qt\Qt5.9.9\5.9.9\mingw53_32\bin\qtenv2.bat
,(这里多说一句,我们也可以在启动文件夹中仿照这种方法,执行自己的脚本文件,进而配置相应的环境),到对应文件夹下打开该文件,其内容如下图 11 所示:
图 11 qtenv2.bat 内容
可以看到,这里就设置了一下 PATH 的环境变量,师兄之前也在电脑上设置了环境变量,但是好像与这个有点不一样,如下图 12 所示,这是师兄最开始自己电脑的环境变量
图 12 本机最开始的环境变量
经过仔细对比,师兄发现这里多了一个 D:\Qt\Qt5.9.9\Tools\QtCreator\bin;
,且顺序有一点不同,但也仅仅是多了这一个路径而已,没想到会出现这么大的问题,师兄突发奇想,难道真的是多了一个路径才造成这样的结果吗?如果填加了这个路径,那么顺序变化会不会有影响呢?
接下来师兄就做了如下实验,我直接将这个看似多余的路径给删除了,也就是图 6 所示,然后在 cmd 中进行 qmake && mingw32-make 命令,继续运行 2-2-2.exe ,此时就会正常运行
到目前为止,我们找到了问题所在,也就是多出来的这个路径造成的,相信大家到这里还是会有疑问,如果不去掉这个路径还会出现这个问题吗?
师兄又做了下面几个实验,分别设置了 PATH 的环境变量,仅仅顺序不一样,在 cmd 中设置一下环境变量顺序,并且从新执行 qmake mingw32-make 命令,下面仅仅列出路径的顺序及对应结果,具体实验结果图就省略了:
set PATH=D:\Qt\Qt5.9.9\5.9.9\mingw53_32\bin;D:/Qt/Qt5.9.9/Tools/mingw530_32\bin;D:\Qt\Qt5.9.9\Tools\QtCreator\bin;%PATH%
结论:这个可以运行
set PATH=D:/Qt/Qt5.9.9/Tools/mingw530_32\bin;D:\Qt\Qt5.9.9\5.9.9\mingw53_32\bin;D:\Qt\Qt5.9.9\Tools\QtCreator\bin;%PATH%
结论:可以运行,说明 Tools/mingw530_32\ 和 5.9.9\mingw53_32 互换位置也可以,它们两个顺序没有影响
set PATH=D:/Qt/Qt5.9.9/Tools/mingw530_32\bin;D:\Qt\Qt5.9.9\Tools\QtCreator\bin;D:\Qt\Qt5.9.9\5.9.9\mingw53_32\bin;%PATH%
结论:不可以运行,说明 Tools\QtCreator 路径要在 5.9.9\mingw53_32 路径后
set PATH=D:\Qt\Qt5.9.9\5.9.9\mingw53_32\bin;D:\Qt\Qt5.9.9\Tools\QtCreator\bin;D:/Qt/Qt5.9.9/Tools/mingw530_32\bin;%PATH%
结论:可以运行,说明 Tools/mingw530_32 路径可以在 Tools\QtCreator\ 路径后面
综合上面实验及其结果,师兄发现了一个有趣的现象,就是 D:\Qt\Qt5.9.9\5.9.9\mingw53_32\bin
与 D:\Qt\Qt5.9.9\Tools\QtCreator\bin
的路径顺序是强相关的。可以没有 D:\Qt\Qt5.9.9\Tools\QtCreator\bin
这个路径,如果在电脑的环境变量中添加了这个路径,那么这个路径 D:\Qt\Qt5.9.9\Tools\QtCreator\bin
必须要在 D:\Qt\Qt5.9.9\5.9.9\mingw53_32\bin
这个路径后面。
相信大家还有一个疑问:D:\Qt\Qt5.9.9\Tools\QtCreator\bin
与 D:\Qt\Qt5.9.9\5.9.9\mingw53_32\bin
路径顺序不同是如何造成这个问题的?
师兄结合自己的经验,初步的想了一下,应该是 mingw32-make 在执行过程中,会在系统的 PATH 路径下找到一些东西来执行,恰好,刚刚那两个路径下都有“同样”(或者可代替的)的东西
然后只有 D:\Qt\Qt5.9.9\5.9.9\mingw53_32\bin
路径下的东西才可以,师兄也分别查看了这个文件夹,很遗憾,以师兄的能力,还是没能找到这两个路径的哪些东西是"一样的",如果有小伙伴知道这个原因,希望能私信告诉师兄一下。
到这里,这个问题基本上就算解决了,如果小伙伴有其他理解,或者觉得师兄有哪些地方理解有问题,也可以私信师兄哈
喜欢的小伙伴请动动你们可爱的小手,多多点赞!你们的支持为我不断写出干活文章提供源源不断的动力!
推荐阅读
《听说你安装测试 OpenCV 总是不成功?你可能遇到这个坑了!》
《反复研究好几遍,我才发现关于 CMake 变量还可以这样理解!》
《安装完 Ceres 库,官方文档就能扔掉吗?这些潜在的知识你可能还不会!》
来源 | 作者 小北师兄
编辑 | 小北师兄
如需转载,请后台留言
分享给朋友或朋友圈请随意
- END -
觉得不错?右下角「点我、点我、点我」
一个例子让你秒懂 Qt Creator 编译原理的更多相关文章
- Qt Creator编译时:cannot open file 'debug\QtGuiEx.exe' File not found
Qt Creator编译时:cannot open file 'debug\QtGuiEx.exe' File not found 利用Qt Creator编译工程时,出现如题目所示的错误,其中红色部 ...
- 嵌入式V3s交叉编译 tslib和QT4.8.7,并使用Qt Creator编译项目
本文主参考:http://zero.lichee.pro/%E5%BA%94%E7%94%A8/QT_index.html 环境 Ubuntu16 64位 arm-linux-gnueabihf ve ...
- QT:提高QT Creator编译速度,配置预编译头Stable.h
提高QT Creator编译速度,配置预编译头Stable.h QT Creator支持预编译头提高编辑速度,网上有些教程写得不详细,走了弯路,具体实现方法如下. (1)工程.PRO文件加入下面代码 ...
- Qt Creator编译问题
有时候需要自己编译Qt Creator,需要注意的就是qmake版本的问题,比如我用4.8.1和4.8.6同样编译出来的Qt Creator在同样的qtconfig-qt4下所呈现的效果是不一样的. ...
- 解决Qt Creator编译输出窗口乱码的问题
设置环境变量LC_ALL为en_US. 附注:将乱码复制到文本编辑器(如Notepad++)后将编码设置为utf-8,可以看到正确的文字. 看样子是编译输出窗口的编码设置出了问题,或者是gcc的输出编 ...
- Qt creator 编译错误 :cannot find file .pro qt
事实上问题的解决的方法非常easy:就是Qt不支持中文的路径,把源代码的路径所有改成英文就可以解决这个问题. 首先问题发生在我执行网上的样例程序时,又一次构建编译也是出错.提示: Cannot fin ...
- 转载-- Qt Creator编译时make: arm-linux-g++: command not found 错误!
前提是已经配置好交叉编译器,但是qt creator找不到. 解决方法: 修改 /usr/local/Trolltech/QtEmbedded-4.7.0-arm/mkspecs/qws/linux- ...
- Qt creator 编译错误:无法解析的外部符号(命令)
问题来自于:仅仅是在creator 中加入了一个新的DIalog类,并在main(),中实例化并show.就出现例如以下的错误: main.obj:-1: error: LNK2019: 无法解析的外 ...
- 一个例子理解c++函数模板的编译
一.例子 template <typename T> inline void callWithMax(const T& a, const T& b){ f(a > b ...
随机推荐
- 字符串 前 L的含义
转自http://blog.csdn.net/whz_zb/article/details/7446901 一. 在字符串前加一个L作用: unicode字符集是两个字节组成的.L告示编译器使用两个字 ...
- [re模块、json&pickle模块]
[re模块.json&pickle模块] re模块 什么是正则? 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则 ...
- 如何更好理解Peterson算法?
如何更好理解Peterson算法? 1 Peterson算法提出的背景 在我们讲述Peterson算法之间,我们先了解一下Peterson算法提出前的背景(即:在这个算法提出之前,前人们都做了哪些工作 ...
- 风变编程(Python自学笔记)第10关-工作量计算器
1.%f的意思是格式化字符串为浮点型,%.1f的意思是格式化字符串为浮点型,并保留1位小数. 2.向上取整:ceil() 使用ceil()方法时需要导入math模块,例如 1 >>> ...
- ruby基础(一)
Ruby基础 1.对象.变量和常量 1.1 对象 在Ruby中表示数据的最基本单位是对象,任何数据都是对象,使用类来表示对象的种类. 一个某个类的对象称作对象的实例. 对象 类 eg 数值 Numer ...
- zabbix学习笔记:zabbix监控之短信报警
zabbix学习笔记:zabbix监控之短信报警 zabbix的报警方式有多种,除了常见的邮件报警外,特殊情况下还需要设置短信报警和微信报警等额外方式.本篇文章向大家介绍短信报警. 短信报警设置 短信 ...
- HDFS 的内存存储是什么?
引言 HDFS 的定位就是一个文件系统,用于存储文件,而 HDFS 对于文件的存储方式有两种: 内存存储 异构存储 内存存储 什么是内存存储? 首先,我们来了解一下到底什么是 "内存存储&q ...
- Java 中布尔(boolean)类型占用多少个字节
为什么要问这个问题,首先在Java中定义的八种基本数据类型中,除了其它七种类型都有明确的内存占用字节数外,就 boolean 类型没有给出具体的占用字节数,因为对虚拟机来说根本就不存在 boolean ...
- 高通 QC协议 谷歌 PD协议
高通 QC协议 谷歌 PD协议 上述协议是两款充电协议 现在已经应用于智能设备的充电中了 https://jingyan.baidu.com/article/7908e85cb04b1baf48 ...
- keil 中的incompatible错误
http://blog.csdn.net/kobesdu/article/details/42268065