]> git.tdb.fi Git - builder.git/blobdiff - source/lib/target.cpp
Refactor transitive dependencies to work on all targets
[builder.git] / source / lib / target.cpp
index 558b3b2c107485594cb8831c40d5cdffb2c238fb..0d823eef6618814c01043f9a71805b562ccad536 100644 (file)
@@ -48,6 +48,50 @@ void Target::add_side_effect(Target &se)
        se.signal_bubble_rebuild.connect(sigc::mem_fun(this, &Target::check_rebuild));
 }
 
+bool Target::find_transitive_dependencies()
+{
+       vector<Target *> found_deps;
+       for(Target *d: depends)
+               if(!d->is_buildable())
+                       find_transitive_dependencies(*d, found_deps);
+
+       bool any_added = false;
+       for(Target *d: found_deps)
+               if(!any_equals(depends, d))
+               {
+                       any_added = true;
+                       add_dependency(*d);
+                       if(d->get_real_target()->is_buildable())
+                               d->signal_modified.connect([this]{ rescan_trans_deps = true; });
+               }
+
+       return any_added;
+}
+
+void Target::find_transitive_dependencies(Target &tgt, vector<Target *> &found_deps) const
+{
+       tgt.prepare();
+
+       Target *rtgt = tgt.get_real_target();
+       Dependencies deps_to_add = rtgt->get_transitive_dependencies();
+       if(rtgt!=&tgt)
+       {
+               for(Target *&d: deps_to_add)
+                       d = resolve_transitive_dependency(tgt, *d);
+       }
+
+       for(Target *d: deps_to_add)
+               if(d)
+               {
+                       auto i = lower_bound(found_deps, d);
+                       if(i==found_deps.end() || *i!=d)
+                       {
+                               found_deps.insert(i, d);
+                               find_transitive_dependencies(*d, found_deps);
+                       }
+               }
+}
+
 Target *Target::get_buildable_target()
 {
        if(primary_target)
@@ -70,7 +114,16 @@ Target *Target::get_buildable_target()
        }
 
        if(self_ok)
+       {
+               if(rescan_trans_deps)
+               {
+                       rescan_trans_deps = false;
+                       if(find_transitive_dependencies())
+                               return get_buildable_target();
+               }
+
                return this;
+       }
 
        return 0;
 }
@@ -150,6 +203,7 @@ void Target::prepare()
                tool->prepare();
 
        find_dependencies();
+       find_transitive_dependencies();
        bool broken = !problems.empty();
 
        if(tool)