【问题标题】:Create CMake/CPack <Library>Config.cmake for shared library为共享库创建 CMake/CPack <Library>Config.cmake
【发布时间】:2016-12-30 09:31:09
【问题描述】:

我有最简单的 c 库,它使用以下 CMakeLists.txt 构建和打包:

cmake_minimum_required(VERSION 3.5)

project (libfoo C)

add_library(foo SHARED impl.c)
target_link_libraries(foo)
install(TARGETS foo LIBRARY DESTINATION lib/)
install(FILES public_header.h DESTINATION include/libfoo)

set(CPACK_GENERATOR "TGZ")
include(CPack)

工作示例位于此处:https://github.com/bjarkef/cmake-simple/tree/master/libfoo

我执行mkdir -p build; (cd build/; cmake ../; make all package;) 来构建一个.tar.gz 包,其中包含已编译的共享库及其公共头文件。这一切都很好。

现在我想修改 CMakeLists.txt 以在不同的项目中创建 CMake find_package 所需的 FooConfig.cmakeFooConfigVersion.cmake 文件以查找 foo 库。我该怎么做?

我发现我应该使用CMakePackageConfigHelpers:configure_package_config_filewrite_basic_package_version_file,我应该创建一个FooLibraryConfig.cmake.in 文件。但是我不知道如何将它们放在一起。

请注意,生成的 .cmake 文件仅包含相对路径,这一点很重要。

【问题讨论】:

    标签: cmake shared-libraries


    【解决方案1】:

    我在顶层 CmakeList.txt 中包含了 cmake 模块:

    # Generate and install package config files
    include(PackageConfigInstall)
    

    在通用 PackageConfigInstall.cmake 文件中,配置文件是从 cmake.in 文件创建并安装的。这个模块可以被其他包重用。

    include(CMakePackageConfigHelpers)
    
    # Generate package config cmake files
    set(${PACKAGE_NAME}_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${PACKAGE_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX})
    
    configure_package_config_file(${PACKAGE_NAME}-config.cmake.in 
       ${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_NAME}-config.cmake 
       INSTALL_DESTINATION ${CMAKE_INSTALL_DIR}/${PACKAGE_NAME}
       PATH_VARS LIB_INSTALL_DIR INCLUDE_INSTALL_DIR APP_INCLUDE_INSTALL_DIR )
    
    configure_file(${PACKAGE_NAME}-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_NAME}-config-version.cmake @ONLY)
    
    # Install package config cmake files
    install(
        FILES
            ${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_NAME}-config.cmake
            ${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_NAME}-config-version.cmake
        DESTINATION
            ${CMAKE_INSTALL_DIR}/${PACKAGE_NAME}
        COMPONENT
            devel
    )
    

    您需要为您的库提供一个包文件,例如 your_lib-config.cmake.in,它将成为 your_lib-config.cmake。这将包含可以使用的包含变量和库变量。

    get_filename_component(YOUR_LIB_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
    
    # flag required by CMakePackageConfigHelpers
    @PACKAGE_INIT@
    
    set_and_check(YOUR_LIB_INCLUDE_DIR @PACKAGE_YOUR_LIB_INCLUDE_INSTALL_DIR@/hal)
    set_and_check(YOUR_LIB_LIBRARY @PACKAGE_LIB_INSTALL_DIR@/@CMAKE_STATIC_LIBRARY_PREFIX@@PROJECT_NAME_LIB@@CMAKE_STATIC_LIBRARY_SUFFIX@)
    set_and_check(YOUR_LIB_LIBRARIES @PACKAGE_LIB_INSTALL_DIR@/@CMAKE_STATIC_LIBRARY_PREFIX@@PROJECT_NAME_LIB@@CMAKE_STATIC_LIBRARY_SUFFIX@)
    

    您还需要一个像这样的 config-version.cmake.in 文件:

    set(PACKAGE_VERSION @PACKAGE_VERSION@)
    
    # Check whether the requested PACKAGE_FIND_VERSION is compatible
    if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
        set(PACKAGE_VERSION_COMPATIBLE FALSE)
    else()
        set(PACKAGE_VERSION_COMPATIBLE TRUE)
        if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
            set(PACKAGE_VERSION_EXACT TRUE)
        endif()
    endif()
    

    打包脚本需要做很多工作才能使其正常工作。我经历了很多试验和错误,最终得到了适用于不同目标(Linux 服务器和嵌入式目标)的东西。我可能遗漏了一些东西,所以请发表评论,我会更新答案。

    【讨论】:

    • 我无法在赏金到期时间内尝试此操作,因此由于您的彻底回答,我已授予您赏金。当我有时间自己尝试时,我会接受你的回答。谢谢你。 :)
    猜你喜欢
    • 2013-07-04
    • 2021-08-24
    • 2013-02-06
    • 2016-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-04
    • 2016-03-03
    相关资源
    最近更新 更多