mirror of
https://github.com/esphome/esphome.git
synced 2026-06-24 13:27:14 +00:00
[espidf] Backport ninja linux-arm64 entry into tools.json on aarch64 hosts (#16527)
This commit is contained in:
@@ -7,6 +7,7 @@ import json
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
import platform
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
@@ -17,7 +18,7 @@ import requests
|
||||
|
||||
from esphome.config_validation import Version
|
||||
from esphome.core import CORE
|
||||
from esphome.helpers import ProgressBar, get_str_env, rmtree
|
||||
from esphome.helpers import ProgressBar, get_str_env, rmtree, write_file_if_changed
|
||||
|
||||
PathType = str | os.PathLike
|
||||
|
||||
@@ -811,6 +812,74 @@ def _write_idf_version_txt(framework_path: Path, version: str) -> None:
|
||||
)
|
||||
|
||||
|
||||
# Backport of espressif/esp-idf#18272: every ESPHome-supported IDF release
|
||||
# through v6.0 ships a tools.json whose ninja 1.12.1 entry has no
|
||||
# ``linux-arm64`` source. ``idf_tools.py`` then either fails to find a
|
||||
# matching binary or grabs the x86_64 one, which can't execute on
|
||||
# aarch64. cmake is already populated across the same release range; we
|
||||
# only need to inject ninja. Values lifted verbatim from the IDF v6.0.1
|
||||
# tools.json where the fix landed natively.
|
||||
_NINJA_ARM64_BACKPORT: dict[str, dict[str, str | int]] = {
|
||||
"1.12.1": {
|
||||
"rename_dist": "ninja-linux-arm64-v1.12.1.zip",
|
||||
"sha256": "5c25c6570b0155e95fce5918cb95f1ad9870df5768653afe128db822301a05a1",
|
||||
"size": 121787,
|
||||
"url": "https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-linux-aarch64.zip",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def _patch_tools_json_for_linux_arm64(framework_path: Path) -> None:
|
||||
"""Inject ninja linux-arm64 entries into the framework's tools.json on aarch64.
|
||||
|
||||
Idempotent: a tools.json that already has the entry, or a host that
|
||||
isn't aarch64, is a no-op. Applied unconditionally on every install
|
||||
check so a build dir extracted before the backport got fixed up
|
||||
without forcing a clean.
|
||||
"""
|
||||
if platform.machine() != "aarch64":
|
||||
return
|
||||
|
||||
tools_json = framework_path / "tools" / "tools.json"
|
||||
if not tools_json.is_file():
|
||||
return
|
||||
|
||||
try:
|
||||
with open(tools_json, encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
except (json.JSONDecodeError, OSError) as e:
|
||||
_LOGGER.warning(
|
||||
"Could not parse %s for linux-arm64 backport (%s); "
|
||||
"skipping. A clean reinstall of the framework directory "
|
||||
"may be needed.",
|
||||
tools_json,
|
||||
e,
|
||||
)
|
||||
return
|
||||
|
||||
changed = False
|
||||
for tool in data.get("tools", []):
|
||||
if tool.get("name") != "ninja":
|
||||
continue
|
||||
for ver in tool.get("versions", []):
|
||||
entry = _NINJA_ARM64_BACKPORT.get(ver.get("name"))
|
||||
if entry is None or ver.get("linux-arm64"):
|
||||
continue
|
||||
ver["linux-arm64"] = entry
|
||||
changed = True
|
||||
|
||||
if changed:
|
||||
# write_file_if_changed stages a tempfile in the destination dir
|
||||
# and atomically replaces — safe against mid-write interruption
|
||||
# and concurrent invocations.
|
||||
write_file_if_changed(tools_json, json.dumps(data, indent=2) + "\n")
|
||||
_LOGGER.info(
|
||||
"Patched %s to add ninja linux-arm64 download "
|
||||
"(espressif/esp-idf#18272 backport).",
|
||||
tools_json,
|
||||
)
|
||||
|
||||
|
||||
def _check_esphome_idf_framework_install(
|
||||
version: str,
|
||||
targets: list[str],
|
||||
@@ -897,6 +966,11 @@ def _check_esphome_idf_framework_install(
|
||||
# clean. Skips when version.txt already exists.
|
||||
_write_idf_version_txt(framework_path, version)
|
||||
|
||||
# Apply the ninja linux-arm64 backport on every invocation, not just on
|
||||
# fresh extracts — idempotent and cheap, and lets a build dir carrying
|
||||
# a pre-patch tools.json get fixed up without forcing a clean.
|
||||
_patch_tools_json_for_linux_arm64(framework_path)
|
||||
|
||||
# 3. Check if the framework tools are the same and correctly installed
|
||||
if not install:
|
||||
install = True
|
||||
|
||||
Reference in New Issue
Block a user