summaryrefslogtreecommitdiff
path: root/xmake/rules/c++/modules
diff options
context:
space:
mode:
Diffstat (limited to 'xmake/rules/c++/modules')
-rw-r--r--xmake/rules/c++/modules/builder.lua43
-rw-r--r--xmake/rules/c++/modules/clang/builder.lua8
-rw-r--r--xmake/rules/c++/modules/clang/support.lua26
-rw-r--r--xmake/rules/c++/modules/gcc/support.lua7
-rw-r--r--xmake/rules/c++/modules/msvc/support.lua7
-rw-r--r--xmake/rules/c++/modules/support.lua9
6 files changed, 87 insertions, 13 deletions
diff --git a/xmake/rules/c++/modules/builder.lua b/xmake/rules/c++/modules/builder.lua
index d0863ad98..b988ff152 100644
--- a/xmake/rules/c++/modules/builder.lua
+++ b/xmake/rules/c++/modules/builder.lua
@@ -194,6 +194,10 @@ function should_build(target, module)
local dependinfo = {}
dependinfo.files = {module.sourcefile}
dependinfo.values = {compinst:program(), compflags}
+ if module.bmifile and not module.headerunit and support.has_two_phase_compilation_support(target) then
+ local bmi_mode = support.has_precompile_reduced_bmi_support(target) and support.get_modulesprecompilereducedbmiflag(target) or "--precompile"
+ table.insert(dependinfo.values, bmi_mode)
+ end
local objectfile_exists = (module.headerunit or support.is_bmionly(target, module.sourcefile)) and true or os.isfile(module.objectfile)
dependinfo.lastmtime = (os.isfile(module.bmifile or module.objectfile) and objectfile_exists) and os.mtime(dependfile) or 0
@@ -241,6 +245,7 @@ function build_modules_for_jobgraph(target, jobgraph, built_modules)
profiler.enter(target:fullname(), "c++ modules", "builder", "schedule module bmi build jobs")
local builder = _builder(target)
local has_two_phase_compilation_support = support.has_two_phase_compilation_support(target)
+ local has_precompile_reduced_bmi = support.has_precompile_reduced_bmi_support(target)
local jobdeps = {}
local buildfilejobs = {}
@@ -272,19 +277,24 @@ function build_modules_for_jobgraph(target, jobgraph, built_modules)
local buildfilejob = _get_module_buildfilejob_for(target, sourcefile, moduletype)
table.insert(buildfilejobs, buildfilejob)
jobgraph:add(buildfilejob, function(_, _, jobopt)
- progress.set_target(jobopt.progress, target)
+ local moduleopt = table.clone(jobopt)
+ progress.set_target(moduleopt.progress, target)
-- build bmi if named job
- jobopt.bmi = module.name
+ moduleopt.bmi = module.name
-- build objectfile here if two phase compilation is not supported
- jobopt.objectfile = not has_two_phase_compilation_support and not bmionly
- builder.make_module_job(target, module, jobopt)
+ moduleopt.objectfile = not has_two_phase_compilation_support and not bmionly
+ builder.make_module_job(target, module, moduleopt)
end)
_merge_jobdeps(jobdeps, _get_jobdeps(target, module, jobgraph, buildfilejob))
-- if two phase compilation supported set jobdeps for objectfile job
if has_two_phase_compilation_support and not bmionly then
local objbuildfilejob = _get_module_buildfilejob_for(target, sourcefile, "objectfile")
- _merge_jobdeps(jobdeps, {[objbuildfilejob] = {buildfilejob}})
+ if has_precompile_reduced_bmi then
+ _merge_jobdeps(jobdeps, _get_jobdeps(target, module, jobgraph, objbuildfilejob))
+ else
+ _merge_jobdeps(jobdeps, {[objbuildfilejob] = {buildfilejob}})
+ end
end
end
end)
@@ -327,10 +337,11 @@ function build_objectfiles_for_jobgraph(target, jobgraph, built_modules)
local module = mapper.get(target, sourcefile)
local buildfilejob = _get_module_buildfilejob_for(target, sourcefile, "objectfile")
jobgraph:add(buildfilejob, function(_, _, jobopt)
- progress.set_target(jobopt.progress, target)
- jobopt.bmi = false
- jobopt.objectfile = true
- builder.make_module_job(target, module, jobopt)
+ local moduleopt = table.clone(jobopt)
+ progress.set_target(moduleopt.progress, target)
+ moduleopt.bmi = false
+ moduleopt.objectfile = true
+ builder.make_module_job(target, module, moduleopt)
end)
end
end
@@ -719,6 +730,16 @@ function build_bmis(target, jobgraph, _, opt)
local built_modules, built_headerunits, _ = scanner.sort_modules_by_dependencies(target, modules, {jobgraph = target:policy("build.jobgraph")})
local headerunits, stlheaderunits = scanner.sort_headerunits(target, built_headerunits)
if jobgraph.add_orders then -- jobgraph
+ if support.has_precompile_reduced_bmi_support(target) then
+ -- schedule object jobs in the BMI stage so both jobs can run concurrently
+ -- after their imported BMIs are ready
+ local append_requires_flags = _builder(target).append_requires_flags
+ if append_requires_flags then
+ append_requires_flags(target, built_modules)
+ end
+ build_objectfiles_for_jobgraph(target, jobgraph, built_modules)
+ end
+
-- build headerunits
if stlheaderunits or headerunits then
build_headerunits_for_jobgraph(target, jobgraph, stlheaderunits, headerunits)
@@ -760,6 +781,10 @@ function build_objectfiles(target, jobgraph, _, opt)
if target:is_moduleonly() and not target:data("cxx.modules.reused") or target:is_phony() then
return
end
+ if jobgraph.add_orders and support.has_precompile_reduced_bmi_support(target) then
+ -- object jobs have already been scheduled by build_bmis()
+ return
+ end
profiler.enter(target:fullname(), "c++ modules", "builder", "objectfiles")
local modules = scanner.get_modules(target)
-- avoid building non referenced modules
diff --git a/xmake/rules/c++/modules/clang/builder.lua b/xmake/rules/c++/modules/clang/builder.lua
index 4839733e0..4ecafb17e 100644
--- a/xmake/rules/c++/modules/clang/builder.lua
+++ b/xmake/rules/c++/modules/clang/builder.lua
@@ -65,6 +65,8 @@ function _make_modulebuildflags(target, module, opt)
local modules_reduced_bmi_flag = support.get_modulesreducedbmiflag(target)
local has_two_phases = target:policy("build.c++.modules.two_phases")
+ local has_precompile_reduced_bmi = support.has_precompile_reduced_bmi_support(target)
+ local modules_precompile_reduced_bmi_flag = has_precompile_reduced_bmi and support.get_modulesprecompilereducedbmiflag(target)
local flags
if opt.bmi then
local module_outputflag = support.get_moduleoutputflag(target)
@@ -72,7 +74,7 @@ function _make_modulebuildflags(target, module, opt)
flags = {"-x", "c++-module"}
if not opt.objectfile then
- table.insert(flags, "--precompile")
+ table.insert(flags, modules_precompile_reduced_bmi_flag or "--precompile")
if target:has_tool("cxx", "clang_cl") then
table.join2(flags, "/clang:-o", "/clang:" .. module.bmifile)
end
@@ -92,7 +94,7 @@ function _make_modulebuildflags(target, module, opt)
end
else
flags = {}
- if not has_two_phases or not module.bmifile then
+ if (has_precompile_reduced_bmi and support.has_module_extension(module.sourcefile)) or not has_two_phases or not module.bmifile then
flags = {"-x", "c++"}
end
local std = (module.name == "std" or module.name == "std.compat")
@@ -171,7 +173,7 @@ function _compile(target, flags, module, opt)
opt = opt or {}
local sourcefile = module.sourcefile
- if not opt.bmi and opt.objectfile and module.bmifile then
+ if not support.has_precompile_reduced_bmi_support(target) and not opt.bmi and opt.objectfile and module.bmifile then
sourcefile = module.bmifile
end
local outputfile = ((opt.bmi and not opt.objectfile) or opt.headerunit) and module.bmifile or module.objectfile
diff --git a/xmake/rules/c++/modules/clang/support.lua b/xmake/rules/c++/modules/clang/support.lua
index 71bd2e735..a010fdde1 100644
--- a/xmake/rules/c++/modules/clang/support.lua
+++ b/xmake/rules/c++/modules/clang/support.lua
@@ -130,6 +130,13 @@ function has_two_phase_compilation_support(target)
return target:policy("build.c++.modules.two_phases")
end
+function has_precompile_reduced_bmi_support(target)
+ if not target:policy("build.c++.modules.clang.precompile_reduced_bmi") or not has_two_phase_compilation_support(target) then
+ return false
+ end
+ return get_modulesprecompilereducedbmiflag(target) ~= nil
+end
+
-- flags that doesn't affect bmi generation
function strippeable_flags()
-- speculative list as there is no resource that list flags that prevent reusability, this list will likely be improve over time
@@ -411,6 +418,25 @@ function get_modulesreducedbmiflag(target)
return modulesreducedbmiflag or nil
end
+function get_modulesprecompilereducedbmiflag(target)
+ local modulesprecompilereducedbmiflag = _g.modulesprecompilereducedbmiflag
+ if modulesprecompilereducedbmiflag == nil then
+ local compinst = target:compiler("cxx")
+ local checkflags = "--precompile-reduced-bmi"
+ if target:has_tool("cxx", "clang_cl") then
+ -- clang_cl.has_flags() appends -c and treats unused-argument warnings as errors,
+ -- but --precompile-reduced-bmi does not use -c. Ignore that specific warning and
+ -- treat unknown-argument warnings as errors to reject unsupported flags.
+ checkflags = {checkflags, "-Wno-unused-command-line-argument", "-Werror=unknown-argument"}
+ end
+ if compinst:has_flags(checkflags, "cxxflags", {flagskey = "clang_modules_precompile_reduced_bmi", tryrun = true}) then
+ modulesprecompilereducedbmiflag = "--precompile-reduced-bmi"
+ end
+ _g.modulesprecompilereducedbmiflag = modulesprecompilereducedbmiflag or false
+ end
+ return modulesprecompilereducedbmiflag or nil
+end
+
function has_clangscandepssupport(target)
local support_clangscandeps = _g.support_clangscandeps
if support_clangscandeps == nil then
diff --git a/xmake/rules/c++/modules/gcc/support.lua b/xmake/rules/c++/modules/gcc/support.lua
index 1204d207d..e57bd5a63 100644
--- a/xmake/rules/c++/modules/gcc/support.lua
+++ b/xmake/rules/c++/modules/gcc/support.lua
@@ -79,6 +79,13 @@ function has_two_phase_compilation_support(_)
return false
end
+function has_precompile_reduced_bmi_support(_)
+ return false
+end
+
+function get_modulesprecompilereducedbmiflag(_)
+end
+
-- flags that doesn't affect bmi generation
function strippeable_flags()
-- speculative list as there is no resource that list flags that prevent reusability, this list will likely be improve over time
diff --git a/xmake/rules/c++/modules/msvc/support.lua b/xmake/rules/c++/modules/msvc/support.lua
index 588921d0e..caaeb9cc6 100644
--- a/xmake/rules/c++/modules/msvc/support.lua
+++ b/xmake/rules/c++/modules/msvc/support.lua
@@ -120,6 +120,13 @@ function has_two_phase_compilation_support(_)
return false
end
+function has_precompile_reduced_bmi_support(_)
+ return false
+end
+
+function get_modulesprecompilereducedbmiflag(_)
+end
+
-- build c++23 standard modules if needed
function get_stdmodules(target, opt)
opt = opt or {}
diff --git a/xmake/rules/c++/modules/support.lua b/xmake/rules/c++/modules/support.lua
index 38df28a05..78d74ae6c 100644
--- a/xmake/rules/c++/modules/support.lua
+++ b/xmake/rules/c++/modules/support.lua
@@ -111,6 +111,14 @@ function has_two_phase_compilation_support(target)
return _support(target).has_two_phase_compilation_support(target)
end
+function has_precompile_reduced_bmi_support(target)
+ return _support(target).has_precompile_reduced_bmi_support(target)
+end
+
+function get_modulesprecompilereducedbmiflag(target)
+ return _support(target).get_modulesprecompilereducedbmiflag(target)
+end
+
-- strip flags not relevent for module reuse
function strip_flags(target, flags, opt)
@@ -437,4 +445,3 @@ function add_installfiles_for_modules(target, modules)
end
end
end
-