main.c revision 146146
1141104Sharti/*-
21590Srgrimes * Copyright (c) 1988, 1989, 1990, 1993
31590Srgrimes *	The Regents of the University of California.  All rights reserved.
41590Srgrimes * Copyright (c) 1989 by Berkeley Softworks
51590Srgrimes * All rights reserved.
61590Srgrimes *
71590Srgrimes * This code is derived from software contributed to Berkeley by
81590Srgrimes * Adam de Boor.
91590Srgrimes *
101590Srgrimes * Redistribution and use in source and binary forms, with or without
111590Srgrimes * modification, are permitted provided that the following conditions
121590Srgrimes * are met:
131590Srgrimes * 1. Redistributions of source code must retain the above copyright
141590Srgrimes *    notice, this list of conditions and the following disclaimer.
151590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
161590Srgrimes *    notice, this list of conditions and the following disclaimer in the
171590Srgrimes *    documentation and/or other materials provided with the distribution.
181590Srgrimes * 3. All advertising materials mentioning features or use of this software
191590Srgrimes *    must display the following acknowledgement:
201590Srgrimes *	This product includes software developed by the University of
211590Srgrimes *	California, Berkeley and its contributors.
221590Srgrimes * 4. Neither the name of the University nor the names of its contributors
231590Srgrimes *    may be used to endorse or promote products derived from this software
241590Srgrimes *    without specific prior written permission.
251590Srgrimes *
261590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
271590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
281590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
291590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
301590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
311590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
321590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
331590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
341590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
351590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
361590Srgrimes * SUCH DAMAGE.
3762833Swsanchez *
3862833Swsanchez * @(#)main.c      8.3 (Berkeley) 3/19/94
391590Srgrimes */
401590Srgrimes
411590Srgrimes#ifndef lint
4294595Sobrien#if 0
4394589Sobrienstatic char copyright[] =
4494589Sobrien"@(#) Copyright (c) 1988, 1989, 1990, 1993\n\
4594589Sobrien	The Regents of the University of California.  All rights reserved.\n";
4694595Sobrien#endif
471590Srgrimes#endif /* not lint */
4894589Sobrien#include <sys/cdefs.h>
4994587Sobrien__FBSDID("$FreeBSD: head/usr.bin/make/main.c 146146 2005-05-12 15:04:14Z harti $");
501590Srgrimes
51144475Sharti/*
52144475Sharti * main.c
531590Srgrimes *	The main file for this entire program. Exit routines etc
541590Srgrimes *	reside here.
551590Srgrimes *
561590Srgrimes * Utility functions defined in this file:
57144475Sharti *	Main_ParseArgLine
58144475Sharti *			Takes a line of arguments, breaks them and
59144475Sharti *			treats them as if they were given when first
60144475Sharti *			invoked. Used by the parse module to implement
61144475Sharti *			the .MFLAGS target.
621590Srgrimes */
631590Srgrimes
64141104Sharti#ifndef MACHINE
65141104Sharti#include <sys/utsname.h>
66141104Sharti#endif
671590Srgrimes#include <sys/param.h>
681590Srgrimes#include <sys/stat.h>
6939006Skato#include <sys/sysctl.h>
70127880Sdes#include <sys/time.h>
71144020Sharti#include <sys/queue.h>
72127899Sru#include <sys/resource.h>
7318730Ssteve#include <sys/wait.h>
7427644Scharnier#include <err.h>
751590Srgrimes#include <errno.h>
76127880Sdes#include <stdlib.h>
77141104Sharti#include <string.h>
7863955Simp#include <unistd.h>
79127880Sdes
80141104Sharti#include "arch.h"
81141133Sharti#include "buf.h"
82141104Sharti#include "config.h"
831590Srgrimes#include "dir.h"
84141104Sharti#include "globals.h"
851590Srgrimes#include "job.h"
86141104Sharti#include "make.h"
87141104Sharti#include "parse.h"
881590Srgrimes#include "pathnames.h"
89141104Sharti#include "str.h"
90141104Sharti#include "suff.h"
91141104Sharti#include "targ.h"
92141104Sharti#include "util.h"
93141104Sharti#include "var.h"
941590Srgrimes
95146146Shartiextern char **environ;	/* XXX what header declares this variable? */
96146146Sharti
97104395Sjmallett#define WANT_ENV_MKLVL	1
98138071Sjmallett#define	MKLVL_MAXVAL	500
99138071Sjmallett#define	MKLVL_ENVVAR	"__MKLVL__"
100104395Sjmallett
101138916Sharti/* ordered list of makefiles to read */
102138916Shartistatic Lst makefiles = Lst_Initializer(makefiles);
103138916Sharti
104138916Sharti/* list of variables to print */
105138916Shartistatic Lst variables = Lst_Initializer(variables);
106138916Sharti
107146146Shartistatic Boolean	expandVars;	/* fully expand printed variables */
108146146Shartistatic Boolean	noBuiltins;	/* -r flag */
109144475Shartistatic Boolean	forceJobs;      /* -j argument given */
110146146Shartistatic char	*curdir;	/* startup directory */
111146146Shartistatic char	*objdir;	/* where we chdir'ed to */
112146146Sharti
113146146Sharti/* (-E) vars to override from env */
114146146ShartiLst envFirstVars = Lst_Initializer(envFirstVars);
115146146Sharti
116146146Sharti/* Targets to be made */
117146146ShartiLst create = Lst_Initializer(create);
118146146Sharti
119146146ShartiBoolean		allPrecious;	/* .PRECIOUS given on line by itself */
120146146ShartiBoolean		beSilent;	/* -s flag */
121146146ShartiBoolean		beVerbose;	/* -v flag */
122144475ShartiBoolean		compatMake;	/* -B argument */
123144475ShartiBoolean		debug;		/* -d flag */
124146146ShartiBoolean		ignoreErrors;	/* -i flag */
125146146Shartiint		jobLimit;	/* -j argument */
126146146ShartiBoolean		jobsRunning;	/* TRUE if the jobs might be running */
127146146ShartiBoolean		keepgoing;	/* -k flag */
128144475ShartiBoolean		noExecute;	/* -n flag */
129144475ShartiBoolean		queryFlag;	/* -q flag */
130144475ShartiBoolean		touchFlag;	/* -t flag */
131144475ShartiBoolean		usePipes;	/* !-P flag */
132146146Shartiuint32_t	warn_cmd;	/* command line warning flags */
133146146Shartiuint32_t	warn_flags;	/* actual warning flags */
134146146Shartiuint32_t	warn_nocmd;	/* command line no-warning flags */
135138916Sharti
136146146Shartitime_t		now;		/* Time at start of make */
137146146Shartistruct GNode	*DEFAULT;	/* .DEFAULT node */
138138916Sharti
139144475Sharti/**
140146143Sharti * Exit with usage message.
141146143Sharti */
142146143Shartistatic void
143146143Shartiusage(void)
144146143Sharti{
145146143Sharti	fprintf(stderr,
146146143Sharti	    "usage: make [-BPSXeiknqrstv] [-C directory] [-D variable]\n"
147146143Sharti	    "\t[-d flags] [-E variable] [-f makefile] [-I directory]\n"
148146143Sharti	    "\t[-j max_jobs] [-m directory] [-V variable]\n"
149146143Sharti	    "\t[variable=value] [target ...]\n");
150146143Sharti	exit(2);
151146143Sharti}
152146143Sharti
153146143Sharti/**
154144475Sharti * MFLAGS_append
155144475Sharti *	Append a flag with an optional argument to MAKEFLAGS and MFLAGS
156133085Sharti */
157133085Shartistatic void
158141252ShartiMFLAGS_append(const char *flag, char *arg)
159133085Sharti{
160140870Sharti	char *str;
161138232Sharti
162146146Sharti	Var_Append(".MAKEFLAGS", flag, VAR_GLOBAL);
163140870Sharti	if (arg != NULL) {
164140870Sharti		str = MAKEFLAGS_quote(arg);
165146146Sharti		Var_Append(".MAKEFLAGS", str, VAR_GLOBAL);
166140870Sharti		free(str);
167140870Sharti	}
168133085Sharti
169133085Sharti	Var_Append("MFLAGS", flag, VAR_GLOBAL);
170140870Sharti	if (arg != NULL) {
171140870Sharti		str = MAKEFLAGS_quote(arg);
172140870Sharti		Var_Append("MFLAGS", str, VAR_GLOBAL);
173140870Sharti		free(str);
174140870Sharti	}
175133085Sharti}
176133085Sharti
177144475Sharti/**
178145679Sharti * Main_ParseWarn
179145679Sharti *
180145679Sharti *	Handle argument to warning option.
181145679Sharti */
182145679Shartiint
183145679ShartiMain_ParseWarn(const char *arg, int iscmd)
184145679Sharti{
185145679Sharti	int i, neg;
186145679Sharti
187145679Sharti	static const struct {
188145679Sharti		const char	*option;
189145679Sharti		uint32_t	flag;
190145679Sharti	} options[] = {
191145679Sharti		{ "dirsyntax",	WARN_DIRSYNTAX },
192145679Sharti		{ NULL,		0 }
193145679Sharti	};
194145679Sharti
195145679Sharti	neg = 0;
196145679Sharti	if (arg[0] == 'n' && arg[1] == 'o') {
197145679Sharti		neg = 1;
198145679Sharti		arg += 2;
199145679Sharti	}
200145679Sharti
201145679Sharti	for (i = 0; options[i].option != NULL; i++)
202145679Sharti		if (strcmp(arg, options[i].option) == 0)
203145679Sharti			break;
204145679Sharti
205145679Sharti	if (options[i].option == NULL)
206145679Sharti		/* unknown option */
207145679Sharti		return (-1);
208145679Sharti
209145679Sharti	if (iscmd) {
210145679Sharti		if (!neg) {
211145679Sharti			warn_cmd |= options[i].flag;
212145679Sharti			warn_nocmd &= ~options[i].flag;
213145679Sharti			warn_flags |= options[i].flag;
214145679Sharti		} else {
215145679Sharti			warn_nocmd |= options[i].flag;
216145679Sharti			warn_cmd &= ~options[i].flag;
217145679Sharti			warn_flags &= ~options[i].flag;
218145679Sharti		}
219145679Sharti	} else {
220145679Sharti		if (!neg) {
221145679Sharti			warn_flags |= (options[i].flag & ~warn_nocmd);
222145679Sharti		} else {
223145679Sharti			warn_flags &= ~(options[i].flag | warn_cmd);
224145679Sharti		}
225145679Sharti	}
226145679Sharti	return (0);
227145679Sharti}
228145679Sharti
229145679Sharti/**
230146143Sharti * Open and parse the given makefile.
231146143Sharti *
232146143Sharti * Results:
233146143Sharti *	TRUE if ok. FALSE if couldn't open file.
234146143Sharti */
235146143Shartistatic Boolean
236146143ShartiReadMakefile(const char p[])
237146143Sharti{
238146143Sharti	char *fname;			/* makefile to read */
239146143Sharti	FILE *stream;
240146143Sharti	char *name, path[MAXPATHLEN];
241146143Sharti	char *MAKEFILE;
242146143Sharti	int setMAKEFILE;
243146143Sharti
244146143Sharti	/* XXX - remove this once constification is done */
245146143Sharti	fname = estrdup(p);
246146143Sharti
247146143Sharti	if (!strcmp(fname, "-")) {
248146143Sharti		Parse_File("(stdin)", stdin);
249146145Sharti		Var_SetGlobal("MAKEFILE", "");
250146143Sharti	} else {
251146143Sharti		setMAKEFILE = strcmp(fname, ".depend");
252146143Sharti
253146143Sharti		/* if we've chdir'd, rebuild the path name */
254146143Sharti		if (curdir != objdir && *fname != '/') {
255146143Sharti			snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname);
256146143Sharti			/*
257146143Sharti			 * XXX The realpath stuff breaks relative includes
258146143Sharti			 * XXX in some cases.   The problem likely is in
259146143Sharti			 * XXX parse.c where it does special things in
260146143Sharti			 * XXX ParseDoInclude if the file is relateive
261146143Sharti			 * XXX or absolute and not a system file.  There
262146143Sharti			 * XXX it assumes that if the current file that's
263146143Sharti			 * XXX being included is absolute, that any files
264146143Sharti			 * XXX that it includes shouldn't do the -I path
265146143Sharti			 * XXX stuff, which is inconsistant with historical
266146143Sharti			 * XXX behavior.  However, I can't pentrate the mists
267146143Sharti			 * XXX further, so I'm putting this workaround in
268146143Sharti			 * XXX here until such time as the underlying bug
269146143Sharti			 * XXX can be fixed.
270146143Sharti			 */
271146143Sharti#if THIS_BREAKS_THINGS
272146143Sharti			if (realpath(path, path) != NULL &&
273146143Sharti			    (stream = fopen(path, "r")) != NULL) {
274146143Sharti				MAKEFILE = fname;
275146143Sharti				fname = path;
276146143Sharti				goto found;
277146143Sharti			}
278146143Sharti		} else if (realpath(fname, path) != NULL) {
279146143Sharti			MAKEFILE = fname;
280146143Sharti			fname = path;
281146143Sharti			if ((stream = fopen(fname, "r")) != NULL)
282146143Sharti				goto found;
283146143Sharti		}
284146143Sharti#else
285146143Sharti			if ((stream = fopen(path, "r")) != NULL) {
286146143Sharti				MAKEFILE = fname;
287146143Sharti				fname = path;
288146143Sharti				goto found;
289146143Sharti			}
290146143Sharti		} else {
291146143Sharti			MAKEFILE = fname;
292146143Sharti			if ((stream = fopen(fname, "r")) != NULL)
293146143Sharti				goto found;
294146143Sharti		}
295146143Sharti#endif
296146143Sharti		/* look in -I and system include directories. */
297146143Sharti		name = Path_FindFile(fname, &parseIncPath);
298146143Sharti		if (!name)
299146143Sharti			name = Path_FindFile(fname, &sysIncPath);
300146143Sharti		if (!name || !(stream = fopen(name, "r")))
301146143Sharti			return (FALSE);
302146143Sharti		MAKEFILE = fname = name;
303146143Sharti		/*
304146143Sharti		 * set the MAKEFILE variable desired by System V fans -- the
305146143Sharti		 * placement of the setting here means it gets set to the last
306146143Sharti		 * makefile specified, as it is set by SysV make.
307146143Sharti		 */
308146143Shartifound:
309146143Sharti		if (setMAKEFILE)
310146145Sharti			Var_SetGlobal("MAKEFILE", MAKEFILE);
311146143Sharti		Parse_File(fname, stream);
312146143Sharti		fclose(stream);
313146143Sharti	}
314146143Sharti	return (TRUE);
315146143Sharti}
316146143Sharti
317146143Sharti/**
318144475Sharti * MainParseArgs
3191590Srgrimes *	Parse a given argument vector. Called from main() and from
3201590Srgrimes *	Main_ParseArgLine() when the .MAKEFLAGS target is used.
3211590Srgrimes *
3221590Srgrimes *	XXX: Deal with command line overriding .MAKEFLAGS in makefile
3231590Srgrimes *
3241590Srgrimes * Side Effects:
3251590Srgrimes *	Various global and local flags will be set depending on the flags
3261590Srgrimes *	given
3271590Srgrimes */
3281590Srgrimesstatic void
329104696SjmallettMainParseArgs(int argc, char **argv)
3301590Srgrimes{
3315814Sjkh	int c;
332146038Sharti	Boolean	found_dd = FALSE;
3331590Srgrimes
334144896Shartirearg:
3351590Srgrimes	optind = 1;	/* since we're called more than once */
336144896Sharti	optreset = 1;
337145627Sharti#define OPTFLAGS "ABC:D:E:I:PSV:Xd:ef:ij:km:nqrstvx:"
338146038Sharti	for (;;) {
339146038Sharti		if ((optind < argc) && strcmp(argv[optind], "--") == 0) {
340146038Sharti			found_dd = TRUE;
341146038Sharti		}
342146038Sharti		if ((c = getopt(argc, argv, OPTFLAGS)) == -1) {
343146038Sharti			break;
344146038Sharti		}
3451590Srgrimes		switch(c) {
346144387Sharti
347144387Sharti		case 'A':
348144387Sharti			arch_fatal = FALSE;
349144387Sharti			MFLAGS_append("-A", NULL);
350144387Sharti			break;
351102393Sjmallett		case 'C':
352107964Sseanc			if (chdir(optarg) == -1)
353107964Sseanc				err(1, "chdir %s", optarg);
354102393Sjmallett			break;
3551590Srgrimes		case 'D':
356146145Sharti			Var_SetGlobal(optarg, "1");
357133085Sharti			MFLAGS_append("-D", optarg);
3581590Srgrimes			break;
3591590Srgrimes		case 'I':
3601590Srgrimes			Parse_AddIncludeDir(optarg);
361133085Sharti			MFLAGS_append("-I", optarg);
3621590Srgrimes			break;
36317193Sbde		case 'V':
364138920Sru			Lst_AtEnd(&variables, estrdup(optarg));
365133085Sharti			MFLAGS_append("-V", optarg);
36617193Sbde			break;
36766365Speter		case 'X':
36866365Speter			expandVars = FALSE;
36966365Speter			break;
3701590Srgrimes		case 'B':
3711590Srgrimes			compatMake = TRUE;
372133085Sharti			MFLAGS_append("-B", NULL);
373137626Sphk			unsetenv("MAKE_JOBS_FIFO");
3741590Srgrimes			break;
3751590Srgrimes		case 'P':
3761590Srgrimes			usePipes = FALSE;
377133085Sharti			MFLAGS_append("-P", NULL);
3781590Srgrimes			break;
3791590Srgrimes		case 'S':
3801590Srgrimes			keepgoing = FALSE;
381133085Sharti			MFLAGS_append("-S", NULL);
3821590Srgrimes			break;
3831590Srgrimes		case 'd': {
3841590Srgrimes			char *modules = optarg;
3851590Srgrimes
3861590Srgrimes			for (; *modules; ++modules)
3871590Srgrimes				switch (*modules) {
3881590Srgrimes				case 'A':
3891590Srgrimes					debug = ~0;
3901590Srgrimes					break;
3911590Srgrimes				case 'a':
3921590Srgrimes					debug |= DEBUG_ARCH;
3931590Srgrimes					break;
3941590Srgrimes				case 'c':
3951590Srgrimes					debug |= DEBUG_COND;
3961590Srgrimes					break;
3971590Srgrimes				case 'd':
3981590Srgrimes					debug |= DEBUG_DIR;
3991590Srgrimes					break;
4001590Srgrimes				case 'f':
4011590Srgrimes					debug |= DEBUG_FOR;
4021590Srgrimes					break;
4031590Srgrimes				case 'g':
4041590Srgrimes					if (modules[1] == '1') {
4051590Srgrimes						debug |= DEBUG_GRAPH1;
4061590Srgrimes						++modules;
4071590Srgrimes					}
4081590Srgrimes					else if (modules[1] == '2') {
4091590Srgrimes						debug |= DEBUG_GRAPH2;
4101590Srgrimes						++modules;
4111590Srgrimes					}
4121590Srgrimes					break;
4131590Srgrimes				case 'j':
4141590Srgrimes					debug |= DEBUG_JOB;
4151590Srgrimes					break;
41660569Swill				case 'l':
41760569Swill					debug |= DEBUG_LOUD;
41860569Swill					break;
4191590Srgrimes				case 'm':
4201590Srgrimes					debug |= DEBUG_MAKE;
4211590Srgrimes					break;
4221590Srgrimes				case 's':
4231590Srgrimes					debug |= DEBUG_SUFF;
4241590Srgrimes					break;
4251590Srgrimes				case 't':
4261590Srgrimes					debug |= DEBUG_TARG;
4271590Srgrimes					break;
4281590Srgrimes				case 'v':
4291590Srgrimes					debug |= DEBUG_VAR;
4301590Srgrimes					break;
4311590Srgrimes				default:
432144475Sharti					warnx("illegal argument to d option "
433144475Sharti					    "-- %c", *modules);
4341590Srgrimes					usage();
4351590Srgrimes				}
436133085Sharti			MFLAGS_append("-d", optarg);
4371590Srgrimes			break;
4381590Srgrimes		}
43949332Shoek		case 'E':
440138920Sru			Lst_AtEnd(&envFirstVars, estrdup(optarg));
441133085Sharti			MFLAGS_append("-E", optarg);
44249332Shoek			break;
4431590Srgrimes		case 'e':
4441590Srgrimes			checkEnvFirst = TRUE;
445133085Sharti			MFLAGS_append("-e", NULL);
4461590Srgrimes			break;
4471590Srgrimes		case 'f':
448138920Sru			Lst_AtEnd(&makefiles, estrdup(optarg));
4491590Srgrimes			break;
4501590Srgrimes		case 'i':
4511590Srgrimes			ignoreErrors = TRUE;
452133085Sharti			MFLAGS_append("-i", NULL);
4531590Srgrimes			break;
45449331Shoek		case 'j': {
45549331Shoek			char *endptr;
45649331Shoek
45718730Ssteve			forceJobs = TRUE;
458146140Sharti			jobLimit = strtol(optarg, &endptr, 10);
459146140Sharti			if (jobLimit <= 0 || *endptr != '\0') {
46049938Shoek				warnx("illegal number, -j argument -- %s",
46149938Shoek				    optarg);
46249938Shoek				usage();
46349331Shoek			}
464133085Sharti			MFLAGS_append("-j", optarg);
4651590Srgrimes			break;
46649331Shoek		}
4671590Srgrimes		case 'k':
4681590Srgrimes			keepgoing = TRUE;
469133085Sharti			MFLAGS_append("-k", NULL);
4701590Srgrimes			break;
47118730Ssteve		case 'm':
472144020Sharti			Path_AddDir(&sysIncPath, optarg);
473133085Sharti			MFLAGS_append("-m", optarg);
47418730Ssteve			break;
4751590Srgrimes		case 'n':
4761590Srgrimes			noExecute = TRUE;
477133085Sharti			MFLAGS_append("-n", NULL);
4781590Srgrimes			break;
4791590Srgrimes		case 'q':
4801590Srgrimes			queryFlag = TRUE;
4811590Srgrimes			/* Kind of nonsensical, wot? */
482133085Sharti			MFLAGS_append("-q", NULL);
4831590Srgrimes			break;
4841590Srgrimes		case 'r':
4851590Srgrimes			noBuiltins = TRUE;
486133085Sharti			MFLAGS_append("-r", NULL);
4871590Srgrimes			break;
4881590Srgrimes		case 's':
4891590Srgrimes			beSilent = TRUE;
490133085Sharti			MFLAGS_append("-s", NULL);
4911590Srgrimes			break;
4921590Srgrimes		case 't':
4931590Srgrimes			touchFlag = TRUE;
494133085Sharti			MFLAGS_append("-t", NULL);
4951590Srgrimes			break;
49641151Sdg		case 'v':
49741151Sdg			beVerbose = TRUE;
498133085Sharti			MFLAGS_append("-v", NULL);
49941151Sdg			break;
500145627Sharti		case 'x':
501145679Sharti			if (Main_ParseWarn(optarg, 1) != -1)
502145627Sharti				MFLAGS_append("-x", optarg);
503145627Sharti			break;
504145627Sharti
5051590Srgrimes		default:
5061590Srgrimes		case '?':
5071590Srgrimes			usage();
5081590Srgrimes		}
5091590Srgrimes	}
510144896Sharti	argv += optind;
511144896Sharti	argc -= optind;
5121590Srgrimes
5131590Srgrimes	oldVars = TRUE;
5141590Srgrimes
5151590Srgrimes	/*
516144896Sharti	 * Parse the rest of the arguments.
517144896Sharti	 *	o Check for variable assignments and perform them if so.
518144896Sharti	 *	o Check for more flags and restart getopt if so.
519144896Sharti	 *      o Anything else is taken to be a target and added
520144896Sharti	 *	  to the end of the "create" list.
5211590Srgrimes	 */
522144896Sharti	for (; *argv != NULL; ++argv, --argc) {
523133562Sharti		if (Parse_IsVar(*argv)) {
524140870Sharti			char *ptr = MAKEFLAGS_quote(*argv);
525133562Sharti
526146146Sharti			Var_Append(".MAKEFLAGS", ptr, VAR_GLOBAL);
527144896Sharti			Parse_DoVar(*argv, VAR_CMD);
528133562Sharti			free(ptr);
529133562Sharti
530144896Sharti		} else if ((*argv)[0] == '-') {
531144896Sharti			if ((*argv)[1] == '\0') {
532144896Sharti				/*
533144896Sharti				 * (*argv) is a single dash, so we
534144896Sharti				 * just ignore it.
535144896Sharti				 */
536146038Sharti			} else if (found_dd) {
537146038Sharti				/*
538146038Sharti				 * Double dash has been found, ignore
539146038Sharti				 * any more options.  But what do we do
540146038Sharti				 * with it?  For now treat it like a target.
541146038Sharti				 */
542146038Sharti				Lst_AtEnd(&create, estrdup(*argv));
543144896Sharti			} else {
544144896Sharti				/*
545146038Sharti				 * (*argv) is a -flag, so backup argv and
546146038Sharti				 * argc.  getopt() expects options to start
547146038Sharti				 * in the 2nd position.
548144896Sharti				 */
549144896Sharti				argc++;
550144896Sharti				argv--;
5511590Srgrimes				goto rearg;
5521590Srgrimes			}
553144896Sharti
554144896Sharti		} else if ((*argv)[0] == '\0') {
555144896Sharti			Punt("illegal (null) argument.");
556144896Sharti
557144896Sharti		} else {
558138916Sharti			Lst_AtEnd(&create, estrdup(*argv));
5591590Srgrimes		}
560144896Sharti	}
5611590Srgrimes}
5621590Srgrimes
563144475Sharti/**
564144475Sharti * Main_ParseArgLine
5651590Srgrimes *  	Used by the parse module when a .MFLAGS or .MAKEFLAGS target
5661590Srgrimes *	is encountered and by main() when reading the .MAKEFLAGS envariable.
5671590Srgrimes *	Takes a line of arguments and breaks it into its
5681590Srgrimes * 	component words and passes those words and the number of them to the
5691590Srgrimes *	MainParseArgs function.
5701590Srgrimes *	The line should have all its leading whitespace removed.
5711590Srgrimes *
5721590Srgrimes * Side Effects:
5731590Srgrimes *	Only those that come from the various arguments.
5741590Srgrimes */
5751590Srgrimesvoid
576140870ShartiMain_ParseArgLine(char *line, int mflags)
5771590Srgrimes{
5781590Srgrimes	char **argv;			/* Manufactured argument vector */
5791590Srgrimes	int argc;			/* Number of arguments in argv */
5801590Srgrimes
5811590Srgrimes	if (line == NULL)
5821590Srgrimes		return;
5831590Srgrimes	for (; *line == ' '; ++line)
5841590Srgrimes		continue;
5851590Srgrimes	if (!*line)
5861590Srgrimes		return;
5871590Srgrimes
588140870Sharti	if (mflags)
589140870Sharti		argv = MAKEFLAGS_break(line, &argc);
590140870Sharti	else
591140870Sharti		argv = brk_string(line, &argc, TRUE);
592140870Sharti
5931590Srgrimes	MainParseArgs(argc, argv);
5941590Srgrimes}
5951590Srgrimes
596146146Shartistatic char *
597141252Shartichdir_verify_path(const char *path, char *obpath)
59818339Sswallace{
59918339Sswallace	struct stat sb;
60018339Sswallace
60118339Sswallace	if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
60275973Sru		if (chdir(path) == -1 || getcwd(obpath, MAXPATHLEN) == NULL) {
60327644Scharnier			warn("warning: %s", path);
604141252Sharti			return (NULL);
60518339Sswallace		}
606138232Sharti		return (obpath);
60718339Sswallace	}
60818339Sswallace
609141252Sharti	return (NULL);
61018339Sswallace}
61118339Sswallace
612146144Sharti/**
613146144Sharti * In lieu of a good way to prevent every possible looping in make(1), stop
614146144Sharti * there from being more than MKLVL_MAXVAL processes forked by make(1), to
615146144Sharti * prevent a forkbomb from happening, in a dumb and mechanical way.
616146144Sharti *
617146144Sharti * Side Effects:
618146144Sharti *	Creates or modifies enviornment variable MKLVL_ENVVAR via setenv().
619138071Sjmallett */
620138071Sjmallettstatic void
621138071Sjmallettcheck_make_level(void)
622138071Sjmallett{
623138071Sjmallett#ifdef WANT_ENV_MKLVL
624138071Sjmallett	char	*value = getenv(MKLVL_ENVVAR);
625138071Sjmallett	int	level = (value == NULL) ? 0 : atoi(value);
626138071Sjmallett
627138071Sjmallett	if (level < 0) {
628144475Sharti		errc(2, EAGAIN, "Invalid value for recursion level (%d).",
629144475Sharti		    level);
630138071Sjmallett	} else if (level > MKLVL_MAXVAL) {
631144475Sharti		errc(2, EAGAIN, "Max recursion level (%d) exceeded.",
632144475Sharti		    MKLVL_MAXVAL);
633138071Sjmallett	} else {
634138071Sjmallett		char new_value[32];
635138071Sjmallett		sprintf(new_value, "%d", level + 1);
636138071Sjmallett		setenv(MKLVL_ENVVAR, new_value, 1);
637138071Sjmallett	}
638138071Sjmallett#endif /* WANT_ENV_MKLVL */
639138071Sjmallett}
640138071Sjmallett
641144475Sharti/**
642144475Sharti * main
6431590Srgrimes *	The main function, for obvious reasons. Initializes variables
6441590Srgrimes *	and a few modules, then parses the arguments give it in the
6451590Srgrimes *	environment and on the command line. Reads the system makefile
6461590Srgrimes *	followed by either Makefile, makefile or the file given by the
6471590Srgrimes *	-f argument. Sets the .MAKEFLAGS PMake variable based on all the
6481590Srgrimes *	flags it has received by then uses either the Make or the Compat
6491590Srgrimes *	module to create the initial list of targets.
6501590Srgrimes *
6511590Srgrimes * Results:
6521590Srgrimes *	If -q was given, exits -1 if anything was out-of-date. Else it exits
6531590Srgrimes *	0.
6541590Srgrimes *
6551590Srgrimes * Side Effects:
6561590Srgrimes *	The program exits when done. Targets are created. etc. etc. etc.
6571590Srgrimes */
6581590Srgrimesint
659104696Sjmallettmain(int argc, char **argv)
6601590Srgrimes{
661146144Sharti    	const char *machine;
662146144Sharti	const char *machine_arch;
663146144Sharti	const char *machine_cpu;
6641590Srgrimes	Boolean outOfDate = TRUE; 	/* FALSE if all targets up to date */
665141252Sharti	char *p, *p1, *pathp;
666141252Sharti	char *path;
66773262Simp	char mdpath[MAXPATHLEN];
66873262Simp	char obpath[MAXPATHLEN];
66973262Simp	char cdpath[MAXPATHLEN];
67018730Ssteve	char *cp = NULL, *start;
671141252Sharti
672146146Sharti	/*
673146146Sharti	 * Initialize file global variables.
674146146Sharti	 */
675146146Sharti	expandVars = TRUE;
676146146Sharti	noBuiltins = FALSE;		/* Read the built-in rules */
677146146Sharti	forceJobs = FALSE;              /* No -j flag */
678146146Sharti	curdir = cdpath;
679146146Sharti
680146146Sharti	/*
681146146Sharti	 * Initialize program global variables.
682146146Sharti	 */
683146146Sharti	beSilent = FALSE;		/* Print commands as executed */
684146146Sharti	ignoreErrors = FALSE;		/* Pay attention to non-zero returns */
685146146Sharti	noExecute = FALSE;		/* Execute all commands */
686146146Sharti	keepgoing = FALSE;		/* Stop on error */
687146146Sharti	allPrecious = FALSE;		/* Remove targets when interrupted */
688146146Sharti	queryFlag = FALSE;		/* This is not just a check-run */
689146146Sharti	touchFlag = FALSE;		/* Actually update targets */
690146146Sharti	usePipes = TRUE;		/* Catch child output in pipes */
691146146Sharti	debug = 0;			/* No debug verbosity, please. */
692146146Sharti	jobsRunning = FALSE;
693146146Sharti
694146146Sharti	jobLimit = DEFMAXJOBS;
695146146Sharti	compatMake = FALSE;		/* No compat mode */
696146146Sharti
697138071Sjmallett	check_make_level();
698104395Sjmallett
69918730Ssteve#ifdef RLIMIT_NOFILE
7001590Srgrimes	/*
70118730Ssteve	 * get rid of resource limit on file descriptors
70218730Ssteve	 */
70318730Ssteve	{
70418730Ssteve		struct rlimit rl;
705146144Sharti		if (getrlimit(RLIMIT_NOFILE, &rl) == -1) {
706146144Sharti			err(2, "getrlimit");
70718730Ssteve		}
708146144Sharti		rl.rlim_cur = rl.rlim_max;
709146144Sharti		if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
710146144Sharti			err(2, "setrlimit");
711146144Sharti		}
71218730Ssteve	}
71318730Ssteve#endif
7141590Srgrimes
7155814Sjkh	/*
71639006Skato	 * PC-98 kernel sets the `i386' string to the utsname.machine and
71739006Skato	 * it cannot be distinguished from IBM-PC by uname(3).  Therefore,
71839006Skato	 * we check machine.ispc98 and adjust the machine variable before
71939006Skato	 * using usname(3) below.
72053631Smarcel	 * NOTE: machdep.ispc98 was defined on 1998/8/31. At that time,
72153631Smarcel	 * __FreeBSD_version was defined as 300003. So, this check can
72253631Smarcel	 * safely be done with any kernel with version > 300003.
72339006Skato	 */
72439006Skato	if (!machine) {
72539006Skato		int	ispc98;
72639006Skato		size_t	len;
72739006Skato
72839006Skato		len = sizeof(ispc98);
72939006Skato		if (!sysctlbyname("machdep.ispc98", &ispc98, &len, NULL, 0)) {
73039006Skato			if (ispc98)
73139006Skato				machine = "pc98";
73239006Skato		}
73339006Skato	}
73439006Skato
73539006Skato	/*
7365814Sjkh	 * Get the name of this type of MACHINE from utsname
7375814Sjkh	 * so we can share an executable for similar machines.
7385814Sjkh	 * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
7395814Sjkh	 *
7405814Sjkh	 * Note that while MACHINE is decided at run-time,
7415814Sjkh	 * MACHINE_ARCH is always known at compile time.
7425814Sjkh	 */
743146144Sharti	if ((machine = getenv("MACHINE")) == NULL) {
744146144Sharti#ifdef MACHINE
745146144Sharti		machine = MACHINE;
746146144Sharti#else
747144475Sharti		static struct utsname utsname;
74818730Ssteve
749144475Sharti		if (uname(&utsname) == -1)
750144475Sharti			err(2, "uname");
751144475Sharti		machine = utsname.machine;
75218339Sswallace#endif
7535814Sjkh	}
7541590Srgrimes
755146144Sharti	if ((machine_arch = getenv("MACHINE_ARCH")) == NULL) {
756146144Sharti#ifdef MACHINE_ARCH
757146144Sharti		machine_arch = MACHINE_ARCH;
758146144Sharti#else
75944362Simp		machine_arch = "unknown";
76044362Simp#endif
76144362Simp	}
76244362Simp
7631590Srgrimes	/*
76472679Skris	 * Set machine_cpu to the minumum supported CPU revision based
76572679Skris	 * on the target architecture, if not already set.
76672679Skris	 */
767146144Sharti	if ((machine_cpu = getenv("MACHINE_CPU")) == NULL) {
76872679Skris		if (!strcmp(machine_arch, "i386"))
76972679Skris			machine_cpu = "i386";
77072679Skris		else if (!strcmp(machine_arch, "alpha"))
77172679Skris			machine_cpu = "ev4";
77272679Skris		else
77372679Skris			machine_cpu = "unknown";
77472679Skris	}
7751590Srgrimes
7761590Srgrimes	/*
7771590Srgrimes	 * Initialize the parsing, directory and variable modules to prepare
7781590Srgrimes	 * for the reading of inclusion paths and variable settings on the
7791590Srgrimes	 * command line
7801590Srgrimes	 */
781146144Sharti	Proc_Init();
782146144Sharti
7831590Srgrimes	Dir_Init();		/* Initialize directory structures so -I flags
7841590Srgrimes				 * can be processed correctly */
785145971Sharti	Var_Init(environ);	/* As well as the lists of variables for
7861590Srgrimes				 * parsing arguments */
7875814Sjkh        str_init();
7881590Srgrimes
7891590Srgrimes	/*
7901590Srgrimes	 * Initialize various variables.
7911590Srgrimes	 *	MAKE also gets this name, for compatibility
7921590Srgrimes	 *	.MAKEFLAGS gets set to the empty string just in case.
7931590Srgrimes	 *	MFLAGS also gets initialized empty, for compatibility.
7941590Srgrimes	 */
795146145Sharti	Var_SetGlobal("MAKE", argv[0]);
796146146Sharti	Var_SetGlobal(".MAKEFLAGS", "");
797146145Sharti	Var_SetGlobal("MFLAGS", "");
798146145Sharti	Var_SetGlobal("MACHINE", machine);
799146145Sharti	Var_SetGlobal("MACHINE_ARCH", machine_arch);
800146145Sharti	Var_SetGlobal("MACHINE_CPU", machine_cpu);
80197121Sru#ifdef MAKE_VERSION
802146145Sharti	Var_SetGlobal("MAKE_VERSION", MAKE_VERSION);
80397121Sru#endif
8041590Srgrimes
8051590Srgrimes	/*
806144896Sharti	 * First snag things out of the MAKEFLAGS environment
807144896Sharti	 * variable.  Then parse the command line arguments.
8081590Srgrimes	 */
809140870Sharti	Main_ParseArgLine(getenv("MAKEFLAGS"), 1);
8108874Srgrimes
8111590Srgrimes	MainParseArgs(argc, argv);
8121590Srgrimes
8131590Srgrimes	/*
814120053Sru	 * Find where we are...
815120053Sru	 */
816120053Sru	if (getcwd(curdir, MAXPATHLEN) == NULL)
817120053Sru		err(2, NULL);
818120053Sru
819141252Sharti	{
820141252Sharti	struct stat sa;
821141252Sharti
822120053Sru	if (stat(curdir, &sa) == -1)
823120053Sru	    err(2, "%s", curdir);
824141252Sharti	}
825120053Sru
826120053Sru	/*
827120053Sru	 * The object directory location is determined using the
828120053Sru	 * following order of preference:
829120053Sru	 *
830120053Sru	 *	1. MAKEOBJDIRPREFIX`cwd`
831120053Sru	 *	2. MAKEOBJDIR
832143412Sharti	 *	3. PATH_OBJDIR.${MACHINE}
833143412Sharti	 *	4. PATH_OBJDIR
834143412Sharti	 *	5. PATH_OBJDIRPREFIX`cwd`
835120053Sru	 *
836120053Sru	 * If one of the first two fails, use the current directory.
837120053Sru	 * If the remaining three all fail, use the current directory.
838120053Sru	 *
839120053Sru	 * Once things are initted,
840120053Sru	 * have to add the original directory to the search path,
841120053Sru	 * and modify the paths for the Makefiles apropriately.  The
842120053Sru	 * current directory is also placed as a variable for make scripts.
843120053Sru	 */
844120053Sru	if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
845120053Sru		if (!(path = getenv("MAKEOBJDIR"))) {
846143412Sharti			path = PATH_OBJDIR;
847143412Sharti			pathp = PATH_OBJDIRPREFIX;
848146145Sharti			snprintf(mdpath, MAXPATHLEN, "%s.%s", path, machine);
849120053Sru			if (!(objdir = chdir_verify_path(mdpath, obpath)))
850120053Sru				if (!(objdir=chdir_verify_path(path, obpath))) {
851138232Sharti					snprintf(mdpath, MAXPATHLEN,
852120053Sru							"%s%s", pathp, curdir);
853120053Sru					if (!(objdir=chdir_verify_path(mdpath,
854120053Sru								       obpath)))
855120053Sru						objdir = curdir;
856120053Sru				}
857120053Sru		}
858120053Sru		else if (!(objdir = chdir_verify_path(path, obpath)))
859120053Sru			objdir = curdir;
860120053Sru	}
861120053Sru	else {
862138232Sharti		snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
863120053Sru		if (!(objdir = chdir_verify_path(mdpath, obpath)))
864120053Sru			objdir = curdir;
865120053Sru	}
866120053Sru	Dir_InitDot();		/* Initialize the "." directory */
867120053Sru	if (objdir != curdir)
868144020Sharti		Path_AddDir(&dirSearchPath, curdir);
869146145Sharti	Var_SetGlobal(".ST_EXPORTVAR", "YES");
870146145Sharti	Var_SetGlobal(".CURDIR", curdir);
871146145Sharti	Var_SetGlobal(".OBJDIR", objdir);
872120053Sru
873137606Sphk	if (getenv("MAKE_JOBS_FIFO") != NULL)
874137606Sphk		forceJobs = TRUE;
875120053Sru	/*
87628228Sfsmp	 * Be compatible if user did not specify -j and did not explicitly
87728228Sfsmp	 * turned compatibility on
87828228Sfsmp	 */
87928228Sfsmp	if (!compatMake && !forceJobs)
88028228Sfsmp		compatMake = TRUE;
88128228Sfsmp
88228228Sfsmp	/*
883144387Sharti	 * Initialize target and suffix modules in preparation for
8841590Srgrimes	 * parsing the makefile(s)
8851590Srgrimes	 */
8861590Srgrimes	Targ_Init();
8871590Srgrimes	Suff_Init();
8881590Srgrimes
88969527Swill	DEFAULT = NULL;
890138232Sharti	time(&now);
8911590Srgrimes
8921590Srgrimes	/*
8931590Srgrimes	 * Set up the .TARGETS variable to contain the list of targets to be
8941590Srgrimes	 * created. If none specified, make the variable empty -- the parser
8951590Srgrimes	 * will fill the thing in with the default or .MAIN target.
8961590Srgrimes	 */
897146145Sharti	if (Lst_IsEmpty(&create)) {
898146145Sharti		Var_SetGlobal(".TARGETS", "");
899146145Sharti	} else {
900138512Sharti		LstNode *ln;
9011590Srgrimes
902138916Sharti		for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) {
903138264Sharti			char *name = Lst_Datum(ln);
9041590Srgrimes
9051590Srgrimes			Var_Append(".TARGETS", name, VAR_GLOBAL);
9061590Srgrimes		}
907146145Sharti	}
9081590Srgrimes
90918730Ssteve
9101590Srgrimes	/*
91118730Ssteve	 * If no user-supplied system path was given (through the -m option)
91218730Ssteve	 * add the directories from the DEFSYSPATH (more than one may be given
91318730Ssteve	 * as dir1:...:dirn) to the system include path.
9141590Srgrimes	 */
915144020Sharti	if (TAILQ_EMPTY(&sysIncPath)) {
916146144Sharti		char syspath[] = PATH_DEFSYSPATH;
917146144Sharti
91818730Ssteve		for (start = syspath; *start != '\0'; start = cp) {
91918730Ssteve			for (cp = start; *cp != '\0' && *cp != ':'; cp++)
92018730Ssteve				continue;
92118730Ssteve			if (*cp == '\0') {
922144020Sharti				Path_AddDir(&sysIncPath, start);
92318730Ssteve			} else {
92418730Ssteve				*cp++ = '\0';
925144020Sharti				Path_AddDir(&sysIncPath, start);
92618730Ssteve			}
92718730Ssteve		}
92818730Ssteve	}
9291590Srgrimes
93018730Ssteve	/*
93118730Ssteve	 * Read in the built-in rules first, followed by the specified
93218730Ssteve	 * makefile, if it was (makefile != (char *) NULL), or the default
93318730Ssteve	 * Makefile and makefile, in that order, if it wasn't.
93418730Ssteve	 */
93518730Ssteve	if (!noBuiltins) {
936138916Sharti		/* Path of sys.mk */
937138916Sharti		Lst sysMkPath = Lst_Initializer(sysMkPath);
938138512Sharti		LstNode *ln;
939146064Sharti		char	defsysmk[] = PATH_DEFSYSMK;
94018730Ssteve
941146064Sharti		Path_Expand(defsysmk, &sysIncPath, &sysMkPath);
942138916Sharti		if (Lst_IsEmpty(&sysMkPath))
943143412Sharti			Fatal("make: no system rules (%s).", PATH_DEFSYSMK);
944143808Sharti		LST_FOREACH(ln, &sysMkPath) {
945143808Sharti			if (!ReadMakefile(Lst_Datum(ln)))
946143808Sharti				break;
947143808Sharti		}
94869527Swill		if (ln != NULL)
94918730Ssteve			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
950138916Sharti		Lst_Destroy(&sysMkPath, free);
95118730Ssteve	}
95218730Ssteve
953138916Sharti	if (!Lst_IsEmpty(&makefiles)) {
954138512Sharti		LstNode *ln;
9551590Srgrimes
956143808Sharti		LST_FOREACH(ln, &makefiles) {
957143808Sharti			if (!ReadMakefile(Lst_Datum(ln)))
958143808Sharti				break;
959143808Sharti		}
96069527Swill		if (ln != NULL)
9611590Srgrimes			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
962143808Sharti	} else if (!ReadMakefile("BSDmakefile"))
963143808Sharti	    if (!ReadMakefile("makefile"))
964143808Sharti		ReadMakefile("Makefile");
9651590Srgrimes
966143808Sharti	ReadMakefile(".depend");
9671590Srgrimes
9681590Srgrimes	/* Install all the flags into the MAKE envariable. */
969146146Sharti	if (((p = Var_Value(".MAKEFLAGS", VAR_GLOBAL, &p1)) != NULL) && *p)
9701590Srgrimes		setenv("MAKEFLAGS", p, 1);
971105826Sjmallett	free(p1);
9721590Srgrimes
9731590Srgrimes	/*
9741590Srgrimes	 * For compatibility, look at the directories in the VPATH variable
9751590Srgrimes	 * and add them to the search path, if the variable is defined. The
9761590Srgrimes	 * variable's value is in the same format as the PATH envariable, i.e.
9771590Srgrimes	 * <directory>:<directory>:<directory>...
9781590Srgrimes	 */
9791590Srgrimes	if (Var_Exists("VPATH", VAR_CMD)) {
9801590Srgrimes		/*
9811590Srgrimes		 * GCC stores string constants in read-only memory, but
9821590Srgrimes		 * Var_Subst will want to write this thing, so store it
9831590Srgrimes		 * in an array
9841590Srgrimes		 */
9851590Srgrimes		static char VPATH[] = "${VPATH}";
986142457Sharti		Buffer	*buf;
987142457Sharti		char	*vpath;
988142457Sharti		char	*ptr;
989142457Sharti		char	savec;
9901590Srgrimes
991146027Sharti		buf = Var_Subst(VPATH, VAR_CMD, FALSE);
992142457Sharti
993143959Sharti		vpath = Buf_Data(buf);
9941590Srgrimes		do {
9951590Srgrimes			/* skip to end of directory */
996142457Sharti			for (ptr = vpath; *ptr != ':' && *ptr != '\0'; ptr++)
997141969Sharti				;
998141969Sharti
9991590Srgrimes			/* Save terminator character so know when to stop */
1000141969Sharti			savec = *ptr;
1001141969Sharti			*ptr = '\0';
1002141969Sharti
10031590Srgrimes			/* Add directory to search path */
1004144020Sharti			Path_AddDir(&dirSearchPath, vpath);
1005141969Sharti
1006142457Sharti			vpath = ptr + 1;
1007141969Sharti		} while (savec != '\0');
1008142457Sharti
1009142457Sharti		Buf_Destroy(buf, TRUE);
10101590Srgrimes	}
10111590Srgrimes
10121590Srgrimes	/*
10131590Srgrimes	 * Now that all search paths have been read for suffixes et al, it's
10141590Srgrimes	 * time to add the default search path to their lists...
10151590Srgrimes	 */
10161590Srgrimes	Suff_DoPaths();
10171590Srgrimes
10181590Srgrimes	/* print the initial graph, if the user requested it */
10191590Srgrimes	if (DEBUG(GRAPH1))
10201590Srgrimes		Targ_PrintGraph(1);
10211590Srgrimes
102217193Sbde	/* print the values of any variables requested by the user */
1023141974Sharti	if (Lst_IsEmpty(&variables)) {
10241590Srgrimes		/*
1025141974Sharti		 * Since the user has not requested that any variables
1026142008Sharti		 * be printed, we can build targets.
1027141974Sharti		 *
1028142008Sharti		 * Have read the entire graph and need to make a list of targets
1029141974Sharti		 * to create. If none was given on the command line, we consult
1030141974Sharti		 * the parsing module to find the main target(s) to create.
10311590Srgrimes		 */
1032138916Sharti		Lst targs = Lst_Initializer(targs);
1033138916Sharti
1034138916Sharti		if (Lst_IsEmpty(&create))
1035138916Sharti			Parse_MainName(&targs);
1036101460Sru		else
1037138916Sharti			Targ_FindList(&targs, &create, TARG_CREATE);
1038101460Sru
1039141974Sharti		if (compatMake) {
1040101460Sru			/*
1041141974Sharti			 * Compat_Init will take care of creating
1042141974Sharti			 * all the targets as well as initializing
1043141974Sharti			 * the module.
1044101460Sru			 */
1045141974Sharti			Compat_Run(&targs);
1046141974Sharti			outOfDate = 0;
1047141974Sharti		} else {
1048141974Sharti			/*
1049141974Sharti			 * Initialize job module before traversing
1050141974Sharti			 * the graph, now that any .BEGIN and .END
1051141974Sharti			 * targets have been read.  This is done
1052141974Sharti			 * only if the -q flag wasn't given (to
1053141974Sharti			 * prevent the .BEGIN from being executed
1054141974Sharti			 * should it exist).
1055141974Sharti			 */
1056101460Sru			if (!queryFlag) {
1057146140Sharti				Job_Init(jobLimit);
1058101460Sru				jobsRunning = TRUE;
1059101460Sru			}
1060101460Sru
1061101460Sru			/* Traverse the graph, checking on all the targets */
1062138916Sharti			outOfDate = Make_Run(&targs);
10631590Srgrimes		}
1064138916Sharti		Lst_Destroy(&targs, NOFREE);
1065141974Sharti
1066141974Sharti	} else {
1067146141Sharti		Var_Print(&variables, expandVars);
106817193Sbde	}
10698874Srgrimes
1070138920Sru	Lst_Destroy(&variables, free);
1071138920Sru	Lst_Destroy(&makefiles, free);
1072138916Sharti	Lst_Destroy(&create, free);
10735814Sjkh
10741590Srgrimes	/* print the graph now it's been processed if the user requested it */
10751590Srgrimes	if (DEBUG(GRAPH2))
10761590Srgrimes		Targ_PrintGraph(2);
10771590Srgrimes
10781590Srgrimes	if (queryFlag && outOfDate)
1079138232Sharti		return (1);
10801590Srgrimes	else
1081138232Sharti		return (0);
10821590Srgrimes}
10831590Srgrimes
1084