From 57ac4f46f10e8525d4a5dec0e6c4c19f1ac35ab7 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sat, 6 Aug 2022 06:24:34 +0200 Subject: Implement module mapper file for MSVC --- xmake/rules/c++/modules/modules_support/common.lua | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'xmake/rules/c++/modules/modules_support/common.lua') diff --git a/xmake/rules/c++/modules/modules_support/common.lua b/xmake/rules/c++/modules/modules_support/common.lua index c91f52a9b..e5c8285b5 100644 --- a/xmake/rules/c++/modules/modules_support/common.lua +++ b/xmake/rules/c++/modules/modules_support/common.lua @@ -448,18 +448,19 @@ end function generate_headerunits_for_batchcmds(target, batchcmds, sourcebatch, modules, opt) -- get headerunits info - local headerunits, stl_headerunits = get_headerunits(target, sourcebatch, modules) + local user_headerunits, stl_headerunits = get_headerunits(target, sourcebatch, modules) -- generate headerunits -- build stl header units as other headerunits may need them - local headerunits_flags - if stl_headerunits then - headerunits_flags = headerunits_flags or {} + if stl_headerunits or user_headerunits then + local headerunits_flags = localcache():get("headerunits_flags") + if stl_headerunits then + modules_support(target).generate_stl_headerunits_for_batchcmds(target, batchcmds, stl_headerunits, opt) table.join2(headerunits_flags, modules_support(target).generate_stl_headerunits_for_batchcmds(target, batchcmds, stl_headerunits, opt)) - end - if headerunits then - headerunits_flags = headerunits_flags or {} - table.join2(headerunits_flags, modules_support(target).generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits, opt)) + end + if user_headerunits then + modules_support(target).generate_user_headerunits_for_batchcmds(target, batchcmds, user_headerunits, opt) + end end return headerunits_flags end -- cgit v1.3.1 From dfbb0c6a93a76a1777682a485be3791a7cd6bd5c Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sat, 6 Aug 2022 23:49:02 +0200 Subject: Add missing C++ header and support experimental/ --- xmake/rules/c++/modules/modules_support/common.lua | 1 + xmake/rules/c++/modules/modules_support/msvc.lua | 2 +- xmake/rules/c++/modules/modules_support/stl_headers.lua | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'xmake/rules/c++/modules/modules_support/common.lua') diff --git a/xmake/rules/c++/modules/modules_support/common.lua b/xmake/rules/c++/modules/modules_support/common.lua index e5c8285b5..bd1603876 100644 --- a/xmake/rules/c++/modules/modules_support/common.lua +++ b/xmake/rules/c++/modules/modules_support/common.lua @@ -44,6 +44,7 @@ function stlmodules_cachedir(target) local stlcachedir = path.join(config.buildir(), "stlmodules", "cache") if not os.isdir(stlcachedir) then os.mkdir(stlcachedir) + os.mkdir(path.join(stlcachedir, "experimental")) end return stlcachedir end diff --git a/xmake/rules/c++/modules/modules_support/msvc.lua b/xmake/rules/c++/modules/modules_support/msvc.lua index dc6739724..d0a5ec08b 100644 --- a/xmake/rules/c++/modules/modules_support/msvc.lua +++ b/xmake/rules/c++/modules/modules_support/msvc.lua @@ -170,7 +170,7 @@ function generate_stl_headerunits_for_batchcmds(target, batchcmds, headerunits, 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}) - _add_module_to_mapper(mapper_file, headerunitflag .. ":angle", headerunit.name .. "=" .. headerunit.name .. get_bmi_extension()) + _add_module_to_mapper(mapper_file, headerunitflag .. ":angle", headerunit.name .. "=" .. path.filename(headerunit.name) .. get_bmi_extension()) end depmtime = math.max(depmtime, os.mtime(bmifile)) end diff --git a/xmake/rules/c++/modules/modules_support/stl_headers.lua b/xmake/rules/c++/modules/modules_support/stl_headers.lua index 849184ee5..599e2830c 100644 --- a/xmake/rules/c++/modules/modules_support/stl_headers.lua +++ b/xmake/rules/c++/modules/modules_support/stl_headers.lua @@ -103,6 +103,7 @@ function _stl_headers() "type_traits", "string_view", "stdexcept", + "condition_variable", "print", "flat_map", "flat_set", @@ -127,6 +128,7 @@ function _stl_headers() "cwctype", "cfenv", "cmath", + "ctime", "clocale", "cstdio"} end @@ -143,6 +145,9 @@ end -- is stl header? function is_stl_header(header) + if header:startswith("experimental/") then + header = header:sub(14, -1) + end return get_stl_headers():has(header) end -- cgit v1.3.1 From f085566ba853eb16c8658da1a38caa3a5e5728d3 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sat, 6 Aug 2022 23:52:08 +0200 Subject: feed the linker with the header unit object files --- xmake/rules/c++/modules/modules_support/common.lua | 5 +- xmake/rules/c++/modules/modules_support/msvc.lua | 105 ++++++++++++++------- 2 files changed, 72 insertions(+), 38 deletions(-) (limited to 'xmake/rules/c++/modules/modules_support/common.lua') diff --git a/xmake/rules/c++/modules/modules_support/common.lua b/xmake/rules/c++/modules/modules_support/common.lua index bd1603876..e32637abf 100644 --- a/xmake/rules/c++/modules/modules_support/common.lua +++ b/xmake/rules/c++/modules/modules_support/common.lua @@ -252,7 +252,6 @@ function _topological_sort_visit(node, nodes, modules, output) assert(not node.tempmarked) node.tempmarked = true local m1 = modules[node.objectfile] - assert(m1 and m1.provides) for _, n in ipairs(nodes) do if not n.tempmarked then local m2 = modules[n.objectfile] @@ -293,7 +292,7 @@ function sort_modules_by_dependencies(objectfiles, modules) local nodes = {} for _, objectfile in ipairs(objectfiles) do local m = modules[objectfile] - if m and m.provides then + if m then table.insert(nodes, {marked = false, tempmarked = false, objectfile = objectfile}) end end @@ -457,13 +456,11 @@ function generate_headerunits_for_batchcmds(target, batchcmds, sourcebatch, modu local headerunits_flags = localcache():get("headerunits_flags") if stl_headerunits then modules_support(target).generate_stl_headerunits_for_batchcmds(target, batchcmds, stl_headerunits, opt) - table.join2(headerunits_flags, modules_support(target).generate_stl_headerunits_for_batchcmds(target, batchcmds, stl_headerunits, opt)) end if user_headerunits then modules_support(target).generate_user_headerunits_for_batchcmds(target, batchcmds, user_headerunits, opt) end end - return headerunits_flags end -- build modules for batchjobs, TODO diff --git a/xmake/rules/c++/modules/modules_support/msvc.lua b/xmake/rules/c++/modules/modules_support/msvc.lua index af73f80af..b54767ee6 100644 --- a/xmake/rules/c++/modules/modules_support/msvc.lua +++ b/xmake/rules/c++/modules/modules_support/msvc.lua @@ -36,6 +36,15 @@ function _get_module_mapper() return mapper_file end +-- get and create the path of linker arguments +function _get_linker_argument_file() + local linker_file = path.join(config.buildir(), "linkargs.txt") + if not os.isfile(linker_file) then + io.writefile(linker_file, "") + end + return linker_file +end + -- add a module or header unit into the mapper -- -- e.g @@ -45,6 +54,7 @@ end function _add_module_to_mapper(file, argument, module) for line in io.lines(file) do if line:startswith(argument .. " " .. module) then + return end end local f = io.open(file, "a") @@ -52,11 +62,28 @@ function _add_module_to_mapper(file, argument, module) f:close() end +-- add an objectfile to the linker args +-- +-- e.g +-- foo.obj +-- +function _add_objectfile_to_link_arguments(file, objectfile) + for line in io.lines(file) do + if line:startswith(objectfile) then + return + end + end + local f = io.open(file, "a") + f:print(objectfile) + f:close() +end + -- load module support for the current target function load(target) local cachedir = common.modules_cachedir(target) local stlcachedir = common.stlmodules_cachedir(target) local mapper_file = _get_module_mapper() + local linker_file = _get_linker_argument_file() -- get flags local modulesflag = get_modulesflag(target) @@ -66,9 +93,15 @@ function load(target) target:add("cxxflags", modulesflag) target:add("cxxflags", {ifcsearchdirflag, cachedir}, {force = true, expand = false}) target:add("cxxflags", {ifcsearchdirflag, stlcachedir}, {force = true, expand = false}) - target:add("cxxflags", "@" .. mapper_file, {force = true, expand = false}) + target:add("cxxflags", {ifcsearchdirflag, path.join(stlcachedir, "experimental")}, {force = true, expand = false}) + target:add("cxxflags", "@" .. mapper_file, {force = true}) + + local linker_file_flag = "@".. linker_file + target:add("ldflags", linker_file_flag, {force = true}) + target:add("arflags", linker_file_flag, {force = true}) + target:add("shflags", linker_file_flag, {force = true}) - -- add stdifcdir in case of if the user want to use Microsoft modularised STL + -- add stdifcdir in case of if the user ask for it if target:values("msvc.modules.stdifcdir") then local stdifcdirflag = get_stdifcdirflag(target) for _, toolchain_inst in ipairs(target:toolchains()) do @@ -114,7 +147,7 @@ function generate_dependencies(target, sourcebatch, opt) local toolchain = target:toolchain("msvc") local vcvars = toolchain:config("vcvars") local scandependenciesflag = get_scandependenciesflag(target) - local common_args = {"/TP", scandependenciesflag} + local common_args = {"-TP", scandependenciesflag} local cachedir = common.modules_cachedir(target) local changed = false for _, sourcefile in ipairs(sourcebatch.sourcefiles) do @@ -130,7 +163,7 @@ function generate_dependencies(target, sourcebatch, opt) local jsonfile = path.join(outputdir, path.filename(sourcefile) .. ".json") if scandependenciesflag then - local args = {jsonfile, sourcefile, "/Fo" .. target:objectfile(sourcefile)} + local args = {jsonfile, sourcefile, "-Fo" .. target:objectfile(sourcefile)} os.vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, args), {envs = vcvars}) else common.fallback_generate_dependencies(target, jsonfile, sourcefile) @@ -150,6 +183,7 @@ function generate_stl_headerunits_for_batchcmds(target, batchcmds, headerunits, local toolchain = target:toolchain("msvc") local vcvars = toolchain:config("vcvars") local mapper_file = _get_module_mapper() + local linker_file = _get_linker_argument_file() -- get flags local exportheaderflag = get_exportheaderflag(target) @@ -162,17 +196,19 @@ function generate_stl_headerunits_for_batchcmds(target, batchcmds, headerunits, local stlcachedir = common.stlmodules_cachedir(target) -- build headerunits - local common_args = {"/TP", exportheaderflag, "/c"} + local common_args = {"-TP", exportheaderflag, "-c"} local objectfiles = {} local depmtime = 0 for _, headerunit in ipairs(headerunits) do 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} + local objectfile = bmifile .. ".obj" + if not os.isfile(bmifile) or not os.isfile(objectfile) then + local args = {headernameflag .. ":angle", headerunit.name, ifcoutputflag, stlcachedir, "-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}), args), {envs = vcvars}) + batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, args), {envs = vcvars}) _add_module_to_mapper(mapper_file, headerunitflag .. ":angle", headerunit.name .. "=" .. path.filename(headerunit.name) .. get_bmi_extension()) + _add_objectfile_to_link_arguments(linker_file, objectfile) end depmtime = math.max(depmtime, os.mtime(bmifile)) end @@ -185,6 +221,7 @@ function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits, local toolchain = target:toolchain("msvc") local vcvars = toolchain:config("vcvars") local mapper_file = _get_module_mapper() + local linker_file = _get_linker_argument_file() -- get flags local exportheaderflag = get_exportheaderflag(target) @@ -197,7 +234,7 @@ function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits, local cachedir = common.modules_cachedir(target) -- build headerunits - local common_args = {"/TP", exportheaderflag, "/c"} + local common_args = {"-TP", exportheaderflag, "-c"} local objectfiles = {} local projectdir = os.projectdir() local depmtime = 0 @@ -223,8 +260,8 @@ function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits, batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, args), {envs = vcvars}) batchcmds:add_depfiles(headerunit.path) _add_module_to_mapper(mapper_file, headerunitflag .. headerunit.type, headerunit.name .. "=" .. path.relative(bmifile, cachedir)) + _add_objectfile_to_link_arguments(linker_file, objectfile) - target:add("objectfiles", objectfile) depmtime = math.max(depmtime, os.mtime(bmifile)) end batchcmds:set_depmtime(depmtime) @@ -245,7 +282,7 @@ function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, op local referenceflag = get_referenceflag(target) -- build modules - local common_args = {"/TP"} + local common_args = {"-TP"} local depmtime = 0 for _, objectfile in ipairs(objectfiles) do local m = modules[objectfile] @@ -263,7 +300,7 @@ function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, op end local bmifile = provide.bmi - local args = {"/c", "/Fo" .. objectfile, interfaceflag, ifcoutputflag, bmifile, provide.sourcefile} + 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)) @@ -288,8 +325,8 @@ function get_modulesflag(target) local modulesflag = _g.modulesflag if modulesflag == nil then local compinst = target:compiler("cxx") - if compinst:has_flags("/experimental:module", "cxxflags", {flagskey = "cl_experimental_module"}) then - modulesflag = "/experimental:module" + if compinst:has_flags("-experimental:module", "cxxflags", {flagskey = "cl_experimental_module"}) then + modulesflag = "-experimental:module" end assert(modulesflag, "compiler(msvc): does not support c++ module!") _g.modulesflag = modulesflag or false @@ -301,8 +338,8 @@ function get_ifcoutputflag(target) local ifcoutputflag = _g.ifcoutputflag if ifcoutputflag == nil then local compinst = target:compiler("cxx") - if compinst:has_flags("/ifcOutput", "cxxflags", {flagskey = "cl_ifc_output"}) then - ifcoutputflag = "/ifcOutput" + if compinst:has_flags("-ifcOutput", "cxxflags", {flagskey = "cl_ifc_output"}) then + ifcoutputflag = "-ifcOutput" end assert(ifcoutputflag, "compiler(msvc): does not support c++ module!") _g.ifcoutputflag = ifcoutputflag or false @@ -314,8 +351,8 @@ function get_ifcsearchdirflag(target) local ifcsearchdirflag = _g.ifcsearchdirflag if ifcsearchdirflag == nil then local compinst = target:compiler("cxx") - if compinst:has_flags("/ifcSearchDir", "cxxflags", {flagskey = "cl_ifc_search_dir"}) then - ifcsearchdirflag = "/ifcSearchDir" + if compinst:has_flags("-ifcSearchDir", "cxxflags", {flagskey = "cl_ifc_search_dir"}) then + ifcsearchdirflag = "-ifcSearchDir" end assert(ifcsearchdirflag, "compiler(msvc): does not support c++ module!") _g.ifcsearchdirflag = ifcsearchdirflag or false @@ -327,8 +364,8 @@ function get_interfaceflag(target) local interfaceflag = _g.interfaceflag if interfaceflag == nil then local compinst = target:compiler("cxx") - if compinst:has_flags("/interface", "cxxflags", {flagskey = "cl_interface"}) then - interfaceflag = "/interface" + if compinst:has_flags("-interface", "cxxflags", {flagskey = "cl_interface"}) then + interfaceflag = "-interface" end assert(interfaceflag, "compiler(msvc): does not support c++ module!") _g.interfaceflag = interfaceflag or false @@ -340,8 +377,8 @@ function get_referenceflag(target) local referenceflag = _g.referenceflag if referenceflag == nil then local compinst = target:compiler("cxx") - if compinst:has_flags("/reference", "cxxflags", {flagskey = "cl_reference"}) then - referenceflag = "/reference" + if compinst:has_flags("-reference", "cxxflags", {flagskey = "cl_reference"}) then + referenceflag = "-reference" end assert(referenceflag, "compiler(msvc): does not support c++ module!") _g.referenceflag = referenceflag or false @@ -353,9 +390,9 @@ function get_headernameflag(target) local headernameflag = _g.headernameflag if headernameflag == nil then local compinst = target:compiler("cxx") - if compinst:has_flags("/headerName:quote", "cxxflags", {flagskey = "cl_header_name_quote"}) and - compinst:has_flags("/headerName:angle", "cxxflags", {flagskey = "cl_header_name_angle"}) then - headernameflag = "/headerName" + if compinst:has_flags("-headerName:quote", "cxxflags", {flagskey = "cl_header_name_quote"}) and + compinst:has_flags("-headerName:angle", "cxxflags", {flagskey = "cl_header_name_angle"}) then + headernameflag = "-headerName" end _g.headernameflag = headernameflag or false end @@ -366,9 +403,9 @@ function get_headerunitflag(target) local headerunitflag = _g.headerunitflag if headerunitflag == nil then local compinst = target:compiler("cxx") - if compinst:has_flags("/headerUnit:quote", "cxxflags", {flagskey = "cl_header_unit_quote"}) and - compinst:has_flags("/headerUnit:angle", "cxxflags", {flagskey = "cl_header_unit_angle"}) then - headerunitflag = "/headerUnit" + if compinst:has_flags("-headerUnit:quote", "cxxflags", {flagskey = "cl_header_unit_quote"}) and + compinst:has_flags("-headerUnit:angle", "cxxflags", {flagskey = "cl_header_unit_angle"}) then + headerunitflag = "-headerUnit" end _g.headerunitflag = headerunitflag or false end @@ -380,8 +417,8 @@ function get_exportheaderflag(target) local exportheaderflag = _g.exportheaderflag if exportheaderflag == nil then local compinst = target:compiler("cxx") - if compinst:has_flags(modulesflag .. " /exportHeader", "cxxflags", {flagskey = "cl_export_header"}) then - exportheaderflag = "/exportHeader" + if compinst:has_flags(modulesflag .. " -exportHeader", "cxxflags", {flagskey = "cl_export_header"}) then + exportheaderflag = "-exportHeader" end _g.exportheaderflag = exportheaderflag or false end @@ -392,8 +429,8 @@ function get_stdifcdirflag(target) local stdifcdirflag = _g.stdifcdirflag if stdifcdirflag == nil then local compinst = target:compiler("cxx") - if compinst:has_flags("/stdIfcDir", "cxxflags", {flagskey = "cl_std_ifc_dir"}) then - stdifcdirflag = "/stdIfcDir" + if compinst:has_flags("-stdIfcDir", "cxxflags", {flagskey = "cl_std_ifc_dir"}) then + stdifcdirflag = "-stdIfcDir" end _g.stdifcdirflag = stdifcdirflag or false end @@ -405,7 +442,7 @@ function get_scandependenciesflag(target) if scandependenciesflag == nil then local compinst = target:compiler("cxx") local scan_dependencies_jsonfile = os.tmpfile() .. ".json" - if compinst:has_flags("/scanDependencies " .. scan_dependencies_jsonfile, "cxflags", {flagskey = "cl_scan_dependencies", + if compinst:has_flags("-scanDependencies " .. scan_dependencies_jsonfile, "cxflags", {flagskey = "cl_scan_dependencies", on_check = function (ok, errors) if os.isfile(scan_dependencies_jsonfile) then ok = true @@ -415,7 +452,7 @@ function get_scandependenciesflag(target) end return ok, errors end}) then - scandependenciesflag = "/scanDependencies" + scandependenciesflag = "-scanDependencies" end _g.scandependenciesflag = scandependenciesflag or false end -- cgit v1.3.1 From c39a7060382929321332cf4fc3c00efa533ea758 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 7 Aug 2022 02:36:46 +0200 Subject: Use target:add("xxflags") instead of passing a file --- xmake/rules/c++/modules/modules_support/common.lua | 3 +++ xmake/rules/c++/modules/modules_support/msvc.lua | 25 ++++++++++++++++------ xmake/rules/c++/modules/xmake.lua | 5 +++++ 3 files changed, 27 insertions(+), 6 deletions(-) (limited to 'xmake/rules/c++/modules/modules_support/common.lua') diff --git a/xmake/rules/c++/modules/modules_support/common.lua b/xmake/rules/c++/modules/modules_support/common.lua index e32637abf..aa1db3f0f 100644 --- a/xmake/rules/c++/modules/modules_support/common.lua +++ b/xmake/rules/c++/modules/modules_support/common.lua @@ -475,3 +475,6 @@ function build_modules_for_batchcmds(target, batchcmds, sourcebatch, modules, op modules_support(target).build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, opt) end +function append_headerunits_objectfiles(target) + modules_support(target).append_headerunits_objectfiles(target) +end \ No newline at end of file diff --git a/xmake/rules/c++/modules/modules_support/msvc.lua b/xmake/rules/c++/modules/modules_support/msvc.lua index b54767ee6..1d946d339 100644 --- a/xmake/rules/c++/modules/modules_support/msvc.lua +++ b/xmake/rules/c++/modules/modules_support/msvc.lua @@ -94,12 +94,6 @@ function load(target) target:add("cxxflags", {ifcsearchdirflag, cachedir}, {force = true, expand = false}) target:add("cxxflags", {ifcsearchdirflag, stlcachedir}, {force = true, expand = false}) target:add("cxxflags", {ifcsearchdirflag, path.join(stlcachedir, "experimental")}, {force = true, expand = false}) - target:add("cxxflags", "@" .. mapper_file, {force = true}) - - local linker_file_flag = "@".. linker_file - target:add("ldflags", linker_file_flag, {force = true}) - target:add("arflags", linker_file_flag, {force = true}) - target:add("shflags", linker_file_flag, {force = true}) -- add stdifcdir in case of if the user ask for it if target:values("msvc.modules.stdifcdir") then @@ -281,6 +275,11 @@ function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, op local interfaceflag = get_interfaceflag(target) local referenceflag = get_referenceflag(target) + -- add + for line in io.lines(mapper_file) do + target:add("cxxflags", line, {force = true}) + end + -- build modules local common_args = {"-TP"} local depmtime = 0 @@ -458,3 +457,17 @@ function get_scandependenciesflag(target) end return scandependenciesflag or nil end + +function append_headerunits_objectfiles(target) + local linker_file = _get_linker_argument_file() + + for line in io.lines(linker_file) do + if target:kind() == "binary" then + target:add("ldflags", line, {force = true}) + elseif target:kind() == "static" then + target:add("arflags", line, {force = true}) + elseif target:kind() == "shared" then + target:add("shflags", line, {force = true}) + end + end +end \ No newline at end of file diff --git a/xmake/rules/c++/modules/xmake.lua b/xmake/rules/c++/modules/xmake.lua index 5676dcb10..4117004cc 100644 --- a/xmake/rules/c++/modules/xmake.lua +++ b/xmake/rules/c++/modules/xmake.lua @@ -99,6 +99,11 @@ rule("c++.build.modules.builder") common.build_modules_for_batchcmds(target, batchcmds, sourcebatch, modules, opt) end) + before_link(function(target) + import("modules_support.common") + common.append_headerunits_objectfiles(target) + end) + -- install modules rule("c++.build.modules.install") set_extensions(".mpp", ".mxx", ".cppm", ".ixx") -- cgit v1.3.1 From 1c96d8379173130442227222c75e0caac6afb40b Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 7 Aug 2022 14:59:23 +0200 Subject: Use localcache instead of a file --- xmake/rules/c++/modules/modules_support/clang.lua | 52 ++++++-------- xmake/rules/c++/modules/modules_support/common.lua | 9 ++- xmake/rules/c++/modules/modules_support/gcc.lua | 4 -- xmake/rules/c++/modules/modules_support/msvc.lua | 81 ++++++---------------- 4 files changed, 51 insertions(+), 95 deletions(-) (limited to 'xmake/rules/c++/modules/modules_support/common.lua') diff --git a/xmake/rules/c++/modules/modules_support/clang.lua b/xmake/rules/c++/modules/modules_support/clang.lua index 28ee152bc..4749f7fe3 100644 --- a/xmake/rules/c++/modules/modules_support/clang.lua +++ b/xmake/rules/c++/modules/modules_support/clang.lua @@ -27,30 +27,21 @@ import("utils.progress") import("private.action.build.object", {alias = "objectbuilder"}) import("common") --- get and create the path of module mapper -function _get_module_mapper() - local mapper_file = path.join(config.buildir(), "mapper.txt") - if not os.isfile(mapper_file) then - io.writefile(mapper_file, "") - end - return mapper_file -end - -- add a module into the mapper -- -- e.g -- -fmodule-file=foo=build/.gens/Foo/rules/modules/cache/foo.pcm -- -function _add_module_to_mapper(target, file, module, bmi) +function _add_module_to_mapper(target, module, bmi) + local cache = common.localcache():get("mapflags") or {} local modulefileflag = get_modulefileflag(target) - for line in io.lines(file) do - if line:startswith(modulefileflag .. module) then - return - end + local mapflag = format("%s%s=%s", modulefileflag, module, bmi) + if table.contains(cache, mapflag) then + return end - local f = io.open(file, "a") - f:print("%s%s=%s", modulefileflag, module, bmi) - f:close() + table.insert(cache, mapflag) + common.localcache():set("mapflags", cache) + common.localcache():save("mapflags") end -- add a header unit into the mapper @@ -58,7 +49,18 @@ end -- e.g -- -fmodule-file=build/.gens/Foo/rules/modules/cache/foo.hpp.pcm -- -function _add_headerunit_to_mapper(target, file, bmi) +function _add_headerunit_to_mapper(target, bmi) + local cache = common.localcache():get("mapflags") or {} + local modulefileflag = get_modulefileflag(target) + local mapflag = format("%s%s", modulefileflag, bmi) + if table.contains(cache, mapflag) then + return + end + table.insert(cache, mapflag) + common.localcache():set("mapflags", cache) + common.localcache():save("mapflags") +end + local modulefileflag = get_modulefileflag(target) for line in io.lines(file) do if line:startswith(modulefileflag .. bmi) then @@ -74,7 +76,6 @@ end function load(target) local cachedir = common.modules_cachedir(target) local stlcachedir = common.stlmodules_cachedir(target) - local mapper_file = _get_module_mapper() -- get module and module cache flags local modulesflag = get_modulesflag(target) @@ -174,7 +175,6 @@ end -- generate target stl header units for batchcmds function generate_stl_headerunits_for_batchcmds(target, batchcmds, headerunits, opt) local compinst = target:compiler("cxx") - local mapper_file = _get_module_mapper() -- get cachedirs local stlcachedir = common.stlmodules_cachedir(target) @@ -195,7 +195,7 @@ function generate_stl_headerunits_for_batchcmds(target, batchcmds, headerunits, -- libc++ have a builtin module mapper if not target:data_set("cxx.modules.use_libc++") then - _add_headerunit_to_mapper(target, mapper_file, bmifile) + _add_headerunit_to_mapper(target, bmifile) end end depmtime = math.max(depmtime, os.mtime(bmifile)) @@ -207,7 +207,6 @@ end function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits, opt) local compinst = target:compiler("cxx") assert(has_headerunitsupport(target), "compiler(clang): does not support c++ header units!") - local mapper_file = _get_module_mapper() -- get cachedirs local cachedir = common.modules_cachedir(target) @@ -248,7 +247,7 @@ function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits, 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) - _add_headerunit_to_mapper(target, mapper_file, bmifile) + _add_headerunit_to_mapper(target, bmifile) depmtime = math.max(depmtime, os.mtime(bmifile)) end @@ -258,7 +257,6 @@ end -- build module files for batchcmds function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, opt) local compinst = target:compiler("cxx") - local mapper_file = _get_module_mapper() -- get cachedirs local cachedir = common.modules_cachedir(target) @@ -298,7 +296,7 @@ function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, op batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, {bmifile}, {"-c", "-o", objectfile})) batchcmds:add_depfiles(provide.sourcefile) - _add_module_to_mapper(target, mapper_file, name, bmifile) + _add_module_to_mapper(target, name, bmifile) target:add("objectfiles", objectfile) depmtime = math.max(depmtime, os.mtime(bmifile)) @@ -459,8 +457,4 @@ function has_headerunitsupport(target) _g.support_headerunits = support_headerunits or false end return support_headerunits or nil -end - --- no .o generated by header units on Clang -function append_headerunits_objectfiles(target) end \ No newline at end of file diff --git a/xmake/rules/c++/modules/modules_support/common.lua b/xmake/rules/c++/modules/modules_support/common.lua index aa1db3f0f..34d014238 100644 --- a/xmake/rules/c++/modules/modules_support/common.lua +++ b/xmake/rules/c++/modules/modules_support/common.lua @@ -476,5 +476,12 @@ function build_modules_for_batchcmds(target, batchcmds, sourcebatch, modules, op end function append_headerunits_objectfiles(target) - modules_support(target).append_headerunits_objectfiles(target) + local cache = localcache():get("headerunit_objectfiles") or {} + if target:is_binary() then + target:add("ldflags", cache, {force = true}) + elseif target:is_static() == "static" then + target:add("arflags", cache, {force = true}) + elseif target:is_shared() == "shared" then + target:add("shflags", cache, {force = true}) + 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 e5deed0cd..99045cf54 100644 --- a/xmake/rules/c++/modules/modules_support/gcc.lua +++ b/xmake/rules/c++/modules/modules_support/gcc.lua @@ -336,8 +336,4 @@ function get_depoutputflag(target) _g.depoutputflag = depoutputflag or false end return depoutputflag or nil -end - --- no .o generated by header units on GCC -function append_headerunits_objectfiles(target) end \ No newline at end of file diff --git a/xmake/rules/c++/modules/modules_support/msvc.lua b/xmake/rules/c++/modules/modules_support/msvc.lua index 371cc1f50..b2b2e605a 100644 --- a/xmake/rules/c++/modules/modules_support/msvc.lua +++ b/xmake/rules/c++/modules/modules_support/msvc.lua @@ -27,39 +27,21 @@ import("utils.progress") import("private.action.build.object", {alias = "objectbuilder"}) import("common") --- get and create the path of module mapper -function _get_module_mapper() - local mapper_file = path.join(config.buildir(), "mapper.txt") - if not os.isfile(mapper_file) then - io.writefile(mapper_file, "") - end - return mapper_file -end - --- get and create the path of linker arguments -function _get_linker_argument_file() - local linker_file = path.join(config.buildir(), "linkargs.txt") - if not os.isfile(linker_file) then - io.writefile(linker_file, "") - end - return linker_file -end - -- add a module or header unit into the mapper -- -- e.g -- /headerUnit:angle cstdint=cstdint.ifc -- /headerUnit:angle glm/mat4x4.hpp=Users\arthu\AppData\Local\.xmake\packages\g\glm\0.9.9+8\91454f3ee0be416cb9c7452970a2300f\include\glm\mat4x4.hpp.ifc -- -function _add_module_to_mapper(file, argument, module) - for line in io.lines(file) do - if line:startswith(argument .. " " .. module) then - return - end +function _add_module_to_mapper(argument, module) + local cache = common.localcache():get("mapflags") or {} + local mapflag = format("%s %s", argument, module) + if table.contains(cache, mapflag) then + return end - local f = io.open(file, "a") - f:print("%s %s", argument, module) - f:close() + table.insert(cache, mapflag) + common.localcache():set("mapflags", cache) + common.localcache():save("mapflags") end -- add an objectfile to the linker args @@ -67,23 +49,20 @@ end -- e.g -- foo.obj -- -function _add_objectfile_to_link_arguments(file, objectfile) - for line in io.lines(file) do - if line:startswith(objectfile) then - return - end +function _add_objectfile_to_link_arguments(objectfile) + local cache = common.localcache():get("headerunit_objectfiles") or {} + if table.contains(cache, objectfile) then + return end - local f = io.open(file, "a") - f:print(objectfile) - f:close() + table.insert(cache, objectfile) + common.localcache():set("headerunit_objectfiles", cache) + common.localcache():save("headerunit_objectfiles") end -- load module support for the current target function load(target) local cachedir = common.modules_cachedir(target) local stlcachedir = common.stlmodules_cachedir(target) - local mapper_file = _get_module_mapper() - local linker_file = _get_linker_argument_file() -- get flags local modulesflag = get_modulesflag(target) @@ -176,8 +155,6 @@ function generate_stl_headerunits_for_batchcmds(target, batchcmds, headerunits, local compinst = target:compiler("cxx") local toolchain = target:toolchain("msvc") local vcvars = toolchain:config("vcvars") - local mapper_file = _get_module_mapper() - local linker_file = _get_linker_argument_file() -- get flags local exportheaderflag = get_exportheaderflag(target) @@ -202,7 +179,7 @@ function generate_stl_headerunits_for_batchcmds(target, batchcmds, headerunits, batchcmds:add_depfiles(headerunit.path) _add_module_to_mapper(headerunitflag .. ":angle", headerunit.name .. "=" .. path.filename(headerunit.name) .. get_bmi_extension()) - _add_objectfile_to_link_arguments(linker_file, objectfile) + _add_objectfile_to_link_arguments(objectfile) end depmtime = math.max(depmtime, os.mtime(bmifile)) end @@ -214,8 +191,6 @@ function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits, local compinst = target:compiler("cxx") local toolchain = target:toolchain("msvc") local vcvars = toolchain:config("vcvars") - local mapper_file = _get_module_mapper() - local linker_file = _get_linker_argument_file() -- get flags local exportheaderflag = get_exportheaderflag(target) @@ -254,7 +229,7 @@ function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits, batchcmds:add_depfiles(headerunit.path) _add_module_to_mapper(headerunitflag .. headerunit.type, headerunit.name .. "=" .. path.relative(bmifile, cachedir)) - _add_objectfile_to_link_arguments(linker_file, objectfile) + _add_objectfile_to_link_arguments(objectfile) depmtime = math.max(depmtime, os.mtime(bmifile)) end @@ -264,7 +239,6 @@ end -- build module files for batchcmds function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, opt) local compinst = target:compiler("cxx") - local mapper_file = _get_module_mapper() local toolchain = target:toolchain("msvc") local vcvars = toolchain:config("vcvars") @@ -277,9 +251,8 @@ function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, op local referenceflag = get_referenceflag(target) -- append module mapper flags - for line in io.lines(mapper_file) do - target:add("cxxflags", line, {force = true}) - end + local cache = common.localcache():get("mapflags") or {} + target:add("cxxflags", cache, {force = true}) -- build modules local common_args = {"-TP"} @@ -307,7 +280,7 @@ function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, op batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, args), {envs = vcvars}) batchcmds:add_depfiles(provide.sourcefile) - _add_module_to_mapper(mapper_file, referenceflag, name .. "=" .. path.filename(bmifile)) + _add_module_to_mapper(referenceflag, name .. "=" .. path.filename(bmifile)) target:add("objectfiles", objectfile) depmtime = math.max(depmtime, os.mtime(bmifile)) @@ -457,18 +430,4 @@ function get_scandependenciesflag(target) _g.scandependenciesflag = scandependenciesflag or false end return scandependenciesflag or nil -end - --- append .obj to final link -function append_headerunits_objectfiles(target) - local linker_file = _get_linker_argument_file() - for line in io.lines(linker_file) do - if target:is_binary() then - target:add("ldflags", line, {force = true}) - elseif target:is_static() == "static" then - target:add("arflags", line, {force = true}) - elseif target:is_shared() == "shared" then - target:add("shflags", line, {force = true}) - end - end end \ No newline at end of file -- cgit v1.3.1