Discussion:
[CMake] Finding Zlib on Windows
Leo Breebaart
2008-09-11 08:28:32 UTC
Permalink
I am having a heck of a time correctly detecting Zlib (and other
libraries) properly on Windows.

Being a newcomer to both CMake and the wonderful world of Windows
.dll and .lib files I fully expect that I am getting things wrong
left and right, and I am hoping people here are willing to help a
newbie along.

The goal:

I want to build a library that itself depends on Zlib, and I want
to build this library in both shared and static variants.

The Zlib I want to use is a self-compiled version of the standard
www.zlib.net v1.2.3 release, and it can be located anywhere on
the system.

I would like to keep my solution as generic as I can, and not
just hardcode paths that work on *my* setup.


The problems:

(1) On Windows, FindPackage(ZLIB) does not work because Zlib can
be anywhere. So I wrote the following CMakeLists fragment in
order to either accept a ZLIB_DIR location from the cmake command
line, or from an environment variable, and use that to tweak the
paths for FindPackage:

IF (NOT ZLIB_DIR)
IF ($ENV{ZLIB_DIR} MATCHES ".+")
FILE(TO_CMAKE_PATH $ENV{ZLIB_DIR} ZLIB_DIR)
MESSAGE(STATUS "ZLIB_DIR from environment: ${ZLIB_DIR}")
ENDIF ($ENV{ZLIB_DIR} MATCHES ".+")
ENDIF (NOT ZLIB_DIR)

SET(CMAKE_INCLUDE_PATH ${ZLIB_DIR}/include ${CMAKE_INCLUDE_PATH})
SET(CMAKE_LIBRARY_PATH ${ZLIB_DIR}/dll ${ZLIB_DIR}/lib ${CMAKE_LIBRARY_PATH})

FIND_PACKAGE(ZLIB REQUIRED)
IF (ZLIB_FOUND)
MESSAGE(STATUS "Cmake FindZLIB: using ZLIB includes at: ${ZLIB_INCLUDE_DIR}")
MESSAGE(STATUS "Cmake FindZLIB: using ZLIB libraries: ${ZLIB_LIBRARIES}")
ENDIF (ZLIB_FOUND)

First question: is this at all the right 'CMake-ish' kind of
thing to do?

The output I get from this is:

-- ZLIB_DIR from environment: C:/zlib
-- Cmake FindZLIB: using ZLIB includes at: C:/zlib/include
-- Cmake FindZLIB: using ZLIB libraries: C:/zlib/lib/zlib.lib


(2) Next, I build my libraries:

INCLUDE_DIRECTORIES(
${ZLIB_INCLUDE_DIR}
)

ADD_LIBRARY(foo SHARED ${LIBFOO_SOURCES})
TARGET_LINK_LIBRARIES(foo ${ZLIB_LIBRARIES})
SET_TARGET_PROPERTIES(foo PROPERTIES
VERSION 0.0.0
SOVERSION 0
)

ADD_LIBRARY(foo-static STATIC ${LIBFOO_SOURCES})
TARGET_LINK_LIBRARIES(foo-static ${ZLIB_LIBRARIES})
SET_TARGET_PROPERTIES(foo-static PROPERTIES
OUTPUT_NAME "foo"
)

Second question: this does not work, because it now always uses
'lib/zlib.lib'. However, that is only necessary for the static
library. For the shared library, I need to link against
dll/zlib1.lib.

If my understanding is correct, what is the best CMake way to
address this issue? Not just for Zlib, but in general: how should
I ensure that appropriate libraries are used for static vs.
shared targets? It seems that FindPackage will always just find
"the first" one. Or am I missing something?

Many thanks in advance,
--
Leo Breebaart <***@lspace.org>
Alexander Neundorf
2008-09-30 22:15:35 UTC
Permalink
Post by Leo Breebaart
I am having a heck of a time correctly detecting Zlib (and other
libraries) properly on Windows.
Being a newcomer to both CMake and the wonderful world of Windows
.dll and .lib files I fully expect that I am getting things wrong
left and right, and I am hoping people here are willing to help a
newbie along.
I want to build a library that itself depends on Zlib, and I want
to build this library in both shared and static variants.
The Zlib I want to use is a self-compiled version of the standard
www.zlib.net v1.2.3 release, and it can be located anywhere on
the system.
I would like to keep my solution as generic as I can, and not
just hardcode paths that work on *my* setup.
(1) On Windows, FindPackage(ZLIB) does not work because Zlib can
be anywhere. So I wrote the following CMakeLists fragment in
order to either accept a ZLIB_DIR location from the cmake command
line, or from an environment variable, and use that to tweak the
I would recommend not to add environment variables for that.
With cmake >= 2.6.0 you can set CMAKE_PREFIX_PATH to a list of custom
directories where cmake should search. Add the install location of your zlib
to it, then it should work.
I would also suggest not to use a dll/ subdir.
Just go with lib/.
Then you also don't have to modify CMAKE_INCLUDE_PATH and CMAKE_LIBRARY_PATH
anymore.

Alex

Loading...