Skip to content

fix(rp2040): do not infer Bluetooth-only Arduino-Pico libraries when Bluetooth is off - #1606

Merged
zackees merged 1 commit into
mainfrom
fix/rp2350-btstack-selection
Oct 2, 2026
Merged

zackees merged 1 commit into
mainfrom
fix/rp2350-btstack-selection

Conversation

@zackees

@zackees zackees commented Oct 2, 2026

Copy link
Copy Markdown
Member

Problem

A plain Raspberry Pi Pico 2 (rp2350, board = rpipico2, no Bluetooth) FastLED build has failed since fbuild 2.5.28. The framework-library selector picks Arduino-Pico's BTstackLib, and compiling it fails:

libraries/BTstackLib/src/BTstackLib.cpp
cores/rp2040/_needsbt.h:4:24: error: static assertion failed: This library needs Bluetooth enabled.

Bisect

Clean builds (--clean) of the same generated project (.build/fbuild/rp2350 from FastLED bash compile rp2350 --examples Blink, earlephilhower core 5.7.0):

fbuild result
2.5.26 pass
2.5.27 pass
2.5.28 fail
2.5.29 fail

The only build change in 2.5.27..2.5.28 is ae0cf3a (#1473): "compile only reached lib/ libraries ... only selected local libraries seed framework-library selection".

Root cause

  1. Seeds changed. Before fix(build): fail oversize images, compile only reached lib/ libraries, warn on ignored version pins #1473, collect_local_library_seeds walked lib/<name>/ through should_scan_entry, which prunes any directory named build. FastLED ships flat in lib/FastLED/ and keeps all of its translation units in fl/build/*.cpp, which are unity TUs. So fbuild 2.5.27 seeded only one FastLED file (platforms/esp/32/drivers/gpio_isr_rx/fast_isr.S). Since fix(build): fail oversize images, compile only reached lib/ libraries, warn on ignored version pins #1473, seeds come from InstalledLibrary::get_source_files(), which is what the build actually compiles. That adds all 29 fl/build/*+.cpp unity TUs. The new seeding is correct ("what compiles is what seeds"). The old behaviour got this right only by accident.
  2. Guard is undecidable. fl/build/platforms+.cpp → platforms/_build.cpp.hpp → platforms/arm/rp/_build.cpp.hpp → platforms/arm/rp/ble_rp.cpp.hpp. That file has #include <BTstackLib.h> under #if FL_BLE_AVAILABLE && defined(FL_IS_RP2350). FastLED headers #define both macros, so by design (docs/architecture/library-selection.md, "undecidable" row, Framework-library scan misses <SPI.h> for SAMD: neither the active conditional include nor the #if 0 LDF hint is seen #1371) the scanner scans every arm. BTstackLib gets selected.
  3. The selected library cannot compile. BTstackLib.h does #include <_needsbt.h>, which static_asserts ENABLE_CLASSIC. Only the board's Bluetooth ipbtstack menu entries set that macro (-DENABLE_CLASSIC=1 -DENABLE_BLE=1 ...).

arduino-cli (it preprocesses) and PlatformIO chain (it does not scan every TU of a dependency library) would not select BTstackLib here.

Confirmed directly. Removing only the #include <BTstackLib.h> line from the project's ble_rp.cpp.hpp (with the selection cache cleared) makes the unfixed build pass.

Fix

Arduino-Pico marks every Bluetooth-only library with #include <_needsbt.h>. Picking one of those by inference when ENABLE_CLASSIC is unset can never produce a working build. The new rp2040/bluetooth_libs.rs removes these libraries from the RP2040 framework-library candidates unless one of the following holds:

  • ENABLE_CLASSIC is truthy, from the board menu defines or from the user's build_flags, or
  • lib_deps names the library. An explicit declaration still wins, and the framework's own error then explains the missing menu.

Generic selection semantics are unchanged. fbuild_library_select::declared_dep_name becomes pub so the lib_deps matching is reused rather than duplicated. A short note was added to docs/architecture/library-selection.md.

Tests

  • New unit tests in crates/fbuild-build-arm/src/rp2040/bluetooth_libs.rs. RED against a pass-through stub: drops_bluetooth_library_when_bluetooth_is_disabled and drops_bluetooth_library_when_enable_classic_is_zero failed. GREEN after the fix: all 5 pass. They cover the menu enabling Bluetooth, a lib_deps declaration, and a commented-out include.
  • soldr cargo test -p fbuild-build-arm -p fbuild-library-select: all pass (233 + 32 + ...).
  • soldr cargo clippy -p fbuild-build-arm -p fbuild-library-select --all-targets -- -D warnings: clean.

End-to-end (locally built FBUILD_DEV_MODE=1 target/debug/fbuild build <proj> -e <env> --clean)

project before (origin/main 144635a) after
rp2350 (rpipico2, no BT) fail: BTstackLib.cpp → _needsbt.h static assertion pass: build succeeded in 36.2s (flash: 618464 bytes, ram: 60168 bytes). Daemon log shows skipping framework library ... BTstackLib (plus SerialBT, HID_Bluetooth, BluetoothHIDMaster, ...)
rp2350w (rpipico2w, board_build.ipbtstack = ipv4btcble, lib_deps = BTstackLib, HTTPUpdate) (passes on 2.5.29) pass: build succeeded in 42.8s, BTstackLib still selected

Related, not fixed here

The library-select cache key hashes seed (TU) contents and each library's canonical header, but not the project headers the walk reaches. Editing only ble_rp.cpp.hpp therefore produced a cache hit with the same key and the stale selection. That made a "remove the include and rebuild" experiment look like the include was not the cause. --clean does not clear ~/.fbuild/<mode>/cache/library-selection. This deserves its own issue.

…Bluetooth is off

Since #1473 seeds every TU a local library compiles, FastLED's unity TUs
(lib/FastLED/fl/build/*.cpp, previously skipped because the seed walk
pruned any dir named 'build') reach platforms/arm/rp/ble_rp.cpp.hpp. Its
#include <BTstackLib.h> sits behind '#if FL_BLE_AVAILABLE &&
defined(FL_IS_RP2350)', both header-derived and therefore undecidable to
the scanner, so every arm is scanned and BTstackLib is selected for a
plain Pico 2 build. BTstackLib.h includes the core's _needsbt.h, which
static_asserts ENABLE_CLASSIC, so the build fails.

Arduino-Pico declares its Bluetooth libraries with #include <_needsbt.h>.
Drop those from the RP2040 framework-library candidates unless
ENABLE_CLASSIC is set (ipbtstack menu or build_flags); a lib_deps entry
still selects one.
@coderabbitai

coderabbitai Bot commented Oct 2, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 29 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository: FastLED/fbuild/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 4749f1a7-254e-4d98-8491-739d5a49d189

📥 Commits

Reviewing files that changed from the base of the PR and between 144635a and a792277.

📒 Files selected for processing (5)
  • crates/fbuild-build-arm/src/rp2040/bluetooth_libs.rs
  • crates/fbuild-build-arm/src/rp2040/mod.rs
  • crates/fbuild-build-arm/src/rp2040/orchestrator.rs
  • crates/fbuild-library-select/src/lib.rs
  • docs/architecture/library-selection.md
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

1 participant