summaryrefslogtreecommitdiff
path: root/xmake/rules/c++/modules/modules_support
diff options
context:
space:
mode:
authorruki <[email protected]>2022-08-07 22:01:09 +0800
committerGitHub <[email protected]>2022-08-07 22:01:09 +0800
commit1e47408bfe508f752aaacdcf530cc8fb3747e9df (patch)
tree04899d36b4565ba398c18a7fe9d88aa41c3b3746 /xmake/rules/c++/modules/modules_support
parentb0379bcadce0b66fa5d3e5fc45d85a8ba365c92b (diff)
parent1c96d8379173130442227222c75e0caac6afb40b (diff)
Merge pull request #2650 from Arthapz/cxxmodules
Implement module mapper file for MSVC and Clang
Diffstat (limited to 'xmake/rules/c++/modules/modules_support')
-rw-r--r--xmake/rules/c++/modules/modules_support/clang.lua140
-rw-r--r--xmake/rules/c++/modules/modules_support/common.lua33
-rw-r--r--xmake/rules/c++/modules/modules_support/gcc.lua39
-rw-r--r--xmake/rules/c++/modules/modules_support/msvc.lua168
-rw-r--r--xmake/rules/c++/modules/modules_support/stl_headers.lua5
5 files changed, 245 insertions, 140 deletions
diff --git a/xmake/rules/c++/modules/modules_support/clang.lua b/xmake/rules/c++/modules/modules_support/clang.lua
index 18243fadf..4749f7fe3 100644
--- a/xmake/rules/c++/modules/modules_support/clang.lua
+++ b/xmake/rules/c++/modules/modules_support/clang.lua
@@ -27,6 +27,51 @@ import("utils.progress")
import("private.action.build.object", {alias = "objectbuilder"})
import("common")
+-- 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, module, bmi)
+ local cache = common.localcache():get("mapflags") or {}
+ local modulefileflag = get_modulefileflag(target)
+ local mapflag = format("%s%s=%s", modulefileflag, module, bmi)
+ if table.contains(cache, mapflag) then
+ return
+ end
+ table.insert(cache, mapflag)
+ common.localcache():set("mapflags", cache)
+ common.localcache():save("mapflags")
+end
+
+-- add a header unit into the mapper
+--
+-- e.g
+-- -fmodule-file=build/.gens/Foo/rules/modules/cache/foo.hpp.pcm
+--
+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
+ return
+ end
+ end
+ local f = io.open(file, "a")
+ f:print("%s%s", modulefileflag, bmi)
+ f:close()
+end
+
-- load module support for the current target
function load(target)
local cachedir = common.modules_cachedir(target)
@@ -34,24 +79,19 @@ function load(target)
-- get module and module cache flags
local modulesflag = get_modulesflag(target)
+ local builtinmodulemapflag = get_builtinmodulemapflag(target)
local implicitmodulesflag = get_implicitmodulesflag(target)
- local implicitmodulemapsflag = get_implicitmodulemapsflag(target)
- local prebuiltmodulepathflag = get_prebuiltmodulepathflag(target)
+ local noimplicitmodulemapsflag = get_noimplicitmodulemapsflag(target)
-- add module flags
target:add("cxxflags", modulesflag)
-- add the module cache directory
+ target:add("cxxflags", builtinmodulemapflag, {force = true})
target:add("cxxflags", implicitmodulesflag, {force = true})
- target:add("cxxflags", implicitmodulemapsflag, {force = true})
- target:add("cxxflags", prebuiltmodulepathflag .. cachedir, prebuiltmodulepathflag .. stlcachedir, {force = true})
+ target:add("cxxflags", noimplicitmodulemapsflag, {force = true})
- -- add module cachedirs of all dependent targets with modules
- -- this target maybe does not contain module files, @see https://github.com/xmake-io/xmake/issues/1858
- for _, dep in ipairs(target:orderdeps()) do
- cachedir = common.modules_cachedir(dep)
- target:add("cxxflags", prebuiltmodulepathflag .. cachedir, {force = true})
- end
+ target:data_set("cxx.modules.use_libc++", table.contains(target:get("cxxflags"), "-stdlib=libc++"))
end
-- get includedirs for stl headers
@@ -145,21 +185,22 @@ function generate_stl_headerunits_for_batchcmds(target, batchcmds, headerunits,
-- build headerunits
local projectdir = os.projectdir()
- local flags = {}
local depmtime = 0
for i, headerunit in ipairs(headerunits) do
local bmifile = path.join(stlcachedir, headerunit.name .. get_bmi_extension())
if not os.isfile(bmifile) then
- local args = {modulecachepathflag .. stlcachedir, "-c", "-o", bmifile, "-x", "c++-system-header", headerunit.path}
+ local args = {modulecachepathflag .. stlcachedir, "-c", "-o", bmifile, "-x", "c++-system-header", headerunit.name}
batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.headerunit.bmi %s", headerunit.name)
batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), args))
- end
- table.insert(flags, modulefileflag .. bmifile)
+ -- libc++ have a builtin module mapper
+ if not target:data_set("cxx.modules.use_libc++") then
+ _add_headerunit_to_mapper(target, bmifile)
+ end
+ end
depmtime = math.max(depmtime, os.mtime(bmifile))
end
batchcmds:set_depmtime(depmtime)
- return flags
end
-- generate target user header units for batchcmds
@@ -205,14 +246,12 @@ 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, bmifile)
- table.insert(flags, modulefileflag .. bmifile)
depmtime = math.max(depmtime, os.mtime(bmifile))
end
batchcmds:set_depmtime(depmtime)
- return flags
end
-- build module files for batchcmds
@@ -225,14 +264,10 @@ function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, op
-- get modules flags
local modulecachepathflag = get_modulecachepathflag(target)
local emitmoduleinterfaceflag = get_emitmoduleinterfaceflag(target)
- local modulefileflag = get_modulefileflag(target)
- -- append deps modules
- for _, dep in ipairs(target:orderdeps()) do
- local flags = dep:data("cxx.modules.flags")
- if flags then
- target:add("cxxflags", flags, {force = true, expand = false})
- end
+ -- append module mapper flags
+ for line in io.lines(mapper_file) do
+ target:add("cxxflags", line, {force = true})
end
-- build modules
@@ -261,10 +296,9 @@ 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)
- local bmiflags = modulefileflag .. bmifile
- target:add("cxxflags", bmiflags, {public = true, force = true})
+ _add_module_to_mapper(target, name, bmifile)
+
target:add("objectfiles", objectfile)
- target:data_add("cxx.modules.flags", bmiflags)
depmtime = math.max(depmtime, os.mtime(bmifile))
end
end
@@ -293,6 +327,34 @@ function get_modulesflag(target)
return modulesflag or nil
end
+function get_builtinmodulemapflag(target)
+ local builtinmodulemapflag = _g.builtinmodulemapflag
+ if builtinmodulemapflag == nil then
+ local compinst = target:compiler("cxx")
+ if compinst:has_flags("-fbuiltin-module-map", "cxxflags", {flagskey = "clang_builtin_module_map"}) then
+ builtinmodulemapflag = "-fbuiltin-module-map"
+ end
+ assert(builtinmodulemapflag, "compiler(clang): does not support c++ module!")
+ _g.builtinmodulemapflag = builtinmodulemapflag or false
+ end
+ return builtinmodulemapflag or nil
+end
+
+function get_modulemapfileflag(target)
+ local modulemapfileflag = _g.modulemapfileflag
+ if modulemapfileflag == nil then
+ local compinst = target:compiler("cxx")
+ local mapper_file = path.join(os.tmpfile(), "mapper.txt")
+ os.touch(mapper_file)
+ if compinst:has_flags("-fmodule-map-file=" .. mapper_file, "cxxflags", {flagskey = "clang_module_map_file"}) then
+ modulemapfileflag = "-fmodule-map-file="
+ end
+ assert(modulemapfileflag, "compiler(clang): does not support c++ module!")
+ _g.modulemapfileflag = modulemapfileflag or false
+ end
+ return modulemapfileflag or nil
+end
+
function get_implicitmodulesflag(target)
local implicitmodulesflag = _g.implicitmodulesflag
if implicitmodulesflag == nil then
@@ -306,17 +368,17 @@ function get_implicitmodulesflag(target)
return implicitmodulesflag or nil
end
-function get_implicitmodulemapsflag(target)
- local implicitmodulemapsflag = _g.implicitmodulemapsflag
- if implicitmodulemapsflag == nil then
+function get_noimplicitmodulemapsflag(target)
+ local noimplicitmodulemapsflag = _g.noimplicitmodulemapsflag
+ if noimplicitmodulemapsflag == nil then
local compinst = target:compiler("cxx")
- if compinst:has_flags("-fimplicit-module-maps", "cxxflags", {flagskey = "clang_implicit_module_maps"}) then
- implicitmodulemapsflag = "-fimplicit-module-maps"
+ if compinst:has_flags("-fno-implicit-module-maps", "cxxflags", {flagskey = "clang_no_implicit_module_maps"}) then
+ noimplicitmodulemapsflag = "-fno-implicit-module-maps"
end
- assert(implicitmodulemapsflag, "compiler(clang): does not support c++ module!")
- _g.implicitmodulemapsflag = implicitmodulemapsflag or false
+ assert(noimplicitmodulemapsflag, "compiler(clang): does not support c++ module!")
+ _g.noimplicitmodulemapsflag = noimplicitmodulemapsflag or false
end
- return implicitmodulemapsflag or nil
+ return noimplicitmodulemapsflag or nil
end
function get_prebuiltmodulepathflag(target)
@@ -388,11 +450,11 @@ function has_headerunitsupport(target)
local support_headerunits = _g.support_headerunits
if support_headerunits == nil then
local compinst = target:compiler("cxx")
- if compinst:has_flags("-x c++-user-header", "cxxflags", {flagskey = "clang_user_header_unit_support", tryrun = true}) and
- compinst:has_flags("-x c++-system-header", "cxxflags", {flagskey = "clang_system_header_unit_support", tryrun = true}) then
+ if compinst:has_flags(get_modulesflag(target) .. " -std=c++20 -x c++-user-header", "cxxflags", {flagskey = "clang_user_header_unit_support", tryrun = true}) and
+ compinst:has_flags(get_modulesflag(target) .. " -std=c++20 -x c++-system-header", "cxxflags", {flagskey = "clang_system_header_unit_support", tryrun = true}) then
support_headerunits = true
end
_g.support_headerunits = support_headerunits or false
end
return support_headerunits or nil
-end
+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 c91f52a9b..34d014238 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
@@ -251,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]
@@ -292,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
@@ -448,20 +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 {}
- 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))
+ 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)
+ 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
@@ -476,3 +475,13 @@ 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)
+ 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 cf996bdea..99045cf54 100644
--- a/xmake/rules/c++/modules/modules_support/gcc.lua
+++ b/xmake/rules/c++/modules/modules_support/gcc.lua
@@ -165,14 +165,17 @@ function generate_stl_headerunits_for_batchcmds(target, batchcmds, headerunits,
-- build headerunits
local projectdir = os.projectdir()
local depmtime = 0
- for i, headerunit in ipairs(headerunits) do
+ for _, headerunit in ipairs(headerunits) do
local bmifile = path.join(stlcachedir, headerunit.name .. get_bmi_extension())
- if _add_module_to_mapper(mapper_file, headerunit.path, path.absolute(bmifile, projectdir)) then
+ if not os.isfile(bmifile) then
local args = { "-c", "-x", "c++-system-header", headerunit.name }
-
batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.headerunit.bmi %s", headerunit.name)
batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), args))
end
+
+ batchcmds:add_depfiles(headerunit.path)
+
+ _add_module_to_mapper(mapper_file, headerunit.path, path.absolute(bmifile, projectdir))
depmtime = math.max(depmtime, os.mtime(bmifile))
end
batchcmds:set_depmtime(depmtime)
@@ -216,11 +219,11 @@ function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits,
headerunit_path = path.is_absolute(headerunit.path) and headerunit.path or path.join(".", headerunit.path)
end
- if _add_module_to_mapper(mapper_file, headerunit_path, path.absolute(bmifile, projectdir)) then
- batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.headerunit.bmi %s", headerunit.name)
- batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), args))
- batchcmds:add_depfiles(headerunit.path)
- end
+ 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_module_to_mapper(mapper_file, headerunit_path, path.absolute(bmifile, projectdir))
depmtime = math.max(depmtime, os.mtime(bmifile))
end
batchcmds:set_depmtime(depmtime)
@@ -254,16 +257,16 @@ function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, op
end
local bmifile = provide.bmi
- if _add_module_to_mapper(mapper_file, name, path.absolute(bmifile, projectdir)) then
- local args = {"-o", objectfile, "-c", provide.sourcefile}
- batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.module.bmi %s", name)
- batchcmds:mkdir(path.directory(objectfile))
- batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, args))
- batchcmds:add_depfiles(provide.sourcefile)
+ local args = {"-o", objectfile, "-c", provide.sourcefile}
+ batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.module.bmi %s", name)
+ batchcmds:mkdir(path.directory(objectfile))
+ batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, args))
+ batchcmds:add_depfiles(provide.sourcefile)
- target:add("objectfiles", objectfile)
- depmtime = math.max(depmtime, os.mtime(bmifile))
- end
+ _add_module_to_mapper(mapper_file, name, path.absolute(bmifile, projectdir))
+
+ target:add("objectfiles", objectfile)
+ depmtime = math.max(depmtime, os.mtime(bmifile))
end
end
batchcmds:set_depmtime(depmtime)
@@ -333,4 +336,4 @@ function get_depoutputflag(target)
_g.depoutputflag = depoutputflag or false
end
return depoutputflag or nil
-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 e261332c0..b2b2e605a 100644
--- a/xmake/rules/c++/modules/modules_support/msvc.lua
+++ b/xmake/rules/c++/modules/modules_support/msvc.lua
@@ -22,10 +22,43 @@
import("core.tool.compiler")
import("core.project.project")
import("core.project.depend")
+import("core.project.config")
import("utils.progress")
import("private.action.build.object", {alias = "objectbuilder"})
import("common")
+-- 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(argument, module)
+ local cache = common.localcache():get("mapflags") or {}
+ local mapflag = format("%s %s", argument, module)
+ if table.contains(cache, mapflag) then
+ return
+ end
+ table.insert(cache, mapflag)
+ common.localcache():set("mapflags", cache)
+ common.localcache():save("mapflags")
+end
+
+-- add an objectfile to the linker args
+--
+-- e.g
+-- foo.obj
+--
+function _add_objectfile_to_link_arguments(objectfile)
+ local cache = common.localcache():get("headerunit_objectfiles") or {}
+ if table.contains(cache, objectfile) then
+ return
+ end
+ 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)
@@ -39,19 +72,22 @@ 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", {ifcsearchdirflag, path.join(stlcachedir, "experimental")}, {force = true, expand = false})
- -- add stdifcdir in case of if the user want to use Microsoft modularised STL
- local stdifcdirflag = get_stdifcdirflag(target)
- for _, toolchain_inst in ipairs(target:toolchains()) do
- if toolchain_inst:name() == "msvc" then
- local vcvars = toolchain_inst:config("vcvars")
- if vcvars.VCInstallDir and vcvars.VCToolsVersion then
- local stdifcdir = path.join(vcvars.VCInstallDir, "Tools", "MSVC", vcvars.VCToolsVersion, "ifc", target:is_arch("x64") and "x64" or "x86")
- if os.isdir(stdifcdir) then
- target:add("cxxflags", {stdifcdirflag, winos.short_path(stdifcdir)}, {force = true, expand = false})
+ -- 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
+ if toolchain_inst:name() == "msvc" then
+ local vcvars = toolchain_inst:config("vcvars")
+ if vcvars.VCInstallDir and vcvars.VCToolsVersion then
+ local stdifcdir = path.join(vcvars.VCInstallDir, "Tools", "MSVC", vcvars.VCToolsVersion, "ifc", target:is_arch("x64") and "x64" or "x86")
+ if os.isdir(stdifcdir) then
+ target:add("cxxflags", {stdifcdirflag, winos.short_path(stdifcdir)}, {force = true, expand = false})
+ end
end
+ break
end
- break
end
end
@@ -84,7 +120,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
@@ -100,7 +136,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)
@@ -131,25 +167,23 @@ function generate_stl_headerunits_for_batchcmds(target, batchcmds, headerunits,
local stlcachedir = common.stlmodules_cachedir(target)
-- build headerunits
- local common_args = {"/TP", exportheaderflag, "/c"}
- local objectfiles = {}
- local flags = {}
+ local common_args = {"-TP", exportheaderflag, "-c"}
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})
- end
-
- local flag = {headerunitflag .. ":angle", headerunit.name .. "=" .. headerunit.name .. get_bmi_extension()}
- table.join2(flags, flag)
+ batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, args), {envs = vcvars})
+ 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(objectfile)
+ end
depmtime = math.max(depmtime, os.mtime(bmifile))
end
batchcmds:set_depmtime(depmtime)
- return flags
end
-- generate target user header units for batchcmds
@@ -169,9 +203,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 objectfiles = {}
- local flags = {}
+ local common_args = {"-TP", exportheaderflag, "-c"}
local projectdir = os.projectdir()
local depmtime = 0
for _, headerunit in ipairs(headerunits) do
@@ -191,44 +223,39 @@ function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits,
batchcmds:mkdir(path.directory(objectfile))
local args = {headernameflag .. headerunit.type, headerunit.path, ifcoutputflag, outputdir, "/Fo" .. objectfile}
+
batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.headerunit.bmi %s", headerunit.name)
batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, args), {envs = vcvars})
-
batchcmds:add_depfiles(headerunit.path)
- local flag = {headerunitflag .. headerunit.type, headerunit.name .. "=" .. path.relative(bmifile, cachedir)}
- table.join2(flags, flag)
- target:add("objectfiles", objectfile)
+ _add_module_to_mapper(headerunitflag .. headerunit.type, headerunit.name .. "=" .. path.relative(bmifile, cachedir))
+ _add_objectfile_to_link_arguments(objectfile)
depmtime = math.max(depmtime, os.mtime(bmifile))
end
batchcmds:set_depmtime(depmtime)
- return flags
end
-- build module files for batchcmds
function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, opt)
- local cachedir = common.modules_cachedir(target)
-
local compinst = target:compiler("cxx")
local toolchain = target:toolchain("msvc")
local vcvars = toolchain:config("vcvars")
+ -- get cachedirs
+ local cachedir = common.modules_cachedir(target)
+
-- get flags
local ifcoutputflag = get_ifcoutputflag(target)
local interfaceflag = get_interfaceflag(target)
local referenceflag = get_referenceflag(target)
- -- append deps modules
- for _, dep in ipairs(target:orderdeps()) do
- local flags = dep:data("cxx.modules.flags")
- if flags then
- target:add("cxxflags", flags, {force = true, expand = false})
- end
- end
+ -- append module mapper flags
+ local cache = common.localcache():get("mapflags") or {}
+ target:add("cxxflags", cache, {force = true})
-- build modules
- local common_args = {"/TP"}
+ local common_args = {"-TP"}
local depmtime = 0
for _, objectfile in ipairs(objectfiles) do
local m = modules[objectfile]
@@ -246,21 +273,20 @@ 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))
- batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, args, bmi_args), {envs = vcvars})
+ batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, args), {envs = vcvars})
batchcmds:add_depfiles(provide.sourcefile)
- local bmiflags = {referenceflag, name .. "=" .. path.filename(bmifile)}
- target:add("cxxflags", bmiflags, {force = true, expand = false})
- for _, f in ipairs(bmiflags) do
- target:data_add("cxx.modules.flags", f)
- end
+ _add_module_to_mapper(referenceflag, name .. "=" .. path.filename(bmifile))
+
target:add("objectfiles", objectfile)
depmtime = math.max(depmtime, os.mtime(bmifile))
end
end
+
batchcmds:set_depmtime(depmtime)
end
@@ -272,8 +298,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
@@ -285,8 +311,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
@@ -298,8 +324,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
@@ -311,8 +337,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
@@ -324,8 +350,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
@@ -337,9 +363,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
@@ -350,9 +376,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
@@ -364,8 +390,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
@@ -376,8 +402,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
@@ -389,7 +415,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
@@ -399,9 +425,9 @@ function get_scandependenciesflag(target)
end
return ok, errors
end}) then
- scandependenciesflag = "/scanDependencies"
+ scandependenciesflag = "-scanDependencies"
end
_g.scandependenciesflag = scandependenciesflag or false
end
return scandependenciesflag or nil
-end
+end \ No newline at end of file
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