xref: /openbsd-src/usr.bin/make/main.c (revision ff0e7be1ebbcc809ea8ad2b6dafe215824da9e46)
1 /*	$OpenBSD: main.c,v 1.130 2023/05/30 04:42:21 espie Exp $ */
2 /*	$NetBSD: main.c,v 1.34 1997/03/24 20:56:36 gwr 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 #include <sys/param.h>	/* MACHINE MACHINE_ARCH */
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <sys/utsname.h>
42 #include <err.h>
43 #include <errno.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <unistd.h>
48 #include "config.h"
49 #include "defines.h"
50 #include "var.h"
51 #include "lowparse.h"
52 #include "parse.h"
53 #include "parsevar.h"
54 #include "dir.h"
55 #include "direxpand.h"
56 #include "error.h"
57 #include "pathnames.h"
58 #include "init.h"
59 #include "job.h"
60 #include "targ.h"
61 #include "suff.h"
62 #include "str.h"
63 #include "main.h"
64 #include "lst.h"
65 #include "memory.h"
66 #include "dump.h"
67 #include "enginechoice.h"
68 
69 #define MAKEFLAGS	".MAKEFLAGS"
70 
71 static LIST		to_create; 	/* Targets to be made */
72 Lst create = &to_create;
73 bool 		allPrecious;	/* .PRECIOUS given on line by itself */
74 
75 static bool	noBuiltins;	/* -r flag */
76 static LIST	makefiles;	/* ordered list of makefiles to read */
77 static LIST	varstoprint;	/* list of variables to print */
78 static int	optj;		/* -j argument */
79 static bool 	compatMake;	/* -B argument */
80 static bool	forceJobs = false;
81 int 		debug;		/* -d flag */
82 bool 		noExecute;	/* -n flag */
83 bool 		keepgoing;	/* -k flag */
84 bool 		queryFlag;	/* -q flag */
85 bool 		touchFlag;	/* -t flag */
86 bool 		ignoreErrors;	/* -i flag */
87 bool 		beSilent;	/* -s flag */
88 bool		dumpData;	/* -p flag */
89 
90 static LIST 	unreadable;
91 
92 struct dirs {
93 	char *current;
94 	char *object;
95 };
96 
97 static void MainParseArgs(int, char **);
98 static void add_dirpath(Lst, const char *);
99 static void usage(void);
100 static void posixParseOptLetter(int);
101 static void record_option(int, const char *);
102 
103 static char *figure_out_MACHINE(void);
104 static char *figure_out_MACHINE_ARCH(void);
105 static char *figure_out_MACHINE_CPU(void);
106 
107 static char *chdir_verify_path(const char *, struct dirs *);
108 static char *figure_out_CURDIR(void);
109 static void setup_CURDIR_OBJDIR(struct dirs *);
110 
111 static void setup_VPATH(void);
112 
113 static void read_all_make_rules(bool, bool, Lst, struct dirs *);
114 static void read_makefile_list(Lst, struct dirs *);
115 static bool ReadMakefile(void *, void *);
116 
117 static void
118 record_option(int c, const char *arg)
119 {
120     	char opt[3];
121 
122 	opt[0] = '-';
123 	opt[1] = c;
124 	opt[2] = '\0';
125 	Var_Append(MAKEFLAGS, opt);
126 	if (arg != NULL)
127 		Var_Append(MAKEFLAGS, arg);
128 }
129 
130 void
131 set_notparallel()
132 {
133 	compatMake = true;
134 }
135 
136 static void
137 posixParseOptLetter(int c)
138 {
139 	switch(c) {
140 	case 'B':
141 		compatMake = true;
142 		return;	/* XXX don't pass to submakes. */
143 	case 'S':
144 		keepgoing = false;
145 		break;
146 	case 'e':
147 		Var_setCheckEnvFirst(true);
148 		break;
149 	case 'i':
150 		ignoreErrors = true;
151 		break;
152 	case 'k':
153 		keepgoing = true;
154 		break;
155 	case 'n':
156 		noExecute = true;
157 		break;
158 	case 'p':
159 		dumpData = true;
160 		break;
161 	case 'q':
162 		queryFlag = true;
163 		/* Kind of nonsensical, wot? */
164 		break;
165 	case 'r':
166 		noBuiltins = true;
167 		break;
168 	case 's':
169 		beSilent = true;
170 		break;
171 	case 't':
172 		touchFlag = true;
173 		break;
174 	default:
175 		usage();
176 	}
177 	record_option(c, NULL);
178 }
179 
180 /*-
181  * MainParseArgs --
182  *	Parse a given argument vector. Called from main() and from
183  *	Main_ParseArgLine() when the .MAKEFLAGS target is used.
184  *
185  *	XXX: Deal with command line overriding .MAKEFLAGS in makefile
186  *
187  * Side Effects:
188  *	Various global and local flags will be set depending on the flags
189  *	given
190  */
191 static void
192 MainParseArgs(int argc, char **argv)
193 {
194 	int c, optend;
195 
196 #define OPTFLAGS "BC:D:I:SV:d:ef:ij:km:npqrst"
197 #define OPTLETTERS "BSiknpqrst"
198 
199 	if (pledge("stdio rpath wpath cpath fattr proc exec", NULL) == -1)
200 		err(2, "pledge");
201 
202 	optind = 1;	/* since we're called more than once */
203 	optreset = 1;
204 	optend = 0;
205 	while (optind < argc) {
206 		if (!optend && argv[optind][0] == '-') {
207 			if (argv[optind][1] == '\0')
208 				optind++;	/* ignore "-" */
209 			else if (argv[optind][1] == '-' &&
210 			    argv[optind][2] == '\0') {
211 				optind++;	/* ignore "--" */
212 				optend++;	/* "--" denotes end of flags */
213 			}
214 		}
215 		c = optend ? -1 : getopt(argc, argv, OPTFLAGS);
216 		switch (c) {
217 		case 'C':
218 			break;
219 		case 'D':
220 			Var_Set(optarg, "1");
221 			record_option(c, optarg);
222 			break;
223 		case 'I':
224 			Parse_AddIncludeDir(optarg);
225 			record_option(c, optarg);
226 			break;
227 		case 'V':
228 			Lst_AtEnd(&varstoprint, optarg);
229 			record_option(c, optarg);
230 			break;
231 		case 'd': {
232 			char *modules = optarg;
233 
234 			for (; *modules; ++modules)
235 				switch (*modules) {
236 				case 'A':
237 					debug = ~0;
238 					break;
239 				case 'a':
240 					debug |= DEBUG_ARCH;
241 					break;
242 				case 'c':
243 					debug |= DEBUG_COND;
244 					break;
245 				case 'd':
246 					debug |= DEBUG_DIR;
247 					break;
248 				case 'D':
249 					debug |= DEBUG_DOUBLE;
250 					break;
251 				case 'e':
252 					debug |= DEBUG_EXPENSIVE;
253 					break;
254 				case 'f':
255 					debug |= DEBUG_FOR;
256 					break;
257 				case 'g':
258 					if (modules[1] == '1') {
259 						debug |= DEBUG_GRAPH1;
260 						++modules;
261 					}
262 					else if (modules[1] == '2') {
263 						debug |= DEBUG_GRAPH2;
264 						++modules;
265 					}
266 					break;
267 				case 'h':
268 					debug |= DEBUG_HELDJOBS;
269 					break;
270 				case 'j':
271 					debug |= DEBUG_JOB | DEBUG_KILL;
272 					break;
273 				case 'J':
274 					/* ignore */
275 					break;
276 				case 'k':
277 					debug |= DEBUG_KILL;
278 					break;
279 				case 'l':
280 					debug |= DEBUG_LOUD;
281 					break;
282 				case 'm':
283 					debug |= DEBUG_MAKE;
284 					break;
285 				case 'n':
286 					debug |= DEBUG_NAME_MATCHING;
287 					break;
288 				case 'p':
289 					debug |= DEBUG_PARALLEL;
290 					break;
291 				case 'q':
292 					debug |= DEBUG_QUICKDEATH;
293 					break;
294 				case 's':
295 					debug |= DEBUG_SUFF;
296 					break;
297 				case 't':
298 					debug |= DEBUG_TARG;
299 					break;
300 				case 'T':
301 					debug |= DEBUG_TARGGROUP;
302 					break;
303 				case 'v':
304 					debug |= DEBUG_VAR;
305 					break;
306 				default:
307 					(void)fprintf(stderr,
308 				"make: illegal argument to -d option -- %c\n",
309 					    *modules);
310 					usage();
311 				}
312 			record_option(c, optarg);
313 			break;
314 		}
315 		case 'f':
316 			Lst_AtEnd(&makefiles, optarg);
317 			break;
318 		case 'j': {
319 			const char *errstr;
320 
321 			forceJobs = true;
322 			optj = strtonum(optarg, 1, INT_MAX, &errstr);
323 			if (errstr != NULL) {
324 				fprintf(stderr,
325 				    "make: illegal argument to -j option"
326 				    " -- %s -- %s\n", optarg, errstr);
327 				usage();
328 			}
329 			record_option(c, optarg);
330 			break;
331 		}
332 		case 'm':
333 			Dir_AddDir(systemIncludePath, optarg);
334 			record_option(c, optarg);
335 			break;
336 		case -1:
337 			/* Check for variable assignments and targets. */
338 			if (argv[optind] != NULL &&
339 			    !Parse_CmdlineVar(argv[optind])) {
340 				if (!*argv[optind])
341 					Punt("illegal (null) argument.");
342 				Lst_AtEnd(create, estrdup(argv[optind]));
343 			}
344 			optind++;	/* skip over non-option */
345 			break;
346 		default:
347 			posixParseOptLetter(c);
348 		}
349 	}
350 }
351 
352 static void
353 MainParseChdir(int argc, char **argv)
354 {
355 	int c, optend, oldopterr;
356 
357 	optind = 1;	/* since we're called more than once */
358 	optreset = 1;
359 	optend = 0;
360 	oldopterr = opterr;
361 	opterr = 0;
362 	while (optind < argc) {
363 		if (!optend && argv[optind][0] == '-') {
364 			if (argv[optind][1] == '\0')
365 				optind++;	/* ignore "-" */
366 			else if (argv[optind][1] == '-' &&
367 			    argv[optind][2] == '\0') {
368 				optind++;	/* ignore "--" */
369 				optend++;	/* "--" denotes end of flags */
370 			}
371 		}
372 		c = optend ? -1 : getopt(argc, argv, OPTFLAGS);
373 		switch (c) {
374 		case 'C':
375 			if (chdir(optarg) == -1)
376 				err(2, "chdir(%s)", optarg);
377 			break;
378 		case -1:
379 			optind++;	/* skip over non-option */
380 			break;
381 		default:
382 			break;
383 		}
384 	}
385 	opterr = oldopterr;
386 }
387 
388 /*-
389  * Main_ParseArgLine --
390  *	Used by the parse module when a .MFLAGS or .MAKEFLAGS target
391  *	is encountered and by main() when reading the .MAKEFLAGS envariable.
392  *	Takes a line of arguments and breaks it into its
393  *	component words and passes those words and the number of them to the
394  *	MainParseArgs function.
395  *	The line should have all its leading whitespace removed.
396  *
397  * Side Effects:
398  *	Only those that come from the various arguments.
399  */
400 void
401 Main_ParseArgLine(const char *line) 	/* Line to fracture */
402 {
403 	char **argv;			/* Manufactured argument vector */
404 	int argc;			/* Number of arguments in argv */
405 	char *args;			/* Space used by the args */
406 	char *buf;
407 	char *argv0;
408 	const char *s;
409 	size_t len;
410 
411 
412 	if (line == NULL)
413 		return;
414 	for (; *line == ' '; ++line)
415 		continue;
416 	if (!*line)
417 		return;
418 
419 	/* POSIX rule: MAKEFLAGS can hold a set of option letters without
420 	 * any blanks or dashes. */
421 	for (s = line;; s++) {
422 		if (*s == '\0') {
423 			while (line != s)
424 				posixParseOptLetter(*line++);
425 			return;
426 		}
427 		if (strchr(OPTLETTERS, *s) == NULL)
428 			break;
429 	}
430 	argv0 = Var_Value(".MAKE");
431 	len = strlen(line) + strlen(argv0) + 2;
432 	buf = emalloc(len);
433 	(void)snprintf(buf, len, "%s %s", argv0, line);
434 
435 	argv = brk_string(buf, &argc, &args);
436 	free(buf);
437 	MainParseArgs(argc, argv);
438 
439 	free(args);
440 	free(argv);
441 }
442 
443 /* Add a :-separated path to a Lst of directories.  */
444 static void
445 add_dirpath(Lst l, const char *n)
446 {
447 	const char *start;
448 	const char *cp;
449 
450 	for (start = n;;) {
451 		for (cp = start; *cp != '\0' && *cp != ':';)
452 			cp++;
453 		Dir_AddDiri(l, start, cp);
454 		if (*cp == '\0')
455 			break;
456 		else
457 			start= cp+1;
458 	}
459 }
460 
461 /*
462  * Get the name of this type of MACHINE from utsname so we can share an
463  * executable for similar machines. (i.e. m68k: amiga hp300, mac68k, sun3, ...)
464  *
465  * Note that MACHINE, MACHINE_ARCH and MACHINE_CPU are decided at
466  * run-time.
467  */
468 static char *
469 figure_out_MACHINE()
470 {
471 	char *r = getenv("MACHINE");
472 	if (r == NULL) {
473 		static struct utsname utsname;
474 
475 		if (uname(&utsname) == -1)
476 			err(2, "uname");
477 		r = utsname.machine;
478 	}
479 	return r;
480 }
481 
482 static char *
483 figure_out_MACHINE_ARCH()
484 {
485 	char *r = getenv("MACHINE_ARCH");
486 	if (r == NULL) {
487 #ifndef MACHINE_ARCH
488 		r = "unknown";	/* XXX: no uname -p yet */
489 #else
490 		r = MACHINE_ARCH;
491 #endif
492 	}
493 	return r;
494 }
495 static char *
496 figure_out_MACHINE_CPU()
497 {
498 	char *r = getenv("MACHINE_CPU");
499 	if (r == NULL) {
500 #if !defined(MACHINE_CPU) && ! defined(MACHINE_ARCH)
501 		r = "unknown";	/* XXX: no uname -p yet */
502 #else
503 #if defined(MACHINE_CPU)
504 		r = MACHINE_CPU;
505 #else
506 		r = MACHINE_ARCH;
507 #endif
508 #endif
509 	}
510 	return r;
511 }
512 
513 static char *
514 figure_out_CURDIR()
515 {
516 	char *dir, *cwd;
517 	struct stat sa, sb;
518 
519 	/* curdir is cwd... */
520 	cwd = dogetcwd();
521 	if (cwd == NULL)
522 		err(2, "getcwd");
523 
524 	if (stat(cwd, &sa) == -1)
525 		err(2, "%s", cwd);
526 
527 	/* ...but we can use the alias $PWD if we can prove it is the same
528 	 * directory */
529 	if ((dir = getenv("PWD")) != NULL) {
530 		if (stat(dir, &sb) == 0 && sa.st_ino == sb.st_ino &&
531 		    sa.st_dev == sb.st_dev) {
532 		    	free(cwd);
533 			return estrdup(dir);
534 		}
535 	}
536 
537 	return cwd;
538 }
539 
540 static char *
541 chdir_verify_path(const char *path, struct dirs *d)
542 {
543 	if (chdir(path) == 0) {
544 		if (path[0] != '/')
545 			return Str_concat(d->current, path, '/');
546 		else
547 			return estrdup(path);
548 	}
549 	return NULL;
550 }
551 
552 static void
553 setup_CURDIR_OBJDIR(struct dirs *d)
554 {
555 	char *path;
556 
557 	d->current = figure_out_CURDIR();
558 	/*
559 	 * If the MAKEOBJDIR (or by default, the _PATH_OBJDIR) directory
560 	 * exists, change into it and build there.
561 	 *
562 	 * Once things are initted,
563 	 * have to add the original directory to the search path,
564 	 * and modify the paths for the Makefiles appropriately.  The
565 	 * current directory is also placed as a variable for make scripts.
566 	 */
567 	if ((path = getenv("MAKEOBJDIR")) == NULL) {
568 		path = _PATH_OBJDIR;
569 	}
570 	d->object = chdir_verify_path(path, d);
571 	if (d->object == NULL)
572 		d->object = d->current;
573 }
574 
575 /*
576  * if the VPATH variable is defined, add its contents to the search path.
577  * Uses the same format as the PATH env variable, i.e.,
578  * <directory>:<directory>:<directory>...
579  */
580 static void
581 setup_VPATH()
582 {
583 	if (Var_Value("VPATH") != NULL) {
584 		char *vpath;
585 
586 		vpath = Var_Subst("${VPATH}", NULL, false);
587 		add_dirpath(defaultPath, vpath);
588 		(void)free(vpath);
589 	}
590 }
591 
592 static void
593 read_makefile_list(Lst mk, struct dirs *d)
594 {
595 	LstNode ln;
596 	ln = Lst_Find(mk, ReadMakefile, d);
597 	if (ln != NULL)
598 		Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
599 }
600 
601 static void
602 read_all_make_rules(bool noBuiltins, bool read_depend,
603     Lst makefiles, struct dirs *d)
604 {
605 	/*
606 	 * Read in the built-in rules first, followed by the specified
607 	 * makefile(s), or the default Makefile or makefile, in that order.
608 	 */
609 	if (!noBuiltins) {
610 		LIST sysMkPath; 		/* Path of sys.mk */
611 
612 		Lst_Init(&sysMkPath);
613 		Dir_Expand(_PATH_DEFSYSMK, systemIncludePath, &sysMkPath);
614 		if (Lst_IsEmpty(&sysMkPath))
615 			Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
616 
617 		read_makefile_list(&sysMkPath, d);
618 	}
619 
620 	if (!Lst_IsEmpty(makefiles)) {
621 		read_makefile_list(makefiles, d);
622 	} else if (!ReadMakefile("makefile", d))
623 		(void)ReadMakefile("Makefile", d);
624 
625 	/* read a .depend file, if it exists, and we're not building depend */
626 
627 	if (read_depend)
628 		(void)ReadMakefile(".depend", d);
629 	Parse_End();
630 }
631 
632 static void
633 run_node(GNode *gn, bool *has_errors, bool *out_of_date)
634 {
635 	LIST l;
636 
637 	Lst_Init(&l);
638 	Lst_AtEnd(&l, gn);
639 	engine_run_list(&l, has_errors, out_of_date);
640 	Lst_Destroy(&l, NOFREE);
641 }
642 
643 int main(int, char **);
644 
645 int
646 main(int argc, char **argv)
647 {
648 	static LIST targs;	/* target nodes to create */
649 	bool outOfDate = false;	/* false if all targets up to date */
650 	bool errored = false;	/* true if errors occurred */
651 	char *machine = figure_out_MACHINE();
652 	char *machine_arch = figure_out_MACHINE_ARCH();
653 	char *machine_cpu = figure_out_MACHINE_CPU();
654 	const char *syspath = _PATH_DEFSYSPATH;
655 	char *p;
656 	static struct dirs d;
657 	bool read_depend = true;/* false if we don't want to read .depend */
658 
659 	MainParseChdir(argc, argv);
660 	setup_CURDIR_OBJDIR(&d);
661 
662 	esetenv("PWD", d.object);
663 	unsetenv("CDPATH");
664 
665 	Static_Lst_Init(create);
666 	Static_Lst_Init(&makefiles);
667 	Static_Lst_Init(&varstoprint);
668 	Static_Lst_Init(&targs);
669 	Static_Lst_Init(&special);
670 
671 	beSilent = false;		/* Print commands as executed */
672 	ignoreErrors = false;		/* Pay attention to non-zero returns */
673 	noExecute = false;		/* Execute all commands */
674 	keepgoing = false;		/* Stop on error */
675 	allPrecious = false;		/* Remove targets when interrupted */
676 	queryFlag = false;		/* This is not just a check-run */
677 	noBuiltins = false;		/* Read the built-in rules */
678 	touchFlag = false;		/* Actually update targets */
679 	debug = 0;			/* No debug verbosity, please. */
680 
681 	optj = DEFMAXJOBS;
682 	compatMake = false;		/* No compat mode */
683 
684 
685 	/*
686 	 * Initialize all external modules.
687 	 */
688 	Init();
689 
690 	if (d.object != d.current)
691 		Dir_AddDir(defaultPath, d.current);
692 	Var_Set(".CURDIR", d.current);
693 	Var_Set(".OBJDIR", d.object);
694 	Parse_setcurdir(d.current);
695 	Targ_setdirs(d.current, d.object);
696 
697 	/*
698 	 * Initialize various variables.
699 	 *	MAKE also gets this name, for compatibility
700 	 *	.MAKEFLAGS gets set to the empty string just in case.
701 	 *	MFLAGS also gets initialized empty, for compatibility.
702 	 */
703 	Var_Set("MAKE", argv[0]);
704 	Var_Set(".MAKE", argv[0]);
705 	Var_Set(MAKEFLAGS, "");
706 	Var_Set("MFLAGS", "");
707 	Var_Set("MACHINE", machine);
708 	Var_Set("MACHINE_ARCH", machine_arch);
709 	Var_Set("MACHINE_CPU", machine_cpu);
710 
711 	/*
712 	 * First snag any flags out of the MAKEFLAGS environment variable.
713 	 */
714 	Main_ParseArgLine(getenv("MAKEFLAGS"));
715 
716 	basedirectory = getenv("MAKEBASEDIRECTORY");
717 	if (basedirectory == NULL)
718 		setenv("MAKEBASEDIRECTORY", d.current, 0);
719 
720 	MainParseArgs(argc, argv);
721 
722 	/*
723 	 * Be compatible if user did not specify -j
724 	 */
725 	if (!forceJobs)
726 		compatMake = true;
727 
728 	/* And set up everything for sub-makes */
729 	Var_AddCmdline(MAKEFLAGS);
730 
731 
732 	/*
733 	 * Set up the .TARGETS variable to contain the list of targets to be
734 	 * created. If none specified, make the variable empty -- the parser
735 	 * will fill the thing in with the default or .MAIN target.
736 	 */
737 	if (!Lst_IsEmpty(create)) {
738 		LstNode ln;
739 
740 		for (ln = Lst_First(create); ln != NULL; ln = Lst_Adv(ln)) {
741 			char *name = Lst_Datum(ln);
742 
743 			if (strcmp(name, "depend") == 0)
744 				read_depend = false;
745 
746 			Var_Append(".TARGETS", name);
747 		}
748 	} else
749 		Var_Set(".TARGETS", "");
750 
751 
752 	/*
753 	 * If no user-supplied system path was given (through the -m option)
754 	 * add the directories from the DEFSYSPATH (more than one may be given
755 	 * as dir1:...:dirn) to the system include path.
756 	 */
757 	if (Lst_IsEmpty(systemIncludePath))
758 	    add_dirpath(systemIncludePath, syspath);
759 
760 	read_all_make_rules(noBuiltins, read_depend, &makefiles, &d);
761 
762 	if (compatMake)
763 		optj = 1;
764 
765 	Var_Append("MFLAGS", Var_Value(MAKEFLAGS));
766 
767 	/* Install all the flags into the MAKEFLAGS env variable. */
768 	if (((p = Var_Value(MAKEFLAGS)) != NULL) && *p)
769 		esetenv("MAKEFLAGS", p);
770 
771 	setup_VPATH();
772 
773 	process_suffixes_after_makefile_is_read();
774 
775 	if (dumpData) {
776 		dump_data();
777 		exit(0);
778 	}
779 
780 	/* Print the initial graph, if the user requested it.  */
781 	if (DEBUG(GRAPH1))
782 		dump_data();
783 
784 	/* Print the values of any variables requested by the user.  */
785 	if (!Lst_IsEmpty(&varstoprint)) {
786 		LstNode ln;
787 
788 		for (ln = Lst_First(&varstoprint); ln != NULL;
789 		    ln = Lst_Adv(ln)) {
790 			char *value = Var_Value(Lst_Datum(ln));
791 
792 			printf("%s\n", value ? value : "");
793 		}
794 	} else {
795 		/* Have now read the entire graph and need to make a list
796 		 * of targets to create. If none was given on the command
797 		 * line, we consult the parsing module to find the main
798 		 * target(s) to create.  */
799 		if (Lst_IsEmpty(create))
800 			Parse_MainName(&targs);
801 		else
802 			Targ_FindList(&targs, create);
803 
804 		choose_engine(compatMake);
805 		Job_Init(optj);
806 		if (!queryFlag && node_is_real(begin_node))
807 			run_node(begin_node, &errored, &outOfDate);
808 
809 		if (!errored)
810 			engine_run_list(&targs, &errored, &outOfDate);
811 
812 		if (!queryFlag && !errored && node_is_real(end_node))
813 			run_node(end_node, &errored, &outOfDate);
814 	}
815 
816 	/* print the graph now it's been processed if the user requested it */
817 	if (DEBUG(GRAPH2))
818 		post_mortem();
819 
820 	/* Note that we only hit this code if -k is used, otherwise we
821 	 * exited early in case of errors. */
822 	if (errored)
823 		Fatal("Errors while building");
824 
825 	if (queryFlag && outOfDate)
826 		return 1;
827 	else
828 		return 0;
829 }
830 
831 struct unreadable {
832 	char *fname;
833 	int errcode;
834 };
835 
836 void
837 dump_unreadable(void)
838 {
839 	struct unreadable *u;
840 
841 	if (Lst_IsEmpty(&unreadable))
842 		return;
843 
844 	fprintf(stderr, "Makefile(s) that couldn't be read:\n");
845 
846 	while ((u = Lst_Pop(&unreadable))) {
847 		fprintf(stderr, "\t%s: %s\n", u->fname, strerror(u->errcode));
848 		free(u->fname);
849 		free(u);
850 	}
851 }
852 
853 static FILE *
854 open_makefile(const char *fname)
855 {
856 	FILE *stream;
857 	struct unreadable *u;
858 
859 	stream = fopen(fname, "r");
860 	if (stream != NULL)
861 		return stream;
862 
863 	if (errno != ENOENT) {
864 		u = emalloc(sizeof *u);
865 		u->fname = estrdup(fname);
866 		u->errcode = errno;
867 		Lst_AtEnd(&unreadable, u);
868 	}
869 
870 	return NULL;
871 }
872 
873 /*-
874  * ReadMakefile  --
875  *	Open and parse the given makefile.
876  *
877  * Results:
878  *	true if ok. false if couldn't open file.
879  *
880  * Side Effects:
881  *	lots
882  */
883 static bool
884 ReadMakefile(void *p, void *q)
885 {
886 	const char *fname = p;	/* makefile to read */
887 	struct dirs *d = q;
888 	FILE *stream;
889 	char *name;
890 
891 	if (!strcmp(fname, "-")) {
892 		Var_Set("MAKEFILE", "");
893 		Parse_File(estrdup("(stdin)"), stdin);
894 	} else {
895 		if ((stream = open_makefile(fname)) != NULL)
896 			goto found;
897 		/* if we've chdir'd, rebuild the path name */
898 		if (d->current != d->object && *fname != '/') {
899 			char *path;
900 
901 			path = Str_concat(d->current, fname, '/');
902 			if ((stream = open_makefile(path)) == NULL)
903 				free(path);
904 			else {
905 				fname = path;
906 				goto found;
907 			}
908 		}
909 		/* look in -I and system include directories. */
910 		name = Dir_FindFile(fname, userIncludePath);
911 		if (!name)
912 			name = Dir_FindFile(fname, systemIncludePath);
913 		if (!name)
914 			return false;
915 		/* do not try to open a file we already have, so that
916 		 * dump_unreadable() yields non-confusing results.
917 		 */
918 		if (strcmp(name, fname) == 0)
919 			return false;
920 		if ((stream = open_makefile(name)) == NULL)
921 			return false;
922 		fname = name;
923 		/*
924 		 * set the MAKEFILE variable desired by System V fans -- the
925 		 * placement of the setting here means it gets set to the last
926 		 * makefile specified, as it is set by SysV make.
927 		 */
928 found:		Var_Set("MAKEFILE", fname);
929 		Parse_File(fname, stream);
930 	}
931 	return true;
932 }
933 
934 
935 /*
936  * usage --
937  *	exit with usage message
938  */
939 static void
940 usage()
941 {
942 	(void)fprintf(stderr,
943 "usage: make [-BeiknpqrSst] [-C directory] [-D variable] [-d flags] [-f mk]\n\
944 	    [-I directory] [-j max_processes] [-m directory] [-V variable]\n\
945 	    [NAME=value ...] [target ...]\n");
946 	exit(2);
947 }
948 
949 
950