From 0eb5c44e2ddb51f58ae76aadf823bacba51078f5 Mon Sep 17 00:00:00 2001 From: Damian Höster Date: Fri, 21 Aug 2026 23:49:41 +0200 Subject: Improve MinGW toolchain support for Clang and libc++ This patch primarily enables support for LLVM libc++ runtimes (c++_static, c++_shared) in the mingw toolchain, and updates C++20 module rules so that `import std;` resolves to LLVM libc++ instead of hardcoded GNU libstdc++ when using Clang on MinGW (llvm-mingw), which caused build failures before. Also, configuring for MinGW on Linux or macOS without a cross-compiler present would previously result in fallback to host-native /usr/bin/gcc. Now unprefixed fallback is only used on Windows/MSYS2/Cygwin hosts. The toolchain check now also automatically selects clang when pointing at llvm-mingw or a clang-only installation, avoiding the need to manually pass clang = true. --- xmake/modules/detect/sdks/find_mingw.lua | 3 ++- xmake/rules/c++/modules/support.lua | 10 +++++++++- xmake/toolchains/mingw/check.lua | 18 ++++++++++++++++++ xmake/toolchains/mingw/xmake.lua | 2 +- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/xmake/modules/detect/sdks/find_mingw.lua b/xmake/modules/detect/sdks/find_mingw.lua index c70bebb11..d6d7e0d8e 100644 --- a/xmake/modules/detect/sdks/find_mingw.lua +++ b/xmake/modules/detect/sdks/find_mingw.lua @@ -108,7 +108,8 @@ function _find_mingw(sdkdir, opt) -- find cross toolchain local toolchain = find_cross_toolchain(sdkdir or bindir, {bindir = bindir, cross = cross}) - if not toolchain then -- fallback, e.g. gcc.exe without cross + -- fallback, e.g. gcc.exe without cross + if not toolchain and (is_host("windows") or is_subhost("msys", "cygwin")) then toolchain = find_cross_toolchain(sdkdir or bindir, {bindir = bindir}) end if toolchain then diff --git a/xmake/rules/c++/modules/support.lua b/xmake/rules/c++/modules/support.lua index 126e25c61..38df28a05 100644 --- a/xmake/rules/c++/modules/support.lua +++ b/xmake/rules/c++/modules/support.lua @@ -92,7 +92,15 @@ function get_cpplibrary_name(target) end elseif target:is_plat("macosx", "iphoneos", "watchos", "appletvos", "applexros", "bsd", "harmony") then return "c++" - elseif target:is_plat("linux", "mingw", "cygwin", "msys", "haiku") then + elseif target:is_plat("linux", "cygwin", "msys", "haiku") then + return "stdc++" + elseif target:is_plat("mingw") then + local toolchain_inst = target:toolchain("mingw") + local is_clang = (toolchain_inst and toolchain_inst:config("clang")) or + target:has_tool("cxx", "clang", "clangxx", "clang_cl") + if is_clang then + return "c++" + end return "stdc++" elseif target:is_plat("windows") then return "msstl" diff --git a/xmake/toolchains/mingw/check.lua b/xmake/toolchains/mingw/check.lua index 15cfe510a..104130fee 100644 --- a/xmake/toolchains/mingw/check.lua +++ b/xmake/toolchains/mingw/check.lua @@ -44,6 +44,24 @@ function main(toolchain) }) end if mingw then + local bindir = mingw.bindir or path.join(mingw.sdkdir, "bin") + local cross = mingw.cross or "" + local is_win = is_host("windows") + local gcc = path.join(bindir, cross .. (is_win and "gcc.exe" or "gcc")) + local clang = path.join(bindir, cross .. (is_win and "clang.exe" or "clang")) + local use_clang = toolchain:config("clang") + if use_clang then + if not os.isexec(clang) then + return false + end + elseif use_clang == false then + if not os.isexec(gcc) then + return false + end + elseif (not os.isexec(gcc) or (mingw.sdkdir and mingw.sdkdir:find("llvm-mingw", 1, true))) + and os.isexec(clang) then + toolchain:config_set("clang", true) + end toolchain:config_set("mingw", mingw.sdkdir) toolchain:config_set("cross", mingw.cross) toolchain:config_set("bindir", mingw.bindir) diff --git a/xmake/toolchains/mingw/xmake.lua b/xmake/toolchains/mingw/xmake.lua index d0695dcfe..a75ab3cce 100644 --- a/xmake/toolchains/mingw/xmake.lua +++ b/xmake/toolchains/mingw/xmake.lua @@ -22,7 +22,7 @@ toolchain("mingw") set_kind("standalone") set_homepage("http://www.mingw.org/") set_description("Minimalist GNU for Windows") - set_runtimes("stdc++_static", "stdc++_shared") + set_runtimes("stdc++_static", "stdc++_shared", "c++_static", "c++_shared") on_check("check") on_load(function (toolchain) -- cgit v1.3.1 From 58983968519544cef4b4cebc08054c3843ba5a55 Mon Sep 17 00:00:00 2001 From: Damian Höster Date: Sun, 23 Aug 2026 18:29:29 +0200 Subject: simplify --- xmake/toolchains/mingw/check.lua | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/xmake/toolchains/mingw/check.lua b/xmake/toolchains/mingw/check.lua index 104130fee..15cfe510a 100644 --- a/xmake/toolchains/mingw/check.lua +++ b/xmake/toolchains/mingw/check.lua @@ -44,24 +44,6 @@ function main(toolchain) }) end if mingw then - local bindir = mingw.bindir or path.join(mingw.sdkdir, "bin") - local cross = mingw.cross or "" - local is_win = is_host("windows") - local gcc = path.join(bindir, cross .. (is_win and "gcc.exe" or "gcc")) - local clang = path.join(bindir, cross .. (is_win and "clang.exe" or "clang")) - local use_clang = toolchain:config("clang") - if use_clang then - if not os.isexec(clang) then - return false - end - elseif use_clang == false then - if not os.isexec(gcc) then - return false - end - elseif (not os.isexec(gcc) or (mingw.sdkdir and mingw.sdkdir:find("llvm-mingw", 1, true))) - and os.isexec(clang) then - toolchain:config_set("clang", true) - end toolchain:config_set("mingw", mingw.sdkdir) toolchain:config_set("cross", mingw.cross) toolchain:config_set("bindir", mingw.bindir) -- cgit v1.3.1