软件包#

什么是软件包?#

软件包是一个压缩的 tarball 文件 (.tar.bz2) 或 .conda 文件,其中包含

  • 系统级库。

  • Python 或其他模块。

  • 可执行程序和其他组件。

  • info/ 目录下的元数据。

  • 直接安装到 install 前缀的一组文件。

Conda 会跟踪软件包和平台之间的依赖关系。conda 软件包格式在所有平台和操作系统上都是相同的。

只有文件(包括符号链接)是 conda 软件包的一部分。目录不包括在内。目录将在需要时创建和删除,但您不能直接从 tar 存档创建空目录。

.conda 文件格式#

.conda 文件格式是在 conda 4.7 中引入的,作为一种更紧凑、更快的 tarball 替代方案。

.conda 文件格式由一个外部的未压缩 ZIP 格式容器组成,其中包含 2 个内部压缩的 .tar 文件。

对于 .conda 格式的初始内部压缩格式支持,我们选择了 Zstandard (zstd)。实际使用的压缩格式并不重要,只要格式受 libarchive 支持即可。压缩格式将来可能会随着更高级的压缩算法的开发而改变,并且 .conda 格式不需要任何改变。只需要更新的 libarchive 就可以将新的压缩格式添加到 .conda 文件中。

这些压缩文件可能比它们的 bzip2 等效文件小得多。此外,它们的解压缩速度也要快得多。在可用情况下,.conda 是首选文件格式,尽管我们继续提供 .tar.bz2 文件作为补充。

阅读有关 .conda 文件格式的引入 的更多信息。

注意

在 conda 4.7 及更高版本中,您不能使用以“.conda”结尾的软件包名称,因为它们与软件包的 .conda 文件格式冲突。

使用软件包#

  • 您可以搜索软件包

conda search scipy
  • 您可以安装软件包

conda install scipy
conda build my_fun_package

软件包结构#

.
├── bin
│   └── pyflakes
├── info
│   ├── LICENSE.txt
│   ├── files
│   ├── index.json
│   ├── paths.json
│   └── recipe
└── lib
    └── python3.5
  • bin 包含与软件包相关的二进制文件。

  • lib 包含相关的库文件(例如 .py 文件)。

  • info 包含软件包元数据。

元软件包#

当 conda 软件包仅用于元数据而不包含任何文件时,它被称为元软件包。元软件包可能包含对几个核心低级库的依赖关系,并且可能包含指向在执行时自动下载的软件文件的链接。元软件包用于捕获元数据并简化复杂的软件包规范。

"anaconda" 是一个元软件包的示例,它收集了 Anaconda 安装程序中的所有软件包。命令 conda create -n envname anaconda 创建一个与 Anaconda 安装程序创建的环境完全匹配的环境。您可以使用 conda metapackage 命令创建元软件包。在命令中包含名称和版本。

Anaconda 元软件包#

Anaconda 元软件包用于创建 Anaconda Distribution 安装程序,以便它们具有一组与之关联的软件包。每个安装程序版本都有一个版本号,对应于特定版本下的一组特定软件包。特定版本下的一组特定软件包被封装在 Anaconda 元软件包中。

Anaconda 元软件包包含几个核心低级库,包括压缩、加密、线性代数和一些 GUI 库。

阅读有关 Anaconda 元软件包和 Anaconda Distribution 的更多信息.

互斥元软件包#

互斥元软件包是一个非常简单的软件包,它有一个名称。它不需要有任何依赖项或构建步骤。互斥元软件包通常是构建另一个软件包的不同变体的食谱中的“输出”。互斥元软件包充当工具,帮助在具有不同名称的软件包之间实现互斥。

让我们看一些有关如何使用互斥元软件包针对不同的 BLAS 实现构建 NumPy 的示例。

使用 BLAS 变体构建 NumPy#

如果您使用 MKL 构建 NumPy,您还需要使用 MKL 构建 SciPy、scikit-learn 以及任何其他使用 BLAS 的软件包。确保这些“变体”(使用特定选项集构建的软件包)一起安装,而不是与备用 BLAS 实现一起安装非常重要。这样做是为了避免崩溃、速度慢或数值问题。对齐这些库是构建时和安装时的考虑因素。我们将展示如何使用元软件包来满足这一需求。

让我们从元软件包 blas=1.0=mkl 开始:AnacondaRecipes/intel_repack-feedstock

请注意,mklblas 的字符串。

当有人使用 mkl-devel 软件包作为构建时依赖项时,该元软件包会使用 run_exports 作为依赖项自动添加:AnacondaRecipes/intel_repack-feedstock

同样,这是 OpenBLAS 的元软件包:AnacondaRecipes/openblas-feedstock

以及 OpenBLAS 的 run_exports,作为 openblas-devel 的一部分:AnacondaRecipes/openblas-feedstock

从根本上说,conda 的互斥模型依赖于软件包名称。OpenBLAS 和 MKL 显然不是同一个软件包名称,因此不是互斥的。conda 并没有阻止同时安装这两个软件包。conda 并没有阻止用 MKL 安装 NumPy,用 OpenBLAS 安装 SciPy。元软件包允许我们实现互斥性。它将选项统一到单个软件包名称下,但使用不同的构建字符串。使用 run_exports 自动添加元软件包有助于确保库使用者(依赖库的软件包构建者)将拥有正确的依赖项信息来实现统一的运行时库集合。

使用 BLAS 变体安装 NumPy#

要指定您想要的 NumPy 变体,您可能需要指定您想要的 BLAS 库

conda install numpy mkl

但是,这实际上并不能阻止选择 OpenBLAS。MKL 及其依赖项都不是互斥的(这意味着它们没有类似的名称和不同的版本/构建字符串)。

此路径可能会导致一些不明确和混合 BLAS 的解决方案,因此建议使用元软件包。为了以一种不含糊的方式指定由 MKL 提供支持的 NumPy,您可以指定互斥软件包(直接或间接)

conda install numpy “blas=*=mkl”

但是,有一个更简单的方法可以解决这个问题。例如,您可能想尝试另一个将所需的互斥软件包作为依赖项的软件包。

OpenBLAS 使用其“nomkl”软件包来实现这一点:AnacondaRecipes/openblas-feedstock

任何软件包都不应将“nomkl”作为依赖项。它严格来说是供用户用来从 MKL(默认值)切换到 OpenBLAS 的实用程序。

MKL 如何成为默认值?求解器需要一种方法来优先考虑某些软件包而不是其他软件包。我们通过一个称为 track_features 的旧 conda 功能来实现这一点,该功能最初用于不同的目的。

Track_features#

conda 的优化目标之一是最小化指定所需规范所需的 track_features 数量。通过将 track_features 添加到一个或多个选项中,conda 将降低其优先级或“降低其权重”。优先级最低的软件包是会在环境中激活最多 track_features 的软件包。许多变体中的默认软件包是在环境中激活最少 track_features 的软件包。

但是,有一个问题:任何 track_features 都必须是唯一的。两个软件包不能提供相同的 track_feature。为此,我们的标准做法是将 track_features 附加到与我们想要设置为非默认值的软件包关联的元软件包。

再看一下 OpenBLAS 食谱:AnacondaRecipes/openblas-feedstock

此附加的 track_features 条目是 MKL 在 OpenBLAS 之上被选择的原因。MKL 没有与之关联的任何 track_features。如果有 3 个选项,您将为默认选项附加 0 个 track_features,为下一个首选选项附加 1 个 track_features,最后为最不喜欢的选项附加 2 个。但是,由于您通常只关心一个默认选项,因此通常将 1 个 track_feature 添加到除默认选项以外的所有选项就足够了。

更多信息#

作为参考,Windows 上的 Visual Studio 版本对齐也使用互斥元软件包。 AnacondaRecipes/aggregate

无架构软件包#

无架构软件包是与架构无关的软件包,因此只需要构建一次。无架构软件包是通用的或 Python 的。无架构通用软件包允许用户在 conda 软件包中分发文档、数据集和源代码。无架构 Python 软件包在下面描述。

meta.yamlbuild 部分中将这些软件包声明为 noarch 可以减少共享 CI 资源。因此,所有符合无架构软件包条件的软件包都应如此声明。

无架构 Python#

构建部分中的 noarch: python 指令使纯 Python 软件包只需要构建一次。

无架构 Python 软件包通过在安装时解决平台和 Python 版本特定的差异,减少了在不同架构和 Python 版本上构建多个不同纯 Python 软件包的开销。

为了符合无架构 Python 软件包的条件,必须满足以下所有条件

  • 没有编译扩展。

  • 没有 post-link、pre-link 或 pre-unlink 脚本。

  • 没有操作系统特定的构建脚本。

  • 没有 Python 版本特定的要求。

  • 除了 Python 版本以外,没有跳过。如果食谱是 py3 唯一的,请删除跳过语句并在主机和运行部分添加 Python 的版本约束。

  • 不使用 2to3。

  • 不使用 setup.py 中的脚本参数。

  • 如果 console_script 入口点位于 setup.py 中,则它们列在 meta.yaml 中。

  • 没有激活脚本。

  • 不是 conda 的依赖项。

注意

虽然 noarch: python 不适用于选择器,但它适用于版本约束。 skip: True  # [py2k] 有时可以替换为主机和运行子部分中的受约束的 Python 版本,例如: python >=3 而不是仅仅 python

注意

只有 console_script 入口点必须列在 meta.yaml 中。其他入口点不会与 noarch 冲突,因此不需要额外的处理。

阅读更多关于 conda 的无架构软件包

更多信息#

有关更多信息,请深入了解我们的 管理软件包指南。详细了解软件包元数据、存储库结构和索引以及软件包匹配规范,请参阅 软件包规范