Summary
A SAMD21/SAMD51 build cannot resolve <SPI.h>, and neither of the two ways FastLED expresses that dependency in src/ is picked up by fbuild's framework-library scan. Only an explicit lib_deps in platformio.ini works.
lib/FastLED/platforms/arm/sam/fastspi_arm_sam.h:17:10: fatal error: SPI.h: No such file or directory
Reproduced on samd21, samd21_zero, samd51j and metro_m4 (FastLED/FastLED#4015).
Both in-source signals are missed
1. The real include, under a condition that is true. fastspi_arm_sam.h:
#if defined(FL_IS_SAMD21) || defined(FL_IS_SAMD51)
#include <SPI.h>
Both macros are defined for these boards, and the file is genuinely compiled — that is precisely why the build fails on the missing header. So the scan either does not evaluate the conditional, or evaluates it without the -D set the real compile has (FL_IS_SAMD21 is derived several headers deep from -D__SAMD21G18A__).
2. The #if 0 LDF hint. platforms/arm/samd/ldf_headers.h, reached from FastLED.h via platforms/ldf_headers.h:
#if 0
#include <SPI.h>
#endif
This is the PlatformIO-LDF idiom — LDF in chain mode scans #include directives without evaluating conditionals, so a dead block declares a dependency. FastLED uses it in platforms/esp/8266/ldf_headers.h as well.
The two misses point in opposite directions: (1) is missed as if conditionals were evaluated, (2) as if they were. Whatever the scanner does, <SPI.h> is unreachable from this include graph either way.
What is and is not surprising
framework_libs.rs is explicit that lib_ldf_mode is unimplemented and that lib_deps is "the escape hatch for a dependency the finder scan never reaches", so needing the escape hatch is a documented outcome rather than a broken promise. Two things still seem worth a decision:
- The seeds walk is described as a "PlatformIO-LDF-style two-pass walk" and "chain-style".
chain in PlatformIO specifically does not evaluate conditionals, which is what makes the #if 0 idiom work. If fbuild's chain-style scan does evaluate them, the shared name is misleading for anyone porting a project that relies on the idiom.
- Case (1) is the more concerning one: a header that is compiled, with an include that is active, did not register as a dependency. That is not an idiom question.
Ask
Either:
- support the
#if 0 hint idiom (a purely textual include scan would cover both cases), or
- document that
#if 0 hints have no effect under fbuild and that conditional includes require lib_deps, so projects know the LDF idiom does not port.
Not urgent — lib_deps unblocks FastLED today. Filing so the divergence is recorded rather than rediscovered.
Context
Summary
A SAMD21/SAMD51 build cannot resolve
<SPI.h>, and neither of the two ways FastLED expresses that dependency insrc/is picked up by fbuild's framework-library scan. Only an explicitlib_depsinplatformio.iniworks.Reproduced on
samd21,samd21_zero,samd51jandmetro_m4(FastLED/FastLED#4015).Both in-source signals are missed
1. The real include, under a condition that is true.
fastspi_arm_sam.h:Both macros are defined for these boards, and the file is genuinely compiled — that is precisely why the build fails on the missing header. So the scan either does not evaluate the conditional, or evaluates it without the
-Dset the real compile has (FL_IS_SAMD21is derived several headers deep from-D__SAMD21G18A__).2. The
#if 0LDF hint.platforms/arm/samd/ldf_headers.h, reached fromFastLED.hviaplatforms/ldf_headers.h:This is the PlatformIO-LDF idiom — LDF in
chainmode scans#includedirectives without evaluating conditionals, so a dead block declares a dependency. FastLED uses it inplatforms/esp/8266/ldf_headers.has well.The two misses point in opposite directions: (1) is missed as if conditionals were evaluated, (2) as if they were. Whatever the scanner does,
<SPI.h>is unreachable from this include graph either way.What is and is not surprising
framework_libs.rsis explicit thatlib_ldf_modeis unimplemented and thatlib_depsis "the escape hatch for a dependency the finder scan never reaches", so needing the escape hatch is a documented outcome rather than a broken promise. Two things still seem worth a decision:chainin PlatformIO specifically does not evaluate conditionals, which is what makes the#if 0idiom work. If fbuild's chain-style scan does evaluate them, the shared name is misleading for anyone porting a project that relies on the idiom.Ask
Either:
#if 0hint idiom (a purely textual include scan would cover both cases), or#if 0hints have no effect under fbuild and that conditional includes requirelib_deps, so projects know the LDF idiom does not port.Not urgent —
lib_depsunblocks FastLED today. Filing so the divergence is recorded rather than rediscovered.Context