[CMake] Finding Zlib on Windows

Leo Breebaart leo at lspace.org
Thu Sep 11 04:28:32 EDT 2008


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  <leo at lspace.org>



More information about the CMake mailing list