首页 > 其他 > 详细

使用VS2012编译QT 5.2.1静态库

时间:2014-03-05 17:30:54      阅读:1169      评论:0      收藏:0      [点我收藏+]
记录一下自己用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,至此静态库编译就全部完成了,庆祝一下吧!bubuko.com,布布扣
 
 
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"
bubuko.com,布布扣
 
增加新的QT版本配置:
bubuko.com,布布扣
Ok后配置就完成了。
 
8.建立QT Project进行测试,这一步很关键:
    创建一个qttest的QT 应用程序,开始编译,啊,居然编译不通过!当然不会通过,因为我们编译的QT 5.2.1的VC运行库是MT和MTd,工程向导创建的缺省是MD和MDd,那就改一下吧,Debug版本改为:Multi-threaded Debug (/MTd),这下编译终于通过了,再次bubuko.com,布布扣,离成功又近了一步,那就赶紧Run吧,然后居然弹出一个Assert窗口bubuko.com,布布扣
 
bubuko.com,布布扣
 
当然和大家一样肯定是去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
     这下终于编译通过并运行成功了!这下可以庆祝了。bubuko.com,布布扣
 
 
被这种莫名其妙的问题卡住,很不爽,索性编了一套带调试信息的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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!