马上,对于问题的长度感到抱歉,但这是由于我提供的所有附加详细信息,我希望这些详细信息可以帮助更快地解决问题
我想实现什么目标?
我需要创建一个具有 SSL 支持的便携式(一体化)应用程序。
问题是什么?
因此,我面临的核心问题是将 SSL 支持纳入我的二进制/便携式应用程序中。
A MCVE该应用程序的功能很简单:
Project .pro
file
QT -= gui
QT += network
CONFIG += c++11 console
CONFIG -= app_bundle
SOURCES += \
main.cpp
INSTALLS += target
Project 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
我在以下人员的帮助下做到了这一点这个脚本 https://pastebin.com/4mGtCVf9改编自ps1
powershell脚本 https://sourceforge.net/p/qtlmovie/code/ci/v1.2.16/tree/build/windows-build-qt-static.ps1?format=raw found 在 Qt 的 wiki 上 https://wiki.qt.io/Building_a_static_Qt_for_Windows_using_MinGW。我做了补充:
OpenSSL 主页$OPENSSL_HOME
线程数$threads
, and
架构类型$arch
要使用的。
Qt 编译详细信息和 OpenSSL 信息
配置如下:
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)"
Note 1:
我在用-openssl
并不是-openssl-linked
。我尝试过用这两种方法构建 Qt 的几种变体-openssl
and -openssl-linked
. -openssl-linked
永远无法成功构建,请参阅这个帖子 https://forum.qt.io/topic/107364/static-compile-qt-5-13-1-with-openssl-1-1-1d-using-mingw-in-windows-10我提出了原因。
Note 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
is:
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 种方法创建文件(库是静态编译的 MinGW OpenSSL 库,位于C:\OpenSSL-Win32\lib\MinGW
)
将库手动输入到 .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
Note 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
suffix)
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 库添加到项目文件中不起作用,或者我在某处做了错误的事情。
Note 4:为什么问题的标题不是:如何将静态库导入到Qt中?
导入静态库很简单,并不复杂。我假设我在启用 SSL 支持的 Qt 静态编译中犯了一个错误。
对于解决这个问题的建议将不胜感激。
Update 1
我已经解决了这个问题-openssl-linked
。原因(或者更确切地说是修复)是没有将 OpenSSL 安装到您的计算机上。相反,提取.a
& include
目录到一个单独的目录。所以一切都是一样的,除了你有lib
s & include
无需安装。
然后使用标准配置(上面提到的),替换-openssl
with -openssl-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
是必需的。