ExternalData

管理存储在源代码树外部的数据文件

简介

使用此模块可以明确地引用存储在源代码树外部的数据文件,并在构建时从任意本地和远程内容寻址位置获取它们。此模块提供的函数识别语法为 DATA{<name>} 的参数作为外部数据的引用,将它们替换为这些数据的本地副本的完整路径,并创建构建规则以获取和更新本地副本。

例如

include(ExternalData)
set(ExternalData_URL_TEMPLATES "file:///local/%(algo)/%(hash)"
                               "file:////host/share/%(algo)/%(hash)"
                               "http://data.org/%(algo)/%(hash)")
ExternalData_Add_Test(MyData
  NAME MyTest
  COMMAND MyExe DATA{MyInput.png}
  )
ExternalData_Add_Target(MyData)

当测试 MyTest 运行时,DATA{MyInput.png} 参数将被替换为磁盘上数据文件 MyInput.png 的真实实例的完整路径。如果源代码树包含内容链接,例如 MyInput.png.md5,则 MyData 目标会在构建树中创建一个真实的 MyInput.png

模块函数

ExternalData_Expand_Arguments

ExternalData_Expand_Arguments 函数评估其参数中的 DATA{} 引用并构建新的参数列表。

ExternalData_Expand_Arguments(
  <target>   # Name of data management target
  <outVar>   # Output variable
  [args...]  # Input arguments, DATA{} allowed
  )

它将参数中的每个 DATA{} 引用替换为磁盘上真实数据文件的完整路径,该文件将在 <target> 构建后存在。

ExternalData_Add_Test

ExternalData_Add_Test 函数围绕 CMake add_test() 命令进行包装,但支持其参数中的 DATA{} 引用。

ExternalData_Add_Test(
  <target>   # Name of data management target
  ...        # Arguments of add_test(), DATA{} allowed
  )

它通过 ExternalData_Expand_Arguments 传递其参数,然后使用结果调用 add_test() 命令。

3.31 版本中的变化: 如果 <target> 之后的参数定义了一个测试,并且其可执行文件是一个 CMake 目标,则该目标的 TEST_LAUNCHERCROSSCOMPILING_EMULATOR 属性中的空值将被保留。请参阅策略 CMP0178

ExternalData_Add_Target

ExternalData_Add_Target 函数创建一个自定义目标来管理外部存储的数据文件的本地实例。

ExternalData_Add_Target(
  <target>                  # Name of data management target
  [SHOW_PROGRESS <ON|OFF>]  # Show progress during the download
  )

它根据需要在目标中创建自定义命令,以便为之前由此模块提供的其他函数评估的每个 DATA{} 引用提供数据文件。数据文件可以从 ExternalData_URL_TEMPLATES 变量中指定的 URL 模板之一获取,或者可以在 ExternalData_OBJECT_STORES 变量中指定的路径之一中本地找到。

3.20 版本中新增: 可以传递 SHOW_PROGRESS 参数以在下载对象期间抑制进度信息。如果未提供,则对于 NinjaNinja Multi-Config 生成器,默认为 OFF,否则为 ON

通常只需要一个目标来管理项目中的所有外部数据。在处理完所有数据引用后,在配置结束时调用此函数一次。

模块变量

以下变量配置行为。应在调用此模块提供的任何函数之前设置它们。

ExternalData_BINARY_ROOT

ExternalData_BINARY_ROOT 变量可以设置为目录,以保存由扩展的 DATA{} 引用命名的真实数据文件。默认值为 CMAKE_BINARY_DIR。目录布局将镜像 ExternalData_SOURCE_ROOT 下内容链接的目录布局。

ExternalData_CUSTOM_SCRIPT_<key>

3.2 版本中新增。

ExternalData_URL_TEMPLATES 列表的条目中,指定由 <key> 标识的 .cmake 自定义获取脚本的完整路径。请参阅 自定义获取脚本

ExternalData_LINK_CONTENT 变量可以设置为受支持的哈希算法的名称,以启用将 DATA{} 语法引用的真实数据文件自动转换为内容链接。对于每个这样的 <file>,都会创建一个名为 <file><ext> 的内容链接。原始文件将重命名为 .ExternalData_<algo>_<hash> 的形式,以便将其暂存以供将来传输到 URL 模板列表中的一个位置(通过此模块范围之外的方法)。内容链接创建的数据获取规则将在无法使用任何 URL 模板找到对象时使用暂存的对象。

3.3 版本中新增。

由扩展的 DATA{} 引用命名的真实数据文件可以通过符号链接在某些平台上在 ExternalData_BINARY_ROOT 下提供。可以设置 ExternalData_NO_SYMLINKS 变量以禁用符号链接的使用并启用副本的使用。

ExternalData_OBJECT_STORES

ExternalData_OBJECT_STORES 变量可以设置为存储使用布局 <dir>/%(algo)/%(hash) 的对象的本地目录列表。这些目录将首先被搜索以查找所需的对象。如果对象在任何存储中都不可用,则它将使用 URL 模板远程获取并添加到列出的第一个本地存储中。如果没有指定存储,则默认值为构建树内的某个位置。

ExternalData_SERIES_PARSE
ExternalData_SERIES_PARSE_PREFIX
ExternalData_SERIES_PARSE_NUMBER
ExternalData_SERIES_PARSE_SUFFIX
ExternalData_SERIES_MATCH

参见 引用文件序列

ExternalData_SOURCE_ROOT

可以将 ExternalData_SOURCE_ROOT 变量设置为包含任何由 DATA{} 引用命名的路径的最高源目录。默认值为 CMAKE_SOURCE_DIRExternalData_SOURCE_ROOTCMAKE_SOURCE_DIR 必须引用单个源发行版内的目录(例如,它们在一个 tarball 中一起提供)。

ExternalData_TIMEOUT_ABSOLUTE

ExternalData_TIMEOUT_ABSOLUTE 变量设置下载的绝对超时时间(以秒为单位),默认值为 300 秒。设置为 0 以禁用强制执行。

ExternalData_TIMEOUT_INACTIVITY

ExternalData_TIMEOUT_INACTIVITY 变量设置下载的空闲超时时间(以秒为单位),默认值为 60 秒。设置为 0 以禁用强制执行。

ExternalData_URL_ALGO_<algo>_<key>

3.3 版本中新增。

指定自定义 URL 组件,以替换表单为 %(algo:<key>) 的 URL 模板占位符,其中 <key> 是有效的 C 标识符,当通过哈希算法 <algo> 引用对象时。如果未定义,则默认 URL 组件对于任何 <key> 仅为 <algo>

ExternalData_URL_TEMPLATES

可以将 ExternalData_URL_TEMPLATES 设置为提供 URL 模板列表,每个模板中使用占位符 %(algo)%(hash)。数据获取规则会按顺序尝试每个 URL 模板,方法是将哈希算法名称替换为 %(algo),并将哈希值替换为 %(hash)。或者,可以使用 %(algo:<key>)ExternalData_URL_ALGO_<algo>_<key> 变量来获得远程 URL 的更大灵活性。

引用文件

引用单个文件

DATA{} 语法是字面量, <name> 是源代码树中的完整路径或相对路径。源代码树必须包含 <name> 处的真实数据文件或 <name><ext> 处的“内容链接”,其中包含使用与 <ext> 对应的哈希算法计算的真实文件的哈希值。例如,参数 DATA{img.png} 可以由当前源目录中的真实 img.png 文件或包含其 MD5 校验和的 img.png.md5 文件满足。

版本 3.8 中新增: 支持具有相同名称但不同哈希算法的多个内容链接(例如 img.png.sha256img.png.sha1),只要它们都对应于同一个真实文件。这允许从由不同哈希算法索引的源获取对象。

引用文件序列

可以使用表单 DATA{<name>,:} 告知 DATA{} 语法获取文件序列,其中 : 是字面量。如果源代码树包含一组命名类似序列的文件或内容链接,则对其中一个成员的引用会添加规则以获取所有这些成员。尽管获取了序列的所有成员,但只有最初由 DATA{} 参数命名的文件会被替换。默认配置识别以 #.ext_#.ext.#.ext-#.ext 结尾的文件序列名称,其中 # 是十进制数字序列, .ext 是任何单个扩展名。使用解析 <number><suffix> 部分的正则表达式配置它,这些部分来自 <name> 的末尾。

ExternalData_SERIES_PARSE = regex of the form (<number>)(<suffix>)$

对于更复杂的情况,请设置

ExternalData_SERIES_PARSE = regex with at least two () groups
ExternalData_SERIES_PARSE_PREFIX = <prefix> regex group number, if any
ExternalData_SERIES_PARSE_NUMBER = <number> regex group number
ExternalData_SERIES_PARSE_SUFFIX = <suffix> regex group number

使用与命名为 <prefix><number><suffix> 的系列成员的 <number> 部分匹配的正则表达式配置系列编号匹配。

ExternalData_SERIES_MATCH = regex matching <number> in all series members

请注意,系列的 <suffix> 不包含哈希算法扩展名。

引用关联文件

DATA{} 语法可以替代匹配与命名文件关联并在同一目录中包含的文件。可以使用语法 DATA{<name>,<opt1>,<opt2>,...} 通过选项指定关联文件。每个选项都可以按名称指定一个文件,或者使用语法 REGEX:<regex> 指定正则表达式以匹配文件名。例如,参数

DATA{MyData/MyInput.mhd,MyInput.img}                   # File pair
DATA{MyData/MyFrames00.png,REGEX:MyFrames[0-9]+\\.png} # Series

将在命令行上传递 MyInput.mhaMyFrames00.png,但确保关联文件存在于它们旁边。

引用目录

DATA{} 语法可以使用尾随斜杠和关联文件列表来引用目录。表单 DATA{<name>/,<opt1>,<opt2>,...} 添加规则以获取目录中与关联文件选项之一匹配的任何文件。例如,参数 DATA{MyDataDir/,REGEX:.*} 将在命令行上传递到 MyDataDir 目录的完整路径,并确保该目录包含与 MyDataDir 源目录中的每个文件或内容链接相对应的文件。

版本 3.3 中新增: 为了匹配子目录中的关联文件,请指定 RECURSE: 选项,例如 DATA{MyDataDir/,RECURSE:,REGEX:.*}

哈希算法

支持以下哈希算法

%(algo)     <ext>     Description
-------     -----     -----------
MD5         .md5      Message-Digest Algorithm 5, RFC 1321
SHA1        .sha1     US Secure Hash Algorithm 1, RFC 3174
SHA224      .sha224   US Secure Hash Algorithms, RFC 4634
SHA256      .sha256   US Secure Hash Algorithms, RFC 4634
SHA384      .sha384   US Secure Hash Algorithms, RFC 4634
SHA512      .sha512   US Secure Hash Algorithms, RFC 4634
SHA3_224    .sha3-224 Keccak SHA-3
SHA3_256    .sha3-256 Keccak SHA-3
SHA3_384    .sha3-384 Keccak SHA-3
SHA3_512    .sha3-512 Keccak SHA-3

版本 3.8 中新增: 添加了 SHA3_* 哈希算法。

请注意,哈希仅用于唯一数据标识和下载验证。

自定义获取脚本

3.2 版本中新增。

当必须从 ExternalData_URL_TEMPLATES 变量中指定的 URL 模板之一获取数据文件时,通常使用 file(DOWNLOAD) 命令进行下载。可以通过使用表单为 ExternalDataCustomScript://<key>/<loc> 的 URL 模板来指定自定义获取脚本的使用。 <key> 必须是 C 标识符, <loc> 必须包含 %(algo)%(hash) 占位符。与密钥对应的变量 ExternalData_CUSTOM_SCRIPT_<key> 必须设置为 .cmake 脚本文件的完整路径。将包含该脚本以执行实际获取,并提供以下变量

ExternalData_CUSTOM_LOCATION

加载自定义获取脚本时,此变量将设置为 URL 的位置部分,其中将包含替换的哈希算法名称和内容哈希值。

ExternalData_CUSTOM_FILE

加载自定义获取脚本时,此变量将设置为脚本必须存储获取内容的文件的完整路径。文件名未指定,不应以任何方式解释。

自定义获取脚本应将获取的内容存储在文件中或设置变量

ExternalData_CUSTOM_ERROR

当自定义获取脚本无法获取请求的内容时,它必须将此变量设置为简短的一行消息,描述失败的原因。