我在我的文章中对此做了很多解释SciPy 2014 演讲 https://www.youtube.com/watch?v=UaIvrDWrIWM。让我在这里给出一个简单的概述。
首先,conda 包非常简单。它只是要安装的文件的 tarball,以及一些元数据info
目录。例如 conda 包python
是文件的 tarball
info/
files
index.json
...
bin/
python
...
lib/
libpython.so
python2.7/
...
...
...
通过查看 Anaconda 中提取的包,您可以准确地看到它的样子pkgs
目录。完整规格位于https://docs.conda.io/projects/conda-build/en/latest/source/package-spec.html https://docs.conda.io/projects/conda-build/en/latest/source/package-spec.html.
当 conda 安装它时,它将 tarball 解压到pkgs
目录并将文件硬链接到安装环境中。最后,一些具有硬编码安装路径的文件已被替换(通常是 shebang 行)。
基本上就是这样。在依赖关系解析方面还发生了一些事情,但是一旦它知道要安装哪些包,它就会这样做。
构建包的过程稍微复杂一些。 @mattexx 的答案及其链接的文档描述了使用 conda build 构建包的一些规范方法。
回答您的其他问题:
此外,由于它与 python 无关并且显然工作得如此良好和流畅,为什么它不被用作像 apt 或 yum 这样的通用包管理器呢?
你当然可以。唯一限制这一点的是为 conda 构建的软件包集。在 Windows 上,这是一个非常好的选择,因为没有像 Linux 上那样的系统包管理器。
仅使用 conda 作为包管理器有哪些限制?会起作用吗?
假设您有您感兴趣的所有内容的 conda 软件包,它会起作用。主要限制是 conda 只想将内容安装到 conda 环境本身中,因此需要系统上特定安装位置的内容可能不太适合 conda (尽管它仍然可行,但如果您将该位置设置为环境路径)。或者例如,conda 可能不适合替代像 Bower 这样的“项目级”包管理器。
另外,conda 可能不应该用于管理系统级库(必须安装在/
前缀),如内核扩展或内核本身,除非您要构建明确使用 conda 作为包管理器的发行版。
关于这些事情我要说的主要事情是 conda 包通常被制作成可重新定位的,这意味着包的安装前缀并不重要。例如,这就是为什么在安装过程中更改硬编码路径的原因。这也意味着使用 conda build 构建的动态库将自动更改其 RPATH(在 Linux 上)和安装名称(在 OS X 上)以使用相对路径而不是绝对路径。
或者反过来,为什么例如apt 和 yum 无法提供 conda 提供的功能? conda 比那些包管理器“更好”还是只是不同?
在某些方面它更好,而在某些方面则不然。你的系统包管理器了解你的系统,并且其中有一些包不会出现在 conda 中(还有一些包,比如内核,可能不应该出现在 conda 中)。
conda 的主要优点是它的环境概念。由于软件包是可重定位的,因此您可以在多个位置安装相同的软件包,并有效地完全独立地安装所有内容,基本上是免费的。
它是否使用某种容器化
不,唯一的“容器化”是拥有单独的安装目录并使包可重新定位。
或所有依赖项的静态链接,
依赖关系链接完全取决于包本身。有些包静态链接它们的依赖项,有些则不然。正如我上面描述的那样,动态链接库的加载路径已更改为可重定位。
为什么它如此“跨平台”?
这里的“跨平台”意味着“跨操作系统”。尽管同一个二进制包无法跨 OS X、Linux 和 Windows 运行,但关键是 conda 本身在这三个平台上的工作方式相同,因此如果您为所有三个平台构建了相同的包,则可以以相同的方式管理它们无论您使用哪一种方式。