Right off the bat, sorry about the length of the question, but it is due to all the additional details I am providing which I hope could help trouble shoot the issue faster
What am I trying to achieve?
I need to create a portable (all-in-one) application, with SSL support.
What is the problem?
So the core problem I am facing is getting SSL support included into my binary/portable app.
A MCVE of the app is simple:
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();
}
Output on my DEV machine:
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"
Info of Dev Machine
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
Running the same binary on a fresh Windows 10 x86 machine results in:
Is SSL Enabled? false
SSL Library Build Version (Qt compiled against): "OpenSSL 1.1.1d 10 Sep 2019"
SSL Library Version String (available locally): ""
Info of Test Machine (Completely fresh install - 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.
Running the same binary on a fresh Windows 7 x64 machine results in:
Is SSL Enabled? false
SSL Library Build Version (Qt compiled against): "OpenSSL 1.1.1d 10 Sep 2019"
SSL Library Version String (available locally): ""
Info of Test Machine (Windows 7 x64 laptop with drivers installed)
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.
By look at the above results, I conclude that installing OpenSSL solves the problem. Good, but I want need to have it included in my portable app.
In achieving this, I am required to
Compile Qt statically with OpenSSL support
I have done this with the help of this script adapted from ps1
powershell script found here on Qt's wiki. I made additions for:
OpenSSL home
$OPENSSL_HOME
number of threads
$threads
, andarchitecture type
$arch
to be used.
Qt Compiling Details & OpenSSL info
Compiler:
mingw32
located inC:\Qt\Qt5.13.1\Tools\mingw730_32\bin
mkspec:
win32-g++
(if that makes any difference).OpenSSL version (32 bit): 1.1.1d
The configuration is as follows:
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:
I am using -openssl
and not -openssl-linked
. I have tried several variations of builing Qt with both -openssl
and -openssl-linked
. -openssl-linked
could never successfully build, see this post I made as to the reason why.
Note 2:
The only successful static Qt compilation I had working was with -ssl -openssl
configuration flags enabled
OpenSSL installation (on DEV machine only) is at
`$OPENSSL_HOME = "C:\OpenSSL-Win32"`
where I am using the statically compiled MinGW
libraries for OpenSSL, found in
`$OPENSSL_HOME = "C:\OpenSSL-Win32\lib\MinGW",`
The file contents of 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
Add link project .pro to OpenSSL libraries
I added the OpenSSL libraries to the .pro
file using 2 methods(libraries are the statically compiled MinGW OpenSSL libraries found at C:\OpenSSL-Win32\lib\MinGW
)
Manual Entry of libraries into .pro file
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
The binary size with and without the linked libraries above remains the same size
The LDD output of the binary (on my dev machine) with libraries added above is:
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
The LDD output of the binary (on my Windows 10 x86 test machine) with libraries added above is:
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 Library Import into .pro file
Import using (External Library
> Import .a
file> Static
& Windows
only options with 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
Using the automatic binary import, the LDD output of the binary (on my dev machine) with libraries added above is:
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
And using the automatic library import, the LDD output of the binary (on my Windows 10 x86 test machine) with libraries added above is:
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
The application output for the dev machine is SSL enabled
as mentioned previously in my post (for both manual and automatic library entry):
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"
The application output for the test machines (w/o OpenSSL installed) is the same as previously too (for both manual and automatic library entry):
Is SSL Enabled? false
SSL Library Build Version (Qt compiled against): "OpenSSL 1.1.1d 10 Sep 2019"
SSL Library Version String (available locally): ""
So with OpenSSL library not being present, it causes the below error when requesting a SSL connection on Non-Dev (fresh / client) machines:
QSslSocket::connectToHostEncrypted: TLS initialization failed
which is the result of the OpenSSL libary not being included in the binary as a dependency. So basically, adding a static OpenSSL library to the project file does not work or I am doing something incorrectly somewhere down the line.
Note 4: Why isn't the question titled: How to Import a static library into Qt?
Importing a static library is straight forward and not complicated. I am assuming I have made a mistake somewhere in the static compilation of Qt with SSL support enabled.
Advice on solving this problem would be greatly appreciated.
Update 1
I have resolved the problem with -openssl-linked
. The cause (or fix rather) is to not install OpenSSL to your machine. Rather, extract the .a
& include
directries into a seperate directory. So everything is the same with exception of you having the lib
s & include
without installing.
Then use the standard configureation (mentioned above), replacing -openssl
with -openssl-linked
and you should have a successful compile.
Updated Problem
When building & running my application with the new Linked OpenSSL Qt kit, I get a message saying:
The code execution cannot proceed because libcrypto.dll was not found. Reinstalling the program may fix this problem.
Followed by another dialog
The code execution cannot proceed because libssl.dll was not found. Reinstalling the program may fix this problem
LDD requirments:
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
Have tested this with and without the .pro LIBS
& INCLUDEPATH
. Both result in the missing dll
's required.