如何使用"现代" CMake在现有库的上下文中导出目标

时间:2018-03-13 15:31:08

标签: module cmake cmake-modules

我正在更新库的(非常旧的)查找模块。所以情况是使用CMake本身的现有共享库。用户可能已经安装了这个地方,包裹寄存处或其他任何地方。

现在他们想要使用它。好方法是

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 ++设置C ++ 11要求11个代码和旧CMakes的警告)

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

  1. 更新find-module以定义导入的库Foo::Foo并正确设置(使用属性),并且还可以为旧的CMake设置FOO_INCLUDE_DIRFOO_LIBRARIES目标。
    这很简单:只需使用find_pathfind_library,设置导入的目标即可完成。向前和向后兼容,因此即使找到旧版本也可以。
  2. 用法:
    用户将(最新的)FindFoo.cmake复制到其项目中,例如cmake/Modules并将CMAKE_MODULE_PATH指向它,或将FindFoo.cmake复制到某个CMake默认路径。

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

      • EXPORTS FooTargetsINCLUDES DESTINATION include添加到install(TARGETS(参见Pfeiffer#24),它基本上只定义了一个导出。 (我真的不明白,为什么我要为已经有名字的东西创建一个额外的名字。为什么以下命令不能简单地引用一个目标?)
      • 添加install(EXPORT FooTargets NAMESPACE Foo:: DESTINATION lib/cmake/Foo),这会在FooTargets.cmake中创建<CMAKE_INSTALL_PREFIX>/lib/cmake/Foo,定义目标Foo::Foo(希望)所有依赖项
      • 添加&#34;某事&#34;可能使用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路径
    2. 用法:
      find_package被搜索时,FooConfig.cmake会自动找到FooConfigVersion.cmakeFoo

      所以Config-Module应该是首选,但我看到的问题是:

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

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

      最后注意:如果它不存在,我想这会成为一个不错的维基词条。

0 个答案:

没有答案