main.c revision 146345
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 146345 2005-05-18 14:50:35Z 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{
578146345Sharti	ArgArray	aa;
5791590Srgrimes
5801590Srgrimes	if (line == NULL)
5811590Srgrimes		return;
5821590Srgrimes	for (; *line == ' '; ++line)
5831590Srgrimes		continue;
5841590Srgrimes	if (!*line)
5851590Srgrimes		return;
5861590Srgrimes
587140870Sharti	if (mflags)
588146345Sharti		MAKEFLAGS_break(&aa, line);
589140870Sharti	else
590146345Sharti		brk_string(&aa, line, TRUE);
591140870Sharti
592146345Sharti	MainParseArgs(aa.argc, aa.argv);
593146345Sharti	ArgArray_Done(&aa);
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 */
665146157Sharti	char *p, *p1;
666146157Sharti	const char *pathp;
667146157Sharti	const char *path;
66873262Simp	char mdpath[MAXPATHLEN];
66973262Simp	char obpath[MAXPATHLEN];
67073262Simp	char cdpath[MAXPATHLEN];
67118730Ssteve	char *cp = NULL, *start;
672141252Sharti
673146146Sharti	/*
674146146Sharti	 * Initialize file global variables.
675146146Sharti	 */
676146146Sharti	expandVars = TRUE;
677146146Sharti	noBuiltins = FALSE;		/* Read the built-in rules */
678146146Sharti	forceJobs = FALSE;              /* No -j flag */
679146146Sharti	curdir = cdpath;
680146146Sharti
681146146Sharti	/*
682146146Sharti	 * Initialize program global variables.
683146146Sharti	 */
684146146Sharti	beSilent = FALSE;		/* Print commands as executed */
685146146Sharti	ignoreErrors = FALSE;		/* Pay attention to non-zero returns */
686146146Sharti	noExecute = FALSE;		/* Execute all commands */
687146146Sharti	keepgoing = FALSE;		/* Stop on error */
688146146Sharti	allPrecious = FALSE;		/* Remove targets when interrupted */
689146146Sharti	queryFlag = FALSE;		/* This is not just a check-run */
690146146Sharti	touchFlag = FALSE;		/* Actually update targets */
691146146Sharti	usePipes = TRUE;		/* Catch child output in pipes */
692146146Sharti	debug = 0;			/* No debug verbosity, please. */
693146146Sharti	jobsRunning = FALSE;
694146146Sharti
695146146Sharti	jobLimit = DEFMAXJOBS;
696146146Sharti	compatMake = FALSE;		/* No compat mode */
697146146Sharti
698138071Sjmallett	check_make_level();
699104395Sjmallett
70018730Ssteve#ifdef RLIMIT_NOFILE
7011590Srgrimes	/*
70218730Ssteve	 * get rid of resource limit on file descriptors
70318730Ssteve	 */
70418730Ssteve	{
70518730Ssteve		struct rlimit rl;
706146144Sharti		if (getrlimit(RLIMIT_NOFILE, &rl) == -1) {
707146144Sharti			err(2, "getrlimit");
70818730Ssteve		}
709146144Sharti		rl.rlim_cur = rl.rlim_max;
710146144Sharti		if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
711146144Sharti			err(2, "setrlimit");
712146144Sharti		}
71318730Ssteve	}
71418730Ssteve#endif
7151590Srgrimes
7165814Sjkh	/*
71739006Skato	 * PC-98 kernel sets the `i386' string to the utsname.machine and
71839006Skato	 * it cannot be distinguished from IBM-PC by uname(3).  Therefore,
71939006Skato	 * we check machine.ispc98 and adjust the machine variable before
72039006Skato	 * using usname(3) below.
72153631Smarcel	 * NOTE: machdep.ispc98 was defined on 1998/8/31. At that time,
72253631Smarcel	 * __FreeBSD_version was defined as 300003. So, this check can
72353631Smarcel	 * safely be done with any kernel with version > 300003.
72439006Skato	 */
725146157Sharti	if ((machine = getenv("MACHINE")) == NULL) {
72639006Skato		int	ispc98;
72739006Skato		size_t	len;
72839006Skato
72939006Skato		len = sizeof(ispc98);
73039006Skato		if (!sysctlbyname("machdep.ispc98", &ispc98, &len, NULL, 0)) {
73139006Skato			if (ispc98)
73239006Skato				machine = "pc98";
73339006Skato		}
73439006Skato	}
73539006Skato
73639006Skato	/*
7375814Sjkh	 * Get the name of this type of MACHINE from utsname
7385814Sjkh	 * so we can share an executable for similar machines.
7395814Sjkh	 * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
7405814Sjkh	 *
7415814Sjkh	 * Note that while MACHINE is decided at run-time,
7425814Sjkh	 * MACHINE_ARCH is always known at compile time.
7435814Sjkh	 */
744146157Sharti	if (machine == NULL) {
745146144Sharti#ifdef MACHINE
746146144Sharti		machine = MACHINE;
747146144Sharti#else
748144475Sharti		static struct utsname utsname;
74918730Ssteve
750144475Sharti		if (uname(&utsname) == -1)
751144475Sharti			err(2, "uname");
752144475Sharti		machine = utsname.machine;
75318339Sswallace#endif
7545814Sjkh	}
7551590Srgrimes
756146144Sharti	if ((machine_arch = getenv("MACHINE_ARCH")) == NULL) {
757146144Sharti#ifdef MACHINE_ARCH
758146144Sharti		machine_arch = MACHINE_ARCH;
759146144Sharti#else
76044362Simp		machine_arch = "unknown";
76144362Simp#endif
76244362Simp	}
76344362Simp
7641590Srgrimes	/*
76572679Skris	 * Set machine_cpu to the minumum supported CPU revision based
76672679Skris	 * on the target architecture, if not already set.
76772679Skris	 */
768146144Sharti	if ((machine_cpu = getenv("MACHINE_CPU")) == NULL) {
76972679Skris		if (!strcmp(machine_arch, "i386"))
77072679Skris			machine_cpu = "i386";
77172679Skris		else if (!strcmp(machine_arch, "alpha"))
77272679Skris			machine_cpu = "ev4";
77372679Skris		else
77472679Skris			machine_cpu = "unknown";
77572679Skris	}
7761590Srgrimes
7771590Srgrimes	/*
7781590Srgrimes	 * Initialize the parsing, directory and variable modules to prepare
7791590Srgrimes	 * for the reading of inclusion paths and variable settings on the
7801590Srgrimes	 * command line
7811590Srgrimes	 */
782146144Sharti	Proc_Init();
783146144Sharti
7841590Srgrimes	Dir_Init();		/* Initialize directory structures so -I flags
7851590Srgrimes				 * can be processed correctly */
786145971Sharti	Var_Init(environ);	/* As well as the lists of variables for
7871590Srgrimes				 * parsing arguments */
7881590Srgrimes	/*
7891590Srgrimes	 * Initialize various variables.
7901590Srgrimes	 *	MAKE also gets this name, for compatibility
7911590Srgrimes	 *	.MAKEFLAGS gets set to the empty string just in case.
7921590Srgrimes	 *	MFLAGS also gets initialized empty, for compatibility.
7931590Srgrimes	 */
794146145Sharti	Var_SetGlobal("MAKE", argv[0]);
795146146Sharti	Var_SetGlobal(".MAKEFLAGS", "");
796146145Sharti	Var_SetGlobal("MFLAGS", "");
797146145Sharti	Var_SetGlobal("MACHINE", machine);
798146145Sharti	Var_SetGlobal("MACHINE_ARCH", machine_arch);
799146145Sharti	Var_SetGlobal("MACHINE_CPU", machine_cpu);
80097121Sru#ifdef MAKE_VERSION
801146145Sharti	Var_SetGlobal("MAKE_VERSION", MAKE_VERSION);
80297121Sru#endif
8031590Srgrimes
8041590Srgrimes	/*
805144896Sharti	 * First snag things out of the MAKEFLAGS environment
806144896Sharti	 * variable.  Then parse the command line arguments.
8071590Srgrimes	 */
808140870Sharti	Main_ParseArgLine(getenv("MAKEFLAGS"), 1);
8098874Srgrimes
8101590Srgrimes	MainParseArgs(argc, argv);
8111590Srgrimes
8121590Srgrimes	/*
813120053Sru	 * Find where we are...
814120053Sru	 */
815120053Sru	if (getcwd(curdir, MAXPATHLEN) == NULL)
816120053Sru		err(2, NULL);
817120053Sru
818141252Sharti	{
819141252Sharti	struct stat sa;
820141252Sharti
821120053Sru	if (stat(curdir, &sa) == -1)
822120053Sru	    err(2, "%s", curdir);
823141252Sharti	}
824120053Sru
825120053Sru	/*
826120053Sru	 * The object directory location is determined using the
827120053Sru	 * following order of preference:
828120053Sru	 *
829120053Sru	 *	1. MAKEOBJDIRPREFIX`cwd`
830120053Sru	 *	2. MAKEOBJDIR
831143412Sharti	 *	3. PATH_OBJDIR.${MACHINE}
832143412Sharti	 *	4. PATH_OBJDIR
833143412Sharti	 *	5. PATH_OBJDIRPREFIX`cwd`
834120053Sru	 *
835120053Sru	 * If one of the first two fails, use the current directory.
836120053Sru	 * If the remaining three all fail, use the current directory.
837120053Sru	 *
838120053Sru	 * Once things are initted,
839120053Sru	 * have to add the original directory to the search path,
840120053Sru	 * and modify the paths for the Makefiles apropriately.  The
841120053Sru	 * current directory is also placed as a variable for make scripts.
842120053Sru	 */
843120053Sru	if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
844120053Sru		if (!(path = getenv("MAKEOBJDIR"))) {
845143412Sharti			path = PATH_OBJDIR;
846143412Sharti			pathp = PATH_OBJDIRPREFIX;
847146145Sharti			snprintf(mdpath, MAXPATHLEN, "%s.%s", path, machine);
848120053Sru			if (!(objdir = chdir_verify_path(mdpath, obpath)))
849120053Sru				if (!(objdir=chdir_verify_path(path, obpath))) {
850138232Sharti					snprintf(mdpath, MAXPATHLEN,
851120053Sru							"%s%s", pathp, curdir);
852120053Sru					if (!(objdir=chdir_verify_path(mdpath,
853120053Sru								       obpath)))
854120053Sru						objdir = curdir;
855120053Sru				}
856120053Sru		}
857120053Sru		else if (!(objdir = chdir_verify_path(path, obpath)))
858120053Sru			objdir = curdir;
859120053Sru	}
860120053Sru	else {
861138232Sharti		snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
862120053Sru		if (!(objdir = chdir_verify_path(mdpath, obpath)))
863120053Sru			objdir = curdir;
864120053Sru	}
865120053Sru	Dir_InitDot();		/* Initialize the "." directory */
866120053Sru	if (objdir != curdir)
867144020Sharti		Path_AddDir(&dirSearchPath, curdir);
868146145Sharti	Var_SetGlobal(".ST_EXPORTVAR", "YES");
869146145Sharti	Var_SetGlobal(".CURDIR", curdir);
870146145Sharti	Var_SetGlobal(".OBJDIR", objdir);
871120053Sru
872137606Sphk	if (getenv("MAKE_JOBS_FIFO") != NULL)
873137606Sphk		forceJobs = TRUE;
874120053Sru	/*
87528228Sfsmp	 * Be compatible if user did not specify -j and did not explicitly
87628228Sfsmp	 * turned compatibility on
87728228Sfsmp	 */
87828228Sfsmp	if (!compatMake && !forceJobs)
87928228Sfsmp		compatMake = TRUE;
88028228Sfsmp
88128228Sfsmp	/*
882144387Sharti	 * Initialize target and suffix modules in preparation for
8831590Srgrimes	 * parsing the makefile(s)
8841590Srgrimes	 */
8851590Srgrimes	Targ_Init();
8861590Srgrimes	Suff_Init();
8871590Srgrimes
88869527Swill	DEFAULT = NULL;
889138232Sharti	time(&now);
8901590Srgrimes
8911590Srgrimes	/*
8921590Srgrimes	 * Set up the .TARGETS variable to contain the list of targets to be
8931590Srgrimes	 * created. If none specified, make the variable empty -- the parser
8941590Srgrimes	 * will fill the thing in with the default or .MAIN target.
8951590Srgrimes	 */
896146145Sharti	if (Lst_IsEmpty(&create)) {
897146145Sharti		Var_SetGlobal(".TARGETS", "");
898146145Sharti	} else {
899138512Sharti		LstNode *ln;
9001590Srgrimes
901138916Sharti		for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) {
902138264Sharti			char *name = Lst_Datum(ln);
9031590Srgrimes
9041590Srgrimes			Var_Append(".TARGETS", name, VAR_GLOBAL);
9051590Srgrimes		}
906146145Sharti	}
9071590Srgrimes
90818730Ssteve
9091590Srgrimes	/*
91018730Ssteve	 * If no user-supplied system path was given (through the -m option)
91118730Ssteve	 * add the directories from the DEFSYSPATH (more than one may be given
91218730Ssteve	 * as dir1:...:dirn) to the system include path.
9131590Srgrimes	 */
914144020Sharti	if (TAILQ_EMPTY(&sysIncPath)) {
915146144Sharti		char syspath[] = PATH_DEFSYSPATH;
916146144Sharti
91718730Ssteve		for (start = syspath; *start != '\0'; start = cp) {
91818730Ssteve			for (cp = start; *cp != '\0' && *cp != ':'; cp++)
91918730Ssteve				continue;
92018730Ssteve			if (*cp == '\0') {
921144020Sharti				Path_AddDir(&sysIncPath, start);
92218730Ssteve			} else {
92318730Ssteve				*cp++ = '\0';
924144020Sharti				Path_AddDir(&sysIncPath, start);
92518730Ssteve			}
92618730Ssteve		}
92718730Ssteve	}
9281590Srgrimes
92918730Ssteve	/*
93018730Ssteve	 * Read in the built-in rules first, followed by the specified
93118730Ssteve	 * makefile, if it was (makefile != (char *) NULL), or the default
93218730Ssteve	 * Makefile and makefile, in that order, if it wasn't.
93318730Ssteve	 */
93418730Ssteve	if (!noBuiltins) {
935138916Sharti		/* Path of sys.mk */
936138916Sharti		Lst sysMkPath = Lst_Initializer(sysMkPath);
937138512Sharti		LstNode *ln;
938146064Sharti		char	defsysmk[] = PATH_DEFSYSMK;
93918730Ssteve
940146064Sharti		Path_Expand(defsysmk, &sysIncPath, &sysMkPath);
941138916Sharti		if (Lst_IsEmpty(&sysMkPath))
942143412Sharti			Fatal("make: no system rules (%s).", PATH_DEFSYSMK);
943143808Sharti		LST_FOREACH(ln, &sysMkPath) {
944143808Sharti			if (!ReadMakefile(Lst_Datum(ln)))
945143808Sharti				break;
946143808Sharti		}
94769527Swill		if (ln != NULL)
94818730Ssteve			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
949138916Sharti		Lst_Destroy(&sysMkPath, free);
95018730Ssteve	}
95118730Ssteve
952138916Sharti	if (!Lst_IsEmpty(&makefiles)) {
953138512Sharti		LstNode *ln;
9541590Srgrimes
955143808Sharti		LST_FOREACH(ln, &makefiles) {
956143808Sharti			if (!ReadMakefile(Lst_Datum(ln)))
957143808Sharti				break;
958143808Sharti		}
95969527Swill		if (ln != NULL)
9601590Srgrimes			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
961143808Sharti	} else if (!ReadMakefile("BSDmakefile"))
962143808Sharti	    if (!ReadMakefile("makefile"))
963143808Sharti		ReadMakefile("Makefile");
9641590Srgrimes
965143808Sharti	ReadMakefile(".depend");
9661590Srgrimes
9671590Srgrimes	/* Install all the flags into the MAKE envariable. */
968146146Sharti	if (((p = Var_Value(".MAKEFLAGS", VAR_GLOBAL, &p1)) != NULL) && *p)
9691590Srgrimes		setenv("MAKEFLAGS", p, 1);
970105826Sjmallett	free(p1);
9711590Srgrimes
9721590Srgrimes	/*
9731590Srgrimes	 * For compatibility, look at the directories in the VPATH variable
9741590Srgrimes	 * and add them to the search path, if the variable is defined. The
9751590Srgrimes	 * variable's value is in the same format as the PATH envariable, i.e.
9761590Srgrimes	 * <directory>:<directory>:<directory>...
9771590Srgrimes	 */
9781590Srgrimes	if (Var_Exists("VPATH", VAR_CMD)) {
9791590Srgrimes		/*
9801590Srgrimes		 * GCC stores string constants in read-only memory, but
9811590Srgrimes		 * Var_Subst will want to write this thing, so store it
9821590Srgrimes		 * in an array
9831590Srgrimes		 */
9841590Srgrimes		static char VPATH[] = "${VPATH}";
985142457Sharti		Buffer	*buf;
986142457Sharti		char	*vpath;
987142457Sharti		char	*ptr;
988142457Sharti		char	savec;
9891590Srgrimes
990146027Sharti		buf = Var_Subst(VPATH, VAR_CMD, FALSE);
991142457Sharti
992143959Sharti		vpath = Buf_Data(buf);
9931590Srgrimes		do {
9941590Srgrimes			/* skip to end of directory */
995142457Sharti			for (ptr = vpath; *ptr != ':' && *ptr != '\0'; ptr++)
996141969Sharti				;
997141969Sharti
9981590Srgrimes			/* Save terminator character so know when to stop */
999141969Sharti			savec = *ptr;
1000141969Sharti			*ptr = '\0';
1001141969Sharti
10021590Srgrimes			/* Add directory to search path */
1003144020Sharti			Path_AddDir(&dirSearchPath, vpath);
1004141969Sharti
1005142457Sharti			vpath = ptr + 1;
1006141969Sharti		} while (savec != '\0');
1007142457Sharti
1008142457Sharti		Buf_Destroy(buf, TRUE);
10091590Srgrimes	}
10101590Srgrimes
10111590Srgrimes	/*
10121590Srgrimes	 * Now that all search paths have been read for suffixes et al, it's
10131590Srgrimes	 * time to add the default search path to their lists...
10141590Srgrimes	 */
10151590Srgrimes	Suff_DoPaths();
10161590Srgrimes
10171590Srgrimes	/* print the initial graph, if the user requested it */
10181590Srgrimes	if (DEBUG(GRAPH1))
10191590Srgrimes		Targ_PrintGraph(1);
10201590Srgrimes
102117193Sbde	/* print the values of any variables requested by the user */
1022141974Sharti	if (Lst_IsEmpty(&variables)) {
10231590Srgrimes		/*
1024141974Sharti		 * Since the user has not requested that any variables
1025142008Sharti		 * be printed, we can build targets.
1026141974Sharti		 *
1027142008Sharti		 * Have read the entire graph and need to make a list of targets
1028141974Sharti		 * to create. If none was given on the command line, we consult
1029141974Sharti		 * the parsing module to find the main target(s) to create.
10301590Srgrimes		 */
1031138916Sharti		Lst targs = Lst_Initializer(targs);
1032138916Sharti
1033138916Sharti		if (Lst_IsEmpty(&create))
1034138916Sharti			Parse_MainName(&targs);
1035101460Sru		else
1036138916Sharti			Targ_FindList(&targs, &create, TARG_CREATE);
1037101460Sru
1038141974Sharti		if (compatMake) {
1039101460Sru			/*
1040141974Sharti			 * Compat_Init will take care of creating
1041141974Sharti			 * all the targets as well as initializing
1042141974Sharti			 * the module.
1043101460Sru			 */
1044141974Sharti			Compat_Run(&targs);
1045141974Sharti			outOfDate = 0;
1046141974Sharti		} else {
1047141974Sharti			/*
1048141974Sharti			 * Initialize job module before traversing
1049141974Sharti			 * the graph, now that any .BEGIN and .END
1050141974Sharti			 * targets have been read.  This is done
1051141974Sharti			 * only if the -q flag wasn't given (to
1052141974Sharti			 * prevent the .BEGIN from being executed
1053141974Sharti			 * should it exist).
1054141974Sharti			 */
1055101460Sru			if (!queryFlag) {
1056146140Sharti				Job_Init(jobLimit);
1057101460Sru				jobsRunning = TRUE;
1058101460Sru			}
1059101460Sru
1060101460Sru			/* Traverse the graph, checking on all the targets */
1061138916Sharti			outOfDate = Make_Run(&targs);
10621590Srgrimes		}
1063138916Sharti		Lst_Destroy(&targs, NOFREE);
1064141974Sharti
1065141974Sharti	} else {
1066146141Sharti		Var_Print(&variables, expandVars);
106717193Sbde	}
10688874Srgrimes
1069138920Sru	Lst_Destroy(&variables, free);
1070138920Sru	Lst_Destroy(&makefiles, free);
1071138916Sharti	Lst_Destroy(&create, free);
10725814Sjkh
10731590Srgrimes	/* print the graph now it's been processed if the user requested it */
10741590Srgrimes	if (DEBUG(GRAPH2))
10751590Srgrimes		Targ_PrintGraph(2);
10761590Srgrimes
10771590Srgrimes	if (queryFlag && outOfDate)
1078138232Sharti		return (1);
10791590Srgrimes	else
1080138232Sharti		return (0);
10811590Srgrimes}
10821590Srgrimes
1083