33export module mcpp.toolchain.registry;
44
55import std;
6+ import mcpp.platform;
67import mcpp.toolchain.clang;
78import mcpp.toolchain.gcc;
89import mcpp.toolchain.llvm;
@@ -101,6 +102,7 @@ std::vector<std::string> frontend_candidates_for(std::string_view ximName,
101102 if (ximName == " gcc" ) return {" g++" };
102103 if (ximName == " llvm" ) return mcpp::toolchain::llvm::frontend_candidates ();
103104 if (ximName == " msvc" ) return {" cl.exe" };
105+ if (ximName == " mingw-gcc" ) return {" g++.exe" , " g++" };
104106 return {" g++" , " clang++" , " x86_64-linux-musl-g++" , " cl.exe" };
105107}
106108
@@ -170,6 +172,10 @@ XimToolchainPackage to_xim_package(const ToolchainSpec& spec) {
170172 std::string ximCompiler = spec.compiler ;
171173 if (mcpp::toolchain::llvm::is_alias (ximCompiler))
172174 ximCompiler = mcpp::toolchain::llvm::package_name ();
175+ // Windows-native MinGW-w64 GCC: user-facing name `mingw`, xim package
176+ // `mingw-gcc` (winlibs GCC+MinGW-w64 UCRT builds mirrored at xlings-res).
177+ if (ximCompiler == " mingw" )
178+ ximCompiler = " mingw-gcc" ;
173179
174180 pkg.ximName = ximCompiler;
175181 pkg.ximVersion = spec.version ;
@@ -221,6 +227,8 @@ std::filesystem::path toolchain_frontend(const std::filesystem::path& binDir,
221227std::string display_label (std::string_view compiler, std::string_view version) {
222228 if (compiler == " musl-gcc" )
223229 return std::format (" gcc {}-musl" , version);
230+ if (compiler == " mingw-gcc" )
231+ return std::format (" mingw {}" , version);
224232 return std::format (" {} {}" , compiler, version);
225233}
226234
@@ -235,6 +243,12 @@ bool matches_default_toolchain(std::string_view configuredDefault,
235243 // The persisted msvc default is always the stable "msvc@system" (never a
236244 // concrete version), so it matches whatever version detection reports.
237245 if (compiler == " msvc" && configuredDefault == " msvc@system" ) return true ;
246+ // Installed-payload rows report the xim name (mingw-gcc); the user-facing
247+ // spec is mingw@<ver> (same shape as the musl-gcc clause above).
248+ if (compiler == " mingw-gcc"
249+ && configuredDefault == std::format (" mingw@{}" , version)) {
250+ return true ;
251+ }
238252 return false ;
239253}
240254
@@ -243,11 +257,15 @@ bool is_system_toolchain(const ToolchainSpec& spec) {
243257}
244258
245259std::vector<std::pair<std::string, std::string>> available_toolchain_indexes () {
246- return {
260+ std::vector<std::pair<std::string, std::string>> out {
247261 {" gcc" , " gcc" },
248262 {" musl-gcc" , " musl-gcc" },
249263 {mcpp::toolchain::llvm::package_name (), " llvm" },
250264 };
265+ // Windows-native toolchain — only meaningful to list on Windows hosts.
266+ if constexpr (mcpp::platform::is_windows)
267+ out.emplace_back (" mingw-gcc" , " mingw-gcc" );
268+ return out;
251269}
252270
253271std::filesystem::path derive_c_compiler (const Toolchain& tc) {
@@ -257,6 +275,15 @@ std::filesystem::path derive_c_compiler(const Toolchain& tc) {
257275std::filesystem::path archive_tool (const Toolchain& tc) {
258276 if (is_clang (tc)) return mcpp::toolchain::clang::archive_tool (tc);
259277
278+ // MinGW bundles its own binutils next to the frontend (self-contained,
279+ // like musl) — never an external binutils xpkg.
280+ if (is_mingw_target (tc)) {
281+ auto ar = tc.binaryPath .parent_path () / " ar.exe" ;
282+ std::error_code ec;
283+ if (std::filesystem::exists (ar, ec)) return ar;
284+ return {};
285+ }
286+
260287 if (!is_musl_target (tc)) {
261288 if (auto binutilsBin = mcpp::toolchain::gcc::find_binutils_bin (tc.binaryPath ))
262289 return *binutilsBin / " ar" ;
0 commit comments