You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fbuild 2.2.5 fails to build any sketch (reproduced with FastLED examples/Blink/Blink.ino) for teensy41. The failure is not in the user sketch or in FastLED — it is in a host-only command-line tool that ships inside the Teensy framework's bundled ssd1351 library:
build error: build failed: compilation failed for
C:\Users\niteris\.fbuild\prod\cache\platforms\dl-framework-arduinoteensy-1.160.0\1b0675c97b0fd8d7\1.160.0\libraries\ssd1351\fontconvert\fontconvert.c:
C:/.../libraries/ssd1351/fontconvert/fontconvert.c:23:10:
fatal error: ft2build.h: No such file or directory
23 | #include <ft2build.h>
| ^~~~~~~~~~~~
compilation terminated.
fontconvert.c is self-documented at the top as:
NOT AN ARDUINO SKETCH. This is a command-line tool for preprocessing fonts to be used with the Adafruit_GFX Arduino library.
REQUIRES FREETYPE LIBRARY. www.freetype.org
It ships with its own Makefile that links -lfreetype. It is a host build-time utility, never intended for ARM cross-compilation.
What Arduino IDE and PlatformIO do that fbuild doesn't
Per the Arduino library specification, the ssd1351 library is a 1.0 flat-layout library (no src/ directory). The spec says:
the source code is searched from the library root folder and the utility folder
Root is non-recursive; the only special subdirectory is literally utility/ (lowercase). Subdirectories like fontconvert/, util/, Fonts/, examples/, and extras/ are ignored for compilation. The ssd1351 author parked the host tool in fontconvert/ (not utility/) precisely so Arduino IDE would skip it.
PlatformIO is doubly protected:
LDF — Blink does not #include <ssd1351.h>, so PIO never compiles ssd1351 at all.
srcDir default = src — even if LDF picked it, PIO's default would skip the flat-layout root entirely.
Note: the ssd1351library.json has "exclude": ["extras", "*.bmp"], but that is an export field governing pio pkg pack packaging — NOT a build filter. Honoring that field alone wouldn't fix this.
Two layered bugs in fbuild
Bug 1 — Library-selection leak. ssd1351 is being compiled even though the sketch never references it. This is the same shape as #204 (teensy30/LC FNET/Snooze/RadioHead/mbedtls), which the #205 → #214 LDF work was supposed to fix for the teensy orchestrator. Either teensy41 isn't going through resolve_framework_library_sources_cached, or the LDF transitively pulls in ssd1351 via some reachable header.
Bug 2 — Arduino library spec violation when scanning a selected library. Even after LDF correctly selects a library, fbuild recursively globs all .c/.cpp files inside it, including non-source subdirectories. Per the Arduino spec, 1.0 flat-layout libraries should only scan the root (non-recursive) + utility/ (literal); 1.5 recursive libraries should only scan src/ recursively. Anything else is ignored.
Bug 2 is the more general one — any library that ships a host-side tool in a non-utility/ subdirectory will hit it.
Reproduction
git clone https://github.com/FastLED/FastLED
cd FastLED
bash compile teensy41
Or, equivalently, any project that includes FastLED targeting teensy41 against framework-arduinoteensy 1.160.0.
This is the third teensy41 issue in quick succession. Suggests teensy41's larger bundled-library set is exercising library-scanner bugs that other platforms hide.
Proposal
Two independent fixes; both should land.
Fix 1 — Investigate why ssd1351 is reaching the compile set on teensy41
Verify that crates/fbuild-build/src/teensy/orchestrator.rs actually goes through resolve_framework_library_sources_cached (the #214 wiring) for teensy41, not just teensy30/LC. If it does, trace why ssd1351 is being pulled in — most likely a transitive #include chain from a header that IS referenced. Dump compile_commands.json for a Blink+teensy41 build and audit the source-file origins, mirroring the #204 evidence table.
Fix 2 — Honor the Arduino library specification when scanning a selected library
When collecting source files inside a chosen Arduino library, dispatch on layout:
if library_dir/src exists:
# 1.5 recursive layout
sources = glob(library_dir/src/**/*.{c,cpp,cc,cxx,S,ino})
else:
# 1.0 flat layout
sources = glob(library_dir/*.{c,cpp,cc,cxx,S,ino}) # non-recursive
sources += glob(library_dir/utility/**/*.{c,cpp,cc,cxx,S}) # only this subdir, literally lowercase
This matches arduino-cli behavior exactly and makes fbuild safe against any well-formed Arduino library shipping companion tooling. It also speeds up scanning by skipping examples/, extras/, Fonts/, etc., which are never compiled in any sane build system.
The fix likely belongs in crates/fbuild-library-select/ (the scanner) and/or crates/fbuild-build/src/framework_libs.rs (where sources are collected per selected library).
Local workaround until fix lands
Delete C:\Users\niteris\.fbuild\prod\cache\platforms\dl-framework-arduinoteensy-1.160.0\1b0675c97b0fd8d7\1.160.0\libraries\ssd1351\fontconvert\fontconvert.c from the framework cache. Confirms whether Bug 2 is the only blocker (i.e. does the build succeed once that one file is gone, or does another ssd1351-internal file also fail).
Acceptance criteria
bash compile teensy41 (FastLED Blink) succeeds on a clean fbuild install with no manual cache surgery.
Regression test: a CI job builds Blink on teensy41 against framework-arduinoteensy-1.160.0 (or whatever is current) and asserts the build passes.
Unit test in the library-source scanner: given a fixture mimicking the ssd1351 1.0 flat layout (root files + fontconvert/fontconvert.c + util/x.c + examples/ + Fonts/), the scanner returns root files + utility/ content only — never reaches fontconvert/, util/, examples/, or Fonts/ (Fix 2).
Equivalent fixture test for a 1.5 recursive layout (src/foo.cpp compiled, src/sub/bar.cpp compiled, root-level baz.cpp NOT compiled).
Decisions
Repo:fastled/fbuild — confirmed via the package's METADATA (links to github.com/fastled/fbuild); the fbuild PyPI package has no Home-page field set.
Two bugs, one issue: Fix 1 (LDF) and Fix 2 (Arduino spec) are filed together because they share a root cause class ("fbuild compiles things Arduino IDE and PlatformIO don't"), are diagnosed by the same evidence, and Fix 2 is the more general protection. Triage may want to split.
Context
fbuild 2.2.5fails to build any sketch (reproduced with FastLEDexamples/Blink/Blink.ino) forteensy41. The failure is not in the user sketch or in FastLED — it is in a host-only command-line tool that ships inside the Teensy framework's bundledssd1351library:fontconvert.cis self-documented at the top as:It ships with its own
Makefilethat links-lfreetype. It is a host build-time utility, never intended for ARM cross-compilation.What Arduino IDE and PlatformIO do that fbuild doesn't
Per the Arduino library specification, the
ssd1351library is a 1.0 flat-layout library (nosrc/directory). The spec says:Root is non-recursive; the only special subdirectory is literally
utility/(lowercase). Subdirectories likefontconvert/,util/,Fonts/,examples/, andextras/are ignored for compilation. The ssd1351 author parked the host tool infontconvert/(notutility/) precisely so Arduino IDE would skip it.PlatformIO is doubly protected:
#include <ssd1351.h>, so PIO never compiles ssd1351 at all.srcDirdefault =src— even if LDF picked it, PIO's default would skip the flat-layout root entirely.Note: the
ssd1351library.jsonhas"exclude": ["extras", "*.bmp"], but that is anexportfield governingpio pkg packpackaging — NOT a build filter. Honoring that field alone wouldn't fix this.Two layered bugs in fbuild
Bug 1 — Library-selection leak. ssd1351 is being compiled even though the sketch never references it. This is the same shape as #204 (teensy30/LC FNET/Snooze/RadioHead/mbedtls), which the #205 → #214 LDF work was supposed to fix for the teensy orchestrator. Either teensy41 isn't going through
resolve_framework_library_sources_cached, or the LDF transitively pulls in ssd1351 via some reachable header.Bug 2 — Arduino library spec violation when scanning a selected library. Even after LDF correctly selects a library, fbuild recursively globs all
.c/.cppfiles inside it, including non-source subdirectories. Per the Arduino spec, 1.0 flat-layout libraries should only scan the root (non-recursive) +utility/(literal); 1.5 recursive libraries should only scansrc/recursively. Anything else is ignored.Bug 2 is the more general one — any library that ships a host-side tool in a non-
utility/subdirectory will hit it.Reproduction
git clone https://github.com/FastLED/FastLED cd FastLED bash compile teensy41Or, equivalently, any project that includes FastLED targeting
teensy41againstframework-arduinoteensy 1.160.0.Environment:
framework-arduinoteensy-1.160.0Recent related teensy41 regressions
Proposal
Two independent fixes; both should land.
Fix 1 — Investigate why ssd1351 is reaching the compile set on teensy41
Verify that
crates/fbuild-build/src/teensy/orchestrator.rsactually goes throughresolve_framework_library_sources_cached(the #214 wiring) forteensy41, not justteensy30/LC. If it does, trace why ssd1351 is being pulled in — most likely a transitive#includechain from a header that IS referenced. Dumpcompile_commands.jsonfor a Blink+teensy41 build and audit the source-file origins, mirroring the #204 evidence table.Fix 2 — Honor the Arduino library specification when scanning a selected library
When collecting source files inside a chosen Arduino library, dispatch on layout:
This matches
arduino-clibehavior exactly and makes fbuild safe against any well-formed Arduino library shipping companion tooling. It also speeds up scanning by skippingexamples/,extras/,Fonts/, etc., which are never compiled in any sane build system.The fix likely belongs in
crates/fbuild-library-select/(the scanner) and/orcrates/fbuild-build/src/framework_libs.rs(where sources are collected per selected library).Local workaround until fix lands
Delete
C:\Users\niteris\.fbuild\prod\cache\platforms\dl-framework-arduinoteensy-1.160.0\1b0675c97b0fd8d7\1.160.0\libraries\ssd1351\fontconvert\fontconvert.cfrom the framework cache. Confirms whether Bug 2 is the only blocker (i.e. does the build succeed once that one file is gone, or does another ssd1351-internal file also fail).Acceptance criteria
bash compile teensy41(FastLED Blink) succeeds on a clean fbuild install with no manual cache surgery.framework-arduinoteensy-1.160.0(or whatever is current) and asserts the build passes.fontconvert/fontconvert.c+util/x.c+examples/+Fonts/), the scanner returns root files +utility/content only — never reachesfontconvert/,util/,examples/, orFonts/(Fix 2).src/foo.cppcompiled,src/sub/bar.cppcompiled, root-levelbaz.cppNOT compiled).Decisions
fastled/fbuild— confirmed via the package'sMETADATA(links togithub.com/fastled/fbuild); thefbuildPyPI package has noHome-pagefield set.crates/fbuild-library-select/,crates/fbuild-build/src/framework_libs.rs,crates/fbuild-build/src/teensy/orchestrator.rs) — based on the feat(library-selection): Rust-native LDF-style transitive header scanner, zccache-backed #205/#205 follow-up: wire library-selection cache into orchestrators (teensy, stm32) #214 PR refs; maintainers know better.buglabel applied — repo's prior issues mostly leave labels empty; following convention.Related issues