1

I have a project where I write a library that uses the exiv2 library. exiv2 itself needs zlib. If I don't import zlib as an external project, I get it to work by installing the package zlib1g-dev (on Ubuntu), because then find_package( ZLIB REQUIRED ) from exiv2 will find it.

For reasons of cross-compilation, I cannot use the pre-compiled library from zlib1g-dev. That's why I want to add the zlib source as an external project and a dependency for exiv2 (also an external project). This is how far I got:

CMakeLists.txt of my library:

# Download and unpack zlib at configure time
configure_file(CMakeLists.in.zlib zlib-download/CMakeLists.txt)
execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
    WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/zlib-download"
)
execute_process(COMMAND "${CMAKE_COMMAND}" --build .
    WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/zlib-download"
)
# Add zlib to the build
add_subdirectory("${CMAKE_CURRENT_BINARY_DIR}/zlib-src"
                 "${CMAKE_CURRENT_BINARY_DIR}/zlib-build"
)


# Download and unpack exiv2 at configure time
configure_file(CMakeLists.in.exiv2 exiv2-download/CMakeLists.txt)
execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
    WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/exiv2-download"
)
execute_process(COMMAND "${CMAKE_COMMAND}" --build .
    WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/exiv2-download"
)
# Override options of exiv2
set(EXIV2_BUILD_SAMPLES OFF CACHE BOOL "" FORCE)
set(EXIV2_BUILD_EXIV2_COMMAND OFF CACHE BOOL "" FORCE)
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
set(EXIV2_ENABLE_DYNAMIC_RUNTIME OFF CACHE BOOL "" FORCE)
# Add exiv2 to the build
add_subdirectory("${CMAKE_CURRENT_BINARY_DIR}/exiv2-src"
                 "${CMAKE_CURRENT_BINARY_DIR}/exiv2-build"
)

add_library(mylibrary mylibrary.cpp)
target_link_libraries(mylibrary exiv2lib)

Where CMakeLists.in.zlib is:

cmake_minimum_required(VERSION 2.8.2)

project(zlib-download NONE)

include(ExternalProject)
ExternalProject_Add(zlib
  GIT_REPOSITORY    https://github.com/madler/zlib.git
  GIT_TAG           master
  SOURCE_DIR        "${CMAKE_CURRENT_BINARY_DIR}/zlib-src"
  BINARY_DIR        "${CMAKE_CURRENT_BINARY_DIR}/zlib-build"
  CONFIGURE_COMMAND ""
  BUILD_COMMAND     ""
  INSTALL_COMMAND   ""
  TEST_COMMAND      ""
)

And CMakeLists.in.exiv2:

cmake_minimum_required(VERSION 2.8.2)

project(exiv2-download NONE)

include(ExternalProject)
ExternalProject_Add(exiv2
  GIT_REPOSITORY    https://github.com/Exiv2/exiv2.git
  GIT_TAG           master
  SOURCE_DIR        "${CMAKE_CURRENT_BINARY_DIR}/exiv2-src"
  BINARY_DIR        "${CMAKE_CURRENT_BINARY_DIR}/exiv2-build"
  CONFIGURE_COMMAND ""
  BUILD_COMMAND     ""
  INSTALL_COMMAND   ""
  TEST_COMMAND      ""
)

But using these CMake files returns an error:

CMake Error at /usr/share/cmake-3.10/Modules/FindPackageHandleStandardArgs.cmake:137 (message):
  Could NOT find ZLIB (missing: ZLIB_LIBRARY ZLIB_INCLUDE_DIR)
Call Stack (most recent call first):
  /usr/share/cmake-3.10/Modules/FindPackageHandleStandardArgs.cmake:378 (_FPHSA_FAILURE_MESSAGE)
  /usr/share/cmake-3.10/Modules/FindZLIB.cmake:112 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
  /tmp/QtCreator-wQKSzo/qtc-cmake-XXbL8ZLF/mylibrary/exiv2-src/cmake/findDependencies.cmake:24 (find_package)
  /tmp/QtCreator-wQKSzo/qtc-cmake-XXbL8ZLF/mylibrary/exiv2-src/CMakeLists.txt:62 (include)

So, how can I make zlib available to exiv2?

stackprotector
  • 10,498
  • 4
  • 35
  • 64
  • I think you will have to install the zlib and then set the ZLIB_DIR variable to be able to use find_package(ZLIB). Or, use find_path() and find_library() to set up your custome ZLIB_INCLUDE_DIR and ZLIB_LIBRARY respectively. – user3389943 Jul 20 '20 at 19:05
  • I would cross compile `zlib` for the target architecture and install it at `/path/to/some/location` and then use `-DCMAKE_PREFIX_PATH=/path/to/some/location` while configuring the CMake build for `exiv2` so that the `find_package(ZLIB)` in `exiv2` picks it up from there. – Nehal J Wani Jul 20 '20 at 20:50
  • Thx at both of you. @NehalJWani I would install it in the out of source build directory then, to not pollute the system. Would that be a good practice? – stackprotector Jul 21 '20 at 04:39
  • 1
    Yes, I think that's a common practice. But also think about this: do you wish to distribute your project? To make it easier, you might want to statically link `zlib`, which means, whatever path you choose to install to, is temporary. *Never* pollute the system. – Nehal J Wani Jul 21 '20 at 11:32

0 Answers0