c++cmakecmake-modules

Make an external project available for find_package CMake


In my project I have a dependency "A" that has another library dependency "B", I'm trying to download and install the dependency B before A in order to clear the conflict. I'm using Externalproject_add, FetchContent_Declare and install, but it fails.

for an example

I got a CMakeList.txt like:

FetchContent_Declare(  libpng
        GIT_REPOSITORY      https://github.com/glennrp/libpng.git
        GIT_TAG             master
        UPDATE_DISCONNECTED TRUE
        STEP_TARGETS        update
        )

FetchContent_GetProperties(libpng)
if (NOT libpng_POPULATED)
    FetchContent_Populate(libpng)
    add_subdirectory("${libpng_SOURCE_DIR}" ${libpng_BINARY_DIR} EXCLUDE_FROM_ALL)
endif()

The CMakeList.txt of this libpng has the line find_package(ZLIB REQUIRED) , at this point I could download and install manually the zlib, but since I'm developing a library I would like my code to take care of this dependency. Also I cannot modify the CMakeList.txt of libpng. So, I have this code but it continues to fail.

FetchContent_Declare(  zlib
        GIT_REPOSITORY      https://github.com/zlib-ng/zlib-ng.git
        GIT_TAG             develop
        UPDATE_DISCONNECTED TRUE
        STEP_TARGETS        update
        )
FetchContent_GetProperties(zlib)
if (NOT zlib_POPULATED)
    FetchContent_Populate(zlib)
    add_subdirectory("${zlib_SOURCE_DIR}" ${zlib_BINARY_DIR} EXCLUDE_FROM_ALL)
endif()
install(TARGETS zlib)

I'm still starting with CMake and I continuous learning but it's hard to find proper examples.

So, How can I install a external project in order to make it available for find_package?


Solution

  • well technically you can "modify" the png project by applying a patch.

    Unfortunately FetchContent/add_subdirectory() i.e. incorporating third party as subproject, can't work with find_package().

    You should replace by something like this

    if(NOT TARGET ZLIB::ZLIB)
      find_package(ZLIB)
    endif()
    

    i.e. create a patch an apply it on top of png

      message(CHECK_START "Fetching png")
      list(APPEND CMAKE_MESSAGE_INDENT "  ")
      FetchContent_Declare(
        png
        GIT_REPOSITORY "https://github.com/glennrp/libpng.git"
        GIT_TAG "master"
        PATCH_COMMAND git apply ".../patches/png.patch")
      # here if you want to force some option(s) (must have CMP0077 to NEW)
      #e.g. set(CMAKE_BUILD_SHARED OFF)
      FetchContent_MakeAvailable(png)
      list(POP_BACK CMAKE_MESSAGE_INDENT)
      message(CHECK_PASS "fetched")
    

    CMake related "issue": https://gitlab.kitware.com/cmake/cmake/-/issues/17735

    note: take a look at https://github.com/google/or-tools/blob/master/cmake/dependencies/CMakeLists.txt (sorry no png)

    note2: madler zlib is unmaintained concerning CMake stuff take a look at my patch ;)