【问题标题】:Should I supply external libraries with a CMakeLists.txt or supply find_packages instead?我应该为外部库提供 CMakeLists.txt 还是提供 find_packages ?
【发布时间】:2022-01-23 03:43:58
【问题描述】:

我正在做一个需要一些外部库的项目。由于它是跨平台的,所以我使用的是 cmake。

分发此类项目时首选的方式是什么?我应该为外部库(例如 zlib)提供它们自己的 CMakeLists.txt,还是应该通过简单地提供 find_packages() 来表示依赖关系?

前者提供了所有需要的东西。而后者让开发人员决定如何提供依赖项(例如 vcpkg)

【问题讨论】:

  • “分发此类项目时首选的方式是什么?” - 没有普遍首选的方法。是否由您决定,是否将外部库构建为项目的一部分(从而为它们提供CMakeLists.txt)或使用find_package 来定位该库。我见过一个项目,它支持这两种方法并让用户在它们之间进行选择。
  • 请注意,“提供外部库”可能对您有一些法律义务,如果这完全合法的话。您应该明确地查阅这些项目的许可证。如果您能够可靠地使find_package 工作,使用此选项是最简单的,但如果这在所有目标系统上都不可能或不可能,您可以使用the FetchContent module 作为后备...跨度>

标签: cmake dependencies


【解决方案1】:

尽管没有普遍首选的方法,我绝对相信你应该坚持find_package。像这样声明你的依赖:

find_package(Pkg [version] REQUIRED [components])

仅当您知道Pkg 本身提供第一方CMake 包配置文件时才包含[version][components]。如果您正在编写和分发库,您将在您的 MyProjConfig.cmake 文件中包含等效的 find_dependency 调用。

如果某些依赖项没有标准的 CMake 查找模块或提供自己的 CMake 包配置文件,则应在./cmake 中编写自己的并将list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 添加到根CMakeLists.txt,在任何find_package 调用之前.您也将安装您的查找模块,并将相同的添加添加到您的配置文件中的模块路径中。

在 find 模块中,您可以使用任何您想为依赖项创建一些导入目标的方法。在这里使用PkgConfig 是一个好方法。

通过find_package 立即与许多依赖项提供程序一起工作:vcpkg、cmake_paths Conan 生成器、Linux 发行版系统包等等。


这样做的主要替代方法是供应代码,这意味着直接将您的依赖项包含在您的构建中,无论是通过复制/粘贴到您的源代码树、git 子模块,还是通过构建时从 Internet 下载 (@987654335 @)。

用于构建这些的机制最终几乎总是add_subdirectory,它将您的依赖项的 CMake 构建拉入您的。

也许最大的问题是大多数项目的 CMake 代码完全没有准备好以这种方式使用。它可能会践踏您的缓存变量、将无效标志注入您的目标、覆盖您生成的标头等等。整合是一场噩梦。

此外,从软件分发的角度来看,这样做会将您的代码与特定版本的依赖项联系起来,并从可能想要打包您的代码的其他人手中夺走控制权。例如,不允许 Debian 软件包捆绑它们的依赖项...如果 libA 依赖于 libB,那么每个软件包都有自己的软件包。使用find_package,维护者将适当的依赖项注入到您的构建中是微不足道的。如果没有,它通常会涉及一个难以维护的补丁。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 2012-04-03
    • 1970-01-01
    • 2016-04-25
    • 2017-11-02
    • 2018-03-17
    • 2015-02-03
    相关资源
    最近更新 更多