gcc 15.0.2+mingw 13.0.0 libstdc++-v3 build error

Summary

When bootstrapping a GCC 15.0.2 toolchain targeting x86_64-w64-mingw32, the build of libstdc++-v3 fails with a cascade of warnings interpreted as errors. The root cause is that the C++ compiler frontend (cc1plus.exe) is inadvertently invoking the C frontend (cc1.exe). This is caused by a corrupted gcc driver configuration, likely due to missing or invalid specs files, causing the driver to misidentify the source language and pass incorrect flags (like -nostdinc++ and -std=gnu++98) to the compiler.

Root Cause

The failure originates from a broken GCC driver configuration for the C++ language on the Windows host. Specifically:

  • Compiler Misidentification: The gcc executable, when processing a .cpp file, fails to correctly spawn the cc1plus frontend with the proper environment. Instead, it appears to be executing the C frontend (cc1.exe) or a corrupted cc1plus.exe instance that believes it is operating in a C context.
  • Invalid Flag Passing: Because the frontend is confused about its target language, it validates standard flags (like -nostdinc++ and -std=gnu++98) against C language rules. Since these flags are C++ specific, they trigger warnings. The build system treats these warnings as errors (-Werror=), halting the process.
  • Missing Specs: The gcc driver relies on specs files to map source file extensions and flags to the correct internal executables and arguments. If these are missing or generated incorrectly during the initial make install-gcc step, the driver defaults to behavior that breaks C++ compilation.

Why This Happens in Real Systems

This scenario is common in cross-compilation bootstrapping, particularly on Windows where path handling and executable suffixes (.exe) complicate the build process.

  • Incomplete Build Stages: The user performed make all-gcc && make install-gcc followed by CRT installation, then attempted to build the rest of GCC (make inside the gcc build folder). This sequence can be fragile. If the initial installation doesn’t populate the libexec/gcc/<target>/<version> directory with the necessary cc1plus.exe and correct specs files, the later stage cannot link properly.
  • Host vs. Target Confusion: The build is being performed on MinGW for MinGW. If the host compiler’s own libraries or headers are picked up accidentally (due to wrong sysroot settings or missing specs), it pollutes the build environment for the target compiler.
  • Strict Build Flags: Enabling --enable-stage1-checking=all and -Werror makes the build extremely sensitive to internal inconsistencies that might otherwise be invisible warnings.

Real-World Impact

  • Build Halting: The compilation of libstdc++-v3 stops immediately. This prevents the creation of the C++ standard library, rendering the toolchain useless for C++ development.
  • Toolchain Corruption: A toolchain installed in this state is incomplete. Even if you bypass the error, the resulting C++ compiler will likely produce incorrect binaries or fail to link against standard libraries.
  • Debugging Difficulty: The error messages point to source code pragmas and standard flags (e.g., #pragma GCC diagnostic ignored "-Wc++11-extensions"), misleading developers into thinking the source code is incompatible with the compiler version, rather than the compiler driver itself being broken.

Example or Code

The error log provided in the prompt is the primary evidence. No specific code is required to reproduce the issue, as it is an environment configuration failure.

// A file similar to what libstdc++ uses internally that triggers the error
// However, the error is NOT in this code. It is in the compiler driver.
#pragma GCC diagnostic ignored "-Wc++11-extensions"

// The compiler complains that the flag passed to the pragma is invalid
// because the compiler instance running thinks it is a C compiler, not C++.

How Senior Engineers Fix It

To resolve this, one must ensure the GCC driver is fully configured to recognize C++ targets and that the necessary frontend binaries are present.

  1. Verify Installation Paths: Ensure that <my-prefix>/libexec/gcc/x86_64-w64-mingw32/15.0.2/ contains cc1plus.exe. If it is missing, the make install-gcc step failed or was incomplete.

  2. Re-generate Specs: Explicitly generate the specs file to ensure the driver knows how to handle C++.

    # Navigate to the gcc build directory
    # Ensure the installed compiler is in the path or use the one just built
    ./gcc/xgcc -B ./gcc/ -v
    
    # Or reinstall gcc ensuring specs are built
    make install-gcc
  3. Clean Build Environment: The safest fix for bootstrapping issues is a clean rebuild of the GCC toolchain components, ensuring dependencies are met in order:

    • Binutils
    • Mingw Headers
    • Mingw CRT
    • GCC (Full build, not just all-gcc)
  4. Adjust configure Flags: Remove --enable-stage1-checking=all temporarily to reduce noise while debugging the build configuration. Ensure --enable-languages=c,c++ is set (though default, explicit is safer).

Why Juniors Miss It

Junior engineers often misinterpret the error messages and focus on the wrong component:

  • Symptom Confusion: They see “warning: argument is not valid for C++” and immediately look at the source code or the Makefile logic, assuming the project is using the wrong flags.
  • Lack of Bootstrapping Context: They may not understand that a compiler is a program that compiles itself. They assume the gcc binary is a monolithic black box and don’t check if the driver (gcc) is correctly invoking the internal frontend (cc1plus).
  • Ignoring Precedence: They don’t verify that the binutils and mingw-crt steps were truly successful and compatible with the GCC version being used. If mingw-crt is slightly mismatched, it can cause subtle header corruptions that manifest later in the build.