利用VC-LTL编译QT5

更新:新版VC-LTL已经可以更简单的实现了,下面的文章仅供纪念~~!不要浪费时间阅读了!不要浪费时间阅读了!

如果你从搜索引擎找到这里,说明你已经知道VC-LTL是什么了。请直接跳到第二节看脚本。

用VC动态编译以后的软件都需要带VC运行时库。如果客户机器上没装这个运行时库就会跳出错误框说“应用程序配置不正确,程序未能启动”云云。更烦人的是每种VC版本的运行时库还不一样,网上搜vcredist能列出从VS2003到VS2017的一堆版本,而且还在不断增加中…

所以很多人编译软件时都喜欢用静态编译,不过静态编译生成的文件比较大。一直以来我们都只能忍受编译出的软件个头大这个事实,直到我找到了VC-LTL。

VC-LTL介绍

使用VC-LTL后可以将程序动态链接到系统自带的msvcrt.dll中,来减少程序体积。就是说加入VC-LTL后编译时还是用-MD参数动态编译,生成的软件和原来的动态编译差不多大,却神奇的不需要带运行时库了。

编译QT5

默认的QT5编译是动态编译的,网上可以看到一些方法是修改配置文件,把原-MD替换成-MT实现静态编译。本文提供了一个加入VC-LTL库编译QT5的方法,相比较静态编译来说,大大减小了体积,而且部署时也不用带运行时库。

脚本

直接上脚本,下面是qt-build.bat文件内容。细心的读者会注意到只编译了release版本,这是因为VC-LTL只支持release编译。debug版不是用来发布的,带不带运行时库不重要对吧^_^

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@echo OFF
REM QT源码路径
SET _QT_ROOT=C:\qt\qt-everywhere-src-5.10.1
REM VC-LTL路径
SET _LTL_ROOT=C:\VC-LTL
REM 编译结果存放路径
SET _PREFIX=C:\QtLtL
REM 取得VS版本

if "_%VCToolsVersion%_" == "__" (
echo 请从VC环境里执行脚本
exit /b 1
)

REM 生成 makefile
SET _ARCH=%Platform%
IF "_%_ARCH%_" == "__" SET _ARCH=%VSCMD_ARG_TGT_ARCH%
IF "_%_ARCH%_" == "__" (
ECHO 无法确定编译平台,假定为x86
SET _ARCH=x86
)
SET _PREFIX=%_PREFIX%\%_ARCH%

%_QT_ROOT%/configure.bat -confirm-license -opensource -platform win32-msvc -release -nomake tests -mp -ltcg ^
-prefix %_PREFIX% ^
-I "%_LTL_ROOT%\VC\%VCToolsVersion%\include" -I "%_LTL_ROOT%\ucrt\%UCRTVersion%" ^
-L "%_LTL_ROOT%\%_ARCH%" -L "%_LTL_ROOT%\VC\%VCToolsVersion%\lib\%_ARCH%" -L "%_LTL_ROOT%\ucrt\%UCRTVersion%\lib\%_ARCH%"

编译步骤

  1. 下载QT5源代码,我下载的是5.10.1版:https://download.qt.io/archive/qt/5.10/5.10.1/single/,解压
  2. 安装perl, ruby, python
  3. 下载VC-LTL,解压
  4. 按上文内容写一个qt-build.bat文件,修改里面的_QT_ROOT_LTL_ROOT_PREFIX,指定源码位置、VC-LTL位置和编译结果存放位置
  5. 修改QT源码内的qtbase\mkspecs\common\msvc-desktop.conf
    1. 找到DEFINES项,行尾加入_Build_By_LTL _NO_CRT_STDIO_INLINE=1 _STATIC_CPPLIB _DISABLE_DEPRECATE_STATIC_CPPLIB定义
    2. 找到QMAKE_LFLAGS_RELEASE,行尾加入msvcrt_advanced.obj ltl.lib vc.lib ucrt.lib
    3. 修改后的内容见文末下载
  6. 从VC命令行工具进入,在一个空路径里执行qt-build.bat。当前路径就是存放编译中间文件的路径了。
  7. 五分钟左右配置完成,输入下面的指令开始编译QT5。编译时间很长,建议下载jom程序来加速编译。下载后把下列nmake换成jom即可。
    1. nmake
    2. nmake install
    3. nmake docs
    4. nmake install_docs

已知问题

  • 有时编译的中间文件不在当前目录下,而是在用户主目录下的source里生成,原因未知。如果脚本执行后当前目录没有生成qtbase等目录,CTRL+C停止,再重新执行。
  • 编译过程有时会出错,可能和杀毒软件有关。重新执行本脚本就可以。

小坑

  • 编译完的QT移个位置就不能运行了,可以在bin目录里加一个qt.conf文件,指定新的路径。
    1
    2
    [Paths]
    Prefix = ..
  • 自己编写的程序可以用windeployqt.exe来确定要带哪些DLL文件,还要带上plugins里的platforms文件夹和styles文件夹
  • 用这个脚本生成的QT库只能用来编译带VC-LTL的Release版,在pro文件里要加上VC-LTL头文件位置(不知道为什么qmake不会记住这个选项):
    1
    2
    3
    4
    DEFINES += QT_DEPRECATED_WARNINGS \
    _DISABLE_DEPRECATE_LTL_MESSAGE
    INCLUDEPATH += C:\\VC-LTL\\VC\\14.12.25827\\include \
    C:\\VC-LTL\\ucrt\\10.0.16299.0

    下载

  • qt-build.bat
  • msvc-desktop.conf