Skip to content

research: evaluate Arduino FQBN resolution as a native build input #1298

Description

@zackees

Context

Reproducing FastLED/FastLED#3876 required the exact Arduino board identity Seeeduino:mbed:xiaonRF52840Plus from Seeed's Seeeduino:mbed@2.9.3 package. Arduino CLI could install that vendor package from Seeed's package index and compile the sketch directly from the FQBN:

arduino-cli core install Seeeduino:mbed@2.9.3 \
  --additional-urls https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json
arduino-cli compile \
  --fqbn Seeeduino:mbed:xiaonRF52840Plus \
  --library /path/to/FastLED examples/Blink

The nearest fbuild reproduction had to go through a PlatformIO board/platform definition. The official Seeed PlatformIO platform URL was rejected before board resolution with unsupported platform: https://github.com/Seeed-Studio/platform-seeedboards.git#..., even though the FQBN and Arduino package describe the target precisely.

The current codebase already contains useful pieces:

  • fbuild_config::BoardConfig::from_boards_txt parses Arduino boards.txt records.
  • fbuild_build_engine::arduino_props applies default and explicit board-menu choices.
  • ResolutionContext is the intended funnel for new board-resolution inputs.
  • Native builds currently select a fixed Platform via Platform::from_platform_str, and the embedded board database is derived from PlatformIO registry JSON.

There is no current FQBN input or Arduino package-index resolver, so vendor cores that are absent from the PlatformIO registry cannot be named in their native Arduino identity.

Proposal

Research and prototype an additive FQBN resolution path for native fbuild builds:

  1. Parse Arduino FQBNs (vendor:architecture:board[:menu=value,...]) into a typed identity.
  2. Resolve an explicitly selected vendor package and version from an installed Arduino data directory and/or a supplied package-index URL.
  3. Read the package's boards.txt, platform.txt, menu selections, tool dependencies, variants, and precompiled framework metadata.
  4. Normalize the result through ResolutionContext/BoardConfig where possible, while documenting which Arduino recipe semantics require a new abstraction.
  5. Keep existing platformio.ini board/platform resolution unchanged; FQBN support should be an additive input, not an implicit reinterpretation of PlatformIO board IDs.
  6. Use Arduino CLI output as a parity oracle during development, without making arduino-cli a runtime dependency of native fbuild.

The Seeed XIAO nRF52840 Plus package above is the motivating vertical slice. Arduino Uno should be used as a control case so the design is not accidentally vendor-specific.

Acceptance criteria

  • RED evidence is checked in showing that native fbuild cannot currently resolve/build Seeeduino:mbed:xiaonRF52840Plus, including the current unsupported-platform or unknown-board diagnostic.
  • A short design note documents FQBN parsing, package/version/index selection, cache layout, offline behavior, checksum/trust policy, menu-option handling, and how Arduino build recipes map to existing fbuild orchestrators.
  • A focused prototype or first implementation resolves Seeeduino:mbed:xiaonRF52840Plus from Seeeduino:mbed@2.9.3 and exposes the normalized board/platform properties in a deterministic test.
  • GREEN evidence demonstrates the same focused repro passing through the proposed native path, ideally compiling Blink; if compilation is deliberately deferred, the issue must produce scoped implementation follow-ups with the remaining unsupported recipe semantics identified.
  • Existing PlatformIO-style resolution tests remain green, and an Arduino Uno FQBN control test proves the parser/resolver is not Seeed-specific.
  • Invalid FQBNs, missing package versions, unavailable indexes, and unsupported architectures fail with actionable diagnostics that include the unresolved identity.

Decisions

  • Treat this as P2 research/feature work: it unlocks exact vendor-core reproduction but does not block already-supported boards.
  • Make FQBN resolution additive to the current PlatformIO configuration model to avoid changing existing project semantics.
  • Pin package version and package-index source explicitly in the reproducible path; silently selecting a latest vendor core would make builds nondeterministic.
  • Prefer a native resolver over shelling out to Arduino CLI so fbuild retains its standalone, cacheable build model.
  • Use the Seeed Mbed package as the first vertical slice because it exercises a real gap that the embedded PlatformIO board database cannot represent today.

Open questions

  • Should the user-facing surface be fbuild build --fqbn ..., a new configuration key, a generated ephemeral environment, or more than one of these?
  • Should fbuild initially consume only already-installed Arduino packages, or own package-index download/install/cache behavior from the first release?
  • How much of generic Arduino platform.txt recipe evaluation should be implemented versus translating known architectures into existing native orchestrators?

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