]> git.tdb.fi Git - builder.git/blobdiff - source/lib/target.cpp
Report which targets participate in a dependency cycle
[builder.git] / source / lib / target.cpp
index d1aaf73be578c3836b48cf251536a4a4d446612b..558b3b2c107485594cb8831c40d5cdffb2c238fb 100644 (file)
@@ -1,6 +1,7 @@
 #include <msp/core/algorithm.h>
 #include <msp/fs/stat.h>
 #include <msp/fs/utils.h>
+#include <msp/strings/utils.h>
 #include "builder.h"
 #include "filetarget.h"
 #include "sourcepackage.h"
@@ -11,6 +12,8 @@
 using namespace std;
 using namespace Msp;
 
+vector<Target *> Target::prepare_stack;
+
 Target::Target(Builder &b, const string &n):
        builder(b),
        name(n)
@@ -118,12 +121,26 @@ void Target::prepare()
                return;
        if(state==PREPARING)
        {
-               builder.get_logger().log("problems", "Dependency cycle detected at %s", name);
-               problems.push_back("Dependency cycle detected");
+               auto i = find(prepare_stack, this);
+               if(i!=prepare_stack.end())
+               {
+                       string cycle;
+                       for(; i!=prepare_stack.end(); ++i)
+                               append(cycle, " -> ", (*i)->name);
+                       append(cycle, " -> ", name);
+                       builder.get_logger().log("problems", "Dependency cycle detected: %s", cycle);
+                       problems.push_back(format("Dependency cycle detected: %s", cycle));
+               }
+               else
+               {
+                       builder.get_logger().log("problems", "Dependency cycle detected at %s", name);
+                       problems.push_back("Dependency cycle detected");
+               }
                state = BROKEN;
                return;
        }
 
+       PushPrepare _push(this);
        state = PREPARING;
        /* Prepare existing dependencies early, because their information may be
        needed to find other dependencies. */