Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

日志与构建产物

5 个工具处理一次构建产生的所有东西 —— 日志行、输出文件、固件清单、 结构化错误信息和尺寸报告。

工具做什么
logs.tail拿一次构建最近的 N 行日志。
list_artifacts(别名 artifacts.list)列出一次构建产生的文件,按类型分组。
artifacts.manifest读一次完成构建的官方 manifest.json
parse_build_errors把原始编译错误转成可读的形式。
parse_size_reportidf.py size 输出转成 flash/RAM 细分。

logs.tail

返回某次构建日志最近的 N 行。

输入:

{
  "task_id": "0abf...e2",
  "lines": 200
}
字段必需说明
task_idbuild 返回的 id。
lines返回多少尾部行。默认 100。
since_seq只返回这个序列号之后的行(从上次调用得到)。

返回:

{
  "task_id": "0abf...e2",
  "lines": [
    { "seq": 4198, "ts": 1712340060, "stream": "stdout", "text": "[1234/1500] CC main.o" },
    { "seq": 4199, "ts": 1712340061, "stream": "stderr", "text": "warning: ..." }
  ],
  "next_seq": 4200,
  "more": false
}

more: true 表示构建还在产生日志行,你应该再问一次。

提示: 对长时间构建,用 build://log/{task_id} 资源 —— 它在新行 到达时推送,而不是你反复问。


list_artifacts / artifacts.list

列出一次构建产生的文件,按类型分组。

输入:

{
  "task_id": "0abf...e2",
  "target": "esp32s3"
}

可以传 task_id(首选 —— 看实际跑的那次构建)或者 target(看 项目当前的 build/ 文件夹)。

返回:

{
  "build_dir": "/work/build",
  "artifacts": {
    "firmware": [
      { "path": "build/my-app.bin", "size": 1048576, "sha256": "..." }
    ],
    "elf": [
      { "path": "build/my-app.elf", "size": 4823104 }
    ],
    "bootloader": [
      { "path": "build/bootloader/bootloader.bin", "size": 24576 }
    ],
    "partitions": [
      { "path": "build/partition_table/partition-table.bin", "size": 3072 }
    ],
    "maps": [
      { "path": "build/my-app.map", "size": 8421376 }
    ],
    "other": []
  }
}

分组器了解 ESP-IDF 的标准输出布局(固件、bootloader、分区表、ELF、 map),按此分组。它不认识的东西落到 other


CLI: espctl artifacts

本地扫描 build/<target>/,挑出符合分类器的文件(.bin.elf.map、bootloader、分区表、sdkconfig 等),输出一份 ArtifactManifest。不联系构建服务器。

espctl artifacts [--target <chip>]

输入

标志默认说明
--target.espctl.toml 里的 default_target芯片 —— 没传就用项目默认值。

输出

Human 模式列出每个被分类的文件:

Artifacts in /path/to/build/esp32s3:
  Bin  bootloader/bootloader.bin  (24576 bytes)
  Bin  esp32s3.bin                (1048576 bytes)
  Elf  esp32s3.elf                (4823104 bytes)
  Map  esp32s3.map                (8421376 bytes)

JSON(--json):完整的 ArtifactManifest,artifacts[] 中每一项 有 artifact_typepathsize_bytes

失败模式

  • build/<target>/ 不存在 → 退出 1。
  • target 不合法 → 退出 2。

示例

# 使用 .espctl.toml 里的 default_target
espctl artifacts

# 显式指定 target
espctl artifacts --target esp32s3

# JSON 输出,方便脚本消费
espctl --json artifacts --target esp32s3

相关


artifacts.manifest

读一次已完成构建的官方 manifest.json。清单是构建产生了什么以及 怎么烧录的权威记录。

输入:

{ "task_id": "0abf...e2" }

返回: manifest.json 的内容。具体形状和配方有关,但总是包含:

{
  "task_id": "0abf...e2",
  "target": "esp32s3",
  "idf_version": "v5.3.1",
  "profile": "release",
  "git_commit": "abc123",
  "built_at": 1712340060,
  "artifacts": [
    { "name": "firmware", "path": "build/my-app.bin", "size": 1048576, "sha256": "..." },
    { "name": "bootloader", "path": "build/bootloader/bootloader.bin", "offset": "0x0" },
    { "name": "partition-table", "path": "build/partition_table/partition-table.bin", "offset": "0x8000" },
    { "name": "app", "path": "build/my-app.bin", "offset": "0x10000" }
  ],
  "flash_size": "4MB",
  "flash_freq": "80m",
  "flash_mode": "dio"
}

当你的助手需要知道“哪个文件烧到哪个 flash 地址“时,这是要调的工具。

安全提示: 你编译好的固件可能包含嵌入的敏感信息(Wi-Fi 密码、 API key)。把 .bin 文件当作敏感文件,不要公开分享。


parse_build_errors

接收原始的编译/链接错误日志(或一个 task_id),返回结构化、去重的 错误信息。

输入:

{ "task_id": "0abf...e2" }

…或者:

{ "log_text": "main.c:42:5: error: ..." }

返回:

{
  "errors": [
    {
      "file": "main/app_main.c",
      "line": 42,
      "column": 5,
      "severity": "error",
      "message": "implicit declaration of function 'foo'",
      "context": [
        "  40 | void app_main(void) {",
        "  41 |     printf(\"hello\\n\");",
        "  42 |     foo();",
        "                       ^"
      ]
    }
  ],
  "warnings": [...],
  "summary": "1 error, 0 warnings"
}

了解 GCC、Clang、CMake 和 ESP-IDF 自己的错误格式。当你的助手想给你 看“这是要改的那一行“而不是堆 500 行日志时很有用。


parse_size_report

解析 idf.py size 的输出,返回按 section 分的 flash/RAM 用量细分。

输入:

{ "task_id": "0abf...e2" }

返回:

{
  "target": "esp32s3",
  "total_flash": { "used": 1048576, "free": 3145728, "total": 4194304 },
  "total_ram":   { "used":  131072, "free":  393216, "total":  524288 },
  "sections": [
    { "name": ".text", "size": 524288, "memory": "flash" },
    { "name": ".rodata", "size": 262144, "memory": "flash" },
    { "name": ".data", "size":  16384, "memory": "ram" },
    { "name": ".bss",  "size": 114688, "memory": "ram" }
  ]
}

parse_build_errors 配合,可以一次性给出完整的构建后摘要。


CLI: espctl clean

按 target 删除构建产物。带 --full 时,把整个 build/sdkconfigmanaged_components/ 一起删。仅本地操作,不会联系构建服务器。

espctl clean [--full] [target]

两种模式

  • 增量清理 —— espctl clean <target>espctl_core::clean_plan 给出的清单删 build/<target>/... 下的 文件。
  • 完全清理 —— espctl clean --full 把整个 build/sdkconfigmanaged_components/ 都删掉(fullclean_plan)。带 --full 时 位置参数 target 会被忽略。

标志矩阵

参数默认说明
target(位置参数)不带 --full 时必填。芯片名。
--fullfalse切到完全清理模式。

输出

Human 模式:

Removed:
  /path/to/build/esp32s3/CMakeCache.txt
  /path/to/build/esp32s3/CMakeFiles
  ...

…或在没有任何东西匹配时输出 Nothing to clean.

JSON(--json):{ "removed": ["/path/...", ...] }

失败模式

情况退出码消息
既没传 target,也没传 --full2target required for clean (use --full for full clean)
target 不合法2invalid target: <name>

预演

破坏性清理前(尤其在 CI 里),先用 MCP 的 get_clean_plan 工具看一眼会删什么 —— 它只告诉你结果,不会真删。

示例

# 增量 —— 只删 build/esp32s3/...
espctl clean esp32s3

# 完全清理 —— build/、sdkconfig、managed_components/
espctl clean --full

# JSON 输出,方便脚本消费
espctl --json clean esp32s3

另见

  • build —— 每个构建产物工具都需要从 完成的构建获得 task_id
  • 资源 —— build://log/{task_id}build://artifacts/{target} 是这些工具的流式替代品。