c++ - 未链接目标二进制文件的静态 OpenSSL *.a 库(使用带有 SSL 的静态编译 Qt)

标签 c++ qt ssl openssl

马上,对问题的长度感到抱歉,但这是由于我提供的所有其他细节,我希望可以帮助更快地解决问题

我想要达到什么目标?

我需要创建一个具有 SSL 支持的可移植(多合一)应用程序。

问题是什么?

所以我面临的核心问题是在我的二进制/可移植应用程序中包含 SSL 支持。

A MCVE 应用程序很简单:

项目.pro文件

QT -= gui
QT += network

CONFIG += c++11 console
CONFIG -= app_bundle

SOURCES += \
        main.cpp

INSTALLS += target

项目main.cpp
#include <QCoreApplication>
#include <QSslSocket>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    qDebug() << "Is SSL Enabled? " << QSslSocket::supportsSsl();
    qDebug() << "SSL Library Build Version (Qt compiled against): " << QSslSocket::sslLibraryBuildVersionString();
    qDebug() << "SSL Library Version String (available locally): " << QSslSocket::sslLibraryVersionString();

    return a.exec();
}

  • 我的 上的输出开发机 :
  •     Is SSL Enabled?  true
        SSL Library Build Version (Qt compiled against):  "OpenSSL 1.1.1d  10 Sep 2019"
        SSL Library Version String (available locally):  "OpenSSL 1.1.1d  10 Sep 2019"
    

    开发机信息
        C:\Users\cybex>echo %PATH%
        C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Strawberry\c\bin;C:\Strawberry\perl\site\bin;C:\Strawberry\perl\bin
    
    
        C:\Users\cybex>openssl
        WARNING: can't open config file: /z/extlib/_openssl_/ssl/openssl.cnf
        OpenSSL> version
        OpenSSL 1.0.2g  1 Mar 2016
    

  • 在新的 Windows 10 x86 机器上运行相同的二进制文件会导致:
  •     Is SSL Enabled?  false
        SSL Library Build Version (Qt compiled against):  "OpenSSL 1.1.1d  10 Sep 2019"
        SSL Library Version String (available locally):  ""
    

    试验机信息 (完全全新安装 - Windows 10 x86)
        C:\Users\cybex>echo %PATH%
        C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\
    
        C:\Users\cybex>openssl
        'openssl' is not recognized as an internal or external command,
        operable program or batch file.
    

  • 在新的 Windows 7 x64 机器上运行相同的二进制文件会导致:
  •     Is SSL Enabled?  false
        SSL Library Build Version (Qt compiled against):  "OpenSSL 1.1.1d  10 Sep 2019"
        SSL Library Version String (available locally):  ""
    

    试验机信息 (安装了驱动程序的 Windows 7 x64 笔记本电脑)
        C:\Users\Home>echo %PATH%
        C:\Program Files (x86)\OpenSSL\libs;C:\Program Files (x86)\Intel\iCLS Client\;C:\Program Files\Intel\iCLS Client\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x64;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x64;C:\Program Files (x86)\OpenSSL\libs;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\
    
        C:\Users\Home>openssl
        'openssl' is not recognized as an internal or external command, operable program or batch file.
    

    通过查看以上结果,我得出结论,安装 OpenSSL 可以解决问题。很好,但我需要将它包含在我的可移植应用程序中。

    在实现这一目标时,我需要
  • 使用 OpenSSL 支持静态编译 Qt

  • 我是在 this script 的帮助下完成的改编自 ps1 powershell script找到 here on Qt's wiki .我做了以下补充:
  • OpenSSL 主页 $OPENSSL_HOME
  • 线程数$threads , 和
  • 建筑类型 $arch要使用的。

  • Qt 编译细节和 OpenSSL 信息
  • 编译器:mingw32位于 C:\Qt\Qt5.13.1\Tools\mingw730_32\bin
  • mkspec:win32-g++ (如果这有什么区别的话)。
  • OpenSSL 版本(32 位):1.1.1d

  • 配置如下 :
    cmd /C "configure.bat -static -debug-and-release -platform win32-g++ -prefix $QtDir `
            -qt-zlib -qt-pcre -qt-libpng -qt-libjpeg -qt-freetype -opengl desktop -sql-sqlite -ssl -openssl -I $($OPENSSL_HOME)\include -L$($OPENSSL_HOME)\lib\MinGW`
            -opensource -confirm-license `
            -make libs -nomake tools -nomake examples -nomake tests -v"
    cmd /C "mingw32-make -k -j$($threads)"
    

    注 1:

    我正在使用 -openssl而不是 -openssl-linked .我已经尝试了几种构建 Qt 的变体 -openssl-openssl-linked . -openssl-linked永远无法成功构建,见 this post我说的原因。

    注 2:

    我唯一成功的静态 Qt 编译是使用 -ssl -openssl启用配置标志

    OpenSSL 安装 (仅在 DEV 机器上)位于
    `$OPENSSL_HOME = "C:\OpenSSL-Win32"` 
    

    我在哪里使用静态编译 MinGW用于 OpenSSL 的库,可在
    `$OPENSSL_HOME = "C:\OpenSSL-Win32\lib\MinGW",`
    
    C:\OpenSSL-Win32\lib\MinGW的文件内容是:
    Directory: C:\OpenSSL-Win32\lib\MinGW
    
    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    -a----       2019/09/11     18:11        3347286 libcrypto.a
    -a----       2019/09/11     18:10         109020 libcrypto.def
    -a----       2019/09/11     18:11         385126 libssl.a
    -a----       2019/09/11     18:10          14033 libssl.def
    
  • 将链接项目 .pro 添加到 OpenSSL 库

  • 我将 OpenSSL 库添加到 .pro文件使用 2 种方法(库是在 C:\OpenSSL-Win32\lib\MinGW 中找到的静态编译的 MinGW OpenSSL 库)

    将库手动输入到 .pro 文件中
    QT -= gui
    QT += network
    
    # OpenSSL static .a libraries
    INCLUDEPATH += "C:\OpenSSL-Win32\include"
    LIBS += -L"C:\OpenSSL-Win32\lib\MinGW\libssl.a"
    LIBS += -L"C:\OpenSSL-Win32\lib\MinGW\libcrypto.a"
    
    CONFIG += c++11 console
    CONFIG -= app_bundle
    
    SOURCES += \
            main.cpp
    
    INSTALLS += target
    

    注释 3

    带有和不带有上述链接库的二进制大小保持不变

    上面添加了库的二进制文件(在我的开发机器上)的 LDD 输出是:
    Start-Process -PassThru .\SSL-Test.exe | Get-Process -Module
    
       Size(K) ModuleName                                         FileName
       ------- ----------                                         --------
          6280 SSL-Test.exe                                       C:\Users\cybex\QtProjects\build-SSL-Test-Desktop_Qt_Op...
          1512 ntdll.dll                                          C:\Windows\SYSTEM32\ntdll.dll
           596 KERNEL32.DLL                                       C:\Windows\system32\KERNEL32.DLL
          1500 KERNELBASE.dll                                     C:\Windows\system32\KERNELBASE.dll
    

    上面添加了库的二进制文件(在我的 Windows 10 x86 测试机器上)的 LDD 输出是:
    Start-Process -PassThru .\SSL-Test.exe | Get-Process -Module
    
       Size(K) ModuleName                                         FileName
       ------- ----------                                         --------
          6280 SSL-Test.exe                                       C:\Users\cybex\Desktop\SSL-Test.exe
          1512 ntdll.dll                                          C:\Windows\SYSTEM32\ntdll.dll
           596 KERNEL32.DLL                                       C:\Windows\system32\KERNEL32.DLL
          1500 KERNELBASE.dll                                     C:\Windows\system32\KERNELBASE.dll
    

    Qt库导入.pro文件

    导入使用( External Library > 导入 .a 文件> StaticWindows 仅带有 no debug 后缀的选项)
    QT -= gui
    QT += network
    
    CONFIG += c++11 console
    CONFIG -= app_bundle
    
    SOURCES += \
            main.cpp
    
    INSTALLS += target
    
    win32: LIBS += -L$$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW/ -lssl
    
    INCLUDEPATH += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW
    DEPENDPATH += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW
    
    win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW/ssl.lib
    else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW/libssl.a
    
    win32: LIBS += -L$$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW/ -lcrypto
    
    INCLUDEPATH += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW
    DEPENDPATH += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW
    
    win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW/crypto.lib
    else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW/libcrypto.a
    

    使用自动二进制导入,上面添加了库的二进制文件(在我的开发机器上)的 LDD 输出是:
    Start-Process -PassThru .\SSL-Test.exe | Get-Process -Module
    
       Size(K) ModuleName                                         FileName
       ------- ----------                                         --------
          6280 SSL-Test.exe                                       C:\Users\cybex\QtProjects\build-SSL-Test-Desktop_Qt_Op...
          1512 ntdll.dll                                          C:\Windows\SYSTEM32\ntdll.dll
           596 KERNEL32.DLL                                       C:\Windows\system32\KERNEL32.DLL
          1500 KERNELBASE.dll                                     C:\Windows\system32\KERNELBASE.dll
    

    并使用自动库导入,上面添加了库的二进制文件(在我的 Windows 10 x86 测试机上)的 LDD 输出是:
    Start-Process -PassThru .\SSL-Test.exe | Get-Process -Module
    
       Size(K) ModuleName                                         FileName
       ------- ----------                                         --------
          6280 SSL-Test.exe                                       C:\Users\cybex\Desktop\SSL-Test.exe
          1512 ntdll.dll                                          C:\Windows\SYSTEM32\ntdll.dll
           596 KERNEL32.DLL                                       C:\Windows\system32\KERNEL32.DLL
          1500 KERNELBASE.dll                                     C:\Windows\system32\KERNELBASE.dll
    

    开发机器的应用程序输出是 SSL enabled正如我之前在帖子中提到的(对于手动和自动库条目):
    Is SSL Enabled?  true
    SSL Library Build Version (Qt compiled against):  "OpenSSL 1.1.1d  10 Sep 2019"
    SSL Library Version String (available locally):  "OpenSSL 1.1.1d  10 Sep 2019"
    

    测试机器(未安装 OpenSSL)的应用程序输出也与以前相同(手动和自动库输入):
    Is SSL Enabled?  false
    SSL Library Build Version (Qt compiled against):  "OpenSSL 1.1.1d  10 Sep 2019"
    SSL Library Version String (available locally):  ""
    

    因此,如果 OpenSSL 库不存在,则在非开发(新/客户端)机器上请求 SSL 连接时会导致以下错误:

    QSslSocket::connectToHostEncrypted: TLS initialization failed



    这是 OpenSSL 库没有作为依赖项包含在二进制文件中的结果。所以基本上,向项目文件添加静态 OpenSSL 库不起作用,或者我在某处做错了一些事情。

    注释 4:
    为什么问题的标题不是:如何将静态库导入 Qt?

    导入静态库很简单,并不复杂。我假设我在启用 SSL 支持的 Qt 静态编译中的某个地方犯了一个错误。

    将不胜感激有关解决此问题的建议。

    更新 1

    我已经用 -openssl-linked 解决了这个问题.原因(或者更确切地说是修复)是没有将 OpenSSL 安装到您的机器上。相反,提取 .a & include目录到一个单独的目录。所以一切都一样,除了你有 lib s & include无需安装。

    然后使用标准配置(上面提到的),替换-openssl-openssl-linked你应该有一个成功的编译。

    更新问题

    使用新的 Linked OpenSSL Qt 套件构建和运行我的应用程序时,我收到一条消息:

    The code execution cannot proceed because libcrypto.dll was not found. Reinstalling the program may fix this problem.



    接着是另一个对话框

    The code execution cannot proceed because libssl.dll was not found. Reinstalling the program may fix this problem



    LDD要求:
    Start-Process -PassThru .\MyAwesomeApp.exe | Get-Process -Module
    
       Size(K) ModuleName                                         FileName
       ------- ----------                                         --------
         22708 MyAwesomeApp.exe                                     C:\Users\CybeX\QtProjects\build-MyAwesomeApp-Desktop_Qt_OpenSSL_Linked_5_13_1_MinGW_32bit-Release\release\MyAwesomeApp.exe
          1924 ntdll.dll                                          C:\WINDOWS\SYSTEM32\ntdll.dll
           328 wow64.dll                                          C:\WINDOWS\System32\wow64.dll
           480 wow64win.dll                                       C:\WINDOWS\System32\wow64win.dll
            40 wow64cpu.dll                                       C:\WINDOWS\System32\wow64cpu.dll
    

    使用和不使用 .pro 对此进行了测试 LIBS & INCLUDEPATH .两者都导致丢失 dll是必需的。

    最佳答案

    -openssl配置选项将 Qt 配置为使用 LoadLibrary 动态加载 libopenssl或其他平台等效功能。所以从现在开始,你所有的努力都是徒劳的。您需要返回并解决 -openssl-linked 问题。

    关于c++ - 未链接目标二进制文件的静态 OpenSSL *.a 库(使用带有 SSL 的静态编译 Qt),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58411359/

    相关文章:

    c++ - Ubuntu下没有libmongoclient.a

    c++ - 如何提取 ZIP 存档

    c++ - Qt图表错误: ASSERT: "width > 0.0" in file painting\qrasterizer. cpp,第761行

    c++ - 为除 qmake 中的一个文件之外的所有文件设置 "treat warnings as errors"

    php - PHP cURL 和 SSL 的奇怪超时

    c# - C++ 函数到 C#

    c++ - 在类中初始化固定大小的常量数组

    c++ - QPixmap 不抓取 Web 浏览器窗口

    amazon-web-services - 如何为 Coreos kubernetes aws 集群创建工作证书

    google-app-engine - App Engine + HTTPS + PageSpeed = 403 禁止错误