]> git.tdb.fi Git - builder.git/blobdiff - source/target.cpp
Refactor transitive dependencies to work on all targets
[builder.git] / source / target.cpp
diff --git a/source/target.cpp b/source/target.cpp
deleted file mode 100644 (file)
index dbdd950..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-#include <msp/core/algorithm.h>
-#include <msp/fs/stat.h>
-#include <msp/fs/utils.h>
-#include "builder.h"
-#include "filetarget.h"
-#include "sourcepackage.h"
-#include "target.h"
-#include "task.h"
-#include "tool.h"
-
-using namespace std;
-using namespace Msp;
-
-Target::Target(Builder &b, const string &n):
-       builder(b),
-       name(n)
-{
-       builder.get_build_graph().add_target(this);
-}
-
-void Target::add_dependency(Target &dep)
-{
-       if(&dep==this)
-               throw invalid_argument("Target::add_depend");
-       depends.push_back(&dep);
-       if(state>PREPARING)
-               dep.signal_bubble_rebuild.connect(sigc::mem_fun(this, &Target::check_rebuild));
-}
-
-void Target::add_transitive_dependency(Target &dep)
-{
-       if(&dep==this)
-               throw invalid_argument("Target::add_transitive_dependency");
-       trans_depends.push_back(&dep);
-}
-
-void Target::add_side_effect(Target &se)
-{
-       side_effects.push_back(&se);
-       if(tool)
-               se.set_tool(*tool);
-       se.primary_target = this;
-       /* Side effects are checked for rebuild after the primary target.  Recheck
-       the primary if a side effect is marked for rebuild. */
-       se.signal_bubble_rebuild.connect(sigc::mem_fun(this, &Target::check_rebuild));
-}
-
-Target *Target::get_buildable_target()
-{
-       if(primary_target)
-               return primary_target->get_buildable_target();
-       if(!needs_rebuild())
-               return 0;
-
-       bool self_ok = state!=BUILDING;
-       for(Target *d: depends)
-       {
-               // Avoid infinite recursion if a target depends on its own side effect
-               if(any_equals(side_effects, d))
-                       continue;
-
-               Target *tgt = d->get_buildable_target();
-               if(tgt)
-                       return tgt;
-               else if(d->needs_rebuild())
-                       self_ok = false;
-       }
-
-       if(self_ok)
-               return this;
-
-       return 0;
-}
-
-void Target::set_tool(Tool &t)
-{
-       tool = &t;
-       for(Target *s: side_effects)
-               s->set_tool(t);
-}
-
-void Target::collect_build_info(BuildInfo &binfo) const
-{
-       if(tool)
-               binfo.update_from(tool->get_build_info());
-       if(component)
-               binfo.update_from(component->get_build_info());
-       else if(package)
-               binfo.update_from(package->get_build_info());
-}
-
-void Target::force_rebuild()
-{
-       if(!is_buildable())
-               throw logic_error("Target::force_rebuild");
-       mark_rebuild("Forced rebuild");
-}
-
-void Target::mark_rebuild(const string &reason)
-{
-       if(reason.empty())
-               throw invalid_argument("No reason given for rebuilding "+name);
-
-       state = REBUILD;
-       rebuild_reason = reason;
-
-       builder.get_logger().log("rebuild", "Rebuilding %s: %s", name, reason);
-
-       signal_bubble_rebuild.emit();
-}
-
-void Target::prepare()
-{
-       if(state>PREPARING)
-               return;
-       if(state==PREPARING)
-       {
-               builder.get_logger().log("problems", "Dependency cycle detected at %s", name);
-               problems.push_back("Dependency cycle detected");
-               state = BROKEN;
-               return;
-       }
-
-       state = PREPARING;
-       /* Prepare existing dependencies early, because their information may be
-       needed to find other dependencies. */
-       for(Target *d: depends)
-               d->prepare();
-       if(tool)
-               tool->prepare();
-
-       find_dependencies();
-       bool broken = !problems.empty();
-
-       if(tool)
-       {
-               if(FileTarget *tool_exe = tool->get_executable())
-                       add_dependency(*tool_exe);
-               broken |= !tool->get_problems().empty();
-
-               // Only check package and component problems for buildable targets
-               // XXX How to propagate nested package problems?
-               broken |= (package && !package->get_problems().empty());
-               broken |= (component && !component->get_problems().empty());
-       }
-
-       /* Now that all dependencies are known, prepare them again.  This will do
-       nothing to already prepared targets. */
-       for(Target *d: depends)
-       {
-               d->prepare();
-               broken |= d->is_broken();
-       }
-       for(Target *d: trans_depends)
-               d->prepare();
-
-       check_rebuild();
-       if(broken)
-               state = BROKEN;
-       else if(state==PREPARING)
-               state = UPTODATE;
-
-       for(Target *d: depends)
-               d->signal_bubble_rebuild.connect(sigc::mem_fun(this, &Target::check_rebuild));
-}
-
-Task *Target::build()
-{
-       if(primary_target)
-               return primary_target->build();
-
-       Task *task = tool->run(*this);
-       task->signal_finished.connect(sigc::mem_fun(this, &Target::build_finished));
-       state = BUILDING;
-
-       build(*task);
-       for(Target *s: side_effects)
-               s->build(*task);
-
-       return task;
-}
-
-void Target::build_finished(bool success)
-{
-       state = UPTODATE;
-       if(success)
-       {
-               modified();
-               for(Target *s: side_effects)
-                       s->build_finished(success);
-               signal_modified.emit();
-       }
-}