You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#1268 (0dd68b24) fixed the teensy linker running in the fbuild daemon's inherited cwd — normally the user's project root — which made arm-none-eabi-gcc/collect2/lto-wrapper drop scratch files there. The user-visible symptom was a stray 0-byte file literally named -r appearing in the repo root after every clean build (downstream report: FastLED/FastLED#3867).
Two things remain: the same bug is still latent in every other ARM linker, and the fix is not in any release.
Part 1 — apply the same fix to the remaining ARM linkers
All of these pass None as the cwd to run_command in exactly the shape teensy did, so any linker-spawned helper writes scratch files into whatever cwd the daemon inherited:
I deliberately scoped #1268 to teensy because that is the only one I could reproduce and verify on the hardware I had. These are very likely to have the identical problem, but each needs checking rather than a blind sed.
Pattern to follow
link_cwd_for in crates/fbuild-build-arm/src/teensy/teensy_linker.rs is reusable as-is — consider lifting it to a shared spot (e.g. crates/fbuild-build-arm/src/linker.rs) rather than copying it six times:
Do not set the cwd unless every argument is absolute. The is_absolute() guard exists because moving cwd also relocates a relative -o. For teensy this was safe: -o is output_dir.join(...), objects/archives arrive absolute, and -T<script> resolves through absolute -L search paths. Verify that per linker — some may pass a relative linker script or output path, in which case they need the arguments absolutized first, or left alone.
arduino_mbed.rs:289 also passes None for env (not just cwd), so it may be a different kind of call — check what it actually spawns before changing it.
Part 2 — cut a release
main is 2 commits ahead of the newest tag, and both are fixes people are currently blocked on:
$ git log --oneline v2.5.14..main
0dd68b24 fix(teensy): run the link in the build dir, not the inherited cwd (#1268)
2976d863 fix(rp): honor Arduino Bluetooth menu (#1263)
Newest tag: v2.5.14. Newest PyPI release: 2.5.14 (published 2026-08-06 05:08:05Z, i.e. before both commits).
Consumers pin fbuild by exact version, so an unreleased fix is an unusable fix:
2976d863 blocks chore(rp2350w): hand off final #3832 hardware validation FastLED#3864 entirely. Without it board_build.ipbtstack = ipv4btcble is ignored, libipv4.a is linked instead of libipv4-bt.a, and the RP2350W build dies at _needsbt.h's static_assert(ENABLE_CLASSIC, ...). All five RP2350W HIL flows are blocked on this, and the FastLED issue currently reads "validated with the local fbuild development executable" — a path that is not reproducible from a clean checkout.
0dd68b24 is what stops bash compile dirtying a clean tree.
Please tag and publish v2.5.15 (or later) containing both. FastLED then bumps its fbuild== pin.
Verification — read this before testing
This bug is intermittent and produces false negatives very easily. Two traps I fell into:
A repeat build is a silent no-op and looks like "fixed". Force real work (-c, or switch examples) and confirm the elapsed build time in the output. A "clean" result from a 2-second rebuild proves nothing.
I concluded zccache-fp on PATH was the trigger from one positive and two negatives. It was pure coincidence. Don't infer causation from a handful of runs here.
Reproduction that does work:
cd /some/empty/dir
rm -f -- ./-r
fbuild.exe "<project-dir>" build -e <env> -c # must show real elapsed time
ls -la -- ./-r # before the fix: 0-byte stray
After the fix the invocation dir stays clean and the stray appears under the gitignored build tree instead. Compare artifact sizes before/after to confirm nothing functional changed — teensy41 was byte-identical (flash 72704, RAM 81984).
Note the file name's leading dash: clean up with rm -- ./-r, never plain rm -r.
Acceptance criteria
Each ARM linker above either runs the link in its (absolute) output dir, or has a comment recording why it must keep the inherited cwd.
link_cwd_for lives in one place rather than being duplicated per linker.
A clean build for at least one non-teensy ARM target leaves the invocation directory unchanged, verified with elapsed build time shown.
soldr cargo test -p fbuild-build-arm --lib passes.
A release ≥ v2.5.15 is tagged and on PyPI containing 0dd68b24 and 2976d863.
Context
#1268 (
0dd68b24) fixed the teensy linker running in the fbuild daemon's inherited cwd — normally the user's project root — which madearm-none-eabi-gcc/collect2/lto-wrapper drop scratch files there. The user-visible symptom was a stray 0-byte file literally named-rappearing in the repo root after every clean build (downstream report: FastLED/FastLED#3867).Two things remain: the same bug is still latent in every other ARM linker, and the fix is not in any release.
Part 1 — apply the same fix to the remaining ARM linkers
All of these pass
Noneas the cwd torun_commandin exactly the shape teensy did, so any linker-spawned helper writes scratch files into whatever cwd the daemon inherited:crates/fbuild-build-arm/src/generic_arm/arm_linker.rscrates/fbuild-build-arm/src/nrf52/nrf52_linker.rscrates/fbuild-build-arm/src/renesas/renesas_linker.rscrates/fbuild-build-arm/src/sam/sam_linker.rscrates/fbuild-build-arm/src/silabs/silabs_linker.rscrates/fbuild-build-arm/src/stm32/orchestrator/arduino_mbed.rsI deliberately scoped #1268 to teensy because that is the only one I could reproduce and verify on the hardware I had. These are very likely to have the identical problem, but each needs checking rather than a blind sed.
Pattern to follow
link_cwd_forincrates/fbuild-build-arm/src/teensy/teensy_linker.rsis reusable as-is — consider lifting it to a shared spot (e.g.crates/fbuild-build-arm/src/linker.rs) rather than copying it six times:The one real hazard
Do not set the cwd unless every argument is absolute. The
is_absolute()guard exists because moving cwd also relocates a relative-o. For teensy this was safe:-oisoutput_dir.join(...), objects/archives arrive absolute, and-T<script>resolves through absolute-Lsearch paths. Verify that per linker — some may pass a relative linker script or output path, in which case they need the arguments absolutized first, or left alone.arduino_mbed.rs:289also passesNonefor env (not just cwd), so it may be a different kind of call — check what it actually spawns before changing it.Part 2 — cut a release
mainis 2 commits ahead of the newest tag, and both are fixes people are currently blocked on:Newest tag:
v2.5.14. Newest PyPI release:2.5.14(published 2026-08-06 05:08:05Z, i.e. before both commits).Consumers pin fbuild by exact version, so an unreleased fix is an unusable fix:
2976d863blocks chore(rp2350w): hand off final #3832 hardware validation FastLED#3864 entirely. Without itboard_build.ipbtstack = ipv4btcbleis ignored,libipv4.ais linked instead oflibipv4-bt.a, and the RP2350W build dies at_needsbt.h'sstatic_assert(ENABLE_CLASSIC, ...). All five RP2350W HIL flows are blocked on this, and the FastLED issue currently reads "validated with the local fbuild development executable" — a path that is not reproducible from a clean checkout.0dd68b24is what stopsbash compiledirtying a clean tree.Please tag and publish
v2.5.15(or later) containing both. FastLED then bumps itsfbuild==pin.Verification — read this before testing
This bug is intermittent and produces false negatives very easily. Two traps I fell into:
-c, or switch examples) and confirm the elapsed build time in the output. A "clean" result from a 2-second rebuild proves nothing.zccache-fponPATHwas the trigger from one positive and two negatives. It was pure coincidence. Don't infer causation from a handful of runs here.Reproduction that does work:
After the fix the invocation dir stays clean and the stray appears under the gitignored build tree instead. Compare artifact sizes before/after to confirm nothing functional changed — teensy41 was byte-identical (flash 72704, RAM 81984).
Note the file name's leading dash: clean up with
rm -- ./-r, never plainrm -r.Acceptance criteria
link_cwd_forlives in one place rather than being duplicated per linker.soldr cargo test -p fbuild-build-arm --libpasses.v2.5.15is tagged and on PyPI containing0dd68b24and2976d863.Related
-rin the CWD when zccache-fp is on PATH #1267, teensy41 on Windows host: GCC LTO temp-file 'mv' strips backslashes from C:\ paths #261-rin the repo root FastLED#3867, chore(rp2350w): hand off final #3832 hardware validation FastLED#3864, feat(rp2350w): complete pin-free AutoResearch and ESP32-C6 peer-network bring-up FastLED#3832