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_HTTPHEADERS

在 4.0 版本中添加。

可以使用 ExternalData_HTTPHEADERS 变量来提供标头列表,每个元素包含一个标头,格式为 Key: Value。 请参阅 file(DOWNLOAD) 命令的 HTTPHEADER 选项。

可以设置 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> 引用的对象时。 如果未定义,则对于任何 <key>,默认 URL 组件仅为 <algo>

ExternalData_URL_TEMPLATES

可以设置 ExternalData_URL_TEMPLATES 以提供 URL 模板列表,每个模板中使用占位符 %(algo)%(hash)。 数据获取规则按顺序尝试每个 URL 模板,方法是将哈希算法名称替换为 %(algo),并将哈希值替换为 %(hash)。 或者,可以使用带有 ExternalData_URL_ALGO_<algo>_<key> 变量的 %(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{} 语法使用 DATA{<name>,:} 形式获取文件序列,其中 : 是字面的。 如果源树包含一组文件或内容链接,这些文件或内容链接的名称类似于序列,则对一个成员的引用会添加规则来获取所有成员。 尽管获取了序列的所有成员,但只有最初由 DATA{} 参数命名的文件才会被替换。 默认配置识别以 #.ext, _#.ext, .#.ext-#.ext 结尾的文件序列名称,其中 # 是一系列十进制数字,.ext 是任何单个扩展名。 使用正则表达式配置它,该正则表达式从 <name> 的末尾解析 <number><suffix> 部分

ExternalData_SERIES_PARSE - 形式为 (<number>)(<suffix>)$ 的正则表达式。

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

  • ExternalData_SERIES_PARSE - 至少有两个 () 组的正则表达式。

  • ExternalData_SERIES_PARSE_PREFIX - <prefix> 的正则表达式组号(如果有)。

  • ExternalData_SERIES_PARSE_NUMBER - <number> 的正则表达式组号。

  • ExternalData_SERIES_PARSE_SUFFIX - <suffix> 的正则表达式组号。

使用正则表达式配置系列编号匹配,该正则表达式匹配名为 <prefix><number><suffix> 的所有系列成员中的 <number> 部分

ExternalData_SERIES_MATCH - 匹配所有系列成员中 <number> 的正则表达式

请注意,序列的 <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>

描述

MD5

.md5

消息摘要算法 5, RFC 1321

SHA1

.sha1

美国安全哈希算法 1, RFC 3174

SHA224

.sha224

美国安全哈希算法, RFC 4634

SHA256

.sha256

美国安全哈希算法, RFC 4634

SHA384

.sha384

美国安全哈希算法, RFC 4634

SHA512

.sha512

美国安全哈希算法, 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

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