Skip to content

Framework-library scan misses <SPI.h> for SAMD: neither the active conditional include nor the #if 0 LDF hint is seen #1371

Description

@zackees

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions