X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Ftarget.cpp;h=cb44b1322d19cad25e8c392077d3e6ea79925485;hb=HEAD;hp=d21bda8f255da200ed9660df546fd235224f1498;hpb=c3968651eb8a2ba66a95398f0571dd5afd37225c;p=builder.git diff --git a/source/target.cpp b/source/target.cpp deleted file mode 100644 index d21bda8..0000000 --- a/source/target.cpp +++ /dev/null @@ -1,193 +0,0 @@ -#include -#include -#include -#include -#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), - package(0), - component(0), - name(n), - tool(0), - state(INIT), - primary_target(0) -{ - 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", format("Rebuilding %s: %s", name, reason)); - - signal_bubble_rebuild.emit(); -} - -void Target::prepare() -{ - if(state>PREPARING) - return; - if(state==PREPARING) - { - builder.get_logger().log("problems", format("Dependency cycle detected at %s", name)); - problems.push_back("Dependency cycle detected"); - state = BROKEN; - return; - } - - state = PREPARING; - 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()); - } - - 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(); - } -}