How to statically compile Qt with OpenSSL support on Windows (with MinGW compiler)
The desired 'outcome' of this Qt build is to build and ship a portable Qt application with built-in SSL support.
So this is an age old problem with a multitude of questions on this topic, yet very few solutions exist that solves the problem. Some of these questions (and problems):
QT https SSL support for static QT static program build - getting 'Protocol “https” is unknown'
about compiling openssl inside qt application
Build Qt static from source enabling OpenSSL support
Compile static version of QT + OpenSSL Support
how to compile qt static with open ssl
Compiling static for Windows with OpenSSL
there are many more
and some of my own questions (using OpenSSL v1.1.1d & Qt 5.13 with MinGW ):
Statically compiled Qt 5.13.1 with OpenSSL 1.1.1d producing QSslSocket::connectToHostEncrypted: TLS initialization failed
Create a standalone binary using Qt with OpenSSL support
Static OpenSSL *.a libraries not linked target binary (using Statically Compiled Qt with SSL)
Static compile Qt 5.13.1 with -openssl-linked using MinGW (Windows 10)
Most of these questions do not have answers, and those answers provided (obviously) did not help in compiling, due to some error output or simply OpenSSL was never linked (built into the portable/binary application), or many other errors.
Further, there appears to be alot of confusion about using -ssl, -openssl-linked, -openssl and what each means. Also, if one should use -L/path/to/libs/static -l library1 -l library2 vs using the OPENSSL_HOME env variable and specify the path to headers & static / linked libraries, etc
Please note:
Ideally, in compiling, specific instructions for libraries would be required such as OpenSSL v1.0.2 or OpenSSL v1.1 and the qmake arguments in building a static Qt with those specific libraries in addition to things that should be considered during the build process.
What does Qt say?
Qt has provide some help in the form of these 2 posts:
Building a static Qt for Windows using MinGW with a Powershell script which does compile Qt statically using MinGW, but adding the various combinations (and permutations) of OpenSSL libraries -l and/or -L to the various paths (.lib), (.a), header files, etc simply did not work
Compiling OpenSSL with MinGW
The aim of this question is to give a detailed explanation and step-wise method in allowing those who need to compile a static Qt version with SSL some support and direction.
This is an unnatural "question", but having seen so many questions with no/very few solutions for cherrypicked cases in each specific question makes a general solution very difficult to obtain.
I am posting this question in hopes of a general solution being made available that could benefit all.
I just noticed this question just recently, so I haven't had time yet to write complete step-by-step instructions from the ground up, but I was able to do a static build of qt-5.15.0 in my environment which is based on MSYS2 shell together with MinGW-w64 with GCC 10 personal build from http://winlibs.com/ with all the prerequisites already compiled in the same environment.
The version of openssl was 1.1.1g built like this (static and shared libraries):
# location of Perl
PERLDIR=/d/Prog/Perl/strawberry-perl-5.30.0.1-64bit-portable/perl
# install destination
INSTALLPREFIX=/d/Prog/winlibs64-10.1.0/custombuilt
# for 32-bit replace mingw64 with mingw in the next line
./Configure --prefix=$INSTALLPREFIX threads shared zlib-dynamic -DOPENSSL_NO_CAPIENG mingw64 &&
make &&
PATH=$PERLDIR/bin:$PATH make -j1 install OPENSSLDIR_dir=$INSTALLPREFIX &&
strip $INSTALLPREFIX/bin/*.exe $INSTALLPREFIX/bin/*.dll &&
cp -f $INSTALLPREFIX/lib/libcrypto.a $INSTALLPREFIX/lib/libeay32.a &&
cp -f $INSTALLPREFIX/lib/libcrypto.dll.a $INSTALLPREFIX/lib/libeay32.dll.a &&
cp -f $INSTALLPREFIX/lib/libssl.a $INSTALLPREFIX/lib/libssleay32.a &&
cp -f $INSTALLPREFIX/lib/libssl.dll.a $INSTALLPREFIX/lib/libssleay32.dll.a &&
cp -f ms/applink.c $INSTALLPREFIX/include/openssl/ &&
echo Success
Here are the steps I did to do the static build of qt-5.15.0:
# location of Python
PY2DIR=/d/Prog/Python/WinPython-64bit-2.7.13.1Zero/python-2.7.13.amd64
# location of all the prerequisites
MINGWPREFIX=/d/Prog/winlibs64-10.1.0/custombuilt
# install destination
INSTALLPREFIX=/d/Prog/winlibs64-10.1.0/custombuilt
# fix missing SHARE_INFO_1 in qtbase/src/corelib/io/qfilesystemengine_win.cpp
echo "#include <levmar.h>" | gcc -E -xc - &> /dev/null && sed -i.bak -e "s/\(#\s*include <\)lm\.h\(>\)/\1levmar.h\2\n\1lmshare.h\2\n\1lmapibuf.h\2/" qtbase/src/corelib/io/qfilesystemengine_win.cpp
# avoid using missing debug ICU libraries in static builds
sed -i.bak -e "s/\(lsicu..\)d/\1/g" qtbase/src/corelib/configure.json
# configure
mkdir -p build_static &&
cd build_static &&
PATH=$PATH:$PY2DIR ../configure -platform win32-g++ -prefix $INSTALLPREFIX/qt -opensource -confirm-license -release -static -no-pch -no-rpath -strip -skip "qtserialbus" -qpa windows -gif -sql-odbc -sql-sqlite -opengl desktop -icu -system-pcre -dbus -system-sqlite -system-zlib -system-libpng -system-libjpeg -system-doubleconversion -system-freetype -system-harfbuzz -libproxy -system-proxies -openssl -openssl-linked -no-xcb -no-compile-examples -skip qtwebengine -nomake examples -system-proxies -plugin-manifests -pkg-config -I $MINGWPREFIX/include/freetype2 -I $MINGWPREFIX/include/mariadb &&
sed -i.bak -e "s/\(-lclang\)\.a/\1 -lpthread/" qttools/src/qdoc/Makefile.* &&
cd .. &&
# build
(
PATH=$PATH:$PY2DIR mingw32-make -Cbuild_static release QMAKE_CXXFLAGS="-fcommon" QMAKE_LFLAGS="-Wl,-allow-multiple-definition" || (
make -Cbuild_static/qttools/src/qdoc &&
PATH=$PATH:$PY2DIR mingw32-make -Cbuild_static release QMAKE_CXXFLAGS="-fcommon" QMAKE_LFLAGS="-Wl,-allow-multiple-definition"
)) &&
# workaround for missing qmake.exe
cp build_static/qtbase/bin/qmake.exe build_static/qtbase/qmake/ &&
make -Cbuild_static install &&
# manually create qt.conf
echo "[Paths]" > $INSTALLPREFIX/qt/bin/qt.conf &&
echo "Prefix=../../qt" >> $INSTALLPREFIX/qt/bin/qt.conf &&
echo Success
I have tested the result by building KeePassXC (https://github.com/keepassxreboot/keepassxc/archive/2.5.4.tar.gz) against it and the resulting package had no Qt DLLs at all and it ran fine.
I've found the lightweight DSP c library - Soundpipe.
I want to use some filters from it. I do not really need binary files, but the problem is that the repository doesn't have its main header file - soundpipe.h. As I understand, this is because the library uses specific modules ported from Csound and FAUST languages. Also the repository's readme doesn't have installation guide for Windows. It says:
By default, Soundpipe needs libsndfile, and a standard build
environment. Other modules that use other external libraries will need
to be explicitly compiled by modifying config.mk (note: but the Makefile's folder doesn't contain config.mk, there is only config.def.mk)
To compile:
make
sudo make install
Ok, I've downloaded and installed libsndfile.
Then I have tried to use MSVC's nmake - it doesn't work:
makefile(7) : fatal error U1036: syntax error : too many names to left of '='
Stop.
Here is the beginning of the makefile:
> .PHONY: all clean install docs bootstrap
>
> default: all
>
> VERSION = 1.5.0
>
> INTERMEDIATES_PREFIX ?= . PREFIX ?= /usr/local
> ...
After that I've downloaded MinGW, mingw32-make result:
config.mk: No such file or directory
mingw32-make: *** No rule to make target 'config.def.mk', needed by 'config.mk'. Stop.
Ok, when I try to run the configure command, it doesn't work on my Win7 x 64 (sh: ./configure: No such file or directory, etc...)
I have the paths in mt system path variable:
C:\MinGW\bin;C:\MinGW\msys\1.0\bin
Links that I've read:
How Do I Run ./configure with MinGW?
Getting mingw-get to install correctly - mingw/msys path missing plus more!
MinGW's configure doesn't work after reinstalling Git for Windows and GCC_TDM too (No idea how to run configure).
Any ideas how to build the library or at least find missing source files (or make through CSound, Faust, ...) ?
The Soundpipe build system is designed to be used with POSIX environments, of which there are a few to choose from on Windows.
I've been able to build Soundpipe using both MSYS2 and Windows Bash on Windows 10.
Im trying to run a c++ program on github. (available at the following link https://github.com/mortehu/text-classifier)
I have a mac, and am trying to run it in the terminal. I think I have downloaded autoconf and automake but am not sure. To run the program I am going to the correct folder in terminal then running
./configure && make
But I get the error:
WARNING: 'aclocal-1.15' is missing on your system.
You should only need it if you modified 'acinclude.m4' or
'configure.ac' or m4 files included by 'configure.ac'.
The 'aclocal' program is part of the GNU Automake package:
http://www.gnu.org/software/automake
It also requires GNU Autoconf, GNU m4 and Perl in order to run:
http://www.gnu.org/software/autoconf
http://www.gnu.org/software/m4/
http://www.perl.org/ make: *** [aclocal.m4] Error 127
I have xcode and g++ and all the things required to run c programs, but as is probably obvious, I have no idea what Im doing.
What is the easiest, simplest way to run the program in the above link? I realise it comes with a readme and example usage but I can not get that to work.
Before running ./configure try running autoreconf -f -i. The autoreconf program automatically runs autoheader, aclocal, automake, autopoint and libtoolize as required.
Edit to add: This is usually caused by checking out code from Git instead of extracting it from a .zip or .tar.gz archive. In order to trigger rebuilds when files change, Git does not preserve files' timestamps, so the configure script might appear to be out of date. As others have mentioned, there are ways to get around this if you don't have a sufficiently recent version of autoreconf.
Another edit: This error can also be caused by copying the source folder extracted from an archive with scp to another machine. The timestamps can be updated, suggesting that a rebuild is necessary. To avoid this, copy the archive and extract it in place.
Often, you don't need any auto* tools and the simplest solution is to simply run touch aclocal.m4 configure in the relevant folder (and also run touch on Makefile.am and Makefile.in if they exist). This will update the timestamp of aclocal.m4 and remind the system that aclocal.m4 is up-to-date and doesn't need to be rebuilt. After this, it's probably best to empty your build directory and rerun configure from scratch after doing this. I run into this problem regularly. For me, the root cause is that I copy a library (e.g. mpfr code for gcc) from another folder and the timestamps change.
Of course, this trick isn't valid if you really do need to regenerate those files, perhaps because you have manually changed them. But hopefully the developers of the package distribute up-to-date files.
And of course, if you do want to install automake and friends, then use the appropriate package-manager for your distribution.
Install aclocal which comes with automake:
brew install automake # for Mac
apt-get install automake # for Ubuntu
Try again:
./configure && make
You can install the version you need easily:
First get source:
$ wget https://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz
Unpack it:
$ tar -xzvf automake-1.15.tar.gz
Build and install:
$ cd automake-1.15
$ ./configure --prefix=/opt/aclocal-1.15
$ make
$ sudo mkdir -p /opt
$ sudo make install
Use it:
$ export PATH=/opt/aclocal-1.15/bin:$PATH
$ aclocal --version
aclocal (GNU automake) 1.15
Now when aclocal is called, you get the right version.
A generic answer that may or not apply to this specific case:
As the error message hint at, aclocal-1.15 should only be required if you modified files that were used to generate aclocal.m4
If you don't modify any of those files (including configure.ac) then you should not need to have aclocal-1.15.
In my case, the problem was not that any of those files was modified but somehow the timestamp on configure.ac was 6 minutes later compared to aclocal.m4.
I haven't figured out why, but a clean clone of my git repo solved the issue for me. Maybe something linked to git and how it created files in the first place.
Rather than rerunning autoconf and friends, I would just try to get a clean clone and try again.
It's also possible that somebody committed a change to configure.ac but didn't regenerate the aclocal.m4, in which case you indeed have to rerun automake and friends.
The whole point of Autotools is to provide an arcane M4-macro-based language which ultimately compiles to a shell script called ./configure. You can ship this compiled shell script with the source code and that script should do everything to detect the environment and prepare the program for building. Autotools should only be required by someone who wants to tweak the tests and refresh that shell script.
It defeats the point of Autotools if GNU This and GNU That has to be installed on the system for it to work. Originally, it was invented to simplify the porting of programs to various Unix systems, which could not be counted on to have anything on them. Even the constructs used by the generated shell code in ./configure had to be very carefully selected to make sure they would work on every broken old shell just about everywhere.
The problem you're running into is due to some broken Makefile steps invented by people who simply don't understand what Autotools is for and the role of the final ./configure script.
As a workaround, you can go into the Makefile and make some changes to get this out of the way. As an example, I'm building the Git head of GNU Awk and running into this same problem. I applied this patch to Makefile.in, however, and I can sucessfully make gawk:
diff --git a/Makefile.in b/Makefile.in
index 5585046..b8b8588 100644
--- a/Makefile.in
+++ b/Makefile.in
## -312,12 +312,12 ## distcleancheck_listfiles = find . -type f -print
# Directory for gawk's data files. Automake supplies datadir.
pkgdatadir = $(datadir)/awk
-ACLOCAL = #ACLOCAL#
+ACLOCAL = true
AMTAR = #AMTAR#
AM_DEFAULT_VERBOSITY = #AM_DEFAULT_VERBOSITY#
-AUTOCONF = #AUTOCONF#
-AUTOHEADER = #AUTOHEADER#
-AUTOMAKE = #AUTOMAKE#
+AUTOCONF = true
+AUTOHEADER = true
+AUTOMAKE = true
AWK = #AWK#
CC = #CC#
CCDEPMODE = #CCDEPMODE#
Basically, I changed things so that the harmless true shell command is substituted for all the Auto-stuff programs.
The actual build steps for Gawk don't need the Auto-stuff! It's only involved in some rules that get invoked if parts of the Auto-stuff have changed and need to be re-processed. However, the Makefile is structured in such a way that it fails if the tools aren't present.
Before the above patch:
$ ./configure
[...]
$ make gawk
CDPATH="${ZSH_VERSION+.}:" && cd . && /bin/bash /home/kaz/gawk/missing aclocal-1.15 -I m4
/home/kaz/gawk/missing: line 81: aclocal-1.15: command not found
WARNING: 'aclocal-1.15' is missing on your system.
You should only need it if you modified 'acinclude.m4' or
'configure.ac' or m4 files included by 'configure.ac'.
The 'aclocal' program is part of the GNU Automake package:
<http://www.gnu.org/software/automake>
It also requires GNU Autoconf, GNU m4 and Perl in order to run:
<http://www.gnu.org/software/autoconf>
<http://www.gnu.org/software/m4/>
<http://www.perl.org/>
make: *** [aclocal.m4] Error 127
After the patch:
$ ./configure
[...]
$ make gawk
CDPATH="${ZSH_VERSION+.}:" && cd . && true -I m4
CDPATH="${ZSH_VERSION+.}:" && cd . && true
gcc -std=gnu99 -DDEFPATH='".:/usr/local/share/awk"' -DDEFLIBPATH="\"/usr/local/lib/gawk\"" -DSHLIBEXT="\"so"\" -DHAVE_CONFIG_H -DGAWK -DLOCALEDIR='"/usr/local/share/locale"' -I. -g -O2 -DNDEBUG -MT array.o -MD -MP -MF .deps/array.Tpo -c -o array.o array.c
[...]
gcc -std=gnu99 -g -O2 -DNDEBUG -Wl,-export-dynamic -o gawk array.o awkgram.o builtin.o cint_array.o command.o debug.o dfa.o eval.o ext.o field.o floatcomp.o gawkapi.o gawkmisc.o getopt.o getopt1.o int_array.o io.o main.o mpfr.o msg.o node.o profile.o random.o re.o regex.o replace.o str_array.o symbol.o version.o -ldl -lm
$ ./gawk --version
GNU Awk 4.1.60, API: 1.2
Copyright (C) 1989, 1991-2015 Free Software Foundation.
[...]
There we go. As you can see, the CDPATH= command lines there are where the Auto-stuff was being invoked, where you see the true commands. These report successful termination, and so it just falls through that junk to do the darned build, which is perfectly configured.
I did make gawk because there are some subdirectories that get built which fail; the trick has to be repeated for their respective Makefiles.
If you're running into this kind of thing with a pristine, official tarball of the program from its developers, then complain. It should just unpack, ./configure and make without you having to patch anything or install any Automake or Autoconf materials.
Ideally, a pull of their Git head should also behave that way.
I think the touch command is the right answer e.g. do something like
touch --date="`date`" aclocal.m4 Makefile.am configure Makefile.in
before [./configure && make].
Sidebar I: Otherwise, I agree with #kaz: adding dependencies for aclocal.m4 and/or configure and/or Makefile.am and/or Makefile.in makes assumptions about the target system that may be invalid. Specifically, those assumptions are
1) that all target systems have autotools,
2) that all target systems have the same version of autotools (e.g. automake.1.15 in this case).
3) that if either (1) or (2) are not true for any user, that the user is extracting the package from a maintainer-produced TAR or ZIP format that maintains timestamps of the relevant files, in which case all autotool/configure/Makefile.am/Makefile.in dependencies in the configure-generated Makefile will be satisfied before the make command is issued.
The second assumption fails on many Mac systems because automake.1.14 is the "latest" for OSX (at least that is what I see in MacPorts, and apparently the same is true for brew).
The third assumption fails spectacularly in a world with Github. This failure is an example of an "everyone thinks they are normative" mindset; specifically, the maintainers, who are the only class of users that should need to edit Makefile.am, have now put everyone into that class.
Perhaps there is an option in autowhatever that keeps these dependencies from being added to Makefile.in and/or Makefile.
Sidebar II [Why #kaz is right]: of course it is obvious, to me and other cognoscenti, to simply try a sequence of [touch] commands to fool the configure-created Makefile from re-running configure and the autotools. But that is not the point of configure; the point of configure is to ensure as many users on as many different systems as as possible can simply do [./configure && make] and move on; most users are not interested in "shaving the yak" e.g. debugging faulty assumptions of the autotools developers.
Sidebar III: it could be argued that ./configure, now that autotools adds these dependencies, is the wrong build tool to use with Github-distributed packages.
Sidebar IV: perhaps configure-based Github repos should put the necessary touch command into their readme, e.g. https://github.com/drbitboy/Tycho2_SQLite_RTree.
2018, yet another solution ...
https://github.com/apereo/mod_auth_cas/issues/97
in some cases simply running
$ autoreconf -f -i
and nothing else .... solves the problem.
You do that in the directory /pcre2-10.30 .
What a nightmare.
(This usually did not solve the problem in 2017, but now usually does seem to solve the problem - they fixed something. Also, it seems your Dockerfile should now usually start with "FROM ibmcom/swift-ubuntu" ; previously you had to give a certain version/dev-build to make it work.)
The problem is not automake package, is the repository
sudo apt-get install automake
Installs version aclocal-1.4, that's why you can't find 1.5 (In Ubuntu 14,15)
Use this script to install latest
https://github.com/gp187/nginx-builder/blob/master/fix/aclocal.sh
2017 - High Sierra
It is really hard to get autoconf 1.15 working on Mac. We hired an expert to get it working. Everything worked beautifully.
Later I happened to upgrade a Mac to High Sierra.
The Docker pipeline stopped working!
Even though autoconf 1.15 is working fine on the Mac.
How to fix,
Short answer, I simply trashed the local repo, and checked out the repo again.
This suggestion is noted in the mix on this QA page and elsewhere.
It then worked fine!
It likely has something to do with the aclocal.m4 and similar files. (But who knows really). I endlessly massaged those files ... but nothing.
For some unknown reason if you just scratch your repo and get the repo again: everything works!
I tried for hours every combo of touching/deleting etc etc the files in question, but no. Just check out the repo from scratch!
I'm using Eclipse CDT on Linux to build a c++ executable and several static libraries which the executable depends on.
Everything is good - Eclipse generates the makefiles for both Debug and Release as expected.
However, I want to compile this code also on a computer without Eclipse installed, so I thought to write a simple makefile which calls the Eclipse makefile.
So I started with something like:
all:
cd Lib1/Release && make all
cd Lib2/Release && make all
...
cd Exec/Release && make all
This works for Release only, as you see...
How can I change the makefile so I can use the selected user's configuration ?
Thank you very much.
With this in your makefile you can invoke 'make debug' or 'make release' to build all the projects in the required mode :
config:
cd Lib1/$(CONFIG) && make all
...
cd LibN/$(CONFIG) && make all
cd Exec/$(CONFIG) && make all
debug:
make config CONFIG=Debug
release:
make config CONFIG=Release
.PHONY: debug release config
How can we create a software package, so that
after extracting our software tar ball user can do
the typical steps?
$ gunzip < mycode.tar.gz | tar xvf -
$ ./configure
$ make
$ make install
An alternative to the hard to understand GNU/Autools is CMake.
http://www.cmake.org/cmake/help/examples.html
e.g. KDE is using it.
Look into the GNU autoconf/automake toolchain. Here's a free tutorial/book.
In the old days, this process was done by hand. Each Makefile was written by hand (the file make uses as a sort of script). This became problematic when it came to portability, and so the configure script was made. The ./configure script was written by hand for each project as well. Eventually this was automated by GNU with their autotools package. This consists of autoconf, automake, and a few others. While alternatives exist, particularly for make, autotools is most widely used. ...At least on GNU/Linux systems. Alternatives include the already mentioned CMake, Boost.Build, Boost.Jam, SCons, and more.
Use autotools to create the configure script (which will generate the Makefile necessary for the last two steps), then make a tarball with all your code and stuff in it.
rpmbuild is a command to build rpm packages
man page
tutorial
Autotools.
You'll need to write a configure.ac and a Makefile.am scripts.
Configure.ac is pretty easy and can be mostly autogenerated from running 'autoscan' on your source code. That will generate a 'configure.scan' file that you'll need to tweak to generate the final configure.ac file.
The Automake.am file is all based off of conventions. You'll probably need something like:
AUTOMAKE_OPTIONS = foreign subdir-objects
AM_CXXFLAGS = -std=c++11 -static-libstdc++ -Wall -Werror \
-Wfatal-errors -I blah
AM_LDFLAGS = blah
bin_PROGRAMS = mybinary
mybinary_SOURCES = \
blah.h blah.cc
everything is based on a naming schema:
dist vs nodist = should it be built
inst vs noinst = should it be installed
DATA = data files
MANS = man pages
SOURCES = source code
so dist_noinst_DATA is for data files required for building but are not installed.
Once you have both of those files you usually need to run something like:
aclocal && autoheader && automake --add-missing && autoconf
to setup autotools files required for building. This can be put in a shell script and run prior to running ./configure.