GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/make/make.c Lines: 0 191 0.0 %
Date: 2016-12-06 Branches: 0 182 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: make.c,v 1.70 2015/08/21 02:19:49 jsg Exp $	*/
2
/*	$NetBSD: make.c,v 1.10 1996/11/06 17:59:15 christos Exp $	*/
3
4
/*
5
 * Copyright (c) 1988, 1989, 1990, 1993
6
 *	The Regents of the University of California.  All rights reserved.
7
 * Copyright (c) 1989 by Berkeley Softworks
8
 * All rights reserved.
9
 *
10
 * This code is derived from software contributed to Berkeley by
11
 * Adam de Boor.
12
 *
13
 * Redistribution and use in source and binary forms, with or without
14
 * modification, are permitted provided that the following conditions
15
 * are met:
16
 * 1. Redistributions of source code must retain the above copyright
17
 *    notice, this list of conditions and the following disclaimer.
18
 * 2. Redistributions in binary form must reproduce the above copyright
19
 *    notice, this list of conditions and the following disclaimer in the
20
 *    documentation and/or other materials provided with the distribution.
21
 * 3. Neither the name of the University nor the names of its contributors
22
 *    may be used to endorse or promote products derived from this software
23
 *    without specific prior written permission.
24
 *
25
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35
 * SUCH DAMAGE.
36
 */
37
38
/*-
39
 * make.c --
40
 *	The functions which perform the examination of targets and
41
 *	their suitability for creation
42
 *
43
 * Interface:
44
 *	Make_Run		Initialize things for the module and recreate
45
 *				whatever needs recreating. Returns true if
46
 *				work was (or would have been) done and
47
 *				false
48
 *				otherwise.
49
 *
50
 *	Make_Update		Update all parents of a given child. Performs
51
 *				various bookkeeping chores like finding the
52
 *				youngest child of the parent, filling
53
 *				the IMPSRC context variable, etc. It will
54
 *				place the parent on the toBeMade queue if it
55
 *				should be.
56
 *
57
 */
58
59
#include <limits.h>
60
#include <signal.h>
61
#include <stddef.h>
62
#include <stdint.h>
63
#include <stdio.h>
64
#include <stdlib.h>
65
#include <string.h>
66
#include <ohash.h>
67
#include "config.h"
68
#include "defines.h"
69
#include "dir.h"
70
#include "job.h"
71
#include "suff.h"
72
#include "var.h"
73
#include "error.h"
74
#include "make.h"
75
#include "gnode.h"
76
#include "extern.h"
77
#include "timestamp.h"
78
#include "engine.h"
79
#include "lst.h"
80
#include "targ.h"
81
#include "targequiv.h"
82
#include "garray.h"
83
#include "memory.h"
84
85
/* what gets added each time. Kept as one static array so that it doesn't
86
 * get resized every time.
87
 */
88
static struct growableArray examine;
89
/* The current fringe of the graph. These are nodes which await examination by
90
 * MakeOODate. It is added to by Make_Update and subtracted from by
91
 * MakeStartJobs */
92
static struct growableArray toBeMade;
93
94
/* Hold back on nodes where equivalent stuff is already building... */
95
static struct growableArray heldBack;
96
97
static struct ohash targets;	/* stuff we must build */
98
99
static void MakeAddChild(void *, void *);
100
static void MakeHandleUse(void *, void *);
101
static bool MakeStartJobs(void);
102
static void MakePrintStatus(void *, void *);
103
static bool try_to_make_node(GNode *);
104
static void add_targets_to_make(Lst);
105
106
static bool has_unmade_predecessor(GNode *);
107
static void requeue_successors(GNode *);
108
static void random_setup(void);
109
110
static bool randomize_queue;
111
long random_delay = 0;
112
113
bool
114
no_jobs_left()
115
{
116
	return Array_IsEmpty(&toBeMade);
117
}
118
119
static void
120
random_setup()
121
{
122
	randomize_queue = Var_Definedi("RANDOM_ORDER", NULL);
123
124
/* no random delay in the new engine for now */
125
#if 0
126
	if (Var_Definedi("RANDOM_DELAY", NULL))
127
		random_delay = strtonum(Var_Value("RANDOM_DELAY"), 0, 1000,
128
		    NULL) * 1000000;
129
#endif
130
131
}
132
133
static void
134
randomize_garray(struct growableArray *g)
135
{
136
	/* This is a fairly standard algorithm to randomize an array. */
137
	unsigned int i, v;
138
	GNode *e;
139
140
	for (i = g->n; i > 0; i--) {
141
		v = arc4random_uniform(i);
142
		if (v == i-1)
143
			continue;
144
		else {
145
			e = g->a[i-1];
146
			g->a[i-1] = g->a[v];
147
			g->a[v] = e;
148
		}
149
	}
150
}
151
152
static bool
153
has_unmade_predecessor(GNode *gn)
154
{
155
	LstNode ln;
156
157
	if (Lst_IsEmpty(&gn->preds))
158
		return false;
159
160
161
	for (ln = Lst_First(&gn->preds); ln != NULL; ln = Lst_Adv(ln)) {
162
		GNode	*pgn = (GNode *)Lst_Datum(ln);
163
164
		if (pgn->must_make && pgn->built_status == UNKNOWN) {
165
			if (DEBUG(MAKE))
166
				printf("predecessor %s not made yet.\n",
167
				    pgn->name);
168
			return true;
169
		}
170
	}
171
	return false;
172
}
173
174
static void
175
requeue_successors(GNode *gn)
176
{
177
	LstNode ln;
178
	/* Deal with successor nodes. If any is marked for making and has an
179
	 * unmade count of 0, has not been made and isn't in the examination
180
	 * queue, it means we need to place it in the queue as it restrained
181
	 * itself before.	*/
182
	for (ln = Lst_First(&gn->successors); ln != NULL; ln = Lst_Adv(ln)) {
183
		GNode	*succ = (GNode *)Lst_Datum(ln);
184
185
		if (succ->must_make && succ->unmade == 0
186
		    && succ->built_status == UNKNOWN)
187
			Array_PushNew(&toBeMade, succ);
188
	}
189
}
190
191
static void
192
requeue(GNode *gn)
193
{
194
	/* this is where we go inside the array and move things around */
195
	unsigned int i, j;
196
197
	for (i = 0, j = 0; i < heldBack.n; i++, j++) {
198
		if (heldBack.a[i]->watched == gn) {
199
			j--;
200
			heldBack.a[i]->built_status = UNKNOWN;
201
			if (DEBUG(HELDJOBS))
202
				printf("%s finished, releasing: %s\n",
203
				    gn->name, heldBack.a[i]->name);
204
			Array_Push(&toBeMade, heldBack.a[i]);
205
			continue;
206
		}
207
		heldBack.a[j] = heldBack.a[i];
208
	}
209
	heldBack.n = j;
210
}
211
212
/*-
213
 *-----------------------------------------------------------------------
214
 * Make_Update	--
215
 *	Perform update on the parents of a node. Used by JobFinish once
216
 *	a node has been dealt with and by MakeStartJobs if it finds an
217
 *	up-to-date node.
218
 *
219
 * Results:
220
 *	Always returns 0
221
 *
222
 * Side Effects:
223
 *	The unmade field of pgn is decremented and pgn may be placed on
224
 *	the toBeMade queue if this field becomes 0.
225
 *
226
 *	If the child was made, the parent's childMade field will be set to
227
 *	true
228
 *-----------------------------------------------------------------------
229
 */
230
void
231
Make_Update(GNode *cgn)	/* the child node */
232
{
233
	GNode	*pgn;	/* the parent node */
234
	LstNode	ln;	/* Element in parents list */
235
236
	/*
237
	 * If the child was actually made, see what its modification time is
238
	 * now -- some rules won't actually update the file. If the file still
239
	 * doesn't exist, make its mtime now.
240
	 */
241
	if (cgn->built_status != UPTODATE) {
242
		/*
243
		 * This is what Make does and it's actually a good thing, as it
244
		 * allows rules like
245
		 *
246
		 *	cmp -s y.tab.h parse.h || cp y.tab.h parse.h
247
		 *
248
		 * to function as intended. Unfortunately, thanks to the
249
		 * stateless nature of NFS, there are times when the
250
		 * modification time of a file created on a remote machine
251
		 * will not be modified before the local stat() implied by
252
		 * the Dir_MTime occurs, thus leading us to believe that the
253
		 * file is unchanged, wreaking havoc with files that depend
254
		 * on this one.
255
		 */
256
		if (noExecute || is_out_of_date(Dir_MTime(cgn)))
257
			clock_gettime(CLOCK_REALTIME, &cgn->mtime);
258
		if (DEBUG(MAKE))
259
			printf("update time: %s\n",
260
			    time_to_string(&cgn->mtime));
261
	}
262
263
	requeue(cgn);
264
	/* SIB: this is where I should mark the build as finished */
265
	for (ln = Lst_First(&cgn->parents); ln != NULL; ln = Lst_Adv(ln)) {
266
		pgn = (GNode *)Lst_Datum(ln);
267
		/* SIB: there should be a siblings loop there */
268
		pgn->unmade--;
269
		if (pgn->must_make) {
270
			if (DEBUG(MAKE))
271
				printf("%s--=%d ",
272
				    pgn->name, pgn->unmade);
273
274
			if ( ! (cgn->type & (OP_EXEC|OP_USE))) {
275
				if (cgn->built_status == MADE)
276
					pgn->childMade = true;
277
				(void)Make_TimeStamp(pgn, cgn);
278
			}
279
			if (pgn->unmade == 0) {
280
				/*
281
				 * Queue the node up -- any unmade
282
				 * predecessors will be dealt with in
283
				 * MakeStartJobs.
284
				 */
285
				if (DEBUG(MAKE))
286
					printf("QUEUING ");
287
				Array_Push(&toBeMade, pgn);
288
			} else if (pgn->unmade < 0) {
289
				Error("Child %s discovered graph cycles through %s", cgn->name, pgn->name);
290
			}
291
		}
292
	}
293
	if (DEBUG(MAKE))
294
		printf("\n");
295
	requeue_successors(cgn);
296
}
297
298
static bool
299
try_to_make_node(GNode *gn)
300
{
301
	if (DEBUG(MAKE))
302
		printf("Examining %s...", gn->name);
303
304
	if (gn->built_status == HELDBACK) {
305
		if (DEBUG(HELDJOBS))
306
			printf("%s already held back ???\n", gn->name);
307
		return false;
308
	}
309
310
	if (gn->unmade != 0) {
311
		if (DEBUG(MAKE))
312
			printf(" Requeuing (%d)\n", gn->unmade);
313
		add_targets_to_make(&gn->children);
314
		Array_Push(&toBeMade, gn);
315
		return false;
316
	}
317
	if (has_been_built(gn)) {
318
		if (DEBUG(MAKE))
319
			printf(" already made\n");
320
		return false;
321
	}
322
	if (has_unmade_predecessor(gn)) {
323
		if (DEBUG(MAKE))
324
			printf(" Dropping for now\n");
325
		return false;
326
	}
327
328
	/* SIB: this is where there should be a siblings loop */
329
	if (gn->unmade != 0) {
330
		if (DEBUG(MAKE))
331
			printf(" Requeuing (after deps: %d)\n", gn->unmade);
332
		add_targets_to_make(&gn->children);
333
		return false;
334
	}
335
	/* this is where we hold back nodes */
336
	if (gn->groupling != NULL) {
337
		GNode *gn2;
338
		for (gn2 = gn->groupling; gn2 != gn; gn2 = gn2->groupling)
339
			if (gn2->built_status == BUILDING) {
340
				gn->watched = gn2;
341
				gn->built_status = HELDBACK;
342
				if (DEBUG(HELDJOBS))
343
					printf("Holding back job %s, "
344
					    "groupling to %s\n",
345
					    gn->name, gn2->name);
346
				Array_Push(&heldBack, gn);
347
				return false;
348
			}
349
	}
350
	if (gn->sibling != gn) {
351
		GNode *gn2;
352
		for (gn2 = gn->sibling; gn2 != gn; gn2 = gn2->sibling)
353
			if (gn2->built_status == BUILDING) {
354
				gn->watched = gn2;
355
				gn->built_status = HELDBACK;
356
				if (DEBUG(HELDJOBS))
357
					printf("Holding back job %s, "
358
					    "sibling to %s\n",
359
					    gn->name, gn2->name);
360
				Array_Push(&heldBack, gn);
361
				return false;
362
			}
363
	}
364
	if (Make_OODate(gn)) {
365
		if (DEBUG(MAKE))
366
			printf("out-of-date\n");
367
		if (queryFlag)
368
			return true;
369
		/* SIB: this is where commands should get prepared */
370
		Make_DoAllVar(gn);
371
		Job_Make(gn);
372
	} else {
373
		if (DEBUG(MAKE))
374
			printf("up-to-date\n");
375
		gn->built_status = UPTODATE;
376
		if (gn->type & OP_JOIN) {
377
			/*
378
			 * Even for an up-to-date .JOIN node, we need it
379
			 * to have its context variables so references
380
			 * to it get the correct value for .TARGET when
381
			 * building up the context variables of its
382
			 * parent(s)...
383
			 */
384
			Make_DoAllVar(gn);
385
		}
386
387
		Make_Update(gn);
388
	}
389
	return false;
390
}
391
392
/*
393
 *-----------------------------------------------------------------------
394
 * MakeStartJobs --
395
 *	Start as many jobs as possible.
396
 *
397
 * Results:
398
 *	If the query flag was given to pmake, no job will be started,
399
 *	but as soon as an out-of-date target is found, this function
400
 *	returns true. At all other times, this function returns false.
401
 *
402
 * Side Effects:
403
 *	Nodes are removed from the toBeMade queue and job table slots
404
 *	are filled.
405
 *-----------------------------------------------------------------------
406
 */
407
static bool
408
MakeStartJobs(void)
409
{
410
	GNode	*gn;
411
412
	while (can_start_job() && (gn = Array_Pop(&toBeMade)) != NULL) {
413
		if (try_to_make_node(gn))
414
			return true;
415
	}
416
	return false;
417
}
418
419
/*-
420
 *-----------------------------------------------------------------------
421
 * MakePrintStatus --
422
 *	Print the status of a top-level node, viz. it being up-to-date
423
 *	already or not created due to an error in a lower level.
424
 *	Callback function for Make_Run via Lst_ForEach.
425
 *
426
 * Side Effects:
427
 *	A message may be printed.
428
 *-----------------------------------------------------------------------
429
 */
430
static void
431
MakePrintStatus(
432
    void *gnp,		    /* Node to examine */
433
    void *cyclep)	    /* True if gn->unmade being non-zero implies
434
			     * a cycle in the graph, not an error in an
435
			     * inferior */
436
{
437
	GNode	*gn = gnp;
438
	bool 	*cp = cyclep;
439
	bool	cycle = *cp;
440
	if (gn->built_status == UPTODATE) {
441
		printf("`%s' is up to date.\n", gn->name);
442
	} else if (gn->unmade != 0) {
443
		if (cycle) {
444
			bool t = true;
445
			/*
446
			 * If printing cycles and came to one that has unmade
447
			 * children, print out the cycle by recursing on its
448
			 * children. Note a cycle like:
449
			 *	a : b
450
			 *	b : c
451
			 *	c : b
452
			 * will cause this to erroneously complain about a
453
			 * being in the cycle, but this is a good approximation.
454
			 */
455
			if (gn->built_status == CYCLE) {
456
				Error("Graph cycles through `%s'", gn->name);
457
				gn->built_status = ENDCYCLE;
458
				Lst_ForEach(&gn->children, MakePrintStatus, &t);
459
				gn->built_status = UNKNOWN;
460
			} else if (gn->built_status != ENDCYCLE) {
461
				gn->built_status = CYCLE;
462
				Lst_ForEach(&gn->children, MakePrintStatus, &t);
463
			}
464
		} else {
465
			printf("`%s' not remade because of errors.\n",
466
			    gn->name);
467
		}
468
	}
469
}
470
471
472
static void
473
MakeAddChild(void *to_addp, void *ap)
474
{
475
	GNode *gn = to_addp;
476
	struct growableArray *a = ap;
477
478
	if (!gn->must_make && !(gn->type & OP_USE))
479
		Array_Push(a, gn);
480
}
481
482
static void
483
MakeHandleUse(void *cgnp, void *pgnp)
484
{
485
	GNode *cgn = cgnp;
486
	GNode *pgn = pgnp;
487
488
	if (cgn->type & OP_USE)
489
		Make_HandleUse(cgn, pgn);
490
}
491
492
/* Add stuff to the toBeMade queue. we try to sort things so that stuff
493
 * that can be done directly is done right away.  This won't be perfect,
494
 * since some dependencies are only discovered later (e.g., SuffFindDeps).
495
 */
496
static void
497
add_targets_to_make(Lst todo)
498
{
499
	GNode *gn;
500
501
	unsigned int slot;
502
503
	AppendList2Array(todo, &examine);
504
505
	while ((gn = Array_Pop(&examine)) != NULL) {
506
		if (gn->must_make) 	/* already known */
507
			continue;
508
		gn->must_make = true;
509
510
		slot = ohash_qlookup(&targets, gn->name);
511
		if (!ohash_find(&targets, slot))
512
			ohash_insert(&targets, slot, gn);
513
514
515
		look_harder_for_target(gn);
516
		kludge_look_harder_for_target(gn);
517
		/*
518
		 * Apply any .USE rules before looking for implicit
519
		 * dependencies to make sure everything that should have
520
		 * commands has commands ...
521
		 */
522
		Lst_ForEach(&gn->children, MakeHandleUse, gn);
523
		Suff_FindDeps(gn);
524
		expand_all_children(gn);
525
526
		if (gn->unmade != 0) {
527
			if (DEBUG(MAKE))
528
				printf("%s: not queuing (%d unmade children)\n",
529
				    gn->name, gn->unmade);
530
			Lst_ForEach(&gn->children, MakeAddChild,
531
			    &examine);
532
		} else {
533
			if (DEBUG(MAKE))
534
				printf("%s: queuing\n", gn->name);
535
			Array_Push(&toBeMade, gn);
536
		}
537
	}
538
	if (randomize_queue)
539
		randomize_garray(&toBeMade);
540
}
541
542
/*-
543
 *-----------------------------------------------------------------------
544
 * Make_Run --
545
 *	Initialize the nodes to remake and the list of nodes which are
546
 *	ready to be made by doing a breadth-first traversal of the graph
547
 *	starting from the nodes in the given list. Once this traversal
548
 *	is finished, all the 'leaves' of the graph are in the toBeMade
549
 *	queue.
550
 *	Using this queue and the Job module, work back up the graph,
551
 *	calling on MakeStartJobs to keep the job table as full as
552
 *	possible.
553
 *
554
 * Results:
555
 *	true if work was done. false otherwise.
556
 *
557
 * Side Effects:
558
 *	The must_make field of all nodes involved in the creation of the given
559
 *	targets is set to 1. The toBeMade list is set to contain all the
560
 *	'leaves' of these subgraphs.
561
 *-----------------------------------------------------------------------
562
 */
563
bool
564
Make_Run(Lst targs)		/* the initial list of targets */
565
{
566
	bool problem;	/* errors occurred */
567
	GNode *gn;
568
	unsigned int i;
569
	bool cycle;
570
571
	/* wild guess at initial sizes */
572
	Array_Init(&toBeMade, 500);
573
	Array_Init(&examine, 150);
574
	Array_Init(&heldBack, 100);
575
	ohash_init(&targets, 10, &gnode_info);
576
	if (DEBUG(PARALLEL))
577
		random_setup();
578
579
	add_targets_to_make(targs);
580
	if (queryFlag) {
581
		/*
582
		 * We wouldn't do any work unless we could start some jobs in
583
		 * the next loop... (we won't actually start any, of course,
584
		 * this is just to see if any of the targets was out of date)
585
		 */
586
		return MakeStartJobs();
587
	} else {
588
		/*
589
		 * Initialization. At the moment, no jobs are running and until
590
		 * some get started, nothing will happen since the remaining
591
		 * upward traversal of the graph is performed by the routines
592
		 * in job.c upon the finishing of a job. So we fill the Job
593
		 * table as much as we can before going into our loop.
594
		 */
595
		(void)MakeStartJobs();
596
	}
597
598
	/*
599
	 * Main Loop: The idea here is that the ending of jobs will take
600
	 * care of the maintenance of data structures and the waiting for output
601
	 * will cause us to be idle most of the time while our children run as
602
	 * much as possible. Because the job table is kept as full as possible,
603
	 * the only time when it will be empty is when all the jobs which need
604
	 * running have been run, so that is the end condition of this loop.
605
	 * Note that the Job module will exit if there were any errors unless
606
	 * the keepgoing flag was given.
607
	 */
608
	while (!Job_Empty()) {
609
		handle_running_jobs();
610
		(void)MakeStartJobs();
611
	}
612
613
	problem = Job_Finish();
614
	cycle = false;
615
616
	for (gn = ohash_first(&targets, &i); gn != NULL;
617
	    gn = ohash_next(&targets, &i)) {
618
	    	if (has_been_built(gn))
619
			continue;
620
		cycle = true;
621
		problem = true;
622
	    	printf("Error: target %s unaccounted for (%s)\n",
623
		    gn->name, status_to_string(gn));
624
	}
625
	/*
626
	 * Print the final status of each target. E.g. if it wasn't made
627
	 * because some inferior reported an error.
628
	 */
629
	Lst_ForEach(targs, MakePrintStatus, &cycle);
630
	if (problem)
631
		Fatal("Errors while building");
632
633
	return true;
634
}