首页 > 解决方案 > 如何在 Windows 下将 Qt5 构建为静态库

问题描述

要将 Qt 应用程序作为简单的 .exe 文件分发给 Windows 用户,需要静态链接 Qt 库的静态版本。假设我们在开放许可证下分发我们的许可证,以便允许 Qt 的静态链接。所以我们只需要 Qt5Core、Qt5Gui、Qt5Widgets 的静态库二进制文件。如何得到它们?

Qt5 的二进制发行版仅带有动态库。它还包含一些 .lib 文件 - 但请注意,这些不是静态库,而是一些辅助文件。它们可以通过大小与真正的静态库区分开来:真正的静态库要大得多(在 Qt5 组件的情况下很多 MB)。所以我们需要自己静态编译Qt5。事实证明这非常困难。

官方说明(http://doc.qt.io/qt-5/windows-building.html)几乎没有用:太短了,他们甚至没有传达任务难度的想法。目前缺少如何将 Qt5 编译为静态库的精确、最新、分步指南。我们应该在这里拥有它。

标签: windowsdeploymentconfigurationqt5static-libraries

解决方案


简短的回答:不要在这上面浪费你的时间。动态链接,并让安装程序分发您的应用程序。这是 Qt5 和 CMake 认真支持的唯一模式。在没有他们的支持和反对他们的建议的情况下工作几乎是绝望的。设置安装程序要容易得多(尽管也没有乐趣 - 我们目前使用来自https://hk.saowen.com/a/d1cf90fcfea6d511629fd5a6c8113808721a7f19656677e8a5fab370a8d35cd4的黑魔法)。

长长的(但不完整的)答案,以防你想比我聪明:

以下步骤使我看似接近解决方案。我成功地构建了静态库,但我无法链接我的应用程序:由于神秘的未解析外部符号导致数百个 LNK2001 和 LNK2019 错误,我不得不放弃。

因此,这里逐步描述了 2018 年 10 月在 Windows10 虚拟桌面上对我有用的方法。对于每个安装步骤,都会进行检查。如果检查失败,则在继续进行之前解决问题。

首先,安装一些稍后需要的工具:

  • Perl,需要 zlib 和 openssl 配置:
  • 一个可以处理 Unix 行尾的编辑器。记事本不行。安装vimemacs或其他任何东西。
  • 巧克力包管理器,需要安装 flex 和 bison:
    • 运行管理员外壳(圆形菜单>搜索“命令”>右键单击“命令提示符”>以管理员身份运行)
    • 从https://chocolatey.org/install#install-with-cmdexe复制下载命令
    • 将命令粘贴到 admin shell,并观看安装
    • 检查:在终端中,尝试命令“choco”
  • qtbase 编译需要的flexbison
    • 获得正确版本的 flex 并不明显。从 gnuwin32.sourceforge.net 我得到了一个过时的 flex,它错过了 Qt 编译期间所需的命令行参数。从源代码编译 flex 引入了进一步的依赖关系。我找到的最简单的解决方案是使用 Chocolatey 包管理器。
    • 在 admin shell 中,运行:“choco install winflexbison3”。这将创建一个目录X,其中包含二进制文件 win_flex.exe 和 win_bison.exe 以及一个支持的“数据”文件夹。找出X的位置。就我而言,X =C:\ProgramData\chocolatey\lib\winflexbison3\tools
    • 检查: cd X,然后运行“win_flex --version”、“win_bison --version”。
    • 在 Qt 编译期间,将需要这些工具的标准名称为“flex”和“bison”。因此我们需要符号链接 flex->win_flex、bison->win_bison。
      • mlink X \flex.exe X \win_flex.exe
      • mlink X \bison.exe X \win_bison.exe
      • 注意:mklink 需要绝对路径才能可靠地工作
      • 注意:符号链接不能转到另一个目录,以免野牛找不到“数据”文件夹
    • X添加到 %PATH%
    • 检查:在任何 shell 中,尝试“flex --version”和“bison --version”

到目前为止的工具。现在我们需要两个必须静态链接到 Qt 的库(从https://stackoverflow.com/a/41815812/1017348学到的魔法):

  • 构建静态zlib
    • 下载https://zlib.net/zlib1211.zip
    • 解压到 C:\Development\zlib-1.2.11
    • 使用可以处理 Unix EOL 的编辑器编辑文件 win32\Makefile.msc:
      • 查找以 CFLAGS 开头的行
        • 将 -MD 替换为 -GL -MT -Zc:wchar_t-
      • 查找以 LDFLAGS 开头的行
        • 将 -debug 替换为 -opt:icf -dynamicbase -nxcompat -ltcg /nodefaultlib:msvcrt
    • 使用以下命令构建 zlib(应该不到一分钟):
      • nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -DNDEBUG -I." OBJA="inffasx64.obj gvmat64.obj inffas8664.obj"
    • 检查:因此,源目录必须包含 zlib.lib (856kB) 等。
  • 构建静态openssl库:
    • 下载https://www.openssl.org/source/openssl-1.1.1.tar.gz
    • 解压到 C:\Development\openssl-1.1.1
    • 从 zlib 复制文件:cd zlib-1.2.11;xcopy zconf.h ..\openssl-1.1.1\ ; zlib.h zlib.lib zlib.pdb 相同
    • cd ..\openssl-1.1.1
    • perl 配置 VC-WIN64A no-asm no-shared zlib no-zlib-dynamic threads --prefix=C:\opt\local_x64
      • 注意:我添加了“no-asm”以避免安装 NASM(Netwide Assembler)
      • 注意:我更改了前缀,因为只有管理员可以安装到 C:\Windows
    • 编辑文件''makefile'':
      • 找到以 CFLAG 开头的行
        • 附加:/Zc:wchar_t- /GL /Zi
      • 找到开头的行:LDFLAGS
        • 将 /debug 替换为 /incremental:no /opt:icf /dynamicbase /nxcompat /ltcg /nodefaultlib:msvcrt
      • 找到以:CNF_EX_LIBS 开头的行
        • 用 zlib.lib 替换 ZLIB1
    • 构建:“nmake”
    • 检查:目录必须包含 openssl.lib(大小?)

现在我们准备好使用 Visual Studio C++ 编译器的命令行版本从源代码构建qtbase :

  • 下载(最新Qt的更新位置):https ://download.qt.io/archive/qt/5.11/5.11.2/submodules/qtbase-everywhere-src-5.11.2.zip
    • 拆包需要 20'
  • 将源目录移动到本地磁盘 (C:\Development)
    • 要使用 Visual Studio,请使用专门配置的终端。使用 Taskbar>Circle>Search 启动“x64 Native Tools Command Prompt for VS 2017”
  • cd qtbase...
  • 检查:配置 --help
  • 配置 -platform win32-msvc2017 -opensource -confirm-license -release -static -openssl-linked no-dbus -no-libpng -no-libjpeg -nomake 示例 -nomake 测试 -prefix C:\opt\local_x64 -IC:\Development \openssl-1.1.1\include -LC:\Development\openssl-1.1.1 -D OPENSSL_LIBS=C:\Development\openssl-1.1.1\libssl.lib
  • 制作
  • 检查:静态库(大 .lib 和小 .prl)位于目录 lib/
    • 54.7 MB Qt5Core.lib
    • 23.4 MB Qt5Widgets.lib
    • 18.2 MB Qt5Gui.lib
    • 07.4 MB Qt5Network.lib
    • ...

就是这样,我们有静态 Qt 库。只是,如上所述,当我尝试将我的应用程序与这些库链接时,这对我没有帮助。


推荐阅读