summaryrefslogtreecommitdiff
path: root/xmake/rules/c++/modules/modules_support
diff options
context:
space:
mode:
authorruki <[email protected]>2023-01-24 21:23:17 +0800
committerGitHub <[email protected]>2023-01-24 21:23:17 +0800
commitb6632b7fca968b1efaa86093d8aa345230dbdf3e (patch)
tree1ce85310576cf13d53737fdd152e6d0c585cf7ba /xmake/rules/c++/modules/modules_support
parent25488d9dd995bf95fafc4153b6c7bdba15334164 (diff)
parent924403375684235e1f34f3b6b2210cc5cda1feb5 (diff)
Merge pull request #3310 from Arthapz/improve-module-compilation
Improve module compilation
Diffstat (limited to 'xmake/rules/c++/modules/modules_support')
-rw-r--r--xmake/rules/c++/modules/modules_support/clang.lua46
-rw-r--r--xmake/rules/c++/modules/modules_support/common.lua75
-rw-r--r--xmake/rules/c++/modules/modules_support/gcc.lua63
-rw-r--r--xmake/rules/c++/modules/modules_support/msvc.lua39
4 files changed, 91 insertions, 132 deletions
diff --git a/xmake/rules/c++/modules/modules_support/clang.lua b/xmake/rules/c++/modules/modules_support/clang.lua
index a6e195e22..320061e1a 100644
--- a/xmake/rules/c++/modules/modules_support/clang.lua
+++ b/xmake/rules/c++/modules/modules_support/clang.lua
@@ -226,7 +226,7 @@ function toolchain_includedirs(target)
if includedirs == nil then
includedirs = {}
local clang, toolname = target:tool("cxx")
- assert(toolname == "clang")
+ assert(toolname:startswith("clang"))
_get_toolchain_includedirs_for_stlheaders(target, includedirs, clang)
local _, result = try {function () return os.iorunv(clang, {"-E", "-stdlib=libc++", "-Wp,-v", "-xc", os.nuldev()}) end}
if result then
@@ -247,8 +247,6 @@ end
-- generate dependency files
function generate_dependencies(target, sourcebatch, opt)
local changed = false
- local cachedir = common.modules_cachedir(target)
- local projectdir = os.projectdir()
for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
local dependfile = target:dependfile(sourcefile)
depend.on_changed(function()
@@ -256,11 +254,7 @@ function generate_dependencies(target, sourcebatch, opt)
progress.show(opt.progress, "${color.build.object}generating.module.deps %s", sourcefile)
end
- local outputdir = path.translate(path.join(cachedir, path.directory(path.relative(sourcefile, projectdir))))
- if not os.isdir(outputdir) then
- os.mkdir(outputdir)
- end
-
+ local outputdir = common.get_outputdir(target, sourcefile)
local jsonfile = path.translate(path.join(outputdir, path.filename(sourcefile) .. ".json"))
if has_clangscandepssupport(target) and not target:policy("build.c++.clang.fallbackscanner") then
local clangscandeps = find_tool("clang-scan-deps")
@@ -277,14 +271,10 @@ function generate_dependencies(target, sourcebatch, opt)
common.fallback_generate_dependencies(target, jsonfile, sourcefile, function(file)
local compinst = target:compiler("cxx")
local compflags = compinst:compflags({sourcefile = file, target = target})
- local flags = {}
- for _, flag in pairs(compflags) do
- if flag:startswith("-stdlib") or (flag:startswith("-f") and not flag:startswith("-fmodules")) or flag:startswith("-D") or flag:startswith("-U") or flag:startswith("-I") or flag:startswith("-isystem") then
- table.insert(flags, flag)
- end
- end
+ -- exclude -fmodule* and -std=c++/gnu++* flags because, when they are set clang try to find bmi of imported modules but they don't exists a this point of compilation
+ compflags = table.remove_if(compflags, function(_, flag) return flag:startswith("-fmodule") or flag:startswith("-std=c++") or flag:startswith("-std=gnu++") end)
local ifile = path.translate(path.join(outputdir, path.filename(file) .. ".i"))
- os.vrunv(compinst:program(), table.join(flags, {"-E", "-x", "c++", file, "-o", ifile}))
+ os.vrunv(compinst:program(), table.join(compflags, {"-E", "-x", "c++", file, "-o", ifile}))
local content = io.readfile(ifile)
os.rm(ifile)
return content
@@ -401,7 +391,7 @@ function generate_user_headerunits_for_batchjobs(target, batchjobs, headerunits,
assert(has_headerunitsupport(target), "compiler(clang): does not support c++ header units!")
-- get cachedirs
- local cachedir = common.modules_cachedir(target)
+ local cachedir = common.modules_cachedir(target, {mkdir = true})
local modulecachepathflag = get_modulecachepathflag(target)
-- flush job
@@ -410,19 +400,13 @@ function generate_user_headerunits_for_batchjobs(target, batchjobs, headerunits,
end, {rootjob = opt.rootjob})
-- build headerunits
- local projectdir = os.projectdir()
for _, headerunit in ipairs(headerunits) do
local file = path.relative(headerunit.path, target:scriptdir())
local objectfile = target:objectfile(file)
- local outputdir
- if headerunit.type == ":quote" then
- outputdir = path.join(cachedir, path.directory(path.relative(headerunit.path, projectdir)))
- else
- outputdir = path.join(cachedir, path.directory(headerunit.path))
- end
+ local outputdir = common.get_outputdir(target, headerunit.path)
local bmifilename = path.basename(objectfile) .. get_bmi_extension()
- local bmifile = (outputdir and path.join(outputdir, bmifilename) or bmifilename)
+ local bmifile = path.join(outputdir, bmifilename)
batchjobs:addjob(headerunit.name, function (index, total)
depend.on_changed(function()
progress.show((index * 100) / total, "${color.build.object}compiling.headerunit.$(mode) %s", headerunit.name)
@@ -454,22 +438,16 @@ function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits,
assert(has_headerunitsupport(target), "compiler(clang): does not support c++ header units!")
-- get cachedirs
- local cachedir = common.modules_cachedir(target)
+ local cachedir = common.modules_cachedir(target, {mkdir = true})
local modulecachepathflag = get_modulecachepathflag(target)
-- build headerunits
- local projectdir = os.projectdir()
local depmtime = 0
for _, headerunit in ipairs(headerunits) do
local file = path.relative(headerunit.path, target:scriptdir())
local objectfile = target:objectfile(file)
- local outputdir
- if headerunit.type == ":quote" then
- outputdir = path.join(cachedir, path.directory(path.relative(headerunit.path, projectdir)))
- else
- outputdir = path.join(cachedir, path.directory(headerunit.path))
- end
+ local outputdir = common.get_outputdir(target, headerunit.path)
batchcmds:mkdir(outputdir)
local bmifilename = path.basename(objectfile) .. get_bmi_extension()
@@ -535,8 +513,8 @@ function build_modules_for_batchjobs(target, batchjobs, objectfiles, modules, op
local fileconfig = target:fileconfig(cppfile)
if fileconfig and fileconfig.install then
batchjobs:addjob(name .. "_metafile", function(index, total)
- local cachedir = common.modules_cachedir(target)
- local metafilepath = path.join(cachedir, path.filename(cppfile) .. ".meta-info")
+ local outputdir = common.get_outputdir(target, cppfile)
+ local metafilepath = path.join(outputdir, path.filename(cppfile) .. ".meta-info")
depend.on_changed(function()
progress.show(opt.progress, "${color.build.object}generating.module.metadata %s", name)
local metadata = common.generate_meta_module_info(target, name, cppfile, module.requires)
diff --git a/xmake/rules/c++/modules/modules_support/common.lua b/xmake/rules/c++/modules/modules_support/common.lua
index 32c1b7be8..7a43cd5f2 100644
--- a/xmake/rules/c++/modules/modules_support/common.lua
+++ b/xmake/rules/c++/modules/modules_support/common.lua
@@ -20,6 +20,7 @@
-- imports
import("core.base.json")
+import("core.base.bytes")
import("core.base.hashset")
import("core.project.config")
import("core.tool.compiler")
@@ -43,7 +44,7 @@ end
-- get stl modules cache directory
function stlmodules_cachedir(target, opt)
opt = opt or {}
- local stlcachedir = path.join(config.buildir(), "stlmodules", "cache")
+ local stlcachedir = path.join(config.buildir(), "stlmodules", "cache", config.mode() or "release")
if opt.mkdir and not os.isdir(stlcachedir) then
os.mkdir(stlcachedir)
os.mkdir(path.join(stlcachedir, "experimental"))
@@ -287,7 +288,6 @@ end
}]]
function _parse_dependencies_data(target, moduleinfos)
local modules
- local cachedir = modules_cachedir(target)
for _, moduleinfo in ipairs(moduleinfos) do
assert(moduleinfo.version <= 1)
for _, rule in ipairs(moduleinfo.rules) do
@@ -297,24 +297,30 @@ function _parse_dependencies_data(target, moduleinfos)
for _, provide in ipairs(rule.provides) do
m.provides = m.provides or {}
assert(provide["logical-name"])
- if provide["compiled-module-path"] then
- if not path.is_absolute(provide["compiled-module-path"]) then
- m.provides[provide["logical-name"]] = path.absolute(path.translate(provide["compiled-module-path"]))
- else
- m.provides[provide["logical-name"]] = path.translate(provide["compiled-module-path"])
+ local bmifile = provide["compiled-module-path"]
+ -- try to find the compiled module path in outputs filed (MSVC doesn't generate compiled-module-path)
+ if not bmifile then
+ for _, output in ipairs(rule.outputs) do
+ if output:endswith(".ifc") or output:endswith(".pcm") or output:endswith(".bmi") then
+ bmifile = output
+ break
+ end
+ end
+
+ -- we didn't found the compiled module path, so we assume it
+ if not bmifile then
+ local name = provide["logical-name"] .. bmi_extension(target)
+ -- partition ":" character is invalid path character on windows
+ -- @see https://github.com/xmake-io/xmake/issues/2954
+ name = name:replace(":", "-")
+ bmifile = path.join(get_outputdir(target, name), name)
end
- else
- -- assume path with name
- local name = provide["logical-name"] .. bmi_extension(target)
- -- partition ":" character is invalid path character on windows
- -- @see https://github.com/xmake-io/xmake/issues/2954
- name = name:replace(":", "-")
- m.provides[provide["logical-name"]] = {
- bmi = path.join(cachedir, name),
- sourcefile = moduleinfo.sourcefile,
- interface = provide["is-interface"]
- }
end
+ m.provides[provide["logical-name"]] = {
+ bmi = bmifile,
+ sourcefile = moduleinfo.sourcefile,
+ interface = provide["is-interface"]
+ }
end
else
m.cppfile = moduleinfo.sourcefile
@@ -516,7 +522,7 @@ end
]
}]]
function fallback_generate_dependencies(target, jsonfile, sourcefile, preprocess_file)
- local output = {version = 0, revision = 0, rules = {}}
+ local output = {version = 1, revision = 0, rules = {}}
local rule = {outputs = {jsonfile}}
rule["primary-output"] = target:objectfile(sourcefile)
@@ -550,6 +556,7 @@ function fallback_generate_dependencies(target, jsonfile, sourcefile, preprocess
if module_depname:startswith(":") then
local module_name = (module_name_export or module_name_private or "")
module_name = module_name:split(":")[1]
+ module_dep["unique-on-source-path"] = true
module_depname = module_name .. module_depname
elseif module_depname:startswith("\"") then
module_depname = module_depname:sub(2, -2)
@@ -569,12 +576,13 @@ function fallback_generate_dependencies(target, jsonfile, sourcefile, preprocess
end
if module_name_export or internal then
- table.insert(rule.outputs, (module_name_export or module_name_private) .. bmi_extension(target))
+ local outputdir = get_outputdir(target, sourcefile)
local provide = {}
provide["logical-name"] = module_name_export or module_name_private
- provide["source-path"] = path.absolute(sourcefile, project.directory())
+ provide["source-path"] = sourcefile
provide["is-interface"] = not internal
+ provide["compiled-module-path"] = path.join(outputdir, (module_name_export or module_name_private) .. bmi_extension(target))
rule.provides = {}
table.insert(rule.provides, provide)
@@ -693,7 +701,6 @@ end
function install_module_target(target)
local sourcebatch = target:sourcebatches()["c++.build.modules.install"]
- local cachedir = modules_cachedir(target)
if sourcebatch and sourcebatch.sourcefiles then
for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
local prefixdir = path.join("modules", target:name())
@@ -704,7 +711,8 @@ function install_module_target(target)
local install = (fileconfig and not fileconfig.install) and false or true
if install then
target:add("installfiles", sourcefile, {prefixdir = prefixdir})
- local metafile = path.join(cachedir, path.filename(sourcefile) .. ".meta-info")
+ local outputdir = get_outputdir(target,sourcefile)
+ local metafile = path.join(outputdir, path.filename(sourcefile) .. ".meta-info")
if os.exists(metafile) then
target:add("installfiles", metafile, {prefixdir = prefixdir})
end
@@ -712,3 +720,24 @@ function install_module_target(target)
end
end
end
+
+function get_outputdir(target, module)
+ local cachedir = modules_cachedir(target)
+ local modulepath = module.path or module
+ local cached = localcache():get2("modules_paths", modulepath)
+ if cached then
+ if not os.exists(cached) then
+ os.mkdir(cached)
+ end
+ return cached
+ else
+ local key = path.directory(modulepath) .. target:name()
+ local hashed = hash.uuid(key):split("-", {plain = true})[1]:lower()
+ local moduledir = path.join(cachedir, hashed)
+ localcache():set2("modules_paths", modulepath, moduledir)
+ if not os.exists(moduledir) then
+ os.mkdir(moduledir)
+ end
+ return moduledir
+ end
+end \ No newline at end of file
diff --git a/xmake/rules/c++/modules/modules_support/gcc.lua b/xmake/rules/c++/modules/modules_support/gcc.lua
index 07b4d130b..eb83ed96d 100644
--- a/xmake/rules/c++/modules/modules_support/gcc.lua
+++ b/xmake/rules/c++/modules/modules_support/gcc.lua
@@ -170,7 +170,6 @@ end
-- generate dependency files
function generate_dependencies(target, sourcebatch, opt)
- local cachedir = common.modules_cachedir(target)
local compinst = target:compiler("cxx")
local common_args = {"-E", "-x", "c++"}
local depformatflag = get_depflag(target, "p1689r5") or get_depflag(target, "trtbd")
@@ -184,11 +183,7 @@ function generate_dependencies(target, sourcebatch, opt)
progress.show(opt.progress, "${color.build.object}generating.module.deps %s", sourcefile)
end
- local outputdir = path.translate(path.join(cachedir, path.directory(path.relative(sourcefile, projectdir))))
- if not os.isdir(outputdir) then
- os.mkdir(outputdir)
- end
-
+ local outputdir = common.get_outputdir(target, sourcefile)
local jsonfile = path.translate(path.join(outputdir, path.filename(sourcefile) .. ".json"))
if depformatflag and depfileflag and depoutputflag and not target:policy("build.c++.gcc.fallbackscanner") then
local ifile = path.translate(path.join(outputdir, path.filename(sourcefile) .. ".i"))
@@ -205,14 +200,10 @@ function generate_dependencies(target, sourcebatch, opt)
common.fallback_generate_dependencies(target, jsonfile, sourcefile, function(file)
local compinst = target:compiler("cxx")
local compflags = compinst:compflags({sourcefile = file, target = target})
- local flags = {}
- for _, flag in ipairs(compflags) do
- if flag:startswith("-std") or (flag:startswith("-f") and not flag:startswith("-fmodules")) or flag:startswith("-D") or flag:startswith("-U") or flag:startswith("-I") or flag:startswith("-isystem") then
- table.insert(flags, flag)
- end
- end
+ -- exclude -fmodule* flags because, when they are set gcc try to find bmi of imported modules but they don't exists a this point of compilation
+ compflags = table.remove_if(compflags, function(_, flag) return flag:startswith("-fmodule") end)
local ifile = path.translate(path.join(outputdir, path.filename(file) .. ".i"))
- os.vrunv(compinst:program(), table.join(common_args, flags, {file, "-o", ifile}))
+ os.vrunv(compinst:program(), table.join(common_args, compflags, {file, "-o", ifile}))
local content = io.readfile(ifile)
os.rm(ifile)
return content
@@ -292,28 +283,21 @@ end
function generate_user_headerunits_for_batchjobs(target, batchjobs, headerunits, opt)
local compinst = target:compiler("cxx")
local mapper_file = _get_module_mapper(target)
- local cachedir = common.modules_cachedir(target)
-- build headerunits
local projectdir = os.projectdir()
for _, headerunit in ipairs(headerunits) do
- local file = path.relative(headerunit.path, projectdir)
- local objectfile = target:objectfile(file)
- local outputdir
local headerunit_path
if headerunit.type == ":quote" then
- outputdir = path.join(cachedir, path.directory(path.relative(headerunit.path, projectdir)))
- else
- outputdir = path.join(cachedir, path.directory(headerunit.path))
- end
- local bmifilename = path.basename(objectfile) .. get_bmi_extension()
- local bmifile = (outputdir and path.join(outputdir, bmifilename) or bmifilename)
- if headerunit.type == ":quote" then
headerunit_path = path.join(".", path.relative(headerunit.path, projectdir))
elseif headerunit.type == ":angle" then
-- if path is relative then its a subtarget path
headerunit_path = path.is_absolute(headerunit.path) and headerunit.path or path.join(".", headerunit.path)
end
+ local objectfile = target:objectfile(headerunit_path)
+ local outputdir = common.get_outputdir(target, headerunit.path)
+ local bmifilename = path.basename(objectfile) .. get_bmi_extension()
+ local bmifile = path.join(outputdir, bmifilename)
batchjobs:addjob(headerunit.name, function (index, total)
depend.on_changed(function()
progress.show((index * 100) / total, "${color.build.object}compiling.headerunit.$(mode) %s", headerunit.name)
@@ -321,9 +305,6 @@ function generate_user_headerunits_for_batchjobs(target, batchjobs, headerunits,
if not os.isdir(objectdir) then
os.mkdir(objectdir)
end
- if not os.isdir(outputdir) then
- os.mkdir(outputdir)
- end
-- generate headerunit
local args = { "-c" }
@@ -343,26 +324,11 @@ end
-- generate target user header units for batchcmds
function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits, opt)
local mapper_file = _get_module_mapper(target)
- local cachedir = common.modules_cachedir(target)
-- build headerunits
local projectdir = os.projectdir()
local depmtime = 0
for _, headerunit in ipairs(headerunits) do
- local file = path.relative(headerunit.path, projectdir)
- local objectfile = target:objectfile(file)
- local outputdir
- if headerunit.type == ":quote" then
- outputdir = path.join(cachedir, path.directory(path.relative(headerunit.path, projectdir)))
- else
- outputdir = path.join(cachedir, path.directory(headerunit.path))
- end
- batchcmds:mkdir(outputdir)
-
- local bmifilename = path.basename(objectfile) .. get_bmi_extension()
- local bmifile = (outputdir and path.join(outputdir, bmifilename) or bmifilename)
- batchcmds:mkdir(path.directory(objectfile))
-
local flags = {"-c"}
local headerunit_path
if headerunit.type == ":quote" then
@@ -373,6 +339,13 @@ function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits,
-- if path is relative then its a subtarget path
headerunit_path = path.is_absolute(headerunit.path) and headerunit.path or path.join(".", headerunit.path)
end
+ local objectfile = target:objectfile(headerunit_path)
+ local outputdir = common.get_outputdir(target, headerunit.path)
+ batchcmds:mkdir(outputdir)
+
+ local bmifilename = path.basename(objectfile) .. get_bmi_extension()
+ local bmifile = (outputdir and path.join(outputdir, bmifilename) or bmifilename)
+ batchcmds:mkdir(path.directory(objectfile))
batchcmds:show_progress(opt.progress, "${color.build.object}compiling.headerunit.$(mode) %s", headerunit.name)
_batchcmds_compile(batchcmds, target, flags)
@@ -417,10 +390,10 @@ function build_modules_for_batchjobs(target, batchjobs, objectfiles, modules, op
local fileconfig = target:fileconfig(cppfile)
if fileconfig and fileconfig.install then
batchjobs:addjob(name .. "_metafile", function(index, total)
- local cachedir = common.modules_cachedir(target)
- local metafilepath = path.join(cachedir, path.filename(cppfile) .. ".meta-info")
+ local outputdir = common.get_outputdir(target, cppfile)
+ local metafilepath = path.join(outputdir, path.filename(cppfile) .. ".meta-info")
depend.on_changed(function()
- progress.show(opt.progress, "${color.build.object}generating.module.metadata %s", name)
+ progress.show((index * 100) / total, "${color.build.object}generating.module.metadata %s", name)
local metadata = common.generate_meta_module_info(target, name, cppfile, module.requires)
json.savefile(metafilepath, metadata)
diff --git a/xmake/rules/c++/modules/modules_support/msvc.lua b/xmake/rules/c++/modules/modules_support/msvc.lua
index 3d4e03db2..e849c24b8 100644
--- a/xmake/rules/c++/modules/modules_support/msvc.lua
+++ b/xmake/rules/c++/modules/modules_support/msvc.lua
@@ -25,7 +25,6 @@ import("core.tool.compiler")
import("core.project.project")
import("core.project.depend")
import("core.project.config")
-import("core.base.hashset")
import("core.base.semver")
import("utils.progress")
import("private.action.build.object", {alias = "objectbuilder"})
@@ -182,8 +181,8 @@ end
function generate_dependencies(target, sourcebatch, opt)
local msvc = target:toolchain("msvc")
local scandependenciesflag = get_scandependenciesflag(target)
+ local ifcoutputflag = get_ifcoutputflag(target)
local common_flags = {"-TP", scandependenciesflag}
- local cachedir = common.modules_cachedir(target)
local changed = false
for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
local dependfile = target:dependfile(sourcefile)
@@ -191,14 +190,11 @@ function generate_dependencies(target, sourcebatch, opt)
if opt.progress then
progress.show(opt.progress, "${color.build.object}generating.module.deps %s", sourcefile)
end
- local outputdir = path.join(cachedir, path.directory(path.relative(sourcefile, projectdir)))
- if not os.isdir(outputdir) then
- os.mkdir(outputdir)
- end
+ local outputdir = common.get_outputdir(target, sourcefile)
- local jsonfile = path.join(outputdir, path.filename(sourcefile) .. ".json")
+ local jsonfile = path.join(outputdir, path.filename(sourcefile) .. ".module.json")
if scandependenciesflag and not target:policy("build.c++.msvc.fallbackscanner") then
- local flags = {jsonfile, sourcefile, "-Fo" .. target:objectfile(sourcefile)}
+ local flags = {jsonfile, sourcefile, ifcoutputflag, outputdir, "-Fo" .. target:objectfile(sourcefile)}
_compile(target, table.join(common_flags, flags), sourcefile)
else
common.fallback_generate_dependencies(target, jsonfile, sourcefile, function(file)
@@ -311,8 +307,6 @@ end
-- generate target user header units for batchcmds
function generate_user_headerunits_for_batchjobs(target, batchjobs, headerunits, opt)
- local cachedir = common.modules_cachedir(target)
-
-- get flags
local exportheaderflag = get_exportheaderflag(target)
local headerunitflag = get_headerunitflag(target)
@@ -326,17 +320,10 @@ function generate_user_headerunits_for_batchjobs(target, batchjobs, headerunits,
end, {rootjob = opt.rootjob})
-- build headerunits
- local projectdir = os.projectdir()
for _, headerunit in ipairs(headerunits) do
local file = path.relative(headerunit.path, target:scriptdir())
local objectfile = target:objectfile(file)
- local outputdir
- if headerunit.type == ":quote" then
- outputdir = path.join(cachedir, path.directory(path.relative(headerunit.path, projectdir)))
- else
- -- if path is relative then its a subtarget path
- outputdir = path.join(cachedir, path.is_absolute(headerunit.path) and path.directory(headerunit.path):sub(3) or headerunit.path)
- end
+ local outputdir = common.get_outputdir(target, headerunit)
local bmifilename = path.basename(objectfile) .. get_bmi_extension()
local bmifile = path.join(outputdir, bmifilename)
batchjobs:addjob(headerunit.name, function (index, total)
@@ -368,7 +355,6 @@ end
-- generate target user header units for batchcmds
function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits, opt)
- local cachedir = common.modules_cachedir(target)
local exportheaderflag = get_exportheaderflag(target)
local headerunitflag = get_headerunitflag(target)
local headernameflag = get_headernameflag(target)
@@ -376,18 +362,11 @@ function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits,
assert(headerunitflag and headernameflag and exportheaderflag, "compiler(msvc): does not support c++ header units!")
-- build headerunits
- local projectdir = os.projectdir()
local depmtime = 0
for _, headerunit in ipairs(headerunits) do
local file = path.relative(headerunit.path, target:scriptdir())
local objectfile = target:objectfile(file)
- local outputdir
- if headerunit.type == ":quote" then
- outputdir = path.join(cachedir, path.directory(path.relative(headerunit.path, projectdir)))
- else
- -- if path is relative then its a subtarget path
- outputdir = path.join(cachedir, path.is_absolute(headerunit.path) and path.directory(headerunit.path):sub(3) or headerunit.path)
- end
+ local outputdir = common.get_outputdir(target, headerunit)
batchcmds:mkdir(outputdir)
local bmifilename = path.basename(objectfile) .. get_bmi_extension()
@@ -466,10 +445,10 @@ function build_modules_for_batchjobs(target, batchjobs, objectfiles, modules, op
local fileconfig = target:fileconfig(cppfile)
if fileconfig and fileconfig.install then
batchjobs:addjob(name .. "_metafile", function(index, total)
- local cachedir = common.modules_cachedir(target)
- local metafilepath = path.join(cachedir, path.filename(cppfile) .. ".meta-info")
+ local outputdir = common.get_outputdir(target, cppfile)
+ local metafilepath = path.join(outputdir, path.filename(cppfile) .. ".meta-info")
depend.on_changed(function()
- progress.show(opt.progress, "${color.build.object}generating.module.metadata %s", name)
+ progress.show((index * 100) / total, "${color.build.object}generating.module.metadata %s", name)
local metadata = common.generate_meta_module_info(target, name, cppfile, module.requires)
json.savefile(metafilepath, metadata)