马上开始,对问题的长度感到抱歉,但这是由于我提供的所有其他详细信息,希望可以帮助您更快地解决问题
我要实现什么目标?
我需要创建一个具有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();
}
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
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.
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可解决此问题。很好,但是我想将其包含在便携式应用程序中。
要实现这一目标,我必须
我是在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
。我尝试使用-openssl
和-openssl-linked
构建Qt的几种变体。 -openssl-linked
永远无法成功构建,请参阅this post我对原因的解释。
注释2:
我唯一成功完成的静态Qt编译是启用了-ssl -openssl
配置标志
OpenSSL安装(仅在DEV计算机上)位于
`$OPENSSL_HOME = "C:\OpenSSL-Win32"`
我在其中使用
中的OpenSSL静态编译的MinGW
库
`$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
我使用2种方法将OpenSSL库添加到.pro
文件中(库是在C:\OpenSSL-Win32\lib\MinGW
找到的静态编译的MinGW OpenSSL库)
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
使用(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库,则在Non-Dev(新鲜/客户端)计算机上请求SSL连接时,它将导致以下错误:
QSslSocket :: connectToHostEncrypted:TLS初始化失败
这是OpenSSL库没有作为依赖项包含在二进制文件中的结果。因此,基本上,将静态OpenSSL库添加到项目文件中是行不通的,否则我在某处做某事是不正确的。
注释4: 为什么标题不是这样的问题:如何将静态库导入Qt?
导入静态库很简单,也并不复杂。我假设在启用了SSL支持的Qt静态编译中某个地方犯了一个错误。
解决此问题的建议将不胜感激。
我已经解决了-openssl-linked
的问题。原因(或更确切地说,是修复)是未将OpenSSL安装到您的计算机上。而是将.a
和include
伪指令提取到单独的目录中。因此,除了没有安装的lib
和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
的要求。
答案 0 :(得分:3)
-openssl
配置选项将Qt配置为使用LoadLibrary
或其他等效的平台功能动态加载libopenssl 。因此,从这一点出发,您的所有努力都是徒劳的。您需要返回并解决-openssl链接的问题。
答案 1 :(得分:0)
如果您正确构建了Qt,并以静态方式链接到ssl,则无需 不再需要将ssl明确链接到应用程序,只需链接 Qt。
gcc的正确格式为-Lrelative-or-absolute/path
(我正在使用* nix路径),-L
用于指定
库所在的路径和-lxyz
的xyz所在的路径
要链接的库的名称ssl
(不带前缀lib
,并且不带
后缀.a
)
但是最终,.a
文件是.o
文件的集合,可以是
在链接阶段添加如下:gcc -o target file.o libssl.a
(因此有时在某些情况下LIBS += /path/libssl.a
可以正常工作)
根据Qt documentation,无需卸载
系统ssl,只需将OPENSSL_LIBS
环境变量传递(导出)到
Qt配置脚本(OPENSSL_LIBS='-L/opt/ssl/lib -lssl -lcrypto'
)
如果同时存在两个文件(.a
,.dll
),则gcc仍可以选择
动态版本,请确保您链接了静态版本
删除.dll
文件。
关于支持ssl的事实,Qt文档尚不清楚(IMHO) 静态链接,我认为是这样,但是应该检查
默认情况下,启用SSL的Qt库动态加载任何 在运行时安装了OpenSSL库。但是,有可能 通过使用以下命令配置Qt,在编译时链接到库 -openssl链接的选项。
我应该为我做构建,我将启用详细输出,并在日志中验证它实际上是静态链接的,我将验证它是否来自正确的目录以及最终的目标Qt包含ssl符号。
答案 2 :(得分:0)
我使用VS2019作为本机win32编译器,而不是mingw:
将openSSL作为静态lib
“ C:\ Program Files(x86)\ Microsoft Visual Studio \ 2019 \ Community \ VC \ Auxiliary \ Build \ vcvars64.bat”
SET CL = / MP
perl配置VC-WIN64A不共享--prefix = C:\ Build-OpenSSL-VC-64-STATIC
nmake
nmake安装
使用静态SSL构建Qt:
.. \ configure -静态-IC:\ Build-OpenSSL-VC-64-STATIC \ include -LC:\ Build-OpenSSL-VC-64-STATIC \ lib OPENSSL_LIBS =“-llibcrypto -llibssl- lgdi32 -lWs2_32 -lwsock32 -ladvapi32 -luser32 -lCRYPT32“ -openssl-linked -static-runtime ...等
32位相同
perl Configure VC-WIN32 no-shared --prefix=C:\Build-OpenSSL-VC-32-STATIC
等
我在没有DLL的单个.exe中具有支持SSL的应用程序。 -static-runtime 没有VC_redistributable依赖项。
然后,您需要允许重新链接已关闭源的应用程序,以使其与LGPL V3兼容
例如,使用此应用程序模板:
答案 3 :(得分:-1)
只需将OpenSSL的4个DLL文件与您的应用程序一起发送(即,将libcrypto-1_1-x64.dll,libssl-1_1-x64.dll,libcrypto-1_1.dll和libssl-1_1.dll复制到您的应用程序的安装中)。
如果您使用的是Qt的免费版本,则静态地构建所有库可能会违反LGPL许可证。