From 10b13558c3ab7d68f85b69b0ee7a5481dfe585dd Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 20 Aug 2026 16:13:55 -0500 Subject: [PATCH] Line-oriented rspfile expansion, adopt the public manifest parser, document the dependency policy --- esphome/arduino/library.py | 7 +++++-- esphome/build_gen/build_tool.py | 8 ++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/esphome/arduino/library.py b/esphome/arduino/library.py index 75ce906b77..443438a725 100644 --- a/esphome/arduino/library.py +++ b/esphome/arduino/library.py @@ -28,7 +28,6 @@ from esphome.platformio.library import ( ConvertedLibrary, InvalidLibrary, LibraryBackend, - _parse_library_json, check_library_data, collect_filtered_files, convert_libraries, @@ -37,6 +36,7 @@ from esphome.platformio.library import ( lex_build_flags, lib_ignore_set, normalize_dependencies, + parse_library_json, parse_library_properties, ) @@ -138,7 +138,7 @@ def _bundled_library(framework_path: Path, name: str) -> ArduinoLibrary: lib_dir = framework_path / "libraries" / name manifest_json = lib_dir / "library.json" if manifest_json.is_file(): - data = _parse_library_json(manifest_json) + data = parse_library_json(manifest_json) else: manifest = lib_dir / "library.properties" data = parse_library_properties(manifest) if manifest.is_file() else {} @@ -174,6 +174,9 @@ def resolve_libraries( and "/" not in library.name and (framework_path / "libraries" / library.name).is_dir() ): + # A bundled library's own manifest dependencies are deliberately + # not walked (PlatformIO's lib_ldf_mode=off does not either); + # core add_library() calls list what they need explicitly. bundled.append(_bundled_library(framework_path, library.name)) else: external.append(library) diff --git a/esphome/build_gen/build_tool.py b/esphome/build_gen/build_tool.py index ef6b1d4cc2..692d006661 100644 --- a/esphome/build_gen/build_tool.py +++ b/esphome/build_gen/build_tool.py @@ -24,9 +24,13 @@ def main() -> int: # Expand the response file here instead of passing @rspfile: GNU ar # treats backslashes in response files as escapes, corrupting Windows # paths ("sub\a.o" -> "suba.o"). - objects = Path(rspfile).read_text(encoding="utf-8").split() + # One path per line (rspfile_content = $in_newline, written without + # escaping), so a path containing a space survives. Expanding into + # argv trades away the OS command-line length limit rspfiles dodge; + # the relative object paths used here stay far below it. + objects = Path(rspfile).read_text(encoding="utf-8").splitlines() return subprocess.run( - [ar, "rc", archive, *objects], check=False, close_fds=False + [ar, "rc", archive, *filter(None, objects)], check=False, close_fds=False ).returncode if mode == "copy": src, dst = sys.argv[2:4]