几篇关于QT静态编译和QT安装的文章

静态编译QT4.* 
安装QT SDK 后,默认采用的是动态链接库的编译方式,如果需要发布程序,需要在可执行的exe文件中添加必须的动态链接库,然而有些动态链接库文件很大,这并不是我们想要的结果。 

最好的办法是提交一个静态链接的程序。但是安装的Qt是动态编译的,要生成静态的版本,就需要自己重新进行编译。 

首先需要修改位于<QTDIR>\mkspecs\win32-g++下的qmake.conf,在QMAKE_LFLAGS标签中增加-static。 

然后在“开始”菜单中运行Qt Command Prompt程序,会启动一个命令行界面。在里面打入 
Command代码 
configure -static -release -no-exceptions  


接受里面提到的许可之后,就会开始编译生成qmake并进行配置。配置完成以后,再输入 
Command代码 
mingw32-make sub-src  

这样就开始对Qt进行编译,这步需要很长时间。 

重新编译和生成自己写的程序,这样的生成的可执行程序就是使用静态链接的,可以直接在未安装Qt的电脑上运行。这样的副作用就是,可执行文件变得非常大,有6.81MB!动态链接的版本只有82.5KB。当然,如果加上那些依赖的动态链接库,静态链接的程序在体积上还是有优势的。 


QT4安装 

1.解压qt-win-opensource-src-4.4.3.zip到目录 
d:\Qt\4.4.3-msvc2005\ 
2.开始——Microsoft Visual Studio 2005——"Visual Studio Tools", 运行命令行. 
d:\Qt\4.4.3-msvc2005>configure -no-stl -no-dsp -vcproj 
3.nmake 
编译过程大概2小时 
4.设置环境变量: 
PATH="d:\Qt\4.4.3-msvc2005\bin". 
"QMAKESPEC"="win32-msvc2005". 
5.安装Qt Visual Studio Integration v1.2.2 
用户名任意,注册码为 
FGJ7UGX-WQPWJ6X-F4M-UG6ZQC-2G8N2G-6AYP3G-864F 
FGJ58F-HQGNCCM-F4M-BVY8ELX-8KG9WT-NU5JAQ-6C21 
FGBBY3M-WYYUFN9-F4M-GWEVVS9-WTKP39X-UKJUUDM-EE0D 
FGM9UXX-PJ8CRVX-F4M-UQDJFQ9-PXHXTQ-BZF46Y9-694B 
6.打开VS2005,"工具" -> "选项" -> "Qt" -> "Builds", 添加我们刚才编译的Qt代码,名字为"Qt 4.4.3", 路径为"d:\Qt\4.4.3-msvc2005\". 
完成 
测试: 
添加头文件: 
#include <QMessageBox> 
在函数void Test::on_pushButton_clicked()体内添加如下代码: 
    QMessageBox box(this); 
    box.setText("hello world."); 
    box.exec(); 





vs 静态编译 
2009-02-18 19:38 
转自: http://www.qtcn.org/bbs/read.php?tid=13825 
如何使用VC2005编译“真正”的静态Qt应用程序 

(下文只涉及windows,不谈及linux、unix等,另外,这里说的VC2005,是因为我用的是2005,其实其他版本的VC亦同样可以参考) 

首先,你应该该知道什么叫静态引用编译、什么叫动态引用编译。我这里只是简单的提提,具体的可以google一下。 

动态引用编译,是指相关的库,以dll的形式引用库。动态编译的Exe程序尺寸比较小,因为相关的库都没有包含进来。当然,程序发布的时候,还要把相关的库也一并发布出去。 

静态引用编译,是指把相关的库也一并引入Exe文件。这是程序的尺寸就会很大,不过,程序发布就会变得简单很多。 

其次,你可能会注意到我标题上写了“真正”这两个字。为什么我要强调真正这两个字呢?因为使用VC编译的C或者C++程序,都需要相关的C runtime库才能运行。如果你是VC6,相应的库就叫MSVCR,如果是vc2005,那就是MSVCR08,vc2008就是MSVCR09。我这里假设你安装的是VC2005,请进入如下目录:${VS Install Dir}\VC\redist\x86 和 ${System Driver}:\windows\WinSxS,你就会发现下面有很多很多的库。没错,这里相当一部分就是C runtime库。 

好了,言归正传,首先,我们用VC2005写了一个不使用MFC的存C或者C++的程序,怎么发布给最终用户呢?有两个方法: 
(1)静态引用C runtime库:打开“项目”->“XXX属性”->“配置属性”->“C/C++”->“代码生成”->“运行时库”。看到了吧?这里一共有四个选项,其中MT开头的是静态引用,MD开头的是动态引用,d结尾的是Debug调试版本,没有d的是Release发布版本,所以就一共有四个选项。我们选择/MT,然后编译程序(生成的程序应该不小),把这个程序发给用户,然后用户就可以直接运行了。 
(2)动态引用C runtime库:跟上面差不多,不过是用/MD选项编译(程序应该只是几十K),然后发给用户。这时,用户是不能运行这个程序的,会报个什么程序引导失败,重装系统可能会修复问题之类的提示。这是我们还要把C runtime库一并发过去。把${VS Install Dir}\VC\redist\x86\Microsoft.VC80.CRT下的所有文件(注意,是所有,包括那个.manifest文件)发给用户,用户把这些文件放在我们的程序的同一个目录,然后再次运行,这时,程序就起来了(VC2005之后,C runtime库的引用改变了很多,建议google一下)。 

说完C runtime库,就来说说Qt库了,这里我假设你用的是最新的Qt4.4.3。我们编译Qt的时候,configure.exe有很多参数,大家可以configure.exe --help来看看,其中,默认生成的Qt库(这里默认的意思,是指没有加-share或者-static参数)是动态引用的,也就是说,编译完后,在QtDir的lib目录下除了一大堆lib文件外,还有一大堆的dll文件。我们发布我们的Exe程序的时候,需要把相应的Qt库的Dll也一并发给用户。 

按照Qt的安装手册和网上一大堆大牛的说法,加上-static参数后,Qt就可以静态编译了,也就是说,lib目录下之后一大堆lib文件,没有dll文件。是否?我们做个试验: 

首先是设置变量: 
set QTDIR=%CD% 
set PATH=%PATH%;%QTDIR%\bin 
set QMAKESPEC=win32-msvc2005 
"C:\Program Files\Microsoft Visual Studio 8\VC\vcvarsall.bat"" x86 
配置makefile: 
configure -release -static -fast -qt-sql-odbc -qt-sql-sqlite -no-webkit 
(这里的参数就不一一说明了,建议读者打入--help认真查查,特别注明一下,之所以-no-webkit,是因为新版的qt加上了Webkit,而这个东东编译的时候非常耗时间,编译后也很大,有100多M,并且我基本不会用到这个东东,所以忽略它) 
然后 
cd src (我之所以直接进入src目录nmake,是因为不想make其它不相干的模块,节省时间) 
nmake 

漫长的等待之后,我们发现lib下果然只有一大堆lib文件了,而且每个lib文件的尺寸都在M以上,似乎已经成功了。然后我们在安装了qt-vsintegration的VC2005新建一个Qt工程,然后编译一个release版本。编译的时候,问题来了。我们选择/MD选项,这时链接就可以通过,但如果我们想要用/MT选项来使用静态C runtime库,就会报一大堆某某函数链接重复之类的错误。经验告诉我们,之所以不能使用/MT来编译,是因为另外一个库——Qt库使用了另外一种引用方式/MD(原则上来说,一个程序里面的所有模块,都应该使用同一种引用方式,具体可以google一下)。很显然,我们编译的所谓静态Qt程序,一样要背着微软的C Runtime库到处跑,还不够“真正”的静态。 


怎么才能做成完全的静态呢?记得之前编译wxWidgets的时候,它除了有SHARED=0或者1的选项之外,还有一个RUNTIME_LIBS = static or dynamic的选项,很显然,这个RUNTIME_LIBS的选项就是我们想要的选项。不过我翻遍了Qt的安装手册以及网上大牛的文章,都没有提及这个问题,我当时心里就觉得奇怪,难道没人遇到过这个问题?我又认真翻查了configure.exe的help,也没有类似的选项,问题一下就僵住了。 

回忆一下刚才我们编译的时候,屏幕上调用cl.exe编译的时候,有这样一个参数:cl.exe .... -MD .... xxx.cpp,眼利的朋友一下就会发现,这个-MD就是c runtime动态引用的选项。然而,怎么把这个-MD改成-MT呢?我们翻开刚才我们编译的qt的src目录下,随便找个目录进去,打开Makefile.Release,我们就会看到CFLAGS=-MD ........,没错,就是这里。我们只要在这里把-MD改成-MT,就会使用静态c runtime库编译Qt了。我们当然不可能一个一个地替换这些makefile,关键是找出生成这些参数的模板文件。很显然,它肯定在qt的mkspecs目录,我们直奔win32-msvc2005目录,果然找到一个qmake.conf文件,果然找到一个QMAKE_CFLAGS_RELEASE = -O2 -MD,把这里的-MD换成-MT,然后清理一下刚才的生成的配置信息(网上又说用nmake confclean来清空,不过我没有成功,貌似是使用了-fast参数的缘故,不过没关系,把这个目录删掉,重新解压一份源代码就可以了,然后把win32-msvc2005目录下的qmake.conf的-MD换成-MT),重新 
configure -release -static -fast -qt-sql-odbc -qt-sql-sqlite -no-webkit 
然后nmake 
又是漫长的等待。不过我们不要干等,看看出来的编译命令,cl.exe .... -MT .... xxx.cpp,果然变成静态c运行库了。 
编译完之后,像刚才那样,在VC2005建一个Qt的工程,然后用/MT这个选项编译,OK,编译成功,出来的Exe文件大小是4.95M,貌似已经把C runtime库嵌进来了。然后把这个程序放到用户那里运行,OK单个Exe文件运行成功了。 

至此,编译真正静态的Qt程序试验完成。总结一下整个过程,首先是要有耐性,因为编译一次Qt都至少两个小时(当然,用一些技巧,例如-fast,-no-qmake,只编译src等等的技巧可以缩短很多时间),我来回就编译了五次Qt;其次熟悉一些常见的编译、链接的错误,例如一见到XXX库已经引用之类的错误,马上就联想到应该是引用不同的库导致的;最后,要善于发现问题,查找问题。 
简单总结静态编译方法:alt + F7 Configuration Proprity->General->Use of MFC ->Use MFC in a Static Library,Character Set最好选择Use Multi-Byte Character Set,免得一些系统不支持Use Unicode Character Set。最后使用Release编译,在“Build”中选"Set Active Configuration"再选中"win32 Release"后确定。 
好像是用了静态编译的话没有.net framework也可以运行 













【Qt】如何打包发布基于Qt4 Windows的软件 

Qt   2009-08-08 11:41   阅读153   评论0  
字号: 大  中  小 
(本文部分内容出自Qt文档Deploying an Application on Windows) 
先从Windows平台开始。 Windows平台下的软件发布最主要的需求是想办法找到在你的发布中应该包含哪些必须的文件, 同时要保证应用程序运行时能正确找到这些文件, 发布基于Qt的软件也是同样的需求。 就不同的情况一一阐述: 
静态链接的情况 
静态链接是最简单的情况,这种情况下需要发布的文件数量是最少的, 只需要发布一个单独的执行档外加编译器相关的dll文件。 这种情况下Qt库首先要静态编译: 
< [other -static> 
nmake sub-src 
//如果用mingw编译,nmake替换成mingw32-make 
//sub-src指只编译src目录,这样省去编译examples等目录的时间 
注意哦,如果你在同一个build目录用不同的configure选项去编译Qt,  必须在重新configure之前运行nmake distclean清除以前生成的目标和中间文件, 保证一个干净的编译环境,不然有可能会出一些奇怪的链接错误哦~~ 
编译好Qt静态库下一步再编译应用程序: 
cd application_dir 
nmake clean 
qmake -config release 
nmake 
编译成功之后应该得到一个可以独立执行的exe文件, 可以将程序拷贝到其他没有安装qt的机器上测试。 需要注意的是这个程序不一定百分之百可以运行,因为编译器带的库仍然是动态编译的,如果你的目标机里没有这些库的话仍然会有运行时的问题。 后面会讲到如何用工具来检查应用程序的依赖。 
静态链接方法比较重要的缺陷是无法支持插件, 而且插件不能编译进程序中,所以插件提供的功能就丢失了。 这样一来要想用到插件的功能还是要用下面的方法。 
动态链接的情况 
动态链接程序的发布需要解决两个问题, Qt库需要与应用一起发布, 另外插件也要一起打包,并保证放在适当的位置, 这样应用程序才能找到它。 
动态编译应用的基础是先将Qt库动态编译(默认参数即是动态编译),这样用普通的程序编译流程就可生成动态编译的执行档,使用的命令与上面相同。 我们可以用一个Qt的例子测试前面说的发布方法, 在Qt包里带的例子Plug & Paint 
是个非常合适的测试例子,它既包含应用又自带插件文件, 可以很好的验证发布是否正确。 该例子在examples/tools/plugandpaint下。 这个例子如果编译成功, 得到一个plugandpaint.exe和pnp_basictools.dll、pnp_extrafilters.dll两个插件文件。 
程序打包 
第一步,将应用程序和Qt库拷贝到同一目录。(Windows下库的搜索先从当前目录开始,然后是在系统PATH环境变量指定的路径查找。) 
第二步,检查应用程序还依赖哪些dll,如编译器带的dll或其他系统dll。 参见应用程序的依赖关系一节。 
第三步,验证程序可以在目标系统上正确运行, 将目前包里的文件拷贝到目标系统上,尝试运行程序。 
第四步,发布插件程序。 插件和普通的动态库的发布不同, 不能简单的将之拷贝到应用目录里。 应用程序在运行时会在其对应的plugins目录下去查找插件。 针对这个例子,发布包应该类似这样的结构: 
模块 
文件名 
执行档 plugandpaint.exe 
Basic Tool插件 plugins\pnp_basictools.dll 
ExtraFilters插件 plugins\pnp_extrafilters.dll 
Qt Core模块 qtcore4.dll 
Qt Gui模块 qtgui4.dll 
除了程序和Qt库,还有下面的编译器库: 
VC++ 6.0 
VC++ 7.1 (2003) 
VC++ 8.0 (2005) 
C运行库 msvcrt.dll msvcr71.dll msvcr80.dll 
C++运行库 msvcp60.dll msvcp71.dll msvcp80.dll 
插件的位置除了Qt默认的路径还可以通过代码里调用Qt的API来指定, 相应的API是QApplication::addLibraryPath()或QApplication::addLibraryPaths(). 如: 
qApp->addLibraryPath(”c:\some\path”); 
上述代码的推荐调用位置是在main函数中,QApplication构造完毕之后。 应用程序会在搜索默认路径之后去搜索你指定的库路径。 
Visual Studio 2005 
vs2005编译的程序在发布的时候还需要考虑一些额外的情况,比较麻烦点。 要把manifest文件拷贝到应用程序的目录, 这个文件包含应用的依赖信息, 在运行时需要用到。 另外,如果你的动态库的依赖和应用不同,那么还需要把manifest文件内嵌到dll文件中。 Qt4.1.3之后的版本提供了CONFIG选项来提供内嵌manifest文件的功能, embed_manifest_dll和embed_manifest_exe, 用法是将下面的选项加入pro文件, 如下: 
CONFIG+=embed_manifest_exe 
默认情况下embed_manifest_dll已经开启。 关于manifest文件的更多信息参考MSDN的相关文章。 
有两种发布vc运行库的方法, 一个是安装vs的运行库到目标系统中, 另外是将库打包到应用程序的目录。 打包vs运行库很简单,就是把 <Visual Studio Install Path>\VC\redist\<Architecture>\Microsoft.VC80.CRT拷贝到应用程序目录,与应用程序一起打包。 如果你在打包运行库的同时还要发布插件程序,要注意把manifest文件从插件中去掉,不然在一些系统上会导致插件无法加载。 去掉manifest的方法是在插件的pro文件中加入下面的选项: 
CONFIG-=embed_manifest_dll 
VS系统的运行包可以免费获得, 只需要将这个安装包和你的应用安装包一起发布,并且在安装你的程序的时候去运行这个安装包就行了。 比如32位的x86系统, 安装32bit-x86-vs运行时包。 其他平台对应的包可以在微软网站找到。 
应用程序的依赖关系 
额外的依赖库 
这里我们的秘密武器终于隆重登场了! 那就是 Dependency Walker工具。 看一张截图: 

用这个工具检查上面的例子, 发现下面的库不是系统自带的: 
Qt 
VC++ 6.0 
VC++ 7.1 (2003) 
VC++ 8.0 (2005) 
MinGW 
QTCORE4.DLL 

QTGUI4.DLL 
MSVCRT.DLL 

MSVCP60.DLL 
MSVCR71.DLL 

MSVCP71.DLL 
MSVCR80.DLL 

MSVCP80.DLL 
MINGWM10.DLL(如果用mingw来编译的话需要这个库) 
别忘了也检查一下plugin库的依赖。 
Qt自带的插件 
很多情况下,我们的程序还依赖Qt带的一些插件,比如图像格式的支持或数据库驱动支持等。 这些插件需要放在plugins的特定子目录下, 如图像格式插件在plugins\imageformat下. Qt搜索插件的默认路径是QTDIR\plugins, 这个路径已经写入了Qt库中, 但我们可以通过以下几种方法来override这个路径。 
编辑qt.conf文件,推荐的方法(后面将写一篇关于qt.conf的帖子) 
用前面提到的QApplication::addLibraryPath函数 
使用第三方的工具修改QtCore库里写入的路径 
Qt文档里有一篇专门写插件的文章,如果你在编译和发布插件时遇到了问题,参考 How to Create Qt Plugins

你可能感兴趣的:(几篇关于QT静态编译和QT安装的文章)