Qt备忘录之五:编译VS2010版Qt5静态链接库

Qt作为跨平台开发框架,由于提供了诸多功能全面的封装类,基本可以满足大部分开发人员需求。官方编译的QT库是动态链接形式的,因此产生一个明显的弊端,就是发布程序时必须将用到的QT库dll文件一并打包,导致文件包体积庞大。若客户电脑也装有QT库,而且版本不同时,还有可能产生冲突。

为了解决这个问题,使用静态链接的Qt库成为唯一选择。由于Qt官方没有提供静态编译好的lib库,需要自行编译。编译过程走了一些弯路,这边做一个记录,既是备忘,也方便有需要的朋友参考。

下载Qt源码(应当是一个名字形如qt-everywhere-opensource-src-x.x.x.zip的压缩包)后,要先进行一些配置之后,才能开始编译。下面以我使用的Qt5.5.0版本为例进行说明。

0. 经验总结

0.1 源代码不要解压到带有中文的路径下,否则可能在configure时导致“找不到xxx文件”错误。

0.2 解压路径名不要太长,否则后面nmake的时候会因为超出系统最大路径字符长度导致一些文件无法生成,造成最终编译失败。

0.3 编译过程需要用到python,在编译前需要先安装python。python安装之后,检查一下PATH环境变量中是否添加了python.exe的目录。如果没有添加,需要手动添加,否则在nmake的时候同样会报找不到python的错误。python3.5.1需要win7.1及以上版本的系统,python2.7.11需要XP以上版本的系统。实测,这两个版本的python都可以正常工作。

0.4 确认所用的nmake.exe和cl.exe所在的路径在系统的环境变量中已经正确定义。也可以直接运行vs安装路径\VC\vcvarsall.bat进行配置。如果电脑中安装有多个vs版本,建议只在环境变量中保留要使用的一个,删除其他的定义,以免后续系统调用错版本导致编译出错。如下图所示方法可以检查python和nmake是否已加入到环境变量中。

检查环境变量

0.5 bin目录qtbase\bin目录也要写进环境变量里

1. 修改配置文件

按照网络上的已有资料,需要修改名为qmake.conf的配置文件。根据需要使用的编译环境的不同,有不同的版本。例如我使用vs2010,则选择qt-everywhere-opensource-src-5.5.0\qtbase\mkspecs\win32-msvc2010文件夹中的文件,该文件内容如下:

[code lang="cpp" collapse="false"]
#
# qmake configuration for win32-msvc2010
#
# Written for Microsoft Visual C++ 2010
#

MSC_VER = 1600
MSVC_VER = 10.0
include(../common/msvc-desktop.conf)
load(qt_config)
[/code]

与网上针对其他版本所述的方法不同,这个conf文件中没有具体对编译条件进行配置,只是调用了另一个配置文件msvc-desktop.conf。该文件中能找到如下内容:

[code lang="cpp" collapse="false"]
#
# qmake configuration for Microsoft Visual Studio C/C++ Compiler
# This mkspec is used for all win32-msvcXXXX specs
#
……
QMAKE_CFLAGS_RELEASE = -O2 -MD
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MD -Zi
QMAKE_CFLAGS_DEBUG = -Zi -MDd
……

unset(MSC_VER)
[/code]

这边的MD和MDd和VS里面配置的意思相同,如果是需要编译静态lib,将这边的MD改为MT,MDd改为MTd。

2. configure

用管理员权限运行vs2010命令工具,转到上述的解压目录。之后便是最重要的Configure。

根据我自己的使用需求,需要用到部分图像处理,以及SQL的支持,因此使用如下的的配置参数。

[code lang="cpp" collapse="false"]
configure -mp -confirm-license -opensource -platform win32-msvc2010 -debug-and-release -static -prefix "E:\160331\Qt5StaticLib" -qt-sql-sqlite -qt-sql-odbc -plugin-sql-sqlite -plugin-sql-odbc -qt-zlib -qt-libpng -qt-libjpeg -opengl desktop -qt-freetype -no-qml-debug -no-angle -nomake tests -nomake examples -skip qtwebkit
[/code]

-mp:仅对msvc有意义,使编译器在单独的进程来创建自己的一个或多个副本,每个副本。然后,这些副本同时编译源文件。因此,能够显著减少构建的源文件的总时间。

-confirm-license:安装许可

-opensource:将编译开源版QT。这里如果不指定的话,运行configure的时候也会要求指定。

-platform:指定编译环境

-debug-and-release:编译debug和release库,也可以只编译debug或者release,默认是-debug

-static:编译静态链接库,如果为-shared就是编译动态链接库,默认是-shared

-prefix:指定编译后的install路径,路径可以是相对路径。如果输入相对路径的话,是以\qtbase\mkspecs为根目录的。

-qt-sql-xxx:SQL相关功能的开关

-plugin-sql-xxx:SQL相关功能作为插件形式编译的开关

第三方库:有下表所示的这些

Library Name Bundled in Qt Installed in System
zlib -qt-zlib -system-zlib
libjpeg -qt-libjpeg -system-libjpeg
libpng -qt-libpng -system-libpng
xcb -qt-xcb -system-xcb
xkbcommon -qt-xkbcommon -system-xkbcommon
freetype -qt-freetype -system-freetype
PCRE -qt-pcre -system-pcre
HarfBuzz-NG -qt-harfbuzz -system-harfbuzz

-opengl desktop:使用opengl的版本,有desktop和ES等几种可选

-no-xxx:不编译这些模块

-nomake:不编译这些示例等使用QT编写的程序。

更多关于configure的参数说明,可以参考Qt官方文档(http://doc.qt.io/qt-5.6/configure-options.htmlhttp://doc.qt.io/qt-4.8/configure-options.html),在此不再赘述。上述两个链接分别是Qt5和Qt4的,对于configure的参数的用法是继承的。

如果configure成功,会有如下提示:

运行configure工具成功

3. nmake和install

接下来就是nmake了。这边需要漫长的等待,大约2~3个小时,所以找点其他事情做。

如果编译过程发生错误,回头检查012中是否有遗漏的。多半编译出错是由于0里面所说的几种情况。再次编译前,最好用nmake distclean命令进行一下清理。

nmake成功之后,可以执行nmake install将编译出来的东西复制到你规定的目录中。

4. 在QTCreator中建立与静态QT环境关联的套件

启动QTCreator后,在“工具——选项”里找到“构建与运行”,如下图所示:

QTCreator添加QT版本

4.1 添加QT版本

在上图所示的界面中,通过“添加”找到编译出来的qmake.exe。如果没有问题,则会如下图所示生成一个“手动”的QT版本。

成功添加qt版本

4.2 配置QT套件

在“构建套件”标签页,新建一个套件,QT版本选择为刚刚手动生成的Qt5StaticLib,编译器和调试器按需配置。

配置QT套件

5. 在VS2010中添加QT版本

安装qt-vs-addin-1.2.4-opensource后,在vs2010中,可以在“Qt5——Qt Options”中,通过“Add”按钮添加QT版本,如下图所示:

VS2010选择Qt版本

添加版本成功后,如下图所示。在此可以选择Qt版本。

在VS2010内选择Qt默认版本

 

6. 迁移

本地运行一切正常。于是将编译出来的静态环境共享给工作室的其他小伙伴,然后就出问题了。如下图所示:

添加Qt版本时报错

更换路径后找不到文件

有的是添加Qt版本的时候报错,有的是报找不到moc.exe,有的报找不到库。不同的工程报出的错误不一样,性质都是一样的,就是找不到指定地址的文件。检查了一下报错信息,指向的都是我原来编译生成的路径。原因是生成特定版本qmake.exe时,其绝对路径直接写入在qmake.exe文件中的,使用二进制工具打开qmake.exe可以查到。依赖于此的所有运行程序和库,在没有声明的情况下,都是在qmake指定的路径下查找。解决方法如下:

在qmake.exe所在路径新建一个名为qt.conf的文件,在文件中添加如下内容:

[code lang="cpp" collapse="false"]
[paths]
Prefix = ../
[/code]

 

二零一六年四月七日

顾毅 写于厦门