Dependency of dependency not being found when using CMake

I am trying to make a library for educational purposes and the current structure is as follows,

📁client
    📁 src
        client.cpp
    CMakeLists.txt
📁 youtube_searcher_library
    📁include
    📁 src
        youtube_searcher_utilities.hpp
        youtube_search.cpp
    CMakeLists.txt

My youtube_search.cpp uses Boost.regex, but I have problems trying to only import the regex module so for now I imported the whole of Boost. The CMakeLists.txt for youtube_searcher_library is as follows,

cmake_minimum_required(VERSION 3.27)

project(youtube_searcher VERSION 1.0.0)

find_package(Boost REQUIRED)

add_library(youtube_searcher STATIC src/youtube_searcher.cpp)

target_link_libraries(youtube_searcher
    PUBLIC
        Boost::boost)

target_include_directories(youtube_searcher
    PUBLIC
        $<INSTALL_INTERFACE:include>                      
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/src
)

install(TARGETS youtube_searcher
    EXPORT youtube_searcherConfig
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

install(EXPORT youtube_searcherConfig
    FILE youtube_searcherTargets.cmake
    NAMESPACE youtube_searcher::
    DESTINATION ${CMAKE_INSTALL_DATADIR}/youtube_searcher/cmake
)

export(TARGETS youtube_searcher
    NAMESPACE youtube_searcher::
    FILE ${CMAKE_CURRENT_BINARY_DIR}/share/cmake/youtube_searcherConfig.cmake
)

My client CMakeLists.txt is as follows,

cmake_minimum_required(VERSION 3.27)

project(client VERSION 1.0.0)

find_package(youtube_searcher REQUIRED)

add_executable(client src/client.cpp)

target_link_libraries(client
    youtube_searcher::youtube_searcher
)

Although I got this to link I receive the following error when trying to run it,

  The link interface of target "youtube_searcher::youtube_searcher" contains:

    Boost::boost

  but the target was not found.  Possible reasons include:

    * There is a typo in the target name.
    * A find_package call is missing for an IMPORTED target.
    * An ALIAS target is missing.

Call Stack (most recent call first):
  CMakeLists.txt:5 (find_package)

It seems that the dependency of my dependency is not in here. Although I thought it would be found when I swapped PRIVATE to PUBLIC in,

target_link_libraries(youtube_searcher
    PUBLIC
        Boost::boost)

Although it’s statically linked so I expected BOOST to be inside my .lib. I don’t understand why it would not be working.

You have to:

  • export targets in a file youtube_searcherTargets.cmake (file name doesn’t really matter) instead of youtube_searcherConfig.cmake.
  • maintain a custom youtube_searcherConfig.cmake which will rely on find_dependency() from CMakeFindDependencyMacro to discover Boost, and include youtube_searcherTargets.cmake.

Regarding Boost regex, you should link Boost::regex instead of Boost::boost (it’s worth noting that Boost::boost doesn’t drag all boost libraries, but only public headers)

project tree:

cmake/
  youtube_searcherConfig.cmake.in
include/
  youtube_searcher.h
src/
  youtube_searcher.cpp
  youtube_searcher_utilities.hpp
CMakeLists.txt

CMakeLists.txt:

cmake_minimum_required(VERSION 3.27)
project(youtube_searcher VERSION 1.0.0)

include(CMakePackageConfigHelpers)
include(GNUInstallDirs)

find_package(Boost REQUIRED regex)

add_library(youtube_searcher STATIC src/youtube_searcher.cpp)

target_link_libraries(youtube_searcher PRIVATE Boost::regex)

target_include_directories(youtube_searcher
    PUBLIC                      
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/src
)

# Installation of binaries & headers

install(TARGETS youtube_searcher
    EXPORT youtube_searcherExport
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

install(
    DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/
    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

# Installation of CMake config file

configure_package_config_file(
    ${CMAKE_CURRENT_SOURCE_DIR}/cmake/youtube_searcherConfig.cmake.in
    youtube_searcherConfig.cmake
    INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/youtube_searcher
)

write_basic_package_version_file(
    youtube_searcherConfigVersion.cmake
    VERSION ${PROJECT_VERSION}
    COMPATIBILITY AnyNewerVersion
)

install(
    EXPORT youtube_searcherExport
    NAMESPACE youtube_searcher::
    FILE youtube_searcherTargets.cmake
    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/youtube_searcher
)

install(
    FILES
        ${CMAKE_CURRENT_BINARY_DIR}/youtube_searcherConfig.cmake
        ${CMAKE_CURRENT_BINARY_DIR}/youtube_searcherConfigVersion.cmake
    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/youtube_searcher
)

# Optional: if you want consumers to be able to consume your library from build tree of youtube_searcher
export(
    EXPORT youtube_searcherExport
    NAMESPACE youtube_searcher::
    FILE youtube_searcherTargets.cmake
)

youtube_searcherConfig.cmake.in:

@PACKAGE_INIT@

include(CMakeFindDependencyMacro)
find_dependency(Boost)

include("${CMAKE_CURRENT_LIST_DIR}/youtube_searcherTargets.cmake")

See also:

Leave a Comment