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