summaryrefslogtreecommitdiff
path: root/xmake/rules/c++/modules/modules_support
diff options
context:
space:
mode:
authorruki <[email protected]>2022-08-09 00:27:34 +0800
committerruki <[email protected]>2022-08-08 20:47:14 +0800
commitbd1263aa60a502120e06eb3fd077d69c689dc5d7 (patch)
treed67227fd3de5875639f11174e258cd52095f6c91 /xmake/rules/c++/modules/modules_support
parent3619f16ac27d39bc77a108244ab6b85f3e404c70 (diff)
build batchjobs modules for gcc
Diffstat (limited to 'xmake/rules/c++/modules/modules_support')
-rw-r--r--xmake/rules/c++/modules/modules_support/common.lua41
-rw-r--r--xmake/rules/c++/modules/modules_support/gcc.lua55
2 files changed, 90 insertions, 6 deletions
diff --git a/xmake/rules/c++/modules/modules_support/common.lua b/xmake/rules/c++/modules/modules_support/common.lua
index ee1016d68..31ab47a81 100644
--- a/xmake/rules/c++/modules/modules_support/common.lua
+++ b/xmake/rules/c++/modules/modules_support/common.lua
@@ -469,6 +469,46 @@ function generate_headerunits_for_batchcmds(target, batchcmds, sourcebatch, modu
end
end
+-- build batch jobs for module dependencies
+function _build_batchjobs_for_moduledeps(modules, batchjobs, rootjob, jobrefs, moduleinfo)
+ local targetjob_ref = jobrefs[moduleinfo.name]
+ if targetjob_ref then
+ batchjobs:add(targetjob_ref, rootjob)
+ else
+ local modulejob = batchjobs:add(moduleinfo.job, rootjob)
+ if modulejob then
+ jobrefs[moduleinfo.name] = modulejob
+ for _, depname in ipairs(moduleinfo.deps) do
+ local dep = modules[depname]
+ if dep then -- maybe nil, e.g. `import <string>;`
+ _build_batchjobs_for_moduledeps(modules, batchjobs, modulejob, jobrefs, dep)
+ end
+ end
+ end
+ end
+end
+
+-- build batchjobs for modules
+function build_batchjobs_for_modules(modules, batchjobs, rootjob)
+ local depset = hashset.new()
+ for _, moduleinfo in pairs(modules) do
+ assert(moduleinfo.job)
+ for _, depname in ipairs(moduleinfo.deps) do
+ depset:insert(depname)
+ end
+ end
+ local modules_root = {}
+ for _, moduleinfo in pairs(modules) do
+ if not depset:has(moduleinfo.name) then
+ table.insert(modules_root, moduleinfo)
+ end
+ end
+ local jobrefs = {}
+ for _, moduleinfo in pairs(modules_root) do
+ _build_batchjobs_for_moduledeps(modules, batchjobs, rootjob, jobrefs, moduleinfo)
+ end
+end
+
-- build modules for batchjobs
function build_modules_for_batchjobs(target, batchjobs, sourcebatch, modules, opt)
local objectfiles = sort_modules_by_dependencies(sourcebatch.objectfiles, modules)
@@ -481,6 +521,7 @@ function build_modules_for_batchcmds(target, batchcmds, sourcebatch, modules, op
modules_support(target).build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, opt)
end
+-- append headerunits objectfiles to link
function append_headerunits_objectfiles(target)
local cache = localcache():get("headerunit_objectfiles") or {}
if target:is_binary() then
diff --git a/xmake/rules/c++/modules/modules_support/gcc.lua b/xmake/rules/c++/modules/modules_support/gcc.lua
index 8f3bacf72..e62721cf3 100644
--- a/xmake/rules/c++/modules/modules_support/gcc.lua
+++ b/xmake/rules/c++/modules/modules_support/gcc.lua
@@ -299,10 +299,55 @@ end
-- build module files for batchjobs
function build_modules_for_batchjobs(target, batchjobs, objectfiles, modules, opt)
- batchjobs:addjob("TODO", function (index, total)
- -- TODO
- raise("build modules not supported!")
- end, {rootjob = opt.rootjob})
+ local compinst = target:compiler("cxx")
+ local mapper_file = _get_module_mapper()
+ local common_args = {"-x", "c++"}
+ local cachedir = common.modules_cachedir(target)
+
+ -- build modules
+ local projectdir = os.projectdir()
+ local depmtime = 0
+ local provided_modules = {}
+ for _, objectfile in ipairs(objectfiles) do
+ local m = modules[objectfile]
+ if m and m.provides then
+ -- assume there that provides is only one, until we encounter the case
+ local length = 0
+ local name, provide
+ for k, v in pairs(m.provides) do
+ length = length + 1
+ name = k
+ provide = v
+ if length > 1 then
+ raise("multiple provides are not supported now!")
+ end
+ end
+
+ local bmifile = provide.bmi
+ local moduleinfo = table.copy(provide)
+ moduleinfo.job = batchjobs:newjob(provide.sourcefile, function (index, total)
+ depend.on_changed(function()
+ local args = {"-o", objectfile, "-c", provide.sourcefile}
+ 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
+ os.vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, args))
+ end, {dependfile = target:dependfile(bmifile), files = {provide.sourcefile}})
+ end)
+ if m.requires then
+ moduleinfo.deps = table.keys(m.requires)
+ end
+ moduleinfo.name = name
+ provided_modules[name] = moduleinfo
+ _add_module_to_mapper(mapper_file, name, path.absolute(bmifile, projectdir))
+ target:add("objectfiles", objectfile)
+ end
+ end
+
+ -- build batchjobs for modules
+ common.build_batchjobs_for_modules(provided_modules, batchjobs, opt.rootjob)
end
-- build module files for batchcmds
@@ -310,8 +355,6 @@ function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, op
local compinst = target:compiler("cxx")
local mapper_file = _get_module_mapper()
local common_args = {"-x", "c++"}
-
- -- get cachedirs
local cachedir = common.modules_cachedir(target)
-- build modules