Skip to content

fix(toolchain): riscv g++ -isystem set misses the default multilib dir - rv32imac CH32V C++ builds fail on Windows #1118

Description

@zackees

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions