用msvc2008编译qt5.4.0

我这里记录一下我用msvc2008编译qt的过程。

qt源码版本:qt5.4.0

编译日期:2015-08-23

编译环境:msvc2008sp1 x86

1.      请先参阅http://doc.qt.io/qt-5/windows-requirements.html,准备环境:Python、Perl、Ruby

2.      虽然qt5.4不再必须依赖于icu,但是如果你要编译qtwebkit,那么还是得编译icu,而icu5.3官方提供的源码包里只有vc2010的解决方案和项目,所以第一步是用vc2008编译icu5.3

    a)        但是你有没有发现qt发行版中的icu53dt.dll有20M+!!!所以这第一小步就献给裁减icu 。google icu可以知道icu是个编码转换库,类似iconv和boost.locale。实际上在Windows上就是WideCharToMultiByte和MultiByteToWideChar两个API的工作,但是很不幸的是qtwebkit并没有使用这两个函数去代替icu库。查阅icu官网可知,icudt里边包含的只是编码字符集等资源,没有多少实际的代码,那么我们就可以想办法去掉我们不会用到的资源——这一点icu早就想到了,他提供了一个页面用于定制icu的资源:http://apps.icu-project.org/datacustom。但是,万事就怕但是,这个页面在我着手整理qt的编译的时候登不上去,我也上不去,顺便又看了下其他页面,发现下载页面(http://site.icu-project.org/download/53)上在说正事的地方也挂了,我去。还好我之前有下过源码,也定制过自己的资源,好怕怕。

    b)        你经过一系列的挣扎拿到了icu5.3的源码和定制过的icudt53l.dat

    c)        用vc2010编译了几次发现整个过程大致是先编译出来icudt53(d).dll,然后makedata那个工程用pkgdata把资源再打包进icudt53(d).dll,形成最后的icudt.dll(注意,不管是debug还是release最后生成的都是icudt53.dll),按照官方说的把icudt53l.dat放到source\data\in下面,发现到某一步的时候某个工程使用了某个工具把他解压开放在了source\data\out下面,恕我无能或无心,三个“某”字没搞清楚

    d)        icu真是的,大部分工程的名称跟他们生成的二进制都不一样,而且目标文件路径都是修改过的,这给我把vc2010的项目改成vc2008的带来了很大的工作量。而且你可以看到allinone.sln里的项目有20+个。然而并不是每个都是必须的,请再次恕我无心,我并没有完全搞清楚哪些项目是必须的,但是我知道makedata、pkgdata两个工具项目是必须的,还有所有dll项目。以下是移植为vc2008版的项目时需要注意的地方:

        i.             依据原项目新建Win32 Console空项目或dll空项目,注意要勾选空项目

        ii.             所有的dll项目的输出路径都是跟source在同一级的bin目录:..\..\..\bin或者..\..\bin

        iii.             所有的exe项目的输出文件都是自定义的,比如.\x86\Debug_derb/derb.exe,.\x86\Release\gennorm2.exe。请注意是链接选项里边的输出文件。重要的几个项目和输出文件的对应关系:common -> icuuc,i18n -> icuin,stubdata -> icudt。请不要修改这些输出文件的路径,因为makedata里边的mak文件会用到这些路径下的文件

        iv.             几乎所有的项目的预定义宏都有_CRT_SECURE_NO_DEPRECATE,某些有U_ATTRIBUTE_DEPRECATED=,还有一些有别的。注意都是添加宏,最好不要动IDE自动添加的宏。几个我记忆中比较特殊的:common的debug版中有宏RBBI_DEBUG,debug和release都有U_COMMON_IMPLEMENTATION、_CRT_SECURE_NO_DEPRECATE和U_COMMON_IMPLEMENTATION;i18n都有宏U_I18N_IMPLEMENTATION,_CRT_SECURE_NO_DEPRECATE,U_ATTRIBUTE_DEPRECATED=;stubdata有宏STUBDATA_BUILD。嗯,我并没有整理出列表,如果你想知道,就自己查看项目配置吧

        v.             包含头文件请自行查看项目配置

        vi.             大部分的exe项目都有自定义生成步骤的,都是一样的,就是把输出文件复制到bin目录下,不过这个好像不是必要的

        vii.             allinone.sln在生成的时候会把发行时的头文件整理好,放到bin同级目录的include文件夹下,我并没有找到是谁干的这个活,所以我就把他生成的头文件全保留下来了,vc2008版的没有这个步骤,所以你得先把这个include文件夹准备好,否则编译失败

我移植完后新增的解决方案和项目文件,可能有的项目是不需要的,路径我都是按原来vc2010的项目的路径放的,免得因路径的问题而编译不成功(include下的文件省略掉了):

用msvc2008编译qt5.4.0_第1张图片

        ix.             请按照我allinone_vc2008中的依赖关系添加项目依赖项,否则就得编译好几次才能完全成功(即使你这样配置了依赖关系,可能还是得编译几次,呃。。。,其实我也没闹明白)

        x.             qt发行版中带的icu的库都是不带d的,说明他只用了icurelease版的库,那么你就只需要编译icu release就行了(我自己在编译qt的时候并没有注意这点,使得qt debug版的依赖debug版的icu,qt release版的依赖release版的icu)。编译完成后,你需要将icudt53.lib重命名为icudt.lib,将icuuc53.lib重命名为icuuc.lib,将icuin53.lib重命名为icuin.lib,因为qt要的就是这个名字的库,不信,你编译的时候看看。注意只改lib,不要动dll

        xi.             ok,icu的编译完成了

3. 接下来编译qt
    a) 请阅读http://doc.qt.io/qt-5/windows-building.html
    b) 我的环境脚本,假设为D:\set_qt_env.bat

  用msvc2008编译qt5.4.0_第2张图片
    c) 先开一个cmd,创建一个目录D:\qt_build,用于编译,cd到D:\qt_build,然后运行刚才那个设置环境的脚本,先配置一下,运行命令:D:\Qt\Qt5.4.0\5.4\Src\configure.bat  -prefix D:\qt5_4_0_msvc2008 -opengl desktop -nomake examples -nomake tests -opensource -icu -qml-debug -I E:\icu4c-release-53-1-source\include -L E:\icu4c-release-53-1-source\bin。你要把这其中的路径修改为你自己的
    d) 如果你想体验我编译时遇到的问题,那么建议你直接就开始编译:set PATH=%PATH%;D:\Qt\Qt5.4.0\Tools\QtCreator\bin,然后执行jom,经过若干小时,编译完成后,执行jom install,他会把发行版的文件和qtcreator需要的配置文件全部复制到prefix指定的目录
    e) 对不起,我忘了我在编译qt时遇到过哪些问题了,好像没什么严重的问题,因为编译时间太长,有空我再试一下,补下这块,就记得有一个文件D:\Qt\Qt5.4.0\5.4\Src\qtmultimedia\src\plugins\directshow\camera\dscamerasession.cpp我是改过的
用msvc2008编译qt5.4.0_第3张图片
4. 再然后编译qtwebkit
    a) 这个还是在刚才编译qt的环境里,你如果另开cmd,请重新执行jom以前的命令
    b) 执行命令SET PATH=%PATH%;D:\qt5_4_0_msvc2008\bin,因为要用编译出来的qt的工具
    c) 执行命令set SQLITE3SRCDIR=D:\Qt\Qt5.4.0\5.4\Src\qtbase\src\3rdparty\sqlite,设置sqlite3的源码路径
    d) perl D:\Qt\Qt5.4.0\5.4\Src\qtwebkit\Tools\Scripts\build-webkit --qt,开始编译,这个编译的时间比qt还长。后来查到还可以在后面加个参数--minimal,但是我没有试过。还是那句话,如果你想亲身体验我编译时遇到的问题,那就开始编译吧
    e) 下面说我遇到的问题和解决方法
        i. qtwebkit要求C99,不幸的是,vc2008是C89,所以在C库上的问题比较多,第一个就是没有头文件stdint.h。我把vc2010的这个文件复制到了vc2008的Microsoft Visual Studio 9.0\VC\include目录下,这个文件会引起WCHAR_MIN和WCHAR_MAX宏重定义,然而并不影响,你可以查看一下两处的定义其实是一样的,这个会出现100+次,如果你觉得烦,可以用#ifdef包裹下。编译完后记得把这个文件删掉哦
        ii. 问题:无法解析的外部符号 "public: static void __cdecl WebCore::TextCodecWin::registerExtendedCodecs,参看https://bugreports.qt.io/browse/QTBUG-43120,I was able to work around this by changing #if OS(WINDOWS) to #if OS(WINCE) in qtwebkit/Source/WebCore/platform/text/TextEncodingRegistry.cpp:301
        iii. 问题:unresolved external symbol class std::nullptr_t nullptr。nullptr这个是C++11才有的,而VC2008是不支持C++11的。仔细查看用到这个的源文件"D:\Qt\Qt5.4.0\5.4\Src\qtwebkit\Tools\WebKitTestRunner\TestController.cpp":517,D:\Qt\Qt5.4.0\5.4\Src\qtwebkit\Source\WTF\wtf/OwnPtr.h(81),发现其实跟这个类型没关系,只是把这个当做了特殊类型用来清空数据,那我就把他改成int了,int也是区别于OwnPtr的另外两个构造函数的:
用msvc2008编译qt5.4.0_第4张图片
..................这是图的分割线...................
用msvc2008编译qt5.4.0_第5张图片
    f) 然后cd /d D:\Qt\Qt5.4.0\5.4\Src\qtwebkit\WebKitBuild\Release,接着nmake install,这个会把发行时需要的库文件和头文件以及qtcreator需要的配置文件复制到prefix目录
    g) 然后就结束了,你编译完最后的发行版就在prefix配置的目录里
5. 接着配置qt creator
    a) 请自行google,反正就是选中prefix目录里的qmake,编译器选择2008 x86的
6. 如果你编译出来的也要供其他人用,那么你就把prefix那个目录复制给其他人,但是他们也得把它放到同样的prefix目录,就是说你在编译qt的时候已经固定了他的安装目录,所以不要配置什么F盘,H盘之类的,别人的机子上可不一定有哦
7. 最后附上我编译出来的包和icu的工程,我配置的prefix目录是D:\qt5_4_0_msvc2008,另外我编译debug版用的是debug版的icu,所以里面会有icu的debug版和release版,icudt53l.dat是我定制的,不过我定制的时候也是一头雾水,不知道该选哪些,就把所有en的、zh的、没有语言前缀的都选上了: http://pan.baidu.com/s/1qWqXuJq




更新(大概是一周之后):
我尝试着顺着这篇文档再来操作的时候,发现在编译qt的时候,他也编译了webkit,因为报错stdint.h没找到,而这个文件是在编译webkit的时候才需要的,于是我把vc2010的这个文件复制过去,然后再次jom,一路顺畅,并没有其他错误。其实查看上文在编译webkit时候出错的那个文件的路径就可以知道,那是测试项目的文件,而那个类又是个模板类,-nomake examples -nomake tests指明不编译例子程序和测试程序,那么就不会用到,所以就不编译nullptr_t参数类型的构造函数,然后就没有出错。
至于为什么我第一次编译qt的时候没有编译webkit,而需要另行编译,我就不知道了。

你可能感兴趣的:(qt)