1/*-
2 * Copyright (c) 1988, 1989, 1990, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 * Copyright (c) 1989 by Berkeley Softworks
5 * 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. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *	This product includes software developed by the University of
21 *	California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 *    may be used to endorse or promote products derived from this software
24 *    without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)main.c      8.3 (Berkeley) 3/19/94
39 */
40
41#ifndef lint
42#if 0
43static char copyright[] =
44"@(#) Copyright (c) 1988, 1989, 1990, 1993\n\
45	The Regents of the University of California.  All rights reserved.\n";
46#endif
47#endif /* not lint */
48#include <sys/cdefs.h>
49__FBSDID("$FreeBSD$");
50
51/*
52 * main.c
53 *	The main file for this entire program. Exit routines etc
54 *	reside here.
55 *
56 * Utility functions defined in this file:
57 *	Main_ParseArgLine
58 *			Takes a line of arguments, breaks them and
59 *			treats them as if they were given when first
60 *			invoked. Used by the parse module to implement
61 *			the .MFLAGS target.
62 */
63
64#include <sys/param.h>
65#include <sys/stat.h>
66#include <sys/time.h>
67#include <sys/queue.h>
68#include <sys/resource.h>
69#include <sys/utsname.h>
70#include <sys/wait.h>
71#include <err.h>
72#include <errno.h>
73#include <stdlib.h>
74#include <string.h>
75#include <unistd.h>
76
77#include "arch.h"
78#include "buf.h"
79#include "config.h"
80#include "dir.h"
81#include "globals.h"
82#include "GNode.h"
83#include "job.h"
84#include "make.h"
85#include "parse.h"
86#include "pathnames.h"
87#include "shell.h"
88#include "str.h"
89#include "suff.h"
90#include "targ.h"
91#include "util.h"
92#include "var.h"
93
94extern char **environ;	/* XXX what header declares this variable? */
95
96#define	WANT_ENV_MKLVL	1
97#define	MKLVL_MAXVAL	500
98#define	MKLVL_ENVVAR	"__MKLVL__"
99
100/* ordered list of makefiles to read */
101static Lst makefiles = Lst_Initializer(makefiles);
102
103/* ordered list of source makefiles */
104static Lst source_makefiles = Lst_Initializer(source_makefiles);
105
106/* list of variables to print */
107static Lst variables = Lst_Initializer(variables);
108
109static Boolean	expandVars;	/* fully expand printed variables */
110static Boolean	noBuiltins;	/* -r flag */
111static Boolean	forceJobs;	/* -j argument given */
112static char	*curdir;	/* startup directory */
113static char	*objdir;	/* where we chdir'ed to */
114static char	**save_argv;	/* saved argv */
115static char	*save_makeflags;/* saved MAKEFLAGS */
116
117/* (-E) vars to override from env */
118Lst envFirstVars = Lst_Initializer(envFirstVars);
119
120/* Targets to be made */
121Lst create = Lst_Initializer(create);
122
123Boolean		allPrecious;	/* .PRECIOUS given on line by itself */
124Boolean		is_posix;	/* .POSIX target seen */
125Boolean		mfAutoDeps;	/* .MAKEFILEDEPS target seen */
126Boolean		remakingMakefiles; /* True if remaking makefiles is in progress */
127Boolean		beSilent;	/* -s flag */
128Boolean		beVerbose;	/* -v flag */
129Boolean		beQuiet;	/* -Q flag */
130Boolean		compatMake;	/* -B argument */
131int		debug;		/* -d flag */
132Boolean		ignoreErrors;	/* -i flag */
133int		jobLimit;	/* -j argument */
134int		makeErrors;	/* Number of targets not remade due to errors */
135Boolean		jobsRunning;	/* TRUE if the jobs might be running */
136Boolean		keepgoing;	/* -k flag */
137Boolean		noExecute;	/* -n flag */
138Boolean		printGraphOnly;	/* -p flag */
139Boolean		queryFlag;	/* -q flag */
140Boolean		touchFlag;	/* -t flag */
141Boolean		usePipes;	/* !-P flag */
142uint32_t	warn_cmd;	/* command line warning flags */
143uint32_t	warn_flags;	/* actual warning flags */
144uint32_t	warn_nocmd;	/* command line no-warning flags */
145
146time_t		now;		/* Time at start of make */
147struct GNode	*DEFAULT;	/* .DEFAULT node */
148
149static struct {
150	const char *foreign_name;
151	const char *freebsd_name;
152} arch_aliases[] = {
153	{ "x86_64", "amd64" },
154	{ "mipsel", "mips" },
155};
156
157/**
158 * Exit with usage message.
159 */
160static void
161usage(void)
162{
163	fprintf(stderr,
164	    "usage: make [-BPSXeiknpqrstv] [-C directory] [-D variable]\n"
165	    "\t[-d flags] [-E variable] [-f makefile] [-I directory]\n"
166	    "\t[-j max_jobs] [-m directory] [-V variable]\n"
167	    "\t[variable=value] [target ...]\n");
168	exit(2);
169}
170
171/**
172 * MFLAGS_append
173 *	Append a flag with an optional argument to MAKEFLAGS and MFLAGS
174 */
175static void
176MFLAGS_append(const char *flag, char *arg)
177{
178	char *str;
179
180	Var_Append(".MAKEFLAGS", flag, VAR_GLOBAL);
181	if (arg != NULL) {
182		str = MAKEFLAGS_quote(arg);
183		Var_Append(".MAKEFLAGS", str, VAR_GLOBAL);
184		free(str);
185	}
186
187	Var_Append("MFLAGS", flag, VAR_GLOBAL);
188	if (arg != NULL) {
189		str = MAKEFLAGS_quote(arg);
190		Var_Append("MFLAGS", str, VAR_GLOBAL);
191		free(str);
192	}
193}
194
195/**
196 * Main_ParseWarn
197 *
198 *	Handle argument to warning option.
199 */
200int
201Main_ParseWarn(const char *arg, int iscmd)
202{
203	int i, neg;
204
205	static const struct {
206		const char	*option;
207		uint32_t	flag;
208	} options[] = {
209		{ "dirsyntax",	WARN_DIRSYNTAX },
210		{ NULL,		0 }
211	};
212
213	neg = 0;
214	if (arg[0] == 'n' && arg[1] == 'o') {
215		neg = 1;
216		arg += 2;
217	}
218
219	for (i = 0; options[i].option != NULL; i++)
220		if (strcmp(arg, options[i].option) == 0)
221			break;
222
223	if (options[i].option == NULL)
224		/* unknown option */
225		return (-1);
226
227	if (iscmd) {
228		if (!neg) {
229			warn_cmd |= options[i].flag;
230			warn_nocmd &= ~options[i].flag;
231			warn_flags |= options[i].flag;
232		} else {
233			warn_nocmd |= options[i].flag;
234			warn_cmd &= ~options[i].flag;
235			warn_flags &= ~options[i].flag;
236		}
237	} else {
238		if (!neg) {
239			warn_flags |= (options[i].flag & ~warn_nocmd);
240		} else {
241			warn_flags &= ~(options[i].flag | warn_cmd);
242		}
243	}
244	return (0);
245}
246
247/**
248 * Open and parse the given makefile.
249 *
250 * Results:
251 *	TRUE if ok. FALSE if couldn't open file.
252 */
253static Boolean
254ReadMakefile(const char p[])
255{
256	char *fname, *fnamesave;	/* makefile to read */
257	FILE *stream;
258	char *name, path[MAXPATHLEN];
259	char *MAKEFILE;
260	int setMAKEFILE;
261
262	/* XXX - remove this once constification is done */
263	fnamesave = fname = estrdup(p);
264
265	if (!strcmp(fname, "-")) {
266		Parse_File("(stdin)", stdin);
267		Var_SetGlobal("MAKEFILE", "");
268	} else {
269		setMAKEFILE = strcmp(fname, ".depend");
270
271		/* if we've chdir'd, rebuild the path name */
272		if (curdir != objdir && *fname != '/') {
273			snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname);
274			/*
275			 * XXX The realpath stuff breaks relative includes
276			 * XXX in some cases.   The problem likely is in
277			 * XXX parse.c where it does special things in
278			 * XXX ParseDoInclude if the file is relative
279			 * XXX or absolute and not a system file.  There
280			 * XXX it assumes that if the current file that's
281			 * XXX being included is absolute, that any files
282			 * XXX that it includes shouldn't do the -I path
283			 * XXX stuff, which is inconsistent with historical
284			 * XXX behavior.  However, I can't penetrate the mists
285			 * XXX further, so I'm putting this workaround in
286			 * XXX here until such time as the underlying bug
287			 * XXX can be fixed.
288			 */
289#if THIS_BREAKS_THINGS
290			if (realpath(path, path) != NULL &&
291			    (stream = fopen(path, "r")) != NULL) {
292				MAKEFILE = fname;
293				fname = path;
294				goto found;
295			}
296		} else if (realpath(fname, path) != NULL) {
297			MAKEFILE = fname;
298			fname = path;
299			if ((stream = fopen(fname, "r")) != NULL)
300				goto found;
301		}
302#else
303			if ((stream = fopen(path, "r")) != NULL) {
304				MAKEFILE = fname;
305				fname = path;
306				goto found;
307			}
308		} else {
309			MAKEFILE = fname;
310			if ((stream = fopen(fname, "r")) != NULL)
311				goto found;
312		}
313#endif
314		/* look in -I and system include directories. */
315		name = Path_FindFile(fname, &parseIncPath);
316		if (!name)
317			name = Path_FindFile(fname, &sysIncPath);
318		if (!name || !(stream = fopen(name, "r"))) {
319			free(fnamesave);
320			return (FALSE);
321		}
322		MAKEFILE = fname = name;
323		/*
324		 * set the MAKEFILE variable desired by System V fans -- the
325		 * placement of the setting here means it gets set to the last
326		 * makefile specified, as it is set by SysV make.
327		 */
328found:
329		if (setMAKEFILE)
330			Var_SetGlobal("MAKEFILE", MAKEFILE);
331		Parse_File(fname, stream);
332	}
333	free(fnamesave);
334	return (TRUE);
335}
336
337/**
338 * Open and parse the given makefile.
339 * If open is successful add it to the list of makefiles.
340 *
341 * Results:
342 *	TRUE if ok. FALSE if couldn't open file.
343 */
344static Boolean
345TryReadMakefile(const char p[])
346{
347	char *data;
348	LstNode *last = Lst_Last(&source_makefiles);
349
350	if (!ReadMakefile(p))
351		return (FALSE);
352
353	data = estrdup(p);
354	if (last == NULL) {
355		LstNode *first = Lst_First(&source_makefiles);
356		Lst_Insert(&source_makefiles, first, data);
357	} else
358		Lst_Append(&source_makefiles, last, estrdup(p));
359	return (TRUE);
360}
361
362/**
363 * MainParseArgs
364 *	Parse a given argument vector. Called from main() and from
365 *	Main_ParseArgLine() when the .MAKEFLAGS target is used.
366 *
367 *	XXX: Deal with command line overriding .MAKEFLAGS in makefile
368 *
369 * Side Effects:
370 *	Various global and local flags will be set depending on the flags
371 *	given
372 */
373static void
374MainParseArgs(int argc, char **argv)
375{
376	int c;
377	Boolean	found_dd = FALSE;
378	char found_dir[MAXPATHLEN + 1];	/* for searching for sys.mk */
379
380rearg:
381	optind = 1;	/* since we're called more than once */
382	optreset = 1;
383#define OPTFLAGS "ABC:D:d:E:ef:I:ij:km:nPpQqrSstV:vXx:"
384	for (;;) {
385		if ((optind < argc) && strcmp(argv[optind], "--") == 0) {
386			found_dd = TRUE;
387		}
388		if ((c = getopt(argc, argv, OPTFLAGS)) == -1) {
389			break;
390		}
391		switch(c) {
392
393		case 'A':
394			arch_fatal = FALSE;
395			MFLAGS_append("-A", NULL);
396			break;
397		case 'B':
398			compatMake = TRUE;
399			MFLAGS_append("-B", NULL);
400			unsetenv("MAKE_JOBS_FIFO");
401			break;
402		case 'C':
403			if (chdir(optarg) == -1)
404				err(1, "chdir %s", optarg);
405			if (getcwd(curdir, MAXPATHLEN) == NULL)
406				err(2, NULL);
407			break;
408		case 'D':
409			Var_SetGlobal(optarg, "1");
410			MFLAGS_append("-D", optarg);
411			break;
412		case 'd': {
413			char *modules = optarg;
414
415			for (; *modules; ++modules)
416				switch (*modules) {
417				case 'A':
418					debug = ~0;
419					break;
420				case 'a':
421					debug |= DEBUG_ARCH;
422					break;
423				case 'c':
424					debug |= DEBUG_COND;
425					break;
426				case 'd':
427					debug |= DEBUG_DIR;
428					break;
429				case 'f':
430					debug |= DEBUG_FOR;
431					break;
432				case 'g':
433					if (modules[1] == '1') {
434						debug |= DEBUG_GRAPH1;
435						++modules;
436					}
437					else if (modules[1] == '2') {
438						debug |= DEBUG_GRAPH2;
439						++modules;
440					}
441					break;
442				case 'j':
443					debug |= DEBUG_JOB;
444					break;
445				case 'l':
446					debug |= DEBUG_LOUD;
447					break;
448				case 'm':
449					debug |= DEBUG_MAKE;
450					break;
451				case 's':
452					debug |= DEBUG_SUFF;
453					break;
454				case 't':
455					debug |= DEBUG_TARG;
456					break;
457				case 'v':
458					debug |= DEBUG_VAR;
459					break;
460				default:
461					warnx("illegal argument to d option "
462					    "-- %c", *modules);
463					usage();
464				}
465			MFLAGS_append("-d", optarg);
466			break;
467		}
468		case 'E':
469			Lst_AtEnd(&envFirstVars, estrdup(optarg));
470			MFLAGS_append("-E", optarg);
471			break;
472		case 'e':
473			checkEnvFirst = TRUE;
474			MFLAGS_append("-e", NULL);
475			break;
476		case 'f':
477			Lst_AtEnd(&makefiles, estrdup(optarg));
478			break;
479		case 'I':
480			Parse_AddIncludeDir(optarg);
481			MFLAGS_append("-I", optarg);
482			break;
483		case 'i':
484			ignoreErrors = TRUE;
485			MFLAGS_append("-i", NULL);
486			break;
487		case 'j': {
488			char *endptr;
489
490			forceJobs = TRUE;
491			jobLimit = strtol(optarg, &endptr, 10);
492			if (jobLimit <= 0 || *endptr != '\0') {
493				warnx("illegal number, -j argument -- %s",
494				    optarg);
495				usage();
496			}
497			MFLAGS_append("-j", optarg);
498			break;
499		}
500		case 'k':
501			keepgoing = TRUE;
502			MFLAGS_append("-k", NULL);
503			break;
504		case 'm':
505			/* look for magic parent directory search string */
506			if (strncmp(".../", optarg, 4) == 0) {
507				if (!Dir_FindHereOrAbove(curdir, optarg + 4,
508				    found_dir, sizeof(found_dir)))
509					break;		/* nothing doing */
510				Path_AddDir(&sysIncPath, found_dir);
511			} else {
512				Path_AddDir(&sysIncPath, optarg);
513			}
514			MFLAGS_append("-m", optarg);
515			break;
516		case 'n':
517			noExecute = TRUE;
518			MFLAGS_append("-n", NULL);
519			break;
520		case 'P':
521			usePipes = FALSE;
522			MFLAGS_append("-P", NULL);
523			break;
524		case 'p':
525			printGraphOnly = TRUE;
526			debug |= DEBUG_GRAPH1;
527			break;
528		case 'Q':
529			beQuiet = TRUE;
530			beVerbose = FALSE;
531			MFLAGS_append("-Q", NULL);
532			break;
533		case 'q':
534			queryFlag = TRUE;
535			/* Kind of nonsensical, wot? */
536			MFLAGS_append("-q", NULL);
537			break;
538		case 'r':
539			noBuiltins = TRUE;
540			MFLAGS_append("-r", NULL);
541			break;
542		case 'S':
543			keepgoing = FALSE;
544			MFLAGS_append("-S", NULL);
545			break;
546		case 's':
547			beSilent = TRUE;
548			MFLAGS_append("-s", NULL);
549			break;
550		case 't':
551			touchFlag = TRUE;
552			MFLAGS_append("-t", NULL);
553			break;
554		case 'V':
555			Lst_AtEnd(&variables, estrdup(optarg));
556			MFLAGS_append("-V", optarg);
557			break;
558		case 'v':
559			beVerbose = TRUE;
560			beQuiet = FALSE;
561			MFLAGS_append("-v", NULL);
562			break;
563		case 'X':
564			expandVars = FALSE;
565			break;
566		case 'x':
567			if (Main_ParseWarn(optarg, 1) != -1)
568				MFLAGS_append("-x", optarg);
569			break;
570
571		default:
572		case '?':
573			usage();
574		}
575	}
576	argv += optind;
577	argc -= optind;
578
579	oldVars = TRUE;
580
581	/*
582	 * Parse the rest of the arguments.
583	 *	o Check for variable assignments and perform them if so.
584	 *	o Check for more flags and restart getopt if so.
585	 *	o Anything else is taken to be a target and added
586	 *	  to the end of the "create" list.
587	 */
588	for (; *argv != NULL; ++argv, --argc) {
589		if (Parse_IsVar(*argv)) {
590			char *ptr = MAKEFLAGS_quote(*argv);
591			char *v = estrdup(*argv);
592
593			Var_Append(".MAKEFLAGS", ptr, VAR_GLOBAL);
594			Parse_DoVar(v, VAR_CMD);
595			free(ptr);
596			free(v);
597
598		} else if ((*argv)[0] == '-') {
599			if ((*argv)[1] == '\0') {
600				/*
601				 * (*argv) is a single dash, so we
602				 * just ignore it.
603				 */
604			} else if (found_dd) {
605				/*
606				 * Double dash has been found, ignore
607				 * any more options.  But what do we do
608				 * with it?  For now treat it like a target.
609				 */
610				Lst_AtEnd(&create, estrdup(*argv));
611			} else {
612				/*
613				 * (*argv) is a -flag, so backup argv and
614				 * argc.  getopt() expects options to start
615				 * in the 2nd position.
616				 */
617				argc++;
618				argv--;
619				goto rearg;
620			}
621
622		} else if ((*argv)[0] == '\0') {
623			Punt("illegal (null) argument.");
624
625		} else {
626			Lst_AtEnd(&create, estrdup(*argv));
627		}
628	}
629}
630
631/**
632 * Main_ParseArgLine
633 *	Used by the parse module when a .MFLAGS or .MAKEFLAGS target
634 *	is encountered and by main() when reading the .MAKEFLAGS envariable.
635 *	Takes a line of arguments and breaks it into its
636 *	component words and passes those words and the number of them to the
637 *	MainParseArgs function.
638 *	The line should have all its leading whitespace removed.
639 *
640 * Side Effects:
641 *	Only those that come from the various arguments.
642 */
643void
644Main_ParseArgLine(char *line, int mflags)
645{
646	ArgArray	aa;
647
648	if (line == NULL)
649		return;
650	for (; *line == ' '; ++line)
651		continue;
652	if (!*line)
653		return;
654
655	if (mflags)
656		MAKEFLAGS_break(&aa, line);
657	else
658		brk_string(&aa, line, TRUE);
659
660	MainParseArgs(aa.argc, aa.argv);
661	ArgArray_Done(&aa);
662}
663
664static char *
665chdir_verify_path(const char *path, char *obpath)
666{
667	struct stat sb;
668
669	if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
670		if (chdir(path) == -1 || getcwd(obpath, MAXPATHLEN) == NULL) {
671			warn("warning: %s", path);
672			return (NULL);
673		}
674		return (obpath);
675	}
676
677	return (NULL);
678}
679
680/**
681 * In lieu of a good way to prevent every possible looping in make(1), stop
682 * there from being more than MKLVL_MAXVAL processes forked by make(1), to
683 * prevent a forkbomb from happening, in a dumb and mechanical way.
684 *
685 * Side Effects:
686 *	Creates or modifies environment variable MKLVL_ENVVAR via setenv().
687 */
688static void
689check_make_level(void)
690{
691#ifdef WANT_ENV_MKLVL
692	char	*value = getenv(MKLVL_ENVVAR);
693	int	level = (value == NULL) ? 0 : atoi(value);
694
695	if (level < 0) {
696		errx(2, "Invalid value for recursion level (%d).", level);
697	} else if (level > MKLVL_MAXVAL) {
698		errx(2, "Max recursion level (%d) exceeded.", MKLVL_MAXVAL);
699	} else {
700		char new_value[32];
701		sprintf(new_value, "%d", level + 1);
702		setenv(MKLVL_ENVVAR, new_value, 1);
703	}
704#endif /* WANT_ENV_MKLVL */
705}
706
707/**
708 * Main_AddSourceMakefile
709 *	Add a file to the list of source makefiles
710 */
711void
712Main_AddSourceMakefile(const char *name)
713{
714
715	Lst_AtEnd(&source_makefiles, estrdup(name));
716}
717
718/**
719 * Remake_Makefiles
720 *	Remake all the makefiles
721 */
722static void
723Remake_Makefiles(void)
724{
725	Lst cleanup;
726	LstNode *ln;
727	int error_cnt = 0;
728	int remade_cnt = 0;
729
730	Compat_InstallSignalHandlers();
731	if (curdir != objdir) {
732		if (chdir(curdir) < 0)
733			Fatal("Failed to change directory to %s.", curdir);
734	}
735
736	Lst_Init(&cleanup);
737	LST_FOREACH(ln, &source_makefiles) {
738		LstNode *ln2;
739		struct GNode *gn;
740		const char *name = Lst_Datum(ln);
741		Boolean saveTouchFlag = touchFlag;
742		Boolean saveQueryFlag = queryFlag;
743		Boolean saveNoExecute = noExecute;
744		int mtime;
745
746		/*
747		 * Create node
748		 */
749		gn = Targ_FindNode(name, TARG_CREATE);
750		DEBUGF(MAKE, ("Checking %s...", gn->name));
751		Suff_FindDeps(gn);
752
753		/*
754		 * -t, -q and -n has no effect unless the makefile is
755		 * specified as one of the targets explicitly in the
756		 * command line
757		 */
758		LST_FOREACH(ln2, &create) {
759			if (!strcmp(gn->name, Lst_Datum(ln2))) {
760				/* found as a target */
761				break;
762			}
763		}
764		if (ln2 == NULL) {
765			touchFlag = FALSE;
766			queryFlag = FALSE;
767			noExecute = FALSE;
768		}
769
770		/*
771		 * Check and remake the makefile
772		 */
773		mtime = Dir_MTime(gn);
774		remakingMakefiles = TRUE;
775		Compat_Make(gn, gn);
776		remakingMakefiles = FALSE;
777
778		/*
779		 * Restore -t, -q and -n behaviour
780		 */
781		touchFlag = saveTouchFlag;
782		queryFlag = saveQueryFlag;
783		noExecute = saveNoExecute;
784
785		/*
786		 * Compat_Make will leave the 'made' field of gn
787		 * in one of the following states:
788		 *	UPTODATE  gn was already up-to-date
789		 *	MADE	  gn was recreated successfully
790		 *	ERROR	  An error occurred while gn was being created
791		 *	ABORTED	  gn was not remade because one of its inferiors
792		 *		  could not be made due to errors.
793		 */
794		if (gn->made == MADE) {
795			if (mtime != Dir_MTime(gn)) {
796				DEBUGF(MAKE,
797				    ("%s updated (%d -> %d).\n",
798				     gn->name, mtime, gn->mtime));
799				remade_cnt++;
800			} else {
801				DEBUGF(MAKE,
802				    ("%s not updated: skipping restart.\n",
803				     gn->name));
804			}
805		} else if (gn->made == ERROR)
806			error_cnt++;
807		else if (gn->made == ABORTED) {
808			printf("`%s' not remade because of errors.\n",
809			    gn->name);
810			error_cnt++;
811		} else if (gn->made == UPTODATE) {
812			Lst_EnQueue(&cleanup, gn);
813		}
814	}
815
816	if (error_cnt > 0)
817		Fatal("Failed to remake Makefiles.");
818	if (remade_cnt > 0) {
819		DEBUGF(MAKE, ("Restarting `%s'.\n", save_argv[0]));
820
821		/*
822		 * Some of makefiles were remade -- restart from clean state
823		 */
824		if (save_makeflags != NULL)
825			setenv("MAKEFLAGS", save_makeflags, 1);
826		else
827			unsetenv("MAKEFLAGS");
828		if (execvp(save_argv[0], save_argv) < 0) {
829			Fatal("Can't restart `%s': %s.",
830			    save_argv[0], strerror(errno));
831		}
832	}
833
834	while (!Lst_IsEmpty(&cleanup)) {
835		GNode *gn = Lst_DeQueue(&cleanup);
836
837		gn->unmade = 0;
838		gn->make = FALSE;
839		gn->made = UNMADE;
840		gn->childMade = FALSE;
841		gn->mtime = gn->cmtime = 0;
842		gn->cmtime_gn = NULL;
843
844		LST_FOREACH(ln, &gn->children) {
845			GNode *cgn = Lst_Datum(ln);
846
847			gn->unmade++;
848			Lst_EnQueue(&cleanup, cgn);
849		}
850	}
851
852	if (curdir != objdir) {
853		if (chdir(objdir) < 0)
854			Fatal("Failed to change directory to %s.", objdir);
855	}
856}
857
858/**
859 * main
860 *	The main function, for obvious reasons. Initializes variables
861 *	and a few modules, then parses the arguments give it in the
862 *	environment and on the command line. Reads the system makefile
863 *	followed by either Makefile, makefile or the file given by the
864 *	-f argument. Sets the .MAKEFLAGS PMake variable based on all the
865 *	flags it has received by then uses either the Make or the Compat
866 *	module to create the initial list of targets.
867 *
868 * Results:
869 *	If -q was given, exits -1 if anything was out-of-date. Else it exits
870 *	0.
871 *
872 * Side Effects:
873 *	The program exits when done. Targets are created. etc. etc. etc.
874 */
875int
876main(int argc, char **argv)
877{
878	const char *machine;
879	const char *machine_arch;
880	const char *machine_cpu;
881	Boolean outOfDate = TRUE;	/* FALSE if all targets up to date */
882	const char *p;
883	const char *pathp;
884	const char *path;
885	char mdpath[MAXPATHLEN];
886	char obpath[MAXPATHLEN];
887	char cdpath[MAXPATHLEN];
888	char found_dir[MAXPATHLEN + 1];	/* for searching for sys.mk */
889	char *cp = NULL, *start;
890
891	save_argv = argv;
892	save_makeflags = getenv("MAKEFLAGS");
893	if (save_makeflags != NULL)
894		save_makeflags = estrdup(save_makeflags);
895
896	/*
897	 * Initialize file global variables.
898	 */
899	expandVars = TRUE;
900	noBuiltins = FALSE;		/* Read the built-in rules */
901	forceJobs = FALSE;		/* No -j flag */
902	curdir = cdpath;
903
904	/*
905	 * Initialize program global variables.
906	 */
907	beSilent = FALSE;		/* Print commands as executed */
908	ignoreErrors = FALSE;		/* Pay attention to non-zero returns */
909	noExecute = FALSE;		/* Execute all commands */
910	printGraphOnly = FALSE;		/* Don't stop after printing graph */
911	keepgoing = FALSE;		/* Stop on error */
912	allPrecious = FALSE;		/* Remove targets when interrupted */
913	queryFlag = FALSE;		/* This is not just a check-run */
914	touchFlag = FALSE;		/* Actually update targets */
915	usePipes = TRUE;		/* Catch child output in pipes */
916	debug = 0;			/* No debug verbosity, please. */
917	jobsRunning = FALSE;
918
919	jobLimit = DEFMAXJOBS;
920	compatMake = FALSE;		/* No compat mode */
921
922	check_make_level();
923
924#ifdef RLIMIT_NOFILE
925	/*
926	 * get rid of resource limit on file descriptors
927	 */
928	{
929		struct rlimit rl;
930		if (getrlimit(RLIMIT_NOFILE, &rl) == -1) {
931			err(2, "getrlimit");
932		}
933		rl.rlim_cur = rl.rlim_max;
934		if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
935			err(2, "setrlimit");
936		}
937	}
938#endif
939
940	/*
941	 * Get the name of this type of MACHINE from utsname
942	 * so we can share an executable for similar machines.
943	 * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
944	 *
945	 * Note that both MACHINE and MACHINE_ARCH are decided at
946	 * run-time.
947	 */
948	if ((machine = getenv("MACHINE")) == NULL) {
949		static struct utsname utsname;
950		unsigned int i;
951
952		if (uname(&utsname) == -1)
953			err(2, "uname");
954		machine = utsname.machine;
955
956		/* Canonicalize non-FreeBSD naming conventions */
957		for (i = 0; i < sizeof(arch_aliases)
958		     / sizeof(arch_aliases[0]); i++)
959			if (!strcmp(machine, arch_aliases[i].foreign_name)) {
960				machine = arch_aliases[i].freebsd_name;
961				break;
962			}
963	}
964
965	if ((machine_arch = getenv("MACHINE_ARCH")) == NULL) {
966#ifdef MACHINE_ARCH
967		machine_arch = MACHINE_ARCH;
968#else
969		machine_arch = "unknown";
970#endif
971	}
972
973	/*
974	 * Set machine_cpu to the minimum supported CPU revision based
975	 * on the target architecture, if not already set.
976	 */
977	if ((machine_cpu = getenv("MACHINE_CPU")) == NULL) {
978		if (!strcmp(machine_arch, "i386"))
979			machine_cpu = "i486";
980		else
981			machine_cpu = "unknown";
982	}
983
984	/*
985	 * Initialize the parsing, directory and variable modules to prepare
986	 * for the reading of inclusion paths and variable settings on the
987	 * command line
988	 */
989	Proc_Init();
990
991	Dir_Init();		/* Initialize directory structures so -I flags
992				 * can be processed correctly */
993	Var_Init(environ);	/* As well as the lists of variables for
994				 * parsing arguments */
995
996	/*
997	 * Initialize the Shell so that we have a shell for != assignments
998	 * on the command line.
999	 */
1000	Shell_Init();
1001
1002	/*
1003	 * Initialize various variables.
1004	 *	MAKE also gets this name, for compatibility
1005	 *	.MAKEFLAGS gets set to the empty string just in case.
1006	 *	MFLAGS also gets initialized empty, for compatibility.
1007	 */
1008	Var_SetGlobal("MAKE", argv[0]);
1009	Var_SetGlobal(".MAKEFLAGS", "");
1010	Var_SetGlobal("MFLAGS", "");
1011	Var_SetGlobal("MACHINE", machine);
1012	Var_SetGlobal("MACHINE_ARCH", machine_arch);
1013	Var_SetGlobal("MACHINE_CPU", machine_cpu);
1014#ifdef MAKE_VERSION
1015	Var_SetGlobal("MAKE_VERSION", MAKE_VERSION);
1016#endif
1017	Var_SetGlobal(".newline", "\n");	/* handy for :@ loops */
1018	{
1019		char tmp[64];
1020
1021		snprintf(tmp, sizeof(tmp), "%u", getpid());
1022		Var_SetGlobal(".MAKE.PID", tmp);
1023		snprintf(tmp, sizeof(tmp), "%u", getppid());
1024		Var_SetGlobal(".MAKE.PPID", tmp);
1025	}
1026	Job_SetPrefix();
1027
1028	/*
1029	 * Find where we are...
1030	 */
1031	if (getcwd(curdir, MAXPATHLEN) == NULL)
1032		err(2, NULL);
1033
1034	/*
1035	 * First snag things out of the MAKEFLAGS environment
1036	 * variable.  Then parse the command line arguments.
1037	 */
1038	Main_ParseArgLine(getenv("MAKEFLAGS"), 1);
1039
1040	MainParseArgs(argc, argv);
1041
1042	/*
1043	 * Verify that cwd is sane (after -C may have changed it).
1044	 */
1045	{
1046	struct stat sa;
1047
1048	if (stat(curdir, &sa) == -1)
1049	    err(2, "%s", curdir);
1050	}
1051
1052	/*
1053	 * The object directory location is determined using the
1054	 * following order of preference:
1055	 *
1056	 *	1. MAKEOBJDIRPREFIX`cwd`
1057	 *	2. MAKEOBJDIR
1058	 *	3. PATH_OBJDIR.${MACHINE}
1059	 *	4. PATH_OBJDIR
1060	 *	5. PATH_OBJDIRPREFIX`cwd`
1061	 *
1062	 * If one of the first two fails, use the current directory.
1063	 * If the remaining three all fail, use the current directory.
1064	 *
1065	 * Once things are initted,
1066	 * have to add the original directory to the search path,
1067	 * and modify the paths for the Makefiles appropriately.  The
1068	 * current directory is also placed as a variable for make scripts.
1069	 */
1070	if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
1071		if (!(path = getenv("MAKEOBJDIR"))) {
1072			path = PATH_OBJDIR;
1073			pathp = PATH_OBJDIRPREFIX;
1074			snprintf(mdpath, MAXPATHLEN, "%s.%s", path, machine);
1075			if (!(objdir = chdir_verify_path(mdpath, obpath)))
1076				if (!(objdir=chdir_verify_path(path, obpath))) {
1077					snprintf(mdpath, MAXPATHLEN,
1078							"%s%s", pathp, curdir);
1079					if (!(objdir=chdir_verify_path(mdpath,
1080								       obpath)))
1081						objdir = curdir;
1082				}
1083		}
1084		else if (!(objdir = chdir_verify_path(path, obpath)))
1085			objdir = curdir;
1086	}
1087	else {
1088		snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
1089		if (!(objdir = chdir_verify_path(mdpath, obpath)))
1090			objdir = curdir;
1091	}
1092	Dir_InitDot();		/* Initialize the "." directory */
1093	if (objdir != curdir)
1094		Path_AddDir(&dirSearchPath, curdir);
1095	Var_SetGlobal(".ST_EXPORTVAR", "YES");
1096	Var_SetGlobal(".CURDIR", curdir);
1097	Var_SetGlobal(".OBJDIR", objdir);
1098
1099	if (getenv("MAKE_JOBS_FIFO") != NULL)
1100		forceJobs = TRUE;
1101	/*
1102	 * Be compatible if user did not specify -j and did not explicitly
1103	 * turned compatibility on
1104	 */
1105	if (!compatMake && !forceJobs)
1106		compatMake = TRUE;
1107
1108	/*
1109	 * Initialize target and suffix modules in preparation for
1110	 * parsing the makefile(s)
1111	 */
1112	Targ_Init();
1113	Suff_Init();
1114
1115	DEFAULT = NULL;
1116	time(&now);
1117
1118	/*
1119	 * Set up the .TARGETS variable to contain the list of targets to be
1120	 * created. If none specified, make the variable empty -- the parser
1121	 * will fill the thing in with the default or .MAIN target.
1122	 */
1123	if (Lst_IsEmpty(&create)) {
1124		Var_SetGlobal(".TARGETS", "");
1125	} else {
1126		LstNode *ln;
1127
1128		for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) {
1129			char *name = Lst_Datum(ln);
1130
1131			Var_Append(".TARGETS", name, VAR_GLOBAL);
1132		}
1133	}
1134
1135
1136	/*
1137	 * If no user-supplied system path was given (through the -m option)
1138	 * add the directories from the DEFSYSPATH (more than one may be given
1139	 * as dir1:...:dirn) to the system include path.
1140	 */
1141	if (TAILQ_EMPTY(&sysIncPath)) {
1142		char defsyspath[] = PATH_DEFSYSPATH;
1143		char *syspath = getenv("MAKESYSPATH");
1144
1145		/*
1146		 * If no user-supplied system path was given (thru -m option)
1147		 * add the directories from the DEFSYSPATH (more than one may
1148		 * be given as dir1:...:dirn) to the system include path.
1149		 */
1150		if (syspath == NULL || *syspath == '\0')
1151			syspath = defsyspath;
1152		else
1153			syspath = estrdup(syspath);
1154
1155		for (start = syspath; *start != '\0'; start = cp) {
1156			for (cp = start; *cp != '\0' && *cp != ':'; cp++)
1157				continue;
1158			if (*cp == ':') {
1159				*cp++ = '\0';
1160			}
1161			/* look for magic parent directory search string */
1162			if (strncmp(".../", start, 4) == 0) {
1163				if (Dir_FindHereOrAbove(curdir, start + 4,
1164				    found_dir, sizeof(found_dir))) {
1165					Path_AddDir(&sysIncPath, found_dir);
1166				}
1167			} else {
1168				Path_AddDir(&sysIncPath, start);
1169			}
1170		}
1171		if (syspath != defsyspath)
1172			free(syspath);
1173	}
1174
1175	/*
1176	 * Read in the built-in rules first, followed by the specified
1177	 * makefile, if it was (makefile != (char *) NULL), or the default
1178	 * Makefile and makefile, in that order, if it wasn't.
1179	 */
1180	if (!noBuiltins) {
1181		/* Path of sys.mk */
1182		Lst sysMkPath = Lst_Initializer(sysMkPath);
1183		LstNode *ln;
1184		char	defsysmk[] = PATH_DEFSYSMK;
1185
1186		Path_Expand(defsysmk, &sysIncPath, &sysMkPath);
1187		if (Lst_IsEmpty(&sysMkPath))
1188			Fatal("make: no system rules (%s).", PATH_DEFSYSMK);
1189		LST_FOREACH(ln, &sysMkPath) {
1190			if (!ReadMakefile(Lst_Datum(ln)))
1191				break;
1192		}
1193		if (ln != NULL)
1194			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
1195		Lst_Destroy(&sysMkPath, free);
1196	}
1197
1198	if (!Lst_IsEmpty(&makefiles)) {
1199		LstNode *ln;
1200
1201		LST_FOREACH(ln, &makefiles) {
1202			if (!TryReadMakefile(Lst_Datum(ln)))
1203				break;
1204		}
1205		if (ln != NULL)
1206			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
1207	} else if (!TryReadMakefile("BSDmakefile"))
1208	    if (!TryReadMakefile("makefile"))
1209		TryReadMakefile("Makefile");
1210
1211	ReadMakefile(".depend");
1212
1213	/* Install all the flags into the MAKEFLAGS envariable. */
1214	if (((p = Var_Value(".MAKEFLAGS", VAR_GLOBAL)) != NULL) && *p)
1215		setenv("MAKEFLAGS", p, 1);
1216	else
1217		setenv("MAKEFLAGS", "", 1);
1218
1219	/*
1220	 * For compatibility, look at the directories in the VPATH variable
1221	 * and add them to the search path, if the variable is defined. The
1222	 * variable's value is in the same format as the PATH envariable, i.e.
1223	 * <directory>:<directory>:<directory>...
1224	 */
1225	if (Var_Exists("VPATH", VAR_CMD)) {
1226		/*
1227		 * GCC stores string constants in read-only memory, but
1228		 * Var_Subst will want to write this thing, so store it
1229		 * in an array
1230		 */
1231		static char VPATH[] = "${VPATH}";
1232		Buffer	*buf;
1233		char	*vpath;
1234		char	*ptr;
1235		char	savec;
1236
1237		buf = Var_Subst(VPATH, VAR_CMD, FALSE);
1238
1239		vpath = Buf_Data(buf);
1240		do {
1241			/* skip to end of directory */
1242			for (ptr = vpath; *ptr != ':' && *ptr != '\0'; ptr++)
1243				;
1244
1245			/* Save terminator character so know when to stop */
1246			savec = *ptr;
1247			*ptr = '\0';
1248
1249			/* Add directory to search path */
1250			Path_AddDir(&dirSearchPath, vpath);
1251
1252			vpath = ptr + 1;
1253		} while (savec != '\0');
1254
1255		Buf_Destroy(buf, TRUE);
1256	}
1257
1258	/*
1259	 * Now that all search paths have been read for suffixes et al, it's
1260	 * time to add the default search path to their lists...
1261	 */
1262	Suff_DoPaths();
1263
1264	/* print the initial graph, if the user requested it */
1265	if (DEBUG(GRAPH1))
1266		Targ_PrintGraph(1);
1267
1268	/* print the values of any variables requested by the user */
1269	if (Lst_IsEmpty(&variables) && !printGraphOnly) {
1270		/*
1271		 * Since the user has not requested that any variables
1272		 * be printed, we can build targets.
1273		 *
1274		 * Have read the entire graph and need to make a list of targets
1275		 * to create. If none was given on the command line, we consult
1276		 * the parsing module to find the main target(s) to create.
1277		 */
1278		Lst targs = Lst_Initializer(targs);
1279
1280		if (!is_posix && mfAutoDeps) {
1281			/*
1282			 * Check if any of the makefiles are out-of-date.
1283			 */
1284			Remake_Makefiles();
1285		}
1286
1287		if (Lst_IsEmpty(&create))
1288			Parse_MainName(&targs);
1289		else
1290			Targ_FindList(&targs, &create, TARG_CREATE);
1291
1292		if (compatMake) {
1293			/*
1294			 * Compat_Init will take care of creating
1295			 * all the targets as well as initializing
1296			 * the module.
1297			 */
1298			Compat_Run(&targs);
1299			outOfDate = 0;
1300		} else {
1301			/*
1302			 * Initialize job module before traversing
1303			 * the graph, now that any .BEGIN and .END
1304			 * targets have been read.  This is done
1305			 * only if the -q flag wasn't given (to
1306			 * prevent the .BEGIN from being executed
1307			 * should it exist).
1308			 */
1309			if (!queryFlag) {
1310				Job_Init(jobLimit);
1311				jobsRunning = TRUE;
1312			}
1313
1314			/* Traverse the graph, checking on all the targets */
1315			outOfDate = Make_Run(&targs);
1316		}
1317		Lst_Destroy(&targs, NOFREE);
1318
1319	} else {
1320		Var_Print(&variables, expandVars);
1321	}
1322
1323	Lst_Destroy(&variables, free);
1324	Lst_Destroy(&makefiles, free);
1325	Lst_Destroy(&source_makefiles, free);
1326	Lst_Destroy(&create, free);
1327
1328	/* print the graph now it's been processed if the user requested it */
1329	if (DEBUG(GRAPH2))
1330		Targ_PrintGraph(2);
1331
1332	if (queryFlag)
1333		return (outOfDate);
1334
1335	if (makeErrors != 0)
1336		Finish(makeErrors);
1337
1338	return (0);
1339}
1340