From 27c9a2853dd699af7dd6bdffcfce46eedf75bd3e Mon Sep 17 00:00:00 2001 From: David Montero Date: Sat, 23 May 2026 17:30:29 +0200 Subject: [PATCH] fix(espidf): glob all main/*.cpp /*.c so helper TUs link MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Multi-file Arduino sketches (robot-desktop-eyes is the canonical case) define classes and free functions in their own translation units — Face::Update(), FaceExpression::GoTo_Surprised(), AsyncTimer::SetIntervalMillis(...), etc. live in Face.cpp, FaceExpression.cpp, AsyncTimer.cpp respectively. The espidf_compiler drops every user-supplied .h/.cpp into project/main/ but the main/CMakeLists.txt only declared `SRCS "main.cpp"`, so the helper TUs never got compiled and the linker died with dozens of "undefined reference to ..." entries. Switch SRCS to a CONFIGURE_DEPENDS glob over the main/ directory so every .cpp/.c that lands in main/ becomes part of the IDF main component automatically. CONFIGURE_DEPENDS makes CMake re-evaluate the glob on every reconfigure, which matters because the persistent build dir is reused across compiles and the set of helper files changes per sketch. Repro: open robot-desktop-eyes, click Compile. Before this commit: 37 linker errors starting at "undefined reference to `u8g2'" and "undefined reference to `Face::Update()`". After: the helper TUs compile and the .elf links. --- .../esp-idf-template/main/CMakeLists.txt | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/backend/app/services/esp-idf-template/main/CMakeLists.txt b/backend/app/services/esp-idf-template/main/CMakeLists.txt index 47251ec9..07537ed1 100644 --- a/backend/app/services/esp-idf-template/main/CMakeLists.txt +++ b/backend/app/services/esp-idf-template/main/CMakeLists.txt @@ -22,8 +22,22 @@ if(DEFINED ENV{ARDUINO_ESP32_PATH}) list(APPEND _cam_includes "${_cam_root}/conversions/include") endif() + # Glob every .cpp / .c that the espidf_compiler dropped into main/ + # alongside main.cpp. Multi-file Arduino projects (robot-desktop-eyes, + # any wokwi.zip with helper .cpp files, etc.) define classes/free + # functions in their own translation units; if SRCS only names + # "main.cpp" the linker dies with "undefined reference to Foo::bar()" + # for every symbol that lives in a helper .cpp. + # + # CONFIGURE_DEPENDS makes CMake re-glob on every cmake run, which is + # what we want — the persistent build dir is reused across compiles + # and the file set changes per sketch. + file(GLOB _user_srcs CONFIGURE_DEPENDS + "${CMAKE_CURRENT_LIST_DIR}/*.cpp" + "${CMAKE_CURRENT_LIST_DIR}/*.c") + idf_component_register( - SRCS "main.cpp" + SRCS ${_user_srcs} INCLUDE_DIRS "." ${_cam_includes} # `driver` brings in the i2c_master_* + i2c_cmd_link_* symbols # libesp32-camera.a's sccb.c references at link time. arduino-esp32