构建 conda 包#

概述#

本教程介绍了如何在 Windows、macOS 和 Linux 上使用 conda-build 创建 conda 包,并以 SEP 和 GDAL 为例。在 工具包 部分提供了额外的 Windows 特定说明。

本教程中最终构建的包可在 anaconda.org(以前称为 Anaconda Cloud)上获得。

本教程还介绍了如何编写食谱。您可以在 GitHub 上的 SEP 食谱GDAL 食谱 中查看最终食谱,以及在 conda-build 文档存储库 中。

谁适合阅读本教程?#

本教程适用于希望构建更复杂的 conda 包的 Windows、macOS 和 Linux 用户。本教程将涉及构建科学包,这些包需要为多个不同 Python 版本编译。

开始之前#

在开始之前,请确保您已安装以下内容:

工具包#

Microsoft Visual Studio#

在 conda 开发人员的标准实践中,针对不同 Python 版本的 conda 包都是使用各自版本的 Visual Studio (VS) 构建的。

  • Python 2.7 包,使用 Visual Studio 2008

  • Python 3.4 包,使用 VS 2010

  • Python 3.5 包,使用 VS 2015,(默认)2017

  • Python 3.6 包,使用 VS 2015,(默认)2017

  • Python 3.7 包,使用 VS 2015,(默认)2017

使用这些版本的 VS 为每个 Python 版本构建包也是 python.org 官方构建 Python 所使用的做法。目前,VS 2008 和 VS 2010 只能通过经销商获得,而 VS 2015 和 VS 2017 可以从 Microsoft 在线购买。请注意,VS 2015 和 VS 2017 还提供社区版,可供使用。

Microsoft Visual Studio 的替代方案#

每个版本的 VS 编译器都有免费的替代方案可供使用。

适用于 Python 2.7 的 MS Visual C++ 编译器和适用于 Windows 7 和 .NET Framework 4 的 Microsoft Windows SDK 都经过了相当充分的测试。Conda-build 经过仔细测试以支持这些配置,但 CMake 构建工具与这些免费的 VS 2008 和 2010 替代方案之间存在已知问题。在这些情况下,您应该优先选择 "NMake Makefile" 生成器,而不是 Visual Studio 解决方案生成器。

Windows 版本#

您可以使用任何最近的 Windows 版本。这些示例是在 Windows 10 上构建的。

其他工具#

一些环境最初可能缺少 patch 或 Git 等工具,而这些工具可能在某些构建工作流程中需要。

在 Windows 上,可以使用以下命令通过 conda 安装它们:

$ conda install git m2-patch

在 macOS 和 Linux 上,请用 patch 替换 m2-patch

制定构建策略#

Conda 食谱通常采用试错法构建。有时,第一次尝试构建包会因编译器或链接器错误而失败,通常是由于缺少依赖项造成的。编写食谱的人员随后会检查这些错误并修改食谱以包含缺少的依赖项,通常作为 meta.yaml 文件的一部分。然后,食谱编写人员再次尝试构建,经过几次这样的试错循环后,包就会成功构建。

使用与您的 Miniconda 安装不同的 Python 版本进行构建#

Miniconda2 和 Miniconda3 都可以通过简单地指定您想要的版本,分别为 Python 2 或 Python 3 构建包。Miniconda2 仅包含 Python 2,而 Miniconda3 仅包含 Python 3。

仅安装其中一个会更容易跟踪构建,但可以同时在同一个系统上安装两者。如果您同时安装了两个,请在 Windows 上使用 where 命令,或在 macOS 或 Linux 上使用 which 命令来查看哪个版本在 PATH 上排在首位,因为这是您将使用的版本。

$ where python

要构建与您 Miniconda 安装中不同的 Python 版本的包,请在 conda-build 命令中使用 --python 选项。例如,要使用 Miniconda2 构建 Python 3.5 包,请执行以下操作:

$ conda-build recipeDirectory --python=3.5

注意

请用您的食谱目录的名称和路径替换 recipeDirectory

自动化测试#

构建完成后,如果食谱目录包含一个测试文件。此测试文件在 Windows 上名为 run_test.bat,在 macOS 或 Linux 上名为 run_test.sh,或在任何平台上名为 run_test.py。运行此文件以测试包,并报告出现的任何错误。看到 "检查输出" 后,您还可以使用以下命令测试是否构建了此包:

$ conda build --test <path to package>.tar.bz2

注意

使用 "test" 部分meta.yaml 文件中将食谱目录中的数据文件移动到测试目录,以便在运行测试时执行此操作。

使用 conda 和 Python 2 或 3 构建 SEP 包#

SEP 文档 指出 SEP 在 Python 2 和 3 上运行,并且它仅依赖于 NumPy。在 PyPI 上搜索 SEP 显示已经存在 SEP 的 PyPI 包

由于 SEP 的 PyPI 包已经存在,因此 conda skeleton 命令可以基于 PyPI 包创建 conda 食谱的骨架或大纲。然后可以手动完成食谱大纲,conda 可以从完成的食谱构建 conda 包。

安装 Visual Studio#

如果您还没有安装,请安装相应的 Visual Studio 版本:

  • 对于 Python 3 - Visual Studio 2017

    1. 选择 "自定义安装" 选项。

    2. 在 "编程语言" 下,选择安装 Visual C++。

  • 对于 Python 2 - Visual Studio 2008

    1. 选择 "自定义安装" 选项。

    2. 选择安装 X64 编译器和工具。安装 Service Pack 1。

创建 conda 骨架食谱#

  1. 运行 skeleton 命令:

    $ conda skeleton pypi sep
    

    skeleton 命令安装到一个名为 sep 的新创建目录中。

  2. 转到 sep 目录以查看文件:

    $ cd sep
    

    您会看到已创建了一个 skeleton 文件:meta.yaml

编辑骨架文件#

对于此包,bld.batbuild.sh 不需要更改。您需要编辑 meta.yaml 文件,添加对 NumPy 的依赖,并通过导入它添加一个可选的已构建包测试。有关可以在 meta.yaml 中指定的更多信息,请参阅 定义元数据 (meta.yaml)

  1. meta.yaml 文件的“requirements”部分添加一行,将 NumPy 添加为构建包的依赖项。

  2. 添加第二行,将 NumPy 列为运行包的依赖项。

  3. 将 NumPy 版本设置为字母 x.x

  4. 确保新行与上一行中的 - python 对齐,以确保正确的 yaml 格式。

示例

requirements:
  host:
    - python
    - numpy     x.x

  run:
    - python
    - numpy     x.x

请注意,存在两种类型的需求,hostrun (build 是另一个有效的参数,但本示例中未显示)。host 表示当目标平台不一定是与本机构建平台相同平台时,需要针对目标平台特定的包。run 表示安装包时应安装的依赖项。

注意

使用字母 x.x 而不是特定版本(例如 1.11)会动态地固定 NumPy,因此 NumPy 的实际版本将从构建命令中获取。目前,NumPy 是唯一可以动态固定的包。固定对于 SEP 非常重要,因为此包通过 Cython 使用 NumPy 的 C API。该 API 在 NumPy 版本之间会发生变化,因此在运行时使用与构建时相同的 NumPy 版本至关重要。

可选:添加对构建包的测试 #

添加此可选测试将在构建结束时测试包,通过确保 Python 语句 import sep 能够成功运行。

  1. 添加 - sep,确保缩进与文件中的其他部分一致。

    test:
      # Python imports
      imports:
        - sep
    

构建包 #

使用您刚刚创建的配方构建包。

$ conda build sep

检查输出 #

  1. 检查输出以确保构建成功完成。输出包含最终包文件的位置以及将包上传到 Anaconda Cloud 的命令。输出将类似于以下内容:

    # Automatic uploading is disabled
    # If you want to upload package(s) to anaconda.org later, type:
    anaconda upload /Users/builder/miniconda3/conda-bld/osx-64/sep-1.0.3-np111py36_0.tar.bz2
    # To have conda build upload to anaconda.org automatically, use
    # $ conda config --set anaconda_upload yes
    anaconda_upload is not set.  Not uploading wheels: []
    ####################################################################################
    Resource usage summary:
    Total time: 0:00:56.4
    CPU usage: sys=0:00:00.7, user=0:00:07.0
    Maximum memory usage observed: 220.1M
    Total disk usage observed (not including envs): 3.9K
    ####################################################################################
    Source and build intermediates have been left in /Users/builder/miniconda3/conda-bld.
    There are currently 437 accumulated.
    To remove them, you can run the ```conda build purge``` command
    
  1. 如果存在任何链接器或编译器错误,请修改配方并重新构建。

使用 conda 和 Python 2 或 3 构建 GDAL 包 #

首先,安装 Anaconda 或 Miniconda 和 conda-build。如果您使用的是 Windows 机器,请使用 conda 安装 Git 和 m2-patch

$ conda install git
$ conda install m2-patch

由于 GDAL 包含 C 和 C++,因此在 Windows 上构建它需要 Visual Studio。此过程描述了如何使用 Python 2 或 Python 3 构建包。按照与您想要构建的版本相对应的说明进行操作。

要构建 GDAL 包

  1. 安装 Visual Studio

    • 选择“自定义安装”。

    • 在“编程语言”下,选择来自 Visual Studio 的工作负载,以便您可以选择“使用 C++ 的桌面开发”和“通用 Windows 平台 C”。

    • 选择“自定义安装”。

    • 选择安装 X64 编译器和工具。

    • 安装 Visual Studio 2008 Service Pack 1。

  2. 安装 Git。由于 GDAL 包源代码是为构建从 GitHub 获取的,因此您必须安装 Git。

    $ conda install git m2-patch conda-build
    
  3. 获取 gdal-feedstock。在本教程中,我们将使用 Anaconda 中的配方。

    $ git clone https://github.com/AnacondaRecipes/gdal-feedstock.git
    
  4. 使用 conda-build 构建 gdal-feedstock

    $ conda build gdal-feedstock
    
  5. 检查输出以确保构建成功完成。输出还包含最终包文件的位置以及将包上传到 Cloud 的命令。对于此特定的包,应该输出两个包:libgdalGDAL

  6. 如果存在任何链接器或编译器错误,请修改配方并再次运行它。

让我们仔细看看 gdal-feedstock 中的内容,特别是在 meta.yaml 文件中。

第一个有趣的部分发生在 source 下的 patches 部分

patches:
  # BUILT_AS_DYNAMIC_LIB.
  - 0001-windowshdf5.patch
  # Use multiple cores on Windows.
  - 0002-multiprocessor.patch
  # disable 12 bit jpeg on Windows as we aren't using internal jpeg
  - 0003-disable_jpeg12.patch

此部分基本上是说“当此包在 Windows 平台上构建时,应用以下补丁文件”。请注意,补丁文件位于配方的 patches 目录中。这些补丁仅应用于 Windows,因为 # [win] 选择器应用于每个补丁条目。有关选择器的更多信息,请参阅 预处理选择器

requirements 部分,请注意如何同时使用 buildhost 需求集 (run 是另一个有效的参数,但本示例中未显示)。对于此配方,构建包所需的所有编译器都列在 build 需求中。通常,此部分将列出构建包所需的包。GDAL 在 Windows 上需要 CMake 以及 C 编译器。请注意,使用语法 {{ compiler('c') }} 将 C 编译器拉入配方中。从 conda-build 3 开始,conda-build 定义了一个 jinja2 函数 compiler() 来动态指定编译器包。因此,在 conda 配方中使用 compiler('c') 函数将为任何构建平台拉入正确的编译器。有关 conda-build 中编译器的更多信息,请参阅 compiler-tools

另请注意,conda-build 使用的编译器可以使用 conda_build_config.yaml 指定。有关如何执行此操作的更多信息,请参阅 使用自定义编译器包与 conda-build 3

请注意,此包具有 outputs 部分。此部分是作为构建此包的结果输出的包列表。在本例中,将构建 libgdalGDAL 包。与普通配方类似,输出可以指定构建脚本、测试脚本和需求。有关输出工作方式的更多信息,请参阅 输出部分

现在,让我们尝试针对一些构建矩阵构建 GDAL。我们将使用 conda-build 配置指定针对 Python 3.7 和 3.5 构建。将以下内容添加到您的 conda_build_config.yaml

python:
   - 3.7
   - 3.5

现在您可以使用以下命令使用 conda-build 构建 GDAL

$ conda build gdal-feedstock

或者显式设置 conda-build 变体矩阵的位置

$ conda build gdal-feedstock --variant-config-file conda_build_config.yaml

如果您想了解有关构建变体和 conda_build_config.yaml 的更多信息,包括如何指定配置文件以及配置文件中可以包含的内容,请查看 创建 conda-build 变体配置文件