c++qtcmakequaziplibz

Build c++ Qt CLI Tool with Quazip


so normally I am an embedded software developer first time I need to do something like that... So I am no expert at all at this... I have come this far with a lot of googling and trial and error methods...

What I want to do

I need to write a C++ CLI application which can zip and unzip files.

My general conditions

I want to use Qt and Quazip since Qt doesn't support zipping natively (or does it). I want to build with Mingw and CMake for Windows 64bit on a Windows 64bit system.

With my knowledge, it would be best if I compile Quazip statically so I don't depend on any other quazip DLL which may be present on other systems...

How I think It works

  1. I need to compile zlib
  2. Then I need to compile Quazip (with zlib)
  3. Link the compiled libraries to my project.

My research

I found two good youtube videos which should help me:

No of these ways did work out for me. Also I found that blog post which was a little bit of help...

http://www.antonioborondo.com/2014/10/22/zipping-and-unzipping-files-with-qt/

This site was available till yesterday now it's gone :D

Also I found that old Stackoverflow question which helped me a bit:

How to connect the QuaZip library in CMake

Detailed steps on what I did:

1. Building zlib

Downloaded the latest version of zlib from the official website. version 1.2.11 I build zlib with the following commands:

cd C:/some/Path/zlib-1.2.11
mingw32-make -f win32/Makefile.gcc

That works perfectly I get a

those files and all the header files (11 files) I copy in a seperate folder. Which looks like this:

Build
|
+-include
+-lib

Headers in the include folder the libs in the lib folder.

2. Building Quazip

Now the messy part...

Downloading the newest version of Quazip (version 0.8.1) from the GitHub.

I tried various ways to compile Quazip. The one I stick to was: Open the .pro file in Qt creator inside the quazip folder (the folder where the sources are located).

So then I added the compiled zlib to the Qmake file. Following lines I added at the end of the file:

INCLUDEPATH += "C:/Build/include" 
LIBS += -L"C:/Build/lib" 
LIBS += -lz

Then build Quazip with QtCreator as release Build. When compiled I get

I copy all the header files from quazip (16 fils) in the include folder and the two libs in the lib folder.

Now I have like a zippackage in the build folder.

3. Adding Quazip and zlib to my Project

Copied the FindQuazip.cmake file into my project form the Quazip Repo. In my CMakeLists.txt I added the following lines:

set(ZLIB_ROOT "C:/BUILD" CACHE PATH "Path to zlib")
find_package(ZLIB REQUIRED)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
find_package(QuaZip REQUIRED)

I need to set the ZLIB_ROOT so CMake uses the zlib I want. If I don't set Root he uses a zlib from a ruby installation from my PC. Also I added

include_directories(
    "${BASE_DIR}/sources"
    "${QUAZIP_INCLUDE_DIR}"
    )

and at the end

add_executable(${PROJECT_NAME} ${SOURCES} ${INC_ALL} )

target_link_libraries(${PROJECT_NAME} Qt5::Network Qt5::Core Qt5::Widgets
    ${ZLIB_LIBRARIES}
    ${QUAZIP_LIBRARIES}
    )

Then I needed to add the FindQuazip.cmake since it would find the libs: I edited the following:

FIND_PATH(QUAZIP_LIBRARY_DIR
          WIN32_DEBUG_POSTFIX d
          NAMES libquazip.a #quazip.dll
          HINTS "C:/Build/lib"
          PATH_SUFFIXES QuaZip/lib
          )
FIND_LIBRARY(QUAZIP_LIBRARIES NAMES libquazip.a HINTS ${QUAZIP_LIBRARY_DIR})
FIND_PATH(QUAZIP_INCLUDE_DIR NAMES quazip.h HINTS ${QUAZIP_LIBRARY_DIR}/../include)
FIND_PATH(QUAZIP_ZLIB_INCLUDE_DIR NAMES zlib.h)

Okay so It took me two days to get to there where I am now. Now when I run CMake every works fine. He finds the libs. I can even include a the Header files of Quazip. But when I then try to compile a minimal example the linker can't find any symbols. Minimal Example:

#include <iostream>
#include <QApplication>
#include "JlCompress.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    cout << __cplusplus << endl;
    cout << "Hello World!" << endl;

    JlCompress::compressDir("C:/WorkspaceLokal/Test/test.zip", "C:/WorkspaceLokal/Test/TestFolder");
    return a.exec();
}

By compiling it I get the following error:

C:\some\path\sources\main.cpp:-1: Fehler: undefined reference to `JlCompress::compressDir(QString, QString, bool)'

This means the linker can't link the function...

My Question

What am I doing wrong? Do I need to compile Quazip in another way?

Edit 4:

since it now works how to I compile the Quazip as a static lib, so that I can link it statically to my application?

Thanks in advance...

Edit 1:

Here are the QUAZIP variables from Qt creator: Qauzip

Edit 2:

Okay. Some news. the libquazip.a is something else and doesn't work. If I link against the quazip.dll compiling works. But when I run the application it crashes at the function call compressDir...

Edit 3:

It works. I just needed to copy the quazip.dll to the compiled executable...


Solution

  • From QuaZip's pro file:

    # You'll need to define this one manually if using a build system other  
    # than qmake or using QuaZIP sources directly in your project.  
    CONFIG(staticlib): DEFINES += QUAZIP_STATIC
    

    This should trigger when you add staticlib to the CONFIG in quazip.pro (2nd line):

    CONFIG += qt warn_on staticlib
    

    If you are not using qmake to build Quazip, just make sure that you #define QUAZIP_STATIC in a way specific to your build system