2

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

  • libz.a
  • libz.dll.a
  • zlib1.dll

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

  • quazip.dll
  • libquazip.a

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...

Teivaz
  • 5,462
  • 4
  • 37
  • 75
Sorkfa
  • 629
  • 7
  • 23

1 Answers1

2

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

king_nak
  • 11,313
  • 33
  • 58
  • Figured that out too. Build that and replaced `quazip.dll` with `libquazip.a` in the FindQuaZip.cmake. Now I get a undefined reference to __imp__ZN10JlCompress11compressDirE7QStringS0_b . Any Idea? – Sorkfa Jun 05 '19 at 11:41
  • I'm using QuaZip 0.7.1 and MSVC in my project... I get a `quazip.lib` file when defining staticlib. It is significantly larger then the old lib file and dll combined (659kB instead of 223kB). Did you re-run qmake before building? (in Qt Creator Build > Run qmake) Did you clear the output path? – king_nak Jun 05 '19 at 11:59
  • From your application .pro file, you should add : DEFINES += QUAZIP_STATIC. This define will disable some import/export definitions in quazip files header. – tunglt Jun 06 '19 at 07:50