From f82716035875b0f035d6e8118774ec5de4b39966 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Fri, 18 Sep 2026 10:33:36 -0700 Subject: [PATCH] fix(esp32): drop core-bundled libraries from lib_deps before the registry `lib_deps = FS / ArduinoOTA / ESPmDNS` is valid PlatformIO: those names resolve to the Arduino core's own libraries/. fbuild sent every bare lib_deps name to the PlatformIO registry, which does not carry them: build error: package error: library 'FS' not found in registry The ESP32 build already puts every bundled library on the include path and compiles it with the framework, so filter the bundled names out with fbuild_library_select::external_declared_deps, as RP2040 already does, both in the build and in `fbuild install` (downloadable_lib_deps). Fixes #1442 Co-Authored-By: Claude Opus 5 (1M context) --- crates/fbuild-build-esp/src/esp32/mod.rs | 11 +++++++ .../src/esp32/orchestrator/build.rs | 13 +++++++- .../src/esp32/orchestrator/mod.rs | 2 +- .../src/esp32/orchestrator/packages.rs | 32 +++++++++++++++++++ crates/fbuild-library-select/src/lib_tests.rs | 29 +++++++++++++++++ 5 files changed, 85 insertions(+), 2 deletions(-) diff --git a/crates/fbuild-build-esp/src/esp32/mod.rs b/crates/fbuild-build-esp/src/esp32/mod.rs index f7095f661..ac79c6868 100644 --- a/crates/fbuild-build-esp/src/esp32/mod.rs +++ b/crates/fbuild-build-esp/src/esp32/mod.rs @@ -28,6 +28,17 @@ impl crate::PlatformSupport for Esp32PlatformSupport { orchestrator::provision_esp32(inputs, mode).await } + /// The Arduino core bundles libraries (FS, WiFi, ESPmDNS, ...) that + /// `lib_deps` may name; the build filters them out before downloading, + /// so provisioning must too (FastLED/fbuild#1442). + fn downloadable_lib_deps( + &self, + inputs: &crate::provision::ProvisionInputs<'_>, + lib_deps: Vec, + ) -> Vec { + orchestrator::downloadable_lib_deps(inputs, lib_deps) + } + fn default_board_id(&self) -> &str { "esp32dev" } diff --git a/crates/fbuild-build-esp/src/esp32/orchestrator/build.rs b/crates/fbuild-build-esp/src/esp32/orchestrator/build.rs index d7e25f0d3..5ae32286b 100644 --- a/crates/fbuild-build-esp/src/esp32/orchestrator/build.rs +++ b/crates/fbuild-build-esp/src/esp32/orchestrator/build.rs @@ -295,7 +295,18 @@ impl BuildOrchestrator for Esp32Orchestrator { } // 8.5. Library dependencies - let lib_deps = ctx.config.get_lib_deps(¶ms.env_name)?; + // + // `lib_deps` may name libraries the Arduino core bundles (`FS`, + // `ArduinoOTA`, `ESPmDNS`, ...), as PlatformIO allows. Those are + // already on the include path above and compiled with the framework, + // so drop them rather than sending them to the registry, which does + // not carry them (FastLED/fbuild#1442). RP2040 does the same. + let lib_deps = fbuild_library_select::external_declared_deps( + &ctx.config.get_lib_deps(¶ms.env_name)?, + &fbuild_packages::library::framework_library::discover_framework_libraries( + &builtin_libs_dir, + ), + ); let lib_ignore = ctx.config.get_lib_ignore(¶ms.env_name)?; use fbuild_packages::Toolchain; diff --git a/crates/fbuild-build-esp/src/esp32/orchestrator/mod.rs b/crates/fbuild-build-esp/src/esp32/orchestrator/mod.rs index ea478d2f0..32ca57f8b 100644 --- a/crates/fbuild-build-esp/src/esp32/orchestrator/mod.rs +++ b/crates/fbuild-build-esp/src/esp32/orchestrator/mod.rs @@ -34,7 +34,7 @@ mod helpers; mod local_libs; mod packages; -pub(crate) use packages::provision_esp32; +pub(crate) use packages::{downloadable_lib_deps, provision_esp32}; #[cfg(test)] mod tests; diff --git a/crates/fbuild-build-esp/src/esp32/orchestrator/packages.rs b/crates/fbuild-build-esp/src/esp32/orchestrator/packages.rs index b28b27cdc..4f0b81d30 100644 --- a/crates/fbuild-build-esp/src/esp32/orchestrator/packages.rs +++ b/crates/fbuild-build-esp/src/esp32/orchestrator/packages.rs @@ -626,3 +626,35 @@ async fn provision_esptool( row.duration_ms = started.elapsed().as_millis() as u64; Some(row) } + +/// Drop `lib_deps` entries the installed Arduino core bundles (`FS`, +/// `ArduinoOTA`, `ESPmDNS`, ...), exactly as the build does, so `fbuild +/// install` does not send them to the registry (FastLED/fbuild#1442). +/// Without an installed platform and framework there is nothing to compare +/// against, and every entry is returned. +pub(crate) fn downloadable_lib_deps( + inputs: &ProvisionInputs<'_>, + lib_deps: Vec, +) -> Vec { + use fbuild_packages::{Framework as _, Package as _}; + let env_config = Some(inputs.env_config); + let platform = pioarduino_platform(inputs.project_dir, env_config); + if !platform.is_installed() { + return lib_deps; + } + let framework = pioarduino_framework( + &platform, + inputs.project_dir, + inputs.board.mcu.as_str(), + env_config, + ); + if !framework.is_installed() { + return lib_deps; + } + fbuild_library_select::external_declared_deps( + &lib_deps, + &fbuild_packages::library::framework_library::discover_framework_libraries( + &framework.get_libraries_dir(), + ), + ) +} diff --git a/crates/fbuild-library-select/src/lib_tests.rs b/crates/fbuild-library-select/src/lib_tests.rs index 0c3dced76..9616692dc 100644 --- a/crates/fbuild-library-select/src/lib_tests.rs +++ b/crates/fbuild-library-select/src/lib_tests.rs @@ -621,3 +621,32 @@ fn declared_dep_name_normalization() { assert_eq!(declared_dep_name("https://example.com/x.git"), None); assert_eq!(declared_dep_name("./local"), None); } + +#[test] +fn esp32_core_bundled_lib_deps_are_not_sent_to_the_registry() { + // FastLED/fbuild#1442: arduino-esp32 ships FS, ArduinoOTA and ESPmDNS in + // its `libraries/`; naming them in lib_deps must not reach the registry, + // while real registry and git dependencies still do. + let tmp = tempdir(); + let libraries = vec![ + lib(tmp.path(), "FS"), + lib(tmp.path(), "ArduinoOTA"), + lib(tmp.path(), "ESPmDNS"), + lib(tmp.path(), "WiFi"), + ]; + let declared = vec![ + "https://github.com/dvarrel/AsyncTCP".to_string(), + "bblanchon/ArduinoJson".to_string(), + "FS".to_string(), + "ArduinoOTA".to_string(), + "ESPmDNS".to_string(), + ]; + + assert_eq!( + external_declared_deps(&declared, &libraries), + vec![ + "https://github.com/dvarrel/AsyncTCP".to_string(), + "bblanchon/ArduinoJson".to_string(), + ] + ); +}