diff options
| author | Arthur LAURENT <[email protected]> | 2022-08-04 23:27:42 +0200 |
|---|---|---|
| committer | Arthur LAURENT <[email protected]> | 2022-08-05 00:12:53 +0200 |
| commit | d2d7292907f6aecbcb0b52aca4897bc7fbaf94cd (patch) | |
| tree | dedbff6c706f5ae911bbf333671734128962d78e | |
| parent | 6c27288e6156c41ad754c7a195faaf40dcce0c18 (diff) | |
Improve header unit support
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/clang.lua | 114 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/gcc.lua | 112 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/msvc.lua | 110 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/xmake.lua | 26 |
4 files changed, 214 insertions, 148 deletions
diff --git a/xmake/rules/c++/modules/modules_support/clang.lua b/xmake/rules/c++/modules/modules_support/clang.lua index fd71b298f..e023acccb 100644 --- a/xmake/rules/c++/modules/modules_support/clang.lua +++ b/xmake/rules/c++/modules/modules_support/clang.lua @@ -127,79 +127,97 @@ 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 = {} + 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 + 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) - if not os.isdir(path.directory(objectfile)) then - os.mkdir(path.directory(objectfile)) - end + table.insert(flags, modulefileflag .. bmifile) + end + return flags +end - 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 +-- 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!") - 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 cachedirs + local cachedir = common.modules_cachedir(target) + + -- 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() + 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 + if not os.isdir(outdir) then + os.mkdir(outdir) + end - 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) + if not os.isdir(path.directory(objectfile)) then + os.mkdir(path.directory(objectfile)) + end - 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) + batchcmds:set_depmtime(os.mtime(bmifile)) + batchcmds:set_depcache(target:dependfile(bmifile)) + + table.insert(flags, modulefileflag .. bmifile) end - return public_flags, private_flags + 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 diff --git a/xmake/rules/c++/modules/modules_support/gcc.lua b/xmake/rules/c++/modules/modules_support/gcc.lua index dba8b7e79..23e89a30b 100644 --- a/xmake/rules/c++/modules/modules_support/gcc.lua +++ b/xmake/rules/c++/modules/modules_support/gcc.lua @@ -149,77 +149,91 @@ 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) + 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)) - 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 + batchcmds:set_depmtime(os.mtime(bmifile)) + batchcmds:set_depcache(target:dependfile(bmifile)) + end + end +end - 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 +-- generate target user header units +function generate_user_headerunits(target, batchcmds, headerunits, opt) + local compinst = target:compiler("cxx") + local mapper_file = _get_module_mapper() - 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 cachedirs + local cachedir = common.modules_cachedir(target) - batchcmds:add_depfiles(headerunit.path) - batchcmds:set_depmtime(os.mtime(bmifile)) - batchcmds:set_depcache(target:dependfile(bmifile)) - end + -- 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 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 + 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)) + 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 - 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) + batchcmds:set_depmtime(os.mtime(bmifile)) + batchcmds:set_depcache(target:dependfile(bmifile)) end end 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) + local projectdir = os.projectdir() for _, objectfile in ipairs(objectfiles) do local m = modules[objectfile] diff --git a/xmake/rules/c++/modules/modules_support/msvc.lua b/xmake/rules/c++/modules/modules_support/msvc.lua index fa5741676..5006b4d9f 100644 --- a/xmake/rules/c++/modules/modules_support/msvc.lua +++ b/xmake/rules/c++/modules/modules_support/msvc.lua @@ -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,84 @@ 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 = {} 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 + batchcmds:set_depmtime(os.mtime(bmifile)) + batchcmds:set_depcache(target:dependfile(bmifile)) - 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}) + local flag = {headerunitflag .. ":angle", headerunit.name .. "=" .. headerunit.name .. get_bmi_extension()} + table.join2(flags, flag) + end + 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() + 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):sub(3)) + end + if not os.isdir(outputdir) then + os.mkdir(outputdir) 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 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) + batchcmds:set_depmtime(os.mtime(bmifile)) + batchcmds:set_depcache(target:dependfile(bmifile)) + batchcmds:set_depmtime(os.mtime(objectfile)) + batchcmds:set_depcache(target:dependfile(objectfile)) + + local flag = {headerunitflag .. headerunit.type, headerunit.name .. "=" .. path.relative(bmifile, cachedir)} + table.join2(flags, flag) + target:add("objectfiles", objectfile) end - return public_flags, private_flags + return flags end -- build module files diff --git a/xmake/rules/c++/modules/xmake.lua b/xmake/rules/c++/modules/xmake.lua index a1d6fdca4..7c68f25e0 100644 --- a/xmake/rules/c++/modules/xmake.lua +++ b/xmake/rules/c++/modules/xmake.lua @@ -91,15 +91,22 @@ rule("c++.build.modules.builder") -- get headerunits info 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 - headerunits = headerunits or {} local unittype = r.method == "include-angle" and ":angle" or ":quote" - table.insert(headerunits, {name = name, path = r.path, type = unittype, stl = stl_headers.is_stl_header(name)}) + + if stl_headers.is_stl_header(name) then + stl_headerunits = stl_headerunits or {} + table.insert(stl_headerunits, {name = name, path = r.path, type = unittype}) + else + headerunits = headerunits or {} + table.insert(headerunits, {name = name, path = r.path, type = unittype,}) + end end end end @@ -107,17 +114,22 @@ rule("c++.build.modules.builder") -- generate headerunits local headerunits_flags - local private_headerunits_flags local modules_support = common.modules_support(target) + -- build stl header units as other headerunits may need them + if stl_headerunits then + headerunits_flags = headerunits_flags or {} + table.join2(headerunits_flags, modules_support.generate_stl_headerunits(target, batchcmds, stl_headerunits, opt)) + + -- force STL header unit generation + batchcmds:runcmds(opt) + end if headerunits then - headerunits_flags, private_headerunits_flags = modules_support.generate_headerunits(target, batchcmds, headerunits, opt) + headerunits_flags = headerunits_flags or {} + table.join2(headerunits_flags, modules_support.generate_user_headerunits(target, batchcmds, headerunits, opt)) end if headerunits_flags then target:add("cxxflags", headerunits_flags, {force = true, expand = false}) end - if private_headerunits_flags then - target:add("cxxflags", private_headerunits_flags, {force = true, expand = false}) - end -- topological sort local objectfiles = common.sort_modules_by_dependencies(sourcebatch.objectfiles, modules) |
