diff options
Diffstat (limited to 'xmake/rules/c++/modules')
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/clang.lua | 65 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/gcc.lua | 50 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/msvc.lua | 71 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/xmake.lua | 8 |
4 files changed, 151 insertions, 43 deletions
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) |
