My project requires a version of zlib
that isn't present on all target machines, so I want to build zlib
from source in my project. Then when I make
my project, it should first build zlib
so it can be linked to when compiling my project.
One complication is that zlib
requires configure
to be run before make
can be run.
I'm not even sure where to start here. Is there functionality built in to Qt Creator for importing 3rd party library source code like this, or do I need to code out a custom .pro
file?
I tried the "Add Library..." menu that appears when right-clicking on my project, but it doesn't recognize the library - likely because no .pro
file exists. I also tried to create a .pro
file by File -> New Project -> Import Existing Project, and it's able to compile zlib
once configure
has been run, but it still doesn't generate a .pro
file.
I thought that maybe the subdirs might be useful, but I'm not sure if that is the right route in this situation, and even if it is I am not sure whether I can auto-create the necessary .pro
file, or I have to create it myself.
Given the source code for a 3rd party library like zlib
, how do I integrate that into an existing Qt project such that I can compile the library from source, and use it in my project?
Yes, you need to create a project file for it. You can find my version below what I used for several projects.
QT -= core gui
TARGET = zlib
TEMPLATE = lib
# Use this for static zlib rather than the default dynamic
# CONFIG += staticlib
include(zlib.pri)
HEADERS += \
$$PWD/crc32.h \
$$PWD/deflate.h \
$$PWD/gzguts.h \
$$PWD/inffast.h \
$$PWD/inffixed.h \
$$PWD/inflate.h \
$$PWD/inftrees.h \
$$PWD/trees.h \
$$PWD/zconf.h \
$$PWD/zlib.h \
$$PWD/zutil.h
SOURCES += \
$$PWD/adler32.c \
$$PWD/compress.c \
$$PWD/crc32.c \
$$PWD/deflate.c \
$$PWD/gzclose.c \
$$PWD/gzlib.c \
$$PWD/gzread.c \
$$PWD/gzwrite.c \
$$PWD/infback.c \
$$PWD/inffast.c \
$$PWD/inflate.c \
$$PWD/inftrees.c \
$$PWD/trees.c \
$$PWD/uncompr.c \
$$PWD/zutil.c
INCLUDEPATH += $$PWD
Then in the project file including this one, you can do something like this:
# CONFIG += order # If you wanna make sure about order. This is optional.
SUBDIRS += \
zlib \
...
If you wanna go even a bit more advanced with qmake, you can do something like this:
SUBDIRS += \
src_zlib \
src_mylib \
...
src_zlib.subdir = $$PWD/zlib
src_zlib.target = sub-zlib
src_zlib.depends =
src_mylib.subdir = $$PWD/mylib
src_mylib.target = sub-mylib
src_mylib.depends = src_zlib
As you can see this way, you would have a lot more reasonable control among the dependencies regardless the order set. For instance, you could still keep the entries in alphabetical order which is helpful with proper maintenance in the long run.
Then, you will need a line like this in the project file (.pro) of your subproject, let us say "foo", which depends on zlib.
LIBS += -L$${PROJECTROOT}/$${SUBDIR_TO_ZLIB} -lz
# These lines are only option, and you do not necessarily need them.
# win32:LIBNAME = zlib.dll
# unix:LIBNAME = libzlib.so
# PRE_TARGETDEPS += $${PROJECTROOT}/$${BUILD_SUBDIR_LIBS}/$${LIBNAME}
Following are instructions for adding a 3rd party repository to your Qt project and building it from source.
Some are able to add such libraries via Qt Creator, but I could never get that to work. So these are instructions on how to create the necessary .pro
and .pri
files instead. In this post, I will use zlib
as an example, although other libraries should be similar.
Since your application depends on this library, we need to ensure that the library is built first. To do this, the 3rd party library and the source code for your application should be in sibling directories.
~/myApp $ ls myApp
src zlib
You probably already have a myApp.pro
file that correctly builds your application. I recommend renaming it to src.pro
, and you'll see why in the next step.
mv src/myApp.pro src/src.pro
Now you can create a new myApp.pro
in the root directory.
~/myApp $ touch myApp.pro
~/myApp $ ls
myApp.pro src zlib
This is a rather simple .pro
file that merely says "build zlib
before myApp
."
# ~/myApp/myApp.pro
TEMPLATE = subdirs
CONFIG += ordered # This tells Qt to compile the following SUBDIRS in order
SUBDIRS = zlib src
Now we need to tell Qt how to build our 3rd party library. We do this by creating a new .pro
file:
# ~/myApp/zlib/zlib.pro
TARGET = z # The name of the output library - can be whatever you want
TEMPLATE = lib # Tells Qt that we are compiling a library so the output will be bundled into a .a or .so file
CONFIG += staticlib # Tells Qt that we want a static library, so a .a file. Remove this and you will get a .so file
QMAKE_CFLAGS_WARN_ON -= -Wall # Optional - disable warnings when compiling this library
QMAKE_CXXFLAGS_WARN_ON -= -Wall # Optional - disable warnings when compiling this library
HEADERS += \
crc32.h \
deflate.h \
gzguts.h \
inffast.h \
inffixed.h \
inflate.h \
inftrees.h \
trees.h \
zconf.h \
zlib.h \
zutil.h
SOURCES += \
adler32.c \
compress.c \
crc32.c \
deflate.c \
gzclose.c \
gzlib.c \
gzread.c \
gzwrite.c \
infback.c \
inffast.c \
inflate.c \
inftrees.c \
trees.c \
uncompr.c \
zutil.c
If you are building something other than zlib
, just change TARGET
to the name of the library, and replace the contents of HEADERS
and SOURCES
with the files that need to be compiled for your library.
You can go ahead now and test out this .pro
file.
~/myApp/zlib/ $ qmake
~/myApp/zlib/ $ make
...
~/myApp/zlib/ $ ls libz.a
libz.a
Yay!
Finally, we need to update the .pro
file of your application to link in the 3rd party library. There are two parts to this:
First, we'll add the header files into the include path. Add this line to src.pro
.
INCLUDEPATH += zlib
This allows you to reference zlib.h
in your code like so:
#include "zlib.h"
Otherwise, you would have to specify the full relative path of the header like this:
#include "zlib/zlib.h"
If you're fine with the second method, then there should be no need to update the INCLUDEPATH
variable.
Second, we need to add the arguments the linker needs to find the static (or shared) library itself. Add this line to src.pro
.
LIBS += -L$$PWD/../zlib -lz
The first part (-L$$PWD/../zlib
) says that the folder containing the library is at ../zlib
, which should be correct since zlib
is a sibling folder to src
. The second part (-lz
) says that the name of the library is z
. The linker infers from this that the library is actually located in the file libz.a
.
At this point, you may have to clean your build by doing a make distclean
. But from there you should be able to build your project with the 3rd party library included by going to your base directory and running qmake
and make
.
cd ~/myApp
qmake -r
make
Note: Big thanks go to @LaszloPapp for getting this process started. Much of the source material for this answer came from his answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With