diff options
| author | ruki <[email protected]> | 2022-11-08 00:32:36 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2022-11-08 00:32:36 +0800 |
| commit | 535fda2702d2e894ac8182c4dba264ee2875e898 (patch) | |
| tree | 0ef27aef2f15545180ef972be962fd95b3c66028 /xmake/rules/c++/modules/modules_support/common.lua | |
| parent | b1ebcb2fc81125989bcea33982e221f3c9136376 (diff) | |
check module circular deps
Diffstat (limited to 'xmake/rules/c++/modules/modules_support/common.lua')
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/common.lua | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/xmake/rules/c++/modules/modules_support/common.lua b/xmake/rules/c++/modules/modules_support/common.lua index b77411155..377af7222 100644 --- a/xmake/rules/c++/modules/modules_support/common.lua +++ b/xmake/rules/c++/modules/modules_support/common.lua @@ -203,7 +203,7 @@ end } } }]] -function parse_dependency_data(target, moduleinfos) +function _parse_dependencies_data(target, moduleinfos) local modules local cachedir = modules_cachedir(target) for _, moduleinfo in ipairs(moduleinfos) do @@ -266,6 +266,49 @@ function parse_dependency_data(target, moduleinfos) return modules end +-- check circular dependencies for the given module +function _check_circular_dependencies_of_module(name, moduledeps, depspath) + for _, dep in ipairs(moduledeps[name]) do + local depinfo = moduledeps[dep] + if depinfo then + local depspath_sub + if depspath then + for idx, name in ipairs(depspath) do + if name == dep then + local circular_deps = table.slice(depspath, idx) + table.insert(circular_deps, dep) + os.raise("circular modules dependency(%s) detected!", table.concat(circular_deps, ", ")) + end + end + depspath_sub = table.join(depspath, dep) + end + _check_circular_dependencies_of_module(dep, moduledeps, depspath_sub) + end + end +end + +-- check circular dependencies +function _check_circular_dependencies(modules) + local moduledeps = {} + for _, mod in pairs(modules) do + if mod then + if mod.provides and mod.requires then + for name, _ in pairs(mod.provides) do + local deps = moduledeps[name] + if deps then + table.join2(deps, mod.requires) + else + moduledeps[name] = table.keys(mod.requires) + end + end + end + end + end + for name, _ in pairs(moduledeps) do + _check_circular_dependencies_of_module(name, moduledeps, {name}) + end +end + function _topological_sort_visit(node, nodes, modules, output) if node.marked then return @@ -455,7 +498,10 @@ function get_module_dependencies(target, sourcebatch, opt) local changed = modules_support(target).generate_dependencies(target, sourcebatch, opt) if changed or modules == nil then local moduleinfos = load_moduleinfos(target, sourcebatch) - modules = parse_dependency_data(target, moduleinfos) + modules = _parse_dependencies_data(target, moduleinfos) + if modules then + _check_circular_dependencies(modules) + end localcache():set2("modules", cachekey, modules) localcache():save() end |
