xref: /netbsd-src/usr.bin/make/targ.c (revision 9fd8799cb5ceb66c69f2eb1a6d26a1d587ba1f1e)
1 /*	$NetBSD: targ.c,v 1.152 2020/12/05 18:38:02 rillig Exp $	*/
2 
3 /*
4  * Copyright (c) 1988, 1989, 1990, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Adam de Boor.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 
35 /*
36  * Copyright (c) 1989 by Berkeley Softworks
37  * All rights reserved.
38  *
39  * This code is derived from software contributed to Berkeley by
40  * Adam de Boor.
41  *
42  * Redistribution and use in source and binary forms, with or without
43  * modification, are permitted provided that the following conditions
44  * are met:
45  * 1. Redistributions of source code must retain the above copyright
46  *    notice, this list of conditions and the following disclaimer.
47  * 2. Redistributions in binary form must reproduce the above copyright
48  *    notice, this list of conditions and the following disclaimer in the
49  *    documentation and/or other materials provided with the distribution.
50  * 3. All advertising materials mentioning features or use of this software
51  *    must display the following acknowledgement:
52  *	This product includes software developed by the University of
53  *	California, Berkeley and its contributors.
54  * 4. Neither the name of the University nor the names of its contributors
55  *    may be used to endorse or promote products derived from this software
56  *    without specific prior written permission.
57  *
58  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68  * SUCH DAMAGE.
69  */
70 
71 /*
72  * Maintaining the targets and sources, which are both implemented as GNode.
73  *
74  * Interface:
75  *	Targ_Init	Initialize the module.
76  *
77  *	Targ_End	Clean up the module.
78  *
79  *	Targ_List	Return the list of all targets so far.
80  *
81  *	GNode_New	Create a new GNode for the passed target
82  *			(string). The node is *not* placed in the
83  *			hash table, though all its fields are
84  *			initialized.
85  *
86  *	Targ_FindNode	Find the node, or return NULL.
87  *
88  *	Targ_GetNode	Find the node, or create it.
89  *
90  *	Targ_NewInternalNode
91  *			Create an internal node.
92  *
93  *	Targ_FindList	Given a list of names, find nodes for all
94  *			of them, creating them as necessary.
95  *
96  *	Targ_Ignore	Return TRUE if errors should be ignored when
97  *			creating the given target.
98  *
99  *	Targ_Silent	Return TRUE if we should be silent when
100  *			creating the given target.
101  *
102  *	Targ_Precious	Return TRUE if the target is precious and
103  *			should not be removed if we are interrupted.
104  *
105  *	Targ_Propagate	Propagate information between related nodes.
106  *			Should be called after the makefiles are parsed
107  *			but before any action is taken.
108  *
109  * Debugging:
110  *	Targ_PrintGraph
111  *			Print out the entire graph, all variables and
112  *			statistics for the directory cache. Should print
113  *			something for suffixes, too, but...
114  */
115 
116 #include <time.h>
117 
118 #include "make.h"
119 #include "dir.h"
120 
121 /*	"@(#)targ.c	8.2 (Berkeley) 3/19/94"	*/
122 MAKE_RCSID("$NetBSD: targ.c,v 1.152 2020/12/05 18:38:02 rillig Exp $");
123 
124 /*
125  * All target nodes that appeared on the left-hand side of one of the
126  * dependency operators ':', '::', '!'.
127  */
128 static GNodeList allTargets = LST_INIT;
129 static HashTable allTargetsByName;
130 
131 #ifdef CLEANUP
132 static GNodeList allNodes = LST_INIT;
133 
134 static void GNode_Free(void *);
135 #endif
136 
137 void
138 Targ_Init(void)
139 {
140 	HashTable_Init(&allTargetsByName);
141 }
142 
143 void
144 Targ_End(void)
145 {
146 	Targ_Stats();
147 #ifdef CLEANUP
148 	Lst_Done(&allTargets);
149 	HashTable_Done(&allTargetsByName);
150 	Lst_DoneCall(&allNodes, GNode_Free);
151 #endif
152 }
153 
154 void
155 Targ_Stats(void)
156 {
157 	HashTable_DebugStats(&allTargetsByName, "targets");
158 }
159 
160 /*
161  * Return the list of all targets, which are all nodes that appear on the
162  * left-hand side of a dependency declaration such as "target: source".
163  * The returned list does not contain pure sources.
164  */
165 GNodeList *
166 Targ_List(void)
167 {
168 	return &allTargets;
169 }
170 
171 /*
172  * Create a new graph node, but don't register it anywhere.
173  *
174  * Graph nodes that appear on the left-hand side of a dependency line such
175  * as "target: source" are called targets.  XXX: In some cases (like the
176  * .ALLTARGETS variable), all nodes are called targets as well, even if they
177  * never appear on the left-hand side.  This is a mistake.
178  *
179  * Typical names for graph nodes are:
180  *	"src.c" (an ordinary file)
181  *	"clean" (a .PHONY target)
182  *	".END" (a special hook target)
183  *	"-lm" (a library)
184  *	"libc.a(isspace.o)" (an archive member)
185  */
186 GNode *
187 GNode_New(const char *name)
188 {
189 	GNode *gn;
190 
191 	gn = bmake_malloc(sizeof *gn);
192 	gn->name = bmake_strdup(name);
193 	gn->uname = NULL;
194 	gn->path = NULL;
195 	gn->type = name[0] == '-' && name[1] == 'l' ? OP_LIB : OP_NONE;
196 	gn->flags = GNF_NONE;
197 	gn->made = UNMADE;
198 	gn->unmade = 0;
199 	gn->mtime = 0;
200 	gn->youngestChild = NULL;
201 	Lst_Init(&gn->implicitParents);
202 	Lst_Init(&gn->parents);
203 	Lst_Init(&gn->children);
204 	Lst_Init(&gn->order_pred);
205 	Lst_Init(&gn->order_succ);
206 	Lst_Init(&gn->cohorts);
207 	gn->cohort_num[0] = '\0';
208 	gn->unmade_cohorts = 0;
209 	gn->centurion = NULL;
210 	gn->checked_seqno = 0;
211 	HashTable_Init(&gn->vars);
212 	Lst_Init(&gn->commands);
213 	gn->suffix = NULL;
214 	gn->fname = NULL;
215 	gn->lineno = 0;
216 
217 #ifdef CLEANUP
218 	Lst_Append(&allNodes, gn);
219 #endif
220 
221 	return gn;
222 }
223 
224 #ifdef CLEANUP
225 static void
226 GNode_Free(void *gnp)
227 {
228 	GNode *gn = gnp;
229 
230 	free(gn->name);
231 	free(gn->uname);
232 	free(gn->path);
233 
234 	/* Don't free gn->youngestChild since it is not owned by this node. */
235 
236 	/*
237 	 * In the following lists, only free the list nodes, but not the
238 	 * GNodes in them since these are not owned by this node.
239 	 */
240 	Lst_Done(&gn->implicitParents);
241 	Lst_Done(&gn->parents);
242 	Lst_Done(&gn->children);
243 	Lst_Done(&gn->order_pred);
244 	Lst_Done(&gn->order_succ);
245 	Lst_Done(&gn->cohorts);
246 
247 	/*
248 	 * Do not free the variables themselves, even though they are owned
249 	 * by this node.
250 	 *
251 	 * XXX: For the nodes that represent targets or sources (and not
252 	 * VAR_GLOBAL), it should be safe to free the variables as well,
253 	 * since each node manages the memory for all its variables itself.
254 	 *
255 	 * XXX: The GNodes that are only used as variable contexts (VAR_CMD,
256 	 * VAR_GLOBAL, VAR_INTERNAL) are not freed at all (see Var_End, where
257 	 * they are not mentioned).  These might be freed at all, if their
258 	 * variable values are indeed not used anywhere else (see Trace_Init
259 	 * for the only suspicious use).
260 	 */
261 	HashTable_Done(&gn->vars);
262 
263 	/*
264 	 * Do not free the commands themselves, as they may be shared with
265 	 * other nodes.
266 	 */
267 	Lst_Done(&gn->commands);
268 
269 	/*
270 	 * gn->suffix is not owned by this node.
271 	 *
272 	 * XXX: gn->suffix should be unreferenced here.  This requires a
273 	 * thorough check that the reference counting is done correctly in
274 	 * all places, otherwise a suffix might be freed too early.
275 	 */
276 
277 	free(gn);
278 }
279 #endif
280 
281 /* Get the existing global node, or return NULL. */
282 GNode *
283 Targ_FindNode(const char *name)
284 {
285 	return HashTable_FindValue(&allTargetsByName, name);
286 }
287 
288 /* Get the existing global node, or create it. */
289 GNode *
290 Targ_GetNode(const char *name)
291 {
292 	Boolean isNew;
293 	HashEntry *he = HashTable_CreateEntry(&allTargetsByName, name, &isNew);
294 	if (!isNew)
295 		return HashEntry_Get(he);
296 
297 	{
298 		GNode *gn = Targ_NewInternalNode(name);
299 		HashEntry_Set(he, gn);
300 		return gn;
301 	}
302 }
303 
304 /*
305  * Create a node, register it in .ALLTARGETS but don't store it in the
306  * table of global nodes.  This means it cannot be found by name.
307  *
308  * This is used for internal nodes, such as cohorts or .WAIT nodes.
309  */
310 GNode *
311 Targ_NewInternalNode(const char *name)
312 {
313 	GNode *gn = GNode_New(name);
314 	Var_Append(".ALLTARGETS", name, VAR_GLOBAL);
315 	Lst_Append(&allTargets, gn);
316 	DEBUG1(TARG, "Adding \"%s\" to all targets.\n", gn->name);
317 	if (doing_depend)
318 		gn->flags |= FROM_DEPEND;
319 	return gn;
320 }
321 
322 /*
323  * Return the .END node, which contains the commands to be run when
324  * everything else has been made.
325  */
326 GNode *Targ_GetEndNode(void)
327 {
328 	/*
329 	 * Save the node locally to avoid having to search for it all
330 	 * the time.
331 	 */
332 	static GNode *endNode = NULL;
333 
334 	if (endNode == NULL) {
335 		endNode = Targ_GetNode(".END");
336 		endNode->type = OP_SPECIAL;
337 	}
338 	return endNode;
339 }
340 
341 /* Add the named nodes to the list, creating them as necessary. */
342 void
343 Targ_FindList(GNodeList *gns, StringList *names)
344 {
345 	StringListNode *ln;
346 
347 	for (ln = names->first; ln != NULL; ln = ln->next) {
348 		const char *name = ln->datum;
349 		GNode *gn = Targ_GetNode(name);
350 		Lst_Append(gns, gn);
351 	}
352 }
353 
354 /*
355  * Return true if errors from shell commands should be ignored when
356  * creating gn.
357  */
358 Boolean
359 Targ_Ignore(const GNode *gn)
360 {
361 	return opts.ignoreErrors || gn->type & OP_IGNORE;
362 }
363 
364 /* Return true if be silent when creating gn. */
365 Boolean
366 Targ_Silent(const GNode *gn)
367 {
368 	return opts.beSilent || gn->type & OP_SILENT;
369 }
370 
371 /* See if the given target is precious. */
372 Boolean
373 Targ_Precious(const GNode *gn)
374 {
375 	/* XXX: Why are '::' targets precious? */
376 	return allPrecious || gn->type & (OP_PRECIOUS | OP_DOUBLEDEP);
377 }
378 
379 /*
380  * The main target to be made; only for debugging output.
381  * See mainNode in parse.c for the definitive source.
382  */
383 static GNode *mainTarg;
384 
385 /* Remember the main target to make; only used for debugging. */
386 void
387 Targ_SetMain(GNode *gn)
388 {
389 	mainTarg = gn;
390 }
391 
392 static void
393 PrintNodeNames(GNodeList *gnodes)
394 {
395 	GNodeListNode *ln;
396 
397 	for (ln = gnodes->first; ln != NULL; ln = ln->next) {
398 		GNode *gn = ln->datum;
399 		debug_printf(" %s%s", gn->name, gn->cohort_num);
400 	}
401 }
402 
403 static void
404 PrintNodeNamesLine(const char *label, GNodeList *gnodes)
405 {
406 	if (Lst_IsEmpty(gnodes))
407 		return;
408 	debug_printf("# %s:", label);
409 	PrintNodeNames(gnodes);
410 	debug_printf("\n");
411 }
412 
413 void
414 Targ_PrintCmds(GNode *gn)
415 {
416 	StringListNode *ln;
417 
418 	for (ln = gn->commands.first; ln != NULL; ln = ln->next) {
419 		const char *cmd = ln->datum;
420 		debug_printf("\t%s\n", cmd);
421 	}
422 }
423 
424 /*
425  * Format a modification time in some reasonable way and return it.
426  * The time is placed in a static area, so it is overwritten with each call.
427  */
428 char *
429 Targ_FmtTime(time_t tm)
430 {
431 	struct tm *parts;
432 	static char buf[128];
433 
434 	/* TODO: Add special case for 0, which often means ENOENT, to make it
435 	 * independent from time zones. */
436 	parts = localtime(&tm);
437 	(void)strftime(buf, sizeof buf, "%k:%M:%S %b %d, %Y", parts);
438 	return buf;
439 }
440 
441 /* Print out a type field giving only those attributes the user can set. */
442 void
443 Targ_PrintType(int type)
444 {
445 	int tbit;
446 
447 	type &= ~OP_OPMASK;
448 
449 	while (type != 0) {
450 		tbit = 1 << (ffs(type) - 1);
451 		type &= ~tbit;
452 
453 		switch (tbit) {
454 #define PRINTBIT(bit, name) case bit: debug_printf(" " name); break
455 #define PRINTDBIT(bit, attr) case bit: if (DEBUG(TARG)) debug_printf(" " attr); break
456 		PRINTBIT(OP_OPTIONAL, ".OPTIONAL");
457 		PRINTBIT(OP_USE, ".USE");
458 		PRINTBIT(OP_EXEC, ".EXEC");
459 		PRINTBIT(OP_IGNORE, ".IGNORE");
460 		PRINTBIT(OP_PRECIOUS, ".PRECIOUS");
461 		PRINTBIT(OP_SILENT, ".SILENT");
462 		PRINTBIT(OP_MAKE, ".MAKE");
463 		PRINTBIT(OP_JOIN, ".JOIN");
464 		PRINTBIT(OP_INVISIBLE, ".INVISIBLE");
465 		PRINTBIT(OP_NOTMAIN, ".NOTMAIN");
466 		PRINTDBIT(OP_LIB, ".LIB");
467 		PRINTDBIT(OP_MEMBER, ".MEMBER");
468 		PRINTDBIT(OP_ARCHV, ".ARCHV");
469 		PRINTDBIT(OP_MADE, ".MADE");
470 		PRINTDBIT(OP_PHONY, ".PHONY");
471 #undef PRINTBIT
472 #undef PRINTDBIT
473 		}
474 	}
475 }
476 
477 static const char *
478 made_name(GNodeMade made)
479 {
480 	switch (made) {
481 	case UNMADE:    return "unmade";
482 	case DEFERRED:  return "deferred";
483 	case REQUESTED: return "requested";
484 	case BEINGMADE: return "being made";
485 	case MADE:      return "made";
486 	case UPTODATE:  return "up-to-date";
487 	case ERROR:     return "error when made";
488 	case ABORTED:   return "aborted";
489 	default:        return "unknown enum_made value";
490 	}
491 }
492 
493 static const char *
494 GNode_OpName(const GNode *gn)
495 {
496 	switch (gn->type & OP_OPMASK) {
497 	case OP_DEPENDS:
498 		return ":";
499 	case OP_FORCE:
500 		return "!";
501 	case OP_DOUBLEDEP:
502 		return "::";
503 	}
504 	return "";
505 }
506 
507 /* Print the contents of a node. */
508 void
509 Targ_PrintNode(GNode *gn, int pass)
510 {
511 	debug_printf("# %s%s", gn->name, gn->cohort_num);
512 	GNode_FprintDetails(opts.debug_file, ", ", gn, "\n");
513 	if (gn->flags == 0)
514 		return;
515 
516 	if (!GNode_IsTarget(gn))
517 		return;
518 
519 	debug_printf("#\n");
520 	if (gn == mainTarg)
521 		debug_printf("# *** MAIN TARGET ***\n");
522 
523 	if (pass >= 2) {
524 		if (gn->unmade > 0)
525 			debug_printf("# %d unmade children\n", gn->unmade);
526 		else
527 			debug_printf("# No unmade children\n");
528 		if (!(gn->type & (OP_JOIN | OP_USE | OP_USEBEFORE | OP_EXEC))) {
529 			if (gn->mtime != 0) {
530 				debug_printf("# last modified %s: %s\n",
531 				    Targ_FmtTime(gn->mtime),
532 				    made_name(gn->made));
533 			} else if (gn->made != UNMADE) {
534 				debug_printf("# non-existent (maybe): %s\n",
535 				    made_name(gn->made));
536 			} else
537 				debug_printf("# unmade\n");
538 		}
539 		PrintNodeNamesLine("implicit parents", &gn->implicitParents);
540 	} else {
541 		if (gn->unmade)
542 			debug_printf("# %d unmade children\n", gn->unmade);
543 	}
544 
545 	PrintNodeNamesLine("parents", &gn->parents);
546 	PrintNodeNamesLine("order_pred", &gn->order_pred);
547 	PrintNodeNamesLine("order_succ", &gn->order_succ);
548 
549 	debug_printf("%-16s%s", gn->name, GNode_OpName(gn));
550 	Targ_PrintType(gn->type);
551 	PrintNodeNames(&gn->children);
552 	debug_printf("\n");
553 	Targ_PrintCmds(gn);
554 	debug_printf("\n\n");
555 	if (gn->type & OP_DOUBLEDEP)
556 		Targ_PrintNodes(&gn->cohorts, pass);
557 }
558 
559 void
560 Targ_PrintNodes(GNodeList *gnodes, int pass)
561 {
562 	GNodeListNode *ln;
563 
564 	for (ln = gnodes->first; ln != NULL; ln = ln->next)
565 		Targ_PrintNode(ln->datum, pass);
566 }
567 
568 /* Print only those targets that are just a source. */
569 static void
570 PrintOnlySources(void)
571 {
572 	GNodeListNode *ln;
573 
574 	for (ln = allTargets.first; ln != NULL; ln = ln->next) {
575 		GNode *gn = ln->datum;
576 		if (GNode_IsTarget(gn))
577 			continue;
578 
579 		debug_printf("#\t%s [%s]", gn->name, GNode_Path(gn));
580 		Targ_PrintType(gn->type);
581 		debug_printf("\n");
582 	}
583 }
584 
585 /*
586  * Input:
587  *	pass		1 => before processing
588  *			2 => after processing
589  *			3 => after processing, an error occurred
590  */
591 void
592 Targ_PrintGraph(int pass)
593 {
594 	debug_printf("#*** Input graph:\n");
595 	Targ_PrintNodes(&allTargets, pass);
596 	debug_printf("\n");
597 	debug_printf("\n");
598 
599 	debug_printf("#\n");
600 	debug_printf("#   Files that are only sources:\n");
601 	PrintOnlySources();
602 
603 	debug_printf("#*** Global Variables:\n");
604 	Var_Dump(VAR_GLOBAL);
605 
606 	debug_printf("#*** Command-line Variables:\n");
607 	Var_Dump(VAR_CMDLINE);
608 
609 	debug_printf("\n");
610 	Dir_PrintDirectories();
611 	debug_printf("\n");
612 
613 	Suff_PrintAll();
614 }
615 
616 /*
617  * Propagate some type information to cohort nodes (those from the '::'
618  * dependency operator).
619  *
620  * Should be called after the makefiles are parsed but before any action is
621  * taken.
622  */
623 void
624 Targ_Propagate(void)
625 {
626 	GNodeListNode *ln, *cln;
627 
628 	for (ln = allTargets.first; ln != NULL; ln = ln->next) {
629 		GNode *gn = ln->datum;
630 		GNodeType type = gn->type;
631 
632 		if (!(type & OP_DOUBLEDEP))
633 			continue;
634 
635 		for (cln = gn->cohorts.first; cln != NULL; cln = cln->next) {
636 			GNode *cohort = cln->datum;
637 
638 			cohort->type |= type & ~OP_OPMASK;
639 		}
640 	}
641 }
642