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 --- .../projects/c++/modules/class_cmake/src/hello.mpp | 11 ++ .../c++/modules/class_cmake/src/hello_impl.cpp | 14 ++ .../projects/c++/modules/class_cmake/src/main.cpp | 7 + tests/projects/c++/modules/class_cmake/test.lua | 1 + tests/projects/c++/modules/class_cmake/xmake.lua | 8 + tests/projects/c++/modules/cmake/src/hello.mpp | 11 -- .../projects/c++/modules/cmake/src/hello_impl.cpp | 14 -- tests/projects/c++/modules/cmake/src/main.cpp | 7 - tests/projects/c++/modules/cmake/test.lua | 60 ------- tests/projects/c++/modules/cmake/xmake.lua | 8 - tests/projects/c++/modules/culling/test.lua | 70 +------- tests/projects/c++/modules/culling2/test.lua | 70 +------- tests/projects/c++/modules/culling3/test.lua | 70 +------- .../c++/modules/duplicate_name_detection/test.lua | 76 +-------- .../c++/modules/internal_partition/test.lua | 2 +- .../c++/modules/packages-subtarget/test.lua | 2 +- tests/projects/c++/modules/packages/test.lua | 2 +- tests/projects/c++/modules/partitions/test.lua | 2 +- .../c++/modules/partitions_implunit/test.lua | 2 +- .../c++/modules/partitions_implunit2/test.lua | 2 +- tests/projects/c++/modules/test_base.lua | 188 +++++++++++++++++---- tests/projects/c++/modules/test_cmake.lua | 78 +++++++++ tests/projects/c++/modules/test_culling.lua | 13 ++ .../c++/modules/test_dependency_scanner.lua | 70 ++------ .../c++/modules/test_duplicate_modules.lua | 33 ++++ tests/projects/c++/modules/test_headerunits.lua | 75 ++------ tests/projects/c++/modules/test_partitions.lua | 12 ++ tests/projects/c++/modules/test_stdmodules.lua | 88 +++------- xmake/rules/c++/modules/msvc/support.lua | 6 +- 29 files changed, 396 insertions(+), 606 deletions(-) create mode 100644 tests/projects/c++/modules/class_cmake/src/hello.mpp create mode 100644 tests/projects/c++/modules/class_cmake/src/hello_impl.cpp create mode 100644 tests/projects/c++/modules/class_cmake/src/main.cpp create mode 100644 tests/projects/c++/modules/class_cmake/test.lua create mode 100644 tests/projects/c++/modules/class_cmake/xmake.lua delete mode 100644 tests/projects/c++/modules/cmake/src/hello.mpp delete mode 100644 tests/projects/c++/modules/cmake/src/hello_impl.cpp delete mode 100644 tests/projects/c++/modules/cmake/src/main.cpp delete mode 100644 tests/projects/c++/modules/cmake/test.lua delete mode 100644 tests/projects/c++/modules/cmake/xmake.lua create mode 100644 tests/projects/c++/modules/test_cmake.lua create mode 100644 tests/projects/c++/modules/test_culling.lua create mode 100644 tests/projects/c++/modules/test_duplicate_modules.lua create mode 100644 tests/projects/c++/modules/test_partitions.lua diff --git a/tests/projects/c++/modules/class_cmake/src/hello.mpp b/tests/projects/c++/modules/class_cmake/src/hello.mpp new file mode 100644 index 000000000..268964aa3 --- /dev/null +++ b/tests/projects/c++/modules/class_cmake/src/hello.mpp @@ -0,0 +1,11 @@ +export module hello; + +export namespace hello { + class say { + public: + say(int data); + void hello(); + private: + int data_; + }; +} diff --git a/tests/projects/c++/modules/class_cmake/src/hello_impl.cpp b/tests/projects/c++/modules/class_cmake/src/hello_impl.cpp new file mode 100644 index 000000000..5dd555a7a --- /dev/null +++ b/tests/projects/c++/modules/class_cmake/src/hello_impl.cpp @@ -0,0 +1,14 @@ +module; +#include + +module hello; + +using namespace std; +namespace hello { + say::say(int data) : data_(data) { + + } + void say::hello() { + cout << "hello, say class: " << data_ << endl; + } +} diff --git a/tests/projects/c++/modules/class_cmake/src/main.cpp b/tests/projects/c++/modules/class_cmake/src/main.cpp new file mode 100644 index 000000000..b96807bda --- /dev/null +++ b/tests/projects/c++/modules/class_cmake/src/main.cpp @@ -0,0 +1,7 @@ +import hello; + +int main() { + hello::say s(sizeof(hello::say)); + s.hello(); + return 0; +} diff --git a/tests/projects/c++/modules/class_cmake/test.lua b/tests/projects/c++/modules/class_cmake/test.lua new file mode 100644 index 000000000..703d66bdc --- /dev/null +++ b/tests/projects/c++/modules/class_cmake/test.lua @@ -0,0 +1 @@ +inherit(".test_cmake") diff --git a/tests/projects/c++/modules/class_cmake/xmake.lua b/tests/projects/c++/modules/class_cmake/xmake.lua new file mode 100644 index 000000000..42da78369 --- /dev/null +++ b/tests/projects/c++/modules/class_cmake/xmake.lua @@ -0,0 +1,8 @@ +add_rules("mode.release", "mode.debug") +set_languages("c++20") + +target("class") + set_kind("binary") + add_files("src/*.cpp", "src/*.mpp") + + diff --git a/tests/projects/c++/modules/cmake/src/hello.mpp b/tests/projects/c++/modules/cmake/src/hello.mpp deleted file mode 100644 index 268964aa3..000000000 --- a/tests/projects/c++/modules/cmake/src/hello.mpp +++ /dev/null @@ -1,11 +0,0 @@ -export module hello; - -export namespace hello { - class say { - public: - say(int data); - void hello(); - private: - int data_; - }; -} diff --git a/tests/projects/c++/modules/cmake/src/hello_impl.cpp b/tests/projects/c++/modules/cmake/src/hello_impl.cpp deleted file mode 100644 index 5dd555a7a..000000000 --- a/tests/projects/c++/modules/cmake/src/hello_impl.cpp +++ /dev/null @@ -1,14 +0,0 @@ -module; -#include - -module hello; - -using namespace std; -namespace hello { - say::say(int data) : data_(data) { - - } - void say::hello() { - cout << "hello, say class: " << data_ << endl; - } -} diff --git a/tests/projects/c++/modules/cmake/src/main.cpp b/tests/projects/c++/modules/cmake/src/main.cpp deleted file mode 100644 index b96807bda..000000000 --- a/tests/projects/c++/modules/cmake/src/main.cpp +++ /dev/null @@ -1,7 +0,0 @@ -import hello; - -int main() { - hello::say s(sizeof(hello::say)); - s.hello(); - return 0; -} diff --git a/tests/projects/c++/modules/cmake/test.lua b/tests/projects/c++/modules/cmake/test.lua deleted file mode 100644 index 2b246c9a6..000000000 --- a/tests/projects/c++/modules/cmake/test.lua +++ /dev/null @@ -1,60 +0,0 @@ -import("lib.detect.find_tool") -import("core.base.semver") -import("core.tool.toolchain") -import("utils.ci.is_running", {alias = "ci_is_running"}) - -function _gen_cmakelist() - if not os.isfile("CMakeLists.txt") then - os.vrunv("xmake project -k cmake") - end -end - -function _build(name, opt) - opt = opt or {} - local build_args = {} - if ci_is_running() then - table.insert(build_args, "-vD") - end - os.rm(".xmake", "build") - os.mv("xmake.lua", "xmake.lua_") - os.vrunv("xmake", table.join({"f", "--trybuild=cmake", "--toolchain=" .. name}, build_args), {shell = true, envs = opt.envs}) - os.vrunv("xmake", table.join({"b"}, build_args), {shell = true, envs = opt.envs}) - os.mv("xmake.lua_", "xmake.lua") -end - -function _build_with(name, minver) - if name == "msvc" then - local _toolchain = toolchain.load(name, {plat = os.host(), arch = os.arch()}) - if _toolchain and _toolchain:check() then - local vcvars = _toolchain:config("vcvars") - if vcvars and vcvars.VCToolsVersion and semver.compare(vcvars.VCToolsVersion, minver) >= 0 then - _build(name, {envs = vcvars}) - end - end - else - local tool = find_tool(name, {version = true}) - if tool and tool.version and semver.compare(tool.version, minver) >= 0 then - local _toolchain = toolchain.load(name, {plat = os.host(), arch = os.arch()}) - if _toolchain and _toolchain:check() then - _build(name) - end - end - end -end - -function main(t) - os.setenv("CMAKE_GENERATOR", "Ninja") - - local cmake = find_tool("cmake", {version = true}) - local ninja = find_tool("ninja") - if ninja and cmake and cmake.version and semver.compare(cmake.version, "3.28") >= 0 then - _gen_cmakelist() - if is_subhost("windows") then - _build_with("clang", "19") - _build_with("msvc", "14.35") - elseif is_subhost("linux") then - _build_with("gcc", "14") - _build_with("clang", "19") - end - end -end diff --git a/tests/projects/c++/modules/cmake/xmake.lua b/tests/projects/c++/modules/cmake/xmake.lua deleted file mode 100644 index 42da78369..000000000 --- a/tests/projects/c++/modules/cmake/xmake.lua +++ /dev/null @@ -1,8 +0,0 @@ -add_rules("mode.release", "mode.debug") -set_languages("c++20") - -target("class") - set_kind("binary") - add_files("src/*.cpp", "src/*.mpp") - - diff --git a/tests/projects/c++/modules/culling/test.lua b/tests/projects/c++/modules/culling/test.lua index 90832e424..7232ae644 100644 --- a/tests/projects/c++/modules/culling/test.lua +++ b/tests/projects/c++/modules/culling/test.lua @@ -1,69 +1 @@ -import("lib.detect.find_tool") -import("core.base.semver") -import("utils.ci.is_running", {alias = "ci_is_running"}) - -function _build() - 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("culled") then - raise("Modules culling does not work\n%s", outdata) - end - end -end - -function can_build() - if is_subhost("windows") then - return true - elseif is_subhost("msys") then - 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 - return true - end - local clang = find_tool("clang", {version = true}) - if clang and clang.version and semver.compare(clang.version, "14.0") >= 0 then - return true - end - end -end - -function main(t) - 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() - end - - os.exec("xmake clean -a") - os.exec("xmake f -c --yes --policies=build.c++.modules.std:n") - _build() - elseif is_subhost("msys") then - os.exec("xmake f -c -p mingw --yes --policies=build.c++.modules.std:n") - _build() - 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() - 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() - end - end -end +inherit(".test_culling") diff --git a/tests/projects/c++/modules/culling2/test.lua b/tests/projects/c++/modules/culling2/test.lua index 90832e424..7232ae644 100644 --- a/tests/projects/c++/modules/culling2/test.lua +++ b/tests/projects/c++/modules/culling2/test.lua @@ -1,69 +1 @@ -import("lib.detect.find_tool") -import("core.base.semver") -import("utils.ci.is_running", {alias = "ci_is_running"}) - -function _build() - 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("culled") then - raise("Modules culling does not work\n%s", outdata) - end - end -end - -function can_build() - if is_subhost("windows") then - return true - elseif is_subhost("msys") then - 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 - return true - end - local clang = find_tool("clang", {version = true}) - if clang and clang.version and semver.compare(clang.version, "14.0") >= 0 then - return true - end - end -end - -function main(t) - 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() - end - - os.exec("xmake clean -a") - os.exec("xmake f -c --yes --policies=build.c++.modules.std:n") - _build() - elseif is_subhost("msys") then - os.exec("xmake f -c -p mingw --yes --policies=build.c++.modules.std:n") - _build() - 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() - 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() - end - end -end +inherit(".test_culling") diff --git a/tests/projects/c++/modules/culling3/test.lua b/tests/projects/c++/modules/culling3/test.lua index d6745625a..7232ae644 100644 --- a/tests/projects/c++/modules/culling3/test.lua +++ b/tests/projects/c++/modules/culling3/test.lua @@ -1,69 +1 @@ -import("lib.detect.find_tool") -import("core.base.semver") -import("utils.ci.is_running", {alias = "ci_is_running"}) - -function _build() - local outdata - if ci_is_running() then - outdata = os.iorun("xmake -rvD") - else - outdata = os.iorun("xmake -rv") - end - if outdata then - if not outdata:find("culled") then - raise("Modules culling does not work\n%s", outdata) - end - end -end - -function can_build() - if is_subhost("windows") then - return true - elseif is_subhost("msys") then - 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 - return true - end - local clang = find_tool("clang", {version = true}) - if clang and clang.version and semver.compare(clang.version, "14.0") >= 0 then - return true - end - end -end - -function main(t) - 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() - end - - os.exec("xmake clean -a") - os.exec("xmake f -c --yes --policies=build.c++.modules.std:n") - _build() - elseif is_subhost("msys") then - os.exec("xmake f -c -p mingw --yes --policies=build.c++.modules.std:n") - _build() - 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() - 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() - end - end -end +inherit(".test_culling") diff --git a/tests/projects/c++/modules/duplicate_name_detection/test.lua b/tests/projects/c++/modules/duplicate_name_detection/test.lua index fd01ea575..0b041cca0 100644 --- a/tests/projects/c++/modules/duplicate_name_detection/test.lua +++ b/tests/projects/c++/modules/duplicate_name_detection/test.lua @@ -1,75 +1 @@ -import("lib.detect.find_tool") -import("core.base.semver") -import("utils.ci.is_running", {alias = "ci_is_running"}) - -function _build() - try { - function() - if ci_is_running() then - os.run("xmake -rvD") - else - os.run("xmake -r") - end - end, - catch { - function (errors) - errors = tostring(errors) - if not errors:find("duplicate module name detected", 1, true) then - raise("Modules duplicate name detection does not work\n%s", errors) - end - end - } - } -end - -function can_build() - if is_subhost("windows") then - return true - elseif is_subhost("msys") then - 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 - return true - end - local clang = find_tool("clang", {version = true}) - if clang and clang.version and semver.compare(clang.version, "14.0") >= 0 then - return true - end - end -end - -function main(t) - 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() - end - - os.exec("xmake clean -a") - os.exec("xmake f -c --yes --policies=build.c++.modules.std:n") - _build() - elseif is_subhost("msys") then - os.exec("xmake f -c -p mingw --yes --policies=build.c++.modules.std:n") - _build() - 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() - 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() - end - end -end +inherit(".test_duplicate_modules") diff --git a/tests/projects/c++/modules/internal_partition/test.lua b/tests/projects/c++/modules/internal_partition/test.lua index 7717f8049..082bfbcaf 100644 --- a/tests/projects/c++/modules/internal_partition/test.lua +++ b/tests/projects/c++/modules/internal_partition/test.lua @@ -1 +1 @@ -inherit(".test_base") +inherit(".test_partitions") diff --git a/tests/projects/c++/modules/packages-subtarget/test.lua b/tests/projects/c++/modules/packages-subtarget/test.lua index c18e5a1d0..7717f8049 100644 --- a/tests/projects/c++/modules/packages-subtarget/test.lua +++ b/tests/projects/c++/modules/packages-subtarget/test.lua @@ -1 +1 @@ -inherit(".test_headerunits") +inherit(".test_base") diff --git a/tests/projects/c++/modules/packages/test.lua b/tests/projects/c++/modules/packages/test.lua index c18e5a1d0..7717f8049 100644 --- a/tests/projects/c++/modules/packages/test.lua +++ b/tests/projects/c++/modules/packages/test.lua @@ -1 +1 @@ -inherit(".test_headerunits") +inherit(".test_base") diff --git a/tests/projects/c++/modules/partitions/test.lua b/tests/projects/c++/modules/partitions/test.lua index e77adc4ae..082bfbcaf 100644 --- a/tests/projects/c++/modules/partitions/test.lua +++ b/tests/projects/c++/modules/partitions/test.lua @@ -1 +1 @@ -inherit(".test_stdmodules") +inherit(".test_partitions") diff --git a/tests/projects/c++/modules/partitions_implunit/test.lua b/tests/projects/c++/modules/partitions_implunit/test.lua index e77adc4ae..082bfbcaf 100644 --- a/tests/projects/c++/modules/partitions_implunit/test.lua +++ b/tests/projects/c++/modules/partitions_implunit/test.lua @@ -1 +1 @@ -inherit(".test_stdmodules") +inherit(".test_partitions") diff --git a/tests/projects/c++/modules/partitions_implunit2/test.lua b/tests/projects/c++/modules/partitions_implunit2/test.lua index e77adc4ae..082bfbcaf 100644 --- a/tests/projects/c++/modules/partitions_implunit2/test.lua +++ b/tests/projects/c++/modules/partitions_implunit2/test.lua @@ -1 +1 @@ -inherit(".test_stdmodules") +inherit(".test_partitions") 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 diff --git a/tests/projects/c++/modules/test_cmake.lua b/tests/projects/c++/modules/test_cmake.lua new file mode 100644 index 000000000..3f3355eb5 --- /dev/null +++ b/tests/projects/c++/modules/test_cmake.lua @@ -0,0 +1,78 @@ +import("lib.detect.find_tool") +import("core.base.semver") +import("core.tool.toolchain") +import("utils.ci.is_running", {alias = "ci_is_running"}) + +function _gen_cmakelist() + if not os.isfile("CMakeLists.txt") then + os.vrunv("xmake project -k cmake") + end +end + +function _build(name, opt) + opt = opt or {} + local build_args = {} + if ci_is_running() then + table.insert(build_args, "-vD") + end + os.rm(".xmake", "build") + os.mv("xmake.lua", "xmake.lua_") + os.vrunv("xmake", table.join({"f", "--trybuild=cmake", "--toolchain=" .. name}, build_args), {shell = true, envs = opt.envs}) + os.vrunv("xmake", table.join({"b"}, build_args), {shell = true, envs = opt.envs}) + os.mv("xmake.lua_", "xmake.lua") +end + +function _build_with(name, minver) + if name == "msvc" then + local _toolchain = toolchain.load(name, {plat = os.host(), arch = os.arch()}) + if _toolchain and _toolchain:check() then + local vcvars = _toolchain:config("vcvars") + if vcvars and vcvars.VCToolsVersion and semver.compare(vcvars.VCToolsVersion, minver) >= 0 then + _build(name, {envs = vcvars}) + end + end + else + local tool = find_tool(name, {version = true}) + if tool and tool.version and semver.compare(tool.version, minver) >= 0 then + local _toolchain = toolchain.load(name, {plat = os.host(), arch = os.arch()}) + if _toolchain and _toolchain:check() then + _build(name) + end + end + end +end + +function main(t) + os.setenv("CMAKE_GENERATOR", "Ninja") + + local cmake = find_tool("cmake", {version = true}) + local ninja = find_tool("ninja") + if ninja and cmake and cmake.version and semver.compare(cmake.version, "3.28") >= 0 then + _gen_cmakelist() + if is_subhost("windows") then + _build_with("clang", "19") + _build_with("msvc", "14.35") + elseif is_subhost("linux") then + _build_with("gcc", "14") + _build_with("clang", "19") + elseif is_subhost("macosx") then + -- macOS doesn't ship clang-scan-deps currently + -- 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 + _build_with("clang", "19") + end + + end +end diff --git a/tests/projects/c++/modules/test_culling.lua b/tests/projects/c++/modules/test_culling.lua new file mode 100644 index 000000000..66f96227a --- /dev/null +++ b/tests/projects/c++/modules/test_culling.lua @@ -0,0 +1,13 @@ +inherit("test_base") + +CLANG_MIN_VER = "17" +GCC_MIN_VER = "11" +MSVC_MIN_VER = "14.29" + +function main(_) + local check_outdata = {str = "culled", format_string = "Modules culling does not work"} + local clang_options = {compiler = "clang", version = CLANG_MIN_VER, check_outdata = check_outdata} + local gcc_options = {compiler = "gcc", version = GCC_MIN_VER, check_outdata} + local msvc_options = {version = MSVC_MIN_VER, check_outdata} + run_tests(clang_options, gcc_options, msvc_options) +end diff --git a/tests/projects/c++/modules/test_dependency_scanner.lua b/tests/projects/c++/modules/test_dependency_scanner.lua index 5f56113c2..c27b52887 100644 --- a/tests/projects/c++/modules/test_dependency_scanner.lua +++ b/tests/projects/c++/modules/test_dependency_scanner.lua @@ -1,9 +1,12 @@ -import("lib.detect.find_tool") -import("core.base.semver") +inherit("test_base") import("utils.ci.is_running", {alias = "ci_is_running"}) -function _build() - os.run("xmake f --foo=n --policies=build.c++.modules.std:n") +CLANG_MIN_VER = "17" +GCC_MIN_VER = "11" +MSVC_MIN_VER = "14.29" + +function _build(platform, toolchain_name, runtimes, policies, flags) + os.exec("xmake f" .. platform .. "--toolchain=" .. toolchain_name .. runtimes .. "-c --yes " .. policies .. " --foo=n") local outdata if ci_is_running() then outdata = os.iorun("xmake -rvD") @@ -15,62 +18,11 @@ function _build() raise("Modules dependency scanner update does not work\n%s", outdata) end end - outdata = os.iorun("xmake") - if outdata then - if outdata:find("compiling") or outdata:find("linking") or outdata:find("generating") then - raise("Modules incremental compilation does not work\n%s", outdata) - end - end -end - -function can_build() - if is_subhost("windows") then - return true - elseif is_subhost("msys") then - 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 - return true - end - local clang = find_tool("clang", {version = true}) - if clang and clang.version and semver.compare(clang.version, "14.0") >= 0 then - return true - end - end end function main(t) - 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() - end - - os.exec("xmake clean -a") - os.exec("xmake f -c --yes --policies=build.c++.modules.std:n") - _build() - elseif is_subhost("msys") then - os.exec("xmake f -c -p mingw --yes --policies=build.c++.modules.std:n") - _build() - 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() - 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() - end - end + local clang_options = {compiler = "clang", version = CLANG_MIN_VER, flags = {"--foo=y"}, after_build = _build} + local gcc_options = {compiler = "gcc", version = GCC_MIN_VER, flags = {"--foo=y"}, after_build = _build} + local msvc_options = {version = MSVC_MIN_VER, flags = {"--foo=y"}, after_build = _build} + run_tests(clang_options, gcc_options, msvc_options) end diff --git a/tests/projects/c++/modules/test_duplicate_modules.lua b/tests/projects/c++/modules/test_duplicate_modules.lua new file mode 100644 index 000000000..76e8806f7 --- /dev/null +++ b/tests/projects/c++/modules/test_duplicate_modules.lua @@ -0,0 +1,33 @@ +inherit("test_base") +import("utils.ci.is_running", {alias = "ci_is_running"}) + +CLANG_MIN_VER = "17" +GCC_MIN_VER = "11" +MSVC_MIN_VER = "14.29" + +function _build() + try { + function() + if ci_is_running() then + os.run("xmake -rvD") + else + os.run("xmake -r") + end + end, + catch { + function (errors) + errors = tostring(errors) + if not errors:find("duplicate module name detected", 1, true) then + raise("Modules duplicate name detection does not work\n%s", errors) + end + end + } + } +end + +function main(_) + local clang_options = {compiler = "clang", version = CLANG_MIN_VER, build = _build} + local gcc_options = {compiler = "gcc", version = GCC_MIN_VER, build = _build} + local msvc_options = {version = MSVC_MIN_VER, build = _build} + run_tests(clang_options, gcc_options, msvc_options) +end diff --git a/tests/projects/c++/modules/test_headerunits.lua b/tests/projects/c++/modules/test_headerunits.lua index 264cca6e6..17f6373c0 100644 --- a/tests/projects/c++/modules/test_headerunits.lua +++ b/tests/projects/c++/modules/test_headerunits.lua @@ -1,70 +1,17 @@ -import("lib.detect.find_tool") -import("core.base.semver") -import("detect.sdks.find_vstudio") +inherit("test_base") import("utils.ci.is_running", {alias = "ci_is_running"}) -function _build() - if ci_is_running() then - os.run("xmake -rvD") - else - os.run("xmake -r") - end - local outdata = os.iorun("xmake") - if outdata then - if outdata:find("compiling") or outdata:find("linking") or outdata:find("generating") then - raise("Modules incremental compilation does not work\n%s", outdata) - end - end -end +GCC_MIN_VER = "11" +MSVC_MIN_VER = "14.30" function main(t) - if is_subhost("windows") then - local clang = find_tool("clang", {version = true}) - if clang and clang.version and semver.compare(clang.version, "15.0") >= 0 then - -- clang headerunit are bugged - -- os.exec("xmake f --toolchain=clang -c --yes --policies=build.c++.modules.std:n,build.c++.modules.fallbackscanner:y") - -- _build() - -- if semver.compare(clang.version, "17.0") >= 0 then - -- os.exec("xmake clean -a") - -- -- clang-scan-deps dependency detection doesn't support header units atm - -- os.exec("xmake f --toolchain=clang --runtimes=c++_shared -c --yes --policies=build.c++.modules.std:n,build.c++.modules.fallbackscanner:y") - -- _build() - -- end - end - - local vs = find_vstudio() - if vs and vs["2022"] then - os.exec("xmake clean -a") - os.exec("xmake f -c --yes --policies=build.c++.modules.std:n") - _build() - end - elseif is_subhost("msys") then - -- on windows, mingw modulemapper doesn't handle headeunit path correctly, but it's working with mingw on macOS / Linux - -- os.exec("xmake f -c -p mingw --yes --policies=build.c++.modules.std:n,build.c++.modules.fallbackscanner:y") - -- _build() - 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 and - os.arch() ~= "arm64" then -- gcc/arm64: internal compiler error: in core_vals, at cp/module.cc:6108 - -- gcc dependency detection doesn't support header units atm - os.exec("xmake f -c --yes --policies=build.c++.modules.std:n,build.c++.modules.fallbackscanner:y") - _build() - end - local clang = find_tool("clang", {version = true}) - if clang and clang.version then - if semver.compare(clang.version, "19.0") >= 0 then - os.exec("xmake clean -a") - -- clang-scan-deps dependency detection doesn't support header units atm - os.exec("xmake f --toolchain=clang -c --yes --policies=build.c++.modules.std:n,build.c++.modules.fallbackscanner:y") - _build() - end - -- libc++ headerunit are bugged - -- if semver.compare(clang.version, "17.0") >= 0 then - -- os.exec("xmake clean -a") - -- -- clang-scan-deps dependency detection doesn't support header units atm - -- os.exec("xmake f --toolchain=clang --runtimes=c++_shared -c --yes --policies=build.c++.modules.std:n,build.c++.modules.fallbackscanner:y") - -- _build() - -- end - end + local gcc_options = {fallbackscanner = true, compiler = "gcc", version = GCC_MIN_VER} + -- gcc/arm64: internal compiler error: in core_vals, at cp/module.cc:6108 + -- on windows, mingw modulemapper doesn't handle headeunit path correctly, but it's working with mingw on macOS / Linux + if os.arch() == "arm64" or is_subhost("msys") then + gcc_options = nil end + local msvc_options = {version = MSVC_MIN_VER} + -- skip clang tests, headerunits with clang is not stable + run_tests(nil, gcc_options, msvc_options) end diff --git a/tests/projects/c++/modules/test_partitions.lua b/tests/projects/c++/modules/test_partitions.lua new file mode 100644 index 000000000..ed03bd9d7 --- /dev/null +++ b/tests/projects/c++/modules/test_partitions.lua @@ -0,0 +1,12 @@ +inherit("test_base") + +CLANG_MIN_VER = "18" +GCC_MIN_VER = "13" +MSVC_MIN_VER = "14.30" + +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 diff --git a/tests/projects/c++/modules/test_stdmodules.lua b/tests/projects/c++/modules/test_stdmodules.lua index 0ca1cc9de..c9062eb96 100644 --- a/tests/projects/c++/modules/test_stdmodules.lua +++ b/tests/projects/c++/modules/test_stdmodules.lua @@ -1,65 +1,31 @@ -import("lib.detect.find_tool") -import("core.base.semver") -import("core.tool.toolchain") -import("utils.ci.is_running", {alias = "ci_is_running"}) +inherit("test_base") -function _build() - if ci_is_running() then - os.run("xmake -rvD") - else - os.run("xmake -r") - end - local outdata = os.iorun("xmake") - if outdata then - if outdata:find("compiling") or outdata:find("linking") or outdata:find("generating") then - raise("Modules incremental compilation does not work\n%s", outdata) - end - end -end +CLANG_MIN_VER = "19" +GCC_MIN_VER = "15" +MSVC_MIN_VER = "14.35" -function main(t) - if is_subhost("windows") then - local clang = find_tool("clang", {version = true}) - if clang and clang.version and semver.compare(clang.version, "19.0") >= 0 then - os.exec("xmake clean -a") - os.exec("xmake f --toolchain=clang -c --yes") - _build() - end - local msvc = toolchain.load("msvc") - if msvc and msvc:check() then - local vcvars = msvc:config("vcvars") - if vcvars and vcvars.VCInstallDir and vcvars.VCToolsVersion and semver.compare(vcvars.VCToolsVersion, "14.35") then - local stdmodulesdir = path.join(vcvars.VCInstallDir, "Tools", "MSVC", vcvars.VCToolsVersion, "modules") - if os.isdir(stdmodulesdir) then - os.exec("xmake clean -a") - os.exec("xmake f -c --yes") - _build() - end - end - end - elseif is_subhost("msys") then - local gcc = find_tool("gcc", {version = true}) - if is_host("linux") and gcc and gcc.version and semver.compare(gcc.version, "15.0") >= 0 then - os.exec("xmake f -c -p mingw --yes") - _build() - end - elseif is_host("linux") then -- or is_host("macosx") then - local gcc = find_tool("gcc", {version = true}) - if is_host("linux") and gcc and gcc.version and semver.compare(gcc.version, "15.0") >= 0 then - os.exec("xmake f -c --yes") - _build() - end - local clang = find_tool("clang", {version = true}) - if clang and clang.version and semver.compare(clang.version, "19.0") >= 0 then - local gcc = find_tool("clang", {version = true}) - if gcc and gcc.version and semver.compare(gcc.version, "15.0") >= 0 then - os.exec("xmake clean -a") - os.exec("xmake f --toolchain=clang -c --yes") - _build() - end - os.exec("xmake clean -a") - os.exec("xmake f --toolchain=clang --runtimes=c++_shared -c --yes") - _build() - end +function main(_) + local clang_options = {stdmodule = true, compiler = "clang", version = CLANG_MIN_VER} + -- latest mingw gcc 15.1 is broken + -- error: F:/msys64/mingw64/include/c++/15.1.0/shared_mutex:105:3: error: 'int std::__glibcxx_rwlock_timedrdlock(pthread_rwlock_t*, const timespec*)' exposes TU-local entity 'int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const timespec*)' + -- 105 | __glibcxx_rwlock_timedrdlock (pthread_rwlock_t *__rwlock, + -- | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ + -- In file included from F:/msys64/mingw64/include/c++/15.1.0/x86_64-w64-mingw32/bits/gthr-default.h:35, + -- from F:/msys64/mingw64/include/c++/15.1.0/x86_64-w64-mingw32/bits/gthr.h:157, + -- from F:/msys64/mingw64/include/c++/15.1.0/ext/atomicity.h:37, + -- from F:/msys64/mingw64/include/c++/15.1.0/bits/ios_base.h:41, + -- from F:/msys64/mingw64/include/c++/15.1.0/streambuf:45, + -- from F:/msys64/mingw64/include/c++/15.1.0/bits/streambuf_iterator.h:37, + -- from F:/msys64/mingw64/include/c++/15.1.0/iterator:68, + -- from F:/msys64/mingw64/include/c++/15.1.0/x86_64-w64-mingw32/bits/stdc++.h:56: + -- F:/msys64/mingw64/include/pthread.h:296:28: note: 'int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const timespec*)' declared with internal linkage + -- 296 | WINPTHREAD_RWLOCK_DECL int pthread_rwlock_timedrdlock(pthread_rwlock_t *l, const struct timespec *ts) + -- | ^~~~~~~~~~~~~~~~~~~~~~~~~~ + -- F:/msys64/mingw64/include/c++/15.1.0/shared_mutex:115:3: error: 'int std::__glibcxx_rwlock_timedwrlock(pthread_rwlock_t*, const timespec*)' exposes TU-local entity 'int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const timespec*)' + -- 115 | __glibcxx_rwlock_timedwrlock (pthread_rwlock_t *__rwlock, local gcc_options = {stdmodule = true, compiler = "gcc", version = GCC_MIN_VER} + if is_subhost("msys") then + gcc_options = nil end + local msvc_options = {stdmodule = true, version = MSVC_MIN_VER} + run_tests(clang_options, gcc_options, msvc_options) end diff --git a/xmake/rules/c++/modules/msvc/support.lua b/xmake/rules/c++/modules/msvc/support.lua index 41c5cd44e..c425ce911 100644 --- a/xmake/rules/c++/modules/msvc/support.lua +++ b/xmake/rules/c++/modules/msvc/support.lua @@ -46,11 +46,13 @@ function load(target) local msvc = target:toolchain("msvc") if msvc then local vcvars = msvc:config("vcvars") - if vcvars.VCInstallDir and vcvars.VCToolsVersion and semver.compare(vcvars.VCToolsVersion, "14.35") > 0 then + if vcvars.VCInstallDir and vcvars.VCToolsVersion and semver.compare(vcvars.VCToolsVersion, "14.35") >= 0 then stdmodulesdir = path.join(vcvars.VCInstallDir, "Tools", "MSVC", vcvars.VCToolsVersion, "modules") end end - target:data_set("c++.msvc.enable_std_import", isatleastcpp23 and os.isdir(stdmodulesdir)) + if stdmodulesdir then + target:data_set("c++.msvc.enable_std_import", isatleastcpp23 and os.isdir(stdmodulesdir)) + end end end -- cgit v1.3.1