From 8b4e9f90ba045edb14cb2800c506ee6bc5118cd7 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 21 May 2025 01:37:17 +0200 Subject: (C++ modules support) refactor tests --- tests/projects/c++/modules/test_base.lua | 188 +++++++++++++++++++++++++------ 1 file changed, 156 insertions(+), 32 deletions(-) (limited to 'tests/projects/c++/modules/test_base.lua') diff --git a/tests/projects/c++/modules/test_base.lua b/tests/projects/c++/modules/test_base.lua index e7919761f..f060cfa0c 100644 --- a/tests/projects/c++/modules/test_base.lua +++ b/tests/projects/c++/modules/test_base.lua @@ -1,16 +1,35 @@ import("lib.detect.find_tool") import("core.base.semver") +import("core.tool.toolchain") import("utils.ci.is_running", {alias = "ci_is_running"}) -function _build() - if ci_is_running() then - os.run("xmake -rvD") +CLANG_MIN_VER = "17" +GCC_MIN_VER = "11" +MSVC_MIN_VER = "14.29" + +function _build(check_outdata) + if check_outdata then + local outdata + if ci_is_running() then + outdata = os.iorun("xmake -rvD") + else + outdata = os.iorun("xmake -rv") + end + if outdata then + if outdata:find(check_outdata.str, 1, true) then + raise(check_outdata.format_string, outdata) + end + end else - os.run("xmake -r") + if ci_is_running() then + os.run("xmake -rvD") + else + os.run("xmake -r") + end end local outdata = os.iorun("xmake") if outdata then - if outdata:find("compiling") or outdata:find("linking") or outdata:find("generating") then + if outdata:find("compiling", 1, true) or outdata:find("linking", 1, true) or outdata:find("generating", 1, true) then raise("Modules incremental compilation does not work\n%s", outdata) end end @@ -23,47 +42,152 @@ function can_build() return true elseif is_host("linux") then local gcc = find_tool("gcc", {version = true}) - if gcc and gcc.version and semver.compare(gcc.version, "11.0") >= 0 then + if gcc and gcc.version and semver.compare(gcc.version, GCC_MIN_VER) >= 0 then return true end local clang = find_tool("clang", {version = true}) - if clang and clang.version and semver.compare(clang.version, "14.0") >= 0 then + if clang and clang.version and semver.compare(clang.version, CLANG_MIN_VER) >= 0 then return true end end end -function main(t) +function build_tests(toolchain_name, opt) + assert(opt and opt.version) + local version if is_subhost("windows") then - local clang = find_tool("clang", {version = true}) - if clang and clang.version and semver.compare(clang.version, "17.0") >= 0 then - os.exec("xmake f --toolchain=clang -c --yes --policies=build.c++.modules.std:n") - _build() - os.exec("xmake clean -a") - os.exec("xmake f --toolchain=clang --runtimes=c++_shared -c --yes --policies=build.c++.modules.std:n") - _build() + 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 + version = vcvars.VCToolsVersion + end + if opt.compiler then + local cc = find_tool(opt.compiler, {version = true}) + if not cc then + wprint(opt.compiler .. " not found, skipping tests") + return + end + version = cc.version + end + + local compiler = toolchain_name == "msvc" and "cl" or opt.compiler + if not version or not (semver.compare(version, opt.version) >= 0) then + local version_str = compiler .. " >= " .. opt.version .. (version and " (found " .. version .. ")" or "") .. " " + wprint(version_str .. "not found, skipping tests") + return + end + + local policies = "--policies=build.c++.modules.std:" .. (opt.stdmodule and "y" or "n") + policies = policies .. ",build.c++.modules.fallbackscanner:" .. (opt.fallbackscanner and "y" or "n") + + local platform = " " + if opt.platform then + platform = " -p " .. opt.platform .. " " + end + + local runtimes = " " + if opt.runtimes then + runtimes = " --runtimes=" .. opt.runtimes .. " " + print("running with config: (toolchain: %s, compiler: %s, version: %s, runtimes: %s)", toolchain_name, compiler, version, opt.runtimes) + else + print("running with config: (toolchain: %s, compiler: %s, version: %s)", toolchain_name, compiler, version) + end + + local flags = "" + if opt.flags then + flags = " " .. table.concat(opt.flags, " ") + end - os.exec("xmake clean -a") - os.exec("xmake f -c --yes --policies=build.c++.modules.std:n") - _build() + os.exec("xmake clean -a") + os.exec("xmake f" .. platform .. "--toolchain=" .. toolchain_name .. runtimes .. "-c --yes " .. policies .. flags) + if opt.build then + opt.build() + else + _build(opt.find_in_outdata) + end + if opt.after_build then + opt.after_build(platform, toolchain_name, runtimes, policies, flags) + end +end + +function run_tests(clang_options, gcc_options, msvc_options) + local clang_libcpp_options + if clang_options then + clang_libcpp_options = table.clone(clang_options) + clang_libcpp_options.runtimes = "c++_shared" + end + if is_subhost("windows") then + if clang_options then + build_tests("llvm", clang_options) + build_tests("clang", clang_options) + if not clang_options.stdmodule then + build_tests("llvm", clang_libcpp_options) + build_tests("clang", clang_libcpp_options) + else + wprint("std modules tests skipped for Windows clang libc++ as it's not currently supported officially") + end + end + if msvc_options then + build_tests("msvc", msvc_options) + end + elseif is_subhost("macosx") then + if clang_options then + -- macOS doesn't ship clang-scan-deps currently + if is_subhost("macosx") then + -- check if normal clang is avalaible + local regular_clang_available = false + + local outdata = os.iorun("clang --version") + if outdata then + regular_clang_available = true + if outdata:find("Apple") then + regular_clang_available = false + end + end + if not regular_clang_available then + wprint("Appleclang isn't shipped with clang-scan-deps, disabling modules tests") + return + end + end + build_tests("llvm", clang_options) + build_tests("clang", clang_options) + end elseif is_subhost("msys") then - os.exec("xmake f -c -p mingw --yes --policies=build.c++.modules.std:n") - _build() + if clang_options then + clang_options.platform = "mingw" + clang_libcpp_options.platform = "mingw" + build_tests("llvm", clang_options) + build_tests("clang", clang_options) + build_tests("llvm", clang_libcpp_options) + build_tests("clang", clang_libcpp_options) + end + if gcc_options then + gcc_options.platform = "mingw" + build_tests("gcc", gcc_options) + end elseif is_host("linux") then - local gcc = find_tool("gcc", {version = true}) - if gcc and gcc.version and semver.compare(gcc.version, "11.0") >= 0 then - os.exec("xmake f -c --yes --policies=build.c++.modules.std:n") - _build() + if clang_options then + build_tests("llvm", clang_options) + build_tests("clang", clang_options) + build_tests("llvm", clang_libcpp_options) + build_tests("clang", clang_libcpp_options) end - local clang = find_tool("clang", {version = true}) - if clang and clang.version and semver.compare(clang.version, "14.0") >= 0 then - os.exec("xmake clean -a") - os.exec("xmake f --toolchain=clang -c --yes --policies=build.c++.modules.std:n") - _build() - os.exec("xmake clean -a") - os.exec("xmake f --toolchain=clang --runtimes=c++_shared -c --yes --policies=build.c++.modules.std:n") - _build() + if gcc_options then + build_tests("gcc", gcc_options) end end end + +function main(_) + local clang_options = {compiler = "clang", version = CLANG_MIN_VER} + local gcc_options = {compiler = "gcc", version = GCC_MIN_VER} + local msvc_options = {version = MSVC_MIN_VER} + run_tests(clang_options, gcc_options, msvc_options) +end -- cgit v1.3.1 From 42ba909a17dd780a8bf1ba51a8fcd05ad9418ebd Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 21 May 2025 02:09:14 +0200 Subject: (C++ modules support) add clang-cl to C++ modules tests --- tests/projects/c++/modules/test_base.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tests/projects/c++/modules/test_base.lua') diff --git a/tests/projects/c++/modules/test_base.lua b/tests/projects/c++/modules/test_base.lua index f060cfa0c..3f05281f3 100644 --- a/tests/projects/c++/modules/test_base.lua +++ b/tests/projects/c++/modules/test_base.lua @@ -127,6 +127,9 @@ function run_tests(clang_options, gcc_options, msvc_options) if clang_options then build_tests("llvm", clang_options) build_tests("clang", clang_options) + local clang_cl_options = table.clone(clang_options) + clang_cl_options.compiler = "clang-cl" + build_tests("clang-cl", clang_cl_options) if not clang_options.stdmodule then build_tests("llvm", clang_libcpp_options) build_tests("clang", clang_libcpp_options) -- cgit v1.3.1 From 481ada9f541be6754801d36bd03c84e7b8665b58 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 22 May 2025 08:51:48 +0200 Subject: (C++ modules support) fix clang-cl --- tests/projects/c++/modules/hello_with_pch/test.lua | 12 ++++++++++++ tests/projects/c++/modules/test_base.lua | 12 ++++++++---- xmake/rules/c++/modules/clang/builder.lua | 4 +++- xmake/rules/c++/modules/scanner.lua | 14 ++++++++++++-- 4 files changed, 35 insertions(+), 7 deletions(-) (limited to 'tests/projects/c++/modules/test_base.lua') diff --git a/tests/projects/c++/modules/hello_with_pch/test.lua b/tests/projects/c++/modules/hello_with_pch/test.lua index 7717f8049..033d2882c 100644 --- a/tests/projects/c++/modules/hello_with_pch/test.lua +++ b/tests/projects/c++/modules/hello_with_pch/test.lua @@ -1 +1,13 @@ inherit(".test_base") + +CLANG_MIN_VER = "17" +GCC_MIN_VER = "11" +MSVC_MIN_VER = "14.29" + +function main(_) + -- clang-cl doesn't support mixing pch and C++ module atm + local clang_options = {compiler = "clang", version = CLANG_MIN_VER, disable_clang_cl = true} + local gcc_options = {compiler = "gcc", version = GCC_MIN_VER} + local msvc_options = {version = MSVC_MIN_VER} + run_tests(clang_options, gcc_options, msvc_options) +end diff --git a/tests/projects/c++/modules/test_base.lua b/tests/projects/c++/modules/test_base.lua index 3f05281f3..0f030e065 100644 --- a/tests/projects/c++/modules/test_base.lua +++ b/tests/projects/c++/modules/test_base.lua @@ -4,6 +4,7 @@ import("core.tool.toolchain") import("utils.ci.is_running", {alias = "ci_is_running"}) CLANG_MIN_VER = "17" +CLANG_CL_MIN_VER = "19" GCC_MIN_VER = "11" MSVC_MIN_VER = "14.29" @@ -83,7 +84,7 @@ function build_tests(toolchain_name, opt) wprint(version_str .. "not found, skipping tests") return end - + local policies = "--policies=build.c++.modules.std:" .. (opt.stdmodule and "y" or "n") policies = policies .. ",build.c++.modules.fallbackscanner:" .. (opt.fallbackscanner and "y" or "n") @@ -127,9 +128,12 @@ function run_tests(clang_options, gcc_options, msvc_options) if clang_options then build_tests("llvm", clang_options) build_tests("clang", clang_options) - local clang_cl_options = table.clone(clang_options) - clang_cl_options.compiler = "clang-cl" - build_tests("clang-cl", clang_cl_options) + if not clang_options.disable_clang_cl then + local clang_cl_options = table.clone(clang_options) + clang_cl_options.compiler = "clang-cl" + clang_cl_options.version = CLANG_CL_MIN_VER + build_tests("clang-cl", clang_cl_options) + end if not clang_options.stdmodule then build_tests("llvm", clang_libcpp_options) build_tests("clang", clang_libcpp_options) diff --git a/xmake/rules/c++/modules/clang/builder.lua b/xmake/rules/c++/modules/clang/builder.lua index 797167283..17189b790 100644 --- a/xmake/rules/c++/modules/clang/builder.lua +++ b/xmake/rules/c++/modules/clang/builder.lua @@ -40,6 +40,9 @@ function _make_modulebuildflags(target, module, opt) flags = {"-x", "c++-module"} if not opt.objectfile then table.insert(flags, "--precompile") + if target:has_tool("cxx", "clang_cl") then + table.join2(flags, "/clang:-o", "/clang:" .. module.bmifile) + end end local std = (module.name == "std" or module.name == "std.compat") if std then @@ -182,7 +185,6 @@ function _get_requiresflags(target, module) end end requiresflags = table.unique(requiresflags) - -- table.sort(requiresflags) support.memcache():set2(cachekey, "requiresflags", requiresflags) support.memcache():set2(cachekey, "oldrequires", requires) end diff --git a/xmake/rules/c++/modules/scanner.lua b/xmake/rules/c++/modules/scanner.lua index 9e95f3cfd..537fb91d9 100644 --- a/xmake/rules/c++/modules/scanner.lua +++ b/xmake/rules/c++/modules/scanner.lua @@ -389,7 +389,12 @@ function _patch_sourcebatch(target, sourcebatch) local can_reuse = nocheck or _are_flags_compatible(target, dep, sourcefile, {strict = strict}) if can_reuse then - support.set_reused(target, dep, sourcefile) + local _reused, from = support.is_reused(dep, sourcefile) + if _reused then + support.set_reused(target, from, sourcefile) + else + support.set_reused(target, dep, sourcefile) + end table.insert(reused, sourcefile) if dep:is_moduleonly() then dep:data_set("cxx.modules.reused", true) @@ -417,10 +422,15 @@ function _patch_sourcebatch(target, sourcebatch) if reused:has(sourcefile) then local dep = target:dep(fileconfig.external) assert(dep, "dep target <%s> for <%s> not found", fileconfig.external, target:fullname()) + local _reused, from = support.is_reused(dep, sourcefile) + if _reused then + support.set_reused(target, from, sourcefile) + else + support.set_reused(target, dep, sourcefile) + end if dep:is_moduleonly() then dep:data_set("cxx.modules.reused", true) end - support.set_reused(target, dep, sourcefile) end target:fileconfig_add(sourcefile, fileconfig) end -- cgit v1.3.1