How to use cmake find_package() with a local copy of the package?

I'm trying to make a project that has both ZLIB and LIBPNG (and other libraries). LibPNG's CMakeLists.txt file has this in it: find_package(ZLIB REQUIRED) It's stock code that comes with it and I don't want to change it.

I'm building on Windows (Visual Studio). This is a cross-platform application (Windows, Mac, Linux and Mobile devices) I cannot rely on /usr/lib versions of any libraries. So I'm building them all with my project together.

I can't get LibPNG to build unless I hack this up. In an upper-level CMakeLists.txt file, I put this in there:

ADD_SUBDIRECTORY(contrib/${CUSTOM_ZLIB_LOCATION})
SET(ZLIB_FOUND ON CACHE BOOL "Yes")
SET(ZLIB_INCLUDE_DIR ${CMAKE_BINARY_DIR}/contrib/${CUSTOM_ZLIB_LOCATION} {CMAKE_SOURCE_DIR}/contrib/${CUSTOM_ZLIB_LOCATION})
SET(ZLIB_LIBRARY zlib CACHE STRING "zlib library name")

This satisfies find_package(ZLIB REQUIRED) But I think this is a hack. Is there some straight forward way to build the local copy of zlib without all the 3 extra lines?


Solution 1:

I only added this line at the beginning (at least before find_package(ZLIB REQUIRED)) and it worked for me.

set(ZLIB_ROOT <zlib folder here>)

But others may need doing something like:

if (CMAKE_VERSION VERSION_GREATER 3.12 OR CMAKE_VERSION VERSION_EQUAL 3.12)
  # Enable find_package uses of <PackageName>_ROOT variables.
  cmake_policy(SET CMP0074 NEW)
endif()

set(ZLIB_ROOT <zlib folder here>)

We set the policy to NEW.
The OLD behavior for this policy is to ignore <PackageName>_ROOT variables.

CMake version 3.22.1 warns when the policy is not set (and defaults to OLD behavior).