summaryrefslogtreecommitdiff
path: root/xmake/rules/c++/modules/modules_support
diff options
context:
space:
mode:
Diffstat (limited to 'xmake/rules/c++/modules/modules_support')
-rw-r--r--xmake/rules/c++/modules/modules_support/clang.lua161
-rw-r--r--xmake/rules/c++/modules/modules_support/common.lua47
-rw-r--r--xmake/rules/c++/modules/modules_support/gcc.lua153
-rw-r--r--xmake/rules/c++/modules/modules_support/msvc.lua152
-rw-r--r--xmake/rules/c++/modules/modules_support/stl_headers.lua28
5 files changed, 323 insertions, 218 deletions
diff --git a/xmake/rules/c++/modules/modules_support/clang.lua b/xmake/rules/c++/modules/modules_support/clang.lua
index 7d841a2be..4cefed14d 100644
--- a/xmake/rules/c++/modules/modules_support/clang.lua
+++ b/xmake/rules/c++/modules/modules_support/clang.lua
@@ -112,7 +112,7 @@ function generate_dependencies(target, sourcebatch, opt)
depend.on_changed(function()
progress.show(opt.progress, "${color.build.object}generating.cxx.module.deps %s", sourcefile)
- local outdir = path.translate(path.join(cachedir, path.directory(path.relative(sourcefile, target:scriptdir()))))
+ local outdir = path.translate(path.join(cachedir, path.directory(path.relative(sourcefile, projectdir))))
if not os.isdir(outdir) then
os.mkdir(outdir)
end
@@ -127,79 +127,94 @@ function generate_dependencies(target, sourcebatch, opt)
end
end
--- generate target header units
-function generate_headerunits(target, batchcmds, headerunits, opt)
+-- generate target stl header units
+function generate_stl_headerunits(target, batchcmds, headerunits, opt)
local compinst = target:compiler("cxx")
- local cachedir = common.modules_cachedir(target)
+
+ -- get cachedirs
local stlcachedir = common.stlmodules_cachedir(target)
- assert(has_headerunitsupport(target), "compiler(clang): does not support c++ header units!")
-- get headerunits flags
local modulecachepathflag = get_modulecachepathflag(target)
- local emitmoduleflag = get_emitmoduleflag(target)
local modulefileflag = get_modulefileflag(target)
-- build headerunits
- local objectfiles = {}
- local public_flags = {}
- local private_flags = {}
local projectdir = os.projectdir()
- for _, headerunit in ipairs(headerunits) do
- if not headerunit.stl then
- local file = path.relative(headerunit.path, target:scriptdir())
- local objectfile = target:objectfile(file)
+ local flags = {}
+ local depmtime = 0
+ for i, headerunit in ipairs(headerunits) do
+ local bmifile = path.join(stlcachedir, headerunit.name .. get_bmi_extension())
+ if not os.isfile(bmifile) then
+ local args = {modulecachepathflag .. stlcachedir, "-c", "-o", bmifile, "-x", "c++-system-header", headerunit.path}
+ batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.headerunit.bmi %s", headerunit.name)
+ batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), args))
+ end
- local outdir
- if headerunit.type == ":quote" then
- outdir = path.join(cachedir, path.directory(path.relative(headerunit.path, projectdir)))
- else
- outdir = path.join(cachedir, path.directory(headerunit.path))
- end
- if not os.isdir(outdir) then
- os.mkdir(outdir)
- end
+ table.insert(flags, modulefileflag .. bmifile)
+ depmtime = math.max(depmtime, os.mtime(bmifile))
+ end
+ batchcmds:set_depmtime(depmtime)
+ return flags
+end
- local bmifilename = path.basename(objectfile) .. get_bmi_extension()
- local bmifile = (outdir and path.join(outdir, bmifilename) or bmifilename)
- if not os.isdir(path.directory(objectfile)) then
- os.mkdir(path.directory(objectfile))
- end
+-- generate target user header units
+function generate_user_headerunits(target, batchcmds, headerunits, opt)
+ local compinst = target:compiler("cxx")
+ assert(has_headerunitsupport(target), "compiler(clang): does not support c++ header units!")
- local args = { modulecachepathflag .. cachedir, emitmoduleflag, "-c", "-o", bmifile}
- if headerunit.type == ":quote" then
- table.join2(args, {"-I", path.directory(headerunit.path), "-x", "c++-user-header", headerunit.path})
- elseif headerunit.type == ":angle" then
- table.join2(args, {"-x", "c++-system-header", headerunit.name})
- end
+ -- get cachedirs
+ local cachedir = common.modules_cachedir(target)
- batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.headerunit.bmi %s", headerunit.name)
- batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), args))
+ -- get headerunits flags
+ local modulecachepathflag = get_modulecachepathflag(target)
+ local emitmoduleflag = get_emitmoduleflag(target)
+ local modulefileflag = get_modulefileflag(target)
- batchcmds:add_depfiles(headerunit.path)
- batchcmds:set_depmtime(os.mtime(bmifile))
- batchcmds:set_depcache(target:dependfile(bmifile))
+ -- build headerunits
+ local objectfiles = {}
+ local flags = {}
+ 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)
- table.insert(public_flags, modulefileflag .. bmifile)
+ local outdir
+ if headerunit.type == ":quote" then
+ outdir = path.join(cachedir, path.directory(path.relative(headerunit.path, projectdir)))
else
- local bmifile = path.join(stlcachedir, headerunit.name .. get_bmi_extension())
- if not os.isfile(bmifile) then
- local args = {modulecachepathflag .. stlcachedir, "-c", "-o", bmifile, "-x", "c++-system-header", headerunit.path}
- batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.headerunit.bmi %s", headerunit.name)
- batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), args))
- end
+ outdir = path.join(cachedir, path.directory(headerunit.path))
+ end
+ batchcmds:mkdir(outdir)
- batchcmds:set_depmtime(os.mtime(bmifile))
- batchcmds:set_depcache(target:dependfile(bmifile))
+ local bmifilename = path.basename(objectfile) .. get_bmi_extension()
+ local bmifile = (outdir and path.join(outdir, bmifilename) or bmifilename)
+ batchcmds:mkdir(path.directory(objectfile))
- table.insert(private_flags, modulefileflag .. bmifile)
+ local args = { modulecachepathflag .. cachedir, emitmoduleflag, "-c", "-o", bmifile}
+ if headerunit.type == ":quote" then
+ table.join2(args, {"-I", path.directory(headerunit.path), "-x", "c++-user-header", headerunit.path})
+ elseif headerunit.type == ":angle" then
+ table.join2(args, {"-x", "c++-system-header", headerunit.name})
end
+
+ batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.headerunit.bmi %s", headerunit.name)
+ batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), args))
+
+ batchcmds:add_depfiles(headerunit.path)
+
+ table.insert(flags, modulefileflag .. bmifile)
+ depmtime = math.max(depmtime, os.mtime(bmifile))
end
- return public_flags, private_flags
+ batchcmds:set_depmtime(depmtime)
+ return flags
end
-- build module files
function build_modules(target, batchcmds, objectfiles, modules, opt)
local compinst = target:compiler("cxx")
+
+ -- get cachedirs
local cachedir = common.modules_cachedir(target)
-- get modules flags
@@ -215,44 +230,42 @@ function build_modules(target, batchcmds, objectfiles, modules, opt)
end
end
+ -- build modules
local common_args = {modulecachepathflag .. cachedir}
+ local depmtime = 0
for _, objectfile in ipairs(objectfiles) do
local m = modules[objectfile]
- if m then
- if not os.isdir(path.directory(objectfile)) then
- os.mkdir(path.directory(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 args = { emitmoduleinterfaceflag }
- local bmiflags = {}
- local bmifiles = {}
- for name, provide in pairs(m.provides) do
- batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.module.bmi %s", name)
-
- local bmifile = provide.bmi
- table.join2(args, { "-c", "-x", "c++-module", "--precompile", provide.sourcefile, "-o", bmifile })
- table.join2(bmifiles, bmifile)
-
- batchcmds:add_depfiles(provide.sourcefile)
- batchcmds:set_depmtime(os.mtime(bmifile))
- batchcmds:set_depcache(target:dependfile(bmifile))
-
- table.join2(bmiflags, {modulefileflag .. bmifile})
- end
+ local bmifile = provide.bmi
+ local args = { emitmoduleinterfaceflag, "-c", "-x", "c++-module", "--precompile", provide.sourcefile, "-o", bmifile }
+ batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.module.bmi %s", name)
+ batchcmds:mkdir(path.directory(objectfile))
batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, args))
- batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, bmifiles, {"-c", "-o", objectfile}))
+ batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, {bmifile}, {"-c", "-o", objectfile}))
- batchcmds:set_depmtime(os.mtime(objectfile))
- batchcmds:set_depcache(target:dependfile(objectfile))
+ batchcmds:add_depfiles(provide.sourcefile)
+ local bmiflags = modulefileflag .. bmifile
target:add("cxxflags", bmiflags, {public = true, force = true})
target:add("objectfiles", objectfile)
- for _, f in ipairs(bmiflags) do
- target:data_add("cxx.modules.flags", f)
- end
+ target:data_add("cxx.modules.flags", bmiflags)
+ depmtime = math.max(depmtime, os.mtime(bmifile))
end
end
+ batchcmds:set_depmtime(depmtime)
end
function get_bmi_extension()
diff --git a/xmake/rules/c++/modules/modules_support/common.lua b/xmake/rules/c++/modules/modules_support/common.lua
index 331f1bea5..9c15cffbe 100644
--- a/xmake/rules/c++/modules/modules_support/common.lua
+++ b/xmake/rules/c++/modules/modules_support/common.lua
@@ -26,6 +26,7 @@ import("core.tool.compiler")
import("core.cache.memcache", {alias = "_memcache"})
import("core.project.project")
import("lib.detect.find_file")
+import("stl_headers")
-- get memcache
function memcache()
@@ -34,10 +35,7 @@ end
-- get stl modules cache directory
function stlmodules_cachedir(target)
- local stlcachedir = path.join(target:autogendir(), "stlmodules", "cache")
- if target:has_tool("cxx", "clang", "clangxx") then
- stlcachedir = path.join(config.buildir(), "stlmodules", "cache")
- end
+ local stlcachedir = path.join(config.buildir(), "stlmodules", "cache")
if not os.isdir(stlcachedir) then
os.mkdir(stlcachedir)
end
@@ -53,12 +51,42 @@ function modules_cachedir(target)
return cachedir
end
+-- get headerunits info
+function get_headerunits(target, sourcebatch)
+ local headerunits
+ local stl_headerunits
+ local modules = target:data("cxx.modules")
+ for _, objectfile in ipairs(sourcebatch.objectfiles) do
+ local m = modules[objectfile]
+ if m then
+ for name, r in pairs(m.requires) do
+ if r.method ~= "by-name" then
+ local unittype = r.method == "include-angle" and ":angle" or ":quote"
+
+ if stl_headers.is_stl_header(name) then
+ stl_headerunits = stl_headerunits or {}
+ if not table.find_if(stl_headerunits, function(i, v) return v.name == name end) then
+ table.insert(stl_headerunits, {name = name, path = r.path, type = unittype})
+ end
+ else
+ headerunits = headerunits or {}
+ if not table.find_if(headerunits, function(i, v) return v.name == name end) then
+ table.insert(headerunits, {name = name, path = r.path, type = unittype})
+ end
+ end
+ end
+ end
+ end
+ end
+ return headerunits, stl_headerunits
+end
+
-- patch sourcebatch
function patch_sourcebatch(target, sourcebatch, opt)
local cachedir = modules_cachedir(target)
sourcebatch.sourcekind = "cxx"
- sourcebatch.objectfiles = sourcebatch.objectfiles or {}
- sourcebatch.dependfiles = sourcebatch.dependfiles or {}
+ sourcebatch.objectfiles = {}
+ sourcebatch.dependfiles = {}
for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
local objectfile = target:objectfile(sourcefile)
local dependfile = target:dependfile(objectfile)
@@ -279,9 +307,12 @@ end
function find_angle_header_file(target, file)
local headerpaths = modules_support(target).toolchain_includedirs(target)
for _, dep in ipairs(target:orderdeps()) do
- table.insert(headerpaths, dep:scriptdir())
+ local includedirs = dep:get("sysincludedirs") or dep:get("includedirs")
+ if includedirs then
+ table.join2(headerpaths, includedirs)
+ end
end
- for _, pkg in ipairs(target:pkgs()) do
+ for _, pkg in pairs(target:pkgs()) do
local includedirs = pkg:get("sysincludedirs") or pkg:get("includedirs")
if includedirs then
table.join2(headerpaths, includedirs)
diff --git a/xmake/rules/c++/modules/modules_support/gcc.lua b/xmake/rules/c++/modules/modules_support/gcc.lua
index 2b21a7091..449c901fd 100644
--- a/xmake/rules/c++/modules/modules_support/gcc.lua
+++ b/xmake/rules/c++/modules/modules_support/gcc.lua
@@ -128,7 +128,7 @@ function generate_dependencies(target, sourcebatch, opt)
depend.on_changed(function()
progress.show(opt.progress, "${color.build.object}generating.cxx.module.deps %s", sourcefile)
- local outdir = path.translate(path.join(cachedir, path.directory(path.relative(sourcefile, target:scriptdir()))))
+ local outdir = path.translate(path.join(cachedir, path.directory(path.relative(sourcefile, projectdir))))
if not os.isdir(outdir) then
os.mkdir(outdir)
end
@@ -149,107 +149,122 @@ function generate_dependencies(target, sourcebatch, opt)
end
end
--- generate target header units
-function generate_headerunits(target, batchcmds, headerunits, opt)
+-- generate target stl header units
+function generate_stl_headerunits(target, batchcmds, headerunits, opt)
local compinst = target:compiler("cxx")
- local cachedir = common.modules_cachedir(target)
- local stlcachedir = common.stlmodules_cachedir(target)
local mapper_file = _get_module_mapper()
+ -- get cachedirs
+ local stlcachedir = common.stlmodules_cachedir(target)
+
-- build headerunits
- local objectfiles = {}
local projectdir = os.projectdir()
- for _, headerunit in ipairs(headerunits) do
- if not headerunit.stl then
- local file = path.relative(headerunit.path, target:scriptdir())
- local objectfile = target:objectfile(file)
+ local depmtime = 0
+ for i, headerunit in ipairs(headerunits) do
+ local bmifile = path.join(stlcachedir, headerunit.name .. get_bmi_extension())
+ if _add_module_to_mapper(mapper_file, headerunit.path, path.absolute(bmifile, projectdir)) then
+ local args = { "-c", "-x", "c++-system-header", headerunit.name }
- local outdir
- if headerunit.type == ":quote" then
- outdir = path.join(cachedir, path.directory(path.relative(headerunit.path, projectdir)))
- else
- outdir = path.join(cachedir, path.directory(headerunit.path))
- end
- if not os.isdir(outdir) then
- os.mkdir(outdir)
- end
+ batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.headerunit.bmi %s", headerunit.name)
+ batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), args))
+ end
+ depmtime = math.max(depmtime, os.mtime(bmifile))
+ end
+ batchcmds:set_depmtime(depmtime)
+end
- local bmifilename = path.basename(objectfile) .. get_bmi_extension()
- local bmifile = (outdir and path.join(outdir, bmifilename) or bmifilename)
- if not os.isdir(path.directory(objectfile)) then
- os.mkdir(path.directory(objectfile))
- end
+-- generate target user header units
+function generate_user_headerunits(target, batchcmds, headerunits, opt)
+ local compinst = target:compiler("cxx")
+ local mapper_file = _get_module_mapper()
- if _add_module_to_mapper(mapper_file, headerunit.path, path.absolute(bmifile, projectdir)) then
- local args = { "-c" }
- if headerunit.type == ":quote" then
- table.join2(args, { "-I", path.directory(headerunit.path), "-x", "c++-user-header", headerunit.name })
- _add_module_to_mapper(mapper_file, path.join(".", path.relative(headerunit.path, projectdir)), path.absolute(bmifile, projectdir))
- elseif headerunit.type == ":angle" then
- table.join2(args, { "-x", "c++-system-header", headerunit.name })
- _add_module_to_mapper(mapper_file, headerunit.name, path.absolute(bmifile, projectdir))
- end
+ -- get cachedirs
+ local cachedir = common.modules_cachedir(target)
- batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.headerunit.bmi %s", headerunit.name)
- batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), args))
+ -- 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)
- batchcmds:add_depfiles(headerunit.path)
- batchcmds:set_depmtime(os.mtime(bmifile))
- batchcmds:set_depcache(target:dependfile(bmifile))
- end
+ local outdir
+ if headerunit.type == ":quote" then
+ outdir = path.join(cachedir, path.directory(path.relative(headerunit.path, projectdir)))
else
- local bmifile = path.join(stlcachedir, headerunit.name .. get_bmi_extension())
- if _add_module_to_mapper(mapper_file, headerunit.path, path.absolute(bmifile, projectdir)) then
- if not os.isfile(bmifile) then
- local args = { "-c", "-x", "c++-system-header", headerunit.name }
+ outdir = path.join(cachedir, path.directory(headerunit.path))
+ end
+ batchcmds:mkdir(outdir)
- batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.headerunit.bmi %s", headerunit.name)
- batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), args))
+ local bmifilename = path.basename(objectfile) .. get_bmi_extension()
+ local bmifile = (outdir and path.join(outdir, bmifilename) or bmifilename)
+ batchcmds:mkdir(path.directory(objectfile))
- batchcmds:set_depmtime(os.mtime(bmifile))
- batchcmds:set_depcache(target:dependfile(bmifile))
- end
- end
+ local args = { "-c" }
+ local headerunit_path
+ if headerunit.type == ":quote" then
+ table.join2(args, { "-I", path.directory(path.relative(headerunit.path, projectdir)), "-x", "c++-user-header", headerunit.name })
+ headerunit_path = path.join(".", path.relative(headerunit.path, projectdir))
+ elseif headerunit.type == ":angle" then
+ table.join2(args, { "-x", "c++-system-header", headerunit.name })
+ -- 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
+
+ if _add_module_to_mapper(mapper_file, headerunit_path, path.absolute(bmifile, projectdir)) then
+ batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.headerunit.bmi %s", headerunit.name)
+ batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), args))
+
+ batchcmds:add_depfiles(headerunit.path)
+ end
+ depmtime = math.max(depmtime, os.mtime(bmifile))
end
+ batchcmds:set_depmtime(depmtime)
end
-- build module files
function build_modules(target, batchcmds, objectfiles, modules, opt)
- local cachedir = common.modules_cachedir(target)
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
local projectdir = os.projectdir()
+ local depmtime = 0
for _, objectfile in ipairs(objectfiles) do
local m = modules[objectfile]
- if m then
- if not os.isdir(path.directory(objectfile)) then
- os.mkdir(path.directory(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 args = {"-o", objectfile}
- for name, provide in pairs(m.provides) do
+ local bmifile = provide.bmi
+ if _add_module_to_mapper(mapper_file, name, path.absolute(bmifile, projectdir)) then
+ local args = {"-o", objectfile, "-c", provide.sourcefile}
+
batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.module.bmi %s", name)
+ batchcmds:mkdir(path.directory(objectfile))
+ batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, args))
- local bmifile = provide.bmi
- if _add_module_to_mapper(mapper_file, name, path.absolute(bmifile, projectdir)) then
- table.join2(args, {"-c", provide.sourcefile})
+ batchcmds:add_depfiles(provide.sourcefile)
+ target:add("objectfiles", objectfile)
- batchcmds:add_depfiles(provide.sourcefile)
- batchcmds:set_depmtime(os.mtime(bmifile))
- batchcmds:set_depcache(target:dependfile(bmifile))
- end
+ depmtime = math.max(depmtime, os.mtime(bmifile))
end
-
- batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, args))
-
- batchcmds:set_depmtime(os.mtime(objectfile))
- batchcmds:set_depcache(target:dependfile(objectfile))
-
- target:add("objectfiles", objectfile)
end
end
+ batchcmds:set_depmtime(depmtime)
end
function get_bmi_extension()
diff --git a/xmake/rules/c++/modules/modules_support/msvc.lua b/xmake/rules/c++/modules/modules_support/msvc.lua
index c2351371f..96997b5b9 100644
--- a/xmake/rules/c++/modules/modules_support/msvc.lua
+++ b/xmake/rules/c++/modules/modules_support/msvc.lua
@@ -90,7 +90,7 @@ function generate_dependencies(target, sourcebatch, opt)
local dependfile = target:dependfile(sourcefile)
depend.on_changed(function ()
progress.show(opt.progress, "${color.build.object}generating.cxx.module.deps %s", sourcefile)
- local outputdir = path.join(cachedir, path.directory(path.relative(sourcefile, target:scriptdir())))
+ local outputdir = path.join(cachedir, path.directory(path.relative(sourcefile, projectdir)))
if not os.isdir(outputdir) then
os.mkdir(outputdir)
end
@@ -109,8 +109,8 @@ function generate_dependencies(target, sourcebatch, opt)
end
end
--- generate target header units
-function generate_headerunits(target, batchcmds, headerunits, opt)
+-- generate target stl header units
+function generate_stl_headerunits(target, batchcmds, headerunits, opt)
local compinst = target:compiler("cxx")
local toolchain = target:toolchain("msvc")
local vcvars = toolchain:config("vcvars")
@@ -123,62 +123,82 @@ function generate_headerunits(target, batchcmds, headerunits, opt)
assert(headerunitflag and headernameflag and exportheaderflag, "compiler(msvc): does not support c++ header units!")
-- get cachedirs
- local cachedir = common.modules_cachedir(target)
local stlcachedir = common.stlmodules_cachedir(target)
-- build headerunits
local common_args = {"/TP", exportheaderflag, "/c"}
local objectfiles = {}
- local public_flags = {}
- local private_flags = {}
- local projectdir = os.projectdir()
+ local flags = {}
+ local depmtime = 0
for _, headerunit in ipairs(headerunits) do
- if not headerunit.stl then
- 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):sub(3))
- end
- if not os.isdir(outputdir) then
- os.mkdir(outputdir)
- end
+ local bmifile = path.join(stlcachedir, headerunit.name .. get_bmi_extension())
+ if not os.isfile(bmifile) then
+ local args = {exportheaderflag, headernameflag .. ":angle", headerunit.name, ifcoutputflag, stlcachedir}
+ batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.headerunit.bmi %s", headerunit.name)
+ batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), args), {envs = vcvars})
+ end
- local bmifilename = path.basename(objectfile) .. get_bmi_extension()
- local bmifile = (outputdir and path.join(outputdir, bmifilename) or bmifilename)
- if not os.isdir(path.directory(objectfile)) then
- os.mkdir(path.directory(objectfile))
- end
+ local flag = {headerunitflag .. ":angle", headerunit.name .. "=" .. headerunit.name .. get_bmi_extension()}
+ table.join2(flags, flag)
- local args = {headernameflag .. headerunit.type, headerunit.path, ifcoutputflag, outputdir, "/Fo" .. objectfile}
- batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.headerunit.bmi %s", headerunit.name)
- batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, args), {envs = vcvars})
+ depmtime = math.max(depmtime, os.mtime(bmifile))
+ end
+ batchcmds:set_depmtime(depmtime)
+ return flags
+end
- batchcmds:add_depfiles(headerunit.path)
- batchcmds:set_depmtime(os.mtime(bmifile))
- batchcmds:set_depcache(target:dependfile(bmifile))
- batchcmds:set_depmtime(os.mtime(objectfile))
- batchcmds:set_depcache(target:dependfile(objectfile))
+-- generate target user header units
+function generate_user_headerunits(target, batchcmds, headerunits, opt)
+ local compinst = target:compiler("cxx")
+ local toolchain = target:toolchain("msvc")
+ local vcvars = toolchain:config("vcvars")
- local flag = {headerunitflag .. headerunit.type, headerunit.name .. "=" .. path.relative(bmifile, cachedir)}
- table.join2(public_flags, flag)
- target:add("objectfiles", objectfile)
- else
- local bmifile = path.join(stlcachedir, headerunit.name .. get_bmi_extension())
- local args = {exportheaderflag, headernameflag .. ":angle", headerunit.name, ifcoutputflag, stlcachedir}
- batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.headerunit.bmi %s", headerunit.name)
- batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), args), {envs = vcvars})
+ -- get flags
+ local exportheaderflag = get_exportheaderflag(target)
+ local headerunitflag = get_headerunitflag(target)
+ local headernameflag = get_headernameflag(target)
+ local ifcoutputflag = get_ifcoutputflag(target)
+ assert(headerunitflag and headernameflag and exportheaderflag, "compiler(msvc): does not support c++ header units!")
- batchcmds:set_depmtime(os.mtime(bmifile))
- batchcmds:set_depcache(target:dependfile(bmifile))
+ -- get cachedirs
+ local cachedir = common.modules_cachedir(target)
- local flag = {headerunitflag .. ":angle", headerunit.name .. "=" .. headerunit.name .. get_bmi_extension()}
- table.join2(private_flags, flag)
+ -- build headerunits
+ local common_args = {"/TP", exportheaderflag, "/c"}
+ local objectfiles = {}
+ local flags = {}
+ 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
+ batchcmds:mkdir(outputdir)
+
+ local bmifilename = path.basename(objectfile) .. get_bmi_extension()
+ local bmifile = path.join(outputdir, bmifilename)
+ batchcmds:mkdir(path.directory(objectfile))
+
+ local args = {headernameflag .. headerunit.type, headerunit.path, ifcoutputflag, outputdir, "/Fo" .. objectfile}
+ batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.headerunit.bmi %s", headerunit.name)
+ batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, args), {envs = vcvars})
+
+ batchcmds:add_depfiles(headerunit.path)
+
+ local flag = {headerunitflag .. headerunit.type, headerunit.name .. "=" .. path.relative(bmifile, cachedir)}
+ table.join2(flags, flag)
+ target:add("objectfiles", objectfile)
+
+ depmtime = math.max(depmtime, os.mtime(bmifile))
end
- return public_flags, private_flags
+ batchcmds:set_depmtime(depmtime)
+ return flags
end
-- build module files
@@ -202,42 +222,42 @@ function build_modules(target, batchcmds, objectfiles, modules, opt)
end
end
- -- compile module files to bmi files
+ -- build modules
local common_args = {"/TP"}
+ local depmtime = 0
for _, objectfile in ipairs(objectfiles) do
local m = modules[objectfile]
- if m then
- if not os.isdir(path.directory(objectfile)) then
- os.mkdir(path.directory(objectfile))
- end
-
- local args = {"/c", "/Fo" .. objectfile}
- local bmiflags = {}
- for name, provide in pairs(m.provides) do
- batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.module.bmi %s", name)
-
- local bmifile = provide.bmi
- table.join2(args, {interfaceflag, ifcoutputflag, bmifile, provide.sourcefile})
-
- batchcmds:add_depfiles(provide.sourcefile)
- batchcmds:set_depmtime(os.mtime(bmifile))
- batchcmds:set_depcache(target:dependfile(bmifile))
-
- table.join2(bmiflags, {referenceflag, name .. "=" .. path.filename(bmifile)})
+ 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 args = {"/c", "/Fo" .. objectfile, interfaceflag, ifcoutputflag, bmifile, provide.sourcefile}
+ batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.module.bmi %s", name)
+ batchcmds:mkdir(path.directory(objectfile))
batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, args, bmi_args), {envs = vcvars})
- batchcmds:set_depmtime(os.mtime(objectfile))
- batchcmds:set_depcache(target:dependfile(objectfile))
+ batchcmds:add_depfiles(provide.sourcefile)
+ local bmiflags = {referenceflag, name .. "=" .. path.filename(bmifile)}
target:add("cxxflags", bmiflags, {force = true, expand = false})
for _, f in ipairs(bmiflags) do
target:data_add("cxx.modules.flags", f)
end
target:add("objectfiles", objectfile)
+ depmtime = math.max(depmtime, os.mtime(bmifile))
end
end
+ batchcmds:set_depmtime(depmtime)
end
function get_bmi_extension()
diff --git a/xmake/rules/c++/modules/modules_support/stl_headers.lua b/xmake/rules/c++/modules/modules_support/stl_headers.lua
index aa5cb497c..849184ee5 100644
--- a/xmake/rules/c++/modules/modules_support/stl_headers.lua
+++ b/xmake/rules/c++/modules/modules_support/stl_headers.lua
@@ -102,7 +102,33 @@ function _stl_headers()
"new",
"type_traits",
"string_view",
- "stdexcept"}
+ "stdexcept",
+ "print",
+ "flat_map",
+ "flat_set",
+ "mdspan",
+ "stdfloat",
+ "generator",
+ "csetjmp",
+ "csignal",
+ "cstdarg",
+ "cstddef",
+ "cstdlib",
+ "cfloat",
+ "cinttypes",
+ "climits",
+ "cstdint",
+ "cassert",
+ "cerrno",
+ "cctype",
+ "cstring",
+ "cuchar",
+ "cwchar",
+ "cwctype",
+ "cfenv",
+ "cmath",
+ "clocale",
+ "cstdio"}
end
-- get all stl headers