diff options
| author | ruki <[email protected]> | 2022-08-09 00:27:34 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2022-08-08 20:47:14 +0800 |
| commit | bd1263aa60a502120e06eb3fd077d69c689dc5d7 (patch) | |
| tree | d67227fd3de5875639f11174e258cd52095f6c91 /xmake/rules/c++/modules/modules_support | |
| parent | 3619f16ac27d39bc77a108244ab6b85f3e404c70 (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.lua | 41 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/gcc.lua | 55 |
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 |
