专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

[原创]也谈QT4.7静态编译

作者:佚名   来源:本站原创   点击数:  更新时间:2011年03月04日   【字体:
网上有很多教程了,这里讲一下我的过程.什么东西试一试才知道是否正确,只有自己做过以后才记忆深刻.
我安装的是这个版本,在此之前,VS2008 已经安装好了.

安装好了后,直接在开始菜单中运行Qt 4.7.0 Command Prompt 命令行,启动控制台窗口
 
这个命令行实际上是一个批处理文件启动的,这个批处理文件的内容如下:
//============
@echo off
rem
rem This file is generated by the Qt installer
rem
echo Setting up a Qt environment...
set QTDIR=e:\Qt\4.7.0
echo -- QTDIR set to e:\Qt\4.7.0
set PATH=e:\Qt\4.7.0\bin;%PATH%
echo -- Added e:\Qt\4.7.0\bin to PATH
set QMAKESPEC=win32-msvc2008
echo -- QMAKESPEC set to "win32-msvc2008"
if not "%1"=="vsvars" goto ENDVSVARS
call "C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat"
:ENDVSVARS
if not "%1"=="vsstart" goto ENDVSSTART
call "C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat"
devenv /useenv
:ENDVSSTART

//==============
内容很简单,但比较方便,QT之前的版本,好像需要自己写一个这样的批处理.




 
在命令行下输入 configure –h 可以看configure程序的帮助
 
输入
configure -release -static -fast –no-qmake -no-webkit -no-qt3support -no-plugin-manifests
开始配置要编译的项目.我对configure程序的理解是,它遍历当前的*.pro文件,根据这些文件生成对应的Makefike. 而Makefile 文件是告诉编译器如何编译项目文件
 
静态的QT 框架,有两个“静态”级别:
 一是不依赖QtCore4.dll 等动态链接库,但这种级别的静态库还是要依赖 Msvcp90.dll Msvcrt90.dll,这些Runtime库并没有一起静态进去。
 
二是完全静态,连Msvcp90.dll Msvcrt90.dll,这些Runtime库一并静态包含,这样在没有QT运行库,也没有VC9.0文件库的用户机器上也能很好的运行。
 
第一种,我已经试过了,跳过下面的步骤,不修改qmake.conf 即可,这里我们要编译第二种,因为想静态,就彻底点,毕竟编译一次不容易。
 
 
在qt的安装目录下找到mkspecs目录,这个目录下安装的是各种开发环境的环境变量。这里我们修改win32-msvc2008 ,打开qmake.conf 文件,这是一个文本文件,把下面红圈中的 QMAKE_CFLAGS_RELEASE 和 QMAKE_CFLAGS_DEBUG 中的 -MD -MDd 分别修改为 -MT 和 -MTd 即可,MT是把vc的Runtime也包含进来。


 
设置好了,运行configure程序,必须在这之前设置qmake.conf文件,否则改动不会在configure配置之后的Makefile文件中体现。
 
这个项目我先后编译过两次,第一使用的参数是:
Configure –static –fast –no-qmake –no-webkit
在正式编译之前,我还试过 Configure –static –no-webkit 这样的参数组合,配置过程非常的漫长,但后来用Configure –static –fast –no-qmake –no-webkit 则非常的快,没有细究–fast –no-qmake 参数到底做了那些事。
配置完成以后,在命令行输入 nmake 开始编译,编译过程非常的漫长,估计只少有5个小时。难以想象,如果把 qtwebkit 一起编译有多么可怕。编译完成以后,目录增大了23G。
后来分析,很多demo ,example 是没有必要编译的。 第一次编译时是没有修改qmake.conf的,编译完毕,能生成静态库,用DEPEND查看,需要msvcrt90.dll 和 msvcp90.dll。
 
第二次编译使用的configure参数是:
Configure –static –fast –no-qmake –no-webkit –no-qt3support –no-plugin-manifests
QT3 我是没有用过,我们公司也没有在QT3上的遗留产品,因此这个肯定不要了。最后一个参数我不是太明白,但网上推荐这么做,也就加上了。
 
回车以后会出现下面的界面,网上都没有人介绍,第一步是选择QT的版本,是LGPL版还是商业版,我这里用的是LGPL版本,因此选o 回车。
 
接下来会提示是否接受LGPL协议,输入y确认。







 
配置过程中会显示一些开关的默认选项,以及一些目录的地址。
简单警告提示后几秒钟开始自动生成Makefile文件。

如果之前用过不同的参数配置,那么需要先运行 nmake confclean , 但这个命令我没有成功过。似乎网上也有人说没有成功。
直接这么nmake 会非常的耗时,因为它会把当前目录下所有的Makefile都编译生成一遍
当然也包含Demos 和Example 目录
 
因为我们只会用到Src目录下的东西,因此,在命令行下输入 cd src 回车,然后在运行nmake。只编译src目录下的相关文件
 
经过一个多小时的时间就编译完了,很快。


看看 cl的参数 –O2 –MT ,说明它是静态编译的。
接下来在这个目录下运行 nmake clean 删除编译过程中的临时文件。 OK 任务完成了。
 
用QtCreator 创建了一个最简单的UI程序,编译后,Release版本有5.4M大小,用Depend看,以及不依赖QtCore4.dll 和 其他dll 了,当然Msvcp90.dll 和Msvcrt90.dll也不用依赖了。
 
 
我还发现了一件有趣的事,静态编译后的lib文件还是放在lib目录下,同样QtCore项目编译的动态库是 QtCore4.lib 和 QtCore4d.lib ,而而静态库是 QtCore.lib 和 QtCored.lib ,那么编译器又是如何找到它们的呢? 这个我还没有细细的研究。
 
当我编译静态库以后,创建的新项目会自动使用静态链接,也就是说,我在.pro文件中没有写
CONFIG += static
它也会自动去链接静态Lib。
接下来我又做了一个实验,把qmake.conf 中的MT,MTd 该为 MD ,MDd。
重新生成这个项目,链接的时候报错了,
@C:\DOCUME~1\tase\LOCALS~1\Temp\TestStatic.exe.26166109.jom
LIBCMT.lib(invarg.obj) : error LNK2005: __invoke_watson 已经在 MSVCRT.lib(MSVCR90.dll) 中定义
LIBCMT.lib(invarg.obj) : error LNK2005: __invalid_parameter_noinfo 已经在 MSVCRT.lib(MSVCR90.dll) 中定义
LINK : warning LNK4098: 默认库“LIBCMT”与其他库的使用冲突;请使用 /NODEFAULTLIB:library
release\TestStatic.exe : fatal error LNK1169: 找到一个或多个多重定义的符号
 
看来是库不兼容啊!
 
正式使用的时候,把静态编译的QT 目录单独使用,动态库在这里是用不着了!
 
个人感觉用QT是不适合静态编译的,QT的静态编译EXE文件太大了,一个什么都不做的exe就有5M之多。相比之下还是VC6静态编译效果好!
 
但我们用QT,又有几个人在乎它的静态编译呢?
关闭窗口

相关文章