From d0ea4cbf8f9258b12d16bd63f25304999610a885 Mon Sep 17 00:00:00 2001 From: David Montero Crespo Date: Wed, 19 Aug 2026 20:10:13 +0200 Subject: [PATCH] fix(espidf): concatenate ALL .ino tabs into the sketch (Arduino semantics) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The arduino-mode branch used only the FIRST .ino in the request and silently dropped every other tab, so any multi-tab sketch (the standard Wokwi/Arduino-IDE project layout) died with 'not declared in this scope' on globals defined in the main file. Concatenate the main sketch (literal sketch.ino, else the first .ino) followed by the remaining tabs alphabetically — the arduino-cli order — with #line markers so diagnostics keep pointing at the real tab/line. Also REQUIRE http_parser: exposing esp_http_server.h activates FastLED's fl net server, which uses the HTTP_GET/HTTP_POST enums http_parser provides. --- backend/app/services/espidf_compiler.py | 31 ++++++++++++++++++------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/backend/app/services/espidf_compiler.py b/backend/app/services/espidf_compiler.py index e5c162fc..a00a3fc2 100644 --- a/backend/app/services/espidf_compiler.py +++ b/backend/app/services/espidf_compiler.py @@ -1790,9 +1790,9 @@ class ESPIDFCompiler: for _comp in ('nvs_flash', 'efuse', 'esp_timer', 'driver', 'spi_flash', 'esp_adc', 'esp_wifi', 'esp_event', 'esp_netif', 'esp_partition', 'esp_http_server', - 'esp_mm', 'esp_hw_support', 'heap', 'esp_system', - 'esp_rom', 'log', 'app_update', 'bt', 'esp_psram', - 'esp_pm'): + 'http_parser', 'esp_mm', 'esp_hw_support', 'heap', + 'esp_system', 'esp_rom', 'log', 'app_update', 'bt', + 'esp_psram', 'esp_pm'): for _root in filter(None, (self.idf5_path, self.idf_path)): if os.path.isdir(os.path.join(_root, 'components', _comp)): extra_requires += f' {_comp}' @@ -3485,12 +3485,27 @@ class ESPIDFCompiler: partition_csv = self._render_partition_csv(board_options['partitionScheme']) (project_dir / 'partitions.csv').write_text(partition_csv, encoding='utf-8') - # Get sketch content + # Get sketch content — Arduino tab semantics: EVERY .ino is part of + # the sketch. The main file (literal sketch.ino, else the first .ino + # sent) comes first so its globals are visible to the other tabs, + # and the rest are concatenated after it in alphabetical order — + # exactly what arduino-cli/the IDE do. #line markers keep compiler + # diagnostics pointing at the real file/line of each tab. + ino_files = [f for f in files if f['name'].endswith('.ino')] main_content = '' - for f in files: - if f['name'].endswith('.ino'): - main_content = f['content'] - break + if ino_files: + main_ino = next( + (f for f in ino_files if f['name'] == 'sketch.ino'), + ino_files[0], + ) + rest = sorted( + (f for f in ino_files if f is not main_ino), + key=lambda f: f['name'], + ) + main_content = '\n'.join( + f'#line 1 "{f["name"]}"\n{f["content"]}' + for f in [main_ino] + rest + ) if not main_content and files: main_content = files[0]['content']