From ae76b2aaf0c8ee2bbc1452999e57284a08ddba7c Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 22 Jan 2023 19:26:23 +0100 Subject: improve module compilation on msvc --- xmake/rules/c++/modules/modules_support/common.lua | 71 +++++++++++++++------- xmake/rules/c++/modules/modules_support/msvc.lua | 39 +++--------- 2 files changed, 57 insertions(+), 53 deletions(-) diff --git a/xmake/rules/c++/modules/modules_support/common.lua b/xmake/rules/c++/modules/modules_support/common.lua index 32c1b7be8..98eae7be9 100644 --- a/xmake/rules/c++/modules/modules_support/common.lua +++ b/xmake/rules/c++/modules/modules_support/common.lua @@ -20,6 +20,7 @@ -- imports import("core.base.json") +import("core.base.bytes") import("core.base.hashset") import("core.project.config") import("core.tool.compiler") @@ -43,7 +44,7 @@ end -- get stl modules cache directory function stlmodules_cachedir(target, opt) opt = opt or {} - local stlcachedir = path.join(config.buildir(), "stlmodules", "cache") + local stlcachedir = path.join(config.buildir(), "stlmodules", "cache", config.mode() or "release") if opt.mkdir and not os.isdir(stlcachedir) then os.mkdir(stlcachedir) os.mkdir(path.join(stlcachedir, "experimental")) @@ -287,7 +288,6 @@ end }]] function _parse_dependencies_data(target, moduleinfos) local modules - local cachedir = modules_cachedir(target) for _, moduleinfo in ipairs(moduleinfos) do assert(moduleinfo.version <= 1) for _, rule in ipairs(moduleinfo.rules) do @@ -297,24 +297,27 @@ function _parse_dependencies_data(target, moduleinfos) for _, provide in ipairs(rule.provides) do m.provides = m.provides or {} assert(provide["logical-name"]) - if provide["compiled-module-path"] then - if not path.is_absolute(provide["compiled-module-path"]) then - m.provides[provide["logical-name"]] = path.absolute(path.translate(provide["compiled-module-path"])) - else - m.provides[provide["logical-name"]] = path.translate(provide["compiled-module-path"]) + local bmifile = provide["compiled-module-path"] + -- try to find the compiled module path in outputs filed (MSVC doesn't generate compiled-module-path) + if not bmifile then + for _, output in ipairs(rule.outputs) do + if output:endswith(".ifc") or output:endswith(".pcm") or output:endswith(".bmi") then + bmifile = output + break + end + end + + -- we didn't found the compiled module path, so we assume it + if not bmifile then + local name = provide["logical-name"] .. bmi_extension(target) + bmifile = path.join(get_outputdir(target, name), name) end - else - -- assume path with name - local name = provide["logical-name"] .. bmi_extension(target) - -- partition ":" character is invalid path character on windows - -- @see https://github.com/xmake-io/xmake/issues/2954 - name = name:replace(":", "-") - m.provides[provide["logical-name"]] = { - bmi = path.join(cachedir, name), - sourcefile = moduleinfo.sourcefile, - interface = provide["is-interface"] - } end + m.provides[provide["logical-name"]] = { + bmi = bmifile, + sourcefile = moduleinfo.sourcefile, + interface = provide["is-interface"] + } end else m.cppfile = moduleinfo.sourcefile @@ -516,7 +519,7 @@ end ] }]] function fallback_generate_dependencies(target, jsonfile, sourcefile, preprocess_file) - local output = {version = 0, revision = 0, rules = {}} + local output = {version = 1, revision = 0, rules = {}} local rule = {outputs = {jsonfile}} rule["primary-output"] = target:objectfile(sourcefile) @@ -550,6 +553,7 @@ function fallback_generate_dependencies(target, jsonfile, sourcefile, preprocess if module_depname:startswith(":") then local module_name = (module_name_export or module_name_private or "") module_name = module_name:split(":")[1] + module_dep["unique-on-source-path"] = true module_depname = module_name .. module_depname elseif module_depname:startswith("\"") then module_depname = module_depname:sub(2, -2) @@ -569,12 +573,13 @@ function fallback_generate_dependencies(target, jsonfile, sourcefile, preprocess end if module_name_export or internal then - table.insert(rule.outputs, (module_name_export or module_name_private) .. bmi_extension(target)) + local outputdir = get_outputdir(target, sourcefile) local provide = {} provide["logical-name"] = module_name_export or module_name_private - provide["source-path"] = path.absolute(sourcefile, project.directory()) + provide["source-path"] = sourcefile provide["is-interface"] = not internal + provide["compiled-module-path"] = path.join(outputdir, (module_name_export or module_name_private) .. bmi_extension(target)) rule.provides = {} table.insert(rule.provides, provide) @@ -693,7 +698,6 @@ end function install_module_target(target) local sourcebatch = target:sourcebatches()["c++.build.modules.install"] - local cachedir = modules_cachedir(target) if sourcebatch and sourcebatch.sourcefiles then for _, sourcefile in ipairs(sourcebatch.sourcefiles) do local prefixdir = path.join("modules", target:name()) @@ -704,7 +708,8 @@ function install_module_target(target) local install = (fileconfig and not fileconfig.install) and false or true if install then target:add("installfiles", sourcefile, {prefixdir = prefixdir}) - local metafile = path.join(cachedir, path.filename(sourcefile) .. ".meta-info") + local outputdir = get_outputdir(target,sourcefile) + local metafile = path.join(outputdir, path.filename(sourcefile) .. ".meta-info") if os.exists(metafile) then target:add("installfiles", metafile, {prefixdir = prefixdir}) end @@ -712,3 +717,23 @@ function install_module_target(target) end end end + +function get_outputdir(target, module) + local cachedir = modules_cachedir(target) + local modulepath = module.path or module + local cached = localcache():get2("modules_paths", modulepath) + if cached then + if not os.exists(cached) then + os.mkdir(cached) + end + return cached + else + local hashed = hash.sha1(bytes(path.directory(modulepath) .. target:name())):sub(1, 6) + local moduledir = path.join(cachedir, hashed) + localcache():set2("modules_paths", modulepath, moduledir) + if not os.exists(moduledir) then + os.mkdir(moduledir) + end + return moduledir + end +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 3d4e03db2..e849c24b8 100644 --- a/xmake/rules/c++/modules/modules_support/msvc.lua +++ b/xmake/rules/c++/modules/modules_support/msvc.lua @@ -25,7 +25,6 @@ import("core.tool.compiler") import("core.project.project") import("core.project.depend") import("core.project.config") -import("core.base.hashset") import("core.base.semver") import("utils.progress") import("private.action.build.object", {alias = "objectbuilder"}) @@ -182,8 +181,8 @@ end function generate_dependencies(target, sourcebatch, opt) local msvc = target:toolchain("msvc") local scandependenciesflag = get_scandependenciesflag(target) + local ifcoutputflag = get_ifcoutputflag(target) local common_flags = {"-TP", scandependenciesflag} - local cachedir = common.modules_cachedir(target) local changed = false for _, sourcefile in ipairs(sourcebatch.sourcefiles) do local dependfile = target:dependfile(sourcefile) @@ -191,14 +190,11 @@ function generate_dependencies(target, sourcebatch, opt) if opt.progress then progress.show(opt.progress, "${color.build.object}generating.module.deps %s", sourcefile) end - local outputdir = path.join(cachedir, path.directory(path.relative(sourcefile, projectdir))) - if not os.isdir(outputdir) then - os.mkdir(outputdir) - end + local outputdir = common.get_outputdir(target, sourcefile) - local jsonfile = path.join(outputdir, path.filename(sourcefile) .. ".json") + local jsonfile = path.join(outputdir, path.filename(sourcefile) .. ".module.json") if scandependenciesflag and not target:policy("build.c++.msvc.fallbackscanner") then - local flags = {jsonfile, sourcefile, "-Fo" .. target:objectfile(sourcefile)} + local flags = {jsonfile, sourcefile, ifcoutputflag, outputdir, "-Fo" .. target:objectfile(sourcefile)} _compile(target, table.join(common_flags, flags), sourcefile) else common.fallback_generate_dependencies(target, jsonfile, sourcefile, function(file) @@ -311,8 +307,6 @@ end -- generate target user header units for batchcmds function generate_user_headerunits_for_batchjobs(target, batchjobs, headerunits, opt) - local cachedir = common.modules_cachedir(target) - -- get flags local exportheaderflag = get_exportheaderflag(target) local headerunitflag = get_headerunitflag(target) @@ -326,17 +320,10 @@ function generate_user_headerunits_for_batchjobs(target, batchjobs, headerunits, end, {rootjob = opt.rootjob}) -- build headerunits - 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 - -- 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 + local outputdir = common.get_outputdir(target, headerunit) local bmifilename = path.basename(objectfile) .. get_bmi_extension() local bmifile = path.join(outputdir, bmifilename) batchjobs:addjob(headerunit.name, function (index, total) @@ -368,7 +355,6 @@ end -- generate target user header units for batchcmds function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits, opt) - local cachedir = common.modules_cachedir(target) local exportheaderflag = get_exportheaderflag(target) local headerunitflag = get_headerunitflag(target) local headernameflag = get_headernameflag(target) @@ -376,18 +362,11 @@ function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits, assert(headerunitflag and headernameflag and exportheaderflag, "compiler(msvc): does not support c++ header units!") -- build headerunits - 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 + local outputdir = common.get_outputdir(target, headerunit) batchcmds:mkdir(outputdir) local bmifilename = path.basename(objectfile) .. get_bmi_extension() @@ -466,10 +445,10 @@ function build_modules_for_batchjobs(target, batchjobs, objectfiles, modules, op local fileconfig = target:fileconfig(cppfile) if fileconfig and fileconfig.install then batchjobs:addjob(name .. "_metafile", function(index, total) - local cachedir = common.modules_cachedir(target) - local metafilepath = path.join(cachedir, path.filename(cppfile) .. ".meta-info") + local outputdir = common.get_outputdir(target, cppfile) + local metafilepath = path.join(outputdir, path.filename(cppfile) .. ".meta-info") depend.on_changed(function() - progress.show(opt.progress, "${color.build.object}generating.module.metadata %s", name) + progress.show((index * 100) / total, "${color.build.object}generating.module.metadata %s", name) local metadata = common.generate_meta_module_info(target, name, cppfile, module.requires) json.savefile(metafilepath, metadata) -- cgit v1.3.1 From cd2be29f2bfc8e5bc85767b9ab182d3712e11532 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 22 Jan 2023 21:53:53 +0100 Subject: improve module compilation on gcc --- xmake/rules/c++/modules/modules_support/gcc.lua | 64 +++++++++---------------- 1 file changed, 23 insertions(+), 41 deletions(-) diff --git a/xmake/rules/c++/modules/modules_support/gcc.lua b/xmake/rules/c++/modules/modules_support/gcc.lua index 07b4d130b..722706603 100644 --- a/xmake/rules/c++/modules/modules_support/gcc.lua +++ b/xmake/rules/c++/modules/modules_support/gcc.lua @@ -74,7 +74,7 @@ function load(target) end target:add("cxxflags", {modulesflag, modulemapperflag .. path.translate(_get_module_mapper(target))}, {force = true, expand = false}) -- fix cxxabi issue, @see https://github.com/xmake-io/xmake/issues/2716#issuecomment-1225057760 - target:add("cxxflags", "-D_GLIBCXX_USE_CXX11_ABI=0") + -- target:add("cxxflags", "-D_GLIBCXX_USE_CXX11_ABI=0") end -- get includedirs for stl headers @@ -170,7 +170,6 @@ end -- generate dependency files function generate_dependencies(target, sourcebatch, opt) - local cachedir = common.modules_cachedir(target) local compinst = target:compiler("cxx") local common_args = {"-E", "-x", "c++"} local depformatflag = get_depflag(target, "p1689r5") or get_depflag(target, "trtbd") @@ -184,11 +183,7 @@ function generate_dependencies(target, sourcebatch, opt) progress.show(opt.progress, "${color.build.object}generating.module.deps %s", sourcefile) end - local outputdir = path.translate(path.join(cachedir, path.directory(path.relative(sourcefile, projectdir)))) - if not os.isdir(outputdir) then - os.mkdir(outputdir) - end - + local outputdir = common.get_outputdir(target, sourcefile) local jsonfile = path.translate(path.join(outputdir, path.filename(sourcefile) .. ".json")) if depformatflag and depfileflag and depoutputflag and not target:policy("build.c++.gcc.fallbackscanner") then local ifile = path.translate(path.join(outputdir, path.filename(sourcefile) .. ".i")) @@ -206,9 +201,14 @@ function generate_dependencies(target, sourcebatch, opt) local compinst = target:compiler("cxx") local compflags = compinst:compflags({sourcefile = file, target = target}) local flags = {} + local next_flag = false for _, flag in ipairs(compflags) do - if flag:startswith("-std") or (flag:startswith("-f") and not flag:startswith("-fmodules")) or flag:startswith("-D") or flag:startswith("-U") or flag:startswith("-I") or flag:startswith("-isystem") then + if flag == "-m64" or flag == "-g" or flag:startswith("-m") or flag:startswith("-std") or (flag:startswith("-f") and not flag:startswith("-fmodule")) or flag:startswith("-D") or flag:startswith("-U") or flag:startswith("-I") or flag:startswith("-isystem") or next_flag then table.insert(flags, flag) + next_flag = false + if flag:startswith("-isystem") then + next_flag = true + end end end local ifile = path.translate(path.join(outputdir, path.filename(file) .. ".i")) @@ -292,28 +292,21 @@ end function generate_user_headerunits_for_batchjobs(target, batchjobs, headerunits, opt) local compinst = target:compiler("cxx") local mapper_file = _get_module_mapper(target) - local cachedir = common.modules_cachedir(target) -- 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 outputdir local headerunit_path - 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)) - end - local bmifilename = path.basename(objectfile) .. get_bmi_extension() - local bmifile = (outputdir and path.join(outputdir, bmifilename) or bmifilename) if headerunit.type == ":quote" then headerunit_path = path.join(".", path.relative(headerunit.path, projectdir)) elseif headerunit.type == ":angle" then -- 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 + local objectfile = target:objectfile(headerunit_path) + local outputdir = common.get_outputdir(target, headerunit.path) + local bmifilename = path.basename(objectfile) .. get_bmi_extension() + local bmifile = path.join(outputdir, bmifilename) batchjobs:addjob(headerunit.name, function (index, total) depend.on_changed(function() progress.show((index * 100) / total, "${color.build.object}compiling.headerunit.$(mode) %s", headerunit.name) @@ -321,9 +314,6 @@ function generate_user_headerunits_for_batchjobs(target, batchjobs, headerunits, if not os.isdir(objectdir) then os.mkdir(objectdir) end - if not os.isdir(outputdir) then - os.mkdir(outputdir) - end -- generate headerunit local args = { "-c" } @@ -343,28 +333,13 @@ end -- generate target user header units for batchcmds function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits, opt) local mapper_file = _get_module_mapper(target) - local cachedir = common.modules_cachedir(target) -- 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) - 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)) - end - batchcmds:mkdir(outputdir) - - local bmifilename = path.basename(objectfile) .. get_bmi_extension() - local bmifile = (outputdir and path.join(outputdir, bmifilename) or bmifilename) - batchcmds:mkdir(path.directory(objectfile)) - - local flags = {"-c"} local headerunit_path + local flags = {"-c"} if headerunit.type == ":quote" then table.join2(flags, {"-I", path(path.relative(headerunit.path, projectdir)):directory(), "-x", "c++-user-header", headerunit.name}) headerunit_path = path.join(".", path.relative(headerunit.path, projectdir)) @@ -373,6 +348,14 @@ function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits, -- 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 + local objectfile = target:objectfile(headerunit_path) + local outputdir = common.get_outputdir(target, headerunit.path) + batchcmds:mkdir(outputdir) + + local bmifilename = path.basename(objectfile) .. get_bmi_extension() + local bmifile = (outputdir and path.join(outputdir, bmifilename) or bmifilename) + batchcmds:mkdir(path.directory(objectfile)) + batchcmds:show_progress(opt.progress, "${color.build.object}compiling.headerunit.$(mode) %s", headerunit.name) _batchcmds_compile(batchcmds, target, flags) @@ -417,8 +400,8 @@ function build_modules_for_batchjobs(target, batchjobs, objectfiles, modules, op local fileconfig = target:fileconfig(cppfile) if fileconfig and fileconfig.install then batchjobs:addjob(name .. "_metafile", function(index, total) - local cachedir = common.modules_cachedir(target) - local metafilepath = path.join(cachedir, path.filename(cppfile) .. ".meta-info") + local outputdir = common.get_outputdir(target, cppfile) + local metafilepath = path.join(outputdir, path.filename(cppfile) .. ".meta-info") depend.on_changed(function() progress.show(opt.progress, "${color.build.object}generating.module.metadata %s", name) local metadata = common.generate_meta_module_info(target, name, cppfile, module.requires) @@ -477,7 +460,6 @@ end -- build module files for batchcmds function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, opt) - local modulemapperflag = get_modulemapperflag(target) local mapper_file = _get_module_mapper(target) -- build modules -- cgit v1.3.1 From 33b8560d8ffb780bde7f73f4d81966d7962d47e3 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 22 Jan 2023 21:54:01 +0100 Subject: improve module compilation on clang --- xmake/rules/c++/modules/modules_support/clang.lua | 40 ++++++++--------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/xmake/rules/c++/modules/modules_support/clang.lua b/xmake/rules/c++/modules/modules_support/clang.lua index a6e195e22..e84848cc3 100644 --- a/xmake/rules/c++/modules/modules_support/clang.lua +++ b/xmake/rules/c++/modules/modules_support/clang.lua @@ -247,7 +247,6 @@ end -- generate dependency files function generate_dependencies(target, sourcebatch, opt) local changed = false - local cachedir = common.modules_cachedir(target) local projectdir = os.projectdir() for _, sourcefile in ipairs(sourcebatch.sourcefiles) do local dependfile = target:dependfile(sourcefile) @@ -256,11 +255,7 @@ function generate_dependencies(target, sourcebatch, opt) progress.show(opt.progress, "${color.build.object}generating.module.deps %s", sourcefile) end - local outputdir = path.translate(path.join(cachedir, path.directory(path.relative(sourcefile, projectdir)))) - if not os.isdir(outputdir) then - os.mkdir(outputdir) - end - + local outputdir = common.get_outputdir(target, sourcefile) local jsonfile = path.translate(path.join(outputdir, path.filename(sourcefile) .. ".json")) if has_clangscandepssupport(target) and not target:policy("build.c++.clang.fallbackscanner") then local clangscandeps = find_tool("clang-scan-deps") @@ -278,9 +273,14 @@ function generate_dependencies(target, sourcebatch, opt) local compinst = target:compiler("cxx") local compflags = compinst:compflags({sourcefile = file, target = target}) local flags = {} + local next_flag = false for _, flag in pairs(compflags) do - if flag:startswith("-stdlib") or (flag:startswith("-f") and not flag:startswith("-fmodules")) or flag:startswith("-D") or flag:startswith("-U") or flag:startswith("-I") or flag:startswith("-isystem") then + if flag == "-m64" or flag == "-g" or flag:startswith("-stdlib") or flag:startswith("-m") or (flag:startswith("-f") and not flag:startswith("-fmodule") and not flag:startswith("-fno-implicit-module-maps")) or flag:startswith("-D") or flag:startswith("-U") or flag:startswith("-I") or flag:startswith("-isystem") or next_flag then table.insert(flags, flag) + next_flag = false + if flag:startswith("-isystem") then + next_flag = true + end end end local ifile = path.translate(path.join(outputdir, path.filename(file) .. ".i")) @@ -401,7 +401,7 @@ function generate_user_headerunits_for_batchjobs(target, batchjobs, headerunits, assert(has_headerunitsupport(target), "compiler(clang): does not support c++ header units!") -- get cachedirs - local cachedir = common.modules_cachedir(target) + local cachedir = common.modules_cachedir(target, {mkdir = true}) local modulecachepathflag = get_modulecachepathflag(target) -- flush job @@ -410,19 +410,13 @@ function generate_user_headerunits_for_batchjobs(target, batchjobs, headerunits, end, {rootjob = opt.rootjob}) -- build headerunits - 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)) - end + local outputdir = common.get_outputdir(target, headerunit.path) local bmifilename = path.basename(objectfile) .. get_bmi_extension() - local bmifile = (outputdir and path.join(outputdir, bmifilename) or bmifilename) + local bmifile = path.join(outputdir, bmifilename) batchjobs:addjob(headerunit.name, function (index, total) depend.on_changed(function() progress.show((index * 100) / total, "${color.build.object}compiling.headerunit.$(mode) %s", headerunit.name) @@ -454,22 +448,16 @@ function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits, assert(has_headerunitsupport(target), "compiler(clang): does not support c++ header units!") -- get cachedirs - local cachedir = common.modules_cachedir(target) + local cachedir = common.modules_cachedir(target, {mkdir = true}) local modulecachepathflag = get_modulecachepathflag(target) -- build headerunits - 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 - outputdir = path.join(cachedir, path.directory(headerunit.path)) - end + local outputdir = common.get_outputdir(target, headerunit.path) batchcmds:mkdir(outputdir) local bmifilename = path.basename(objectfile) .. get_bmi_extension() @@ -535,8 +523,8 @@ function build_modules_for_batchjobs(target, batchjobs, objectfiles, modules, op local fileconfig = target:fileconfig(cppfile) if fileconfig and fileconfig.install then batchjobs:addjob(name .. "_metafile", function(index, total) - local cachedir = common.modules_cachedir(target) - local metafilepath = path.join(cachedir, path.filename(cppfile) .. ".meta-info") + local outputdir = common.get_outputdir(target, cppfile) + local metafilepath = path.join(outputdir, path.filename(cppfile) .. ".meta-info") depend.on_changed(function() progress.show(opt.progress, "${color.build.object}generating.module.metadata %s", name) local metadata = common.generate_meta_module_info(target, name, cppfile, module.requires) -- cgit v1.3.1 From e5709e2df72b30201941670a5b9d23f8ea1fc251 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 22 Jan 2023 22:02:20 +0100 Subject: revert wrong change --- xmake/rules/c++/modules/modules_support/gcc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xmake/rules/c++/modules/modules_support/gcc.lua b/xmake/rules/c++/modules/modules_support/gcc.lua index 722706603..ee3f547bd 100644 --- a/xmake/rules/c++/modules/modules_support/gcc.lua +++ b/xmake/rules/c++/modules/modules_support/gcc.lua @@ -74,7 +74,7 @@ function load(target) end target:add("cxxflags", {modulesflag, modulemapperflag .. path.translate(_get_module_mapper(target))}, {force = true, expand = false}) -- fix cxxabi issue, @see https://github.com/xmake-io/xmake/issues/2716#issuecomment-1225057760 - -- target:add("cxxflags", "-D_GLIBCXX_USE_CXX11_ABI=0") + target:add("cxxflags", "-D_GLIBCXX_USE_CXX11_ABI=0") end -- get includedirs for stl headers -- cgit v1.3.1 From 1294b1fa8b7022c711f148de258756794cf8ae66 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 23 Jan 2023 11:58:34 +0100 Subject: use uuid instead of sha1 for module cache directories --- xmake/rules/c++/modules/modules_support/common.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xmake/rules/c++/modules/modules_support/common.lua b/xmake/rules/c++/modules/modules_support/common.lua index 98eae7be9..a01c78710 100644 --- a/xmake/rules/c++/modules/modules_support/common.lua +++ b/xmake/rules/c++/modules/modules_support/common.lua @@ -728,7 +728,8 @@ function get_outputdir(target, module) end return cached else - local hashed = hash.sha1(bytes(path.directory(modulepath) .. target:name())):sub(1, 6) + local key = path.directory(modulepath) .. target:name() + local hashed = hash.uuid(key):split("-", {plain = true})[1]:lower() local moduledir = path.join(cachedir, hashed) localcache():set2("modules_paths", modulepath, moduledir) if not os.exists(moduledir) then -- cgit v1.3.1 From acedc8854cdf5e59915bfcf6fc1e979b91ff4d6b Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 23 Jan 2023 11:58:45 +0100 Subject: format --- xmake/rules/c++/modules/modules_support/clang.lua | 6 ++++-- xmake/rules/c++/modules/modules_support/gcc.lua | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/xmake/rules/c++/modules/modules_support/clang.lua b/xmake/rules/c++/modules/modules_support/clang.lua index e84848cc3..b341df0d4 100644 --- a/xmake/rules/c++/modules/modules_support/clang.lua +++ b/xmake/rules/c++/modules/modules_support/clang.lua @@ -274,8 +274,10 @@ function generate_dependencies(target, sourcebatch, opt) local compflags = compinst:compflags({sourcefile = file, target = target}) local flags = {} local next_flag = false - for _, flag in pairs(compflags) do - if flag == "-m64" or flag == "-g" or flag:startswith("-stdlib") or flag:startswith("-m") or (flag:startswith("-f") and not flag:startswith("-fmodule") and not flag:startswith("-fno-implicit-module-maps")) or flag:startswith("-D") or flag:startswith("-U") or flag:startswith("-I") or flag:startswith("-isystem") or next_flag then + for _, flag in ipairs(compflags) do + if flag == "-m64" or flag == "-g" or flag:startswith("-stdlib") or flag:startswith("-m") or + (flag:startswith("-f") and not flag:startswith("-fmodule") and not flag:startswith("-fno-implicit-module-maps")) or + flag:startswith("-D") or flag:startswith("-U") or flag:startswith("-I") or flag:startswith("-isystem") or next_flag then table.insert(flags, flag) next_flag = false if flag:startswith("-isystem") then diff --git a/xmake/rules/c++/modules/modules_support/gcc.lua b/xmake/rules/c++/modules/modules_support/gcc.lua index ee3f547bd..3ab790daf 100644 --- a/xmake/rules/c++/modules/modules_support/gcc.lua +++ b/xmake/rules/c++/modules/modules_support/gcc.lua @@ -203,7 +203,9 @@ function generate_dependencies(target, sourcebatch, opt) local flags = {} local next_flag = false for _, flag in ipairs(compflags) do - if flag == "-m64" or flag == "-g" or flag:startswith("-m") or flag:startswith("-std") or (flag:startswith("-f") and not flag:startswith("-fmodule")) or flag:startswith("-D") or flag:startswith("-U") or flag:startswith("-I") or flag:startswith("-isystem") or next_flag then + if flag == "-m64" or flag == "-g" or flag:startswith("-m") or flag:startswith("-std") or + (flag:startswith("-f") and not flag:startswith("-fmodule")) or flag:startswith("-D") or + flag:startswith("-U") or flag:startswith("-I") or flag:startswith("-isystem") or next_flag then table.insert(flags, flag) next_flag = false if flag:startswith("-isystem") then -- cgit v1.3.1 From bfc401680246307bb59874c53fb4c6bb2369255b Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 23 Jan 2023 12:28:01 +0100 Subject: revert wrong change --- xmake/rules/c++/modules/modules_support/common.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xmake/rules/c++/modules/modules_support/common.lua b/xmake/rules/c++/modules/modules_support/common.lua index a01c78710..7a43cd5f2 100644 --- a/xmake/rules/c++/modules/modules_support/common.lua +++ b/xmake/rules/c++/modules/modules_support/common.lua @@ -310,6 +310,9 @@ function _parse_dependencies_data(target, moduleinfos) -- we didn't found the compiled module path, so we assume it if not bmifile then local name = provide["logical-name"] .. bmi_extension(target) + -- partition ":" character is invalid path character on windows + -- @see https://github.com/xmake-io/xmake/issues/2954 + name = name:replace(":", "-") bmifile = path.join(get_outputdir(target, name), name) end end -- cgit v1.3.1 From 59ad2808f83e7e4da2d52991bf47abe537bec642 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 23 Jan 2023 12:30:50 +0100 Subject: clang missing flag --- xmake/rules/c++/modules/modules_support/clang.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xmake/rules/c++/modules/modules_support/clang.lua b/xmake/rules/c++/modules/modules_support/clang.lua index b341df0d4..c88a844a8 100644 --- a/xmake/rules/c++/modules/modules_support/clang.lua +++ b/xmake/rules/c++/modules/modules_support/clang.lua @@ -277,7 +277,8 @@ function generate_dependencies(target, sourcebatch, opt) for _, flag in ipairs(compflags) do if flag == "-m64" or flag == "-g" or flag:startswith("-stdlib") or flag:startswith("-m") or (flag:startswith("-f") and not flag:startswith("-fmodule") and not flag:startswith("-fno-implicit-module-maps")) or - flag:startswith("-D") or flag:startswith("-U") or flag:startswith("-I") or flag:startswith("-isystem") or next_flag then + flag:startswith("-D") or flag:startswith("-U") or flag:startswith("-I") or flag:startswith("-isystem") or next_flag or + flag:startswith("-iframework") then table.insert(flags, flag) next_flag = false if flag:startswith("-isystem") then -- cgit v1.3.1 From 270b45e610c37472c3cb7a9c23cd3cf52e3f1232 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 23 Jan 2023 15:38:48 +0100 Subject: simplify fallback dependency parser --- xmake/rules/c++/modules/modules_support/clang.lua | 18 +++++------------- xmake/rules/c++/modules/modules_support/gcc.lua | 23 ++++++++--------------- 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/xmake/rules/c++/modules/modules_support/clang.lua b/xmake/rules/c++/modules/modules_support/clang.lua index c88a844a8..aeb8ebd53 100644 --- a/xmake/rules/c++/modules/modules_support/clang.lua +++ b/xmake/rules/c++/modules/modules_support/clang.lua @@ -272,22 +272,14 @@ function generate_dependencies(target, sourcebatch, opt) common.fallback_generate_dependencies(target, jsonfile, sourcefile, function(file) local compinst = target:compiler("cxx") local compflags = compinst:compflags({sourcefile = file, target = target}) - local flags = {} - local next_flag = false - for _, flag in ipairs(compflags) do - if flag == "-m64" or flag == "-g" or flag:startswith("-stdlib") or flag:startswith("-m") or - (flag:startswith("-f") and not flag:startswith("-fmodule") and not flag:startswith("-fno-implicit-module-maps")) or - flag:startswith("-D") or flag:startswith("-U") or flag:startswith("-I") or flag:startswith("-isystem") or next_flag or - flag:startswith("-iframework") then - table.insert(flags, flag) - next_flag = false - if flag:startswith("-isystem") then - next_flag = true - end + for i, flag in ipairs(compflags) do + -- exclude -fmodule* and -std=c++/gnu++* flags because, when they are set clang try to find bmi of imported modules but they don't exists a this point of compilation + if flag:startswith("-fmodule") or flag:startswith("-std=c++") or flag:startswith("-std=gnu++") then + table.remove(compflags, i) end end local ifile = path.translate(path.join(outputdir, path.filename(file) .. ".i")) - os.vrunv(compinst:program(), table.join(flags, {"-E", "-x", "c++", file, "-o", ifile})) + os.vrunv(compinst:program(), table.join(compflags, {"-E", "-x", "c++", file, "-o", ifile})) local content = io.readfile(ifile) os.rm(ifile) return content diff --git a/xmake/rules/c++/modules/modules_support/gcc.lua b/xmake/rules/c++/modules/modules_support/gcc.lua index 3ab790daf..2864e41a4 100644 --- a/xmake/rules/c++/modules/modules_support/gcc.lua +++ b/xmake/rules/c++/modules/modules_support/gcc.lua @@ -200,21 +200,14 @@ function generate_dependencies(target, sourcebatch, opt) common.fallback_generate_dependencies(target, jsonfile, sourcefile, function(file) local compinst = target:compiler("cxx") local compflags = compinst:compflags({sourcefile = file, target = target}) - local flags = {} - local next_flag = false - for _, flag in ipairs(compflags) do - if flag == "-m64" or flag == "-g" or flag:startswith("-m") or flag:startswith("-std") or - (flag:startswith("-f") and not flag:startswith("-fmodule")) or flag:startswith("-D") or - flag:startswith("-U") or flag:startswith("-I") or flag:startswith("-isystem") or next_flag then - table.insert(flags, flag) - next_flag = false - if flag:startswith("-isystem") then - next_flag = true - end + for i, flag in ipairs(compflags) do + -- exclude -fmodule* flags because, when they are set gcc try to find bmi of imported modules but they don't exists a this point of compilation + if flag:startswith("-fmodule") then + table.remove(compflags, i) end end local ifile = path.translate(path.join(outputdir, path.filename(file) .. ".i")) - os.vrunv(compinst:program(), table.join(common_args, flags, {file, "-o", ifile})) + os.vrunv(compinst:program(), table.join(common_args, compflags, {file, "-o", ifile})) local content = io.readfile(ifile) os.rm(ifile) return content @@ -340,8 +333,8 @@ function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits, local projectdir = os.projectdir() local depmtime = 0 for _, headerunit in ipairs(headerunits) do - local headerunit_path local flags = {"-c"} + local headerunit_path if headerunit.type == ":quote" then table.join2(flags, {"-I", path(path.relative(headerunit.path, projectdir)):directory(), "-x", "c++-user-header", headerunit.name}) headerunit_path = path.join(".", path.relative(headerunit.path, projectdir)) @@ -358,7 +351,6 @@ function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits, local bmifile = (outputdir and path.join(outputdir, bmifilename) or bmifilename) batchcmds:mkdir(path.directory(objectfile)) - batchcmds:show_progress(opt.progress, "${color.build.object}compiling.headerunit.$(mode) %s", headerunit.name) _batchcmds_compile(batchcmds, target, flags) batchcmds:add_depfiles(headerunit.path) @@ -405,7 +397,7 @@ function build_modules_for_batchjobs(target, batchjobs, objectfiles, modules, op local outputdir = common.get_outputdir(target, cppfile) local metafilepath = path.join(outputdir, path.filename(cppfile) .. ".meta-info") depend.on_changed(function() - progress.show(opt.progress, "${color.build.object}generating.module.metadata %s", name) + progress.show((index * 100) / total, "${color.build.object}generating.module.metadata %s", name) local metadata = common.generate_meta_module_info(target, name, cppfile, module.requires) json.savefile(metafilepath, metadata) @@ -462,6 +454,7 @@ end -- build module files for batchcmds function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, opt) + local modulemapperflag = get_modulemapperflag(target) local mapper_file = _get_module_mapper(target) -- build modules -- cgit v1.3.1 From 81d8ae23bbd8a980fff00f4b305adabc422a8c89 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 23 Jan 2023 16:57:03 +0100 Subject: support clang++ in toolchain_includedirs --- xmake/rules/c++/modules/modules_support/clang.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xmake/rules/c++/modules/modules_support/clang.lua b/xmake/rules/c++/modules/modules_support/clang.lua index aeb8ebd53..3fdbb1b09 100644 --- a/xmake/rules/c++/modules/modules_support/clang.lua +++ b/xmake/rules/c++/modules/modules_support/clang.lua @@ -226,7 +226,7 @@ function toolchain_includedirs(target) if includedirs == nil then includedirs = {} local clang, toolname = target:tool("cxx") - assert(toolname == "clang") + assert(toolname:startswith("clang")) _get_toolchain_includedirs_for_stlheaders(target, includedirs, clang) local _, result = try {function () return os.iorunv(clang, {"-E", "-stdlib=libc++", "-Wp,-v", "-xc", os.nuldev()}) end} if result then -- cgit v1.3.1 From d7816ecb549f15bed8937a3362856fc6e7ec9129 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 23 Jan 2023 16:59:41 +0100 Subject: cleanup --- xmake/rules/c++/modules/modules_support/clang.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/xmake/rules/c++/modules/modules_support/clang.lua b/xmake/rules/c++/modules/modules_support/clang.lua index 3fdbb1b09..17ce22659 100644 --- a/xmake/rules/c++/modules/modules_support/clang.lua +++ b/xmake/rules/c++/modules/modules_support/clang.lua @@ -247,7 +247,6 @@ end -- generate dependency files function generate_dependencies(target, sourcebatch, opt) local changed = false - local projectdir = os.projectdir() for _, sourcefile in ipairs(sourcebatch.sourcefiles) do local dependfile = target:dependfile(sourcefile) depend.on_changed(function() -- cgit v1.3.1 From 924403375684235e1f34f3b6b2210cc5cda1feb5 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 24 Jan 2023 12:11:37 +0100 Subject: fix unsafe table remove --- xmake/rules/c++/modules/modules_support/clang.lua | 8 ++------ xmake/rules/c++/modules/modules_support/gcc.lua | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/xmake/rules/c++/modules/modules_support/clang.lua b/xmake/rules/c++/modules/modules_support/clang.lua index 17ce22659..320061e1a 100644 --- a/xmake/rules/c++/modules/modules_support/clang.lua +++ b/xmake/rules/c++/modules/modules_support/clang.lua @@ -271,12 +271,8 @@ function generate_dependencies(target, sourcebatch, opt) common.fallback_generate_dependencies(target, jsonfile, sourcefile, function(file) local compinst = target:compiler("cxx") local compflags = compinst:compflags({sourcefile = file, target = target}) - for i, flag in ipairs(compflags) do - -- exclude -fmodule* and -std=c++/gnu++* flags because, when they are set clang try to find bmi of imported modules but they don't exists a this point of compilation - if flag:startswith("-fmodule") or flag:startswith("-std=c++") or flag:startswith("-std=gnu++") then - table.remove(compflags, i) - end - end + -- exclude -fmodule* and -std=c++/gnu++* flags because, when they are set clang try to find bmi of imported modules but they don't exists a this point of compilation + compflags = table.remove_if(compflags, function(_, flag) return flag:startswith("-fmodule") or flag:startswith("-std=c++") or flag:startswith("-std=gnu++") end) local ifile = path.translate(path.join(outputdir, path.filename(file) .. ".i")) os.vrunv(compinst:program(), table.join(compflags, {"-E", "-x", "c++", file, "-o", ifile})) local content = io.readfile(ifile) diff --git a/xmake/rules/c++/modules/modules_support/gcc.lua b/xmake/rules/c++/modules/modules_support/gcc.lua index 2864e41a4..eb83ed96d 100644 --- a/xmake/rules/c++/modules/modules_support/gcc.lua +++ b/xmake/rules/c++/modules/modules_support/gcc.lua @@ -200,12 +200,8 @@ function generate_dependencies(target, sourcebatch, opt) common.fallback_generate_dependencies(target, jsonfile, sourcefile, function(file) local compinst = target:compiler("cxx") local compflags = compinst:compflags({sourcefile = file, target = target}) - for i, flag in ipairs(compflags) do - -- exclude -fmodule* flags because, when they are set gcc try to find bmi of imported modules but they don't exists a this point of compilation - if flag:startswith("-fmodule") then - table.remove(compflags, i) - end - end + -- exclude -fmodule* flags because, when they are set gcc try to find bmi of imported modules but they don't exists a this point of compilation + compflags = table.remove_if(compflags, function(_, flag) return flag:startswith("-fmodule") end) local ifile = path.translate(path.join(outputdir, path.filename(file) .. ".i")) os.vrunv(compinst:program(), table.join(common_args, compflags, {file, "-o", ifile})) local content = io.readfile(ifile) -- cgit v1.3.1