diff options
| author | ruki <[email protected]> | 2024-02-11 12:45:31 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-02-11 12:45:31 +0800 |
| commit | a7396842b55fb3d9747b5da199d6d5ec1afb8aa9 (patch) | |
| tree | 52722618a91ecbb537534f75874949a68b02a5e3 /xmake/rules/c++/modules/modules_support | |
| parent | c68dad9c520093e74de0659d8723bfe5b14aae9a (diff) | |
| parent | b6983ac3373a704f0f63c514655221473383e46d (diff) | |
Merge pull request #4707 from Arthapz/support-moduleonly-libraries
Support moduleonly libraries
Diffstat (limited to 'xmake/rules/c++/modules/modules_support')
8 files changed, 90 insertions, 91 deletions
diff --git a/xmake/rules/c++/modules/modules_support/builder.lua b/xmake/rules/c++/modules/modules_support/builder.lua index 4ceb67b0b..936f90414 100644 --- a/xmake/rules/c++/modules/modules_support/builder.lua +++ b/xmake/rules/c++/modules/modules_support/builder.lua @@ -21,6 +21,7 @@ -- imports import("core.base.json") import("core.base.option") +import("async.runjobs") import("private.async.buildjobs") import("core.tool.compiler") import("core.project.config") @@ -31,8 +32,7 @@ import("dependency_scanner") -- build target modules function _build_modules(target, sourcebatch, modules, opt) - local objectfiles = dependency_scanner.sort_modules_by_dependencies(sourcebatch.objectfiles, modules) - + local objectfiles = sourcebatch.objectfiles _builder(target).populate_module_map(target, modules) -- build modules @@ -42,22 +42,15 @@ function _build_modules(target, sourcebatch, modules, opt) goto CONTINUE end - local name, provide, cppfile = compiler_support.get_provided_module(module) + local name, _, cppfile = compiler_support.get_provided_module(module) cppfile = cppfile or module.cppfile - local fileconfig = target:fileconfig(cppfile) - local bmifile = provide and compiler_support.get_bmi_path(provide.bmi) - -- add objectfile if module is not from external dep - if not (fileconfig and fileconfig.external) then - target:add("objectfiles", objectfile) - end - local deps = {} for _, dep in ipairs(table.keys(module.requires or {})) do table.insert(deps, opt.batchjobs and target:name() .. dep or dep) end - opt.build_module(deps, module, name, provide, objectfile, cppfile, fileconfig) + opt.build_module(deps, module, name, objectfile, cppfile) ::CONTINUE:: end @@ -198,21 +191,10 @@ function build_modules_for_batchjobs(target, batchjobs, sourcebatch, modules, op local modulesjobs = {} _build_modules(target, sourcebatch, modules, table.join(opt, { - build_module = function(deps, module, name, provide, objectfile, cppfile, fileconfig) + build_module = function(deps, module, name, objectfile, cppfile) local job_name = name and target:name() .. name or cppfile modulesjobs[job_name] = _builder(target).make_module_buildjobs(target, batchjobs, job_name, deps, {module = module, objectfile = objectfile, cppfile = cppfile}) - - if provide and fileconfig and fileconfig.public then - batchjobs:addjob(name .. "_metafile", function(index, total) - local metafilepath = compiler_support.get_metafile(target, cppfile) - depend.on_changed(function() - progress.show((index * 100) / total, "${color.build.target}<%s> generating.module.metadata %s", target:name(), name) - local metadata = _generate_meta_module_info(target, name, cppfile, module.requires) - json.savefile(metafilepath, metadata) - end, {dependfile = target:dependfile(metafilepath), files = {cppfile}, changed = target:is_rebuilt()}) - end, {rootjob = opt.rootjob}) - end end })) @@ -228,17 +210,8 @@ function build_modules_for_batchcmds(target, batchcmds, sourcebatch, modules, op -- build modules _build_modules(target, sourcebatch, modules, table.join(opt, { - build_module = function(_, module, name, provide, objectfile, cppfile, fileconfig) + build_module = function(_, module, _, objectfile, cppfile) depmtime = math.max(depmtime, _builder(target).make_module_buildcmds(target, batchcmds, {module = module, cppfile = cppfile, objectfile = objectfile, progress = opt.progress})) - - if provide and fileconfig and fileconfig.public then - local metafilepath = compiler_support.get_metafile(target, cppfile) - depend.on_changed(function() - progress.show(opt.progress, "${color.build.target}<%s> generating.module.metadata %s", target:name(), name) - local metadata = _generate_meta_module_info(target, name, cppfile, module.requires) - json.savefile(metafilepath, metadata) - end, {dependfile = target:dependfile(metafilepath), files = {cppfile}, changed = target:is_rebuilt()}) - end end })) @@ -312,6 +285,33 @@ function build_headerunits_for_batchcmds(target, batchcmds, sourcebatch, modules end end +function generate_metadata(target, modules) + local public_modules + for _, module in table.orderpairs(modules) do + local _, _, cppfile = compiler_support.get_provided_module(module) + local fileconfig = target:fileconfig(cppfile) + local public = fileconfig and fileconfig.public + if public then + public_modules = public_modules or {} + table.insert(public_modules, module) + end + end + + if not public_modules then + return + end + + local jobs = option.get("jobs") or os.default_njob() + runjobs(target:name() .. "_install_modules", function(index) + local module = public_modules[index] + local name, _, cppfile = compiler_support.get_provided_module(module) + local metafilepath = compiler_support.get_metafile(target, cppfile) + progress.show((index * 100) / #public_modules, "${color.build.target}<%s> generating.module.metadata %s", target:name(), name) + local metadata = _generate_meta_module_info(target, name, cppfile, module.requires) + json.savefile(metafilepath, metadata) + end, {comax = jobs, total = #public_modules}) +end + -- flush target module mapper keys function flush_target_module_mapper_keys(target) local memcache = compiler_support.memcache() diff --git a/xmake/rules/c++/modules/modules_support/clang/builder.lua b/xmake/rules/c++/modules/modules_support/clang/builder.lua index 15a53c00b..0e5f0b5bd 100644 --- a/xmake/rules/c++/modules/modules_support/clang/builder.lua +++ b/xmake/rules/c++/modules/modules_support/clang/builder.lua @@ -38,12 +38,12 @@ function _make_modulebuildflags(target, provide, bmifile, opt) local flags local precompile = false - if module_outputflag and provide and not opt.external then -- one step compilation of named module, clang >= 16 + if module_outputflag and provide and opt.build_objectfile then -- one step compilation of named module, clang >= 16 flags = {{"-x", "c++-module", module_outputflag .. bmifile}} elseif provide then -- two step compilation of named module precompile = true flags = {{"-x", "c++-module", "--precompile"}} - if not opt.external then + if opt.build_objectfile then table.insert(flags, {}) end else -- internal module, no bmi needed @@ -199,7 +199,7 @@ function make_module_buildjobs(target, batchjobs, job_name, deps, opt) return { name = job_name, deps = deps, - sourcefile = cppfile, + sourcefile = opt.cppfile, job = batchjobs:newjob(name or opt.cppfile, function(index, total) local compinst = compiler.load("cxx", {target = target}) @@ -242,10 +242,12 @@ function make_module_buildjobs(target, batchjobs, job_name, deps, opt) end end - local fileconfig = target:fileconfig(opt.cppfile) - local external = fileconfig and fileconfig.external + local fileconfig = target:fileconfig(opt.cppfile) + local public = fileconfig and fileconfig.public + local external = fileconfig and fileconfig.external + local build_objectfile = target:kind() == "binary" or (not public and not external) - local precompile, first_step, second_step = _make_modulebuildflags(target, provide, bmifile, {sourcefile = opt.cppfile, external = external, name = name}) + local precompile, first_step, second_step = _make_modulebuildflags(target, provide, bmifile, {sourcefile = opt.cppfile, build_objectfile = build_objectfile, name = name}) _compile(target, first_step, opt.cppfile, precompile and bmifile or opt.objectfile) @@ -289,6 +291,7 @@ function make_module_buildcmds(target, batchcmds, opt) build = should_build(target, opt.cppfile, bmifile, {objectfile = opt.objectfile, requires = opt.module.requires}) end + local build_objectfile = target:kind() == "binary" if build then -- compile if it's a named module if provide or compiler_support.has_module_extension(opt.cppfile) then @@ -296,9 +299,11 @@ function make_module_buildcmds(target, batchcmds, opt) batchcmds:mkdir(path.directory(opt.objectfile)) local fileconfig = target:fileconfig(opt.cppfile) + local public = fileconfig and fileconfig.public local external = fileconfig and fileconfig.external + local build_objectfile = target:kind() == "binary" or (not public and not external) - local precompile, first_step, second_step = _make_modulebuildflags(target, provide, bmifile, {batchcmds = true, sourcefile = opt.cppfile, external = external, name = name}) + local precompile, first_step, second_step = _make_modulebuildflags(target, provide, bmifile, {batchcmds = true, sourcefile = opt.cppfile, build_objectfile = build_objectfile, name = name}) _batchcmds_compile(batchcmds, target, first_step, opt.cppfile, precompile and bmifile or opt.objectfile) if second_step then diff --git a/xmake/rules/c++/modules/modules_support/compiler_support.lua b/xmake/rules/c++/modules/modules_support/compiler_support.lua index 52ee86a57..d11e833fd 100644 --- a/xmake/rules/c++/modules/modules_support/compiler_support.lua +++ b/xmake/rules/c++/modules/modules_support/compiler_support.lua @@ -64,14 +64,26 @@ function patch_sourcebatch(target, sourcebatch) end -- cull sourcebatch objectfiles -function cull_objectfiles(target, sourcebatch) +function cull_objectfiles(target, modules, sourcebatch) + + -- don't cull for executables + if target:is_binary() then + return + end - sourcebatch.sourcekind = "cxx" sourcebatch.objectfiles = {} for _, sourcefile in ipairs(sourcebatch.sourcefiles) do - local fileconfig = target:fileconfig(sourcefile) - if not (fileconfig and fileconfig.external) then - local objectfile = target:objectfile(sourcefile) + local objectfile = target:objectfile(sourcefile) + local module = modules[objectfile] + local _, provide, _ = get_provided_module(module) + if provide then + local fileconfig = target:fileconfig(sourcefile) + local public = fileconfig and fileconfig.public + local external = fileconfig and fileconfig.external + if not public and not external then + table.insert(sourcebatch.objectfiles, objectfile) + end + else table.insert(sourcebatch.objectfiles, objectfile) end end diff --git a/xmake/rules/c++/modules/modules_support/dependency_scanner.lua b/xmake/rules/c++/modules/modules_support/dependency_scanner.lua index 7ad344750..0b02292ef 100644 --- a/xmake/rules/c++/modules/modules_support/dependency_scanner.lua +++ b/xmake/rules/c++/modules/modules_support/dependency_scanner.lua @@ -182,7 +182,7 @@ function _get_edges(nodes, modules) for _, required_node in ipairs(nodes) do local name, _, _ = compiler_support.get_provided_module(modules[required_node]) if name and name == required_name then - table.insert(edges, {node, required_node}) + table.insert(edges, {required_node, node}) break end end @@ -396,9 +396,9 @@ function get_all_packages_modules(target, opt) end -- topological sort -function sort_modules_by_dependencies(objectfiles, modules) +function sort_modules_by_dependencies(target, objectfiles, modules) local result = {} - local edges, nodeps_nodes = _get_edges(objectfiles, modules) + local edges = _get_edges(objectfiles, modules) local dag = graph.new(true) for _, e in ipairs(edges) do dag:add_edge(e[1], e[2]) @@ -418,10 +418,17 @@ function sort_modules_by_dependencies(objectfiles, modules) for _, objectfile in ipairs(objectfiles_sorted) do table.insert(result, objectfile) end + local objectfiles_sorted_set = hashset.from(objectfiles_sorted) for _, objectfile in ipairs(objectfiles) do if not objectfiles_sorted_set:has(objectfile) then - table.insert(result, objectfile) + -- cull unreferenced non-public named module but add non-module files and implementation modules + local _, provide, cppfile = compiler_support.get_provided_module(modules[objectfile]) + local fileconfig = target:fileconfig(cppfile) + local public = fileconfig and fileconfig.public + if not provide or public then + table.insert(result, objectfile) + end end end return result diff --git a/xmake/rules/c++/modules/modules_support/gcc/builder.lua b/xmake/rules/c++/modules/modules_support/gcc/builder.lua index 7e96c3fcc..c4c9871e2 100644 --- a/xmake/rules/c++/modules/modules_support/gcc/builder.lua +++ b/xmake/rules/c++/modules/modules_support/gcc/builder.lua @@ -99,31 +99,14 @@ end function _get_maplines(target, module) local maplines = {} - local m_name, m = compiler_support.get_provided_module(module) + local m_name, m, cppfile = compiler_support.get_provided_module(module) if m then table.insert(maplines, m_name .. " " .. compiler_support.get_bmi_path(m.bmi)) end for required, _ in table.orderpairs(module.requires) do - local dep_module - local dep_target - for _, dep in ipairs(target:orderdeps()) do - dep_module = get_from_target_mapper(dep, required) - if dep_module then - dep_target = dep - break - end - end - - -- if not in target dep - if not dep_module then - dep_module = get_from_target_mapper(target, required) - if dep_module then - dep_target = target - end - end - - assert(dep_module, "module dependency %s required for %s not found", required, m_name) + local dep_module = get_from_target_mapper(target, required) + assert(dep_module, "module dependency %s required for %s not found", required, m_name or module.cppfile) local bmifile = dep_module.bmi local mapline @@ -143,7 +126,7 @@ function _get_maplines(target, module) -- append deps if dep_module.opt and dep_module.opt.deps then - local deps = _get_maplines(dep_target, { name = dep_module.name, bmi = bmifile, requires = dep_module.opt.deps }) + local deps = _get_maplines(target, {name = dep_module.name, bmi = bmifile, requires = dep_module.opt.deps}) table.join2(maplines, deps) end end @@ -173,16 +156,6 @@ end -- populate module map function populate_module_map(target, modules) - - -- append all modules - for _, module in pairs(modules) do - local name, provide = compiler_support.get_provided_module(module) - if provide then - add_module_to_target_mapper(target, name, provide.sourcefile, compiler_support.get_bmi_path(provide.bmi)) - end - end - - -- then update their deps for _, module in pairs(modules) do local name, provide = compiler_support.get_provided_module(module) if provide then diff --git a/xmake/rules/c++/modules/modules_support/gcc/compiler_support.lua b/xmake/rules/c++/modules/modules_support/gcc/compiler_support.lua index a598f39f5..c365a107a 100644 --- a/xmake/rules/c++/modules/modules_support/gcc/compiler_support.lua +++ b/xmake/rules/c++/modules/modules_support/gcc/compiler_support.lua @@ -99,7 +99,6 @@ end -- not supported atm function get_stdmodules(target) - return {} end function get_bmi_extension() diff --git a/xmake/rules/c++/modules/modules_support/msvc/builder.lua b/xmake/rules/c++/modules/modules_support/msvc/builder.lua index 10a0ad409..3fc86b369 100644 --- a/xmake/rules/c++/modules/modules_support/msvc/builder.lua +++ b/xmake/rules/c++/modules/modules_support/msvc/builder.lua @@ -37,11 +37,11 @@ function _make_modulebuildflags(target, provide, bmifile, opt) local ifconlyflag = compiler_support.get_ifconlyflag(target) local interfaceflag = compiler_support.get_interfaceflag(target) local internalpartitionflag = compiler_support.get_internalpartitionflag(target) - local ifconly = (opt.external and ifconlyflag) + local ifconly = (not opt.build_objectfile and ifconlyflag) local flags if provide then -- named module - flags = table.join({"-TP", ifcoutputflag, bmifile, provide.interface and interfaceflag or internalpartitionflag}, ifconly or {}) + flags = table.join({"-TP", ifcoutputflag, path(bmifile), provide.interface and interfaceflag or internalpartitionflag}, ifconly or {}) else flags = {"-TP"} end @@ -102,8 +102,8 @@ function _batchcmds_compile(batchcmds, target, flags, sourcefile, outputfile) opt = opt or {} local compinst = target:compiler("cxx") local compflags = compinst:compflags({sourcefile = sourcefile, target = target}) - flags = table.join("-c", compflags or {}, flags, {"/Fo", outputfile, sourcefile}) - batchcmds:compilev(flags, {compiler = compinst, sourcekind = "cxx"}) + flags = table.join(compflags or {}, flags) + batchcmds:compile(sourcefile, outputfile, {sourcekind = "cxx", compflags = flags}) end -- get module requires flags @@ -260,8 +260,10 @@ function make_module_buildjobs(target, batchjobs, job_name, deps, opt) end local fileconfig = target:fileconfig(opt.cppfile) + local public = fileconfig and fileconfig.public local external = fileconfig and fileconfig.external - local flags = _make_modulebuildflags(target, provide, bmifile, {external = external}) + local build_objectfile = target:kind() == "binary" or (not public and not external) + local flags = _make_modulebuildflags(target, provide, bmifile, {build_objectfile = build_objectfile}) _compile(target, flags, opt.cppfile, opt.objectfile) else @@ -276,7 +278,7 @@ function make_module_buildjobs(target, batchjobs, job_name, deps, opt) end -- build module file for batchcmds -function make_module_buildcmds(target, batchcmds, should_build, mark_build, opt) +function make_module_buildcmds(target, batchcmds, opt) local name, provide, _ = compiler_support.get_provided_module(opt.module) local bmifile = provide and compiler_support.get_bmi_path(provide.bmi) @@ -308,9 +310,11 @@ function make_module_buildcmds(target, batchcmds, should_build, mark_build, opt) batchcmds:mkdir(path.directory(opt.objectfile)) local fileconfig = target:fileconfig(opt.cppfile) - local external = fileconfig and fileconfig.external - local flags = _make_modulebuildflags(target, provide, bmifile, opt.cppfile, opt.objectfile, {batchcmds = true, external = external}) - _batchcmds_compile(batchcmds, target, flags, opt.cppfile, objectfile) + local public = fileconfig and fileconfig.public + local external = fileconfig and fileconfig.external + local build_objectfile = target:kind() == "binary" or (not public and not external) + local flags = _make_modulebuildflags(target, provide, bmifile, {build_objectfile = build_objectfile}) + _batchcmds_compile(batchcmds, target, flags, opt.cppfile, opt.objectfile) else batchcmds:rm(opt.objectfile) -- force rebuild for .cpp files end diff --git a/xmake/rules/c++/modules/modules_support/msvc/compiler_support.lua b/xmake/rules/c++/modules/modules_support/msvc/compiler_support.lua index 662fd603e..e65effa11 100644 --- a/xmake/rules/c++/modules/modules_support/msvc/compiler_support.lua +++ b/xmake/rules/c++/modules/modules_support/msvc/compiler_support.lua @@ -88,7 +88,6 @@ function get_stdmodules(target) end end end - return {} end function get_bmi_extension() |
