From f4b7776cd69fb1454b85d352126d610271628ec0 Mon Sep 17 00:00:00 2001 From: David Montero Date: Sat, 23 May 2026 09:00:22 +0200 Subject: [PATCH] fix(espidf): scan all project files for external #includes, not just the .ino When a sketch's external library headers were only referenced from project headers (e.g. esp32-eyes.ino includes Common.h, Common.h includes ), the compile failed with fatal error: ESP32Servo.h: No such file or directory because _detect_external_includes was only called on main_content (the processed .ino). Project .h/.cpp files were never scanned, so ESP32Servo / DHT / Adafruit_Sensor referenced only transitively through user code never reached _resolve_library_components and never landed in user_libs_all/. Fix: collect ext_headers from main_content PLUS every uploaded .h/.hpp/.ino/.c/.cpp file before resolving libraries. Lib resolver already walks transitive includes inside the lib bundle once it's copied; this just makes sure the first-level set covers user project headers too. Repro: open https://velxio.dev/example/robot-desktop-eyes, click Compile. Before this commit: 13 errors starting at ESP32Servo.h. After: ext_headers includes ESP32Servo.h on the first pass and the build proceeds. --- backend/app/services/espidf_compiler.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/backend/app/services/espidf_compiler.py b/backend/app/services/espidf_compiler.py index abcfd80d..5a1d1110 100644 --- a/backend/app/services/espidf_compiler.py +++ b/backend/app/services/espidf_compiler.py @@ -1614,7 +1614,22 @@ class ESPIDFCompiler: # proper ESP-IDF component with its own CMakeLists.txt and # INCLUDE_DIRS. The root CMakeLists.txt (template) adds user_libs # to EXTRA_COMPONENT_DIRS so ESP-IDF discovers them automatically. - ext_headers = self._detect_external_includes(main_content) + # + # Scan the .ino AND every user-supplied .h/.hpp/.c/.cpp so + # transitive includes inside project headers (e.g. Common.h + # → ) are picked up. Previously only main_content + # was scanned, so libs only referenced from project headers + # never reached _resolve_library_components and the build + # died with "fatal error: ESP32Servo.h: No such file". + ext_headers_set: set[str] = set( + self._detect_external_includes(main_content) + ) + for _f in files: + if _f.get('name', '').endswith(('.h', '.hpp', '.ino', '.c', '.cpp')): + ext_headers_set.update( + self._detect_external_includes(_f.get('content', '')) + ) + ext_headers = list(ext_headers_set) component_names: list[str] = [] # arduino-esp32 component name (directory basename of ARDUINO_ESP32_PATH) arduino_comp_name = Path(self.arduino_path).name if self.arduino_path else 'arduino-esp32'