Skip to content

LDF misses library-source includes behind #if / __has_include — Teensyduino bundled libs never linked (reopens #1214 class) #1337

Description

@zackees

Summary

Teensyduino bundled framework libraries land on the include path but their sources never reach the link line, so any TU that includes them compiles and then fails with undefined references.

This is the same class as #1214 ("LDF resolves libraries only from sketch includes — library-source #include <SPI.h> never reaches the link line", closed 2026-08-01), but the symptom persists on current releases.

Repro (FastLED, ~1 minute)

bash compile teensy30 --examples SpecialDrivers/Adafruit/AdafruitBridge
undefined reference to `Adafruit_NeoPixel::Adafruit_NeoPixel(unsigned short, unsigned char, unsigned short)'
undefined reference to `Adafruit_NeoPixel::begin()'
undefined reference to `Adafruit_NeoPixel::show()'
collect2.exe: error: ld returned 1 exit status

Tested on Windows:

fbuild result
2.5.18 fails
2.5.19 fails

Where the sources are

Teensyduino ships headers and sources together:

.../dl-framework-arduinoteensy-1.160.0/.../1.160.0/libraries/
    Adafruit_NeoPixel/Adafruit_NeoPixel.h  + Adafruit_NeoPixel.cpp
    Audio/...                              + *.cpp
    SPI/SPI.h                              + SPI.cpp

All three are omitted the same way, which is why FastLED's teensy41 all sweep reports Audio, Adafruit_NeoPixel and SPI link errors together (FastLED/FastLED#3838). It currently fails all 8 Teensy workflows (teensy30/31/32/35/36/40/41/LC), not just teensy41.

Likely gap vs #1214

The failing include is in library source and inside a preprocessor conditional — FastLED src/platforms/adafruit/clockless.cpp.hpp:7:

#if FL_HAS_INCLUDE(<Adafruit_NeoPixel.h>)
#include <Adafruit_NeoPixel.h>

If the LDF scanner skips #if blocks (or cannot evaluate __has_include), it never sees the include — while the compiler's __has_include resolves it, because the header is on the path fbuild provided. The header's presence is what activates the code needing the library, so the two decisions have to agree.

Suggested handling: when a framework libraries/<name> directory is placed on the include path, treat a reference from any compiled TU (sketch or library source, including inside conditionals) as a link dependency — or resolve __has_include consistently between the scanner and the compiler.

Impact

Blocks FastLED master CI: 8 Teensy workflows red. FastLED has no local fix available — per-example include shims and example filters are both explicitly ruled out by FastLED/FastLED#3838's acceptance criteria, and it has no per-example lib_deps mechanism.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions