CPM 参考

rapids_cpm 函数允许项目查找或构建依赖项,并内置对这些依赖项的跟踪,以提供正确的导出支持。

rapids-cmake 包默认设置

rapids-cmake 提供了一系列预定义的包,以确保所有使用者使用相同版本的依赖项。每个预配置包使用的确切版本可以在页面底部找到。

rapids-cmake 包覆盖

rapids-cmake 允许项目覆盖由 rapids-cmake 提供的预定义包的默认值,同时也会覆盖任何 rapids_cpm_find(), CPM, 和 FetchContent() 包调用。

当项目的覆盖设置存在时,将不会对该项目进行 find_package()<cmake:command:find_package> 搜索。这样做是为了确保使用请求的修改版本。

如果一个项目在多个覆盖文件中列出,将使用第一个文件的值,之后对该包的所有调用都将被忽略。这种“先记录者赢”的方法用于匹配 FetchContent,并允许父项目覆盖子项目。

如果覆盖设置是针对现有默认项目,只需要指定要覆盖的字段。

例如,如果您想更改 fmt 的版本,您可以这样做:

{
  "packages": {
    "fmt": {
      "version": "100.1.0"
    }
  }
}

如果您想指定一个全新的项目,您至少需要指定所有必需的字段:

{
  "packages": {
    "new_dependency": {
      "version": "1.2.3",
      "git_url": "https://github.com/org/new_dependency.git",
      "git_tag": "${version}"
    }
  }
}

可重现的 rapids-cmake 构建

rapids-cmake 默认的 versions.json 对依赖项使用分支名或 git 标签名。这样做是为了让项目可以“随依赖项同步更新”。这直接与可重现发布包的概念冲突,即可重现发布包每次构建时都会生成按位相同的文件。

rapids_cpm_generate_pinned_versions() 可用于生成一组明确固定的 git SHA1 值,对应于正在使用的 rapids-cmake 依赖项集。这使得构建时可获得一组完全可重现的依赖项。

要在您的发布 CI/CD 中利用此行为,需要进行如下设置:

1. 在构建期间通过 rapids_cpm_generate_pinned_versions() 或指定 RAPIDS_CMAKE_CPM_PINNED_VERSIONS_FILE 来启用固定版本文件的生成。 2. 如果构建成功,创建发布分支并提交生成的固定 versions.json 到仓库。 3. 现在可以通过将 RAPIDS_CMAKE_CPM_OVERRIDE_VERSION_FILE 设置为生成的固定版本文件的路径来使用固定版本重新构建项目。

rapids-cpm 命令行控制

rapids-cpm 提供了多个命令行选项来控制行为。

有些构建完全离线执行,默认的包和覆盖 url 无法使用。在这些情况下,您可以使用变量 RAPIDS_CMAKE_CPM_OVERRIDE_VERSION_FILE 来提供新的 versions.json,该文件将代替该项目中指定的所有覆盖设置。这将允许您为所有依赖项指定自定义内部 url,而无需修改项目源代码。

` cmake -DRAPIDS_CMAKE_CPM_OVERRIDE_VERSION_FILE=<abs/path/to/custom/override_versions.json> .... `

要请求生成一个固定的包覆盖文件而无需修改项目,请使用变量 RAPIDS_CMAKE_CPM_PINNED_VERSIONS_FILE

` cmake -DRAPIDS_CMAKE_CPM_PINNED_VERSIONS_FILE `

附加的 CPM 命令行控制

此外,任何 CPM 选项都可以与 rapids-cpm 一起使用。完整的 CPM 选项列表可以在 CPM README.md 中找到;我们在下面记录了一些最重要的选项。

如果您需要明确指定一个包必须被下载而不是在本地搜索,您需要启用变量 CPM_DOWNLOAD_<package_name>

` cmake -DCPM_DOWNLOAD_<package_name>=ON .... `

如果您需要明确指定所有包必须被下载而不是在本地搜索,您需要启用变量 CPM_DOWNLOAD_ALL

` cmake -DCPM_DOWNLOAD_ALL=ON .... `

rapids-cmake 包版本格式

rapids-cmake 使用一个 JSON 文件来编码项目的版本以及如何下载项目。

JSON 格式是一个根对象,其中包含 packages 对象。

packages 对象包含所有支持的包的键/值映射,其中键是项目的区分大小写的名称,值是 project 对象,如下例所示:

{
  "packages": {
    "Thrust": {
      "version": "1.12.0",
      "git_url": "https://github.com/NVIDIA/thrust.git",
      "git_tag": "${version}",
      "git_shallow": true,
      "always_download": true,
      "exclude_from_all": false
    }
  }
}

项目对象字段

每个 project 对象必须包含以下字段,以便 rapids-cmake 可以根据需要正确使用 CPM 查找或下载项目。

version

一个必需的字符串,表示项目的版本,当查找项目的本地安装副本时,将由 rapids_cpm_find() 使用。

支持以下占位符
  • ${rapids-cmake-version} 将被评估为当前的 rapids-cmake cal-ver 值的“主要.次要”版本(major.minor)。

  • $ENV{variable} 将被评估为列出的环境变量的内容

git_url

一个必需的字符串,表示 git url,当找不到项目的本地安装副本时,将由 rapids_cpm_find() 用于在本地克隆项目。

支持以下占位符
  • ${rapids-cmake-version} 将被评估为当前的 rapids-cmake cal-ver 值的“主要.次要”版本(major.minor)。

  • ${version} 将被评估为 version 字段的内容。

  • $ENV{variable} 将被评估为列出的环境变量的内容

git_tag

一个必需的字符串,表示 git 标签,当找不到项目的本地安装副本时,将由 rapids_cpm_find() 用于在本地克隆项目。

支持以下占位符
  • ${rapids-cmake-version} 将被评估为当前的 rapids-cmake cal-ver 值的“主要.次要”版本(major.minor)。

  • ${version} 将被评估为 version 字段的内容。

  • $ENV{variable} 将被评估为列出的环境变量的内容

git_shallow

一个可选的布尔值,表示是否应该进行浅层 git 克隆。

如果不存在此字段,默认值为 true

exclude_from_all

一个可选的布尔值,表示 CMake 的 `EXCLUDE_FROM_ALL` 属性。如果设置为 true,并且项目是从源代码构建的,该项目的所有目标将从 ALL 构建规则中排除。这意味着消费项目未使用的任何目标都不会被编译。当一个项目生成了不需要的多个目标且不希望承担构建它们的成本时,此功能很有用。

如果不存在此字段,默认值为 false

always_download

一个可选的布尔值,表示 CPM 是否应该仅下载包( CPM_DOWNLOAD_ALL )而不是先在机器上搜索它。

此字段的默认值为 false,除非满足以下所有条件。
  • 项目同时存在于默认文件和覆盖文件中

  • 在覆盖设置中存在 git_url, git_tag, patches

  • 定义中存在补丁条目

patches

一个可选的字典列表,每个字典代表一个 git 补丁集,用于在项目从源代码构建时应用到项目。

如果此字段存在于默认包中,当该包存在覆盖文件条目时,此值将被忽略。这确保了在覆盖设置存在时,仅使用覆盖设置中的补丁、git url 或 proprietary_binary 条目。

正在使用的包定义中存在补丁条目将导致 always_download 值始终为 true。

补丁数组中的每个字典包含以下字段

file

{
  "patches": [
    {
      "file": "Thrust/cub_odr.diff",
      "issue": "cub kernel dispatch ODR [https://github.com/NVIDIA/cub/issues/545]",
      "fixed_in": ""
    }
  ]
}

inline_patch 互斥的字符串字段。只能提供其中一个字段。

要应用的 git diff ( .diff ) 或 patch ( .patch ) 文件的绝对或相对路径。相对路径是相对于 rapids-cmake/cpm/patches 目录进行评估的。

支持以下占位符
  • ${current_json_dir} 将被评估为包含当前 json 文件的目录的绝对路径

inline_patch

{
  "patches": [
    {
      "inline_patch": {
        "type": "patch",
        "content": [
          "From deacd3fafd7fcfee954ae3044ae3ab60d36a9f3a Mon Sep 17 00:00:00 2001",
          "From: Robert Maynard <rmaynard@nvidia.com>",
          "Date: Wed, 31 Jan 2024 15:00:47 -0500",
          "Subject: [PATCH 1/2] Move GIT SHA1",
          "",
          "---",
          " git_file_1.txt | 1 +",
          " 1 file changed, 1 insertion(+)",
          " create mode 100644 git_file_1.txt",
          "",
          "diff --git a/git_file_1.txt b/git_file_1.txt",
          "new file mode 100644",
          "index 00000000..b242c360",
          "--- /dev/null",
          "+++ b/git_file_1.txt",
          "@@ -0,0 +1 @@",
          "+added file",
          "--",
          "2.43.0",
          ""
        ]
      },
      "issue": "Example of an inline patch",
      "fixed_in": ""
    }
  ]
}

file 互斥的字典字段。只能提供其中一个字段。

inline_patch 的必需键是
  • type 补丁的格式,可以是 diff ( git diff ) 或 patch ( git format-patch )。

  • content 补丁文件的行,表示为字符串数组(每个元素是一行)。

issue

一个必需的字符串,解释需要此补丁的原因。最好字符串中还包含此补丁解决的上游问题或 PR 的 URL。

fixed_in

一个必需的条目,表示从哪个版本开始不再需要此补丁。如果所有版本都需要此补丁,应提供一个空字符串。

required

一个可选的布尔值,表示是否要求补丁正确应用。

此字段的默认值为 false

build

一个可选的布尔值,指定此补丁是否为构建补丁。构建补丁仅影响构建过程,不影响运行时功能或导出的头文件。如果所有补丁都是构建补丁,则无需下载项目,并且可以使用 find_package() 找到。

此字段的默认值为 false

proprietary_binary

一个可选的字典,以 CPU 架构和操作系统为键,URL 为值,表示预构建的专有版本库的下载链接。这在项目的搜索逻辑中创建了一个新条目

  • 搜索与 version 键匹配的本地版本
    • always_download 禁用

  • 如果存在有效的 OS + CPU Arch,则下载专有版本
    • USE_PROPRIETARY_BLOB 关闭禁用

  • 回退到使用 git url 和 tag

为了确定正确的键,CMake 将查询与 <arch>-<os> 的小写值匹配的键,其中 arch 对应于 CMAKE_SYSTEM_PROCESSORos 对应于 CMAKE_SYSTEM_NAME

如果不存在这样的键,使用 proprietary_binary 的请求将被忽略。

{
  "proprietary_binary": {
    "aarch64-linux": "<url>",
    "x86_64-linux": "<url>"
  }
}
由于这表示一个专有二进制文件,只有以下包支持此命令
  • nvcomp

由于专有二进制文件的要求,需要用户明确选择启用。因此要使用此二进制文件,调用者必须调用相关的 rapids_cpm 命令,并将 USE_PROPRIETARY_BLOB 设置为 ON

支持以下占位符
  • ${rapids-cmake-version} 将被评估为当前的 rapids-cmake cal-ver 值的“主要.次要”版本(major.minor)。

  • ${version} 将被评估为 version 字段的内容。

  • ${cuda-toolkit-version} 将被评估为当前 CUDA Toolkit 版本的“主要.次要”版本(major.minor)。

  • ${cuda-toolkit-version-major} 将被评估为当前 CUDA Toolkit 版本的“主要”版本(major)。

  • ${cuda-toolkit-version-mapping} 将被评估为当前 CUDA Toolkit 主要版本值在 json cuda_version_mapping 条目中的内容

  • $ENV{variable} 将被评估为列出的环境变量的内容

如果此字段存在于默认包中,当该包存在覆盖文件条目时,此值将被忽略。这确保了在覆盖设置中仅使用 git url 或 proprietary_binary 条目。

proprietary_binary_cuda_version_mapping

一个可选的字典,以 CUDA 主要版本为键,任意值为值,这些值用于计算预构建的专有二进制文件在 proprietary_binary 字典中的下载 url。

{
  "proprietary_binary_cuda_version_mapping": {
    "11": "11.8",
    "12": "12.3"
  },
  "proprietary_binary": {
    "aarch64-linux": "<url>/binary_${cuda-toolkit-version-mapping}.tar.gz",
    "x86_64-linux": "<url>/binary_${cuda-toolkit-version-mapping}.tar.gz"
  }
}
由于这代表了专有二进制字典所需的元信息,只有以下包支持此条目
  • nvcomp

rapids-cmake 包版本

{
  "packages": {
    "benchmark": {
      "version": "1.8.0",
      "git_url": "https://github.com/google/benchmark.git",
      "git_tag": "v${version}"
    },
    "bs_thread_pool": {
      "version": "4.1.0",
      "git_url": "https://github.com/bshoshany/thread-pool.git",
      "git_tag": "097aa718f25d44315cadb80b407144ad455ee4f9"
    },
    "CCCL": {
      "version": "2.7.0",
      "git_shallow": false,
      "git_url": "https://github.com/NVIDIA/cccl.git",
      "git_tag": "v${version}",
      "patches": [
        {
          "file": "cccl/backport-suppress-execution-checks.patch",
          "issue": "backport suppression for execution types for vocabulary types https://github.com/NVIDIA/cccl/pull/3578",
          "fixed_in": "3.0.0"
        }
      ]
    },
    "cuco": {
      "version": "0.0.1",
      "git_shallow": false,
      "always_download": true,
      "git_url": "https://github.com/NVIDIA/cuCollections.git",
      "git_tag": "7b422c00f3541e2472e8d1047b7c3bb4e83c7e2c"
    },
    "rapids_logger": {
      "version": "0.1.0",
      "git_shallow": false,
      "git_url": "https://github.com/rapidsai/rapids-logger.git",
      "git_tag": "46070bb255482f0782ca840ae45de9354380e298"
    },
    "fmt": {
      "version": "11.0.2",
      "git_url": "https://github.com/fmtlib/fmt.git",
      "git_tag": "${version}"
    },
    "GTest": {
      "version": "1.16.0",
      "git_url": "https://github.com/google/googletest.git",
      "git_tag": "v${version}"
    },
    "nvbench": {
      "version": "0.0",
      "git_shallow": false,
      "git_url": "https://github.com/NVIDIA/nvbench.git",
      "git_tag": "555d628e9b250868c9da003e4407087ff1982e8e"
    },
    "nvcomp": {
      "version": "4.2.0.11",
      "git_url": "https://github.com/NVIDIA/nvcomp.git",
      "git_tag": "v2.2.0",
      "proprietary_binary_cuda_version_mapping": {
        "11": "11",
        "12": "12"
      },
      "proprietary_binary": {
        "x86_64-linux": "https://developer.download.nvidia.com/compute/nvcomp/redist/nvcomp/linux-x86_64/nvcomp-linux-x86_64-${version}_cuda${cuda-toolkit-version-mapping}-archive.tar.xz",
        "aarch64-linux": "https://developer.download.nvidia.com/compute/nvcomp/redist/nvcomp/linux-sbsa/nvcomp-linux-sbsa-${version}_cuda${cuda-toolkit-version-mapping}-archive.tar.xz"
      }
    },
    "nvtx3": {
      "version": "3.1.0",
      "git_url": "https://github.com/NVIDIA/NVTX.git",
      "git_tag": "v${version}"
    },
    "rmm": {
      "version": "${rapids-cmake-version}",
      "git_url": "https://github.com/rapidsai/rmm.git",
      "git_tag": "branch-${version}"
    },
    "spdlog": {
      "version": "1.14.1",
      "git_url": "https://github.com/gabime/spdlog.git",
      "git_tag": "v${version}"
    }
  }
}