Version: 2.5.21 (pip), Windows 11. Consumer is a FastAPI build helper that drives a
generated platformio.ini scaffold, one [env:*] per supported board.
Summary
Both PlatformIO spellings of "pin this platform to a version" are accepted without
complaint and then dropped:
[env:esp32]
platform = espressif32@6.5.0 ; version discarded
board = esp32dev
framework = arduino
platform_packages = platform-espressif32@6.5.0 ; entry discarded
The build succeeds and uses the const-pinned default platform. Nothing in the output
says the pin had no effect, so the sketch that comes out is not the one the ini asked
for and there is no signal to say so.
Where it happens
The platform key. Platform::from_platform_str
(crates/fbuild-core/src/lib.rs:150) lowercases the whole value and substring-matches
it:
} else if s.contains("espressif32") {
Some(Self::Espressif32)
espressif32@6.5.0 contains espressif32, so it resolves to Espressif32 and
everything after the @ is gone. Every caller reaches the platform through this
function, so the version has nowhere else to be read.
The platform_packages key. parse_platform_packages_entry
(crates/fbuild-config/src/platform_packages.rs:90) documents and implements the same
outcome deliberately:
// Plain `name @ <version>` (no URL, no slash, no `#sha`) is a registry
// version pin, not an override we can act on.
That reasoning is sound — there is no registry resolver to hand it to. The issue is
that it returns None silently, which is indistinguishable from "no override was
requested".
There is warning machinery for exactly this shape of problem in
crates/fbuild-config/src/pio_env.rs ("unsupported and ignored" / "recognized but
no-op"), but it covers PLATFORMIO_* environment variables only, not ini keys.
Why it matters to us
Pinning the ESP32 Arduino core is the fix for a real hardware problem: IDF 5 removed
I2S LCD mode, the new and legacy I2S drivers cannot coexist, and core 2.0.17 is the last
version that works for the audio path we generate. When the pin is silently ignored, the
resulting failure appears on the bench as an audio fault, and the ini says the opposite
of what was built. A pin that quietly does nothing costs more debugging time than a pin
that is refused outright.
What does work, and is worth documenting
The URL forms of platform_packages are honoured for ESP32 —
resolve_pioarduino_packages
(crates/fbuild-build-esp/src/esp32/orchestrator/packages.rs) resolves overrides for
both platform-espressif32 and framework-arduinoespressif32, per #672:
platform_packages =
platform-espressif32@https://github.com/pioarduino/platform-espressif32/archive/<sha>.tar.gz
That is a genuinely good escape hatch and it solved our problem once we found it. It is
not obvious from the outside that the URL form works while the version form does not.
Possible resolutions, cheapest first
- Warn and continue. When a
platform value carries an @<version> suffix, or a
platform_packages entry is a bare version pin, say so on stderr and name the
version actually used. This alone removes the failure mode: the pin still does
nothing, but nobody is misled about it.
- Point at the escape hatch in that warning — one line naming the URL form.
- Honour registry version pins, which needs a registry resolver and is a feature
rather than a fix. Only worth it if that resolver is wanted for other reasons.
We would take (1) happily; the silence is the whole problem, not the missing feature.
Offer
We build on Windows 11 against ESP32-S3, classic ESP32 and ESP8266 daily and are glad to
test a branch on any of them.
Version: 2.5.21 (pip), Windows 11. Consumer is a FastAPI build helper that drives a
generated
platformio.iniscaffold, one[env:*]per supported board.Summary
Both PlatformIO spellings of "pin this platform to a version" are accepted without
complaint and then dropped:
The build succeeds and uses the const-pinned default platform. Nothing in the output
says the pin had no effect, so the sketch that comes out is not the one the ini asked
for and there is no signal to say so.
Where it happens
The
platformkey.Platform::from_platform_str(
crates/fbuild-core/src/lib.rs:150) lowercases the whole value and substring-matchesit:
espressif32@6.5.0containsespressif32, so it resolves toEspressif32andeverything after the
@is gone. Every caller reaches the platform through thisfunction, so the version has nowhere else to be read.
The
platform_packageskey.parse_platform_packages_entry(
crates/fbuild-config/src/platform_packages.rs:90) documents and implements the sameoutcome deliberately:
That reasoning is sound — there is no registry resolver to hand it to. The issue is
that it returns
Nonesilently, which is indistinguishable from "no override wasrequested".
There is warning machinery for exactly this shape of problem in
crates/fbuild-config/src/pio_env.rs("unsupported and ignored" / "recognized butno-op"), but it covers
PLATFORMIO_*environment variables only, not ini keys.Why it matters to us
Pinning the ESP32 Arduino core is the fix for a real hardware problem: IDF 5 removed
I2S LCD mode, the new and legacy I2S drivers cannot coexist, and core 2.0.17 is the last
version that works for the audio path we generate. When the pin is silently ignored, the
resulting failure appears on the bench as an audio fault, and the ini says the opposite
of what was built. A pin that quietly does nothing costs more debugging time than a pin
that is refused outright.
What does work, and is worth documenting
The URL forms of
platform_packagesare honoured for ESP32 —resolve_pioarduino_packages(
crates/fbuild-build-esp/src/esp32/orchestrator/packages.rs) resolves overrides forboth
platform-espressif32andframework-arduinoespressif32, per #672:platform_packages = platform-espressif32@https://github.com/pioarduino/platform-espressif32/archive/<sha>.tar.gzThat is a genuinely good escape hatch and it solved our problem once we found it. It is
not obvious from the outside that the URL form works while the version form does not.
Possible resolutions, cheapest first
platformvalue carries an@<version>suffix, or aplatform_packagesentry is a bare version pin, say so on stderr and name theversion actually used. This alone removes the failure mode: the pin still does
nothing, but nobody is misled about it.
rather than a fix. Only worth it if that resolver is wanted for other reasons.
We would take (1) happily; the silence is the whole problem, not the missing feature.
Offer
We build on Windows 11 against ESP32-S3, classic ESP32 and ESP8266 daily and are glad to
test a branch on any of them.