zoukankan      html  css  js  c++  java
  • 一个例子让你秒懂 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 所示

    img

    图 1 Qt Creator 编译输出结果

    小伙伴请对图片上红色框起来的内容 mingw32-make 留个印象,下面还会用到这个。编译完成后就可直接正常运行。

    可以看到,用 Qt Creator 创建项目/编译运行项目非常简单,几步操作下来就可以运行一个程序。


    2 命令行编译:

    为了了解 Qt Creator 背后为大家做的工作,需要知道如何用命令行编译这个程序。我们先建立一个文件夹 2-2-2,然后将上面写好代码的 main.cpp 原封不动的拷贝到这个文件夹中,目前为止,准备工作完毕,接下来进入正题。

    在 Windows 中,需要打开 cmd 这个终端程序(定位到 2-2-2 目录),然后按照如下命令即可编译 Qt 程序,主要步骤如下:

    1. 调用 qmake -project 生成 .pro 文件,在该文件中添加 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets这句话
    2. 调用 qmake 生成 Makefile 文件和 debug / release 目录等等,
    3. 调用 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 所示

    img

    图 2 Qt 自带环境终端

    2)按照下图 3,图 4 方法进行操作即可

    img

    图 3 终端运行命令及结果

    这里有两点需要注意:

    1. 在使用 qmake -project 之后,需要在生成的 .pro 文件中进行 Qt 库的包含,比如我这里就需要添加greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 这一行代码。

    2. 黄色画线地方,在这个终端中,前面必须加上 /d 才能跳转到对应的文件夹中,然后再用 qmake -project 即可生成 .pro 文件

    继续按照下图 4 方式操作

    img

    图 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 所示

    img

    图 5 Makefile 文件内容

    可以看到 CC CXX 表示用了什么编译器,这里用了 gcc/g++,链接器使用了 g++,等等,从这里都可以看到编译程序需要哪些库以及编译选项


    1.2 在 Cmd 终端中直接进行编译

    Win + R 输入 cmd 进入终端,跳转到对应文件夹中,然后运行上述命令,但要注意,你必须要配置好系统的 PATH 环境变量才行,比如我自己配置的环境变量如下图 6 所示

    img

    图 6 本机系统环境变量配置信息

    之后依次运行以下命令即可

    qmake -project` 之后修改 .pro 文件,在运行下面命令,`qmake && mingw32-make
    

    cd release && 2-2-2.exe 即可运行程序


    **
    **

    1.3 拓展

    如果按照上面的方法来做,相信大家肯定能够成功运行(师兄研究半天才得出的终极结论),但是师兄第一次实验就没有这么幸运了,走了好多弯路,下面师兄就把自己遇到的问题,中间思考过程以及最终结论一一说明

    如果你们用过 Qt 开发过界面程序,那么肯定遇到过类似下图的问题:

    img

    图 7 遇到的问题

    师兄做这个实验也遇到了这个问题,首先,师兄没有使用 Qt 自带的运行环境(哈哈 师兄当时可能是飘了img,不过不飘就不会得出上面的终极结论分享给大家了,算了算还是不亏的img),就直接打开了 cmd ,然后调用上面 qmake -project ,qmake,mingw32-make 直接一波操作操,心想,肯定可以直接运行了

    没想到现实 pia pia pia~,运行 .exe 时就出现了上面的提示,师兄当时就蒙了, QT 自带环境也是在终端运行的啊,我也是在终端运行的啊,我在安装 Qt 的时候也设置了环境变量了,为什么会出现这个问题呢?

    想必大家也是跟师兄有着同样的问题,先看一下这个问题,一般引起这个问题都是缺少相应的 dll 结尾的动态链接库,那么好办了,经过我这两天对 Qt 的了解,还真的有一个解决方法,那么就是用 Qt 自带的部署程序 windeployqt ,通过这个程序就可以将一些依赖自动复制到你的文件夹中了,然后在运行就会发现解决了,如图 8 所示

    img

    图 8 利用 windeployqt 程序运行结果

    图 8 中红色框都是 windeployqt 部署程序生成的,会自动的把你的依赖全部拷贝过来,这种也是将自己的程序,放到没有 Qt 环境的计算机上运行的必备操作。

    到这里你以为就完了,不不不,还远远没到,师兄觉得每次命令行编译完成后都要部署一下才能运行太麻烦,说明这个方案不适用于平常的开发,只是一种可选择方案,师兄觉得这个解决方案就用来发布程序就行了。

    这又回到了问题的开始,还记得上面师兄说过这么一句,师兄不用 Qt 自带的环境,就在 cmd 命令行中直接键入相应的命令,之后才出现了问题,那咱们就顺藤摸瓜,这个 Qt 环境与我自己直接在命令行中键入命令有什么不一样吗?

    打开计算机开始界面,找到 Qt 自带环境的应用程序,如下图 9 所示

    img

    图 9 Qt 自带环境探索结果

    鼠标右键点击 Qt5.9.9(MinGw 5.3.0 32-bit) 之后点击“开文件位置”,得到如下图 10 所示

    img

    图 10 Qt 自带环境探索结果 2

    可以看到,这里最终会调用一个 qtenv2.bat 的一个脚本文件,目标是:C:WindowsSystem32cmd.exe /A /Q /K D:QtQt5.9.95.9.9mingw53_32inqtenv2.bat,(这里多说一句,我们也可以在启动文件夹中仿照这种方法,执行自己的脚本文件,进而配置相应的环境),到对应文件夹下打开该文件,其内容如下图 11 所示:

    img

    图 11 qtenv2.bat 内容

    可以看到,这里就设置了一下 PATH 的环境变量,师兄之前也在电脑上设置了环境变量,但是好像与这个有点不一样,如下图 12 所示,这是师兄最开始自己电脑的环境变量

    img

    图 12 本机最开始的环境变量

    经过仔细对比,师兄发现这里多了一个 D:QtQt5.9.9ToolsQtCreatorin; ,且顺序有一点不同,但也仅仅是多了这一个路径而已,没想到会出现这么大的问题,师兄突发奇想,难道真的是多了一个路径才造成这样的结果吗?如果填加了这个路径,那么顺序变化会不会有影响呢?

    接下来师兄就做了如下实验,我直接将这个看似多余的路径给删除了,也就是图 6 所示,然后在 cmd 中进行 qmake && mingw32-make 命令,继续运行 2-2-2.exe ,此时就会正常运行

    到目前为止,我们找到了问题所在,也就是多出来的这个路径造成的,相信大家到这里还是会有疑问,如果不去掉这个路径还会出现这个问题吗?

    师兄又做了下面几个实验,分别设置了 PATH 的环境变量,仅仅顺序不一样,在 cmd 中设置一下环境变量顺序,并且从新执行 qmake mingw32-make 命令,下面仅仅列出路径的顺序及对应结果,具体实验结果图就省略了:

    set PATH=D:QtQt5.9.95.9.9mingw53_32in;D:/Qt/Qt5.9.9/Tools/mingw530_32in;D:QtQt5.9.9ToolsQtCreatorin;%PATH%

    结论:这个可以运行

    set PATH=D:/Qt/Qt5.9.9/Tools/mingw530_32in;D:QtQt5.9.95.9.9mingw53_32in;D:QtQt5.9.9ToolsQtCreatorin;%PATH%

    结论:可以运行,说明 Tools/mingw530_32 和 5.9.9mingw53_32 互换位置也可以,它们两个顺序没有影响

    set PATH=D:/Qt/Qt5.9.9/Tools/mingw530_32in;D:QtQt5.9.9ToolsQtCreatorin;D:QtQt5.9.95.9.9mingw53_32in;%PATH%

    结论:不可以运行,说明 ToolsQtCreator 路径要在 5.9.9mingw53_32 路径后

    set PATH=D:QtQt5.9.95.9.9mingw53_32in;D:QtQt5.9.9ToolsQtCreatorin;D:/Qt/Qt5.9.9/Tools/mingw530_32in;%PATH%

    结论:可以运行,说明 Tools/mingw530_32 路径可以在 ToolsQtCreator 路径后面

    综合上面实验及其结果,师兄发现了一个有趣的现象,就是 D:QtQt5.9.95.9.9mingw53_32inD:QtQt5.9.9ToolsQtCreatorin 的路径顺序是强相关的。可以没有 D:QtQt5.9.9ToolsQtCreatorin 这个路径,如果在电脑的环境变量中添加了这个路径,那么这个路径 D:QtQt5.9.9ToolsQtCreatorin 必须要在 D:QtQt5.9.95.9.9mingw53_32in 这个路径后面。

    相信大家还有一个疑问:D:QtQt5.9.9ToolsQtCreatorinD:QtQt5.9.95.9.9mingw53_32in 路径顺序不同是如何造成这个问题的?

    师兄结合自己的经验,初步的想了一下,应该是 mingw32-make 在执行过程中,会在系统的 PATH 路径下找到一些东西来执行,恰好,刚刚那两个路径下都有“同样”(或者可代替的)的东西

    然后只有 D:QtQt5.9.95.9.9mingw53_32in路径下的东西才可以,师兄也分别查看了这个文件夹,很遗憾,以师兄的能力,还是没能找到这两个路径的哪些东西是"一样的",如果有小伙伴知道这个原因,希望能私信告诉师兄一下。

    到这里,这个问题基本上就算解决了,如果小伙伴有其他理解,或者觉得师兄有哪些地方理解有问题,也可以私信师兄哈

    喜欢的小伙伴请动动你们可爱的小手,多多点赞!你们的支持为我不断写出干活文章提供源源不断的动力!


    推荐阅读

    《听说你安装测试 OpenCV 总是不成功?你可能遇到这个坑了!

    《反复研究好几遍,我才发现关于 CMake 变量还可以这样理解!

    《安装完 Ceres 库,官方文档就能扔掉吗?这些潜在的知识你可能还不会!


    来源 | 作者 小北师兄

    编辑 | 小北师兄

    如需转载,请后台留言

    分享给朋友或朋友圈请随意

    - END -

    觉得不错?右下角「点我、点我、点我」img

  • 相关阅读:
    计算机编程的24条法则
    爱的十个秘密10.热情的力量
    爱的十个秘密9.承诺的力量
    CPU信息的获得(转自大富翁)
    从编程员的角度理解 NTFS 2000:流和硬链接
    爱的十个秘密8.沟通的力量
    Delphi面向对象编程的20条规则(转自太平洋电脑网)
    程序读取计算机设备管理器中各设备的状态(启用/禁用)?(转自大富翁)
    关于NTFS文件系统中的数据流问题
    Windows新版算号器技术原理
  • 原文地址:https://www.cnblogs.com/ncuneugcj/p/14613282.html
Copyright © 2011-2022 走看看