Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake: wrong zlib found - how to build zlib from src (with main project CMakeLists.txt) and link it?

// brief version

How can I make CMake to use my supplied zlib (which it also has to build from source) instead of the one found by the finder without breaking the finder for other libs (OpenGL)?

ZLib needs to be used by the main project and also libPNG which comes as source as well.

Primary target platform is Windows.

// longer version:

In my project I need to link against libpng, zlib and OpenGL. With libpng being dependent on zlib. But zlib is also required by the main project.

I need to supply sourcecode for all libs except OpenGL, and build those libraries along with the main project to assert linking the correct version and simplify building on Windows.

I found ways to do all this with custom libraries where no built-in finder exists, but I can't override the finder properly for just zlib. If I change the search path for libs, then OpenGL is not found.

However I can't get cmake to use my supplied zlib instead of a rouge zlib.DLL that the package finder finds somewhere in my system. (The one from tortoise git)

I tried to set ZLIB_LIBRARY to a specific filepath, but that only works on MinGW, and I also think this is not the way to do it.

(And also I had to explicitly link to png16_static instead of just libpng, for an inexplicable reason.)

Any help on this is much appreciated. Maybe I'm taking this on the wrong way?


Target&Development Platform:

Windows7
Visual Studio 2010
and MinGW (both need to work)

My (simplified example) CMakeLists.txt:

cmake_minimum_required (VERSION 2.6)

project (MyProject)

  find_package(OpenGL)

  add_executable(MyProject main.cpp)

  include_directories(${INCLUDE_DIRECTORIES} "${PROJECT_BINARY_DIR}")

  include_directories(${INCLUDE_DIRECTORIES} "external_libs/lpng162")

  include_directories(${INCLUDE_DIRECTORIES} "external_libs/zlib-1.2.8")

  include_directories(${INCLUDE_DIRECTORIES} "${PROJECT_BINARY_DIR}/external_libs/zlib-1.2.8")

  add_subdirectory("external_libs/zlib-1.2.8")
  link_directories(${LINK_DIRECTORIES} "${PROJECT_BINARY_DIR}/external_libs/zlib-1.2.8")

  # libpng will not build correctly if this not set
  set (ZLIB_ROOT "${PROJECT_SOURCE_DIR}/external_libs/zlib-1.2.8")

  # manually set this to prevent cmake from finding the tortiose-git zlib.dll first
  # DOES NOT WORK CORRECTLY, only with mingw32
  set (ZLIB_LIBRARY "${PROJECT_BINARY_DIR}/external_libs/zlib-1.2.8/libzlib.dll")

  add_subdirectory("external_libs/lpng162")

  TARGET_LINK_LIBRARIES(MyProject png16_static zlib ${OPENGL_LIBRARY})

Project (simplified example) structure:

./main.cpp
./CMakeLists.txt
./external_libs/zlib-1.2.8/ <- contains respective source
./external_libs/lpng162/    <- contains respective source
like image 963
Rock Avatar asked Jul 17 '13 11:07

Rock


1 Answers

Third-party libraries most likely call FindZLIB.cmake to determine the location of CMake. You already had the right idea by setting the ZLIB_LIBRARY manually, but were not quite getting it right:

add_subdirectory(<path_to_zlib_src_dir>)

set(ZLIB_INCLUDE_DIR  "<path_to_zlib_src_dir>" "${CMAKE_BINARY_DIR}/<path_to_zlib_build_dir>")
set(ZLIB_LIBRARY zlib)

add_subdirectory(<path_to_lpng_src_dir>)    
  • The include directory needs to contain both src and build path as zconf.h is build by CMake
  • The library name is only the CMake-target name, not the complete path to the resulting file.
  • On Windows dlls are not automatically copied by CMake. You might want to add some additional code to make sure that the zlib and lpng dlls end up in the right place.
  • You can call find_package(zlib) yourself to make sure it behaves as expected
  • In the rare case that a third-party lib does not use the find script, you will have to dig into that project's CMakeLists to find out what is going on
like image 172
ComicSansMS Avatar answered Sep 28 '22 02:09

ComicSansMS