CMake find_package for another library in same project

2.6k views Asked by At

I want to make a builder project that checks out sub-modules and builds them as a group, and I would like to build them in a single pass.

builder
  submod1
  submod2 #depends on submod1 
  submod3 #depends on submod2

For testing I downloaded ZeroMQ and cppzmq as submodules and built both with the cppzmq/demo to confirm they are linkable. I chose them because cppzmq checks for libzmq as a target but the demo only links with a find_package.

cmake_minimum_required(VERSION 3.10)
project(ZMQ_builder)
option(BUILD_TESTS "No tests" OFF)
option(CPPZMQ_BUILD_TESTS "No tests" OFF)
option(BUILD_STATIC "ninja can only build static or shared" OFF)
option(BUILD_SHARED "ninja can only build static or shared" ON)
add_subdirectory(libzmq)
set_property(TARGET libzmq PROPERTY CXX_STANDARD 17)
if (NOT TARGET libzmq AND NOT TARGET libzmq-static)
    message(WARNING "libzmq and libzmq-static don't exist after being created")
endif()
if(NOT TARGET ZeroMQ)
    message(status "ZeroMQ needs an alias") #prints this
    add_library(ZeroMQ ALIAS libzmq)
endif()
if(NOT TARGET ZeroMQ)
    message(WARNING "ZeroMQ Target Still doesn't exist")
endif()
if(NOT ZeroMQ_FOUND)
    message(WARNING "ZeroMQ marked as not found") #prints this warning
    find_package(ZeroMQ)
    #set(ZeroMQ_FOUND true)
endif()
add_subdirectory(cppzmq)
find_package(cppzmq) #dies here
add_subdirectory(cppzmq/demo)

which outputs

ZeroMQ marked as not found .../builder\CMakeLists.txt   28
CMake Warning at ...\builder\CMakeLists.txt:29 (find_package):
  By not providing "FindZeroMQ.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "ZeroMQ", but
  CMake did not find one.

  Could not find a package configuration file provided by "ZeroMQ" with any
  of the following names:

    ZeroMQConfig.cmake
    zeromq-config.cmake

  Add the installation prefix of "ZeroMQ" to CMAKE_PREFIX_PATH or set
  "ZeroMQ_DIR" to a directory containing one of the above files.  If "ZeroMQ"
  provides a separate development package or SDK, be sure it has been
  installed.    ...\builder\CMakeLists.txt  29  
ZeroMQ was NOT found!   .../builder/build/cppzmq/cppzmqConfig.cmake 53  

So the find call ignored the ZeroMQ alias Target (add_library(ZeroMQ ALIAS libzmq)) and also missed ".../builder/build/libzmq/ZeroMQConfig.cmake" despite finding "../builder/build/cppzmq/cppzmqConfig.cmake"

I don't understand why find_package is ignoring the ZeroMQ target that's already in the build? and also why the build can find cppzmqConfig.cmake but not ZeroMQConfig.cmake despite both existing?

1

There are 1 answers

0
Sir Demios On BEST ANSWER

find_package() doesn't actually look at the global targets list, it has its own targets list that only prevents other find calls from refetching

instead of creating an alias target call find_package_handle_standard_args in a Find<>.cmake module for each class

so for this case a Findcppzmq.cmake

include(FindPackageHandleStandardArgs)
find_package(ZeroMQ REQUIRED)
if(TARGET cppzmq)
    find_package_handle_standard_args(cppzmq
    REQUIRED_VARS cppzmq_BINARY_DIR)
endif()

and a FindZeroMQ.cmake

include(FindPackageHandleStandardArgs)
if(TARGET ZeroMQ)
    find_package_handle_standard_args(ZeroMQ
    REQUIRED_VARS ZeroMQ_BINARY_DIR)
endif()

alternatively if all the repos in the builder project are seperate you can instead use ExternalProject_Add so that projects will be generated in order at build time. Making an effective package.

cmake_minimum_required(VERSION 3.16)
project(ExternalBuilder)
include(ExternalProject)
set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_LIST_DIR}/install)
set(CMAKE_MODULE_PATH ${CMAKE_INSTALL_PREFIX})
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
ExternalProject_Add(
    ZeroMQ
    GIT_REPOSITORY https://github.com/zeromq/libzmq.git
    GIT_TAG v4.3.2
    CMAKE_ARGS -DCMAKE_MODULE_PATH:PATH=${CMAKE_INSTALL_PREFIX} -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX} -DBUILD_TESTS=OFF -DBUILD_STATIC=OFF
)
ExternalProject_Add(
    cppzmq
    DEPENDS ZeroMQ
    GIT_REPOSITORY https://github.com/zeromq/cppzmq.git
    GIT_TAG v4.7.1
    CMAKE_ARGS -DCMAKE_MODULE_PATH:PATH=${CMAKE_INSTALL_PREFIX} -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX} -DCPPZMQ_BUILD_TESTS=OFF
)
ExternalProject_Add(
    zmqProject
    DEPENDS ZeroMQ
    ...
)