您的位置:首页 > 编程语言 > Qt开发

使用VS2012编译QT 5.2.1静态库

2014-03-04 22:13 507 查看
记录一下自己用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窗口







解决方法:

1. 添加qwindows.lib的路径。

项目-> 属性-> 配置属性->链接器-> 常规-> 附加库目录,加上qwindows.lib的路径。



2.在工程的main.cpp中,加入如下代码:

#include <QtPlugin>

Q_IMPORT_PLUGIN (QWindowsIntegrationPlugin);

#pragma comment (lib,"opengl32.lib")

#ifdef _DEBUG	//Debug mode
#pragma comment (lib,"Qt5PlatformSupportd.lib")
#pragma comment (lib,"qwindowsd.lib")
#else			//Release mode
#pragma comment (lib,"Qt5PlatformSupport.lib")
#pragma comment (lib,"qwindows.lib")
#endif


3.如果要兼容XP,修改vc2012的平台工具集

项目-> 属性-> 配置属性-> 常规-> 平台工具集

选择v110_xp



用vs2012 x86编译的Qt5.1.1,assistant无法启动问题

被这种莫名其妙的问题卡住,很不爽,索性编了一套带调试信息的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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: