mirror of
https://github.com/esphome/esphome.git
synced 2026-02-08 16:51:52 +00:00
Create and use buildinfo.json instead of parsing linker script
Co-authored-by: J. Nick Koston <nick+github@koston.org>
This commit is contained in:
@@ -528,44 +528,37 @@ def compile_program(args: ArgsProtocol, config: ConfigType) -> int:
|
||||
|
||||
def _check_and_emit_buildinfo():
|
||||
"""Check if firmware was rebuilt and emit buildinfo."""
|
||||
import json
|
||||
|
||||
firmware_path = CORE.firmware_bin
|
||||
buildinfo_ld_path = CORE.relative_build_path("buildinfo.ld")
|
||||
buildinfo_json_path = CORE.relative_build_path("buildinfo.json")
|
||||
|
||||
# Check if both files exist
|
||||
if not firmware_path.exists() or not buildinfo_ld_path.exists():
|
||||
if not firmware_path.exists() or not buildinfo_json_path.exists():
|
||||
return
|
||||
|
||||
# Check if firmware is newer than buildinfo linker script (indicating a relink occurred)
|
||||
if firmware_path.stat().st_mtime <= buildinfo_ld_path.stat().st_mtime:
|
||||
# Check if firmware is newer than buildinfo (indicating a relink occurred)
|
||||
if firmware_path.stat().st_mtime <= buildinfo_json_path.stat().st_mtime:
|
||||
return
|
||||
|
||||
# Read buildinfo values from linker script
|
||||
# Read buildinfo from JSON
|
||||
try:
|
||||
with open(buildinfo_ld_path, encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
except OSError as e:
|
||||
with open(buildinfo_json_path, encoding="utf-8") as f:
|
||||
buildinfo = json.load(f)
|
||||
except (OSError, json.JSONDecodeError) as e:
|
||||
_LOGGER.debug("Failed to read buildinfo: %s", e)
|
||||
return
|
||||
|
||||
config_hash_match = re.search(r"ESPHOME_CONFIG_HASH = 0x([0-9a-fA-F]+);", content)
|
||||
build_time_match = re.search(r"ESPHOME_BUILD_TIME = (\d+);", content)
|
||||
config_hash = buildinfo.get("config_hash")
|
||||
build_time = buildinfo.get("build_time")
|
||||
|
||||
if not config_hash_match or not build_time_match:
|
||||
if config_hash is None or build_time is None:
|
||||
return
|
||||
|
||||
config_hash = config_hash_match.group(1)
|
||||
build_time = int(build_time_match.group(1))
|
||||
|
||||
# Emit buildinfo
|
||||
print("=== ESPHome Build Info ===")
|
||||
print(f"Config Hash: 0x{config_hash}")
|
||||
print(
|
||||
f"Build Time: {build_time} ({time.strftime('%Y-%m-%d %H:%M:%S %z', time.localtime(build_time))})"
|
||||
_LOGGER.info(
|
||||
"Build Info: config_hash=0x%08x build_time=%s", config_hash, build_time
|
||||
)
|
||||
print("===========================")
|
||||
|
||||
# TODO: Future commit will create JSON manifest with OTA metadata here
|
||||
|
||||
|
||||
def upload_using_esptool(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from collections.abc import Callable
|
||||
import importlib
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
@@ -249,8 +250,16 @@ def copy_src_tree():
|
||||
write_file_if_changed(
|
||||
CORE.relative_src_path("esphome", "core", "version.h"), generate_version_h()
|
||||
)
|
||||
# Write buildinfo linker script and copy the PlatformIO script
|
||||
write_file(CORE.relative_build_path("buildinfo.ld"), generate_buildinfo_ld())
|
||||
# Write buildinfo linker script, JSON metadata, and copy the PlatformIO script
|
||||
config_hash, build_time, build_time_str = get_buildinfo()
|
||||
write_file(
|
||||
CORE.relative_build_path("buildinfo.ld"),
|
||||
generate_buildinfo_ld(config_hash, build_time, build_time_str),
|
||||
)
|
||||
write_file(
|
||||
CORE.relative_build_path("buildinfo.json"),
|
||||
json.dumps({"config_hash": config_hash, "build_time": build_time}),
|
||||
)
|
||||
copy_file_if_changed(
|
||||
Path(__file__).parent / "core" / "buildinfo.py.script",
|
||||
CORE.relative_build_path("buildinfo.py"),
|
||||
@@ -306,17 +315,27 @@ def _encode_string_symbols(
|
||||
return symbols
|
||||
|
||||
|
||||
def generate_buildinfo_ld() -> str:
|
||||
"""Generate buildinfo linker script with config hash and build time."""
|
||||
def get_buildinfo() -> tuple[int, int, str]:
|
||||
"""Calculate buildinfo values from current config.
|
||||
|
||||
Returns:
|
||||
Tuple of (config_hash, build_time, build_time_str)
|
||||
"""
|
||||
from esphome import yaml_util
|
||||
|
||||
# Use the same clean YAML representation as 'esphome config' command
|
||||
config_str = yaml_util.dump(CORE.config, show_secrets=True)
|
||||
config_hash = fnv1a_32bit_hash(config_str)
|
||||
config_hash_str = f"{config_hash:08x}"
|
||||
|
||||
build_time = int(time.time())
|
||||
build_time_str = time.strftime("%b %d %Y, %H:%M:%S", time.localtime(build_time))
|
||||
return config_hash, build_time, build_time_str
|
||||
|
||||
|
||||
def generate_buildinfo_ld(
|
||||
config_hash: int, build_time: int, build_time_str: str
|
||||
) -> str:
|
||||
"""Generate buildinfo linker script with config hash and build time."""
|
||||
config_hash_str = f"{config_hash:08x}"
|
||||
|
||||
# Generate symbols for all 4 variants: 32LE, 32BE, 64LE, 64BE
|
||||
all_variants: list[str] = []
|
||||
|
||||
Reference in New Issue
Block a user