【发布时间】:2020-02-13 02:52:19
【问题描述】:
马上开始,对于问题的长度感到抱歉,但这是由于我提供的所有其他详细信息,我希望可以帮助更快地解决问题
我想达到什么目的?
我需要创建一个支持 SSL 的可移植(一体化)应用程序。
有什么问题?
所以我面临的核心问题是将 SSL 支持包含在我的二进制/便携式应用程序中。
应用的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();
}
在我的 DEV 机器上输出:
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\binmkspec:
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。我尝试了几种使用-openssl 和-openssl-linked 构建Qt 的变体。 -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 库
我使用 2 种方法将 OpenSSL 库添加到 .pro 文件(库是在 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 文件> Static & Windows 仅带有 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 初始化失败
这是 OpenSSL 库未作为依赖项包含在二进制文件中的结果。所以基本上,在项目文件中添加一个静态 OpenSSL 库是行不通的,或者我在某处做错了。
注 4: 为什么问题的标题不是:How to Import a static library into Qt?
导入静态库很简单,并不复杂。我假设我在启用 SSL 支持的 Qt 静态编译中犯了一个错误。
我们将不胜感激有关解决此问题的建议。
更新 1
我已经解决了-openssl-linked 的问题。原因(或者更确切地说是修复)是没有将 OpenSSL 安装到您的机器上。相反,将.a 和include 目录提取到单独的目录中。所以一切都是一样的,除了你没有安装libs & include。
然后使用标准配置(上面提到),将-openssl替换为-openssl-linked,你应该可以成功编译。
更新问题
在使用新的Linked OpenSSL Qt 工具包构建和运行我的应用程序时,我收到一条消息:
代码执行无法继续,因为找不到 libcrypto.dll。重新安装程序可能会解决此问题。
随后是另一个对话框
无法继续执行代码,因为找不到 libssl.dll。重新安装程序可能会解决此问题
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 的必需项。
【问题讨论】:
-
您是否尝试过将 .pro 文件
win32: LIBS += -L... -lssl更改为以-l:libssl.a结尾 gcc 将尝试尽可能链接到共享库,因此如果该目录中存在共享库,则链接器将使用自动动态库。 -
@TinfoilPancakes 也会尝试,但会先试一试n.m.的答案