diff options
Diffstat (limited to 'xmake/rules/c++/modules/scanner.lua')
| -rw-r--r-- | xmake/rules/c++/modules/scanner.lua | 120 |
1 files changed, 69 insertions, 51 deletions
diff --git a/xmake/rules/c++/modules/scanner.lua b/xmake/rules/c++/modules/scanner.lua index fe9b9c63d..9c71fa035 100644 --- a/xmake/rules/c++/modules/scanner.lua +++ b/xmake/rules/c++/modules/scanner.lua @@ -145,8 +145,9 @@ function _parse_dependencies_data(target, moduleinfos) modules_names:insert(module.name) module.headerunit = provide["is-headerunit"] module.interface = (not module.headerunit and provide["is-interface"] == nil) and true or provide["is-interface"] - module.implementation = not module.interface and not module.headerunit - module.method = provide["lookup-method"] or "by-name" + if module.name then + module.method = provide["lookup-method"] or "by-name" + end if module.headerunit then local key = support.get_headerunit_key(target, module.sourcefile) @@ -199,7 +200,7 @@ function _get_edges(target, nodes, modules) local deps_names = hashset.new() for _, node in ipairs(table.unique(nodes)) do local module = modules[node] - if module.interface or module.implementation then + if module.name then if deps_names:has(module.name) then raise("duplicate module name detected for \"" .. module.name .. "\"\n <" .. target:fullname() .. "> -> " .. module.sourcefile .. "\n <" .. target:fullname() .. "> -> " .. name_filemap[module.name]) end @@ -212,7 +213,7 @@ function _get_edges(target, nodes, modules) for dep_name, _ in table.orderpairs(module.deps) do for _, dep_node in ipairs(nodes) do local dep_module = modules[dep_node] - if (dep_module.interface or dep_module.implementation or dep_module.headerunit) and dep_name == dep_module.name then + if dep_module.name and dep_name == dep_module.name then table.insert(edges, {dep_node, node}) break end @@ -280,31 +281,34 @@ function _get_targetdeps_modules(target) local _, stdmodules_set = support.get_stdmodules(target) local modules for _, dep in ipairs(target:orderdeps()) do - local sourcebatch = dep:sourcebatches()["c++.build.modules.builder"] - if sourcebatch and sourcebatch.sourcefiles then - for _, sourcefile in ipairs(sourcebatch.sourcefiles) do - modules = modules or {} - if support.is_public(dep, sourcefile) or stdmodules_set:has(sourcefile) then - local _fileconfig = dep:fileconfig(sourcefile) - local fileconfig = {} - if _fileconfig then - fileconfig.defines = _fileconfig.defines - fileconfig.undefines = _fileconfig.undefines - fileconfig.includedirs = _fileconfig.includedirs - end - fileconfig.defines = table.join(fileconfig.defines or {}, dep:get("defines") or {}) - fileconfig.undefines = table.join(fileconfig.undefines or {}, dep:get("undefines") or {}) - fileconfig.includedirs = table.join(fileconfig.includedirs or {}, dep:get("includedirs") or {}) - if not dep:is_phony() then - if target:namespace() == dep:namespace() then - fileconfig.external = dep:name() - else - fileconfig.external = dep:fullname() + local sourcebatches = dep:sourcebatches() + if sourcebatches and sourcebatches["c++.build.modules.scanner"] then + local sourcebatch = sourcebatches["c++.build.modules.scanner"] + if sourcebatch.sourcefiles then + for _, sourcefile in ipairs(sourcebatch.sourcefiles) do + modules = modules or {} + if support.is_public(dep, sourcefile) or stdmodules_set:has(sourcefile) then + local _fileconfig = dep:fileconfig(sourcefile) + local fileconfig = {} + if _fileconfig then + fileconfig.defines = _fileconfig.defines + fileconfig.undefines = _fileconfig.undefines + fileconfig.includedirs = _fileconfig.includedirs + end + fileconfig.defines = table.join(fileconfig.defines or {}, dep:get("defines") or {}) + fileconfig.undefines = table.join(fileconfig.undefines or {}, dep:get("undefines") or {}) + fileconfig.includedirs = table.join(fileconfig.includedirs or {}, dep:get("includedirs") or {}) + if not dep:is_phony() then + if target:namespace() == dep:namespace() then + fileconfig.external = dep:name() + else + fileconfig.external = dep:fullname() + end + fileconfig.bmionly = not dep:is_moduleonly() + end + if not modules[sourcefile] then + modules[sourcefile] = fileconfig end - fileconfig.bmionly = not dep:is_moduleonly() - end - if not modules[sourcefile] then - modules[sourcefile] = fileconfig end end end @@ -377,13 +381,12 @@ function _patch_sourcebatch(target, sourcebatch) end sourcebatch.sourcekind = "cxx" - sourcebatch.objectfiles = {} sourcebatch.dependfiles = {} for _, sourcefile in ipairs(sourcebatch.sourcefiles) do local reused, from = support.is_reused(target, sourcefile) local _target = reused and from or target local objectfile = _target:objectfile(sourcefile) - local dependfile = _target:dependfile(sourcefile or objectfile) + local dependfile = _target:dependfile(objectfile) table.insert(sourcebatch.dependfiles, dependfile) end end @@ -420,16 +423,24 @@ function _do_parse(target, sourcebatch) end -- steal from c++.build sourcebatch named modules with cpp extensions - local cxx_sourcebatch = target:sourcebatches()["c++.build"] - if cxx_sourcebatch then + local sourcebatches = target:sourcebatches() + if sourcebatches and sourcebatches["c++.build"] then + local cxx_sourcebatch = sourcebatches["c++.build"] cxx_sourcebatch.sourcefiles = {} cxx_sourcebatch.dependfiles = {} + cxx_sourcebatch.objectfiles = {} for _, sourcefile in ipairs(sourcebatch.sourcefiles) do local module = mapper.get(target, sourcefile) - if module and not module.interface and not module.implementation then + local insert = true + if module then + insert = not module.name + end + + if insert then table.insert(cxx_sourcebatch.sourcefiles, sourcefile) local objectfile = target:objectfile(sourcefile) table.insert(cxx_sourcebatch.dependfiles, target:dependfile(objectfile)) + table.insert(cxx_sourcebatch.objectfiles, objectfile) end end end @@ -688,16 +699,14 @@ function sort_modules_by_dependencies(target, modules) local culleds for _, sourcefile in ipairs(sourcefiles_sorted) do local module = mapper.get(target, sourcefile) - local is_named = module.interface or module.implementation or module.headerunit - local sort = (is_named and module.sourcealias) or (module.headerunit and not module.alias) or (not is_named) + local name = module.name + local is_named = name ~= nil + local sort = (is_named and (module.sourcealias or not module.alias)) or not is_named if sort then local insert = false - local name local reused, from = support.is_reused(target, sourcefile) - if module.name and not module.headerunit then -- named modules - name = module.name - + if is_named and not module.headerunit then -- named modules insert = not support.can_be_culled(target, sourcefile) -- if module is cullable (culling policy enabled and not a public module), try to cull @@ -726,9 +735,9 @@ function sort_modules_by_dependencies(target, modules) table.insert(built_headerunits, sourcefile) else table.insert(built_modules, sourcefile) - -- insert objectfile if module is not imported from a static / shared library and if has a custom extension (not .cpp) + -- insert objectfile if module named and is not imported from a static / shared library or if from a C++ file with a c++ module extension -- if not so objectfile will be handled by c++.build rule - if not support.is_bmionly(target, sourcefile) then + if not support.is_bmionly(target, sourcefile) and (support.has_module_extension(sourcefile) or is_named) then local objectfile = target:objectfile(sourcefile) table.insert(objectfiles, tostring(objectfile)) end @@ -775,19 +784,28 @@ function get_modules(target) end function after_scan(target) - local compile_commands = os.getenv("XMAKE_IN_PROJECT_GENERATOR") and os.getenv("XMAKE_IN_COMPILE_COMMANDS_PROJECT_GENERATOR") - if not os.getenv("XMAKE_IN_PROJECT_GENERATOR") or compile_commands then - local sourcebatch_scanner = target:sourcebatches()["c++.build.modules.scanner"] - local sourcebatch_builder = target:sourcebatches()["c++.build.modules.builder"] - if target:data("cxx.has_modules") and not target:is_moduleonly() then + local sourcebatches = target:sourcebatches() + local sourcebatch_builder = sourcebatches and sourcebatches["c++.build.modules.builder"] + local sourcebatch_scanner = sourcebatches and sourcebatches["c++.build.modules.scanner"] + if sourcebatch_scanner then + sourcebatch_scanner.sourcefiles = {} + end + if sourcebatch_builder then + sourcebatch_builder.sourcefiles = {} + sourcebatch_builder.dependfiles = {} + sourcebatch_builder.objectfiles = {} + end + if target:data("cxx.has_modules") then + if target:is_moduleonly() or target:is_phony() then + return + end + local compile_commands = os.getenv("XMAKE_IN_PROJECT_GENERATOR") and os.getenv("XMAKE_IN_COMPILE_COMMANDS_PROJECT_GENERATOR") + local need_objectfiles = not os.getenv("XMAKE_IN_PROJECT_GENERATOR") or compile_commands + if need_objectfiles then local modules = get_modules(target) local _, _, objectfiles = sort_modules_by_dependencies(target, modules, {jobgraph = target:policy("build.jobgraph")}) - sourcebatch_scanner.objectfiles = objectfiles + assert(sourcebatch_builder) sourcebatch_builder.objectfiles = objectfiles - elseif sourcebatch_scanner then - -- avoid duplicate linking of object files of non-module programs - sourcebatch_scanner.objectfiles = {} - sourcebatch_builder.objectfiles = {} end end end |
