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

标签 c++ qt ssl openssl mingw

如何在 Windows 上使用 OpenSSL 支持静态编译 Qt(使用 MinGW 编译器)
此 Qt 构建的期望“结果”是构建和发布具有内置 SSL 支持的可移植 Qt 应用程序。

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

  • QT https SSL support for static QT static program build - getting 'Protocol “https” is unknown'
  • about compiling openssl inside qt application
  • Build Qt static from source enabling OpenSSL support
  • Compile static version of QT + OpenSSL Support
  • how to compile qt static with open ssl
  • Compiling static for Windows with OpenSSL

  • 还有很多

    和我自己的一些问题(使用 OpenSSL v1.1.1d & Qt 5.13 with MinGW ):
  • Statically compiled Qt 5.13.1 with OpenSSL 1.1.1d producing QSslSocket::connectToHostEncrypted: TLS initialization failed
  • Create a standalone binary using Qt with OpenSSL support
  • Static OpenSSL *.a libraries not linked target binary (using Statically Compiled Qt with SSL)
  • Static compile Qt 5.13.1 with -openssl-linked using MinGW (Windows 10)

  • 这些问题中的大多数都没有答案,并且提供的这些答案(显然)对编译没有帮助,因为一些错误输出或只是 OpenSSL 从未链接(内置于可移植/二进制应用程序中),或许多其他错误。

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

    请注意:

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

    Qt 说什么?

    Qt 以以下 2 篇文章的形式提供了一些帮助:
  • Building a static Qt for Windows using MinGW 带有 Powershell 脚本,该脚本使用 MinGW 静态编译 Qt,但将 OpenSSL 库 -l 和/或 -L 的各种组合(和排列)添加到各种路径( .lib )、( .a )、头文件等根本没有工作
  • Compiling OpenSSL with MinGW

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

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

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

    最佳答案

    我最近才注意到这个问题,所以我还没有时间从头开始编写完整的分步说明,但是我能够在我的环境中进行 qt-5.15.0 的静态构建基于 MSYS2 shell 和 MinGW-w64 以及来自 http://winlibs.com/ 的 GCC 10 个人构建已经在同一环境中编译了所有先决条件。
    openssl 的版本是 1.1.1g,像这样构建的(静态库和共享库):

    # 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 静态构建的步骤:
    # 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.h\2\n\1lmshare.h\2\n\1lmapibuf.h\2/" 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,它运行良好。

    关于c++ - 如何使用 MinGW 编译器和 SSL 支持静态编译 Qt,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62180840/

    相关文章:

    c++ - VS2012 错误 C1107

    c++ - Qt Widget 类的父级始终为 NULL

    c++ - 在使用 Qt Creator 创建一个非常简单的项目时卡在 Qt 中的 "segmentation fault"

    Python - 套接字错误,地址正在使用

    cordova - phonegap inapp 浏览器证书超链接打不开

    c# - 如何以编程方式查找用于签署给定证书的证书?

    c++ - 使用最大日期时的 COleDateTime 行为

    c++ - 我们应该在 lambda 中通过 const 引用捕获吗?

    c++ - 想要类型上的 constexpr 开关盒

    c++ - 在 Mac 上部署 Qt 应用程序 : This application failed to start because it could not find or load the Qt platform plugin "cocoa" in ""