diff --git a/tests/projects/c++/modules/hello_with_pch/test.lua b/tests/projects/c++/modules/hello_with_pch/test.lua
new file mode 100644
index 00000000000..7717f804997
--- /dev/null
+++ b/tests/projects/c++/modules/hello_with_pch/test.lua
@@ -0,0 +1 @@
+inherit(".test_base")
diff --git a/tests/projects/c++/modules/test_pch.lua b/tests/projects/c++/modules/test_pch.lua
deleted file mode 100644
index 98286c2299d..00000000000
--- a/tests/projects/c++/modules/test_pch.lua
+++ /dev/null
@@ -1,31 +0,0 @@
-import("lib.detect.find_tool")
-import("core.base.semver")
-import("detect.sdks.find_vstudio")
-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
-
-function main(t)
- -- TODO c++ modules with pch does not work for gcc now.
- if is_host("linux") then
- local clang = find_tool("clang", {version = true})
- if clang then
- os.exec("xmake f --toolchain=clang -c --yes --policies=build.c++.modules.std:n,build.c++.clang.fallbackscanner")
- _build()
- end
- else
- _build()
- end
-end
diff --git a/xmake/modules/core/project/depend.lua b/xmake/modules/core/project/depend.lua
index 05b93acf148..ca213d97554 100644
--- a/xmake/modules/core/project/depend.lua
+++ b/xmake/modules/core/project/depend.lua
@@ -70,6 +70,8 @@ end
-- show diagnosis info?
function _is_show_diagnosis_info()
+ return true
+ --[[
local show = _g.is_show_diagnosis_info
if show == nil then
if project.policy("diagnosis.check_build_deps") then
@@ -79,7 +81,7 @@ function _is_show_diagnosis_info()
end
_g.is_show_diagnosis_info = show
end
- return show
+ return show]]
end
-- save dependent info to file
diff --git a/xmake/modules/core/tools/gcc.lua b/xmake/modules/core/tools/gcc.lua
index 059eb5977cc..3de17be4a42 100644
--- a/xmake/modules/core/tools/gcc.lua
+++ b/xmake/modules/core/tools/gcc.lua
@@ -31,6 +31,7 @@ import("core.language.language")
import("utils.progress")
import("private.cache.build_cache")
import("private.service.distcc_build.client", {alias = "distcc_build_client"})
+import("rules.c++.modules.modules_support.compiler_support", {rootdir = os.programdir()})
function init(self)
@@ -864,24 +865,35 @@ function _compile(self, sourcefile, objectfile, compflags, opt)
end
end
--- make the compile arguments list for the precompiled header
-function _compargv_pch(self, pcheaderfile, pcoutputfile, flags, opt)
-
- -- remove "-include xxx.h" and "-include-pch xxx.pch"
- local pchflags = {}
+-- remove "-include xxx.h" and "-include-pch xxx.pch"
+function _remove_flags_for_pch(self, flags, opt)
+ opt = opt or {}
+ local result = {}
local include = false
+ local pchfile = opt.pchfile
for _, flag in ipairs(flags) do
+ local inserted = false
if not flag:startswith("-include") then
if not include then
- table.insert(pchflags, flag)
+ inserted = true
end
include = false
else
include = true
end
+ if pchfile and flag:startswith("-fmodules") then
+ inserted = false
+ end
+ if inserted then
+ table.insert(result, flag)
+ end
end
+ return result
+end
- -- set the language of precompiled header?
+-- make the compile arguments list for the precompiled header
+function _translate_flags_for_pch(self, flags)
+ local pchflags = _remove_flags_for_pch(self, flags, {pchfile = true})
if self:kind() == "cxx" then
table.insert(pchflags, "-x")
table.insert(pchflags, "c++-header")
@@ -895,19 +907,24 @@ function _compargv_pch(self, pcheaderfile, pcoutputfile, flags, opt)
table.insert(pchflags, "-x")
table.insert(pchflags, "objective-c-header")
end
+ return pchflags
+end
- -- make the compile arguments list
- local argv = table.join("-c", pchflags, "-o", pcoutputfile, pcheaderfile)
- return self:program(), argv
+-- remove the force includes for c++modules
+-- @see https://github.com/xmake-io/xmake/issues/4051#issuecomment-2795707800
+function _translate_flags_for_mpp(self, flags)
+ return _remove_flags_for_pch(self, flags)
end
-- make the compile arguments list
function compargv(self, sourcefile, objectfile, flags, opt)
- -- precompiled header?
+ -- is precompiled header or module files? remove the force includes.
local extension = path.extension(sourcefile)
if (extension:startswith(".h") or extension == ".inl") then
- return _compargv_pch(self, sourcefile, objectfile, flags, opt)
+ flags = _translate_flags_for_pch(self, flags)
+ elseif compiler_support.has_module_extension(sourcefile, {extension = extension}) then
+ flags = _translate_flags_for_mpp(self, flags)
end
local argv = table.join("-c", flags, "-o", objectfile, sourcefile)
diff --git a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua
index b69826694e0..9b0846930d1 100644
--- a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua
+++ b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua
@@ -30,6 +30,7 @@ import("detect.sdks.find_cuda")
import("vsfile")
import("vsutils")
import("private.utils.toolchain", {alias = "toolchain_utils"})
+import("rules.c++.modules.modules_support.compiler_support", {rootdir = os.programdir()})
function _make_dirs(dir, vcxprojdir)
dir = dir:trim()
@@ -132,12 +133,6 @@ function _split_gpucodes(flag)
return flag:split(",")
end
--- is module file?
-function _is_modulefile(sourcefile)
- local extension = path.extension(sourcefile)
- return extension == ".mpp" or extension == ".mxx" or extension == ".cppm" or extension == ".ixx"
-end
-
-- make compiling command
function _make_compcmd(compargv, sourcefile, objectfile, vcxprojdir)
local argv = {}
@@ -1179,7 +1174,7 @@ function _make_source_file_forall(vcxprojfile, vsinfo, target, sourcefile, sourc
else
-- compile as c++ modules
- if _is_modulefile(sourcefile) then
+ if compiler_support.has_module_extension(sourcefile) then
vcxprojfile:print("CompileAsCppModule")
end
@@ -1316,7 +1311,7 @@ function _make_source_file_forspec(vcxprojfile, vsinfo, target, sourcefile, sour
-- for *.c/cpp/cu files
else
-- compile as c++ modules
- if _is_modulefile(sourcefile) then
+ if compiler_support.has_module_extension(sourcefile) then
vcxprojfile:print("CompileAsCppModule")
end
diff --git a/xmake/rules/c++/modules/modules_support/builder.lua b/xmake/rules/c++/modules/modules_support/builder.lua
index 7ec120cc96f..a02e1e7d36f 100644
--- a/xmake/rules/c++/modules/modules_support/builder.lua
+++ b/xmake/rules/c++/modules/modules_support/builder.lua
@@ -48,8 +48,9 @@ function _build_modules(target, sourcebatch, modules, opt)
-- we need to use the full path as dep name if requre item is headerunit
local dep = name
if req.method:startswith("include-") and req.path then
- dep = path.normalize(req.path)
+ dep = req.path
end
+ dep = path.normalize(dep)
local depname = target:fullname() .. "/module/" .. dep
table.insert(deps, depname)
end
@@ -279,7 +280,7 @@ function build_modules_for_batchjobs(target, batchjobs, sourcebatch, modules, op
-- add module jobs
_build_modules(target, sourcebatch, modules, table.join(opt, {
build_module = function(deps, module, name, objectfile, cppfile)
- local job_name = target:fullname() .. "/module/" .. (name or cppfile)
+ local job_name = target:fullname() .. "/module/" .. path.normalize(name or cppfile)
modulesjobs[job_name] = _builder(target).make_module_buildjobs(target, batchjobs, job_name, deps,
{module = module, objectfile = objectfile, cppfile = cppfile})
end
@@ -306,7 +307,7 @@ function build_modules_for_jobgraph(target, jobgraph, sourcebatch, modules, opt)
-- add module jobs
_build_modules(target, sourcebatch, modules, table.join(opt, {
build_module = function(deps, module, name, objectfile, cppfile)
- local jobname = target:fullname() .. "/module/" .. (name or cppfile)
+ local jobname = target:fullname() .. "/module/" .. path.normalize(name or cppfile)
_builder(target).make_module_jobgraph(target, jobgraph, {
module = module, objectfile = objectfile, cppfile = cppfile
})
@@ -355,7 +356,7 @@ function build_headerunits_for_batchjobs(target, batchjobs, sourcebatch, modules
local modulesjobs = {}
_build_headerunits(target, headerunits, table.join(opt, {
build_headerunit = function(headerunit, key, bmifile, outputdir, build)
- local job_name = target:fullname() .. "/module/" .. key
+ local job_name = target:fullname() .. "/module/" .. path.normalize(key)
local job = _builder(target).make_headerunit_buildjobs(target, job_name, batchjobs, headerunit, bmifile, outputdir, table.join(opt, {build = build}))
if job then
modulesjobs[job_name] = job
@@ -392,7 +393,7 @@ function build_headerunits_for_jobgraph(target, jobgraph, sourcebatch, modules,
local modulesjobs = {}
_build_headerunits(target, headerunits, table.join(opt, {
build_headerunit = function(headerunit, key, bmifile, outputdir, build)
- local job_name = target:fullname() .. "/module/" .. key
+ local job_name = target:fullname() .. "/module/" .. path.normalize(key)
_builder(target).make_headerunit_jobgraph(target,
job_name, jobgraph, headerunit, bmifile, outputdir, table.join(opt, {build = build}))
end
diff --git a/xmake/rules/c++/modules/modules_support/compiler_support.lua b/xmake/rules/c++/modules/modules_support/compiler_support.lua
index eed30a32054..554b536cf9e 100644
--- a/xmake/rules/c++/modules/modules_support/compiler_support.lua
+++ b/xmake/rules/c++/modules/modules_support/compiler_support.lua
@@ -82,13 +82,14 @@ function get_bmi_path(bmifile)
end
-- has module extension? e.g. *.mpp, ...
-function has_module_extension(sourcefile)
+function has_module_extension(sourcefile, opt)
+ opt = opt or {}
local modulexts = _g.modulexts
if modulexts == nil then
modulexts = hashset.of(".mpp", ".mxx", ".cppm", ".ixx")
_g.modulexts = modulexts
end
- local extension = path.extension(sourcefile)
+ local extension = opt.extension or path.extension(sourcefile)
return modulexts:has(extension:lower())
end