Is there any way to building static Qt with static OpenSSL?
Asked Answered
R

4

17

Original question was slightly different but part of a more major question.

I am trying to build Qt 5.2 as static with static OpenSSL on Windows.

My final goal is to ship a single binary without the need to provide libeay32.dll and ssleay32.dll with it. However, it seems to me that this is impossible. I built static Qt with static openssl libs but it seems like Qt is outright ignoring the libs provided and always searches for DLLs.

This answer also suggests that QtNetwork always searches for DLLs and ignores everything else but it also states that "two options are to compile OpenSSL into Qt..." but this does not seem to be the case.

Can someone provide a definitive answer?

This is my Qt configure (line breaks added for readability):

configure -static -qmake -opensource -nomake examples -opengl desktop
-platform win32-msvc2010 -openssl -I C:\git\openssl\build\include
-L C:\git\openssl\build\lib OPENSSL_LIBS="-llibeay32 -lssleay32 -lgdi32"
Rockel answered 30/12, 2013 at 16:11 Comment(10)
Why don't you provide the relevant nmake VERBOSE= output to see what include paths are passed to the toolchain?Dreadnought
@Laszlo Papp: edited.Rockel
That is not the nmake VERBOSE=1 output.Dreadnought
Can you specify exactly what command to execute? Because this is the output I get.. I will try to clean the configuration just in case.Rockel
As you can see the openssl include path is not passed to the compiler...Dreadnought
So, it seems the problem was that you have not re-run qmake?Dreadnought
Btw, are you OK with not being able to supply security fixes in openssl this way? Also, have you tried -openssl-linked?Dreadnought
From my understanding the only thing openssl-linked does is that your program will fail to even start up if the ssl libs are not found. Without that it only fails when sending the request over https. Also, I don't think security fixes are a problem.. because I would either have to supply new DLLs via update or just update the whole binary, it's the same thing. For now I decided to simply distribute the DLLs with the installer and it's all working but I am still curious whether it's possible to do it.Rockel
Hmm, I believe your understanding is incorrect. Security fixes are a problem because users will rely on your existence for the software getting more secure with security updates. They could not make it without you unlike if it is not statically linked in...Dreadnought
Also, what exactly do you mean by "but this does not seem to be the case." in your question?Dreadnought
I
15

Is there any way to building static Qt with static OpenSSL?

Sure, you need to use the following option when configuring Qt:

-openssl-linked

The reason is that QtNetwork uses the QLibrary class by default for dynamically opening the library to get the necessary symbols.

This is the option to tell Qt not to do so, and respect the the normal linkage rules.

That being said, it is not recommended to use static linkage for openssl if security updates need to be available for the end user without your involvement. Consider that for a moment what happens if you are gone, not working on this project anymore, etc.

Also, this setup is not tested frequently, so you may actually encounter some issues that should be fixed upstream, but this is solution design for the use case in question.

Disclaimer: since SO is about programming, I am ignoring the licensing consequences for static linking againt Qt, so I would just like to quickly remind that you that be aware of the proper usage not to get into legal troubles.

Idalia answered 11/1, 2014 at 21:59 Comment(0)
K
1

OPENSSL_LIBS="-llibeay32 -lssleay32"...

Avoid -l altogether (and -L, and -Wl,-Bstatic). The linker sometimes ignores the request for static linking (Apple), and sometimes a script modifies it (I can't tell you how many custom build scripts have bitten me).

Instead, use a fully specified archive just like you would use an object file. In your LDLIBS add the following so there's no chance for a script to screw things up or the linker to ignore your request:

/usr/local/ssl/lib/libssl.a /usr/local/ssl/lib/libcrypto.a

Obviously, you should change the path of libssl.a and libcrypto.a to match your installation.

If you don't have an LDLIBS, then add it to LDFLAGS (or "other linker flags" in the IDE).

In Qt, it looks like that would be QMAKE_LFLAGS or LIBS. Or you could try this post: How to add "Additional Dependencies" (Linker settings).

The same trick applies to shared objects, too (but linkers favor shared objects, so it usually does not become an issue). That is, you can specify:

/usr/local/ssl/lib/libssl.so /usr/local/ssl/lib/libcrypto.so

The thing to remember when specifying a shared object like above is that you have to specify an rpath to ensure the runtime linker gets the message. That is, you should add the following to LDFLAGS or "other linker options":

-Wl,-rpath=/usr/local/ssl/lib

I've been bitten a few when specifying shared objects when using the OpenSSL FIPS Capable Library that resides in /usr/local/ssl/lib because the runtime linker uses the distribution's OpenSSL in /usr/lib or /usr/lib64. The OpenSSL FIPS Capable Library is the one you call FIPS_mode_set on.

You can also remove (or rename) the shared object from the location, leaving only the static archive. I've had to use this technique in the past when building under Xcode for iPhone. Xcode refused to use the static archive, even with a properly placed -Bstatic. (Cross-compilers and modified toolchains are some of the worst to use at times). I don't think you should have to modify install directories, so I generally don't use it technique.

To summarize, leave nothing to chance and avoid -l, -L, and -Wl,-Bstatic. Fully specify what you want and use the fully qualified library path name, and use them like object files. Use an rpath if you are specifying a shared object.

Kiki answered 11/1, 2014 at 8:16 Comment(5)
-l and -L are fine actually if there is no clash, and that should be the recommendation as well IMO since that is more portable as opposed to specifying a full path, which is OS specific at large.Dreadnought
Laszlo - I kind of agree, but I can tell you for certain that the linker and scripts don't do what you want at times. That never happens when you abandon -L, -l and -Bstatic in favor of fully specifying libraries and archives like object files. I cited examples of problems with both (and cen is having a similar problem). Its the difference between theory and practice.Kiki
IMO, it is your practice, but it is not like that when people use it correctly. Writing platform dependent buildsystem in a Qt Project looks out of place.Dreadnought
Lazlo - OK, whatever. You're right. Have you tried testing that "it is not like that when people use it correctly" theory on Apple platforms? Or when using OpenSSL in an alternate location for the FIPS library?Kiki
Yes, also, the OP is asking about Windows AFAICT, not Apple.Dreadnought
C
1

This is how I build Qt 5.7.1 with SSL support on Windows using MSVC 2013:

Make sure Perl, Python and Ruby can be found in the PATH environment variable.

Download Qt from the github repository:

cd C:\Qt
git clone https://github.com/qt/qt5.git
cd C:\Qt\qt5 
git checkout 5.7 

Make sure to checkout commit 36e7cff94fbb4af5d8de6739e66164c6e6873586. At this time, checking out 5.7 does exactly that.

Place the contents below in qt5vars.bat located at C:\Qt\qt5. Make adjustments if you need to:

@echo off

REM Set up \Microsoft Visual Studio 2015, where <arch> is \c amd64, \c x86, etc.
CALL "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86

REM Edit this location to point to the source code of Qt
SET _ROOT=C:\Qt\qt5

SET PATH=%_ROOT%\qtbase\bin;%_ROOT%\gnuwin32\bin;%PATH%

REM Uncomment the below line when using a git checkout of the source repository
SET PATH=%_ROOT%\qtrepotools\bin;%PATH%

REM Uncomment the below line when building with OpenSSL enabled. If so, make sure the directory points
REM to the correct location (binaries for OpenSSL).
SET PATH=C:\OpenSSL-Win32\bin;%PATH%

REM When compiling with ICU, uncomment the lines below and change <icupath> appropriately:
REM SET INCLUDE=<icupath>\include;%INCLUDE%
REM SET LIB=<icupath>\lib;%LIB%
REM SET PATH=<icupath>\lib;%PATH%

REM Contrary to earlier recommendations, do NOT set QMAKESPEC.

SET _ROOT=

REM Keeps the command line open when this script is run.
cmd /k

After that, execute this file and properly initiate the repository:

qt5vars.bat 
perl init-repository

Finally, to configure and compile the library successfully (with debug and release versions), make sure the paths referenced by configure are also valid on your system:

configure -static -static-runtime -debug-and-release -ssl -openssl -openssl-linked -opengl dynamic -platform win32-msvc2013 -prefix C:\Qt\qt5.7-msvc2013-static -nomake tests -nomake examples -I "C:\OpenSSL-Win32\include" -L "C:\OpenSSL-Win32\lib\VC\static" OPENSSL_LIBS="-lUser32 -lAdvapi32 -lGdi32 -lCrypt32" OPENSSL_LIBS_DEBUG="-lssleay32MTd -llibeay32MTd" OPENSSL_LIBS_RELEASE="-lssleay32MT -llibeay32MT"
nmake
nmake install

Everything so far should have run smoothly and beautifully. Now it's a matter of configuring Qt Creator to detect this new Qt Version and create a new Kit use on your projects:

Commendatory answered 30/6, 2017 at 18:43 Comment(0)
B
0

build Qt statically with OpenSSL on Win 10

  1. download Qt 5.15.1 Source Code from Qt Maintenance Tool.
  2. install Python, Perl, OpenSSL, jom
  3. make sure they are in Path environment variable.
  4. open x64 Native Tools Command Prompt for VS 2019

download OpenSSL from here https://slproweb.com/products/Win32OpenSSL.html

# remove previous config cache
rm /d/Qt/5.15.1/Src/config.cache

set OPENSSL_DIR=C:\Program Files\OpenSSL-Win64
configure.bat -release -opensource -confirm-license -static -no-pch -optimize-size -opengl desktop -platform win32-msvc  -prefix "D:\Qt\5.15.1\msvc2019_64_static" -skip webengine -nomake tools -nomake tests -nomake examples -openssl-linked OPENSSL_INCDIR="%OPENSSL_DIR%\include" OPENSSL_LIBDIR="%OPENSSL_DIR%\lib\VC\static" OPENSSL_LIBS="-lWs2_32 -lGdi32 -lAdvapi32 -lCrypt32 -lUser32 -llibssl64MDd -llibcrypto64MDd" OPENSSL_LIBS_DEBUG="-llibssl64MDd -llibcrypto64MDd" OPENSSL_LIBS_RELEASE="-llibssl64MD -llibcrypto64MD"  

D:\jom_1_1_3\jom.exe -j8
D:\jom_1_1_3\jom.exe -j8 install
Bantustan answered 29/9, 2020 at 6:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.