diff options
author | Bent Bisballe Nyeng <deva@aasimon.org> | 2025-01-16 18:16:27 +0100 |
---|---|---|
committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2025-01-16 19:36:15 +0100 |
commit | 4f77a82425f60ff928880048dfa79fdd6fba56d8 (patch) | |
tree | 96d810deff9dbafae4f94748fa68dbbc701f3b35 /src/build.cc | |
parent | c50b7554cfd23b53107f2a2917a0be22a68b0c11 (diff) |
Add cyclic dependency detection.develop
Diffstat (limited to 'src/build.cc')
-rw-r--r-- | src/build.cc | 67 |
1 files changed, 49 insertions, 18 deletions
diff --git a/src/build.cc b/src/build.cc index 906c3ea..a31f6a5 100644 --- a/src/build.cc +++ b/src/build.cc @@ -131,17 +131,35 @@ int build(const ctor::settings& settings, return 0; } -namespace -{ -std::vector<std::shared_ptr<Task>> getDepTasks(std::shared_ptr<Task> task) +std::vector<std::shared_ptr<Task>> getDepTasks(std::shared_ptr<Task> task, + std::vector<std::shared_ptr<Task>> trace) { std::vector<std::shared_ptr<Task>> tasks; tasks.push_back(task); + trace.push_back(task); auto deps = task->getDependsTasks(); for(const auto& dep : deps) { - auto depSet = getDepTasks(dep); + if(std::find(trace.begin(), trace.end(), dep) != trace.end()) + { + trace.push_back(dep); + std::cerr << "Error: Cyclic dependency detected: "; + bool first{true}; + for(auto t : trace) + { + if(!first) + { + std::cerr << " -> "; + } + + first = false; + std::cerr << t->target(); + } + std::cerr << '\n'; + throw 1; + } + auto depSet = getDepTasks(dep, trace); for(const auto& dep_inner : depSet) { if(std::find(tasks.begin(), tasks.end(), dep_inner) == tasks.end()) @@ -153,7 +171,6 @@ std::vector<std::shared_ptr<Task>> getDepTasks(std::shared_ptr<Task> task) return tasks; } -} int build(const ctor::settings& settings, const std::string& name, @@ -167,20 +184,27 @@ int build(const ctor::settings& settings, { task_found = true; - auto depSet = getDepTasks(task); - std::vector<std::shared_ptr<Task>> ts; - for(const auto& task_inner : depSet) + try { - if(std::find(ts.begin(), ts.end(), task_inner) == ts.end()) + auto depSet = getDepTasks(task); + std::vector<std::shared_ptr<Task>> ts; + for(const auto& task_inner : depSet) { - ts.push_back(task_inner); + if(std::find(ts.begin(), ts.end(), task_inner) == ts.end()) + { + ts.push_back(task_inner); + } } - } - auto ret = build(settings, name, ts, all_tasks, dryrun); - if(ret != 0) + auto ret = build(settings, name, ts, all_tasks, dryrun); + if(ret != 0) + { + return ret; + } + } + catch(...) { - return ret; + return 1; // cycle detected } break; @@ -214,14 +238,21 @@ int build(const ctor::settings& settings, { task_found = true; - auto depSet = getDepTasks(task); - for(const auto& task_inner : depSet) + try { - if(std::find(ts.begin(), ts.end(), task_inner) == ts.end()) + auto depSet = getDepTasks(task); + for(const auto& task_inner : depSet) { - ts.push_back(task_inner); + if(std::find(ts.begin(), ts.end(), task_inner) == ts.end()) + { + ts.push_back(task_inner); + } } } + catch(...) + { + return 1; // cycle detected + } } } } |