diff options
Diffstat (limited to 'xmake/rules/c++/modules/modules_support')
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/clang.lua | 161 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/common.lua | 47 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/gcc.lua | 153 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/msvc.lua | 152 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/stl_headers.lua | 28 |
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 |
