]> git.tdb.fi Git - builder.git/commitdiff
Report which targets participate in a dependency cycle
authorMikko Rasa <tdb@tdb.fi>
Thu, 5 Jan 2023 09:56:38 +0000 (11:56 +0200)
committerMikko Rasa <tdb@tdb.fi>
Thu, 5 Jan 2023 13:58:51 +0000 (15:58 +0200)
source/lib/target.cpp
source/lib/target.h

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. */
index 0ba38f82031b06122aa10c001f222e0bbf143c49..1ae268cce54b5c7096c48aa6d9c8a7a665e50785 100644 (file)
@@ -6,6 +6,7 @@
 #include <string>
 #include <vector>
 #include <sigc++/signal.h>
+#include <msp/core/noncopyable.h>
 #include <msp/time/timestamp.h>
 #include "libbuilder_api.h"
 
@@ -41,6 +42,12 @@ protected:
                BROKEN
        };
 
+       struct PushPrepare: Msp::NonCopyable
+       {
+               PushPrepare(Target *t) { prepare_stack.push_back(t); }
+               ~PushPrepare() { prepare_stack.pop_back(); }
+       };
+
 public:
        sigc::signal<void> signal_bubble_rebuild;
        sigc::signal<void> signal_modified;
@@ -61,6 +68,8 @@ protected:
        Dependencies side_effects;
        Target *primary_target = 0;
 
+       static std::vector<Target *> prepare_stack;
+
        Target(Builder &, const std::string &);
 public:
        virtual ~Target() { }