Repository navigation
Description
Title: platformio.ini advanced build configurations are not yet compatible with PlatformIO/SCons flag workflows
Summary
fbuild advertises compatibility with platformio.ini, but today that compatibility is mostly limited to flat config values like build_flags / build_src_flags and environment inheritance. Standard PlatformIO patterns for advanced build configurations are not modeled yet, so a project that uses normal PlatformIO debug/custom build techniques can silently build with different semantics under fbuild.
What this means in practice
A lot of PlatformIO projects define advanced build flavors by combining:
build_type = debug|release|testdebug_build_flagsbuild_unflagsextra_scriptsthat mutate SCons construction variables such asCPPDEFINES,CCFLAGS,CXXFLAGS,LINKFLAGS, orCPPPATH
That is the standard PlatformIO/SCons workflow for �advanced build types�: the INI selects the build flavor, and either declarative keys or SCons script hooks add/remove the actual compiler/linker flags.
Right now fbuild does not appear to implement that model. It reads ordinary build_flags / build_src_flags, has its own internal BuildProfile abstraction (release vs quick), and supports one-off caller-injected flags, but it does not map the PlatformIO build-type layer onto those internal profiles.
Repo evidence
PlatformIOConfig::get_build_flags()only readsbuild_flags, andget_build_src_flags()only readsbuild_src_flags:crates/fbuild-config/src/ini_parser.rs:123-143BuildContext::new()only collectsbuild_flagsandbuild_src_flagsbefore build orchestration:crates/fbuild-build/src/pipeline.rs:106-111- Build orchestration has an internal profile system (
release,quick) rather than aplatformio.ini-drivenbuild_typemodel:crates/fbuild-build/src/compiler.rs:24-29,crates/fbuild-build/src/lib.rs:138-166 PLATFORMIO_BUILD_UNFLAGSis listed as a supported env override and has an accessor, but I could not find any point where it is applied to the effective flag set:crates/fbuild-config/src/pio_env.rs:15-21,crates/fbuild-config/src/pio_env.rs:111-121PLATFORMIO_EXTRA_SCRIPTSis explicitly recognized as warn-only / no-op today:crates/fbuild-config/src/pio_env.rs:43-59- I could not find any repo references to
build_typeordebug_build_flags
Expected behavior
At minimum, fbuild should not silently accept a platformio.ini that depends on PlatformIO advanced build-type mechanics while producing a materially different build.
Preferred direction:
- Parse and honor
build_type,debug_build_flags, andbuild_unflagsfromplatformio.ini - Define a compatibility mapping from PlatformIO build types to fbuild build profiles, including a real debug-oriented path rather than only
release/quick - Apply
build_unflagsagainst framework/toolchain/default/user flags in the same stage where the final effective flag set is assembled - Detect
extra_scripts/ SCons flag mutation patterns and either:- support a constrained compatibility subset, or
- fail fast with a clear diagnostic that advanced scripting is not yet supported
- Add tests with representative fixtures for:
- a plain
build_type = debugenvironment - a
build_unflagsoverride (for example removing a default-std=or warning flag) - a project that depends on
extra_scriptsto mutateCPPDEFINES/CCFLAGS/LINKFLAGS
- a plain
Why this matters
Without this, �compatible with platformio.ini� is true for basic environments but not for a common class of real-world PlatformIO projects. Those projects often rely on advanced build types specifically to control optimization/debug info, remove framework defaults, or inject profile-specific compile/link behavior. If fbuild ignores that layer, migration can succeed syntactically while diverging semantically.
PlatformIO references
- Build configurations (
build_type,debug_build_flags): https://docs.platformio.org/en/stable/projectconf/build_configurations.html build_flagsSCons scopes and dynamic flags: https://docs.platformio.org/en/stable/projectconf/sections/env/options/build/build_flags.htmlSection [env]includesbuild_type,build_flags,build_src_flags,build_unflags,build_src_filter: https://docs.platformio.org/en/latest/projectconf/sections/env/index.html- Construction environments /
extra_scriptsmutatingenvandprojenv: https://docs.platformio.org/en/latest/scripting/construction_environments.html
Activity
zackees commentedon Apr 13, 2026
Investigation split into child issues:
platformio.inibuild_type=debuganddebug_build_flagsbuild_unflagsto the effective native flag scopesextra_scriptsenv/projenvmutations__idedata/ project metadata can support a scripted-project bridgeCurrent read from the research:
build_type=debug,debug_build_flags,build_unflags) look like a good fit for native compatibility work.extra_scriptsis the real boundary. Once arbitrary Python mutates SCons environments, full parity likely means either a very constrained shim or explicit fallback to--platformio.That points toward option (2) unless the spike in #39 turns up something unexpectedly stronger.
zackees commentedon Apr 13, 2026
Additional child issue from deeper investigation: #40 tracks the mismatch between declared-supported PLATFORMIO_* overrides and the config getters that actually consume them.
zackees commentedon Apr 13, 2026
Added #41 for the concrete runtime-bridge experiment: execute PlatformIO/SCons just far enough to dump resolved build state, then feed that into native fbuild.
zackees commentedon Apr 13, 2026
Runtime-bridge analysis
I think the promising path is not a parser, but a runtime bridge:
Why this looks feasible
.cache/platformio-core/platformio/builder/main.py:167-180,.cache/platformio-core/platformio/builder/main.py:214-227envandprojenv, which is exactly the point where project-vs-global flag mutations have settled: https://docs.platformio.org/en/latest/scripting/construction_environments.htmlbuild_type, defines, includes,cc_flags,cxx_flags, tool paths, targets, flash image metadata):.cache/platformio-core/platformio/builder/tools/piointegration.py:141-173build_unflagsin a well-defined order:.cache/platformio-core/platformio/builder/tools/piobuild.py:94-128What this should NOT be
__idedataas-is, because some scripts may branch on integration/service stages and that dump is editor-oriented, not build-replay-orientedWhat the prototype should dump
envscopes:CPPDEFINES,CPPPATH,CCFLAGS,CFLAGS,CXXFLAGS,ASFLAGS,LINKFLAGS,LIBPATH,LIBSprojenvscopes separatelyCC,CXX,AR, linker, objcopy, gdb when present)BUILD_TYPE, linker script info, flash image metadataPIOBUILDFILESand related nodes if available)Decision impact
--platformiofallback for scripted projects.That makes #41 the key experiment before deciding whether the long-term answer is a stronger version of option (2) or a real option (3).
zackees commentedon Apr 13, 2026
PR #42 is up with the native extra_scripts runtime bridge implementation. It covers the constrained runtime path for common env / projenv flag mutations, applies the resulting overlay to compile/link phases, and fails fast on unsupported scripted behavior instead of silently drifting.
zackees commentedon Apr 13, 2026
Merged in PR #42: the implementation follows the expanded
(2)path discussed here. fbuild now has a constrainedextra_scriptsruntime bridge that executes simple PlatformIO-style script mutations, captures the resulting compile/link overlays, applies them to the native build, and fails fast for unsupported dynamic behavior instead of silently drifting. This keeps native builds compatible with common SCons flag workflows without committing the project to full SCons re-hosting.Key boundary: supported script behavior is limited to straightforward flag/path/library mutations on common scopes (
CPPDEFINES,CPPPATH,CCFLAGS,CFLAGS,CXXFLAGS,ASFLAGS,LINKFLAGS,LIBPATH,LIBS) plusenv/ post-projenvaccess. More dynamic script behavior should still fall back to--platformio.zackees commentedon Apr 17, 2026
Status — closing umbrella; remaining scope is independently tracked
The original five asks in this issue are mostly delivered. The remaining surface lives in the two independent child issues #38 and #39, each actionable on its own without needing this umbrella to coordinate them.
Delivered
build_type,debug_build_flags,build_unflagsfromplatformio.ini— ✅ done incrates/fbuild-build/src/pipeline.rs(BuildContext::newreads all three;build_type = debugtriggersapply_debug_build_type;build_unflagsis applied across user / src / overlay link scopes)apply_debug_build_type;releasefalls back to the existingBuildProfile::Release. A future full mapping (includingtest) can be filed separately if needed.build_unflagsagainst framework/toolchain/user flag sets — ✅ closed by Apply PlatformIO build_unflags to the effective native flag scopes #37 (PRs feat(build): apply build_unflags to framework compile flags, ESP32 wired (#37) #63 and feat(build): wire build_unflags through all remaining platform compilers (#37) #64, across all platforms)extra_scriptsand handle them — ✅ partially done (script_runtime::resolve_extra_script_overlayincrates/fbuild-build/src/script_runtime.rsruns scripts via a Python harness); the remaining design work on what script patterns to support is tracked in Define native support boundaries for PlatformIO extra_scripts env/projenv mutations #38crates/fbuild-build/src/pipeline.rsandcrates/fbuild-config/src/ini_parser.rscoverbuild_type,debug_build_flags,build_unflags;extra_scriptscases covered inscript_runtime.rstestsRemaining active scope
extra_scriptsenv/projenv mutations (what to support, what to reject, how to diagnose)__idedata/ project metadata can back a scripted-project bridgeBoth are independent and actionable without needing this umbrella as a coordination point. Closing.