记录一下自己用VS2012编译QT 5.2.1为静态库的过程,希望给能看到本文的朋友一个参考。
1.首先下载源码(版本:5.2.1):
http://download.qt-project.org/official_releases/qt/5.2/5.2.1/single/qt-everywhere-opensource-src-5.2.1.zip
解压到目录 qt-everywhere-opensource-src-5.2.1\
2.更改VC运行库的配置:
VS2012对应的配置文件是:qt-everywhere-opensource-src-5.2.1\qtbase\mkspecs\win32-msvc2012\qmake.conf
把MD改为 MT, MDd改为MTd,共三处:
QMAKE_CFLAGS_RELEASE =
-O2 -MT
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO +=
-O2 -MT -Zi
QMAKE_CFLAGS_DEBUG =
-Zi -MTd
3.建立一个批处理文件:
比如建立一个文件名为vs2012.build.bat的bat文件,放到目录qt-everywhere-opensource-src-5.2.1下面,然后进行编辑,内容如下:
configure -confirm-license -opensource
-platform win32-msvc2012 -vcproj -debug-and-release -static -prefix
"D:\Qt\5.2.1-static" -no-opengl -qt-zlib -qt-libpng -qt-libjpeg -qt-freetype
-no-angle -nomake tests -no-compile-examples
4.运行vs2012.build.bat:
首先必须要运行VS2012的批处理文件(安装后会有这个快捷方式):VS2012
x86 Native Tools Command
Prompt.bat,这样就打开了一个控制台窗口,CD到目录qt-everywhere-opensource-src-5.2.1,再运行vs2012.build.bat,
完成后检查是否成功,成功后就继续下一步.
5.开始编译:
编译只要执行 nmake
即可,这是一个漫长的过程,................,不出意外最后没有任何错误的结束了。
6.安装:
上述编译成功后,只要执行 nmake
install就会把最终的bin/lib/include等等相关的文件复制到我们之前配置的目录D:\Qt\5.2.1-static,至此静态库编译就全部完成了,庆祝一下吧!
7.安装和配置QT VS Add-in:
但不要高兴的太早,我们必须得建立一个测试程序运行起来才算成功,有一个VS2012的插件是必须要安装的,那就是Qt
VS Add-in, 我下载的是最新的:
http://download.qt-project.org/development_releases/vsaddin/qt-vs-addin-opensource-1.2.3-alpha.exe,安装完成后运行VS2012,会多一个"Qt5"的菜单,运行
"Qt Options"
增加新的QT版本配置:

Ok后配置就完成了。
8.建立QT Project进行测试,这一步很关键:
创建一个qttest的QT 应用程序,开始编译,啊,居然编译不通过!当然不会通过,因为我们编译的QT
5.2.1的VC运行库是MT和MTd,工程向导创建的缺省是MD和MDd,那就改一下吧,Debug版本改为:Multi-threaded Debug
(/MTd),这下编译终于通过了,再次

,离成功又近了一步,那就赶紧Run吧,然后居然弹出一个Assert窗口

。
当然和大家一样肯定是去google错误了,获取的信息是:插件无法加载,毕竟我们现在是static library,当然无法加载
dll了,好在官方给出了staitc library加载plugin的办法:使用宏
Q_IMPORT_PLUGIN,在main.cpp中增加代码如下:
#include < QtPlugin >
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)
至于为什么是QWindowsIntegrationPlugin这个名字,在网上搜索了很久都没找到,最后我是在qwindows.lib中搜索到的
.
继续编译,报错unresolved external symbol "struct
QStaticPlugin const __cdecl
qt_static_plugin_QWindowsIntegrationPlugin(void),这个简单,增加lib path:
$(QTDIR)\plugins\platforms,然后增加qwindowsd.lib(Release是qwindows.lib).
再进行编译,又link出错:
qwindowsd.lib(qwindowsintegration.obj) : error LNK2001: unresolved external
symbol "public: virtual void __thiscall
QBasicFontDatabase::populateFontDatabase(void)
那肯定是有依赖的lib没增加,最后找到了需要再手动增加 Qt5PlatformSupportd.lib(同样Release是Qt5PlatformSupport.lib),最终QT
lib文件有这样几个文件:
Qt5Cored.lib
Qt5Guid.lib
Qt5Widgetsd.lib
qwindowsd.lib
Qt5PlatformSupportd.lib
这下终于编译通过并运行成功了!这下可以庆祝了。

被这种莫名其妙的问题卡住,很不爽,索性编了一套带调试信息的Release版,调试后,发现问题是出在文件TextEncodingRegistry.cpp中(Qt5Webkit模块):PassOwnPtr<TextCodec>
newTextCodec(const TextEncoding&
encoding){ MutexLocker
lock(encodingRegistryMutex());
ASSERT(textCodecMap);
TextCodecFactory factory =
textCodecMap->get(encoding.name());
ASSERT(factory.function); return
factory.function(encoding,
factory.additionalData);}上面那行红色的代码,encoding.name()的值是"ISO-8859-1",返回的factory却是空的,导致后面调用它的成员函数function时直接Access
Violation。在网上查了一下,发现这个问题早在Qt 4.8.2时就已经存在了,同样的工具链(vs2012
x86),同样的异常代码:https://bugs.webkit.org/show_bug.cgi?id=90008好像是HashMap的成员函数get的问题,还没有细查,依照上述链接中的解决方案修改就好了:将函数:static
void addToTextCodecMap(const char* name, NewTextCodecFunction function, const
void* additionalData){ const
char* atomicName = textEncodingNameMap->get(name);
ASSERT(atomicName);
textCodecMap->add(atomicName, TextCodecFactory(function,
additionalData));}修改为:static
void addToTextCodecMap(const char* name, NewTextCodecFunction function, const
void* additionalData){ // const
char* atomicName = textEncodingNameMap->get(name);
const char* atomicName;
TextEncodingNameMap::iterator pos; for (pos =
textEncodingNameMap->begin(); pos != textEncodingNameMap->end(); ++pos)
{ if (strcmp(pos->key,
name) == 0) {
atomicName = pos->value;
break;
} }
ASSERT(atomicName);
textCodecMap->add(atomicName, TextCodecFactory(function,
additionalData));}将函数:PassOwnPtr<TextCodec>
newTextCodec(const TextEncoding&
encoding){ MutexLocker
lock(encodingRegistryMutex());
ASSERT(textCodecMap); TextCodecFactory factory =
textCodecMap->get(encoding.name());
ASSERT(factory.function); return
factory.function(encoding,
factory.additionalData);}修改为:PassOwnPtr<TextCodec>
newTextCodec(const TextEncoding&
encoding){ MutexLocker
lock(encodingRegistryMutex());
ASSERT(textCodecMap); // TextCodecFactory factory
= textCodecMap->get(encoding.name());
TextCodecFactory factory; TextCodecMap::iterator
pos; for (pos = textCodecMap->begin(); pos !=
textCodecMap->end(); ++pos) {
if (strcmp(pos->key, encoding.name()) == 0)
{ factory =
pos->value;
break;
} }
ASSERT(factory.function); return
factory.function(encoding,
factory.additionalData);}注:Qt5Webkit的KeyValuePair的键/值使用的是key/value,不是原来的first/second。 使用VS2012编译QT 5.2.1静态库,布布扣,bubuko.com
使用VS2012编译QT 5.2.1静态库
原文:http://www.cnblogs.com/elitiwin/p/3581301.html