]> git.tdb.fi Git - builder.git/blob - source/target.cpp
Builder can build itself now.
[builder.git] / source / target.cpp
1 #include <msp/path/utils.h>
2 #include "action.h"
3 #include "builder.h"
4 #include "target.h"
5
6 using namespace std;
7 using namespace Msp;
8
9 Target *Target::get_buildable_target()
10 {
11         bool self_ok=true;
12         for(list<Target *>::iterator i=depends.begin(); i!=depends.end(); ++i)
13         {
14                 Target *tgt=(*i)->get_buildable_target();
15                 if(tgt)
16                         return tgt;
17                 else if((*i)->get_rebuild())
18                         self_ok=false;
19         }
20
21         if(self_ok && rebuild && !building)
22                 return this;
23
24         return 0;
25 }
26
27 void Target::add_depend(Target *dep)
28 {
29         depends.push_back(dep);
30         dep->rdepends.push_back(this);
31 }
32
33 void Target::prepare()
34 {
35         if(prepared)
36                 return;
37
38         for(list<Target *>::iterator i=depends.begin(); i!=depends.end(); ++i)
39                 (*i)->prepare();
40
41         check_rebuild();
42 }
43
44 Target::Target(Builder &b, const Package *p, const string &n):
45         builder(b),
46         package(p),
47         name(n),
48         building(false),
49         rebuild(false),
50         prepared(false),
51         buildable(false)
52 {
53         struct stat st;
54         if(!Path::stat(name, st))
55         {
56                 mtime=Time::TimeStamp::from_unixtime(st.st_mtime);
57                 vmtime=mtime;
58         }
59 }
60
61 void Target::mark_rebuild(const std::string &reason)
62 {
63         rebuild=true;
64         rebuild_reason=reason;
65 }
66
67 void Target::check_rebuild()
68 {
69         if(!buildable)
70                 return;
71
72         if(!mtime)
73                 mark_rebuild("Does not exist");
74         else
75         {
76                 for(list<Target *>::iterator i=depends.begin(); (i!=depends.end() && !rebuild); ++i)
77                 {
78                         if((*i)->get_virtual_mtime()>mtime)
79                                 mark_rebuild((*i)->get_name()+" has changed");
80                         else if((*i)->get_rebuild())
81                                 mark_rebuild((*i)->get_name()+" needs rebuilding");
82                 }
83         }
84 }
85
86 Action *Target::build(Action *action)
87 {
88         building=true;
89         action->signal_done.connect(sigc::mem_fun(this, &Target::build_done));
90         return action;
91 }
92
93 void Target::build_done()
94 {
95         building=false;
96         rebuild=false;
97 }