找回密码
 立即注册
收起左侧

【抛砖引玉】Qt静态编译配置VS动态编译

25
回复
17665
查看
[复制链接]
累计签到:894 天
连续签到:1 天
来源: 2014-2-20 11:37:20 显示全部楼层 |阅读模式
【抛砖引玉】Qt4.8.5 + Creator 2.8.0静态编译配置VS动态编译

第一部分 写在前面

         作为一个Qter,我想很多人会和我一样,怎么才能编译输出一个可执行文件,这样不需要其他动态链接库就可以放在别人的同平台上的电脑上运行,也就是“静态编译”?带着这个疑问,我将在本文中介绍动态编译与静态编译生成的文件到底有什么差异。
         我只是一个Qt的初学者,有的只是对Qt的爱好,文中语言若有不巧当之处,还请见谅。
         文中提到的项目及工具下载地址:
1、  静态编译和动态编译测试源项目:http://pan.baidu.com/s/1AHVaQ
2、  Dependency Walker:http://pan.baidu.com/s/1bniV4Ur
4、  Enigma Virtual Box v6.80:http://pan.baidu.com/s/1ntx4rnN
5、  MoleBox Pro 2.6.5:http://pan.baidu.com/s/1hqBlCAK

第二部分 动态编译

        当安装好QtCreator后,默认的就是动态编译方式。
    在没有添加系统环境变量的情况下,到编译目录运行会出现如下错误。

    我相信大家都知道这个问题,我在此提出这个问题的目的是向大家推荐一款软件,Dependency Walker
    树形图中黄色问号部分就是缺少的
dll,复制dllexe目录下再次检验是否缺少dll。如下图第一次缺少mingwm10.dllQtCored4.dllQtGuid4.dll,第二次打开缺少libgcc_s_dw2-1.dll,所以一共是拷了四个文件。
   
PS:不用管软件中间部分窗口中的提示。





现在就可以运行了。



第三部分 静态编译
第一步

文件目录C:\Qt\4.8.5\mkspecs\win32-g++\qmake.conf

改成

其他不要动,保存,关闭。

第二步
运行Qt 4.8.5 Command Prompt



输入configure -platform win32-g++ -static -release -no-exceptions





回车
输入o





回车
输入y





回车
等待中(根据电脑配置的不同,时间有所差异,我的电脑用时12分钟)











输入mingw32-make sub-src
回车





等待中(根据电脑配置的不同,时间有所差异,我的电脑用时1.5小时)





到此为止,静态编译Release成功,像往常一样新建项目,编译运行。Release没有问题,但是Debug会出现以下问题。






新建项目,内容和原来一样。编译Release,用Dependency Walker查看。





以下是本次测试中动态编译Release和静态编译Release发布程序所需文件的对比。





第四部分 如何在动态编译模式单文件发布程序

         提到这个问题,要说到两个软件,MoleBoxEnigma Virtual Box
         我是用的是MoleBoxPro 2.6.5





Enigma Virtual Box 6.80(这个是绿色单文件版,最新版7.10,但却是安装版)



第五部分 如何回到动态编译

输入configure -platform win32-g++ -shared –release





回车
输入o



回车
输入y



回车
等待完成



到此为止,又回到动态编译模式,ReleaseDebug都是动态编译。

第六部分 静态编译VS动态编译

         借助此次静态编译和动态编译配置间的切换,我做了以下测试。
测试环境:
操作系统:Windows 8.1专业版X64
处理器:Celeron(R) Dual-Core CPU       T3000 @ 1.80GHz    1.80GHz
内存:3GB
Qt4.8.5
Creator2.8.0
注:1、静态编译Debug出错,所以无数据。
2、无特殊注明情况下,文件大小单位为MB

表1 动态编译和静态编译差异概览
  
编译方式
  
版本
生成文件数量
可删除文件数量
EXE文件大小
依赖DLL文件数量
依赖DLL文件大小
发布总大小
  
动态编译
  
Debug
5
4
885KB
4
214MB
215MB
Release
5
4
85KB
4
12.5MB
12.5MB
  
静态编译
  
Debug
4
4
-
-
-
-
Release
5
4
8.75MB
0
0
8.75MB
由上表可知:
1、在不打包程序和压缩(加壳)情况下,发布程序文件总大小:静态Release < 动态Release << 动态Debug。
2、根据Release和Debug版本的区别,可以推断:静态Release < 静态Debug。



表2 分别使用MoleBox 和 Enigma Virtual Box打包程序及与UPX压缩程序的对比
  
编译方式
  
版本
原大小
MoleBox Pro 2.6.5
Enigma Virtual Box 6.80
UPX
  
动态编译
  
Debug
215MB
63.8MB
64.0MB
-
Release
12.5MB
5.44MB
5.70MB
-
  
静态编译
  
Debug
-
-
-
-
Release
8.75MB
3.98MB
9.09MB
3.19MB
由上表可知:
1、打包程序可以明显缩小文件体积(≥ 50%)。
2、MoleBox比Enigma Virtual Box略胜一筹。
3、单文件压缩时,UPX占据优势,Enigma Virtual Box把文件越压缩越大。
注:
1、测试过程中,运行MoleBox打包的程序有时会提示Out Of Memory的错误,说明MoleBox Pro 2.6.5不稳定。
2、想用UPX对MoleBox和Enigma Virtual Box打包的程序进行压缩时提示,CantPackException:section size problem的错误。
3、Enigma Virtual Box耗时比MoleBox长。



表3 四种方式发布程序最小文件大小

源文件大小
MoleBox打包
Enigma Virtual Box打包
UPX
最小文件大小
  
静态Debug
  
0
0
0
0
0
  
静态Release
  
8.75
3.98
9.09
3.19
3.19
  
动态Debug
  
215
63.8
64
0
63.8
  
动态Release
  
12.5
5.44
5.7
0
5.44
由上表可知:
1、使用UPX对静态Release编译的程序压缩后,文件最小。



表4 MoleBox与Enigma Virtual Box的对比

源文件大小
MoleBox打包
Enigma Virtual Box打包
  
静态Debug
  
0
0
0
  
静态Release
  
8.75
3.98
9.09
  
动态Debug
  
215
63.8
64
  
动态Release
  
12.5
5.44
5.7
由上表可知:
1、MoleBox比Enigma Virtual Box略占优势。
注:
1、打开速度Enigma Virtual Box占优势,而且稳定性占优势。



表5 MoleBox 、Enigma Virtual Box、UPX用于压缩文件的对比

源文件大小
MoleBox压缩
Enigma Virtual Box压缩
UPX
  
静态Release
  
8.75
3.98
9.09
3.19
  
压缩比
  
1
0.454857143
1.038857143
0.364571429
由上表可知:
1、UPX占绝对优势。
2、Enigma Virtual Box压缩后文件竟然比源文件还大。



图1 两种编译方式两种版本大比拼



图2 MoleBox VS Enigma Virtual Box



图3 压缩比



第七部分 结语

通过以上的图表对比可知:

    的确,静态编译产生的文件比打包压缩后的动态编译文件还小。
而且静态编译是一步到位,不用再对文件进行打包和压缩。但是,请
看下图

    显而易见,静态Release生成的目标程序是动态Debug的10多倍,是
动态Release的100多倍。
    试想一下,一个程序是这样,那么10个、100个、1000个、10000个
……会是什么样子。

最后用一句话总结一下:
    静态编译是给软件使用者的电脑节省空间;
    动态编译是给软件开发者的电脑节省空间。


    不言而喻,Qter应首选动态编译。



第八部分 写在最后

    看到这里,你也许会问这个帖子不应该挂悬赏,应该是个教程贴。
至此,我也该说出我发此贴的目的了,正如标题中所说“抛砖引玉”。
①我希望有人可以给出更简单更方便的静态编译方法;
②我希望有人可以发现更好的打包程序软件和压缩软件;
③我最希望有人可以提出动态编译和静态编译自由切换的解决方案。
    【Qter.org有您更精彩】



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
参与人数 2人气 +5 收起 理由
shasidaran + 2 很详细!
xflcx1991 + 3 对我帮助很大!

查看全部评分总评分 : 人气 +5

相关帖子

回复

使用道具 举报

尚未签到

2014-2-20 11:54:09 显示全部楼层
支持一下,好像你自己有权限可以置顶的吧?

对了,你这悬赏100是怎么回事。。。
回复 支持 反对

使用道具 举报

累计签到:894 天
连续签到:1 天
2014-2-20 13:28:11 显示全部楼层
Joey_Chan 发表于 2014-2-20 11:54
支持一下,好像你自己有权限可以置顶的吧?

对了,你这悬赏100是怎么回事。。。 ...

嗯,我有置顶的权限。
这个悬赏100是我希望有人可以提出更好的静态编译的方法。
这篇文章中的方法又不足之处,正如标题中说的“抛砖引玉”一样。
回复 支持 反对

使用道具 举报

累计签到:1570 天
连续签到:1 天
2014-2-21 17:58:14 显示全部楼层
很好的帖子,讲得很细,分析得很全。

我想说几点:

1.其实动态编译有一个很大的优点就是可以多个exe文件共享dll文件,所以如果要发布多个Qt程序,动态编译文件体积更小。

2.其实,静态库和动态库应该是可以同时存在的,在Qt Creator中配置一下,在创建或者打开项目的时候选择使用哪个Qt版本即可。

3.好像在编译静态库的时候可以配置哪些模块编译,哪些模块不编译,这样生成的可执行文件就可以不包含一些没用的东西,那样文件体积可能更小。

第2,3两条需要楼主测试一下!

最后再给个建议就是,希望文章中可以把关键步骤介绍详细一点,比如输入一条命令,这条命令是干嘛的,这样对初学者更有帮助。
回复 支持 反对

使用道具 举报

累计签到:609 天
连续签到:1 天
2014-2-22 10:01:39 显示全部楼层
赞同yafeilinux的观点--- ---"希望文章中可以把关键步骤介绍详细一点,比如输入一条命令,这条命令是干嘛的,这样对初学者更有帮助。" 让我们知其然的同时,能够知其所以然!
回复 支持 反对

使用道具 举报

累计签到:331 天
连续签到:1 天
2014-2-22 18:46:23 显示全部楼层
图表是用什么做的,蛮漂亮的。
回复 支持 反对

使用道具 举报

累计签到:894 天
连续签到:1 天
2014-2-23 08:06:11 显示全部楼层
yafeilinux 发表于 2014-2-21 17:58
很好的帖子,讲得很细,分析得很全。

我想说几点:

谢谢yafei老师的赞同和指点,对于第2、3条,我会找时间测试一下。

由于时间问题,刚开学,手里的任务还没做完,所以没把命令解释清楚。

有时间,我会再修改一下。
回复 支持 反对

使用道具 举报

累计签到:894 天
连续签到:1 天
2014-2-23 08:06:46 显示全部楼层
心寒若冰 发表于 2014-2-22 10:01
赞同yafeilinux的观点--- ---"希望文章中可以把关键步骤介绍详细一点,比如输入一条命令,这条命令是干嘛的 ...

嗯,好的,找时间我修改一下,下次发帖一定注意。
回复 支持 反对

使用道具 举报

累计签到:894 天
连续签到:1 天
2014-2-23 08:07:45 显示全部楼层
loadomain 发表于 2014-2-22 18:46
图表是用什么做的,蛮漂亮的。

用Office 2013的Excel做的,为了直观的表示,做了几张图。
回复 支持 反对

使用道具 举报

累计签到:331 天
连续签到:1 天
2014-2-24 15:01:54 显示全部楼层
Syylc120317 发表于 2014-2-23 08:07
用Office 2013的Excel做的,为了直观的表示,做了几张图。

记忆中2003挺难看的,现在渲染地越来越漂亮了。
回复 支持 反对

使用道具 举报

累计签到:894 天
连续签到:1 天
2014-2-24 21:11:26 显示全部楼层
loadomain 发表于 2014-2-24 15:01
记忆中2003挺难看的,现在渲染地越来越漂亮了。

嗯,不怎么用Excel,这一次用一下,没有想到这么炫
回复 支持 反对

使用道具 举报

累计签到:2 天
连续签到:1 天
2014-2-26 09:28:33 显示全部楼层
使用qt静态的编译共享库 怎么只产生lib库,没有dll啊?
好像lib也不能链接,这是为什么?
回复 支持 反对

使用道具 举报

累计签到:894 天
连续签到:1 天
2014-2-26 09:43:04 显示全部楼层
zhang2349 发表于 2014-2-26 09:28
使用qt静态的编译共享库 怎么只产生lib库,没有dll啊?
好像lib也不能链接,这是为什么? ...

静态的产生lib和a文件,动态编译才生成dll文件。
回复 支持 反对

使用道具 举报

累计签到:2 天
连续签到:1 天
2014-2-26 10:11:39 显示全部楼层
Syylc120317 发表于 2014-2-26 09:43
静态的产生lib和a文件,动态编译才生成dll文件。

那我想编译自己的dll 但不依赖于qt库 要怎么弄呢?
回复 支持 反对

使用道具 举报

累计签到:894 天
连续签到:1 天
2014-2-26 13:30:39 显示全部楼层
zhang2349 发表于 2014-2-26 10:11
那我想编译自己的dll 但不依赖于qt库 要怎么弄呢?

你百度两个视频,是教程。
Candand Qt 97 - How to Create a DLL
Candand Qt 98 - How to use a DLL
回复 支持 反对

使用道具 举报

累计签到:2 天
连续签到:1 天
2014-2-26 13:57:38 显示全部楼层
Syylc120317 发表于 2014-2-26 13:30
你百度两个视频,是教程。
Candand Qt 97 - How to Create a DLL
Candand Qt 98 - How to use a DLL

你还是没明白我的意思
像你帖子里说的动态编译的exe 要依赖QtCored4.dll等dll, 静态编译exe的就不需要QtCored4.dll

我现在按你的流程来创建一个dll, 动态的编译会产生dll,并依赖QtCored4.dll等dll, 静态编译出来的话就不产生dll了 就只有lib库了,可以也不能被其他exe链接


我的目的是想要 创建一个dll,但是不想依赖QtCored4.dll等dll。
回复 支持 反对

使用道具 举报

累计签到:894 天
连续签到:1 天
2014-2-26 14:22:34 显示全部楼层
zhang2349 发表于 2014-2-26 13:57
你还是没明白我的意思
像你帖子里说的动态编译的exe 要依赖QtCored4.dll等dll, 静态编译exe的就不需要Qt ...

你这么说的意思是把QtCored4.dll编译到你的dll里面去,
你在头文件里包括#include<QCore>这样行吗,
我没有试过这种方法,现在我的电脑是动态编译的。
回复 支持 反对

使用道具 举报

累计签到:12 天
连续签到:1 天
2014-3-13 23:14:58 显示全部楼层
初学也能这么牛啊,这些知识不知可以在那本书或哪里可以获取啊。
回复 支持 反对

使用道具 举报

累计签到:894 天
连续签到:1 天
2014-3-14 08:05:22 显示全部楼层
zhiwo513 发表于 2014-3-13 23:14
初学也能这么牛啊,这些知识不知可以在那本书或哪里可以获取啊。

书中没有,不过网络上有参考。
回复 支持 反对

使用道具 举报

累计签到:79 天
连续签到:1 天
2014-7-11 13:35:42 显示全部楼层
静态编译,给控制塔器输入configure -platform win32-g++ -static -release -no-exceptions,回车以后提示不是内部命令这是怎么回事,一直都卡在这里。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了