Severity: CRITICAL — every rv32imac CH32V C++ build (V103/V203/V208/V303/V307/X035/L103) fails on Windows. The bench-prep box is Windows.
Problem
get_cxx_system_includes in crates/fbuild-toolchain/src/toolchain/riscv.rs:77-139 builds the C++ -isystem list (the workaround for the known Windows xPack g++ header-resolution breakage) by pushing <ver>/riscv-none-elf/<march>/<mabi>. But xPack riscv-none-elf-gcc 14.2.0-3 has no rv32imac/ilp32 multilib subdirectory — that combination is the toolchain's default multilib (-print-multi-directory → .), whose bits/c++config.h lives at <ver>/riscv-none-elf/ directly. The nonexistent path is silently skipped, so the compile fails.
Until PR #1113, this was masked: the dead-march bug compiled everything as rv32ec_zicsr/ilp32e, and the rv32ec/ilp32e multilib dir does exist. #1113 fixed the ISA selection and thereby exposed this on all rv32imac boards.
Evidence (verified empirically on this machine)
riscv-none-elf-g++ -march=rv32imac_zicsr -mabi=ilp32 <file.cpp> with fbuild's exact -isystem list → bits/c++config.h: No such file or directory.
- Adding
-isystem <ver>/riscv-none-elf → compiles.
riscv-none-elf-gcc -march=rv32imac_zicsr -mabi=ilp32 -print-multi-directory → . (default multilib).
Why CI missed it
All build-ch32*.yml run via template_build.yml on ubuntu-latest only, where GCC resolves its own headers and the -isystem workaround is unnecessary. There is no Windows platform-build lane for CH32V.
Secondary defect (same function)
The multilib-dir heuristic march.split('_').next() is wrong in general: real F-extension multilib dirs keep _zicsr (e.g. rv32imafc_zicsr/ilp32f), so a future hard-float board (see the V30x FPU issue) hits the same silent skip.
Fix direction
Resolve the multilib dir by invoking gcc -march=<m> -mabi=<a> -print-multi-directory and map . → <ver>/riscv-none-elf; or minimally, fall back to pushing <ver>/riscv-none-elf whenever the computed multilib dir does not exist. Prefer the -print-multi-directory approach — it kills the heuristic too.
Acceptance
- On Windows:
soldr cargo run -p fbuild-cli -- build tests/platform/ch32v203 -e ch32v203 succeeds (C++ TUs compile).
tests/platform/ch32v003 still builds (rv32ec path unchanged).
- Consider adding a windows-latest lane to at least one CH32V build workflow so this class of failure is CI-visible.
Found during the 2026-07-21 CH32V bench-readiness sweep.
Severity: CRITICAL — every rv32imac CH32V C++ build (V103/V203/V208/V303/V307/X035/L103) fails on Windows. The bench-prep box is Windows.
Problem
get_cxx_system_includesincrates/fbuild-toolchain/src/toolchain/riscv.rs:77-139builds the C++-isystemlist (the workaround for the known Windows xPack g++ header-resolution breakage) by pushing<ver>/riscv-none-elf/<march>/<mabi>. But xPack riscv-none-elf-gcc 14.2.0-3 has norv32imac/ilp32multilib subdirectory — that combination is the toolchain's default multilib (-print-multi-directory→.), whosebits/c++config.hlives at<ver>/riscv-none-elf/directly. The nonexistent path is silently skipped, so the compile fails.Until PR #1113, this was masked: the dead-march bug compiled everything as
rv32ec_zicsr/ilp32e, and therv32ec/ilp32emultilib dir does exist. #1113 fixed the ISA selection and thereby exposed this on all rv32imac boards.Evidence (verified empirically on this machine)
riscv-none-elf-g++ -march=rv32imac_zicsr -mabi=ilp32 <file.cpp>with fbuild's exact-isystemlist →bits/c++config.h: No such file or directory.-isystem <ver>/riscv-none-elf→ compiles.riscv-none-elf-gcc -march=rv32imac_zicsr -mabi=ilp32 -print-multi-directory→.(default multilib).Why CI missed it
All
build-ch32*.ymlrun viatemplate_build.ymlon ubuntu-latest only, where GCC resolves its own headers and the-isystemworkaround is unnecessary. There is no Windows platform-build lane for CH32V.Secondary defect (same function)
The multilib-dir heuristic
march.split('_').next()is wrong in general: real F-extension multilib dirs keep_zicsr(e.g.rv32imafc_zicsr/ilp32f), so a future hard-float board (see the V30x FPU issue) hits the same silent skip.Fix direction
Resolve the multilib dir by invoking
gcc -march=<m> -mabi=<a> -print-multi-directoryand map.→<ver>/riscv-none-elf; or minimally, fall back to pushing<ver>/riscv-none-elfwhenever the computed multilib dir does not exist. Prefer the-print-multi-directoryapproach — it kills the heuristic too.Acceptance
soldr cargo run -p fbuild-cli -- build tests/platform/ch32v203 -e ch32v203succeeds (C++ TUs compile).tests/platform/ch32v003still builds (rv32ec path unchanged).Found during the 2026-07-21 CH32V bench-readiness sweep.