为共享库创建CMake / CPack <library> Config.cmake

时间:2016-08-23 13:51:07

标签: cmake shared-libraries

我有最简单的c-library,使用以下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 FooConfig.cmake所需的FooConfigVersion.cmakefind_package个文件,以查找foo库。我该怎么做?

我发现我应该使用CMakePackageConfigHelpersconfigure_package_config_filewrite_basic_package_version_file,我应该创建一个FooLibraryConfig.cmake.in文件。但是我无法弄清楚如何把它们放在一起。

请注意,生成的.cmake文件只包含相对路径非常重要。

1 个答案:

答案 0 :(得分:0)

我的cmake模块包含在顶级CmakeList.txt中:

# 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。这将包含可以使用的include和library变量。

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服务器和嵌入式目标)的东西。我可能已经遗漏了一些东西,所以请注释,我会更新答案。