Build CMake:配置文件包依赖于查找模块包的推荐方法

Build CMake:配置文件包依赖于查找模块包的推荐方法,build,cmake,Build,Cmake,我刚刚读了关于CMake的配置文件包“概念”的书,听起来很有希望。我非常喜欢它,如果我自己创建一个配置文件包,我可以指定它所依赖的其他包。我的问题是:如何创建一个“可重新定位”的配置文件包,它依赖于Find模块包(例如boost) 更详细地说:假设我想创建一个名为HyDi的包。然后,很好地解释了如何自动创建相应的HydiConfig.cmake和HydiTargets.cmake文件。CMakeLists.txt的一个非常简单的版本可以做到这一点: project(HyDi) find_pac

我刚刚读了关于CMake的配置文件包“概念”的书,听起来很有希望。我非常喜欢它,如果我自己创建一个配置文件包,我可以指定它所依赖的其他包。我的问题是:如何创建一个“可重新定位”的配置文件包,它依赖于Find模块包(例如boost)

更详细地说:假设我想创建一个名为HyDi的包。然后,很好地解释了如何自动创建相应的HydiConfig.cmake和HydiTargets.cmake文件。CMakeLists.txt的一个非常简单的版本可以做到这一点:

project(HyDi)

find_package(Boost COMPONENTS program_options)
add_library(HyDi foo.cpp foo.hpp)
target_include_directories(HyDi PUBLIC INTERFACE ${Boost_INCLUDE_DIRS})
target_link_libraries(HyDi ${Boost_LIBRARIES})
target_compile_options(HyDi INTERFACE PUBLIC "-std=c++11")


install(TARGETS HyDi EXPORT HyDiTarget
  LIBRARY DESTINATION lib
  ARCHIVE DESTINATION lib
  RUNTIME DESTINATION bin
  INCLUDES DESTINATION include
)

install(FILES foo.hpp DESTINATION include)

configure_file(cmake/HyDiConfig.cmake
  "${CMAKE_CURRENT_BINARY_DIR}/HyDi/HyDiConfig.cmake"
  COPYONLY
)

set(ConfigPackageLocation lib/cmake/HyDi)
install(EXPORT HyDiTarget FILE HyDiTargets.cmake 
    NAMESPACE Upstream:: DESTINATION ${ConfigPackageLocation} )
install(FILES cmake/HyDiConfig.cmake DESTINATION ${ConfigPackageLocation})
相应的HydiConfig.cmake为:

include(CMakeFindDependencyMacro)
find_dependency(Boost COMPONENTS program_options)

include("${CMAKE_CURRENT_LIST_DIR}/HyDiTargets.cmake")
但是,如果安装此库,HyDiTargets.cmake文件将包含硬编码的Boost库的include路径,因此无法重新定位

注意,给出了一个示例,说明了如何不包括本质上是我的版本的boost库。但不幸的是,他们没有解释如何做得更好


我知道我可以使用cmake构建boost,然后将boost作为配置文件包导入,这样我的HydiTargets.cmake就可以重新定位。但这种方法并不适用于提供Findxxx.cmake文件的所有其他库

实际上,当注入一个“硬编码”路径来增强库时(而您做得不对),可以正确地执行此操作。因为在编译并安装了库之后,它应该与特定的boost版本(在编译库时)进行“链接”——即它的头文件和静态/动态库

考虑场景:成功安装库后,有人并行安装新版本的boost库(或您依赖的任何其他第三方库)(是的,boost和其他一些库可以在相同的安装前缀中共存)。为了使事情看起来像一个真实世界的例子,假设它与以前的版本ABI不兼容。现在,如果那个“幸运”的开发人员想要使用您的(已经编译和安装的)库(使用导出的目标和提供的
HyDiConfig.cmake
),他会遇到麻烦:

  • 您的库已经链接到“以前的”boost版本(请记住ABI不兼容和更新的版本)
  • 因此,当您以某种方式替换“硬编码”路径并找到一个更新的版本时(正如您在
    HyDiConfig.cmake
    中尝试的那样),您的“幸运”客户会为您的混乱而生气
这不仅仅是关于boost…对于所有第三方库都是相同的策略:它们应该与编译时保持相同(或者如果我们谈论的是运行时的动态链接,那么至少是ABI兼容的,但这是一个单独的故事)

此外,您的用户甚至可能不在其应用程序中使用boost(但安装了多个版本)——为什么要查找smth?您已经知道(多亏了CMake和硬编码路径)您的库需要什么boost版本!因此,在这种情况下,找到smth new是完全错误的!“太晚了…您的库已经编译、链接和安装了!


另一个例子:他想使用其他(较新)版本的boost…这取决于
find_-package(boost)
find_-package(yourLib)
的顺序,结果可能会有所不同…但他无论如何都会对你生气的!

谢谢ruslo,但这个解决方案本质上意味着我必须使用cmake构建boost(这仍然是实验性的)好的,我只是再次看了一下hunter,是的,对于boost来说这是一个选项。但是我不知道如何为我的其他七个外部库获得一个cmake包(配置模式)(除非hunter中存在一个包)。此外,我希望尽可能避免使用第三方cmake工具。非常有趣的问题,我面临着同样的问题。您是否提出了解决方案?不幸的是,我至今尚未找到令人满意的解决方案。但我也从大约2年来没有详细研究过该问题。。。