4

我正在更新一个(非常旧的)库的查找模块。所以情况是一个现有的共享库,它使用 CMake 本身。用户可能已经将它安装在某个地方,在包 repos 或其他地方。

现在他们想用这个。好的方法是

find_package(Foo REQUIRED)
target_link_libraries(MyProject Foo::Foo)

所以这就是目标。

问题是:一个好的 find_package-Config 或 -Module 看起来如何允许这个 2-liner 工作?它应该满足这两个要求:

  • 允许 CMake 版本使用比用于构建它的库更旧的库
  • 强制执行例如 C++11 模式。在 Find-Module 中,可以根据版本(cxx_std_11(CMake 3.8+)、cxx_alias_templates(CMake 3.1+),check_cxx_source_compiles使用 C++11 代码和对旧 CMake 的警告)设置 C++11 要求

有两种方法可以做到这一点:

  1. 更新 find-module 以定义一个导入的库Foo::Foo并正确设置它(使用属性)并且很高兴也为旧的 CMake w/o 目标设置FOO_INCLUDE_DIR和设置。 这很简单:只需使用and ,设置导入的目标即可。向前和向后兼容,因此即使是旧版本也能找到。FOO_LIBRARIES
    find_pathfind_library

用法:
用户将其项目复制(最新)FindFoo.cmake到 egcmake/Modules并指向CMAKE_MODULE_PATH它,或复制FindFoo.cmake到某些 CMake 默认路径。

  1. Daniel PfeifferModern CMakeIf you are the library author, don't make a Find<mypackage>.cmake script!所以我们导出和安装目标。
    这有点乱。需要进行以下更改:

    • Add EXPORTS FooTargetsand INCLUDES DESTINATION includeto install(TARGETS(参见 Pfeiffer #24),它基本上只是定义了一个导出。(我真的不明白,为什么我要为已经有名字的东西创建一个额外的名字。为什么下面的命令不能简单地引用一个目标?)
    • 添加install(EXPORT FooTargets NAMESPACE Foo:: DESTINATION lib/cmake/Foo)它会创建一个FooTargets.cmakein<CMAKE_INSTALL_PREFIX>/lib/cmake/Foo定义一个Foo::Foo具有(希望)其所有依赖项的目标
    • 根据我的理解,FooConfigVersion.cmake可能通过使用它来添加“某物” ,将版本硬编码到该文件write_basic_package_version_file
    • 创建一个FooConfig.cmake可用于find_dependency搜索 Foo 依赖并包含的库的FooTargets.cmake
    • 安装FooConfig.cmakeFooConfigVersion.cmake_lib/cmake/Foo
    • 修改target_include_directories为使用单独的BUILD_INTERFACEINSTALL_INTERFACE路径

用法:
find_package自动查找FooConfig.cmakeFooConfigVersion.cmake何时Foo搜索。

所以应该首选配置模块,但我看到的问题是:

  • 过程看起来更复杂
  • 它不能用于使用户能够找到旧版本的库(没有使用这种方法)
  • 它不包括所有使用旧 CMake 的(库)用户(2.8.11 可能是这里所需的最低要求)
  • 它需要更新的 CMake 版本来构建库本身
  • C++11 的要求似乎很难编码

那么我们可以用 CMake-Config 解决需求吗?答案应该提供一个解决方案,或者至少是一个有充分根据的“不可能”。它还应该解决最后概述的问题。

最后说明:如果它不存在,我想这是一个很好的 wiki 条目。

4

0 回答 0