3rd Party Libraries for C++ Apps: Bane of Existence

It’s about time that I brought my manga reading application back to life with my Qt skills I’ve acquired from work.

Extracting .zip and .cbz files are an integral part of the application. The most luck I’ve had in finding a library that performs this functionality is QuaZip. And luck is a bit of an overstatement.

I don’t know exactly what I did almost three years ago when I managed to build it and successfully #include it inside of my project files. I believe the method ended up being including all of the headers and source files from QuaZip into my application - a bloated and cumbersome way.

This time around, I figured out how to build QuaZip and zlib and then simply add the shared object files to my Qt project. Much cleaner, and it works perfectly.

Let’s go over how I did this. Hopefully it will help someone out there.

Versioning

  • Operating System: Ubuntu 20.04
  • Qt: 5.12.8
  • zlib: 1.1
  • QuaZip: 0.7.3
  • CMake: v.3.21.2

Taking Care of zlib

QuaZip is dependent on zlib. zlib is a compression library that is apparently included in Qt installations.

I searched for it extensively inside of the Qt installation, finding it in a 3rd party folder. It seemed inadequate for the purposes of linking it with QuaZip, so I went the route of installing it from scratch with the following steps inside of my home directory.

wget http://www.zlib.net/zlib-1.2.11.tar.gz
tar -xvzf zlib-1.2.11.tar.gz
cd zlib-1.2.11/
./configure --prefix=/usr/local/zlib
sudo make install

This placed the shared object file inside of /usr/local/zlib since I specified a prefix in the ./configure command.

Taking Care of QuaZip

When going back to use QuaZip this time around, referencing its page on the internet, I did not realize that this documentation was out of date. Github shows that there is a newer version of QuaZip that uses CMake.

Instead of bothering with qmake again, I figured I would give this a try.

I downloaded the newest QuaZip release and then cd‘d into the extracted directory. Then I ran

cmake -S . -B ~/quazip -D QUAZIP_QT_MAJOR_VERSION=5
cmake --build ~/quazip

This built the necessary components into a folder of my choosing, in this case ~/quazip. I specified the Qt version to be 5 since I am running 5.12.8, but you can also specify 4 or 6.

Then I installed it with the following command.

cmake --build ~/quazip --target install

It installed the .so file inside of /usr/local/lib/ as qauzip1-qt5.so and put the included headers inside of /usr/local/include/QuaZip-Qt5-1.1.

Integrating QuaZip into the Qt Project

This was the most difficult part for me, as I was unfamiliar with how to dynamically link a 3rd party library to my Qt application. I was initially looking for how to do this with QuaZip, but I abstracted away from this single use case and looked at how to do this in general so I could extrapolate.

The two 3rd party dynamic linking methods for Qt most commonly mentioned seemed to be:

  • Importing literally all of the library files into a dependencies/ folder in your project and then including the QuaZip .pri file in your .pro file
  • Importing the shared object libraries that were generated to create a dynamic link

I did not want to go down the path of bloating my software with all of the QuaZip and zlib sources and headers, so I opted for the second option.

An easy way to do this was going into the .pro file, right clicking, selecting Add library..., selecting External library, selecting the .so file that was generated for QuaZip, and making sure the Platform was specified to only be Linux. The Include path was automatically filled in for me when I selected to shared object file. It generate the following in my .pro file.

unix:!macx: LIBS += -L$$PWD/../../../usr/local/lib/ -lqauzip1-qt5

INCLUDEPATH += $$PWD/../../../usr/local/include/QuaZip-Qt5-1.1
DEPENDPATH += $$PWD/../../../usr/local/include/QuaZip-Qt5-1.1

This is dynamic linkage.

I did the same thing for zlib, which sat in /usr/local alongside QuaZip. The following was generated in my .pro file after adding the shared object library.

unix:!macx: LIBS += -L$$PWD/../../../usr/local/zlib/lib/ -lz

INCLUDEPATH += $$PWD/../../../usr/local/zlib/include
DEPENDPATH += $$PWD/../../../usr/local/zlib/include

It worked.

After I finish developing my application, the next step is going to be figuring out how to bundle these 3rd party libraries inside of the installations for others to use on their own machine.