A fast, next-generation multi-platform compiler, deployer, and monitor for embedded development, directly compatible with platformio.ini
Fbuild is a next-generation embedded development tool featuring a clean, transparent architecture. It provides fast incremental builds, URL-based package management, and soon to be comprehensive multi-platform support for Arduino and ESP32 development.
platformio.ini compatible
fbuiold uses the same platformio.ini already used in platformio sketches.
Design Goals
- Replaces
platformioinFastLEDrepo builders - Correct and parallel package management system
- locking is done through a daemon process
- packages are fingerprinted to their version and cached, download only once
- sccache for caching compiles
- Eesily add features via AI
- This codebase is designed and implemented by AI, just fork it and ask ai to make your change Please send us a PR!
Current Status: v1.1.0 - Full Arduino Uno / esp32c6 support with working build system
Quick start - Build, deploy, and monitor in one command:
# install
pip install fbuild# Default action: build + deploy
fbuild tests/esp32c6# Default action: build + deploy + monitor
fbuild tests/esp32c6 --monitorDeploy commands:
# Deploy with clean build
fbuild deploy tests/esp32c6 --clean
# Deploy with monitoring and test patterns
fbuild deploy tests/esp32c6 --monitor="--timeout 60 --halt-on-error \"TEST FAILED\" --halt-on-success \"TEST PASSED\""Monitor command:
# Monitor serial output with pattern matching
uv run fbuild monitor --timeout 60 --halt-on-error "TEST FAILED" --halt-on-success "TEST PASSED"- Serial monitoring requires pyserial to attach to the USB device
- Port auto-detection works similarly to PlatformIO
fbuild supports deploying to QEMU for testing ESP32 firmware without physical hardware.
| Platform | QEMU Status | Notes |
|---|---|---|
| ESP32dev (original ESP32) | β Fully supported | Recommended for QEMU testing |
| ESP32-S3 | β Not supported | Bootloader incompatible with QEMU |
| ESP32C6 | β Not supported | QEMU lacks C6 emulation |
| ESP32C3 | May work (RISC-V architecture) |
# Build for QEMU (use esp32dev)
fbuild build tests/esp32dev -e esp32dev-qemu
# Deploy to QEMU
fbuild deploy tests/esp32dev -e esp32dev-qemu --qemuAdd QEMU environment to platformio.ini:
[env:esp32dev-qemu]
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.34/platform-espressif32.zip
board = esp32dev
framework = arduino
board_build.flash_mode = dio # Required for QEMU
board_upload.flash_mode = dio # Required for QEMU- Docker installed and running
espressif/idf:latestDocker image (pulled automatically)
-
ESP32-S3 bootloader incompatibility: The ESP32-S3 software bootloader contains QIO mode detection logic that crashes in QEMU. Use ESP32dev for QEMU testing instead.
-
ESP32C6 chip ID mismatch: QEMU doesn't have native ESP32C6 support yet. It falls back to ESP32C3 emulation, which causes chip ID validation failures.
-
Performance: QEMU emulation is slower than real hardware. Use for basic functional testing, not performance validation.
-
Peripheral emulation: Not all peripherals are fully emulated. Test on real hardware for production validation.
- URL-based Package Management: Direct URLs to toolchains and platforms - no hidden registries
- Library Management: Download and compile Arduino libraries from GitHub URLs
- Fast Incremental Builds: 0.76s rebuilds, 3s full builds (cached)
- LTO Support: Link-Time Optimization for optimal code size
- Transparent Architecture: Know exactly what's happening at every step
- Real Downloads, No Mocks: All packages are real, validated, and checksummed
- Cross-platform Support: Windows, macOS, and Linux
- Modern Python: 100% type-safe, PEP 8 compliant, tested
# Install from PyPI (when published)
pip install fbuild
# Or install from source
git clone https://github.com/yourusername/fbuild.git
cd fbuild
pip install -e .- Create project structure:
mkdir my-project && cd my-project
mkdir src- Create platformio.ini:
[env:uno]
platform = atmelavr
board = uno
framework = arduino- Write your sketch (
src/main.ino):
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}- Build:
fbuild buildOn first build, Fbuild will:
- Download AVR-GCC toolchain (50MB, one-time)
- Download Arduino AVR core (5MB, one-time)
- Compile your sketch
- Generate
firmware.hexin.fbuild/build/uno/
Build time: ~19s first build, ~3s subsequent builds, <1s incremental
# Build with auto-detected environment
fbuild build
# Build specific environment
fbuild build --environment uno
fbuild build -e mega
# Clean build (remove all build artifacts)
fbuild build --clean
# Verbose output (shows all compiler commands)
fbuild build --verbose
# Build in different directory
fbuild build --project-dir /path/to/projectBuilding environment: uno
Downloading toolchain: avr-gcc 7.3.0-atmel3.6.1-arduino7
Downloading: 100% ββββββββββββββββββββ 50.1MB/50.1MB
Extracting package...
Toolchain ready at: .fbuild/cache/...
Downloading Arduino core: 1.8.6
Compiling sketch...
Compiling Arduino core...
Linking firmware...
Converting to Intel HEX...
β Build successful!
Firmware: .fbuild/build/uno/firmware.hex
Program: 1058 bytes (3.3% of 32256 bytes)
RAM: 9 bytes (0.4% of 2048 bytes)
Build time: 3.06s
Minimal configuration:
[env:uno]
platform = atmelavr
board = uno
framework = arduinoFull configuration:
[platformio]
default_envs = uno
[env:uno]
platform = atmelavr
board = uno
framework = arduino
upload_port = COM3 # Future: for uploading
monitor_speed = 9600 # Future: for serial monitor
build_flags =
-DDEBUG
-DLED_PIN=13
lib_deps =
https://github.com/FastLED/FastLED
https://github.com/adafruit/Adafruit_NeoPixelFbuild supports downloading and compiling Arduino libraries directly from GitHub URLs:
[env:uno]
platform = atmelavr
board = uno
framework = arduino
lib_deps =
https://github.com/FastLED/FastLEDFeatures:
- Automatic GitHub URL optimization (converts repo URLs to zip downloads)
- Automatic branch detection (main vs master)
- Proper Arduino library structure handling
- LTO (Link-Time Optimization) for optimal code size
- Support for complex libraries with assembly optimizations
Example build with FastLED:
β Build successful!
Firmware: tests/uno/.fbuild/build/uno/firmware.hex
Size: 12KB (4318 bytes program, 3689 bytes RAM)
Build time: 78.59 seconds
Arduino AVR Platform - Fully Supported β
- Arduino Uno (atmega328p, 16MHz) - Fully tested β
ESP32 Platform - Supported β
- ESP32 Dev (esp32dev) - Supported β
- ESP32-C3 (esp32-c3-devkitm-1) - Supported β
- ESP32-C6 (esp32c6-devkit) - Supported β
- ESP32-S3 (esp32-s3-devkitc-1) - Supported β
- ESP32-S2 - Supported β
- ESP32-H2 - Supported β
- ESP32-P4 - Supported β
- ESP32-C2 - Supported β (v0.1.0+)
- Uses skeleton library approach with ROM linker scripts
- Full Arduino framework support
- 220KB firmware size typical
Planned Support:
- Arduino Mega
- Arduino Nano
- Arduino Leonardo
- More AVR boards
- Teensy 3.x/4.x platforms
Benchmarks (Arduino Uno Blink sketch):
| Build Type | Time | Description |
|---|---|---|
| First build | 19.25s | Includes toolchain download (50MB) |
| Full build | 3.06s | All packages cached |
| Incremental | 0.76s | No source changes |
| Clean build | 2.58s | Rebuild from cache |
Firmware Size (Blink):
- Program: 1,058 bytes (3.3% of 32KB flash)
- RAM: 9 bytes (0.4% of 2KB RAM)
Direct URLs and hash-based caching mean you know exactly what you're downloading. No hidden package registries or opaque dependency resolution.
Real downloads with checksum verification ensure consistent, reproducible builds. No mocks in production code.
Optimized incremental builds complete in under 1 second, with intelligent caching for full rebuilds in 2-5 seconds.
100% type-safe (mypy), PEP 8 compliant, and comprehensive test coverage ensure a maintainable and reliable codebase.
Actionable error messages with suggestions help you quickly identify and fix issues without requiring forum searches.
See docs/build-system.md for comprehensive architecture documentation.
See docs/architecture.dot for a Graphviz diagram (render with dot -Tpng).
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CLI LAYER β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β cli.py β β
β β βββ build command βββββββ β β
β β βββ deploy command ββββββΌβββΊ daemon/client.py βββΊ IPC (file-based) βββ β β
β β βββ monitor command βββββ β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β DAEMON LAYER (Background Process) β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β daemon.py (Server) β β
β β βββ lock_manager.py (ResourceLockManager) βββ Memory-based locks only! β β
β β βββ status_manager.py β β
β β βββ process_tracker.py β β
β β βββ device_manager.py βββΊ device_discovery.py β β
β β βββ shared_serial.py β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β βΌ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Request Processors (daemon/processors/) β β
β β βββ build_processor.py βββββββββββββΊ BUILD LAYER β β
β β βββ deploy_processor.py ββββββββββββΊ DEPLOY LAYER β β
β β βββ monitor_processor.py βββββββββββΊ monitor.py β β
β β βββ install_deps_processor.py ββββββΊ PACKAGES LAYER β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββΌβββββββββββββββββββ
βΌ βΌ βΌ
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββββββββββββββββββββββββββββββββββ
β CONFIG LAYER β β PACKAGES LAYER β β BUILD LAYER β
β β β β β β
β βββββββββββββββ β β βββββββββββββββ β β βββββββββββββββββββββββββββββββββββββββββββββββ β
β β ini_parser β β β β cache.py β β β β Platform Orchestrators β β
β β .py β β β β β β β β β orchestrator.py (IBuildOrchestrator) β β
β β (PlatformIO β β β β βΌ β β β β β β β
β β Config) β β β β downloader β β β β βββ orchestrator_avr.py β β
β β β β β β β .py β β β β βββ orchestrator_esp32.py β β
β β βΌ β β β ββββββββ¬βββββββ β β β βββ orchestrator_rp2040.py β β
β βboard_config β β β β β β β βββ orchestrator_stm32.py β β
β β .py β β β βΌ β β β βββ orchestrator_teensy.py β β
β β β β β β βββββββββββββββ β β βββββββββββββββββββββββββββββββββββββββββββββββ β
β β βΌ β β β β Toolchains β β β β β
β βboard_loader β β β β toolchain β β β βΌ β
β β .py β β β β .py (AVR) β β β βββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β β β β toolchain_ β β β β Compilation β β
β β βΌ β β β β esp32.py β β β β source_scanner.py βββΊ compiler.py β β
β β mcu_specs β β β β toolchain_ β β β β β β β
β β .py β β β β rp2040.py β β β β configurable_compiler.py β β β
β βββββββββββββββ β β β ... β β β β β β β β
β β β βββββββββββββββ β β β βΌ βΌ β β
β β β β β β β flag_builder.py βββΊ compilation_executor β β
β β β βΌ β β βββββββββββββββββββββββββββββββββββββββββββββββ β
β β β βββββββββββββββ β β β β
β β β β Frameworks β β β βΌ β
β β β βarduino_core β β β βββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β .py β β β β Linking β β
β β β β framework_ β β β β linker.py βββΊ archive_creator.py β β
β β β β esp32.py β β β β β β β
β β β β ... β β β β βΌ β β
β β β βββββββββββββββ β β β configurable_linker.py β β
β β β β β β β β β β
β β β βΌ β β β βΌ β β
β β β βββββββββββββββ β β β binary_generator.py βββΊ firmware.hex/.bin β β
β β β β Libraries β β β βββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β library_ β β β β
β β β β manager.py β β β build_state.py (BuildStateTracker) β
β β β β β β β βββββββββββββββββββββββββββββββββββββββββββββββββββ
β β β β βΌ β β
β β β β library_ β β
β β β β compiler.py β β
β β β β β β β
β β β β βΌ β β
β β β βgithub_utils β β
β β β βplatformio_ β β
β β β β registry.py β β
β β β βββββββββββββββ β
βββββββββββββββββββ βββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β DEPLOY LAYER β
β β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ β
β β deployer.py β β deployer_esp32 β β monitor.py β β qemu_runner.py β β
β β (IDeployer) β β .py β β (Serial Monitor)β β (Emulator) β β
β β β β β (esptool) β β β β β β
β β βΌ β ββββββββββ¬βββββββββ ββββββββββ¬βββββββββ ββββββββββ¬βββββββββ β
β β [avrdude] β β β β β
β ββββββββββ¬βββββββββ β β β β
β ββββββββββββββββββββββ΄βββββββββββββββββββββ΄βββββββββββββββββββββ β
β β β
β βΌ β
β ββββββββββββββββββββββββββββββββ β
β β External Dependencies β β
β β esptool, avrdude, pyserial β β
β β Docker (QEMU) β β
β ββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β LEDGER LAYER β
β βββββββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββββββ β
β β ledger/board_ledger.py β β daemon/firmware_ledger.py β β
β β (Board tracking) β β (Firmware tracking) β β
β βββββββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Key Data Flows:
- Build Request: CLI β Daemon Client β Daemon Server β Build Processor β Platform Orchestrator β Compiler β Linker β firmware.hex/.bin
- Deploy Request: CLI β Daemon Client β Daemon Server β Deploy Processor β Deployer (esptool/avrdude) β Device
- Package Download: Orchestrator β Cache β Downloader β fingerprint verification β extracted packages
The library management system handles downloading, compiling, and linking Arduino libraries:
-
Library Downloading
- Optimizes GitHub URLs to direct zip downloads
- Detects and uses appropriate branch (main/master)
- Extracts libraries with proper directory structure
-
Library Compilation
- Compiles C/C++ library sources with LTO flags (
-flto -fno-fat-lto-objects) - Resolves include paths for Arduino library structure
- Generates LTO bytecode objects for optimal linking
- Compiles C/C++ library sources with LTO flags (
-
Library Linking
- Passes library object files directly to linker (no archiving)
- LTO-aware linking with
--allow-multiple-definitionfor symbol resolution - Proper handling of weak symbols and ISR handlers
Technical Solutions:
- LTO Bytecode: Generate only LTO bytecode to avoid AVR register limitations during compilation
- Direct Object Linking: Pass object files directly to linker instead of archiving for better LTO integration
- Multiple Definition Handling: Support libraries that define symbols in multiple files (e.g., FastLED ISR handlers)
my-project/
βββ platformio.ini # Configuration file
βββ src/
β βββ main.ino # Your Arduino sketch
β βββ helpers.cpp # Additional C++ files
βββ .fbuild/ # Build artifacts (auto-generated)
βββ cache/
β βββ packages/ # Downloaded toolchains
β βββ extracted/ # Arduino cores
βββ build/
βββ uno/
βββ src/ # Compiled sketch objects
βββ core/ # Compiled Arduino core
βββ firmware.hex # Final output β Upload this!
Fbuild includes comprehensive integration tests:
# Run all tests
pytest tests/
# Run integration tests only
pytest tests/integration/
# Run with verbose output
pytest -v tests/integration/
# Test results: 11/11 passingTest Coverage:
- Full build success path
- Incremental builds
- Clean builds
- Firmware size validation
- HEX format validation
- Error handling (missing config, syntax errors, etc.)
Make sure you're in the project directory or use -d:
fbuild build -d /path/to/projectClear cache and rebuild:
rm -rf .fbuild/cache/
fbuild buildCheck the error message for line numbers:
Error: src/main.ino:5:1: error: expected ';' before '}' token
Common issues:
- Missing semicolon
- Missing closing brace
- Undefined function (missing #include or prototype)
- First build with downloads: 15-30s (expected)
- Cached builds: 2-5s (expected)
- Incremental: <1s (expected)
If slower, check:
- Network speed (for downloads)
- Disk speed (SSD recommended)
- Use
--verboseto see what's slow
See docs/build-system.md for more troubleshooting.
To develop Fbuild, run . ./activate.sh
This environment requires you to use git-bash.
Run ./lint.sh to find linting errors using pylint, flake8 and mypy.
BSD 3-Clause License
