C++/Qt 开发环境提升

概述

该文章主要针对Qt开发环境的高效使用,也包括工程、运行调试相关的QA。主要内容有:Qt源码编译、Qt版本小记、控制台的打印顺序QA、调试过程中的结构体局部变量怎么啦QA、Qt调试运行中文乱码、qmake使用、如何提升QtCreator编译速度、利用断言追查错误代码…

Qt源码编译

2019年06月07号,难得清闲。好久了,想编译下自己电脑上的Qt源码,以方便后期运行调试及源码学习过程,现在开始一边执行这个过程,一边来写博客:

  • 配置环境变量

增加QtPath=D:\Qt\4.8.6; MingWPath=D:\Qt\mingw32\bin;的Path路径,他们分别是configure、gcc、g++、mingw32-make工具的执行路径。可输入gcc --version和g++ --version和mingw32-make --version验证编译器安装成功 。
<后记1>
the first and the second compile 都是在虚拟机里进行的,虚拟机比较干净木有因环境变量导致问题;the third compile在公司的电脑进行的,make了一会就开始报错:提示类似Microsoft Visual Studio头文件中**无定义等… us 是想用mingw进行编译的,怎么跑VS啦,这一定是环境变量搞的鬼-于是找了这篇参考,文章提到了:要检查用户变量INCLUDE、LIB、PATH、MSDevDir和MSVCDir,删除有关\Microsoft Visual Studio\VC98的信息,否则它们会与后续的mingw32-make冲突,导致编译出错。

  • 安装Perl

前几天见5.12的安装包里直接附带着它。Perl借取了C、sed、awk、shell 脚本语言以及很多其他程序语言的特性。其中最重要的特性是它内部集成了正则表达式的功能,以及巨大的第三方代码库CPAN。ActivePerl一个perl脚本解释器。其包含了包括有 Perl for Win32、Perl for ISAPI、PerlScript、Perl Package Manager四套开发工具程序,可以让用户编写出适用于unix,windows,linux系统的CGI程序来。我们要安装的就是这个ActivePerl。ActivePerl下载链接-官方,需要注册账号哦!家里的移动网速齐慢,喝个茶去。ZOL软件下载-ActivePerl 5.26.1(用这个吧-亲测可用)!

  • 执行编译配置

configure -debug-and-release -opensource -prefix “D:\Qt\4.8.6” -platform win32-g++ -nomake demos -nomake examples

执行上述语句后,若没有错误,将提示:Qt is now configured for building. Just run mingw32-make.To reconfigure, run mingw32-make confclean and configure.

第二次编译的时候遇到的一个错误:
​​​​​​​​​​​​在这里插入图片描述
先看看configure参数编译选项,但是怎么通过帮助查寻选项呢?木有找到-

-platform … The operating system and compiler you are building on. (default %QMAKESPEC%)

qmake需要一个平台和编译器描述文件,其中包含许多默认值用于生成适当的Makefiles。标准的Qt发行版附带了许多这些文件,位于Qt安装的子目录mkspecs中。可查看D:\Qt\4.8.6\mkspecs目录。一番小研究,是有 win32-g++ 这个选项的,且上周编译就是这么用的没问题。最后只能放大招,重启系统,因为,我在进行这次安装前进行过直接删除、Qt卸载等一系列乱七八糟的操作,用的是虚拟机,好久没关机啦!事实证明,大招果然管用!

<后记2> //对应环境变量模块的 <后记1>
C++/Qt 开发环境提升_第1张图片
环境变量的检查如上,是在 configure执行的第一步进行的, 在没有VS安装的这个虚拟机里INCLUDE,LIB都是空的。对于有VS的机器上,应该清理这3个环境变量配置,并重启一个cmd重新执行confgure后,再后续步骤。(环境变量导致的编译问题,无非是查找头文件、动态库站错位诱发的,理论上讲mingw的相应h/dll路径配置在vs前头,也能解决上述问题,未测试!)
另,使用qmake -query 可以查看Qt的安装信息,如QT_INSTALL_LIBS

  • 编译过程 mingw32-make

执行make指令没有多久,就遇到了下面的错误,以前也了解到Qt的编译和使用上有时候对路径的要求比较苛刻,于是乎将Dos当前目录从C盘切换到了Qt-src所在的目录,D:\Qt4.8.6 去重新执行configure 与 mingw32-make,结果是称心的!
C++/Qt 开发环境提升_第2张图片
反正是过了很久,终于编译完成了!但是出来的提示却很奇怪,简直不相信自己的眼睛,提示 如下,让我重新执行make ?
在这里插入图片描述
我很乖的又执行了,mingw-make指令,不过,感觉上当受骗啦,明明是在又重新编译啦!第二次执行make结束后,没有上述提示!另外,在QtCreator中可以为make配置 -j4 编译参数,估计这里的命令行编译也是生效的!(第二次编译时证明管用-编译时间缩短到<3h!)

  • 安装过程mingw32-make install

若不执行安装过程,可能无法在QtCreator中配置环境成功!在执行该指令的过程也有点奇怪,一开始还好,各种copy过程,像是在执行安装过程,可是后来又进入了编译过程,难道是因为上次上当第二次编译没有执行完?

  • 编译版使用
    编译版本使用中,F5调试运行正常,可准确进入Qt内部函数。但有一个问题,从应用代码跳到Qt头文件,以前可以直接按F4跳转对应cpp文件,现在不行了!通过include目录对比发现:
安装版本 编译版本
C++/Qt 开发环境提升_第3张图片 C++/Qt 开发环境提升_第4张图片

在编译版本中,install后所有目录头文件都是实体定义文件,但是纯安装版本中却是相对路径引用,下以QApplication为例说明:

安装版include\Qt 安装版include\QtGui
#include “…/QtGui/qapplication.h” #include “…/…/src/gui/kernel/qapplication.h”

解决办法:在makeinstall后,-掉其src/include目录,换成exe安装版的include,亲测可用。

  • 还有一个问题

有时候为了调试一个比较深的貌似跨线程导致的问题,我们使用纯debug断点调试,可能要不来效果,这时候需要在源码中加入打印信息,这时候,我们如何执行编译与安装步骤呢?

Qt-IDE使用

Qt帮助系统

你认为Qt-Assistant它内容多很详细,但实际上Qt提供更强大的在线帮助!先来看看Qt的资源中心,你可以向上一层到主页然后去Qt产品中心感受下绚丽多彩。
这是Qt中国白皮书模块中的一篇:Qt工业应用的基本要点,放心是中文的,看完是不是有所收获!类似的好资料,在这里还有很多!

Qt-Assistant中的部分英文描述的解读与学习,可以参考软开-专业英语。

控制台的使用

一直有个疑问:不管是系统控制台,还是QtCreator控制台,多线程访问控制器输出时,它们能否保证显示顺序就是真实的运行顺序 ?

在进入这个问题前我们先来看看控制台基础概念。在MSDN上有一部分关于Console的资料,可以找找你想要的答案!控制台有一个输入缓冲、至少一个屏幕缓冲(输出缓冲)构成。多个进程可共享一个控制台。其实到现在,骨子里我是相信在多线程下Console显示能保证与实际系统运行顺序一致的,但是打印看上去有点怪?而这种所谓的怪现象,可能并不怪,这可能是CPU执行策略导致的,那么我们应该去研究CPU时间片、轮循、CPU等待、并行执行等概念!

关于多线程的执行,我有一堆问题没有搞明白,这个以后单独开一篇boke。先看看这个问题: 在多核CPU下,同一进程下的多个线程可不可以并行运行 ? 也许对想搞明白什么有所帮助。另外,用户应用程序中,能否通过底层接口感知到自己的执行cpu、直接的执行时间、等待时间等?

断言

define Q_ASSERT_X(cond, where, what) ((!(cond)) ? qt_assert_x(where, what,__FILE__,__LINE__) : qt_noop())
 
int qAllocMore(int alloc, int extra)
{
    Q_ASSERT(alloc >= 0 && extra >= 0);
    Q_ASSERT_X(alloc < (1 << 30) - extra, "qAllocMore", "Requested size is too large!");
 
    //控制台打印信息
    //ASSERT failure in qAllocMore: "Requested size is too large!", file tools\qbytearray.cpp, line 73
 
}
 
//请继续学习qt_assert_x的实现过程

“__FILE__”:在源文件中插入当前源文件路径及文件名; __LINE__:在源代码中插入当前源代码行号;

单步调试-结构体局部变量

刚刚发现了一个奇怪的问题,在使用QtCreator进行F10单步调试时,函数内部的结构体变量,即使是加上断点也走不到,且运行到该行时,断点符号会消失。初步感觉上,是程序没有编译好,但是重新完全编译后,依然存在该问题,勾起了我的好奇心。于是乎单独的写了一个测例,测试结果说明了,局部的结构体变量,如果这个结构体没有构造函数(无关乎结构体组成元素的类型),则在进行QtCreator下的gdb调试时,定义局部结构体变量的这一行,不会走到。然后,我打开了好久不用的VS,发现其测试结果与上述一致,在一行结构体(无构造函数)局部变量定义代码前边加上断点标记符号,但是在进行调试运行时该标记会自动消失,即不能断在该行,单步调试也不走它。

另外,发现这个局部的结构体变量,在进行memset前极有可能出现不是全零的情况,因此对于结构体变量的memset初始化过程,并不是可有可无的。

异常告警1

在这里插入图片描述
在学习QtCreator架构时,打开了 帮助 - 关于插件 - C++ - ClangCodeModel插件,结果就有上述提示。未继续深究Clang!

无法使用高级搜索

这里指的是在QtCreator中无法使用 Ctrl+Shift+F 组合按键,打开IDE的高级搜索功能。在办公机器(Win7系统)存在这样的问题,知道其与搜狗输入法有关,因为只要在使用上述组合键时,先按Ctrl+Shift+空格将输入法隐藏,则可以正常打开QtCreator高级搜索。但是这招在Win10机器上却不管用。后来多方查证,关闭了搜狗输入法-属性设置-高级-系统功能快捷键-取消简繁切换的勾选,问题解决。

调试乱码问题

Qt5 中文乱码解决方法剖析 # https://blog.csdn.net/li_jian_xing/article/details/47609621

qMake使用

比较喜欢博主dbzhang800的几篇文章,受益匪浅:
浅谈 qmake 之 pro、pri、prf、prl文件 # https://blog.csdn.net/dbzhang800/article/details/6348432
qmake 乱乱乱谈(一) https://blog.csdn.net/dbzhang800/article/details/6758204
qmake 乱乱乱谈(二) https://blog.csdn.net/dbzhang800/article/details/6758605
qmake 乱乱乱谈(三) https://blog.csdn.net/dbzhang800/article/details/6761828

提升编译速度

https://blog.csdn.net/xinala1122/article/details/79162795
https://blog.csdn.net/imxiangzi/article/details/76179204

Qt版本调研

Qt 下载 #https://blog.csdn.net/friendan/article/details/44873347
Ubuntu下 嵌入式Qt开发环境的搭建 # https://blog.csdn.net/lpp0900320123/article/details/24876159
Qt4过渡至Qt5 # http://blog.sina.com.cn/s/blog_a6fb6cc90101endy.html

嵌入式运行

嵌Linux上第二次启动Qt程序

进来有个缩短Qt应用程序初始化时间的工作,在测试中发现:在Linux系统不断电的情况下,第二次启动该程序比第一次启动该程序,在初始化(主关注UI创建)耗时上要快出50%左右。进一步编写独立测试程序,得到如下测试结果:

测试程序名称 程序构造
Helloword-T 一个Widget背景、两个按钮、一个文本框
Helloword-1 控制台应用程序(无UI)
Helloword-2 一个Widget背景 无其他控件
Helloword-3 一个Widget背景、一个按钮
Helloword-4 一个Widget背景、六个按钮
Helloword-5 Helloword-T的副本可执行程序
测试结果(每条测试前,对设备重新上电,Linux系统已完全启动)
打印Helloword-T程序从mian函数入口到到app返回前的耗时(app创建、ui创建、ui弹出)
单独启动Helloword-T程序 打印173ms
第一启动 Helloword-1 关闭后启动 Helloword-T 打印173ms
第一启动 Helloword-2 关闭后启动 Helloword-T 打印105ms
第一启动 Helloword-3 关闭后启动 Helloword-T 打印91ms
第一启动 Helloword-4 关闭后启动 Helloword-T 打印91ms
第一启动 Helloword-5 关闭后启动 Helloword-T 打印24ms

经过初步调研,这与Linux缓存机制有关。为了提高文件系统性能,内核利用一部分物理内存分配出缓冲区,用于缓存系统操作和数据文件,当内核收到读写的请求时,内核先去缓存区找是否有请求的数据,有就直接返回,如果没有则通过驱动程序直接操作磁盘。即使你的程序运行结束后,Cache Memory也不会自动释放。这就会导致你在Linux系统中程序频繁读写文件后,你会发现可用物理内存会很少。其实这缓存内存(Cache Memory)在你需要使用内存的时候会自动释放,所以你不必担心没有内存可用。#看到这,基本明白了,我Qt控件在Qt动态库(文件)中,第一进程启动后,一部分库被加载到了linux缓存中,后续进程会省下部分加载时间,因此会快。
验证:第一启动 Helloword-3 关闭后,执行 echo 3 > /proc/sys/vm/drop_caches指令,此时再启动 Helloword-T 打印173ms,与单独第一次启动它时,耗时一致!

字库问题

嵌入式Linux上移植的字库时非常少的,若在跨平台代码中,使用大号字体,使用斜体、加粗等样式时,在嵌入式Linux环境下运行,可能直接导致段错误使得程序崩溃,切问题原因不好追查!!

Qt辅导书

  • 《Qt高级编程》
  • 《C++ Qt设计模式》与下载
  • 《C++ GUI Qt 4 编程 第二版》推荐原书站点,可下载到与本书配套的示例程序,还可以与各位专业人士一起讨论Qt的相关技术问题。

你可能感兴趣的:(C++/Qt)