How to use zlib with Qt applications under Windows...

in #qt4 years ago

Qt needs special build script to be able to use zlib as it uses more functions than standard binary has. I used following build file saved in root directory of zlib source tree as zlib.pro:

TARGET = zlib1
TEMPLATE = lib
CONFIG -= qt debug
CONFIG += dll

win32 {
        DEFINES += WINAPI_FAMILY=100
        RC_FILE = win32\\zlib1.rc
        DEF_FILE = win32\\zlib.def
}

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

HEADERS +=      crc32.h \
                deflate.h \
                inffast.h \
                inffixed.h \
                inflate.h \
                inftrees.h \
                trees.h \
                zconf.h \
                zlib.h \
                zutil.h

Copy zlib import library to Visual Studio directory

This creates a file zlib1.lib that needs to be copied to C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Tools\MSVC\14.16.27023\lib\x64. The path might be slightly different depending on version of Visual C++. Some software require that the import library for dynamic-link library is named "zdll.lib", so you can just rename or make a copy of the file.

If you have multiple directories with different version numbers, the import library needs to be copied to lib\x64 subdirectory of all directories.

Copy zlib headers to Visual Studio directory

You also need to copy zconf.h and zlib.h from the built zlib directory to C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Tools\MSVC\14.16.27023\include...

If you have multiple directories with different version numbers, the two files needs to be copied to include subdirectory of all directories.

Building Qt using dll files

When you build Qt from sources, you can pass -system-zlib to configure and it will build the libraries against the zlib version you built using the qmake project above, you need to copy zlib1.dll to bin directory of installation directory of Qt, or qtbase\bin directory of the source tree, if you didn't specify installation directory.

You need to run configure once without -system-zlib so it builds qmake.exe binary. Do not build anything else from Qt until you have built zlib first.

If you get error about missing zlib.lib, the Qt version tries to find the static version of zlib, you can either build static version or just use the import library for dynamic-link library.

If you have OpenSSL installed, you can also pass -openssl-linked -I c:\OpenSSL-Win64\include -L c:\OpenSSL-Win64\lib and it will enable support for https protocol using OpenSSL. This requires libcrypto-1_1-x64.dll and libssl-1_1-x64.dll in same directory as the application binaries. You can find the files in directory c:\OpenSSL-Win64\bin.

OpenSSL needs to be installed to directory under root of drive, the path can't have any special characters.

Building own applications

If your own application use qmake projects, you can just add the zlib source directory with zlib.pro as sub-directory of your source tree and qmake will automatically make sure it gets added to the build.

For example, in root directory of your project:

TEMPLATE = subdirs
SUBDIRS = zlib src

The order of the sub-directories is important as it will decide the build order.

in src\src.pro, you need to have:

!contains(CONFIG, zlib):LIBS += -L../zlib/Release zlib1.lib
INCLUDEPATH += ../zlib

This makes sure your project file works also with stock Qt libraries that have statically linked zlib.

The example project file doesn't build debug version of zlib as Visual C++ doesn't use different names for Release and Debug builds.

If you need to test for Debug or Release build, you can use:

DEBUG_SOURCES =
INCLUDEPATH += ../zlib
CONFIG(debug, debug|release) {
    DEFINES      += _DEBUG
    DEBUG_SOURCES    = debugimpl.cpp
}

SOURCES +=  $$DEBUG_SOURCES

!isEmpty(DEBUG_SOURCES) {
    !contains(CONFIG, zlib):LIBS += -L../zlib/Debug zlib1.lib
} else {
    !contains(CONFIG, zlib):LIBS += -L../zlib/Release zlib1.lib
}

Replace debugimpl.cpp with any filename(s) in your project that are only used for debug builds. You also need to remove debug from line CONFIG -= qt debug in zlib.pro.