Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include	"mk.h"
2
 
3
int runerrs;
4
 
5
void
6
mk(char *target)
7
{
8
	Node *node;
9
	int did = 0;
10
 
11
	nproc();		/* it can be updated dynamically */
12
	nrep();			/* it can be updated dynamically */
13
	runerrs = 0;
14
	node = graph(target);
15
	if(DEBUG(D_GRAPH)){
16
		dumpn("new target\n", node);
17
		Bflush(&bout);
18
	}
19
	clrmade(node);
20
	while(node->flags&NOTMADE){
21
		if(work(node, (Node *)0, (Arc *)0))
22
			did = 1;	/* found something to do */
23
		else {
24
			if(waitup(1, (int *)0) > 0){
25
				if(node->flags&(NOTMADE|BEINGMADE)){
26
					assert(/*must be run errors*/ runerrs);
27
					break;	/* nothing more waiting */
28
				}
29
			}
30
		}
31
	}
32
	if(node->flags&BEINGMADE)
33
		waitup(-1, (int *)0);
34
	while(jobs)
35
		waitup(-2, (int *)0);
36
	assert(/*target didnt get done*/ runerrs || (node->flags&MADE));
37
	if(did == 0)
38
		Bprint(&bout, "mk: '%s' is up to date\n", node->name);
39
}
40
 
41
void
42
clrmade(Node *n)
43
{
44
	Arc *a;
45
 
46
	n->flags &= ~(CANPRETEND|PRETENDING);
47
	if(strchr(n->name, '(') ==0 || n->time)
48
		n->flags |= CANPRETEND;
49
	MADESET(n, NOTMADE);
50
	for(a = n->prereqs; a; a = a->next)
51
		if(a->n)
52
			clrmade(a->n);
53
}
54
 
55
static void
56
unpretend(Node *n)
57
{
58
	MADESET(n, NOTMADE);
59
	n->flags &= ~(CANPRETEND|PRETENDING);
60
	n->time = 0;
61
}
62
 
63
int
64
work(Node *node, Node *p, Arc *parc)
65
{
66
	Arc *a, *ra;
67
	int weoutofdate;
68
	int ready;
69
	int did = 0;
70
	char cwd[256];
71
 
72
	/*print("work(%s) flags=0x%x time=%lud\n", node->name, node->flags, node->time);/**/
73
	if(node->flags&BEINGMADE)
74
		return(did);
75
	if((node->flags&MADE) && (node->flags&PRETENDING) && p && outofdate(p, parc, 0)){
76
		if(explain)
77
			fprint(1, "unpretending %s(%lud) because %s is out of date(%lud)\n",
78
				node->name, node->time, p->name, p->time);
79
		unpretend(node);
80
	}
81
	/*
82
		have a look if we are pretending in case
83
		someone has been unpretended out from underneath us
84
	*/
85
	if(node->flags&MADE){
86
		if(node->flags&PRETENDING){
87
			node->time = 0;
88
		}else
89
			return(did);
90
	}
91
	/* consider no prerequisite case */
92
	if(node->prereqs == 0){
93
		if(node->time == 0){
94
			if(getwd(cwd, sizeof cwd))
95
				fprint(2, "mk: don't know how to make '%s' in directory %s\n", node->name, cwd);
96
			else
97
				fprint(2, "mk: don't know how to make '%s'\n", node->name);
98
			if(kflag){
99
				node->flags |= BEINGMADE;
100
				runerrs++;
101
			} else
102
				Exit();
103
		} else
104
			MADESET(node, MADE);
105
		return(did);
106
	}
107
	/*
108
		now see if we are out of date or what
109
	*/
110
	ready = 1;
111
	weoutofdate = aflag;
112
	ra = 0;
113
	for(a = node->prereqs; a; a = a->next)
114
		if(a->n){
115
			did = work(a->n, node, a) || did;
116
			if(a->n->flags&(NOTMADE|BEINGMADE))
117
				ready = 0;
118
			if(outofdate(node, a, 0)){
119
				weoutofdate = 1;
120
				if((ra == 0) || (ra->n == 0)
121
						|| (ra->n->time < a->n->time))
122
					ra = a;
123
			}
124
		} else {
125
			if(node->time == 0){
126
				if(ra == 0)
127
					ra = a;
128
				weoutofdate = 1;
129
			}
130
		}
131
	if(ready == 0)	/* can't do anything now */
132
		return(did);
133
	if(weoutofdate == 0){
134
		MADESET(node, MADE);
135
		return(did);
136
	}
137
	/*
138
		can we pretend to be made?
139
	*/
140
	if((iflag == 0) && (node->time == 0) && (node->flags&(PRETENDING|CANPRETEND))
141
			&& p && ra->n && !outofdate(p, ra, 0)){
142
		node->flags &= ~CANPRETEND;
143
		MADESET(node, MADE);
144
		if(explain && ((node->flags&PRETENDING) == 0))
145
			fprint(1, "pretending %s has time %lud\n", node->name, node->time);
146
		node->flags |= PRETENDING;
147
		return(did);
148
	}
149
	/*
150
		node is out of date and we REALLY do have to do something.
151
		quickly rescan for pretenders
152
	*/
153
	for(a = node->prereqs; a; a = a->next)
154
		if(a->n && (a->n->flags&PRETENDING)){
155
			if(explain)
156
				Bprint(&bout, "unpretending %s because of %s because of %s\n",
157
				a->n->name, node->name, ra->n? ra->n->name : "rule with no prerequisites");
158
 
159
			unpretend(a->n);
160
			did = work(a->n, node, a) || did;
161
			ready = 0;
162
		}
163
	if(ready == 0)	/* try later unless nothing has happened for -k's sake */
164
		return(did || work(node, p, parc));
165
	did = dorecipe(node) || did;
166
	return(did);
167
}
168
 
169
void
170
update(int fake, Node *node)
171
{
172
	Arc *a;
173
 
174
	MADESET(node, fake? BEINGMADE : MADE);
175
	if(((node->flags&VIRTUAL) == 0) && (access(node->name, 0) == 0)){
176
		node->time = timeof(node->name, 1);
177
		node->flags &= ~(CANPRETEND|PRETENDING);
178
		for(a = node->prereqs; a; a = a->next)
179
			if(a->prog)
180
				outofdate(node, a, 1);
181
	} else {
182
		node->time = 1;
183
		for(a = node->prereqs; a; a = a->next)
184
			if(a->n && outofdate(node, a, 1))
185
				node->time = a->n->time;
186
	}
187
/*	print("----node %s time=%lud flags=0x%x\n", node->name, node->time, node->flags);/**/
188
}
189
 
190
static
191
pcmp(char *prog, char *p, char *q)
192
{
193
	char buf[3*NAMEBLOCK];
194
	int pid;
195
 
196
	Bflush(&bout);
197
	snprint(buf, sizeof buf, "%s '%s' '%s'\n", prog, p, q);
198
	pid = pipecmd(buf, 0, 0);
199
	while(waitup(-3, &pid) >= 0)
200
		;
201
	return(pid? 2:1);
202
}
203
 
204
int
205
outofdate(Node *node, Arc *arc, int eval)
206
{
207
	char buf[3*NAMEBLOCK], *str;
208
	Symtab *sym;
209
	int ret;
210
 
211
	str = 0;
212
	if(arc->prog){
213
		snprint(buf, sizeof buf, "%s%c%s", node->name, 0377,
214
			arc->n->name);
215
		sym = symlook(buf, S_OUTOFDATE, 0);
216
		if(sym == 0 || eval){
217
			if(sym == 0)
218
				str = strdup(buf);
219
			ret = pcmp(arc->prog, node->name, arc->n->name);
220
			if(sym)
221
				sym->u.value = ret;
222
			else
223
				symlook(str, S_OUTOFDATE, (void *)ret);
224
		} else
225
			ret = sym->u.value;
226
		return(ret-1);
227
	} else if(strchr(arc->n->name, '(') && arc->n->time == 0)  /* missing archive member */
228
		return 1;
229
	else
230
		/*
231
		 * Treat equal times as out-of-date.
232
		 * It's a race, and the safer option is to do
233
		 * extra building rather than not enough.
234
	 	 */
235
		return node->time <= arc->n->time;
236
}