summaryrefslogtreecommitdiff
path: root/src/build.cc
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2025-01-16 18:16:27 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2025-01-16 19:36:15 +0100
commit4f77a82425f60ff928880048dfa79fdd6fba56d8 (patch)
tree96d810deff9dbafae4f94748fa68dbbc701f3b35 /src/build.cc
parentc50b7554cfd23b53107f2a2917a0be22a68b0c11 (diff)
Add cyclic dependency detection.develop
Diffstat (limited to 'src/build.cc')
-rw-r--r--src/build.cc67
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
+ }
}
}
}