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

Bja*_*sen 7 cmake shared-libraries

我有最简单的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)
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

jer*_*are 0

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

# Generate and install package config files
include(PackageConfigInstall)
Run Code Online (Sandbox Code Playgroud)

在通用 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
)
Run Code Online (Sandbox Code Playgroud)

您的库需要一个包文件,例如 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@)
Run Code Online (Sandbox Code Playgroud)

您还需要一个像这样的 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()
Run Code Online (Sandbox Code Playgroud)

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