Language/Platform/Build-Independent 依赖管理器

Language/Platform/Build-Independent Dependency Manager

我需要一个不依赖于特定语言或构建系统的依赖管理器。我研究了几个优秀的工具(Gradle、Bazel、Hunter、Biicode、Conan 等),但 none 满足我的要求(见下文)。我还使用了 Git 子模块和 Mercurial Subrepos。

Daniel Pfeifer 在 Meeting C++ 2014 的 presentation 中详细描述了我的需求。总结此依赖项工具的目标(在链接视频的@18:55 讨论):

我要补充的进一步要求或说明:

很高兴:

在彻底搜索可用技术、与各种语言(即 npm)的包管理器进行比较,甚至在我自己的依赖管理器工具中有一个 运行 之后,我选择了 Conan。在深入研究柯南之后,我发现它开箱即用地满足了我的大部分要求,并且易于扩展。

在研究柯南之前,我将 BitBake 视为我正在寻找的模型。然而,它只是 linux 并且主要面向嵌入式 linux 发行版。柯南具有与 bb 基本相同的配方功能,并且是真正的跨平台

以下是我的要求以及我在柯南中发现的内容:

  • Not just a package manager
  • Supports pre-built or source dependencies

Conan 支持经典的发布或开发依赖项,还允许您打包源代码。如果具有特定 configurations/settings 的二进制文件不存在于注册表中(或 "repository",用柯南的说法),将从源构建二进制文件。

  • Can download or find locally - no unnecessary downloads
  • Integrated with the system installer - can check if lib is installed

柯南维护一个本地注册表作为缓存。因此,碰巧共享依赖项的独立项目不需要重做昂贵的下载和构建。

Conan 不会阻止您查找系统包而不是声明的依赖项。如果您编写要传递前缀路径的构建脚本,则可以动态更改各个依赖项的路径。

  • Fetches using a variety of methods (i.e. download, or VCS clones, etc.)

实施配方的 source 函数可以完全控制如何获取依赖项。 Conan 支持 download/clone 来源的食谱,或者可以 "snapshot" 来源,将其与食谱本身打包。

  • No need to adapt source code in any way
  • No need to adapt the build system

Conan 支持各种生成器,使您选择的构建系统可以使用依赖项。对特定构建系统的不可知论是 Conan 的真正胜利,也是最终导致 Bazel、Buckaroo 等依赖管理变得繁琐的原因。

  • Cross-platform Python. Check.

  • Suitable for third-party and/or versioned dependencies, but also capable of specifying non-versioned and/or co-developed dependencies (probably specified by a git/mercurial hash or tag).

构建时考虑了 semver,但可以使用任何字符串标识符作为版本。另外还有 userchannel 作为包版本的命名空间。

  • Provides a mechanism to override the specified fetching behavior to use some alternate dependency version of my choosing.

您可以通过不将特定依赖项包含在 install 命令中来阻止获取特定依赖项。或者您可以修改或覆盖生成的前缀信息以指向磁盘上的不同位置。

  • No need to manually set up a dependency store. I'm not opposed to a central dependency location as a way to avoid redundant or circular dependencies. However, we need the simplicity of cloning a repo and executing some top-level build script that invokes the dependency manager and builds everything. Despite the requirement that I should not have to modify my build system, obviously some top-level build must wield the dependency manager and then feed those dependencies to the individual builds. The requirement means that the individual builds should not be aware of the dependency manager. For example, if using CMake for a C++ package, I should not need to modify its CMakeLists.txt to make special functional calls to locate dependencies. Rather, the top-level build manager should invoke the dependency manager to retrieve the dependencies and then provide arguments CMake can consume in traditional ways (i.e find_package or add_subdirectory). In other words, I should always have the option of manually doing the work of the top-level build and dependency manager and the individual build should not know the difference.

Conan 在本地注册表中缓存依赖项。这是无缝的。您将在柯南文档中看到的规范模式是在您的构建脚本中添加一些特定于柯南的调用,但这是可以避免的。再一次,如果您将构建脚本写入消费者前缀路径 and/or 输入参数,您可以传递信息而根本不使用柯南。我认为 Conan CMake 生成器可以使用一些工作来使它更优雅。作为后备,Conan 让我编写自己的生成器。

  • A way to interrogate the dependency manager after-the-fact to find where a dependency was placed. This would allow me to create VCS hooks to automatically update the hash in dependency metadata of co-developed source repo dependencies. (Like submodules or subrepos do).

生成器指向这些位置。借助 Python 的全部功能,您可以根据自己的喜好对其进行自定义。

目前合作开发依赖项目对我来说是最大的问号。意思是,我不知道 Conan 是否有开箱即用的东西来使跟踪提交变得容易,但我相信钩子在那里可以添加这种定制。

我在柯南中发现的其他东西:

  • Conan 提供了下载或构建我在开发过程中需要的工具链的功能。它使用 Python virtualenv 使 enabling/disabling 这些自定义环境变得简单,而不会污染我的系统安装。