diff options
Diffstat (limited to 'tests/projects')
7 files changed, 143 insertions, 9 deletions
diff --git a/tests/projects/c++/modules/precompile_reduced_bmi/src/base.mpp b/tests/projects/c++/modules/precompile_reduced_bmi/src/base.mpp new file mode 100644 index 000000000..e3e6224f2 --- /dev/null +++ b/tests/projects/c++/modules/precompile_reduced_bmi/src/base.mpp @@ -0,0 +1,5 @@ +export module base; + +export int base_value() { + return 40; +} diff --git a/tests/projects/c++/modules/precompile_reduced_bmi/src/hello.mpp b/tests/projects/c++/modules/precompile_reduced_bmi/src/hello.mpp new file mode 100644 index 000000000..9de491171 --- /dev/null +++ b/tests/projects/c++/modules/precompile_reduced_bmi/src/hello.mpp @@ -0,0 +1,7 @@ +export module hello; + +import base; + +export int answer() { + return base_value() + 2; +} diff --git a/tests/projects/c++/modules/precompile_reduced_bmi/src/main.cpp b/tests/projects/c++/modules/precompile_reduced_bmi/src/main.cpp new file mode 100644 index 000000000..75adbd883 --- /dev/null +++ b/tests/projects/c++/modules/precompile_reduced_bmi/src/main.cpp @@ -0,0 +1,5 @@ +import hello; + +int main() { + return answer() == 42 ? 0 : 1; +} diff --git a/tests/projects/c++/modules/precompile_reduced_bmi/test.lua b/tests/projects/c++/modules/precompile_reduced_bmi/test.lua new file mode 100644 index 000000000..765290f7b --- /dev/null +++ b/tests/projects/c++/modules/precompile_reduced_bmi/test.lua @@ -0,0 +1,107 @@ +inherit(".test_base") +import("core.base.json") + +local _CLANG_MIN_VER = "23" + +function clang_min_ver() + return _CLANG_MIN_VER +end + +function _check_commands(config, outdata) + local has_precompile_reduced_bmi = outdata:find("--precompile-reduced-bmi", 1, true) ~= nil + local expect_precompile_reduced_bmi = config.precompile_reduced_bmi and config.two_phases + assert(has_precompile_reduced_bmi == expect_precompile_reduced_bmi, + "unexpected --precompile-reduced-bmi usage\n%s", outdata) + + if config.two_phases then + local object_command + for _, line in ipairs(outdata:split("\n", {plain = true})) do + if line:find("hello.mpp", 1, true) and + (line:find("hello.mpp.o", 1, true) or line:find("hello.mpp.obj", 1, true)) and + line:find(" -c ", 1, true) and + not line:find("clang-scan-deps", 1, true) and + not line:find("--precompile", 1, true) then + object_command = line + break + end + end + assert(object_command, "module object command missing\n%s", outdata) + local consumes_bmi = object_command:find("hello.pcm", 1, true) ~= nil + assert(consumes_bmi ~= expect_precompile_reduced_bmi, "unexpected module object input\n%s", outdata) + end +end + +function _check_incremental() + local outdata = os.iorun("xmake -v") + 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 + +function _check_compile_commands(config) + os.run("xmake project -k compile_commands") + local bmi_command + local object_command + for _, command in ipairs(assert(json.loadfile("compile_commands.json"))) do + if command.file:endswith("hello.mpp") then + local commandline = command.command or table.concat(command.arguments or {}, " ") + if commandline:find("--precompile", 1, true) then + bmi_command = commandline + elseif commandline:find("hello.mpp.o", 1, true) or commandline:find("hello.mpp.obj", 1, true) then + object_command = commandline + end + end + end + assert(bmi_command, "module BMI command missing from compile_commands.json") + assert(object_command, "module object command missing from compile_commands.json") + local expect_precompile_reduced_bmi = config.precompile_reduced_bmi and config.two_phases + assert((bmi_command:find("--precompile-reduced-bmi", 1, true) ~= nil) == expect_precompile_reduced_bmi, + "unexpected module BMI command\n%s", bmi_command) + assert(object_command:find("hello.mpp", 1, true) and not object_command:find("hello.pcm", 1, true), + "unexpected module object command\n%s", object_command) +end + +function _configure(config) + local argv = {"f", "--yes", "--toolchain=" .. config.toolchain} + if config.platform then + table.join2(argv, {"-p", config.platform}) + end + if config.runtimes then + table.insert(argv, "--runtimes=" .. config.runtimes) + end + local policies = "--policies=build.c++.modules.std:" .. (config.stdmodule and "y" or "n") + policies = policies .. ",build.c++.modules.fallbackscanner:" .. (config.fallbackscanner and "y" or "n") + policies = policies .. ",build.c++.modules.two_phases:" .. (config.two_phases and "y" or "n") + policies = policies .. ",build.c++.modules.clang.precompile_reduced_bmi:" .. (config.precompile_reduced_bmi and "y" or "n") + table.insert(argv, policies) + table.join2(argv, config.flags or {}) + os.execv("xmake", argv) +end + +function _check_build(config) + local outdata = os.iorun("xmake -rv") + _check_commands(config, outdata) + + os.run("xmake run") + _check_incremental() + if config.two_phases then + _check_compile_commands(config) + end + + if config.two_phases then + local toggled_config = table.clone(config) + toggled_config.precompile_reduced_bmi = not config.precompile_reduced_bmi + _configure(toggled_config) + local toggled_outdata = os.iorun("xmake -v") + _check_commands(toggled_config, toggled_outdata) + os.run("xmake run") + _check_incremental() + _check_compile_commands(toggled_config) + end +end + +function main(_) + run_tests({compiler = "clang", version = clang_min_ver(), precompile_reduced_bmi = true, build = _check_build}) +end diff --git a/tests/projects/c++/modules/precompile_reduced_bmi/xmake.lua b/tests/projects/c++/modules/precompile_reduced_bmi/xmake.lua new file mode 100644 index 000000000..0aa2dc516 --- /dev/null +++ b/tests/projects/c++/modules/precompile_reduced_bmi/xmake.lua @@ -0,0 +1,6 @@ +add_rules("mode.release", "mode.debug") +set_languages("c++20") + +target("precompile_reduced_bmi") + set_kind("binary") + add_files("src/*.cpp", "src/*.mpp") diff --git a/tests/projects/c++/modules/stdmodules_deps/src/bar.mpp b/tests/projects/c++/modules/stdmodules_deps/src/bar.mpp index 001cd7c2d..ab104076c 100644 --- a/tests/projects/c++/modules/stdmodules_deps/src/bar.mpp +++ b/tests/projects/c++/modules/stdmodules_deps/src/bar.mpp @@ -4,11 +4,9 @@ import std; export auto my_sum2(std::size_t a, std::size_t b) -> std::size_t; -#if defined(__GNUC__) && !defined(__clang__) -inline -#else -module :private; -#endif - auto my_sum2(std::size_t a, std::size_t b) -> std::size_t { +// Clang 23 implements P1857R3, which rejects module directives controlled by +// preprocessing conditionals. This test therefore uses an inline definition. +// See https://wg21.link/P1857R3 +inline auto my_sum2(std::size_t a, std::size_t b) -> std::size_t { return a + a + b + b; } diff --git a/tests/projects/c++/modules/test_base.lua b/tests/projects/c++/modules/test_base.lua index 372229695..2d0fa3f57 100644 --- a/tests/projects/c++/modules/test_base.lua +++ b/tests/projects/c++/modules/test_base.lua @@ -103,6 +103,9 @@ function build_tests(toolchain_name, opt) 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") policies = policies .. ",build.c++.modules.two_phases:" .. (two_phases and "y" or "n") + if opt.precompile_reduced_bmi ~= nil then + policies = policies .. ",build.c++.modules.clang.precompile_reduced_bmi:" .. (opt.precompile_reduced_bmi and "y" or "n") + end local platform = " " if opt.platform then @@ -127,7 +130,7 @@ function build_tests(toolchain_name, opt) os.exec("xmake clean -a") os.exec("xmake f" .. platform .. "--toolchain=" .. toolchain_name .. runtimes .. "-c --yes " .. policies .. flags) if opt.build then - opt.build() + opt.build(table.join(opt, {toolchain = toolchain_name, two_phases = two_phases})) else _build(opt.check_outdata) end @@ -150,9 +153,12 @@ function run_tests(clang_options, gcc_options, msvc_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() + local clang_cl_minver = clang_cl_min_ver() + if semver.compare(clang_cl_options.version, clang_cl_minver) < 0 then + clang_cl_options.version = clang_cl_minver + end build_tests("clang-cl", clang_cl_options) - build_tests("clang-cl", table.join(clang_options, {two_phases = false})) + build_tests("clang-cl", table.join(clang_cl_options, {two_phases = false})) end if clang_options.stdmodule then wprint("std modules tests skipped for Windows clang libc++ as it's not currently supported officially") |
