Search code examples
boostcmake

Install target dependencies with cmake


I have a project that is supposed to install a static library and all its dependencies. One of these dependencies is boost.

I have something like the following but it doesn't work:

cmake_minimum_required(VERSION 3.9.0)

project(install_test)

find_package(Boost REQUIRED COMPONENTS system)

set(Boost_USE_STATIC_LIBS TRUE)

add_executable(test src/main.cpp)

target_link_libraries(test Boost::boost)

add_dependencies(test Boost::boost)

install(TARGETS test DESTINATION ${CMAKE_INSTALL_LIBDIR})

install(TARGETS Boost::boost DESTINATION ${CMAKE_INSTALL_LIBDIR})

Note: boost can be found, if I remove the latest install statement everything works.

How can do this?


Solution

  • Since the installation is likely to happen to the same machine (on wich your library is to be compiled), and the Boost library is already installed (since it can be found), you should export your library with its dependencies via Config.cmake file. All the dependencies are to be found via find_dependency (I do not think that you want to copy all the boost libraries). It will search for required packages on linking with your installed library.

    ${PROJECT_NAME}Config.cmake.in file

    @PACKAGE_INIT@
    
    include(CMakeFindDependencyMacro)
    
    find_dependency(glad REQUIRED)
    find_dependency(glm REQUIRED)
    
    include("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")
    
    check_required_components(gl_traits)
    

    CMakeLists.txt

    #... define here sources and public headers
    
    add_library(${PROJECT_NAME}
        STATIC
            ${PUBLIC_HEADERS}
    
            ${SOURCES}
        )
    
    set_target_properties(${PROJECT_NAME}
        PROPERTIES
    
            OUTPUT_NAME ${PROJECT_NAME}
            DEBUG_POSTFIX "_d"
    
        )
    
    target_link_libraries(${PROJECT_NAME}
        PUBLIC
            Boost::boost
        )
    
    target_include_directories(${PROJECT_NAME}
        PUBLIC
            $<INSTALL_INTERFACE:${INSTALL_INCLUDEDIR}/${PROJECT_NAME}>
            $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/${PROJECT_NAME}>
    
        PRIVATE
            $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
        )
    
    set(targets_export_name ${PROJECT_NAME}Targets)
    set(project_config ${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake)
    set(version_config ${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake)
    
    include(CMakePackageConfigHelpers)
    
    write_basic_package_version_file(
            ${version_config}
        VERSION
            ${PROJECT_VERSION}
        COMPATIBILITY SameMajorVersion
        )
    
    configure_package_config_file(
            ${PROJECT_SOURCE_DIR}/cmake/${PROJECT_NAME}Config.cmake.in
            ${project_config}
        INSTALL_DESTINATION
            ${INSTALL_CMAKEDIR}
        )
    
    install(TARGETS
            ${PROJECT_NAME}
        EXPORT
            ${targets_export_name}
        ARCHIVE
            DESTINATION ${INSTALL_LIBDIR}
            COMPONENT lib
        LIBRARY
            DESTINATION ${INSTALL_LIBDIR}
            COMPONENT lib
        RUNTIME
            DESTINATION ${INSTALL_BINDIR}
            COMPONENT bin
        )
    
    install(EXPORT
            ${targets_export_name}
        DESTINATION
            ${INSTALL_CMAKEDIR}
        )
    
    install(FILES ${PUBLIC_HEADERS} DESTINATION ${INSTALL_INCLUDEDIR}/${PROJECT_NAME} COMPONENT dev)
    install(FILES 
            ${project_config}
            ${version_config}
        DESTINATION
            ${INSTALL_CMAKEDIR}
        )
    

    If you need to install target's files use $<TARGET_FILE:target_name>