定义元数据 (meta.yaml)#
conda-build 配方中的所有元数据都在 meta.yaml
文件中指定。请参阅下面的示例
{% set version = "1.1.0" %}
package:
name: imagesize
version: {{ version }}
source:
url: https://pypi.io/packages/source/i/imagesize/imagesize-{{ version }}.tar.gz
sha256: f3832918bc3c66617f92e35f5d70729187676313caa60c187eb0f28b8fe5e3b5
build:
noarch: python
number: 0
script: python -m pip install --no-deps --ignore-installed .
requirements:
host:
- python
- pip
run:
- python
test:
imports:
- imagesize
about:
home: https://github.com/shibukawa/imagesize_py
license: MIT
summary: 'Getting image size from png/jpeg/jpeg2000/gif file'
description: |
This module analyzes jpeg/jpeg2000/png/gif image header and
return image size.
dev_url: https://github.com/shibukawa/imagesize_py
doc_url: https://pypi.python.org/pypi/imagesize
doc_source_url: https://github.com/shibukawa/imagesize_py/blob/master/README.rst
除了 package/name
和 package/version
之外,所有部分都是可选的。
标头只能出现一次。如果它们多次出现,则仅记住最后一个。例如,package:
标头在文件中应仅出现一次。
Package 部分#
指定软件包信息。
软件包名称#
软件包的小写名称。它可以包含“-”,但不能包含空格。
package:
name: bsdiff4
软件包版本#
软件包的版本号。使用 PEP-386 verlib 约定。不能包含“-”。YAML 将版本号(如 1.0)解释为浮点数,这意味着 0.10 将与 0.1 相同。为避免这种情况,请将版本号放在引号中,以便将其解释为字符串。
package:
version: "1.1.4"
注意
构建后版本控制:在某些情况下,您可能在构建后才知道软件包的版本、构建号或构建字符串。在这些情况下,您可以执行 使用 Jinja 模板 或利用 Git 环境变量 和 继承的环境变量。
Source 部分#
指定软件包的源代码来自何处。源可能来自 tarball 文件、git、hg 或 svn。它可能是本地路径,并且可能包含补丁。
来自 tarball 或 zip 档案的源#
source:
url: https://pypi.python.org/packages/source/b/bsdiff4/bsdiff4-1.1.4.tar.gz
md5: 29f6089290505fc1a852e176bd276c43
sha1: f0a2c9a30073449cfb7d171c57552f3109d93894
sha224: ebf3e3b54353146ca21128ed6399739663a1256a223f438ed0223845
sha256: 5a022ff4c1d1de87232b1c70bde50afbb98212fd246be4a867d8737173cf1f8f
sha384: 23eee6ee2e5d1054780e331857589bfba098255a88ae4edd47102fce676694ce0f543dc5c0d27c51f77cc4546d4e74c0
sha512: b968c7dc99132252a83b175a96ec75ec842edf9e2494db2c07b419e61a0b1cf6984e7c544452f9ab56aa8581caf966c0f6933fc22a071ccc4fbb5d22b363fe54
如果提取的档案在其顶层仅包含 1 个文件夹,则其内容将向上移动 1 级,以便提取的软件包内容位于工作文件夹的根目录中。
您还可以为同一源档案指定多个 URL。如果一个 URL 失败,将按顺序尝试它们。
source:
url:
- https://archive.linux.duke.edu/cran/src/contrib/ggblanket_6.0.0.tar.gz
- https://archive.linux.duke.edu/cran/src/contrib/Archive/ggblanket/ggblanket_6.0.0.tar.gz
sha256: cd2181fe3d3365eaf36ff8bbbc90ea9d76c56d40e63386b4eefa0e3120ec6665
来自 git 的源#
git_url 也可以是相对于配方目录的相对路径。
source:
git_url: https://github.com/ilanschnell/bsdiff4.git
git_rev: 1.1.4 # (Defaults to "HEAD")
git_depth: 1 # (Defaults to -1/not shallow)
depth 参数与执行浅克隆的能力有关。浅克隆意味着您仅从 Git 下载部分历史记录。如果您知道只需要最近的更改,则可以声明 git_depth: 1
,这比克隆整个仓库更快。将其设置为 1 的缺点是,除非标签位于该特定提交上,否则当您在 git_rev
中引用它时(例如),您将没有该标签。如果您的 git_depth
不足以捕获 git_rev
中的标签,则会遇到错误。因此,在上面的示例中,除非 1.1.4 是非常 head 的提交并且是您要抓取的那个,否则您可能会遇到错误。
来自 hg 的源#
source:
hg_url: ssh://[email protected]/ilanschnell/bsdiff4
hg_tag: 1.1.4
来自 svn 的源#
source:
svn_url: https://github.com/ilanschnell/bsdiff
svn_rev: 1.1.4 # (defaults to head)
svn_ignore_externals: True # (defaults to False)
svn_username: username # Optional, if set must also have svn_password
svn_password: password # Optional, if set must also have svn_username
要访问受限 SVN 存储库,请同时指定 svn_username
和 svn_password
。
注意
以明文形式存储凭据存在风险。或者,考虑使用环境变量
source:
svn_username: {{ environ["SVN_USERNAME"] }}
svn_password: {{ environ["SVN_PASSWORD"] }}
来自本地路径的源#
如果路径是相对路径,则相对于配方目录。源在构建之前复制到工作目录。
source:
path: ../src
如果本地路径是 git 或 svn 存储库,您将获得构建环境中定义的相应环境变量。git_url 或 hg_url 与 path 作为源参数之间的唯一实际区别在于,git_url 和 hg_url 将是存储库的克隆,而 path 将是存储库的副本。使用 path 允许您使用工作目录中未暂存和未提交的更改来构建软件包。git_url 只能构建到最新的提交。
哈希值#
Conda-build 可以使用不同的哈希算法检查提供的源的完整性
md5
、sha1
和sha256
将在提取之前检查提供的十六进制摘要与下载的档案是否一致。content_md5
、content_sha1
和content_sha256
将检查提供的十六进制摘要与(提取的)目录的内容是否一致。content_hash_skip
可以接受要检查期间忽略的相对文件和目录的列表(例如,当使用git_url
克隆存储库时,忽略.git/
目录很有用)。
补丁#
补丁可以有选择地应用于源。
source:
#[source information here]
patches:
- my.patch # the patch file is expected to be found in the recipe
Conda-build 自动确定补丁剥离级别。
目标路径#
在 conda-build 的工作目录中,您可以指定一个特定的文件夹来放置源。此功能在 conda-build 3.0 中是新增功能。Conda-build 将始终让您进入同一文件夹(build folder/work),但这取决于您是否希望将源提取到该文件夹中,还是嵌套得更深。此功能在处理多个源时尤其有用,但也适用于具有单个源的配方。
source:
#[source information here]
folder: my-destination/folder
文件名#
filename 键是 fn
。以前 URL 源类型需要它。现在不是必需的。
如果提供了 fn
键,则文件以该名称保存在磁盘上。如果未提供 fn
键,则文件以与 URL 的最后一部分匹配的名称保存在磁盘上。
例如,http://www.something.com/myfile.zip
具有 myfile.zip
的隐式文件名。用户可以通过手动指定 fn
来更改此设置。
source:
url: http://www.something.com/myfile.zip
fn: otherfilename.zip
来自多个源的源#
某些软件最容易通过聚合多个部分来构建。为此,conda-build 3.0 添加了对任意指定多个源的支持。
语法是源字典的列表。此列表的每个成员都遵循与早期 conda-build 版本的单个源相同的规则(上面列出)。支持每个成员的所有功能。
示例
source:
- url: https://package1.com/a.tar.bz2
folder: stuff
- url: https://package1.com/b.tar.bz2
folder: stuff
- git_url: https://github.com/conda/conda-build
folder: conda-build
在此处,两个 URL tarball 将进入一个文件夹,git 仓库被检出到其自己的空间中。Git 不会克隆到非空文件夹中。
注意
破折号表示 YAML 语法中的列表项。
Build 部分#
指定构建信息。
每个期望路径的字段也可以处理 glob 模式。匹配从构建环境的顶部执行,因此要匹配项目中的文件,可以使用类似于以下模式的模式:“**/myproject/**/*.txt”。此模式将匹配在您的项目中找到的任何 .txt 文件。
注意
对于以 * 开头的模式,引号 (“”) 是必需的。
仅在 conda-build >= 3.0 中支持使用 ** 的递归 globbing。
构建号和字符串#
对于同一版本的新构建,应递增构建号。该数字默认为 0
。构建字符串不能包含“-”。字符串默认为默认 conda-build 字符串加上构建号。
build:
number: 1
string: abc
当软件包受到来自 conda_build_config.yaml 文件的一个或多个变量的影响时,将出现哈希值。哈希值由“已使用”变量组成 - 如果使用了任何内容,则您将获得哈希值。如果您不使用这些变量,则您将没有哈希值。有一些特殊情况不会影响哈希值,例如 Python 和 R 或任何已经在构建字符串中占有一席之地的东西。
如果以下条件对任何依赖项都为真,则构建哈希值将添加到构建字符串中
软件包是 build、host 或 run deps 中的显式依赖项
软件包在 conda_build_config.yaml 中有一个匹配的条目,该条目是特定版本的 pin,而不是下限
该软件包未被 ignore_version 忽略
或
软件包使用 {{ compiler() }} jinja2 函数
您还可以使用以下方式影响哪些变量被考虑用于哈希值
build:
force_use_keys:
- package_1
force_ignore_keys:
- package_2
这将确保 package_2
的值不会被考虑用于哈希值,而 package_1
将会被考虑,无论 conda-build 通过其检查发现使用了什么。
这可能有助于进一步拆分复杂的多输出构建,以确保构建每个软件包,或者在使用更复杂的模板或脚本时确保正确的软件包哈希值。
Python 入口点#
以下示例创建一个名为“bsdiff4”的 Python 入口点,该入口点调用 bsdiff4.cli.main_bsdiff4()
。
build:
entry_points:
- bsdiff4 = bsdiff4.cli:main_bsdiff4
- bspatch4 = bsdiff4.cli:main_bspatch4
Python.app#
如果设置了 osx_is_app,则入口点在 macOS 中使用 python.app
而不是 Python。默认值为 False
。
build:
osx_is_app: True
python_site_packages_path#
名称为 python
的软件包可以选择使用 python_site_packages_path
指定 site-packages 目录相对于环境根目录的位置。这应仅在 python
软件包中使用,并且仅当路径不是 CPython 默认路径时才使用。
build:
python_site_packages_path: lib/python3.13t/site-packages
Track features#
将 track_features 添加到一个或多个选项将导致 conda 降低其优先级或“权衡”。优先级最低的软件包是会导致环境中激活最多 track_features 的软件包。许多变体中的默认软件包是会导致激活最少 track_features 的软件包。
给定 subdir 中的任何两个软件包都不应具有相同的 track_feature。
build:
track_features:
- feature2
保留 Python egg 目录#
某些使用 setuptools 特定功能的软件包需要此功能。默认值为 False
。
build:
preserve_egg_dir: True
跳过将某些 .py 文件编译为 .pyc 文件#
某些软件包附带无法编译的 .py
文件,例如包含模板的文件。某些软件包还附带不应编译的 .py
文件,因为在构建时未知将要使用的 Python 解释器。在这些情况下,conda-build 可以跳过尝试编译这些文件。本节中使用的模式不需要 ** 来处理递归路径。
build:
skip_compile_pyc:
- "*/templates/*.py" # These should not (and cannot) be compiled
- "*/share/plugins/gdb/*.py" # The python embedded into gdb is unknown
No link#
应始终复制且永远不应软链接或硬链接的文件 glob 列表。
build:
no_link:
- bin/*.py # Don't link any .py files in bin/
Script#
代替 build.sh
或 bld.bat
使用。对于短的构建脚本,这可能更方便。您可能需要使用 选择器 为不同的平台使用不同的脚本。
build:
script: python setup.py install --single-version-externally-managed --record=record.txt
RPATH#
设置在 Linux 上使可执行文件可重定位时使用的 RPATH。这是 Linux 功能,在其他系统上将被忽略。默认值为 lib/
。
build:
rpaths:
- lib/
- lib/R/lib/
Force files#
强制始终包含文件,即使它们已经通过构建依赖项存在于环境中也是如此。例如,这可能是为 conda 本身创建配方所必需的。
build:
always_include_files:
- bin/file1
- bin/file2
重定位#
高级功能。您可以使用以下 4 个键来控制从构建环境到安装环境的可重定位文件
binary_relocation。
has_prefix_files。
binary_has_prefix_files。
ignore_prefix_files。
有关更多信息,请参阅 使软件包可重定位。
二进制重定位#
是否应使用 macOS 上的 install_name_tool 或 Linux 上的 patchelf 使二进制文件可重定位。默认值为 True
。它也接受 False
,表示不重定位任何文件,或文件列表,表示仅对列出的文件进行重定位。
build:
binary_relocation: False
检测带有前缀的二进制文件#
二进制文件可能包含构建前缀,需要在安装时将其替换为安装前缀。Conda 可以自动识别和注册此类文件。默认值为 True
。
注意
默认值在 conda build 2.0 中从 False
更改为 True
。将其设置为 False
意味着仍将完成二进制重定位---RPATH---替换,但二进制文件中的硬编码前缀将不会被替换。文本文件中的前缀仍将被替换。
build:
detect_binary_files_with_prefix: False
Windows 处理二进制前缀替换的方式与 macOS 和 Linux 等类 Unix 系统非常不同。目前,我们不知道任何可执行文件或库在 Windows 上使用硬编码嵌入路径来查找其他库或程序数据。相反,Windows 遵循 DLL 搜索路径规则,或者更原生支持使用相对路径的可重定位性。因此,conda 会忽略大多数前缀。但是,pip 为 Python 入口点创建的可执行文件确实在 Windows 上使用嵌入路径。因此,conda-build 默认检测所有文件中的前缀并记录它们。如果您在 Windows 上遇到有关路径长度的错误,则应尝试禁用 detect_binary_files_with_prefix。较新版本的 Conda(例如最近的 4.2.x 系列版本及更高版本)应该没有问题,但早期版本的 conda 确实错误地尝试应用任何二进制前缀替换。
Binary has prefix files#
默认情况下,conda-build 尝试检测所有文件中的前缀。您也可以选择单独指定带有二进制前缀的文件。当文件可能因某种原因被错误地检测为文本时,这允许您将文件类型指定为二进制文件。二进制文件是包含 NULL 字节的文件。
build:
binary_has_prefix_files:
- bin/binaryfile1
- lib/binaryfile2
Text files with prefix files#
文本文件---不包含 NULL 字节的文件---可能包含构建前缀,需要在安装时将其替换为安装前缀。Conda 将自动注册此类文件。包含构建前缀的二进制文件通常以不同的方式处理---请参阅 Binary has prefix files---但可能存在需要将此类二进制文件视为普通文本文件的情况,在这种情况下,需要识别它们。
build:
has_prefix_files:
- bin/file1
- lib/file2
Ignore prefix files#
用于从列表中排除构建配方中的某些或所有文件,这些文件的前缀被构建前缀替换为安装前缀。
要忽略构建配方中的所有文件,请使用
build:
ignore_prefix_files: True
要指定单个文件名,请使用
build:
ignore_prefix_files:
- file1
此设置独立于 RPATH 替换。使用 检测带有前缀的二进制文件 设置来控制该行为。
跳过构建#
指定 conda-build 是否应跳过此配方的构建。对于定义特定于平台的配方特别有用。默认值为 False
。
build:
skip: True # [not win]
架构独立的软件包#
允许您在构建软件包时指定“no architecture”,从而使其与所有平台和架构兼容。Noarch 软件包可以安装在任何平台上。
从 conda-build 2.1 和 conda 4.3 开始,出现了一种支持不同语言的新语法。将 noarch 键指定为 generic
告诉 conda 不要尝试任何内容操作。
build:
noarch: generic
noarch: generic
对于静态 javascript 资源和源档案等软件包最有用。对于可以在任何 Python 版本上运行的纯 Python 软件包,您可以改用 noarch: python
值
build:
noarch: python
noarch_python
的旧语法仍然有效,当您需要确保您的软件包可以安装在 conda 4.3 尚不可用的地方时,应使用它。所有其他形式的 noarch 软件包都需要 conda >=4.3 才能安装。
build:
noarch_python: True
警告
在撰写本文时,noarch
软件包不应使用 preprocess-selectors:noarch
软件包使用在构建平台中评估为 True
的指令构建,这可能会导致在其他平台上安装不正确/不完整。
包含构建配方#
完整的 conda-build 配方和呈现的 meta.yaml
文件默认包含在 软件包元数据 中。您可以使用以下方式禁用此功能
build:
include_recipe: False
使用环境变量#
通常,build.sh
或 bld.bat
中的构建脚本不会传递来自命令行的环境变量。构建脚本只能看到 环境变量 中记录的环境变量。要“白名单”应传递到构建脚本的环境变量
build:
script_env:
- MYVAR
- ANOTHER_VAR
如果列出的环境变量在 conda-build 进程本身看到的环境中丢失,则在构建过程中会发出 UserWarning,并且该变量保持未定义状态。
此外,可以通过包含 =
后跟所需值来设置值
build:
script_env:
- MY_VAR=some value
注意
继承环境变量可能会使其他人难以使用您的配方从源代码重现二进制文件。请谨慎使用此功能,或使用 =
语法显式设置值。
注意
如果您使用 --no-test
和 --test
拆分构建和测试阶段,则需要确保构建时和测试时存在的环境变量匹配。如果您不这样做,软件包哈希值可能会使用不同的值,并且您的软件包可能无法测试,因为哈希值会不同。
导出运行时需求#
某些 build 或 host Requirements 部分 将施加运行时需求。最常见的情况是共享库(例如 libpng),构建时需要链接,运行时需要解析链接。使用 run_exports
(conda-build 3 中的新增功能),可以通过 host 需求隐式添加运行时需求(例如,libpng 导出 libpng),而使用 run_exports/strong
甚至可以通过 build 需求添加运行时需求(例如,GCC 导出 libgcc)。
# meta.yaml of libpng
build:
run_exports:
- libpng
在此处,由于未指定任何特定类型的 run_exports
,因此 libpng 的 run_exports
被认为是“弱”的。这意味着它们仅在 libpng 位于 host 部分时才适用,届时它们将将其导出添加到 run 部分。如果 libpng 列在 build 部分中,则 run_exports
将不适用于 run 部分。
# meta.yaml of gcc compiler
build:
run_exports:
strong:
- libgcc
还有 run_exports/weak
,它等效于不明确类型的 run_exports
,但如果您想定义强和弱 run exports,则很有用。
强 run_exports
用于运行时等,其中同一运行时需要存在于 host 和 run 环境中,并且应使用哪个运行时由 build 部分中存在的内容决定。这种机制是我们如何在 Windows 上对齐适当的软件,在 Windows 上,我们必须匹配环境中所有共享库中使用的 MSVC 版本。
# meta.yaml of some package using gcc and libpng
requirements:
build:
- gcc # has a strong run export
host:
- libpng # has a (weak) run export
# - libgcc <-- implicitly added by gcc
run:
# - libgcc <-- implicitly added by gcc
# - libpng <-- implicitly added by libpng
您可以直接表达版本约束,也可以使用 额外的 Jinja2 函数 中列出的任何 Jinja2 帮助器函数。
例如,您可以使用 Pinning 表达式 来获得相对于构建时存在的版本的灵活版本 pinning
build:
run_exports:
- {{ pin_subpackage('libpng', max_pin='x.x') }}
在此示例中,如果 libpng 版本为 1.6.34,则此 pinning 表达式将评估为 >=1.6.34,<1.7
。
如果构建和链接依赖项需要对运行环境施加约束,但不一定需要拉入其他软件包,则可以通过更改 Run_constrained 条目来完成。除了添加到 run
需求的 weak
/strong
run_exports
之外,weak_constrains
和 strong_constrains
添加到 run_constrained
需求。使用这些,可以表达兼容但不必需的软件包(例如,链接依赖项的可选插件或某些系统属性)的最低版本
requirements:
build:
- build-tool # has a strong run_constrained export
host:
- link-dependency # has a weak run_constrained export
run:
run_constrained:
# - system-dependency >=min <-- implicitly added by build-tool
# - optional-plugin >=min <-- implicitly added by link-dependency
请注意,run_exports
可以在 build 部分中指定,也可以在拆分软件包的每个输出基础上指定。
run_exports
仅影响直接命名的依赖项。例如,如果您有一个包含列出 run_exports
的编译器的元软件包,您还需要在元软件包中定义 run_exports
,以便在人们安装您的元软件包时生效。这很重要,因为如果 run_exports
影响传递依赖项,您将看到许多添加到共享库的依赖项,而这些共享库实际上不是直接依赖项。例如,Python 使用 bzip2,后者可以使用 run_exports
来确保人们使用兼容版本的 bzip2。如果人们将 python 列为构建时依赖项,则 bzip2 应仅对 Python 本身施加,而不应自动作为运行时依赖项强加给使用 Python 的事物。
此功能的潜在缺点是,它从下游用户那里夺走了一些对约束的控制权。如果上游软件包具有有问题的 run_exports
约束,您可以通过在 build/ignore_run_exports
部分中列出上游软件包名称来忽略它
build:
ignore_run_exports:
- libstdc++
您还可以使用 build/ignore_run_exports_from
部分列出 run_exports
约束来自的软件包
build:
ignore_run_exports_from:
- {{ compiler('cxx') }}
Pin runtime dependencies#
pin_depends
构建键可用于对输出配方或构建的软件包强制执行 pinning 行为。
有两种可能的行为
build:
pin_depends: record
对于 record
值,conda-build 将记录所有需求,就像它们将安装在名为 info/requires 的文件中一样。这些 pin 不会显示在 conda render
的输出中,并且它们不会影响输出软件包的实际运行依赖项。它只是在此新文件中添加。
build:
pin_depends: strict
对于 strict
值,conda-build 将 pin 应用于实际元数据。这确实会影响 conda render
的输出,并且还会影响构建的最终结果。软件包依赖项将被严格 pin 到构建字符串级别。这将取代 conda-build 可能正在执行的任何动态或兼容 pinning。
忽略过度链接/过度依赖检查中的文件#
构建部分中的 overlinking_ignore_patterns
键可用于忽略过度链接和过度依赖检查的文件模式。这有时对于加速具有许多文件(大型重新打包作业)的构建或您知道只有一小部分文件应检查的构建很有用。
此处允许使用 Glob 模式,但请注意您的引用,尤其是带有前导通配符的引用。
请谨慎使用此功能,因为过度链接检查通常确实可以防止您犯错。
build:
overlinking_ignore_patterns:
- "bin/*"
Requirements section#
指定构建和运行时需求。这些需求的依赖项会自动包含在内。
需求的版本必须遵循 conda 匹配规范。请参阅 包匹配规范。
Build#
构建包所需的工具。这些包在构建系统上运行,包括诸如版本控制系统 (Git、SVN)、构建工具 (GNU make、Autotool、CMake) 和编译器(真实的交叉编译器、伪交叉编译器或非交叉编译时的本地编译器)以及任何源代码预处理器。
提供 “sysroot” 文件的包,例如 CDT
包(见下文),也属于构建部分。
requirements:
build:
- git
- cmake
Host#
此部分在 conda-build 3.0 中添加。它表示当目标平台不一定与本地构建平台相同时,需要特定于目标平台的包。例如,为了使配方“能够交叉编译”,共享库需求必须列在 host 部分,而不是 build 部分,以便链接的共享库是用于目标平台的,而不是本地构建平台的。您还应该包括需要解释器的包的基本解释器。换句话说,Python 包会在此处列出 python
,而 R 包会列出 mro-base
或 r-base
。
requirements:
build:
- {{ compiler('c') }}
- {{ cdt('xorg-x11-proto-devel') }} # [linux]
host:
- python
注意
当同时定义了 build 和 host 部分时,build 部分可以被认为是“构建工具”——在本地平台运行,但输出用于目标平台的结果。例如,一个在 linux-64 上运行,但目标是 linux-armv7 的交叉编译器。
PREFIX 环境变量指向 host 前缀。关于构建期间的激活,host 和 build 环境都被激活。build 前缀在 host 前缀之后激活,以便 build 前缀(始终包含运行平台的本地可执行文件)优先于 host 前缀,而 host 前缀不能保证提供本地可执行文件(例如,当交叉编译时)。
从 conda-build 3.1.4 开始,当 build 和 host 都被定义,或者当使用 {{ compiler() }}
Jinja2 函数时,build 和 host 前缀始终是分开的。build 和 host 合并的唯一情况是当 host 部分不存在,并且 meta.yaml 中没有使用 {{ compiler() }}
Jinja2 函数时。由于这些是分开的,因此在迁移您的配方时,您可能会看到一些构建失败。例如,假设您有一个配方来构建 Python 扩展。如果您将 compiler Jinja2 函数添加到 build 部分,但您没有将 Python 依赖项从 build 部分移动到 host 部分,则您的配方将失败。它将失败,因为 host 环境是检测新文件的位置,但由于您只在 build 环境中拥有 Python,因此您的扩展将被安装到 build 环境中。将不会检测到任何文件。此外,当 Python 未安装到 host 环境中时,诸如 PYTHON 之类的变量将未定义。
在 Linux 上,使用 Anaconda Inc. 在 defaults
元通道中提供的编译器包,可以通过使用我们的 CDT
(核心依赖树) 包来防止您的构建系统泄漏到构建的软件中,用于任何 “系统” 依赖项。这些包是来自 CentOS6 的重新打包的库和头文件,并被解压到我们的伪交叉编译器的 sysroot 中,并由它们自动找到。
请注意,什么符合 “系统” 依赖项是一个见仁见智的问题。Anaconda Distribution 选择不提供 X11 或 GL 包,因此我们使用 CDT 包用于 X11。Conda-forge 选择提供 X11 和 GL 包。
在 macOS 上,您也可以使用 {{ compiler() }}
来获取 Anaconda Inc. 在 defaults
元通道中提供的编译器包。环境变量 MACOSX_DEPLOYMENT_TARGET
和 CONDA_BUILD_SYSROOT
将由 conda-build 适当地设置(请参阅 环境变量)。CONDA_BUILD_SYSROOT
将指定包含 macOS SDK 的文件夹。这些设置实现了向后兼容性,同时仍然提供对 C++14 和 C++17 的访问。请注意,conda-build 将通过解析 conda_build_config.yaml
来设置 CONDA_BUILD_SYSROOT
。有关更多详细信息,请参阅 Anaconda 编译器工具。
TL;DR: 如果您使用 {{ compiler() }}
Jinja2 来利用我们的新编译器,您还必须将任何非严格意义上的构建工具移动到您的 host 依赖项中。这包括 Python、Python 库以及您需要在构建中链接的任何共享库。构建工具的示例包括任何 {{ compiler() }}
、Make、Autoconf、Perl(用于运行脚本,而不是安装 Perl 软件)和 Python(用于运行脚本,而不是安装软件)。
Run#
运行包所需的包。这些是在安装包时自动安装的依赖项。包名称应遵循 包匹配规范。
requirements:
run:
- python
- argparse # [py26]
- six >=1.8.0
要针对不同版本的 NumPy 构建配方并确保每个版本都是包依赖项的一部分,请在 meta.yaml
中将 numpy x.x
列为需求,并使用带有 NumPy 版本选项的 conda-build
,例如 --numpy 1.7
。
meta.yaml
文件中的行应字面上写着 numpy x.x
,并且不应有任何数字。如果 meta.yaml
文件使用 numpy x.x
,则必须将 --numpy
选项与 conda-build
一起使用。
requirements:
run:
- python
- numpy x.x
注意
自从 conda-build 3 以来,您可以不手动指定运行时需求,而是可以使用 run_exports 扩充在您的 build 和 host 部分中使用的包,然后这些包将自动添加到您的运行时需求中。
Run_constrained#
在运行时可选的包,但如果安装了这些包,则必须遵守提供的附加约束。
包名称应遵循 包匹配规范。
requirements:
run_constrained:
- optional-subpackage =={{ version }}
例如,假设我们有一个环境,其中安装了版本为 1.0 的包 “a”。如果我们安装的包 “b” 具有 “a>1.0” 的 run_constrained 条目,则 conda 将需要升级环境中的 “a” 才能安装 “b”。
这在虚拟包的上下文中尤其有用,其中 run_constrained 依赖项不是 conda 管理的包,而是一个 虚拟包,它表示 conda 无法更改的系统属性。例如,linux 上的包可能会对 __glibc>=2.12 施加 run_constrained 依赖项。这是与 CentOS 6 一致的版本界限。针对 glibc 2.12 构建的软件将与 CentOS 6 兼容。此 run_constrained 依赖项可帮助 conda 告知用户,如果其系统 glibc 版本太旧,则无法安装给定的包。
Test section#
如果存在此部分,或者配方中存在 run_test.[py,pl,sh,bat,r]
文件,则在构建完成后,包将被安装到测试环境中,并在那里运行测试。
Test files#
从配方复制到临时测试目录并在测试期间需要的测试文件。如果提供路径,则必须使用正斜杠。
test:
files:
- test-data.txt
Source files#
从源工作目录复制到临时测试目录并在测试期间需要的测试文件。
test:
source_files:
- test-data.txt
- some/directory
- some/directory/pattern*.sh
此功能在 conda-build 2.0 中添加。
Test requirements#
除了运行时需求之外,您还可以指定测试期间所需的需求。您在上面 “run” 部分中指定的运行时需求在测试期间会自动包含在内。
test:
requires:
- nose
Test commands#
作为测试的一部分运行的命令。
test:
commands:
- bsdiff4 -h
- bspatch4 -h
Python imports#
将在测试环境中导入的 Python 模块或包的列表。
test:
imports:
- bsdiff4
这相当于拥有一个包含以下内容的 run_test.py
import bsdiff4
Run test script#
如果脚本 run_test.sh
---或 .bat
、.py
、.pl
或 .r
---是配方的一部分,则会自动运行。
注意
Python .py、Perl .pl 和 R .r 脚本仅在分别是 Python、Perl 和 R 包的一部分时才有效。
Downstream tests#
知道您的软件构建并成功运行了其测试是必要的,但对于保持整个软件系统运行而言是不够的。为了确信包的新构建没有破坏其他下游软件,conda-build 支持下游测试的概念。
test:
downstreams:
- some_downstream_pkg
这表示 “当我构建此配方时,在您在此处运行我的测试套件后,还要下载并运行一些依赖于我的包的 some_downstream_pkg。” Conda-build 负责确保您刚刚构建的包被安装到用于测试 some_downstream_pkg 的环境中。如果 conda-build 由于无法满足的依赖项而无法创建该环境,它将跳过这些下游测试并向您发出警告。当您正在构建需要您重建下游依赖项的包的新版本时,通常会发生这种情况。
下游规范是完整的 conda 规范,类似于 requirements 部分。您可以在此处对您的规范放置版本约束
test:
downstreams:
- some_downstream_pkg >=2.0
可以指定多个包来运行下游测试
test:
downstreams:
- some_downstream_pkg
- other_downstream_pkg
但是,这并不意味着这些包会一起测试。相反,每个包都会测试与您的新包的兼容性,然后每个包的测试套件都会与新包分别运行。
Outputs section#
显式指定打包步骤。此部分支持多个输出,以及不同的包输出类型。格式是映射列表。子包的构建字符串由其运行时依赖项确定。此支持在 conda-build 2.1.0 中添加。
outputs:
- name: some-subpackage
version: 1.0
- name: some-other-subpackage
version: 2.0
注意
如果在 outputs 部分中指定了任何输出,则会绕过 conda-build 的默认打包行为。换句话说,如果指定了任何子包,那么您将不会获得此配方的正常顶级构建,除非显式地为其定义子包。这是现有行为的替代方案,而不是对其的补充。有关更多信息,请参阅 隐式元包。每个输出都可以有自己的版本和需求。此外,子包可以施加类似于 Pin downstream 的下游 pinning,以帮助保持您的包对齐。
Specifying files to include in output#
您可以通过 3 种方式指定要包含在包中的文件
显式文件列表。
将文件移动到构建前缀的脚本。
以上两者
显式文件列表是相对于构建前缀根目录的相对路径。显式文件列表支持 glob 表达式。也支持目录名称,它们会递归地包含内容。
警告
当将 outputs/files 定义为列表而不指定 outputs/script 时,前缀中的任何文件(包括由 host 依赖项安装的文件)如果与 glob 表达式之一匹配,则会包含在输出中。
outputs:
- name: subpackage-name
files:
- a-file
- a-folder
- *.some-extension
- somefolder/*.some-extension
可以通过将 files
定义为字典,将要 include
的文件与要 exclude
的文件分开,从而实现对文件匹配的更大控制。当使用 include/exclude 时,仅考虑由当前配方安装的文件。即,排除前缀中由 host 依赖项安装的文件。include/exclude 不能与直接在 outputs/files
中列出的 glob 表达式同时使用。与 include 和 exclude 表达式都匹配的文件将被排除。
outputs:
- name: subpackage-name
files:
include:
- a-file
- a-folder
- *.some-extension
- somefolder/*.some-extension
exclude:
- *.exclude-extension
- a-folder/**/*.some-extension
创建或移动文件到构建前缀的脚本可以是任何类型的脚本。已知脚本类型只需要指定脚本名称。当前,可识别的扩展名列表为 py、bat、ps1 和 sh。
outputs:
- name: subpackage-name
script: move-files.py
如果文件扩展名无法识别,则必须指定解释器命令。
outputs:
- name: subpackage-name
script: some-script.extension
script_interpreter: program plus arguments to run script
对于移动或创建文件的脚本,在每次脚本执行开始时,都会提供工作目录的全新副本。这确保了脚本之间的结果彼此独立。
注意
对于文件列表或脚本方法,允许多个包包含给定的文件,但可能阻止同时安装这两个包。Conda 不允许这种情况,因为它会创建不明确的运行时条件。
当同时给出脚本和文件时,首先运行脚本,然后仅打包显式文件列表中的文件。
Subpackage requirements#
像顶级配方一样,子包可以有零个或多个列为构建需求的依赖项,以及零个或多个列为运行时需求的依赖项。
列为子包构建需求的依赖项仅在该子包的打包阶段可用。
子包不会自动继承其顶级配方的任何依赖项,因此子包需要的任何构建或运行时需求都必须显式指定。
outputs:
- name: subpackage-name
requirements:
build:
- some-dep
run:
- some-dep
子包 requirements 部分也可能有一个依赖项列表,但没有 build 部分或 run 部分。这与拥有一个包含此依赖项列表的 build 部分和一个包含相同依赖项列表的 run 部分相同。
outputs:
- name: subpackage-name
requirements:
- some-dep
您还可以在安装给定的(子)包作为构建依赖项时施加运行时依赖项。例如,如果我们有一个总括的 “compilers” 包,并且在该包中,有 gcc
和 libgcc
输出,我们可以强制使用 GCC 的配方包含匹配的 libgcc 运行时需求
outputs:
- name: gcc
run_exports:
- libgcc 2.*
- name: libgcc
有关更多信息,请参阅 导出运行时需求 部分。
注意
变体表达式在这里非常强大。您可以在 run_exports
条目中将版本需求表示为 Jinja 函数,以根据配方生成的 libgcc 的实际版本插入值。请在 引用子包 中阅读有关它们的更多信息。
Implicit metapackages#
当将顶级包视为较小子包的集合时,将顶级包定义为几个子包的组合可能很方便。如果您这样做,并且您没有定义与顶级包/名称匹配的子包名称,conda-build 将为您创建一个元包。此元包具有从其依赖子包中提取的运行时需求,以便获得准确的构建字符串。
示例:在此示例中,将为 subpackage-example
创建一个元包。它将具有对 subpackage1
、subpackage2
、some-dep
和 some-other-dep
的运行时依赖项。
package:
name: subpackage-example
version: 1.0
requirements:
run:
- subpackage1
- subpackage2
outputs:
- name: subpackage1
requirements:
- some-dep
- name: subpackage2
requirements:
- some-other-dep
- name: subpackage3
requirements:
- some-totally-exotic-dep
Subpackage tests#
您可以独立于顶级包测试子包。每个单独包的独立测试脚本文件在子包的 test 部分下指定。这些文件支持与顶级 run_test.*
脚本相同的格式,即 .py、.pl、.r、.bat 和 .sh。将来可能会扩展这些格式以支持其他脚本类型。
outputs:
- name: subpackage-name
test:
script: some-other-script.py
默认情况下,run_test.*
脚本仅适用于顶级包。要将它们也应用于子包,请在 script 部分中显式列出它们
outputs:
- name: subpackage-name
test:
script: run_test.py
可以使用子包测试的可选 test/requires 部分来指定子包的测试需求。子包测试还在测试期间安装其运行时需求。
示例:在此示例中,subpackage-name
的测试安装了 some-test-dep
和 subpackage-run-req
,但不安装 some-top-level-run-req
。
requirements:
run:
- some-top-level-run-req
outputs:
- name: subpackage-name
requirements:
- subpackage-run-req
test:
script: run_test.py
requires:
- some-test-dep
Output type#
Conda-build 支持创建除 conda 包之外的其他包。目前,该支持仅包括 wheel,但随着需求的出现,可能会出现其他类型。如果未指定 type,则默认值为 conda
。
requirements:
build:
- wheel
outputs:
- name: name-of-wheel-package
type: wheel
目前,您必须在顶级 requirements/build 部分中包含 wheel 包才能构建 wheel。
在指定 type 时,name 字段是可选的,它默认为顶级配方的 package/name 字段。
requirements:
build:
- wheel
outputs:
- type: wheel
Conda-build 目前只知道如何测试 conda 包。Conda-build 确实支持使用 Twine 将包上传到 PyPI。请参阅 conda-build 帮助输出 (conda-build --help
) 以获取将被传递给 Twine 的接受参数列表。
注意
您必须使用 pip 安装 Twine 才能使其工作。
About section#
指定有关包的标识信息。该信息显示在 Anaconda.org 频道中。
about:
home: https://github.com/ilanschnell/bsdiff4
license: BSD 3-Clause
license_file: LICENSE
license_family: BSD
license_url: https://github.com/bacchusrx/bsdiff4/blob/master/LICENSE
summary: binary diff and patch using the BSDIFF4 format
description: |
This module provides an interface to the BSDIFF4 format, command line interfaces
(bsdiff4, bspatch4) and tests.
dev_url: https://github.com/ilanschnell/bsdiff4
doc_url: https://bsdiff4.readthedocs.io
doc_source_url: https://github.com/ilanschnell/bsdiff4/blob/main/README.rst
License file#
将包含软件许可证的文件添加到包元数据。许多许可证要求许可证声明与包一起分发。文件名相对于源或配方目录。该值可以是单个文件名或多个许可证文件的 YAML 列表。值也可以指向包含许可证信息的目录。目录条目必须以 /
后缀结尾(这是为了减少意外包含非许可证文件;目录的所有内容将被无条件地递归添加)。
about:
license_file:
- LICENSE
- vendor-licenses/
Prelink Message File#
与许可证文件类似,用户可以将 prelink 消息文件添加到 conda 包。
about:
prelink_message:
- prelink_message_file.txt
- folder-with-all-prelink-messages/
App section#
如果存在 app 部分,则该包是一个应用程序,这意味着它会出现在 Anaconda Navigator 中。
Entry point#
在 Navigator 中调用以启动应用程序的命令。
app:
entry: ipython notebook
Icon file#
配方中包含的图标文件。
app:
icon: icon_64x64.png
Summary#
Navigator 中使用的包摘要。
app:
summary: "The Jupyter Notebook"
Own environment#
如果为 True
,则通过 Navigator 安装应用程序会将其安装到自己的环境中。默认值为 False
。
app:
own_environment: True
Extra section#
一个无模式区域,用于以标准 YAML 格式存储非 conda 特定的元数据。
示例:存储配方维护者信息
extra:
maintainers:
- name of maintainer
Templating with Jinja#
Conda-build 支持 meta.yaml
文件中的 Jinja 模板。
示例:以下 meta.yaml
将与为 Git 仓库定义的 GIT 值一起使用。配方包含在 Git 仓库的根目录中,因此 git_url
是 ../
package:
name: mypkg
version: {{ GIT_DESCRIBE_TAG }}
build:
number: {{ GIT_DESCRIBE_NUMBER }}
# Note that this will override the default build string with the Python
# and NumPy versions
string: {{ GIT_BUILD_STR }}
source:
git_url: ../
Conda-build 检查您使用的 Jinja2 变量是否已定义,如果未定义,则会产生清晰的错误。
您还可以对这些环境变量使用不同的语法,该语法允许设置默认值,尽管它有点冗长。
示例:使用允许默认值的语法的前一个示例的版本
package:
name: mypkg
version: {{ environ.get('GIT_DESCRIBE_TAG', '') }}
build:
number: {{ environ.get('GIT_DESCRIBE_NUMBER', 0) }}
# Note that this will override the default build string with the Python
# and NumPy versions
string: {{ environ.get('GIT_BUILD_STR', '') }}
source:
git_url: ../
使用模板的另一种可能性是从您下载的源代码中获取数据。
示例:处理项目的 setup.py
并获取版本和其他元数据
{% set data = load_setup_py_data() %}
package:
name: conda-build-test-source-setup-py-data
version: {{ data.get('version') }}
# source will be downloaded prior to filling in jinja templates
# Example assumes that this folder has setup.py in it
source:
path_url: ../
这些函数与任何其他变量(如 Git 和 Mercurial)完全兼容。
将此任意扩展到其他函数需要函数在 Jinja 处理之前预定义,这在实践中意味着更改 conda-build 源代码。请参阅 conda-build 问题跟踪器。
有关更多信息,请参阅 Jinja2 模板文档 和 可用环境变量列表。
Jinja 模板在构建过程中进行评估。要检索完全渲染的 meta.yaml
,请使用 conda render 命令。
Loading data from other files#
Jinja2 还有几个附加函数可用,可用于从其他文件加载数据。这些函数是 load_setup_py_data
、load_file_regex
、load_file_data
和 load_str_data
。
load_setup_py_data
:从setup.py
文件加载数据。这对于从项目的setup.py
文件中获取版本等元数据非常有用。例如{% set data = load_setup_py_data() %} {% set version = data.get('version') %} package: name: foo version: {{ version }}
load_file_regex
:在文件中搜索正则表达式,将第一个匹配项作为 Python re.Match 对象返回。例如,使用
load_file_regex(load_file, regex_pattern, from_recipe_dir=False) -> re.Match | None
{% set version_match = load_file_regex( load_file="conda_package_streaming/__init__.py", regex_pattern='^__version__ = "(.+)"') %} {% set version = version_match[1] %} package: version: {{ version }}
load_file_data
:解析 JSON、TOML 或 YAML 文件并从中加载数据。例如,您可以使用它从pyproject.toml
加载 poetry 配置。这尤其有用,因为setup.py
不再是定义项目元数据的唯一标准方法(请参阅 PEP 517 和 PEP 518){% set pyproject = load_file_data('pyproject.toml') %} {% set poetry = pyproject.get('tool', {}).get('poetry') %} package: name: {{ poetry.get('name') }} version: {{ poetry.get('version') }}
load_str_data
:从字符串加载和解析数据。这类似于load_file_data
,但它接受字符串而不是文件作为参数。乍一看这可能看起来毫无意义,但您可以使用它通过环境变量传递更复杂的数据结构。例如{% set extra_deps = load_str_data(environ.get("EXTRA_DEPS", []), "json") %} requirements: run: - ... {% for dep in extra_deps %} - {{ dep }} {% endfor %}
然后,您可以将
EXTRA_DEPS
环境变量传递给构建,如下所示EXTRA_DEPS='["foo =1.0", "bar >=2.0"]' conda build path/to/recipe
函数 load_setup_py_data
、load_file_regex
和 load_file_data
都接受参数 from_recipe_dir
和 recipe_dir
。如果 from_recipe_dir
设置为 true,则还必须传递 recipe_dir
。在这种情况下,将在相对于配方目录的位置搜索相关文件。否则,将在源中搜索文件(在下载和提取后,如果需要)。如果给定文件是绝对路径,则不会搜索这两个目录。
函数 load_file_data
和 load_str_data
也接受 *args
和 **kwargs
,它们会逐字传递给用于解析文件的函数。对于 JSON,这将是 json.load
;对于 TOML,是 toml.load
;对于 YAML,是 yaml.safe_load
。
Conda-build specific Jinja2 functions#
除了默认的 Jinja2 功能外,在 conda-build 过程中还可以使用其他 Jinja 函数:pin_compatible
、pin_subpackage
、compiler
和 resolved_packages
。有关前 3 个函数的定义,请参阅 额外的 Jinja2 函数。resolved_packages
的定义如下所示
resolved_packages('environment_name')
:返回最终的软件包列表(形式为package_name version build_string
),这些软件包在requirements:host
或requirements:build
中列出。 这包括所有将安装在 host 或 build 环境中的软件包(包括间接依赖项)。environment_name
必须是host
或build
之一。 此函数对于创建元软件包非常有用,这些元软件包希望将其直接和间接依赖项精确匹配。 例如requirements: host: - curl 7.55.1 run: {% for package in resolved_packages('host') %} - {{ package }} {% endfor %}
可能会呈现为(取决于软件包依赖关系和平台)
requirements: host: - curl 7.55.1 run: - ca-certificates 2017.08.26 h1d4fec5_0 - curl 7.55.1 h78862de_4 - libgcc-ng 7.2.0 h7cc24e2_2 - libssh2 1.8.0 h9cfc8f7_4 - openssl 1.0.2n hb7f436b_0 - zlib 1.2.11 ha838bed_2
在此,
resolved_packages
的输出是['ca-certificates 2017.08.26 h1d4fec5_0', 'curl 7.55.1 h78862de_4', 'libgcc-ng 7.2.0 h7cc24e2_2', 'libssh2 1.8.0 h9cfc8f7_4', 'openssl 1.0.2n hb7f436b_0', 'zlib 1.2.11 ha838bed_2']
预处理选择器#
您可以向任何行添加选择器,这些选择器用作预处理阶段的一部分。 在读取 meta.yaml
文件之前,将评估每个选择器,如果它为 False
,则删除它所在的行。 选择器的形式为行尾的 # [<selector>]
。
source:
url: http://path/to/unix/source # [not win]
url: http://path/to/windows/source # [win]
注意
预处理选择器在 Jinja 模板之后进行评估。
选择器是执行的有效 Python 语句。 定义了以下变量。 除非另有说明,否则变量均为布尔值。
x86 |
如果系统架构为 x86,则为 True,包括 32 位和 64 位,适用于 Intel 或 AMD 芯片。 |
x86_64 |
如果系统架构为 x86_64,则为 True,即 64 位,适用于 Intel 或 AMD 芯片。 |
linux |
如果平台为 Linux,则为 True。 |
linux32 |
如果平台为 Linux 且 Python 架构为 32 位并使用 x86,则为 True。 |
linux64 |
如果平台为 Linux 且 Python 架构为 64 位并使用 x86,则为 True。 |
armv6l |
如果平台为 Linux 且 Python 架构为 armv6l,则为 True。 |
armv7l |
如果平台为 Linux 且 Python 架构为 armv7l,则为 True。 |
aarch64 |
如果平台为 Linux 且 Python 架构为 aarch64,则为 True。 |
ppc64le |
如果平台为 Linux 且 Python 架构为 ppc64le,则为 True。 |
s390x |
如果平台为 Linux 且 Python 架构为 s390x,则为 True。 |
osx |
如果平台为 macOS,则为 True。 |
arm64 |
如果平台为 macOS 或 Windows 且 Python 架构为 arm64,则为 True。 |
unix |
如果平台为 macOS 或 Linux 或 emscripten,则为 True。 |
win |
如果平台为 Windows,则为 True。 |
win32 |
如果平台为 Windows 且 Python 架构为 32 位,则为 True。 |
win64 |
如果平台为 Windows 且 Python 架构为 64 位,则为 True。 |
py |
Python 版本,以整数形式表示,例如 |
py3k |
如果 Python 主要版本为 3,则为 True。 |
py2k |
如果 Python 主要版本为 2,则为 True。 |
py27 |
如果 Python 版本为 2.7,则为 True。 不建议使用此选择器,而建议使用比较运算符(例如 py==27)。 |
py34 |
如果 Python 版本为 3.4,则为 True。 不建议使用此选择器,而建议使用比较运算符(例如 py==34)。 |
py35 |
如果 Python 版本为 3.5,则为 True。 不建议使用此选择器,而建议使用比较运算符(例如 py==35)。 |
py36 |
如果 Python 版本为 3.6,则为 True。 不建议使用此选择器,而建议使用比较运算符(例如 py==36)。 |
np |
NumPy 版本,以整数形式表示,例如 |
build_platform |
conda 可执行文件的本机 subdir |
不鼓励使用 Python 版本选择器 py27、py34 等,而建议使用更通用的比较运算符。 此系列中的其他选择器将不会添加到 conda-build 中。
请注意,对于 conda 支持的每个具有操作系统和架构的 subdir,会分别为操作系统和架构创建两个预处理选择器,除非架构不是有效的 python 表达式(特别是 *-32 和 *-64)。
因为选择器是任何有效的 Python 表达式,所以可以实现复杂的逻辑
source:
url: http://path/to/windows/source # [win]
url: http://path/to/python2/unix/source # [unix and py2k]
url: http://path/to/python3/unix/source # [unix and py>=35]
注意
选择器仅删除它们所在的行,因此您可能需要在多行上放置相同的选择器
source:
url: http://path/to/windows/source # [win]
md5: 30fbf531409a18a48b1be249052e242a # [win]
url: http://path/to/unix/source # [unix]
md5: 88510902197cba0d1ab4791e0f41a66e # [unix]
注意
要选择多个操作系统,请使用 or
语句。 虽然可能很想使用 skip: True # [win and osx]
,但这仅在平台同时为 windows 和 osx 时才有效(即永远不会发生)。
build:
skip: True # [win or osx]