跳转至

Toolchain

Machine.toolchain(也包含在快照中)报告主机 PATH 上找到的 C、C++、CUDA 编译器和构建系统,因此工具无需自己调用即可了解机器真实的构建能力。

from mainboard import Machine

toolchain = Machine().toolchain
for tool in toolchain.tools:
    print(tool.name, tool.version, tool.path)

只保留实际位于 PATH 上的工具,因此该列表反映主机真正能够运行的内容。每个工具保持其注册顺序,并按类别分组。

在快照中

Machine().model_dump_json()toolchain 字段列出每个可用工具:

{
  "tools": [
    {
      "name": "gcc",
      "category": "c-compiler",
      "path": "/usr/bin/gcc",
      "version": "13.2.0",
      "available": true
    },
    {
      "name": "clang",
      "category": "c-compiler",
      "path": "/usr/bin/clang",
      "version": "21.0.0",
      "available": true
    },
    {
      "name": "nvcc",
      "category": "cuda-compiler",
      "path": "/usr/local/cuda/bin/nvcc",
      "version": "13.0",
      "available": true
    },
    {
      "name": "cmake",
      "category": "build-system",
      "path": "/usr/bin/cmake",
      "version": "3.28.3",
      "available": true
    },
    {
      "name": "ninja",
      "category": "build-system",
      "path": "/usr/bin/ninja",
      "version": "1.11.1",
      "available": true
    }
  ]
}

当工具存在但其版本输出无法解析时,versionnull

DetectedTool

tools 中的每一项都是一个 DetectedTool,即一次探测的结构化结果。

字段 类型 含义
name str 工具的显示名称,例如 gcccmake
category ToolCategory 工具所属的工具链分组
path str \| None 解析后二进制文件的绝对路径,不在 PATH 上时为 None
version str \| None 解析出的版本字符串,缺失或无法解析时为 None
available bool 二进制文件是否在 PATH 上找到

ToolCategory

ToolCategory 是一个将每个工具分组的 StrEnum

成员
C_COMPILER c-compiler
CXX_COMPILER cxx-compiler
CUDA_COMPILER cuda-compiler
BUILD_SYSTEM build-system

Toolchain.by_category 将可用工具重新归入这些分组。

from mainboard import Machine, ToolCategory

toolchain = Machine().toolchain
cuda = toolchain.by_category.get(ToolCategory.CUDA_COMPILER, ())
print([tool.name for tool in cuda])

如何探测

探测是数据驱动的。ToolProbe 是查找一个工具的不可变配方,而模块级的 TOOL_PROBES 元组就是 Toolchain.probe() 运行的注册表。

字段 类型 含义
name str DetectedTool 上报告的显示名称
category ToolCategory 工具所属的工具链分组
binaries tuple[str, ...] 候选可执行文件名,按顺序尝试直到有一个在 PATH 上
version_args tuple[str, ...] 让二进制文件打印版本的参数,默认为 ("--version",)
pattern re.Pattern[str] 正则表达式,其第一个分组从命令输出中捕获版本

对于每次探测,PATH 上找到的第一个二进制文件胜出。捕获其版本输出,pattern 的第一个分组成为 version。默认注册表覆盖 gcc、clang、g++、clang++、nvcc、cmake、ninja、make 和 meson。

扩展注册表

添加一个工具只需一行。将一个 ToolProbe 追加到 TOOL_PROBES,下一次探测就会发现它,且无需改动任何探测逻辑。

from mainboard.models.toolchain import TOOL_PROBES, ToolProbe
from mainboard import ToolCategory

bazel = ToolProbe("bazel", ToolCategory.BUILD_SYSTEM, ("bazel",))
probes = (*TOOL_PROBES, bazel)

from mainboard import Toolchain

toolchain = Toolchain.probe(probes)

版本命令不标准的工具可设置 version_argspattern

import re
from mainboard.models.toolchain import ToolProbe
from mainboard import ToolCategory

icx = ToolProbe(
    "icx",
    ToolCategory.C_COMPILER,
    ("icx",),
    version_args=("--version",),
    pattern=re.compile(r"(\d+\.\d+\.\d+)"),
)

一个全新的工具家族只需一个 ToolCategory 成员加上它的探测项,因此模型通过添加代码而非修改探测循环来增长。