[espidf] Share one text sdkconfig parser

This commit is contained in:
J. Nick Koston
2026-09-29 21:06:21 +02:00
parent 61e7c2583a
commit 7a182ccddb
4 changed files with 48 additions and 15 deletions
+4 -5
View File
@@ -924,14 +924,13 @@ def _check_and_emit_build_info() -> None:
def _get_configured_xtal_freq() -> int | None:
"""Read the configured crystal frequency from the sdkconfig file."""
from esphome.espidf.toolchain import parse_sdkconfig
sdkconfig_path = CORE.relative_build_path(f"sdkconfig.{CORE.name}")
if not sdkconfig_path.is_file():
return None
with suppress(OSError, ValueError):
content = sdkconfig_path.read_text()
for line in content.splitlines():
if line.startswith("CONFIG_XTAL_FREQ="):
return int(line.split("=", 1)[1])
with suppress(OSError, ValueError, KeyError):
return int(parse_sdkconfig(sdkconfig_path)["CONFIG_XTAL_FREQ"])
return None
+7 -10
View File
@@ -90,16 +90,13 @@ def _snapshot_blocks_cache(sdkconfig_path: Path) -> bool:
build off blocks so those users skip the doomed probe on every compile;
the probe still guards against unknown nondeterminism.
"""
reproducible = False
for line in sdkconfig_path.read_text(encoding="utf-8").splitlines():
name, _, value = line.partition("=")
name = name.strip()
value = value.strip().strip('"')
if _SECURE_OPTION.match(name) and value not in _DISABLED_VALUES:
return True
if name == "CONFIG_APP_REPRODUCIBLE_BUILD":
reproducible = value not in _DISABLED_VALUES
return not reproducible
config = toolchain.parse_sdkconfig(sdkconfig_path)
if any(
_SECURE_OPTION.match(name) and value not in _DISABLED_VALUES
for name, value in config.items()
):
return True
return config.get("CONFIG_APP_REPRODUCIBLE_BUILD", "") in _DISABLED_VALUES
def tree_uses_cached_bootloader(build_dir: Path) -> bool:
+18
View File
@@ -261,6 +261,24 @@ def _load_sdkconfig_json(build_dir: Path) -> dict | None:
return config if isinstance(config, dict) else None
def parse_sdkconfig(path: Path) -> dict[str, str]:
"""Map each CONFIG_X=value line of a text sdkconfig to its raw value.
Comment lines ("# CONFIG_X is not set") are skipped and quoted values
are unquoted.
"""
result = {}
for line in path.read_text(encoding="utf-8").splitlines():
if not line.startswith("CONFIG_"):
continue
name, _, value = line.partition("=")
value = value.strip()
if len(value) >= 2 and value[0] == value[-1] == '"':
value = value[1:-1]
result[name] = value
return result
def _resolved_c_compiler() -> str | None:
"""The configured build's resolved C compiler, or None."""
description = read_json_file(_build_dir() / "project_description.json")
+19
View File
@@ -1277,3 +1277,22 @@ def test_resolved_c_compiler_none_without_a_usable_description(
build.mkdir(parents=True)
(build / "project_description.json").write_text(description)
assert toolchain._resolved_c_compiler() is None
def test_parse_sdkconfig(tmp_path: Path) -> None:
path = tmp_path / "sdkconfig"
path.write_text(
"# comment\n"
"# CONFIG_DISABLED is not set\n"
"CONFIG_INT=240\n"
'CONFIG_STR="key.pem"\n'
'CONFIG_EMPTY=""\n'
"CONFIG_BOOL=y\n"
"not_config=1\n"
)
assert toolchain.parse_sdkconfig(path) == {
"CONFIG_INT": "240",
"CONFIG_STR": "key.pem",
"CONFIG_EMPTY": "",
"CONFIG_BOOL": "y",
}