]> git.tdb.fi Git - builder.git/blob - source/target.cpp
Move some file-related things from Target to FileTarget
[builder.git] / source / target.cpp
1 /* $Id$
2
3 This file is part of builder
4 Copyright © 2006-2009  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include <msp/fs/stat.h>
9 #include <msp/fs/utils.h>
10 #include "action.h"
11 #include "builder.h"
12 #include "filetarget.h"
13 #include "package.h"
14 #include "target.h"
15
16 using namespace std;
17 using namespace Msp;
18
19 Target::Target(Builder &b, const Package *p, const string &n):
20         builder(b),
21         package(p),
22         name(n),
23         buildable(false),
24         building(false),
25         rebuild(false),
26         deps_ready(false),
27         preparing(false),
28         prepared(false)
29 { }
30
31 Target *Target::get_buildable_target()
32 {
33         if(!rebuild)
34                 return 0;
35
36         bool self_ok = !building;
37         for(TargetList::iterator i=depends.begin(); i!=depends.end(); ++i)
38         {
39                 Target *tgt = (*i)->get_buildable_target();
40                 if(tgt)
41                         return tgt;
42                 else if((*i)->get_rebuild())
43                         self_ok = false;
44         }
45
46         if(self_ok)
47                 return this;
48
49         return 0;
50 }
51
52 void Target::add_depend(Target *dep)
53 {
54         if(dep==this)
55                 throw InvalidParameterValue("A target can't depend on itself");
56         depends.push_back(dep);
57 }
58
59 void Target::prepare()
60 {
61         if(prepared)
62                 return;
63         if(preparing)
64         {
65                 builder.problem((package ? package->get_name() : string()), "Dependency cycle detected at "+name);
66                 return;
67         }
68
69         preparing = true;
70         for(TargetList::iterator i=depends.begin(); i!=depends.end(); ++i)
71                 (*i)->prepare();
72
73         check_rebuild();
74         preparing = false;
75         prepared = true;
76 }
77
78 Action *Target::build()
79 {
80         if(!buildable)
81         {
82                 rebuild = false;
83                 return 0;
84         }
85
86         // XXX Minor breach of OO here
87         if(FileTarget *ft = dynamic_cast<FileTarget *>(this))
88                 if(!builder.get_dry_run() && FS::exists(ft->get_path()))
89                         FS::unlink(ft->get_path());
90
91         Action *action = create_action();
92         if(action)
93         {
94                 action->signal_done.connect(sigc::mem_fun(this, &Target::build_done));
95
96                 building = true;
97         }
98
99         return action;
100 }
101
102 void Target::mark_rebuild(const std::string &reason)
103 {
104         rebuild = true;
105         rebuild_reason = reason;
106 }
107
108 void Target::build_done()
109 {
110         building = false;
111         rebuild = false;
112 }