使用 find_package(<package_name>) 时如何访问所有库

How to access all libraries when use find_package(<package_name>)

install 多个库和 export 具有相同的名称(在一个组件内)。像下面这样

install(
     TARGETS sip
     EXPORT voip-protocols-config)

install(
     TARGETS rtp
     EXPORT voip-protocols-config)

install(
     EXPORT voip-protocols-config
     NAMESPACE voip)

在 App 端使用 find_package(voip REQUIRED COMPONENTS voip-protocols) 然后访问这些库,但是有办法使用一些符号,如 *Cmake Generator Expression 来列出组件内的所有库吗?

使用这种方法,可以在程序中隐藏库端的详细信息,并将库链接到应用程序,如下所示:

find_package(voip REQUIRED COMPONENTS voip-protocols)
add_executable(${PROJECT_NAME})
target_link_libraries(${PROJECT_NAME} voip::*)

导出目标时(使用 install(TARGETS .. EXPORT))CMake 不会创建额外的“有用”目标。相反,您(作为项目的开发人员)可以自由地显式添加此类目标。

第一种方法 是在项目的 CMakeLists.txt 中创建额外的 INTERFACE 目标并安装它:

# Create "all" library
add_library(voip INTERFACE)
# Link the library with those ones, which you want to represent.
target_link_libraries(voip INTERFACE sip rtp <list other targets here>)
# Install library, so it will be accessible to the user of the package
# via name voip::voip.
install(TARGETS voip
  EXPORT voip-protocols-config)

第二种方法 将向 项目配置脚本 .

添加额外的 INTERFACE IMPORTED 目标

应该注意,提供配置脚本的预期方式是手动编写(或编写其模板并使用configure_package_config_file)。至于CMake生成的脚本install(EXPORT),这些文件可以包含到手写文件中。 CMake 在 documentation.

中描述了该过程

voip-protocols-config.cmake:

# Assume that install(EXPORT) creates file `voip-targets.cmake`
include (${CMAKE_CURRENT_LIST_DIR}/voip-targets.cmake)

# Create "all" library
add_library(voip::voip INTERFACE IMPORTED)
# Link the library with those ones, which you want to represent.
target_link_libraries(voip INTERFACE voip::sip voip::rtp <list other targets here>)

请注意,CMake 不会根据 find_package 的 COMPONENTS 参数自动 select 库。项目的开发人员应该在包配置脚本中处理该参数。 CMake 文档提供了此类处理的示例。