cmakecmake-gui

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.


Solution

  • You have to:

    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: