diff options
| author | Arthur LAURENT <[email protected]> | 2022-08-06 23:52:08 +0200 |
|---|---|---|
| committer | Arthur LAURENT <[email protected]> | 2022-08-06 23:52:45 +0200 |
| commit | f085566ba853eb16c8658da1a38caa3a5e5728d3 (patch) | |
| tree | bfc2501a3955f114d863982d733a0700cf6351d9 /xmake/rules/c++/modules/modules_support/msvc.lua | |
| parent | 2486a47e5997a5e3183e135a2ac86df4c83f5a30 (diff) | |
feed the linker with the header unit object files
Diffstat (limited to 'xmake/rules/c++/modules/modules_support/msvc.lua')
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/msvc.lua | 105 |
1 files changed, 71 insertions, 34 deletions
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 |
