如何使用 MinGW 编译器和 SSL 支持静态编译 Qt

2022-01-07 00:00:00 qt ssl openssl mingw c++

如何在 Windows 上使用 OpenSSL 支持静态编译 Qt(使用 MinGW 编译器)此 Qt 构建的预期结果"是构建和发布具有内置 SSL 支持的便携式 Qt 应用程序.

How to statically compile Qt with OpenSSL support on Windows (with MinGW compiler) The desired 'outcome' of this Qt build is to build and ship a portable Qt application with built-in SSL support.

所以这是一个古老的问题,有很多关于这个主题的问题,但很少有解决方案可以解决这个问题.其中一些问题(和问题):

So this is an age old problem with a multitude of questions on this topic, yet very few solutions exist that solves the problem. Some of these questions (and problems):

  • QT https SSL支持静态 QT 静态程序构建 - 获取协议https"未知"
  • 关于在qt应用程序内编译openssl
  • 从源代码构建 Qt 静态启用 OpenSSL 支持
  • 编译静态版本的 QT + OpenSSL支持
  • 如何编译qt静态使用开放 ssl
  • 使用 OpenSSL 为 Windows 编译静态

还有更多

以及我自己的一些问题(使用 OpenSSL v1.1.1d & Qt 5.13 和 MinGW):

and some of my own questions (using OpenSSL v1.1.1d & Qt 5.13 with MinGW ):

  • 静态编译的 Qt5.13.1 使用 OpenSSL 1.1.1d 生成 QSslSocket::connectToHostEncrypted:TLS 初始化失败
  • 使用支持 OpenSSL 的 Qt 创建独立二进制文件
  • 静态 OpenSSL *.a 库不是链接目标二进制文件(使用带有 SSL 的静态编译 Qt)
  • 静态编译 Qt5.13.1 with -openssl-linked using MinGW (Windows 10)

这些问题中的大多数都没有答案,并且提供的这些答案(显然)对编译没有帮助,原因是一些错误输出或根本没有链接 OpenSSL(内置在便携式/二进制应用程序中),或许多其他错误.

Most of these questions do not have answers, and those answers provided (obviously) did not help in compiling, due to some error output or simply OpenSSL was never linked (built into the portable/binary application), or many other errors.

此外,关于使用 -ssl-openssl-linked-openssl 以及它们的含义似乎存在很多混淆.此外,如果应该使用 -L/path/to/libs/static -l library1 -l library2 与使用 OPENSSL_HOME 环境变量并指定头文件的路径静态/链接库等

Further, there appears to be alot of confusion about using -ssl, -openssl-linked, -openssl and what each means. Also, if one should use -L/path/to/libs/static -l library1 -l library2 vs using the OPENSSL_HOME env variable and specify the path to headers & static / linked libraries, etc

请注意:

理想情况下,在编译时,需要特定的库指令,例如 OpenSSL v1.0.2OpenSSL v1.1qmake除了在构建过程中应考虑的事项外,使用这些特定库构建静态 Qt 的参数.

Ideally, in compiling, specific instructions for libraries would be required such as OpenSSL v1.0.2 or OpenSSL v1.1 and the qmake arguments in building a static Qt with those specific libraries in addition to things that should be considered during the build process.

Qt 怎么说?

Qt 以以下 2 个帖子的形式提供了一些帮助:

Qt has provide some help in the form of these 2 posts:

  • 使用 MinGW 为 Windows 构建静态 Qt 使用 Powershell 脚本,该脚本使用 MinGW 静态编译 Qt,但将 OpenSSL 库 -l 和/或 -L 的各种组合(和排列)添加到各种路径 (.lib)、(.a)、头文件等根本不起作用
  • 使用 MinGW 编译 OpenSSL
  • Building a static Qt for Windows using MinGW with a Powershell script which does compile Qt statically using MinGW, but adding the various combinations (and permutations) of OpenSSL libraries -l and/or -L to the various paths (.lib), (.a), header files, etc simply did not work
  • Compiling OpenSSL with MinGW

这个问题的目的是给出一个详细的解释和逐步的方法,让那些需要编译带有SSL的静态Qt版本的人得到一些支持和指导.

这是一个不自然的问题",但是在每个特定问题中看到了如此多的问题而没有/很少有针对精选案例的解决方案,因此很难获得通用解决方案.

This is an unnatural "question", but having seen so many questions with no/very few solutions for cherrypicked cases in each specific question makes a general solution very difficult to obtain.

我发布这个问题是希望提供一个可以使所有人受益的通用解决方案.

推荐答案

我最近才注意到这个问题,所以我还没有时间从头开始写完整的分步说明,但我是能够在我的环境中进行 qt-5.15.0 的静态构建,它基于 MSYS2 shell 和 MinGW-w64 以及来自 http://winlibs.com/,所有先决条件都已在同一环境中编译.

I just noticed this question just recently, so I haven't had time yet to write complete step-by-step instructions from the ground up, but I was able to do a static build of qt-5.15.0 in my environment which is based on MSYS2 shell together with MinGW-w64 with GCC 10 personal build from http://winlibs.com/ with all the prerequisites already compiled in the same environment.

openssl 的版本是 1.1.1g 是这样构建的(静态和共享库):

The version of openssl was 1.1.1g built like this (static and shared libraries):

# location of Perl
PERLDIR=/d/Prog/Perl/strawberry-perl-5.30.0.1-64bit-portable/perl
# install destination
INSTALLPREFIX=/d/Prog/winlibs64-10.1.0/custombuilt
# for 32-bit replace mingw64 with mingw in the next line
./Configure --prefix=$INSTALLPREFIX threads shared zlib-dynamic -DOPENSSL_NO_CAPIENG mingw64 &&
make &&
PATH=$PERLDIR/bin:$PATH make -j1 install OPENSSLDIR_dir=$INSTALLPREFIX &&
strip $INSTALLPREFIX/bin/*.exe $INSTALLPREFIX/bin/*.dll &&
cp -f $INSTALLPREFIX/lib/libcrypto.a $INSTALLPREFIX/lib/libeay32.a && 
cp -f $INSTALLPREFIX/lib/libcrypto.dll.a $INSTALLPREFIX/lib/libeay32.dll.a && 
cp -f $INSTALLPREFIX/lib/libssl.a $INSTALLPREFIX/lib/libssleay32.a && 
cp -f $INSTALLPREFIX/lib/libssl.dll.a $INSTALLPREFIX/lib/libssleay32.dll.a && 
cp -f ms/applink.c $INSTALLPREFIX/include/openssl/ && 
echo Success

以下是我执行 qt-5.15.0 静态构建的步骤:

Here are the steps I did to do the static build of qt-5.15.0:

# location of Python
PY2DIR=/d/Prog/Python/WinPython-64bit-2.7.13.1Zero/python-2.7.13.amd64
# location of all the prerequisites
MINGWPREFIX=/d/Prog/winlibs64-10.1.0/custombuilt
# install destination
INSTALLPREFIX=/d/Prog/winlibs64-10.1.0/custombuilt
# fix missing SHARE_INFO_1 in qtbase/src/corelib/io/qfilesystemengine_win.cpp 
echo "#include <levmar.h>" | gcc -E -xc - &> /dev/null && sed -i.bak -e "s/(#s*include <)lm.h(>)/1levmar.h2
1lmshare.h2
1lmapibuf.h2/" qtbase/src/corelib/io/qfilesystemengine_win.cpp
# avoid using missing debug ICU libraries in static builds
sed -i.bak -e "s/(lsicu..)d/1/g" qtbase/src/corelib/configure.json
# configure
mkdir -p build_static &&
cd build_static &&
PATH=$PATH:$PY2DIR ../configure -platform win32-g++ -prefix $INSTALLPREFIX/qt -opensource -confirm-license -release -static -no-pch -no-rpath -strip -skip "qtserialbus" -qpa windows -gif -sql-odbc -sql-sqlite -opengl desktop -icu -system-pcre -dbus -system-sqlite -system-zlib -system-libpng -system-libjpeg -system-doubleconversion -system-freetype -system-harfbuzz -libproxy -system-proxies -openssl -openssl-linked -no-xcb -no-compile-examples -skip qtwebengine -nomake examples -system-proxies -plugin-manifests -pkg-config -I $MINGWPREFIX/include/freetype2 -I $MINGWPREFIX/include/mariadb &&
sed -i.bak -e "s/(-lclang).a/1 -lpthread/" qttools/src/qdoc/Makefile.* &&
cd .. &&
# build
(
 PATH=$PATH:$PY2DIR mingw32-make -Cbuild_static release QMAKE_CXXFLAGS="-fcommon" QMAKE_LFLAGS="-Wl,-allow-multiple-definition" || (
  make -Cbuild_static/qttools/src/qdoc &&
  PATH=$PATH:$PY2DIR mingw32-make -Cbuild_static release QMAKE_CXXFLAGS="-fcommon" QMAKE_LFLAGS="-Wl,-allow-multiple-definition"
)) &&
# workaround for missing qmake.exe
cp build_static/qtbase/bin/qmake.exe build_static/qtbase/qmake/ &&
make -Cbuild_static install &&
# manually create qt.conf
echo "[Paths]" > $INSTALLPREFIX/qt/bin/qt.conf &&
echo "Prefix=../../qt" >> $INSTALLPREFIX/qt/bin/qt.conf &&
echo Success

我通过构建 KeePassXC (https://github.com/keepassxreboot/keepassxc/archive/2.5.4.tar.gz)反对它,结果包根本没有Qt DLL,它运行良好.

I have tested the result by building KeePassXC (https://github.com/keepassxreboot/keepassxc/archive/2.5.4.tar.gz) against it and the resulting package had no Qt DLLs at all and it ran fine.

相关文章