From 2ec98bd08913bf172b27f642f3751dd12eb10825 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 15 Sep 2025 03:34:34 +0200 Subject: fix(C++ modules) fix stdmodule detection when multiple runtimes are used --- xmake/rules/c++/modules/support.lua | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'xmake/rules/c++/modules/support.lua') diff --git a/xmake/rules/c++/modules/support.lua b/xmake/rules/c++/modules/support.lua index ef1d1f9dd..5ba12adef 100644 --- a/xmake/rules/c++/modules/support.lua +++ b/xmake/rules/c++/modules/support.lua @@ -69,6 +69,24 @@ function load(target) _support(target).load(target) end +function get_cpplibrary_name(target) + -- libc++ come first because on windows, if we use libc++ clang will still use msvc crt so MD / MT / MDd / MTd can be set + if target:has_runtime("c++_shared", "c++_static") then + return "c++" + elseif target:has_runtime("stdc++_shared", "stdc++_static") then + return "stdc++" + elseif target:has_runtime("MD", "MT", "MDd", "MTd") then + return "msstl" + end + if target:is_plat("macosx", "iphoneos", "appletvos") then + return "c++" + elseif target:is_plat("linux") then + return "stdc++" + elseif target:is_plat("windows") then + return "msstl" + end +end + function has_two_phase_compilation_support(target) return _support(target).has_two_phase_compilation_support(target) end @@ -282,13 +300,14 @@ end -- get stdmodules function get_stdmodules(target) - local stdmodules = memcache():get("c++.modules.stdmodules") - local stdmodules_set = memcache():get("c++.modules.stdmodules_set") + local cpplib = get_cpplibrary_name(target) + local stdmodules = memcache():get2(cpplib, "c++.modules.stdmodules") + local stdmodules_set = memcache():get2(cpplib, "c++.modules.stdmodules_set") if not stdmodules or not stdmodules_set then stdmodules = _support(target).get_stdmodules(target) stdmodules_set = hashset.from(stdmodules or {}) - memcache():set("c++.modules.stdmodules", stdmodules) - memcache():set("c++.modules.stdmodules_set", stdmodules_set) + memcache():set2(cpplib, "c++.modules.stdmodules", stdmodules) + memcache():set2(cpplib, "c++.modules.stdmodules_set", stdmodules_set) end return stdmodules, stdmodules_set end -- cgit v1.3.1 From 665a36326b092b14b6024f6e0d0dfaf2660b855a Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 15 Sep 2025 04:47:52 +0200 Subject: fix(C++ modules) fix culling --- xmake/rules/c++/modules/support.lua | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'xmake/rules/c++/modules/support.lua') diff --git a/xmake/rules/c++/modules/support.lua b/xmake/rules/c++/modules/support.lua index 5ba12adef..cce8272c8 100644 --- a/xmake/rules/c++/modules/support.lua +++ b/xmake/rules/c++/modules/support.lua @@ -258,6 +258,12 @@ function can_be_culled(target, sourcefile) can_cull = can_cull and fileconfig.cull end end + if can_cull then + can_cull = false + if is_stdmodule or (fileconfig and fileconfig.external) then + can_cull = true + end + end return can_cull and not public end -- cgit v1.3.1 From bcc3c5617baad62989a45a44aa2890fda5eba0f3 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 25 Sep 2025 17:51:15 +0200 Subject: nfc(C++ modules) apply PR suggestion --- .../c++/modules/add_move_remove_module/test.lua | 4 +- .../c++/modules/multiple_runtimes/test.lua | 75 +++++++++++----------- .../c++/modules/multiple_runtimes/xmake.lua | 39 +++++++---- xmake/rules/c++/modules/support.lua | 8 +-- 4 files changed, 69 insertions(+), 57 deletions(-) (limited to 'xmake/rules/c++/modules/support.lua') diff --git a/tests/projects/c++/modules/add_move_remove_module/test.lua b/tests/projects/c++/modules/add_move_remove_module/test.lua index 627688f6c..ad8c4833b 100644 --- a/tests/projects/c++/modules/add_move_remove_module/test.lua +++ b/tests/projects/c++/modules/add_move_remove_module/test.lua @@ -5,10 +5,10 @@ CLANG_MIN_VER = is_subhost("windows") and "19" or "17" GCC_MIN_VER = "11" MSVC_MIN_VER = "14.29" -function _build(check_outdata) +function _build(_) local flags = "" if ci_is_running() then - flags = "-vD" + flags = "-vD" end os.run("xmake -r " .. flags) io.writefile("src/bar.mpp", "export module bar;\n export {\n inline int bar() { return 0; }\n}") diff --git a/tests/projects/c++/modules/multiple_runtimes/test.lua b/tests/projects/c++/modules/multiple_runtimes/test.lua index 2050445f3..ad2585efa 100644 --- a/tests/projects/c++/modules/multiple_runtimes/test.lua +++ b/tests/projects/c++/modules/multiple_runtimes/test.lua @@ -7,61 +7,64 @@ CLANG_MIN_VER = "19" GCC_MIN_VER = "15" MSVC_MIN_VER = "14.35" -function main(_) - if not is_subhost("windows") and not is_host("linux") then - return +function _check_tool_version(name, min_ver) + local tool = find_tool(name, {version = true}) + if not (tool and tool.version and semver.compare(tool.version, min_ver) >= 0) then + return false + end + return true +end + + +function _check_msvc_version(min_ver) + local msvc = toolchain.load("msvc") + if not msvc or not msvc:check() then + return false + end + local vcvars = msvc:config("vcvars") + if not vcvars or not vcvars.VCInstallDir or not vcvars.VCToolsVersion then + return false + end + local version = vcvars.VCToolsVersion + if not version or not (semver.compare(version, min_ver) >= 0) then + return false end + return true +end +function main(_) if is_subhost("windows") then - local msvc = toolchain.load("msvc") - if not msvc or not msvc:check() then - wprint("msvc not found, skipping tests") - return - end - local vcvars = msvc:config("vcvars") - if not vcvars or not vcvars.VCInstallDir or not vcvars.VCToolsVersion then - wprint("msvc not found, skipping tests") - return - end - local version = vcvars.VCToolsVersion - if not version or not (semver.compare(version, MSVC_MIN_VER) >= 0) then + if not _check_msvc_version(MSVC_MIN_VER) then return end -- on windows, llvm libc++ std module is currently not supported, uncommend when supported - local clang = find_tool("clang", {version = true}) - if not (clang and clang.version and semver.compare(clang.version, CLANG_MIN_VER) >= 0) then + -- if not check_tool_version("clang", CLANG_MIN_VER) then + -- return + -- end + elseif is_host("linux") then + if not _check_tool_version("gcc", GCC_MIN_VER) or not _check_tool_version("clang", CLANG_MIN_VER) then return end else - local gcc = find_tool("gcc", {version = true}) - if not (gcc and gcc.version and semver.compare(gcc.version, GCC_MIN_VER) >= 0) then - return - end - local clang = find_tool("clang", {version = true}) - if not (clang and clang.version and semver.compare(clang.version, CLANG_MIN_VER) >= 0) then - return - end + return end local cl_str = "modules\\std.ixx" local clang_str = is_host("windows") and "v1\\std.cppm" or "v1/std.cppm" local gcc_str = "v1/std.cppm" - local flags = "" - if ci_is_running() then - flags = "-vD" - end + local flags = true and "-vD" or "" local outdata - outdata = os.iorun("xmake -r " .. flags) + outdata = os.iorun("xmake b " .. flags) if outdata then - local error = true + local success = false -- on windows, llvm libc++ std module is currently not supported, uncommend when supported - if is_host("windows") and outdata:find(cl_str, 1, true) and outdata:find(clang_str, 1, true) then - error = false - elseif outdata:find(clang_str, 1, true) and outdata:find(gcc_str, 1, true) then - error = false + if is_subhost("windows") then + success = outdata:find(cl_str, 1, true) -- and outdata:find(clang_str, 1, true) + else + success = outdata:find(gcc_str, 1, true) and outdata:find(clang_str, 1, true) end - if error then + if not success then raise("Multiple runtimes doesn't work\n%s", outdata) end end diff --git a/tests/projects/c++/modules/multiple_runtimes/xmake.lua b/tests/projects/c++/modules/multiple_runtimes/xmake.lua index 736079687..f67ab211b 100644 --- a/tests/projects/c++/modules/multiple_runtimes/xmake.lua +++ b/tests/projects/c++/modules/multiple_runtimes/xmake.lua @@ -1,29 +1,40 @@ add_rules("mode.debug", "mode.release") -add_files("src/*.cpp") set_languages("c++23") set_encodings("utf-8") -target("llvm") - set_kind("binary") - set_toolchains("clang") - set_runtimes("c++_shared") - set_policy("build.c++.modules", true) - add_files("src/main.cpp") +if is_plat("windows") then + -- on windows, llvm libc++ std module is currently not supported, uncommend when supported + -- target("llvm") + -- set_kind("binary") + -- set_toolchains("clang") + -- set_runtimes("c++_shared") + -- set_policy("build.c++.modules", true) + -- add_files("src/main.cpp") -if is_plat("linux") or is_plat("mingw") then - target("gnu") + target("llvm-msvc") set_kind("binary") - set_toolchains("gcc") - set_runtimes("stdc++_shared") + set_toolchains("clang") set_policy("build.c++.modules", true) - set_policy("build.c++.modules.gcc.cxx11abi", true) add_files("src/main.cpp") -end -if is_plat("windows") then target("msvc") set_kind("binary") set_toolchains("msvc") set_policy("build.c++.modules", true) add_files("src/main.cpp") +else + target("llvm") + set_kind("binary") + set_toolchains("clang") + set_runtimes("c++_shared") + set_policy("build.c++.modules", true) + add_files("src/main.cpp") + + target("gnu") + set_kind("binary") + set_toolchains("gcc") + set_runtimes("stdc++_shared") + set_policy("build.c++.modules", true) + set_policy("build.c++.modules.gcc.cxx11abi", true) + add_files("src/main.cpp") end diff --git a/xmake/rules/c++/modules/support.lua b/xmake/rules/c++/modules/support.lua index cce8272c8..8d1c39531 100644 --- a/xmake/rules/c++/modules/support.lua +++ b/xmake/rules/c++/modules/support.lua @@ -78,9 +78,10 @@ function get_cpplibrary_name(target) elseif target:has_runtime("MD", "MT", "MDd", "MTd") then return "msstl" end + -- if no specified runtime, fallback on native platform C++ library if target:is_plat("macosx", "iphoneos", "appletvos") then return "c++" - elseif target:is_plat("linux") then + elseif target:is_plat("linux") or target:is_plat("mingw") then return "stdc++" elseif target:is_plat("windows") then return "msstl" @@ -259,10 +260,7 @@ function can_be_culled(target, sourcefile) end end if can_cull then - can_cull = false - if is_stdmodule or (fileconfig and fileconfig.external) then - can_cull = true - end + can_cull = is_stdmodule or (fileconfig and fileconfig.external) end return can_cull and not public end -- cgit v1.3.1