summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2022-11-01 23:35:02 +0800
committerGitHub <[email protected]>2022-11-01 23:35:02 +0800
commit1912c580ec4f817ef40aa44dc893cbf4c1d8db8e (patch)
tree47d5ff5309a5ed549c9da407189a2001dd3c5575
parente3f66afa1533661eda37f934357623134dd0e467 (diff)
parent3abe482e186a3851f9349d5011e93d8c529de2d8 (diff)
Merge pull request #3001 from xmake-io/modules
Incremental compilation support for modules #3000
-rw-r--r--tests/projects/c++/modules/user_headerunit/src/hello.mpp3
-rw-r--r--xmake/modules/core/project/depend.lua2
-rw-r--r--xmake/modules/core/tools/cl.lua3
-rw-r--r--xmake/modules/core/tools/gcc.lua14
-rw-r--r--xmake/modules/private/action/build/object.lua2
-rw-r--r--xmake/modules/private/cache/build_cache.lua35
-rw-r--r--xmake/modules/private/service/distcc_build/client.lua4
-rw-r--r--xmake/modules/private/tools/cl/parse_deps_json.lua45
-rw-r--r--xmake/modules/private/tools/gcc/parse_deps.lua28
-rw-r--r--xmake/rules/c++/modules/modules_support/clang.lua65
-rw-r--r--xmake/rules/c++/modules/modules_support/gcc.lua50
-rw-r--r--xmake/rules/c++/modules/modules_support/msvc.lua71
-rw-r--r--xmake/rules/c++/modules/xmake.lua8
13 files changed, 264 insertions, 66 deletions
diff --git a/tests/projects/c++/modules/user_headerunit/src/hello.mpp b/tests/projects/c++/modules/user_headerunit/src/hello.mpp
index 5b2f434ad..f2e4022f7 100644
--- a/tests/projects/c++/modules/user_headerunit/src/hello.mpp
+++ b/tests/projects/c++/modules/user_headerunit/src/hello.mpp
@@ -1,10 +1,11 @@
module;
#include <cstdio>
+import "header.hpp";
export module hello;
export namespace hello {
void say(const char *arg) {
- printf("%s\n", arg);
+ printf("%s: %s\n", FOO, arg);
}
}
diff --git a/xmake/modules/core/project/depend.lua b/xmake/modules/core/project/depend.lua
index 632ecd70f..78150c117 100644
--- a/xmake/modules/core/project/depend.lua
+++ b/xmake/modules/core/project/depend.lua
@@ -29,7 +29,7 @@ import("private.tools.armcc.parse_deps", {alias = "parse_deps_armcc"})
-- load depfiles
function _load_depfiles(parser, dependinfo, depfiles)
- depfiles = parser(depfiles)
+ depfiles = parser(depfiles, dependinfo)
if depfiles then
if dependinfo.files then
table.join2(dependinfo.files, depfiles)
diff --git a/xmake/modules/core/tools/cl.lua b/xmake/modules/core/tools/cl.lua
index 31bdce256..7905668a9 100644
--- a/xmake/modules/core/tools/cl.lua
+++ b/xmake/modules/core/tools/cl.lua
@@ -514,6 +514,7 @@ end
-- do compile
function _compile(self, sourcefile, objectfile, compflags, opt)
+ opt = opt or {}
local function _compile_fallback()
local program, argv = compargv(self, sourcefile, objectfile, compflags, opt)
return vstool.iorunv(program, argv, {envs = self:runenvs()})
@@ -524,7 +525,7 @@ function _compile(self, sourcefile, objectfile, compflags, opt)
cppinfo = distcc_build_client.singleton():compile(program, argv, {envs = self:runenvs(),
preprocess = _preprocess, compile = _compile_preprocessed_file, compile_fallback = _compile_fallback,
target = opt.target, tool = self, remote = true})
- elseif build_cache.is_enabled() and build_cache.is_supported(self:kind()) then
+ elseif build_cache.is_enabled(opt.target) and build_cache.is_supported(self:kind()) then
local program, argv = compargv(self, sourcefile, objectfile, compflags, table.join(opt, {rawargs = true}))
cppinfo = build_cache.build(program, argv, {envs = self:runenvs(),
preprocess = _preprocess, compile = _compile_preprocessed_file, compile_fallback = _compile_fallback,
diff --git a/xmake/modules/core/tools/gcc.lua b/xmake/modules/core/tools/gcc.lua
index 1c3a29c01..a3888ac34 100644
--- a/xmake/modules/core/tools/gcc.lua
+++ b/xmake/modules/core/tools/gcc.lua
@@ -555,6 +555,7 @@ end
-- do compile
function _compile(self, sourcefile, objectfile, compflags, opt)
+ opt = opt or {}
local program, argv = compargv(self, sourcefile, objectfile, compflags)
local function _compile_fallback()
return os.iorunv(program, argv, {envs = self:runenvs()})
@@ -564,7 +565,7 @@ function _compile(self, sourcefile, objectfile, compflags, opt)
cppinfo = distcc_build_client.singleton():compile(program, argv, {envs = self:runenvs(),
preprocess = _preprocess, compile = _compile_preprocessed_file, compile_fallback = _compile_fallback,
tool = self, remote = true})
- elseif build_cache.is_enabled() and build_cache.is_supported(self:kind()) then
+ elseif build_cache.is_enabled(opt.target) and build_cache.is_supported(self:kind()) then
cppinfo = build_cache.build(program, argv, {envs = self:runenvs(),
preprocess = _preprocess, compile = _compile_preprocessed_file, compile_fallback = _compile_fallback,
tool = self})
@@ -603,6 +604,13 @@ function _compargv_pch(self, pcheaderfile, pcoutputfile, flags)
return self:program(), table.join("-c", pchflags, "-o", pcoutputfile, pcheaderfile)
end
+-- get modules cache directory
+function _modules_cachedir(target)
+ if target and target.autogendir and target:data("cxx.has_modules") then -- we need ignore option instance
+ return path.join(target:autogendir(), "rules", "modules", "cache")
+ end
+end
+
-- make the compile arguments list
function compargv(self, sourcefile, objectfile, flags)
-- precompiled header?
@@ -614,12 +622,13 @@ function compargv(self, sourcefile, objectfile, flags)
end
-- compile the source file
-function compile(self, sourcefile, objectfile, dependinfo, flags)
+function compile(self, sourcefile, objectfile, dependinfo, flags, opt)
-- ensure the object directory
os.mkdir(path.directory(objectfile))
-- compile it
+ opt = opt or {}
local depfile = dependinfo and os.tmpfile() or nil
try
{
@@ -705,6 +714,7 @@ function compile(self, sourcefile, objectfile, dependinfo, flags)
if depfile and os.isfile(depfile) then
if dependinfo then
dependinfo.depfiles_gcc = io.readfile(depfile, {continuation = "\\"})
+ dependinfo.modules_cachedir = _modules_cachedir(opt.target)
end
-- remove the temporary dependent file
diff --git a/xmake/modules/private/action/build/object.lua b/xmake/modules/private/action/build/object.lua
index a89b149ff..00493cf4d 100644
--- a/xmake/modules/private/action/build/object.lua
+++ b/xmake/modules/private/action/build/object.lua
@@ -67,7 +67,7 @@ function _do_build_file(target, sourcefile, opt)
-- exists ccache or distcc?
-- we just show cache/distc to avoid confusion with third-party ccache/distcc
local prefix = ""
- if build_cache.is_enabled() and build_cache.is_supported(sourcekind) then
+ if build_cache.is_enabled(target) and build_cache.is_supported(sourcekind) then
prefix = "cache "
end
if distcc_build_client.is_distccjob() and distcc_build_client.singleton():has_freejobs() then
diff --git a/xmake/modules/private/cache/build_cache.lua b/xmake/modules/private/cache/build_cache.lua
index 4cb1be5ca..24124417c 100644
--- a/xmake/modules/private/cache/build_cache.lua
+++ b/xmake/modules/private/cache/build_cache.lua
@@ -21,12 +21,23 @@
-- imports
import("core.base.bytes")
import("core.base.hashset")
+import("core.cache.memcache")
import("core.project.config")
import("core.project.policy")
import("core.project.project")
import("private.service.client_config")
import("private.service.remote_cache.client", {alias = "remote_cache_client"})
+-- get memcache
+function _memcache()
+ local cache = _g.memcache
+ if not cache then
+ cache = memcache.cache("build_cache")
+ _g.memcache = cache
+ end
+ return cache
+end
+
-- get exist info
function _get_existinfo()
local existinfo = _g.existinfo
@@ -38,21 +49,27 @@ function _get_existinfo()
end
-- is enabled?
-function is_enabled()
- local build_cache = _g.build_cache
- if build_cache == nil then
- if build_cache == nil and os.isfile(os.projectfile()) then
+function is_enabled(target)
+ local key = tostring(target or "all")
+ local result = _memcache():get2("enabled", key)
+ if result == nil then
+ -- target may be option instance
+ if target and target.policy then
+ result = target:policy("build.ccache")
+ end
+ if result == nil and os.isfile(os.projectfile()) then
local policy = project.policy("build.ccache")
if policy ~= nil then
- build_cache = policy
+ result = policy
end
end
- if build_cache == nil then
- build_cache = config.get("ccache") or false
+ if result == nil then
+ result = config.get("ccache")
end
- _g.build_cache = build_cache
+ result = result or false
+ _memcache():set2("enabled", key)
end
- return build_cache or false
+ return result
end
-- is supported?
diff --git a/xmake/modules/private/service/distcc_build/client.lua b/xmake/modules/private/service/distcc_build/client.lua
index 50bf82f21..38b2145ef 100644
--- a/xmake/modules/private/service/distcc_build/client.lua
+++ b/xmake/modules/private/service/distcc_build/client.lua
@@ -244,7 +244,7 @@ function distcc_build_client:compile(program, argv, opt)
-- get objectfile from the build cache first
local cached = false
local cachekey
- if build_cache.is_enabled() then
+ if build_cache.is_enabled(opt.target) then
cachekey = build_cache.cachekey(program, cppinfo, opt.envs)
local objectfile_cached, objectfile_infofile = build_cache.get(cachekey)
if objectfile_cached then
@@ -341,7 +341,7 @@ function distcc_build_client:compile(program, argv, opt)
else
compile(program, cppinfo, opt)
end
- if build_cache.is_enabled() then
+ if build_cache.is_enabled(opt.target) then
local cachekey = build_cache.cachekey(program, cppinfo, opt.envs)
if cachekey then
local extrainfo
diff --git a/xmake/modules/private/tools/cl/parse_deps_json.lua b/xmake/modules/private/tools/cl/parse_deps_json.lua
index f274dc382..459a8b112 100644
--- a/xmake/modules/private/tools/cl/parse_deps_json.lua
+++ b/xmake/modules/private/tools/cl/parse_deps_json.lua
@@ -80,15 +80,54 @@ function _normailize_dep(dep, projectdir)
end
-- parse depsfiles from string
+--
+--[[
+{
+ "Version": "1.2",
+ "Data": {
+ "Source": "c:\users\ruki\desktop\user_headerunit\src\main.cpp",
+ "ProvidedModule": "",
+ "Includes": [],
+ "ImportedModules": [
+ {
+ "Name": "hello",
+ "BMI": "c:\users\ruki\desktop\user_headerunit\src\hello.ifc"
+ }
+ ],
+ "ImportedHeaderUnits": [
+ {
+ "Header": "c:\users\ruki\desktop\user_headerunit\src\header.hpp",
+ "BMI": "c:\users\ruki\desktop\user_headerunit\src\header.hpp.ifc"
+ }
+ ]
+ }
+}]]
function main(depsdata)
-- decode json data first
depsdata = json.decode(depsdata)
-- get includes
- local includes
- if depsdata and depsdata.Data then
- includes = depsdata.Data.Includes
+ local data
+ if depsdata then
+ data = depsdata.Data
+ end
+ if data then
+ includes = data.Includes
+ for _, item in ipairs(data.ImportedModules) do
+ local bmifile = item.BMI
+ if bmifile then
+ includes = includes or {}
+ table.insert(includes, bmifile)
+ end
+ end
+ for _, item in ipairs(data.ImportedHeaderUnits) do
+ local bmifile = item.BMI
+ if bmifile then
+ includes = includes or {}
+ table.insert(includes, bmifile)
+ end
+ end
end
-- translate it
diff --git a/xmake/modules/private/tools/gcc/parse_deps.lua b/xmake/modules/private/tools/gcc/parse_deps.lua
index 3b682753c..3bc067861 100644
--- a/xmake/modules/private/tools/gcc/parse_deps.lua
+++ b/xmake/modules/private/tools/gcc/parse_deps.lua
@@ -54,7 +54,7 @@ end
-- src/tbox/libc/string/../../prefix/../config.h \
-- build/iphoneos/x86_64/release/tbox.config.h \
--
--- with c++ modules:
+-- with c++ modules (gcc):
-- build/.objs/dependence/linux/x86_64/release/src/foo.mpp.o: src/foo.mpp\
-- build/.objs/dependence/linux/x86_64/release/src/foo.mpp.o gcm.cache/foo.gcm: bar.c++m cat.c++m\
-- foo.c++m: gcm.cache/foo.gcm\
@@ -62,7 +62,7 @@ end
-- gcm.cache/foo.gcm:| build/.objs/dependence/linux/x86_64/release/src/foo.mpp.o\
-- CXX_IMPORTS += bar.c++m cat.c++m\
--
-function main(depsdata)
+function main(depsdata, opt)
-- we assume there is only one valid line
local block = 0
@@ -85,7 +85,7 @@ function main(depsdata)
end
else
includefile = includefile:replace(space_placeholder, ' ', plain)
- includefile = includefile:split("\n", {plain = true})[1]
+ includefile = includefile:split("\n", plain)[1]
if #includefile > 0 then
includefile = _normailize_dep(includefile, projectdir)
if includefile then
@@ -94,5 +94,27 @@ function main(depsdata)
end
end
end
+ -- with c++ modules (gcc):
+ -- CXX_IMPORTS += bar.c++m cat.c++m\
+ --
+ -- @see https://github.com/xmake-io/xmake/issues/3000
+ opt = opt or {}
+ if opt.modules_cachedir and line:find("CXX_IMPORTS += ", 1, true) then
+ local modulefiles = line:split("CXX_IMPORTS += ", plain)[2]
+ if modulefiles then
+ for _, modulefile in ipairs(modulefiles:split(' ', plain)) do
+ modulefile = modulefile:replace(".c++m", ".gcm", plain)
+ if #modulefile > 0 then
+ if not path.is_absolute(modulefile) then
+ modulefile = path.absolute(modulefile, opt.modules_cachedir)
+ end
+ modulefile = _normailize_dep(modulefile, projectdir)
+ if modulefile then
+ results:insert(modulefile)
+ end
+ end
+ end
+ end
+ end
return results:to_array()
end
diff --git a/xmake/rules/c++/modules/modules_support/clang.lua b/xmake/rules/c++/modules/modules_support/clang.lua
index 4eaee0a84..100830046 100644
--- a/xmake/rules/c++/modules/modules_support/clang.lua
+++ b/xmake/rules/c++/modules/modules_support/clang.lua
@@ -19,6 +19,7 @@
--
-- imports
+import("core.base.option")
import("core.tool.compiler")
import("core.project.project")
import("core.project.depend")
@@ -108,6 +109,47 @@ function _get_toolchain_includedirs_for_stlheaders(includedirs, clang)
os.tryrm(tmpfile)
end
+-- build module file
+function _build_modulefile(target, sourcefile, opt)
+ local objectfile = opt.objectfile
+ local dependfile = opt.dependfile
+ local compinst = compiler.load("cxx", {target = target})
+ local compflags = compinst:compflags({target = target})
+ local dependinfo = option.get("rebuild") and {} or (depend.load(dependfile) or {})
+
+ -- need build this object?
+ local dryrun = option.get("dry-run")
+ local depvalues = {compinst:program(), compflags}
+ local lastmtime = os.isfile(objectfile) and os.mtime(dependfile) or 0
+ if not dryrun and not depend.is_changed(dependinfo, {lastmtime = lastmtime, values = depvalues}) then
+ return
+ end
+
+ local bmifile = opt.bmifile
+ local common_args = opt.common_args
+ local requiresflags = opt.requiresflags
+ local bmiflags = table.join("-x", "c++-module", "--precompile", compflags, common_args, requiresflags or {})
+ local objflags = table.join(compflags, common_args, requiresflags or {})
+
+ -- trace
+ progress.show(opt.progress, "${color.build.object}generating.cxx.module.bmi %s", opt.name)
+ vprint(compinst:compcmd(sourcefile, bmifile, {compflags = bmiflags, rawargs = true}))
+ vprint(compinst:compcmd(bmifile, objectfile, {compflags = objflags, rawargs = true}))
+
+ if not dryrun then
+
+ -- do compile
+ dependinfo.files = {}
+ assert(compinst:compile(sourcefile, bmifile, {dependinfo = dependinfo, compflags = bmiflags}))
+ assert(compinst:compile(bmifile, objectfile, {compflags = objflags}))
+
+ -- update files and values to the dependent file
+ dependinfo.values = depvalues
+ table.join2(dependinfo.files, sourcefile)
+ depend.save(dependinfo, dependfile)
+ end
+end
+
-- provide toolchain include directories for stl headerunit when p1689 is not supported
function toolchain_includedirs(target)
local includedirs = _g.includedirs
@@ -369,20 +411,15 @@ function build_modules_for_batchjobs(target, batchjobs, objectfiles, modules, op
requiresflags = get_requiresflags(target, module.requires)
end
- depend.on_changed(function()
- progress.show((index * 100) / total, "${color.build.object}generating.cxx.module.bmi %s", name)
- local bmidir = path.directory(bmifile)
- if not os.isdir(bmidir) then
- os.mkdir(bmidir)
- end
- local objectdir = path.directory(objectfile)
- if not os.isdir(objectdir) then
- os.mkdir(objectdir)
- end
- local args = { "-c", "-x", "c++-module", "--precompile", provide.sourcefile, "-o", bmifile}
- os.vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, requiresflags or {}, args))
- os.vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, requiresflags or {}, {bmifile}, {"-c", "-o", objectfile}))
- end, {dependfile = target:dependfile(bmifile), files = {provide.sourcefile}})
+ _build_modulefile(target, provide.sourcefile, {
+ objectfile = objectfile,
+ dependfile = target:dependfile(bmifile),
+ bmifile = bmifile,
+ name = name,
+ common_args = common_args,
+ requiresflags = requiresflags,
+ progress = (index * 100) / total})
+
_add_module_to_mapper(target, name, bmifile, requiresflags)
end)
if module.requires then
diff --git a/xmake/rules/c++/modules/modules_support/gcc.lua b/xmake/rules/c++/modules/modules_support/gcc.lua
index 20a8437aa..28ece4dd8 100644
--- a/xmake/rules/c++/modules/modules_support/gcc.lua
+++ b/xmake/rules/c++/modules/modules_support/gcc.lua
@@ -19,6 +19,7 @@
--
-- imports
+import("core.base.option")
import("core.tool.compiler")
import("core.project.project")
import("core.project.depend")
@@ -93,6 +94,39 @@ function _get_toolchain_includedirs_for_stlheaders(includedirs, gcc)
os.tryrm(tmpfile)
end
+-- build module file
+function _build_modulefile(target, sourcefile, opt)
+ local objectfile = opt.objectfile
+ local dependfile = opt.dependfile
+ local compinst = compiler.load("cxx", {target = target})
+ local compflags = table.join("-x", "c++", compinst:compflags({target = target}))
+ local dependinfo = option.get("rebuild") and {} or (depend.load(dependfile) or {})
+
+ -- need build this object?
+ local dryrun = option.get("dry-run")
+ local depvalues = {compinst:program(), compflags}
+ local lastmtime = os.isfile(objectfile) and os.mtime(dependfile) or 0
+ if not dryrun and not depend.is_changed(dependinfo, {lastmtime = lastmtime, values = depvalues}) then
+ return
+ end
+
+ -- trace
+ progress.show(opt.progress, "${color.build.object}generating.cxx.module.bmi %s", opt.name)
+ vprint(compinst:compcmd(sourcefile, objectfile, {compflags = compflags, rawargs = true}))
+
+ if not dryrun then
+
+ -- do compile
+ dependinfo.files = {}
+ assert(compinst:compile(sourcefile, objectfile, {dependinfo = dependinfo, compflags = compflags}))
+
+ -- update files and values to the dependent file
+ dependinfo.values = depvalues
+ table.join2(dependinfo.files, sourcefile)
+ depend.save(dependinfo, dependfile)
+ end
+end
+
-- provide toolchain include directories for stl headerunit when p1689 is not supported
function toolchain_includedirs(target)
local includedirs = _g.includedirs
@@ -317,9 +351,7 @@ end
-- build module files for batchjobs
function build_modules_for_batchjobs(target, batchjobs, objectfiles, modules, opt)
- local compinst = target:compiler("cxx")
local mapper_file = _get_module_mapper()
- local common_args = {"-x", "c++"}
local cachedir = common.modules_cachedir(target)
-- build modules
@@ -343,15 +375,11 @@ function build_modules_for_batchjobs(target, batchjobs, objectfiles, modules, op
local bmifile = provide.bmi
local moduleinfo = table.copy(provide)
moduleinfo.job = batchjobs:newjob(provide.sourcefile, function (index, total)
- depend.on_changed(function()
- progress.show((index * 100) / total, "${color.build.object}generating.cxx.module.bmi %s", name)
- local objectdir = path.directory(objectfile)
- if not os.isdir(objectdir) then
- os.mkdir(objectdir)
- end
- local args = {"-o", objectfile, "-c", provide.sourcefile}
- os.vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, args))
- end, {dependfile = target:dependfile(bmifile), files = {provide.sourcefile}})
+ _build_modulefile(target, provide.sourcefile, {
+ objectfile = objectfile,
+ dependfile = target:dependfile(bmifile),
+ name = name,
+ progress = (index * 100) / total})
end)
if m.requires then
moduleinfo.deps = table.keys(m.requires)
diff --git a/xmake/rules/c++/modules/modules_support/msvc.lua b/xmake/rules/c++/modules/modules_support/msvc.lua
index 97cc00d9c..04ab2bf7a 100644
--- a/xmake/rules/c++/modules/modules_support/msvc.lua
+++ b/xmake/rules/c++/modules/modules_support/msvc.lua
@@ -19,6 +19,7 @@
--
-- imports
+import("core.base.option")
import("core.tool.compiler")
import("core.project.project")
import("core.project.depend")
@@ -83,6 +84,46 @@ function _add_objectfile_to_link_arguments(target, objectfile)
common.localcache():save(cachekey)
end
+-- build module file
+function _build_modulefile(target, sourcefile, opt)
+ local objectfile = opt.objectfile
+ local dependfile = opt.dependfile
+ local compinst = compiler.load("cxx", {target = target})
+ local compflags = compinst:compflags({target = target})
+ local dependinfo = option.get("rebuild") and {} or (depend.load(dependfile) or {})
+
+ -- need build this object?
+ local dryrun = option.get("dry-run")
+ local depvalues = {compinst:program(), compflags}
+ local lastmtime = os.isfile(objectfile) and os.mtime(dependfile) or 0
+ if not dryrun and not depend.is_changed(dependinfo, {lastmtime = lastmtime, values = depvalues}) then
+ return
+ end
+
+ -- init flags
+ local requiresflags = opt.requiresflags
+ local interfaceflag = opt.interfaceflag
+ local ifcoutputflag = opt.ifcoutputflag
+ local bmifile = opt.bmifile
+ local flags = table.join("-TP", requiresflags or {}, interfaceflag, ifcoutputflag, bmifile, compflags)
+
+ -- trace
+ progress.show(opt.progress, "${color.build.object}generating.cxx.module.bmi %s", opt.name)
+ vprint(compinst:compcmd(sourcefile, objectfile, {compflags = flags, rawargs = true}))
+
+ if not dryrun then
+
+ -- do compile
+ dependinfo.files = {}
+ assert(compinst:compile(sourcefile, objectfile, {dependinfo = dependinfo, compflags = flags}))
+
+ -- update files and values to the dependent file
+ dependinfo.values = depvalues
+ table.join2(dependinfo.files, sourcefile)
+ depend.save(dependinfo, dependfile)
+ end
+end
+
-- load module support for the current target
function load(target)
-- get flags
@@ -367,7 +408,6 @@ function build_modules_for_batchjobs(target, batchjobs, objectfiles, modules, op
_flush_mapper(target)
end, {rootjob = opt.rootjob})
- local common_flags = {"-TP"}
local modulesjobs = {}
for _, objectfile in ipairs(objectfiles) do
local module = modules[objectfile]
@@ -394,22 +434,17 @@ function build_modules_for_batchjobs(target, batchjobs, objectfiles, modules, op
if module.requires then
requiresflags = get_requiresflags(target, module.requires, {expand = true})
end
- depend.on_changed(function()
- progress.show((index * 100) / total, "${color.build.object}generating.cxx.module.bmi %s", name)
- local objectdir = path.directory(objectfile)
- if not os.isdir(objectdir) then
- os.mkdir(objectdir)
- end
- local flags = {
- "-c",
- "-Fo" .. objectfile,
- interfaceflag,
- ifcoutputflag,
- bmifile,
- provide.sourcefile
- }
- _compile(target, table.join(common_flags, requiresflags or {}, flags))
- end, {dependfile = target:dependfile(bmifile), files = {provide.sourcefile}})
+
+ _build_modulefile(target, provide.sourcefile, {
+ objectfile = objectfile,
+ dependfile = target:dependfile(bmifile),
+ name = name,
+ bmifile = bmifile,
+ requiresflags = requiresflags,
+ interfaceflag = interfaceflag,
+ ifcoutputflag = ifcoutputflag,
+ progress = (index * 100) / total})
+
_add_module_to_mapper(target, referenceflag, name, name, objectfile, bmifile, requiresflags)
end)
if module.requires then
@@ -648,7 +683,7 @@ function get_requiresflags(target, requires, opt)
local flags = {}
local modulemap = _get_modulemap_from_mapper(target)
-- add deps required module flags
- for name, _ in pairs(requires) do
+ for name, _ in table.orderpairs(requires) do
for _, dep in ipairs(target:orderdeps()) do
local modulemap_ = _get_modulemap_from_mapper(dep)
if modulemap_[name] then
diff --git a/xmake/rules/c++/modules/xmake.lua b/xmake/rules/c++/modules/xmake.lua
index 4a7193710..5c90cd3ea 100644
--- a/xmake/rules/c++/modules/xmake.lua
+++ b/xmake/rules/c++/modules/xmake.lua
@@ -36,6 +36,14 @@ rule("c++.build.modules")
-- maybe we will have a more fine-grained configuration strategy to disable it in the future.
target:set("policy", "build.across_targets_in_parallel", false)
+ -- disable ccache for this target
+ --
+ -- Caching can affect incremental compilation, for example
+ -- by interfering with the results of depfile generation for msvc.
+ --
+ -- @see https://github.com/xmake-io/xmake/issues/3000
+ target:set("policy", "build.ccache", false)
+
-- get modules support
local modules_support = common.modules_support(target)