From 3cb975509bc43a5a92bc3033c11f407d15c98f5d Mon Sep 17 00:00:00 2001 From: ruki Date: Sun, 30 Oct 2022 21:33:24 +0800 Subject: save dependinfo for gcc/modules --- tests/projects/c++/modules/user_headerunit/src/hello.mpp | 3 ++- xmake/rules/c++/modules/modules_support/gcc.lua | 9 +++++++-- 2 files changed, 9 insertions(+), 3 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 +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/rules/c++/modules/modules_support/gcc.lua b/xmake/rules/c++/modules/modules_support/gcc.lua index 20a8437aa..23a63dee8 100644 --- a/xmake/rules/c++/modules/modules_support/gcc.lua +++ b/xmake/rules/c++/modules/modules_support/gcc.lua @@ -349,8 +349,13 @@ function build_modules_for_batchjobs(target, batchjobs, objectfiles, modules, op 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)) + + -- do compile + local dependinfo = {} + local compflags = table.join(compinst:compflags({target = target}), common_args) + assert(compinst:compile(provide.sourcefile, objectfile, {dependinfo = dependinfo, compflags = compflags})) + return dependinfo + end, {dependfile = target:dependfile(bmifile), files = {provide.sourcefile}}) end) if m.requires then -- cgit v1.3.1 From 183157bfed3743ba908f3219179b513a33849508 Mon Sep 17 00:00:00 2001 From: ruki Date: Sun, 30 Oct 2022 23:01:41 +0800 Subject: improve to build module for gcc --- xmake/rules/c++/modules/modules_support/gcc.lua | 54 +++++++++++++++++-------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/xmake/rules/c++/modules/modules_support/gcc.lua b/xmake/rules/c++/modules/modules_support/gcc.lua index 23a63dee8..9ad0c37c8 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,20 +375,10 @@ 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 - - -- do compile - local dependinfo = {} - local compflags = table.join(compinst:compflags({target = target}), common_args) - assert(compinst:compile(provide.sourcefile, objectfile, {dependinfo = dependinfo, compflags = compflags})) - return dependinfo - - end, {dependfile = target:dependfile(bmifile), files = {provide.sourcefile}}) + _build_modulefile(target, provide.sourcefile, { + objectfile = objectfile, + dependfile = target:dependfile(bmifile), + bmifile = bmifile, name = name, progress = (index * 100) / total}) end) if m.requires then moduleinfo.deps = table.keys(m.requires) -- cgit v1.3.1 From aa7c4501a00054a06defc92545109f844588cdb1 Mon Sep 17 00:00:00 2001 From: ruki Date: Mon, 31 Oct 2022 22:47:07 +0800 Subject: generate deps for clang module --- xmake/rules/c++/modules/modules_support/clang.lua | 65 ++++++++++++++++++----- xmake/rules/c++/modules/modules_support/gcc.lua | 3 +- 2 files changed, 53 insertions(+), 15 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 9ad0c37c8..28ece4dd8 100644 --- a/xmake/rules/c++/modules/modules_support/gcc.lua +++ b/xmake/rules/c++/modules/modules_support/gcc.lua @@ -378,7 +378,8 @@ function build_modules_for_batchjobs(target, batchjobs, objectfiles, modules, op _build_modulefile(target, provide.sourcefile, { objectfile = objectfile, dependfile = target:dependfile(bmifile), - bmifile = bmifile, name = name, progress = (index * 100) / total}) + name = name, + progress = (index * 100) / total}) end) if m.requires then moduleinfo.deps = table.keys(m.requires) -- cgit v1.3.1 From 9f242e47e9ad175a073414a3606a193dfe06d8a6 Mon Sep 17 00:00:00 2001 From: ruki Date: Mon, 31 Oct 2022 23:58:37 +0800 Subject: generate includedeps for msvc/modules --- xmake/rules/c++/modules/modules_support/msvc.lua | 69 ++++++++++++++++++------ 1 file changed, 52 insertions(+), 17 deletions(-) diff --git a/xmake/rules/c++/modules/modules_support/msvc.lua b/xmake/rules/c++/modules/modules_support/msvc.lua index 97cc00d9c..560e2cc91 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 -- cgit v1.3.1 From ad6067482d7220a384dc0f5430bb8df1159fec50 Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 1 Nov 2022 00:44:04 +0800 Subject: improve to parse cl deps --- xmake/modules/private/tools/cl/parse_deps_json.lua | 45 ++++++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) 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 -- cgit v1.3.1 From 055c7aa757886af0faa87c21e407495ead4c066e Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 1 Nov 2022 00:46:41 +0800 Subject: sort requires flags --- xmake/rules/c++/modules/modules_support/msvc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xmake/rules/c++/modules/modules_support/msvc.lua b/xmake/rules/c++/modules/modules_support/msvc.lua index 560e2cc91..04ab2bf7a 100644 --- a/xmake/rules/c++/modules/modules_support/msvc.lua +++ b/xmake/rules/c++/modules/modules_support/msvc.lua @@ -683,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 -- cgit v1.3.1 From e639c493025b5d6c5cbdbe588759d34ff8d772b4 Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 1 Nov 2022 22:54:09 +0800 Subject: disable ccache for c++modules --- xmake/modules/core/tools/cl.lua | 3 +- xmake/modules/core/tools/gcc.lua | 5 ++-- xmake/modules/private/action/build/object.lua | 2 +- xmake/modules/private/cache/build_cache.lua | 35 ++++++++++++++++------ .../private/service/distcc_build/client.lua | 4 +-- xmake/rules/c++/modules/xmake.lua | 8 +++++ 6 files changed, 42 insertions(+), 15 deletions(-) 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..897103404 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}) @@ -614,7 +615,7 @@ 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)) 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/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) -- cgit v1.3.1 From a9a1788edab12cd63931278ce8d0e4ed02f5046d Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 2 Nov 2022 00:46:11 +0800 Subject: paser gcc deps with modules --- xmake/modules/core/project/depend.lua | 2 +- xmake/modules/core/tools/gcc.lua | 9 +++++++++ xmake/modules/private/tools/gcc/parse_deps.lua | 26 +++++++++++++++++++++++--- 3 files changed, 33 insertions(+), 4 deletions(-) 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/gcc.lua b/xmake/modules/core/tools/gcc.lua index 897103404..3a916ac9a 100644 --- a/xmake/modules/core/tools/gcc.lua +++ b/xmake/modules/core/tools/gcc.lua @@ -604,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 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? @@ -621,6 +628,7 @@ function compile(self, sourcefile, objectfile, dependinfo, flags, opt) os.mkdir(path.directory(objectfile)) -- compile it + opt = opt or {} local depfile = dependinfo and os.tmpfile() or nil try { @@ -706,6 +714,7 @@ function compile(self, sourcefile, objectfile, dependinfo, flags, opt) 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/tools/gcc/parse_deps.lua b/xmake/modules/private/tools/gcc/parse_deps.lua index 3b682753c..811119a9a 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,25 @@ function main(depsdata) end end end + -- with c++ modules (gcc): + -- CXX_IMPORTS += bar.c++m cat.c++m\ + 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 -- cgit v1.3.1 From accbf055ab1e80233696f2a69c6e7c1e4b10cca5 Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 2 Nov 2022 00:46:40 +0800 Subject: optimize to parse deps --- xmake/modules/core/tools/gcc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xmake/modules/core/tools/gcc.lua b/xmake/modules/core/tools/gcc.lua index 3a916ac9a..a3888ac34 100644 --- a/xmake/modules/core/tools/gcc.lua +++ b/xmake/modules/core/tools/gcc.lua @@ -606,7 +606,7 @@ end -- get modules cache directory function _modules_cachedir(target) - if target and target.autogendir then -- we need ignore option instance + 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 -- cgit v1.3.1 From 3abe482e186a3851f9349d5011e93d8c529de2d8 Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 2 Nov 2022 00:46:48 +0800 Subject: improve comments --- xmake/modules/private/tools/gcc/parse_deps.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xmake/modules/private/tools/gcc/parse_deps.lua b/xmake/modules/private/tools/gcc/parse_deps.lua index 811119a9a..3bc067861 100644 --- a/xmake/modules/private/tools/gcc/parse_deps.lua +++ b/xmake/modules/private/tools/gcc/parse_deps.lua @@ -96,6 +96,8 @@ function main(depsdata, opt) 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] -- cgit v1.3.1