Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct
Building static Qt from sources OpenSSL failure (Windows)
Decided to take the plunge and build the latest version of Qt statically linked with OpenSSL and I get the following error during the configure phase:
ERROR: Feature 'openssl-linked' was enabled, but the pre-condition '!features.securetransport && libs.openssl' failed.
I've got OpenSSL 1.1.1g from slproweb.com.
I'm using Visual Studio 2017.
I had previously built Qt 5.9.4 (eventually).
Lots of Google searching on the subject. There's not much that's recent i.e. current versions of various components. What worked for Qt 5.9.4 obviously doesn't work anymore.
Looks at the test logs to see why the OpenSSL detection failed.
On a side note, do not forget the license constraints that come with a static build of a GPL/LGPL library.
I'm getting a lot of unresolved external symbol errors e.g.
libcrypto64MDd.lib(drbg_lib.obj) : error LNK2001: unresolved external symbol __imp__time64
libcrypto64MDd.lib(ct_policy.obj) : error LNK2001: unresolved external symbol __imp__time64
libcrypto64MDd.lib(ocsp_cl.obj) : error LNK2001: unresolved external symbol __imp__time64
libcrypto64MDd.lib(x509_vfy.obj) : error LNK2001: unresolved external symbol __imp__time64
libcrypto64MDd.lib(a_time.obj) : error LNK2001: unresolved external symbol __imp__time64
libssl64MDd.lib(statem_clnt.obj) : error LNK2001: unresolved external symbol __imp__time64
libssl64MDd.lib(ssl_asn1.obj) : error LNK2001: unresolved external symbol __imp__time64
libssl64MDd.lib(extensions_srvr.obj) : error LNK2001: unresolved external symbol __imp__time64
libssl64MDd.lib(extensions_clnt.obj) : error LNK2001: unresolved external symbol __imp__time64
libssl64MDd.lib(ssl_lib.obj) : error LNK2001: unresolved external symbol __imp__time64
libssl64MDd.lib(ssl_sess.obj) : error LNK2001: unresolved external symbol __imp__time64
libssl64MDd.lib(statem_srvr.obj) : error LNK2001: unresolved external symbol __imp__time64
libssl64MDd.lib(s3_lib.obj) : error LNK2001: unresolved external symbol __imp__time64
etc. etc. etc.
Seems I'm missing a library include but I can't tell which one.
Which compiler are you using ?
Which compiler was used to build OpenSSL ?
I've got OpenSSL 1.1.1g from slproweb.com.
I'm using Visual Studio 2017.
There's some sort of path problem. The procedure described here:
Is clearly wrong. Checking the log file showed that it couldn't find the libraries e.g. Crypt32. I put copies in the OpenSSL static library directory but I still get the same undefined symbol errors.
Are you sure you are building for the right architecture ?
Which version of Qt are you building ?
I tried building for both x86 and x64 with the same result.
The problem is trying to statically link OpenSSL. If I configure with -openssl-runtime, the configuration completes normally.
Clearly, some library necessary to statically link OpenSSL (using -openssl-linked) is missing. But I can't tell what library it needs.
Here are some other unresolved external symbols it complains about:
libcrypto64MDd.lib(blake2s.obj) : error LNK2001: unresolved external symbol __imp__wassert
libcrypto64MDd.lib(store_lib.obj) : error LNK2001: unresolved external symbol __imp__stricmp
libcrypto64MDd.lib(dso_win32.obj) : error LNK2001: unresolved external symbol __imp_strncpy
libcrypto64MDd.lib(b_dump.obj) : error LNK2001: unresolved external symbol __imp_fwrite
libcrypto64MDd.lib(ui_openssl.obj) : error LNK2001: unresolved external symbol __imp_fgets
libcrypto64MDd.lib(ui_openssl.obj) : error LNK2001: unresolved external symbol __imp_fopen
These would appear to be pretty basic standard C functions.
Apparently, configure wanted to see -llibucrt as part of the OPENSSL_LIBS to resolve the undefined external symbols.
This seems counter-intuitive though because these symbols should have been defined during the linking process after Qt got compiled. It sounds like there should be a way to tell configure that some symbols are going to be defined later.
Okay, so not out of the woods yet. Even though Qt appeared to have compiled statically linked with statically linked OpenSSL (having used the -openssl-linked configuration option), my application was still compiled with references to the OpenSSL DLL files. That makes no sense at all.
And to add insult to injury, I got the dreaded "Invalid address specified to RtlValidateHeap" error when trying to debug the app. This appears to be referenced in this bug report https://bugreports.qt.io/browse/QTBUG-61752 which supposedly isn't a bug I had previously built Qt 5.9.4 statically linked and didn't have this issue.
I'll probably take a stab at redoing the whole thing with Visual Studio 2019.
Today's update: I recompiled Qt 5.15 using Visual Studio 2017 and I still get the RtlValidateHeap error trying to debug my app.
I made some changes to the configure command to point to static versions of the OpenSSL libraries.
I downloaded OpenSSL 1.1.1g from http://slproweb.com/ using the larger installer which has static libraries in it.
To simplify things, I created a folder with the MT versions of the ssl and crypto libraries both the debug and release versions. This folder also has the includes folder within it. And it has the Ws2_32, Gdi32, Advapi32, Crypt32, and User32 libraries in it.
Sadly, though, my app is still looking for the damn DLL files. Dumpbin /imports confirms this.
One thing to take into account, you have to use the same runtime type for all the dependencies.
You can't mix libraries built against the dynamic and static runtime.
Once more unto the breech, dear friends.
So, I tried compiling Qt with Visual Studio 2019. While it compiles, my app doesn't link. I'm getting an unresolved external symbol error for __GSHandlerCheck_EH4
Bleah. If this wasn't such a ginormous PITA...
Are all your dependencies also built with VS2019 ?
The references are from Qt5Core.lib
So, to get past the GSHandlerCheck_EH4 problem, I had to include libcmt (or libcmtd for debug builds).
That introduced some other problems which were solved by adding ucrt from Windows Kits to the INCLUDEPATH and adding the corresponding ucrt (and ucrtd for debug builds) to the LIBS in my .pro file.
I confirmed that my app didn't reference the OpenSSL DLLs by using dumpbin /imports.
Note that this is with Visual Studio 2019 so it would seem that something significant has changed since VS 2017.
Sadly, we're not entirely out of the woods because launching a debug build results in crash in RtlValidateHeap. Release builds work fine. Note that this crash happens in a simple HelloWorld app as well. This problem is documented in depth here:
The comment "Not our bug. This is a compiler regression." is troubling since it would appear that it hasn't been truly fixed in VS 2019 even though Microsoft says that it has. Apparently, there is a workaround that involves making a change to qarraydata.cpp (and some other files) which you can read about towards the bottom of the above link.
For simplicity sake, I may start over with VS 2017. Reading more about the RtlValidateHeap problem, people have been saying that the error isn't fixed. Why the error still exists in VS 2019 is a mystery.
RogueWarrior last edited by RogueWarrior
Okay, so I think I've got it all sorted out. First, I uninstalled Visual Studio 2017 and reinstalled it.
Then, I downloaded prebuilt OpenSSL from http://slproweb.com/ using the larger installer which has static libraries in it. I chose the 64-bit version. I created a folder (C:\Users\media\Documents\openssl-1.1.1g-libs-static) with the following:
The OpenSSL include folder
Those last five were copied from "C:Program Files(x86)/Windows Kits/10/Lib/10.0.18362.0/um/x64". I could probably have figured out a way to reference them in the original path but that's "an exercise left to the reader"
Step 2: I created a Qt folder in C: and downloaded and extracted the Qt 5.15 sources into it.
Step 3 - The qt5vars.cmd file
I created a qt5vars-blahblahblah.cmd file with the following in it:
REM Set up \Microsoft Visual Studio 2017, where <arch> is \c amd64, \c x86, etc.
CALL "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" x64
REM Uncomment the below line when using a git checkout of the source repository
REM SET PATH=%_ROOT%\qtrepotools\bin;%PATH%
REM SET QMAKESPEC=
Again, this could probably be done better but it works so dink with it on your own.
Step 4: Launch the x64 Native Tools Command Prompt for VS 2017
cd into the Qt 5.15 folder.
Execute this line:
C:\WINDOWS\system32\cmd.exe /E:ON /V:ON /k C:\Qt\qt5vars-5150-x64-2017.cmd
And this line:
Then you configure Qt with this line:
configure OPENSSL_INCDIR="%OPENSSL_DIR%\include" OPENSSL_LIBDIR="%OPENSSL_DIR%" OPENSSL_LIBS="-lWs2_32 -lGdi32 -lAdvapi32 -lCrypt32 -lUser32" OPENSSL_LIBS_DEBUG="-llibssl64MTd -llibcrypto64MTd" OPENSSL_LIBS_RELEASE="-llibssl64MT -llibcrypto64MT" -opensource -static -static-runtime -openssl-linked -confirm-license -platform win32-msvc2017 -opengl desktop -nomake examples -nomake tools -nomake tests
This step also builds precompiled headers. One thing I've run into is that if the configure fails, you have to start with a fresh Qt sources extraction because I couldn't figure out a way to clean out the entrails. But, if all goes well with the configure operation, you'll be prompted to run nmake and then nmake install. This process takes many hours to complete.
The good news at this point is that I appear to have statically linked apps with OpenSSL statically linked as well. dumpbin /imports verifies that the DLLs aren't being referenced. Also, that debugging crash appears to have gone away by reinstalling VS 2017.
I'm not 100% sure this is all correct so I'm not going to mark this as solved just yet.
Follow up: I built my app, put it in an installer, and gave it to a friend to test. All seems to work as expected.