From c63ec8672646e4b1698c8b8a5764b0c08025cf23 Mon Sep 17 00:00:00 2001 From: tyeth Date: Fri, 28 Aug 2026 13:46:45 +0100 Subject: [PATCH] libraries: guard TinyUSB include for PlatformIO only Under PlatformIO, framework-bundled libraries do not receive lib_deps include paths, so the unguarded #include hard-fails every SAMD build with USE_TINYUSB. Adafruit_TinyUSB.h lives in the library's src/, and only src/arduino is ever added to the include path (platform.txt does this for arduino-cli; PlatformIO's atmelsam builder does the same), so the header is unreachable from these five sources. Skip the include under PlatformIO when it is unreachable, keeping it plain and unconditional everywhere else. The nesting is deliberate: the include is what the Arduino builder discovers the TinyUSB library from, and its dependency-detection pass cannot parse a __has_include() expression -- it then finds no dependency, TinyUSB is never linked, and the usbstack=tinyusb examples fail with undefined references to Serial and Adafruit_USBD_CDC::begin. Putting __has_include() inside #ifdef PLATFORMIO leaves it in a branch arduino-cli skips without evaluating, so arduino-cli behaviour is unchanged. Verified both ways in CI. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01TJa4WYfEHBFUhnJVRLja7A --- libraries/I2S/src/I2S.cpp | 13 ++++++++++++- .../src/SAMD_AnalogCorrection.cpp | 13 ++++++++++++- libraries/SPI/SPI.cpp | 13 ++++++++++++- libraries/Servo/src/samd/Servo.cpp | 13 ++++++++++++- libraries/Wire/Wire.cpp | 13 ++++++++++++- 5 files changed, 60 insertions(+), 5 deletions(-) diff --git a/libraries/I2S/src/I2S.cpp b/libraries/I2S/src/I2S.cpp index 00837e202..2628d5870 100644 --- a/libraries/I2S/src/I2S.cpp +++ b/libraries/I2S/src/I2S.cpp @@ -38,9 +38,20 @@ static I2SDevice_SAMD21G18x i2sd(*I2S); #include "I2S.h" #ifdef USE_TINYUSB -// For Serial when selecting TinyUSB +// For Serial when selecting TinyUSB (also causes the Arduino builder to link +// the TinyUSB library). Outside PlatformIO this include must stay plain and +// unconditional: the Arduino builder discovers the library from it, and its +// dependency-detection pass cannot parse a __has_include() expression. +#ifdef PLATFORMIO +// PlatformIO does not give framework-bundled libraries the lib_deps include +// paths, so the header can be unreachable here; skip it instead of failing. +#if !defined(__has_include) || __has_include() #include #endif +#else +#include +#endif +#endif int I2SClass::_beginCount = 0; diff --git a/libraries/SAMD_AnalogCorrection/src/SAMD_AnalogCorrection.cpp b/libraries/SAMD_AnalogCorrection/src/SAMD_AnalogCorrection.cpp index e39ab43e3..7deeaf0bd 100644 --- a/libraries/SAMD_AnalogCorrection/src/SAMD_AnalogCorrection.cpp +++ b/libraries/SAMD_AnalogCorrection/src/SAMD_AnalogCorrection.cpp @@ -20,9 +20,20 @@ #include "SAMD_AnalogCorrection.h" #ifdef USE_TINYUSB -// For Serial when selecting TinyUSB +// For Serial when selecting TinyUSB (also causes the Arduino builder to link +// the TinyUSB library). Outside PlatformIO this include must stay plain and +// unconditional: the Arduino builder discovers the library from it, and its +// dependency-detection pass cannot parse a __has_include() expression. +#ifdef PLATFORMIO +// PlatformIO does not give framework-bundled libraries the lib_deps include +// paths, so the header can be unreachable here; skip it instead of failing. +#if !defined(__has_include) || __has_include() #include #endif +#else +#include +#endif +#endif void analogReadCorrection (int offset, uint16_t gain) { diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index 0393752d7..42c0564d5 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -23,9 +23,20 @@ #include #ifdef USE_TINYUSB -// For Serial when selecting TinyUSB +// For Serial when selecting TinyUSB (also causes the Arduino builder to link +// the TinyUSB library). Outside PlatformIO this include must stay plain and +// unconditional: the Arduino builder discovers the library from it, and its +// dependency-detection pass cannot parse a __has_include() expression. +#ifdef PLATFORMIO +// PlatformIO does not give framework-bundled libraries the lib_deps include +// paths, so the header can be unreachable here; skip it instead of failing. +#if !defined(__has_include) || __has_include() #include #endif +#else +#include +#endif +#endif #define SPI_IMODE_NONE 0 #define SPI_IMODE_EXTINT 1 diff --git a/libraries/Servo/src/samd/Servo.cpp b/libraries/Servo/src/samd/Servo.cpp index ba07e70a7..5cf289978 100644 --- a/libraries/Servo/src/samd/Servo.cpp +++ b/libraries/Servo/src/samd/Servo.cpp @@ -22,9 +22,20 @@ #include #ifdef USE_TINYUSB -// For Serial when selecting TinyUSB +// For Serial when selecting TinyUSB (also causes the Arduino builder to link +// the TinyUSB library). Outside PlatformIO this include must stay plain and +// unconditional: the Arduino builder discovers the library from it, and its +// dependency-detection pass cannot parse a __has_include() expression. +#ifdef PLATFORMIO +// PlatformIO does not give framework-bundled libraries the lib_deps include +// paths, so the header can be unreachable here; skip it instead of failing. +#if !defined(__has_include) || __has_include() #include #endif +#else +#include +#endif +#endif #if defined(__SAMD51__) // Different prescalers depending on FCPU (avoid overflowing 16-bit counter) diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp index da9732c59..f79ad0038 100644 --- a/libraries/Wire/Wire.cpp +++ b/libraries/Wire/Wire.cpp @@ -25,9 +25,20 @@ extern "C" { #include #ifdef USE_TINYUSB -// For Serial when selecting TinyUSB +// For Serial when selecting TinyUSB (also causes the Arduino builder to link +// the TinyUSB library). Outside PlatformIO this include must stay plain and +// unconditional: the Arduino builder discovers the library from it, and its +// dependency-detection pass cannot parse a __has_include() expression. +#ifdef PLATFORMIO +// PlatformIO does not give framework-bundled libraries the lib_deps include +// paths, so the header can be unreachable here; skip it instead of failing. +#if !defined(__has_include) || __has_include() #include #endif +#else +#include +#endif +#endif #include "Wire.h"