代码工程 /Qt /5.9.3源码编译

概述

之前写过一篇 Qt 4.8.6 源码编译的文章,去年开始,我已经正式全面使用Qt 5.9.3啦,拖拖拉拉,终于碰到了过不去的坎!前期写的一个项目,建的是桌面Qt工程,现在为了方便展示打印信息(qDebug或printf),希望能发布一版控制台应用程序。程序的控制台版本很快出来了,但是出现了许多奇奇怪怪的现象,列举其中一个,“warning,QApplication was not created in main() thread” …

小试牛刀

本小节,我们先粗略的进行一次源码编译从尝试,时间不多的猿,就不要看了,直接跳到后一个章节…

安装Perl

在4.8.6源码编译那篇文章中也提到过,高版本的Qt安装程序中已经自带perl安装了,我们只需要在Qt初始安装界面中勾选对应的组件即可。如下是在安装,qt-opensource-windows-x86-5.9.3.exe 时出现的告警…
在这里插入图片描述
出现上述安装错误时,切莫着急点击Retry,其实此时Qt的安装程序已将perl解压到了我们安装目录的响应文件夹下,如下图。找到D:\Qt\Qt5.9.3\Tools\Perl52213_32\strawberry-perl-5.22.1.3-32bit.msi 点击安装(可设置安装目录D:\Qt\Strawberry\),安装成功后,点击第一张图中的忽略此错误,然后继续Qt的安装…
在这里插入图片描述

configure

configure 本质上应该是一个编译脚本?为了配置编译参数,我们要先cd到D:\Qt\Qt5.9.3\5.9.3\Src目录下,然后执行配置,configure的配置参数实在是太多,我们这里暂不深究,我的第一次尝试,使用了如下配置:
configure -debug-and-release -opensource -prefix “D:\Qt\5.9.3” -platform win32-g++ -nomake demos -nomake examples -nomake tests -skip qt3d -no-qml-debug -no-angle
在这里插入图片描述
参数 -nomake demos 是我编译4.8.6 时曾经使用过的,错就错了吧,先不深究,实在是没时间。直接去掉此项参数重新执行configure…
在这里插入图片描述
选择 ‘y’ ,如果configure参数中加入了 ‘ -confirm-license’ 则应该不会有此提示。确认后,configure过程自动进行了一段时间的检查,似乎主要是一些系统资源和配置的检查,此处也不深究,大约4分钟吧,检查结果如下…
在这里插入图片描述
其他注意事项:
执行configure时的路径是D:\Qt\Qt5.9.3\5.9.3\Src 不是 D:\Qt\Qt5.9.3\5.9.3\Src\qtbase, 曾经因为此路径错误,提示 #ERROR: unknown command line option ‘-skip’
其实这也不难理解,在上述两个(两层)目录中均存在configure脚本,而脚本中的配置或其他执行参数是不一致的。
说到这里,我插点别的,Qt 5.9.3 for Desktop (MinGW 5.3.0 32 bit) 是Qt提供的一个命令行执行程序,实际上它仅仅是一个快捷方式,它的目标是:
C:\Windows\System32\cmd.exe /A /Q /K D:\Qt\Qt5.9.3\5.9.3\mingw53_32\bin\qtenv2.bat
即在系统命令行程序基础上,加了执行参数(qtenv2.bat):

@echo off
echo Setting up environment for Qt usage...
set PATH=D:\Qt\Qt5.9.3\5.9.3\mingw53_32\bin;D:/Qt/Qt5.9.3/Tools/mingw530_32\bin;%PATH%
cd /D D:\Qt\Qt5.9.3\5.9.3\mingw53_32

哦,对了,本次尝试,最终使用的编译参数为:

configure -debug-and-release -opensource -confirm-license -prefix "D:\Qt\5.9.3" -platform win32-g++ -nomake examples -nomake tests -skip qt3d -no-qml-debug -no-angle -no-opengl -skip webengine

执行编译

按照上一节中 configure后的提示,执行mingw32-make -j4 开始源码编译过程。mingw32-make可执行程序存在于 D:\Qt\Qt5.9.3\Tools\mingw530_32\bin 工具目录下,它是mingw编译工具,并不属于Qt。
期间遇到了好几次编译错误,如下仅列举了部分错误及其临时处理办法。
一开始警告我,fatal error: GLES2/gl2.h: No such file or director //临时不编译opengl /增加不编译选项…

后来又警告我,要编译Qml必须要安装python,我明明已经增加了 -no-qml-debug 参数配置,气的我直接又增加了 -skip webengine 编译参数。重新configure,重新make,没一会就编译完成了…

以下,是第二次编译尝试,在办公电脑上实施的,以失败告终,主要失败现象是,qmake编译完成却没有install(拷贝)成功,新建工程后,可以正常编译,可以直接运行,但是却不能调试运行,错误如下:

D:\Qt\Qt5.9.3\Tools\Tools\mingw530_32\bin下的工具程序,如g++,gcc,gdb等,在Strawberry解释器安装目录D:\Qt\Strawberry\c\bin下也是存在的,且Strawberry在安装的过程中默认将其添加了系统Path环境变量,这样的话会造成编译问题吗?理论上不会啊?mingw32-make如果有调用gcc等,会先搜索本地目录然后才是系统环境变量吧!如果存在此类性质的错误,通过makefile文件可以查的!

执行安装

按照上一节中 configure后的提示,执行 mingw32-make install 命令行(注意install前没有短横线),这个过程时间也挺长的,注意耐心等待… 安装到最后,提示如下图。新编译出来的文件都被放进了指定目录 D:\Qt\5.9.3在这里插入图片描述
查看了下D:\Qt\5.9.3\bin目录,能用到的动态库,已经都是新编译日期了!迫不及待的测试了下效果,新建了一个Qt控制台程序,尝试跳入QCoreApplication源码,失败,失败!连头文件跳转都是失败的!重新配置了下qmake路径到新编译的qmake,还是不行!无奈,我只好注掉原安装目录 D:\Qt\Qt5.9.3\5.9.3\mingw53_32(如将其修改为D:\Qt\Qt5.9.3\5.9.3\mingw53_32==),然后重新配置QtCreator的开发环境,然后重新新建工程,重新测试,可以进入QCoreApplication源码啦!
后来想到,Qt发布版安装后,我将Qt的库和qmake所在的文件夹,配置到了操作系统的path目录中,使用源码重新编译它们后,独立于发布版的这些文件,我们自己又生成了一份,为了使用新的qmake,我们必须重新指定Path或配置QtCreator…

主目录编译后生成的目录Qt 安装版本的目录
在这里插入图片描述在这里插入图片描述在这里插入图片描述

2021年4月30号晚上11:00开始鼓捣,到5月01号01:00,然后早上起来从8:30搞到10:00,第一次 Qt 5.9.3 源码编译尝试终于结束。后续章节,我们将对整个Qt源码编译体系做一个更加详细的学习!

再试牛刀

CMD导致的杯具

(后记),没有使用Qt的命令行程序,而是直接使用了系统CMD程序(这是一种不太好的做法)。
在这里插入图片描述
在 D:\Qt\Qt5.9.3\5.9.3\Src目录下执行configure本身是没有问题的,但是过程中却找不到mingw32-make程序,因为我们并没有配置它的路径D:\Qt\Qt5.9.3\Tools\Tools\mingw530_32\bin到环境变量,为此,却系统Path中直接增加它,echo确认生效。
configure设置后,执行mingw32-make -j8 开始编译过程,结果如下:
在这里插入图片描述
如上,编译错误应该还是环境变量的问题,第一次源码编译,我们使用Qt-CMD时,并没有类似错误。排查此问题的过程:基于错误 Makefile.Release:6877: recipe for target ‘.obj/release/qwin10helpers.o’ failed 搜索qwin10helpers文件,找到对应的 Makefile.Release 文件,其6877行为:

$(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj\release\qwin10helpers.o qwin10helpers.cpp
//其中:
CXX        = g++    
CXXFLAGS   = -fno-keep-inline-dllexport -O2 -std=c++1y -fno-exceptions -Wextra -Wall -W -Wvla $(DEFINES)

将此6877行展开,正是编译编译过程中的内容,可惜我依然没有看出什么道道。顺着编译内容继续向上看,发现:
在这里插入图片描述
qwin10helpers.cpp 编译失败是因为 # include <uiviewsettingsinterop.h> 找不到此文件,那么此文件在哪里呢,我们在Qt大目录下搜索,发现其路径在 D:\Qt\Qt5.9.3\Tools\mingw530_32\i686-w64-mingw32\include 下,并不是源码Src下的头文件!
在 Makefile.Release 的INCPATH定义中,确实找不到上述路径,连 ‘Tool’ 字符串都搜不到,搜索到的 ‘i686-w64-mingw32’ 字符串都是 D:/Qt/Strawberry 目录下的,在对应的pro文件中也没有发现相关配置…
我们已经知道,Qt-CMD相对于SYS-CMD,多执行了:
set PATH=D:\Qt\Qt5.9.3\5.9.3\mingw53_32\bin;D:/Qt/Qt5.9.3/Tools/mingw530_32\bin;%PATH%
通过执行 echo %PATH% 可发现,被动态 set PATH 的路径是排在全部路径序列的最前边的,而虽然我们在系统环境变量中静态的增加了D:\Qt\Qt5.9.3\Tools\mingw530_32\bin路径,但是却是排在最后的…
在这里插入图片描述
为了验证,环境变量的排序,会对编译过程造成影响,我们在系统环境变量设置中,将D:\Qt\Qt5.9.3\Tools\mingw530_32\bin路径,移动到所有Strawberry环境变量之前。本想直接重新configure和make,但是却没有识别到变化,无奈,执行了会 mingw32-make clean -j8 然后强硬终止,然后重新 configure 和 mingw32-make…
还是没有成功,换了错误位置,但依然有很多的编译错误…
我放弃了…
尽管,上述错误产生的来龙去脉,我还是没搞清楚,但是请先记住一点,在使用mingw编译时,请将它相关的全部环境变量,设置到变量序列的开头的位置,如果有一天使用msvc来编译,道理应该是一致的…
不甘心,再次尝试,得到如下结果和结论:
卸载Qt安装程序,重新安装,使用Qt的命令行程序,重新执行配置、编译和安装,均无异常…
在此种状态下,重新打开qwin10helpers.cpp所在工程的 Makefile.Release 文件,重新检索 i686-w64-mingw32 关键字,发现它们均是 D:/Qt/Qt5.9.3/Tools/mingw530_32 直接或间接目录下的,不再是 D:/Qt/Strawberry 的直接或间接目录,且此文件中找不到任何Strawberry字符串的影子。这说明, D:/Qt/Strawberry 环境变量排在 D:\Qt\Qt5.9.3\Tools\mingw530_32\bin 之前,的确影响到了Makefile文件的生成;在源码编译时,最好使用Qt-CMD启动命令行程序,以使得mingw的相关路径或工具优先被检索使用…

正式使用新环境

之前源码编译完成后,也新建了控制台应用程序、Widget应用程序等进行基本测试,均可进入Qt库源码。然而将项目程序放在此新环境下进行调试时,却一直无法跳进源码中,思考了超过2小时,才有眉目。之前为了方便程序在其他机器上运行,我的bin文件夹下拷贝了一整套的Qt动态库文件,这样做的结果是,我在编译程序时,连接阶段用的都是自身bin夹下的库,而非Qt相关目录下新编出来的库,因此,无法进入源码,也就不足为奇了…
人啊,一不小心就会犯些低级错误,而且直到因此头破血流才猛然醒悟!比如,本该用千兆网口的时候你却不小心接在了百兆口上,却在代码中查了半天为啥丢数据;你本想让程序持续在工控机运行,但OS却给你偷偷到时间休眠了,大半天你在代码里就是没找到为啥好好运行着的流程怎么就无征兆的异常停止了…

Qt 安装版(exe文件)

如下,我们对比着Qt4.8.6和Qt5.9.3两个版本,对Qt的exe安装版本进行了一个简单的介绍…

目录基本说明

以Qt动态库所在目录bin来看的话,Qt5.9.3 默认的安装目录(D:\Qt\Qt5.9.3\5.9.3\mingw53_32)比 Qt4.8.6默认的安装目录深了两级(D:\Qt\4.8.6),其下是Qt5.9.3下子目录和文件列表:
在这里插入图片描述
其中,Tools目录下包含:mingw530_32全部安装文件(g++、gcc、gdb…本质上它们是与Qt无关的)、QtCreator安装文件、Perl52213_32原始文件。
其中,5.9.3 目录下包含:Src全部Qt源码,mingw53_32(下面将重点说说这个文件夹);
在这里插入图片描述
其中,bin,是人家Qt在发行此安装版本前使用源码提前编译好的主要的Qt动态库和可执行文件。lib,中存储的是相关的编译连接文件。plugins,中是Qt一些插件相关的动态库。qml,中也是一些相关的动态库。
其中,doc,是Qt帮助文档使用的文件。
其中,include中包含了用户可能会用到的头文件。这些头文件都是从src中完全拷贝过来的。我们写代码时,应用的头文件最终调用至此,我们在自己的程序中执行Qt类的跳转时,也会跳转到此处。

一个小插曲

在使用4.8.6安装版的时候,在QtCreator中可以直接F2跳转到框架类对应的头文件,然后F4跳转到对应的cpp文件;当时发现4.8.6的编译版,若不进行任何处理,使用F2跳转到框架类定义中后,再按F4却没有反应了(当时也作了分析和处理,可参考);在使用Qt5.9.3安装版时,没有自主编译过,发现其现象与当时4.8.6编译版的情况类似,F4不再能跳转cpp文件…
如下我们以QCoreApplication类为例:

  • 在Qt4.8.6-Exe安装版中,选中QCoreApplication,按F2,跳转到了D:\Qt\4.8.6\src\corelib\kernel\qcoreapplication.h,也即qcoreapplication.cpp 所在目录,所以可以使用F4进行跳转;我们在#include 上按住Ctrl鼠标左键跳转,到的是D:\Qt\4.8.6\include\QtCore\QCoreApplication (无后缀),我们打开此文件和其目录查看如下:
    在这里插入图片描述
//include/QtCore/QCoreApplication 无后缀文件 //其内容如下 //即指向同一目录下的另一个带.h后缀的文件
#include "qcoreapplication.h"  

//include/QtCore/qcoreapplication.h 文件内容如下:
#include "../../src/corelib/kernel/qcoreapplication.h"  //仅有一个文件路径指向源码下真正类定义头文件

打开此处的 qcoreapplication.h 文件,发现其内容指向了源码中真正的 “…/…/src/corelib/kernel/qcoreapplication.h”
头文件!也就是说,从main函数中的QCoreApplication跳转过程大约是:
搜索main.cpp包含的头文件(#include ),然后找到QCoreApplication同名无后缀文件->找到同目录下的qcoreapplication.h文件(仅包含一个路径)->找到源码src下真正的qcoreapplication.h头文件定义!

  • 我们安装exe版的Qt后,D:\Qt\4.8.6\bin下的动态库,既有Debug版本又有release版本,但是我们似乎是不能直接用它来做调试的(即无法断点在源码中),这是因为sec下的源码并没有与bin下的库建立编译调试对应关系?具体的这块,也没搞很清楚,据不可靠经验,不是在自己机器编译出来的程序,似乎不太可能建立这种断点调试关系…
  • 在Qt5.9.3-Exe安装版中,选中QCoreApplication,按F2,跳转到了D:\Qt\5.9.3\5.9.3\mingw53_32\include\QtCore\qcoreapplication.h;这是Qt4.8.6中在#include 上按住Ctrl鼠标左键跳转时的 ‘同类路径’ ;
    在这里插入图片描述
    打开,无后缀的QCoreApplication文件,其内容与4.8.6中一致;但是打开此处的qcoreapplication.h文件,发现其内容不再是一个相对路径,而成了实打实的头文件定义。根据前期对源码编译和安装过程的分析,我们知道这个头文件在在install过程时,从src源码目录下拷贝过去的。
  • 简单总结下。能不能从自己的代码中方便跳转到cpp源码文件中,取决于如下流程,#include 即无后缀QCoreApplication头文件,是否能通过他关联到src下的真正的qcoreapplication.h类头文件定义,如果没有这个完整的指向链,则无法实现到源码cpp的跳转;更不可能实现代码断点调试。

重新来过

这次我们将细致的研究整个Qt的安装过程/源码编译过程。Building Qt Sources,可以先细看下…

为啥要这么较真…

接下来将具体的介绍编译过程中的各个环节…

编译环境

Perl

Perl一种功能丰富的计算机程序语言,它像C一样强大,像awk、sed等脚本描述语言一样方便。Perl具有高级语言(如C)的强大能力和灵活性;Perl与脚本语言一样,不需要编译器和链接器来运行代码。本文的最前边已经讲解到,估计5.0以上的exe安装版都开始自带Strawberry Perl,它是用于MS Windows的perl环境,其中包含运行和开发perl应用程序所需的一切,它被设计为尽可能接近UNIX系统上的perl环境。在Qt4.8.6编译时,我们使用的是Active Perl,它与Strawberry Perl应该同属开源Perl语言解释器,但两者是有差别的,此处不再细究。接下来我们看看为啥在编译Qt源码时无可避免的需要Perl环境:

关于下载地址,可以参考
https://wenku.baidu.com/view/a67ff7c9541810a6f524ccbff121dd36a32dc4c4.html

Python

关于下载地址,可以参考
https://wenku.baidu.com/view/a67ff7c9541810a6f524ccbff121dd36a32dc4c4.html

Ruby

关于下载地址,可以参考
https://wenku.baidu.com/view/a67ff7c9541810a6f524ccbff121dd36a32dc4c4.html

编译配置(Configure)

Qt Configure Options,Qt 帮助文档中有如下描述:
configure is a command-line tool(命令行工具) which determines(决定)how to build Qt for a particular(特定)platform. Configure can exclude(排除) a feature in Qt as well as determine how Qt builds and deploys(部署) applications onto host platforms. This page discusses some of the configure options, but for the full list of options, enter the command configure -h. Configure should be run from the main Qt source directory. (如果要查看全部的选项列表,请在Qt源码主目录执行configure -h命令)
Unless stated otherwise,(除非另有说明)the commands in this page are for the Linux platforms. On macOS and on Windows, the PATH and directory structure are different, therefore the commands will vary. Also, on Windows systems, the configure script is called configure.bat. After running configure, build the sources with the make tool belonging to the chosen toolchain.

常见问题

exited with code 0x0000139

遇到上述问题时,清空了所有编译中间文件,删除了.user文件重新编译,无果。最后将可执行文件拷贝到Qt的bin目录下,运行结果如下:
在这里插入图片描述
由于我这个项目中使用了QChart的相关类,该类的相关功能似乎是依赖于OpenGL的,但是我在进行源码编译的时候,我是屏蔽了OpenGL的相关选项的。因此,出现了动态库不匹配的问题,故出现了0x0000139错误…
修改configure脚本中,去掉 " -no-opengl" 选项,然后重新编译,结果,又开始出错了…
在这里插入图片描述
此问题,还没去解决呢…

Qt 5.93 安装参考

看到的一些还算靠谱的文章,
http://www.bubuko.com/infodetail-2455121.html
文中提到了一些官方参考 …
Perl

https://wenku.baidu.com/view/a67ff7c9541810a6f524ccbff121dd36a32dc4c4.html

官方的确有提到一些安装问题…
https://doc.qt.io/qt-5/configure-options.html

QT 源码编译–windows
https://blog.csdn.net/hulingerlin/article/details/81914279

Qt 交叉编译

鼓捣这么多的Qt的编译过程,除了 ‘更好更透彻的在WIN系统上进行调试和源码学些’ 这个原因外,还有一个重要原因是,在能在嵌入式Linux上实现交叉编译…

//这是一个交叉环境的编译 //
https://blog.csdn.net/qq_41622002/article/details/103313458

关于交叉编译的相关内容,将单独开篇…

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值