main.c revision 177101
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 177101 2008-03-12 14:50:58Z obrien $");
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
641590Srgrimes#include <sys/param.h>
651590Srgrimes#include <sys/stat.h>
6639006Skato#include <sys/sysctl.h>
67127880Sdes#include <sys/time.h>
68144020Sharti#include <sys/queue.h>
69127899Sru#include <sys/resource.h>
70153115Sru#include <sys/utsname.h>
7118730Ssteve#include <sys/wait.h>
7227644Scharnier#include <err.h>
731590Srgrimes#include <errno.h>
74127880Sdes#include <stdlib.h>
75141104Sharti#include <string.h>
7663955Simp#include <unistd.h>
77127880Sdes
78141104Sharti#include "arch.h"
79141133Sharti#include "buf.h"
80141104Sharti#include "config.h"
811590Srgrimes#include "dir.h"
82141104Sharti#include "globals.h"
83167330Sfjoe#include "GNode.h"
841590Srgrimes#include "job.h"
85141104Sharti#include "make.h"
86141104Sharti#include "parse.h"
871590Srgrimes#include "pathnames.h"
88146572Sharti#include "shell.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
97160442Sobrien#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
104167330Sfjoe/* ordered list of source makefiles */
105167330Sfjoestatic Lst source_makefiles = Lst_Initializer(source_makefiles);
106167330Sfjoe
107138916Sharti/* list of variables to print */
108138916Shartistatic Lst variables = Lst_Initializer(variables);
109138916Sharti
110146146Shartistatic Boolean	expandVars;	/* fully expand printed variables */
111146146Shartistatic Boolean	noBuiltins;	/* -r flag */
112160442Sobrienstatic Boolean	forceJobs;	/* -j argument given */
113146146Shartistatic char	*curdir;	/* startup directory */
114146146Shartistatic char	*objdir;	/* where we chdir'ed to */
115167330Sfjoestatic char	**save_argv;	/* saved argv */
116167330Sfjoestatic char	*save_makeflags;/* saved MAKEFLAGS */
117146146Sharti
118146146Sharti/* (-E) vars to override from env */
119146146ShartiLst envFirstVars = Lst_Initializer(envFirstVars);
120146146Sharti
121146146Sharti/* Targets to be made */
122146146ShartiLst create = Lst_Initializer(create);
123146146Sharti
124146146ShartiBoolean		allPrecious;	/* .PRECIOUS given on line by itself */
125167330SfjoeBoolean		is_posix;	/* .POSIX target seen */
126177101SobrienBoolean		mfAutoDeps;	/* .MAKEFILEDEPS target seen */
127146146ShartiBoolean		beSilent;	/* -s flag */
128146146ShartiBoolean		beVerbose;	/* -v flag */
129144475ShartiBoolean		compatMake;	/* -B argument */
130149844Shartiint		debug;		/* -d flag */
131146146ShartiBoolean		ignoreErrors;	/* -i flag */
132146146Shartiint		jobLimit;	/* -j argument */
133146146ShartiBoolean		jobsRunning;	/* TRUE if the jobs might be running */
134146146ShartiBoolean		keepgoing;	/* -k flag */
135144475ShartiBoolean		noExecute;	/* -n flag */
136144475ShartiBoolean		queryFlag;	/* -q flag */
137144475ShartiBoolean		touchFlag;	/* -t flag */
138144475ShartiBoolean		usePipes;	/* !-P flag */
139146146Shartiuint32_t	warn_cmd;	/* command line warning flags */
140146146Shartiuint32_t	warn_flags;	/* actual warning flags */
141146146Shartiuint32_t	warn_nocmd;	/* command line no-warning flags */
142138916Sharti
143146146Shartitime_t		now;		/* Time at start of make */
144146146Shartistruct GNode	*DEFAULT;	/* .DEFAULT node */
145138916Sharti
146144475Sharti/**
147146143Sharti * Exit with usage message.
148146143Sharti */
149146143Shartistatic void
150146143Shartiusage(void)
151146143Sharti{
152146143Sharti	fprintf(stderr,
153146143Sharti	    "usage: make [-BPSXeiknqrstv] [-C directory] [-D variable]\n"
154146143Sharti	    "\t[-d flags] [-E variable] [-f makefile] [-I directory]\n"
155146143Sharti	    "\t[-j max_jobs] [-m directory] [-V variable]\n"
156146143Sharti	    "\t[variable=value] [target ...]\n");
157146143Sharti	exit(2);
158146143Sharti}
159146143Sharti
160146143Sharti/**
161144475Sharti * MFLAGS_append
162144475Sharti *	Append a flag with an optional argument to MAKEFLAGS and MFLAGS
163133085Sharti */
164133085Shartistatic void
165141252ShartiMFLAGS_append(const char *flag, char *arg)
166133085Sharti{
167140870Sharti	char *str;
168138232Sharti
169146146Sharti	Var_Append(".MAKEFLAGS", flag, VAR_GLOBAL);
170140870Sharti	if (arg != NULL) {
171140870Sharti		str = MAKEFLAGS_quote(arg);
172146146Sharti		Var_Append(".MAKEFLAGS", str, VAR_GLOBAL);
173140870Sharti		free(str);
174140870Sharti	}
175133085Sharti
176133085Sharti	Var_Append("MFLAGS", flag, VAR_GLOBAL);
177140870Sharti	if (arg != NULL) {
178140870Sharti		str = MAKEFLAGS_quote(arg);
179140870Sharti		Var_Append("MFLAGS", str, VAR_GLOBAL);
180140870Sharti		free(str);
181140870Sharti	}
182133085Sharti}
183133085Sharti
184144475Sharti/**
185145679Sharti * Main_ParseWarn
186145679Sharti *
187145679Sharti *	Handle argument to warning option.
188145679Sharti */
189145679Shartiint
190145679ShartiMain_ParseWarn(const char *arg, int iscmd)
191145679Sharti{
192145679Sharti	int i, neg;
193145679Sharti
194145679Sharti	static const struct {
195145679Sharti		const char	*option;
196145679Sharti		uint32_t	flag;
197145679Sharti	} options[] = {
198145679Sharti		{ "dirsyntax",	WARN_DIRSYNTAX },
199145679Sharti		{ NULL,		0 }
200145679Sharti	};
201145679Sharti
202145679Sharti	neg = 0;
203145679Sharti	if (arg[0] == 'n' && arg[1] == 'o') {
204145679Sharti		neg = 1;
205145679Sharti		arg += 2;
206145679Sharti	}
207145679Sharti
208145679Sharti	for (i = 0; options[i].option != NULL; i++)
209145679Sharti		if (strcmp(arg, options[i].option) == 0)
210145679Sharti			break;
211145679Sharti
212145679Sharti	if (options[i].option == NULL)
213145679Sharti		/* unknown option */
214145679Sharti		return (-1);
215145679Sharti
216145679Sharti	if (iscmd) {
217145679Sharti		if (!neg) {
218145679Sharti			warn_cmd |= options[i].flag;
219145679Sharti			warn_nocmd &= ~options[i].flag;
220145679Sharti			warn_flags |= options[i].flag;
221145679Sharti		} else {
222145679Sharti			warn_nocmd |= options[i].flag;
223145679Sharti			warn_cmd &= ~options[i].flag;
224145679Sharti			warn_flags &= ~options[i].flag;
225145679Sharti		}
226145679Sharti	} else {
227145679Sharti		if (!neg) {
228145679Sharti			warn_flags |= (options[i].flag & ~warn_nocmd);
229145679Sharti		} else {
230145679Sharti			warn_flags &= ~(options[i].flag | warn_cmd);
231145679Sharti		}
232145679Sharti	}
233145679Sharti	return (0);
234145679Sharti}
235145679Sharti
236145679Sharti/**
237146143Sharti * Open and parse the given makefile.
238146143Sharti *
239146143Sharti * Results:
240146143Sharti *	TRUE if ok. FALSE if couldn't open file.
241146143Sharti */
242146143Shartistatic Boolean
243146143ShartiReadMakefile(const char p[])
244146143Sharti{
245152982Sdavidxu	char *fname, *fnamesave;	/* makefile to read */
246146143Sharti	FILE *stream;
247146143Sharti	char *name, path[MAXPATHLEN];
248146143Sharti	char *MAKEFILE;
249146143Sharti	int setMAKEFILE;
250146143Sharti
251146143Sharti	/* XXX - remove this once constification is done */
252152982Sdavidxu	fnamesave = fname = estrdup(p);
253146143Sharti
254146143Sharti	if (!strcmp(fname, "-")) {
255146143Sharti		Parse_File("(stdin)", stdin);
256146145Sharti		Var_SetGlobal("MAKEFILE", "");
257146143Sharti	} else {
258146143Sharti		setMAKEFILE = strcmp(fname, ".depend");
259146143Sharti
260146143Sharti		/* if we've chdir'd, rebuild the path name */
261146143Sharti		if (curdir != objdir && *fname != '/') {
262146143Sharti			snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname);
263146143Sharti			/*
264146143Sharti			 * XXX The realpath stuff breaks relative includes
265146143Sharti			 * XXX in some cases.   The problem likely is in
266146143Sharti			 * XXX parse.c where it does special things in
267146143Sharti			 * XXX ParseDoInclude if the file is relateive
268146143Sharti			 * XXX or absolute and not a system file.  There
269146143Sharti			 * XXX it assumes that if the current file that's
270146143Sharti			 * XXX being included is absolute, that any files
271146143Sharti			 * XXX that it includes shouldn't do the -I path
272146143Sharti			 * XXX stuff, which is inconsistant with historical
273146143Sharti			 * XXX behavior.  However, I can't pentrate the mists
274146143Sharti			 * XXX further, so I'm putting this workaround in
275146143Sharti			 * XXX here until such time as the underlying bug
276146143Sharti			 * XXX can be fixed.
277146143Sharti			 */
278146143Sharti#if THIS_BREAKS_THINGS
279146143Sharti			if (realpath(path, path) != NULL &&
280146143Sharti			    (stream = fopen(path, "r")) != NULL) {
281146143Sharti				MAKEFILE = fname;
282146143Sharti				fname = path;
283146143Sharti				goto found;
284146143Sharti			}
285146143Sharti		} else if (realpath(fname, path) != NULL) {
286146143Sharti			MAKEFILE = fname;
287146143Sharti			fname = path;
288146143Sharti			if ((stream = fopen(fname, "r")) != NULL)
289146143Sharti				goto found;
290146143Sharti		}
291146143Sharti#else
292146143Sharti			if ((stream = fopen(path, "r")) != NULL) {
293146143Sharti				MAKEFILE = fname;
294146143Sharti				fname = path;
295146143Sharti				goto found;
296146143Sharti			}
297146143Sharti		} else {
298146143Sharti			MAKEFILE = fname;
299146143Sharti			if ((stream = fopen(fname, "r")) != NULL)
300146143Sharti				goto found;
301146143Sharti		}
302146143Sharti#endif
303146143Sharti		/* look in -I and system include directories. */
304146143Sharti		name = Path_FindFile(fname, &parseIncPath);
305146143Sharti		if (!name)
306146143Sharti			name = Path_FindFile(fname, &sysIncPath);
307152969Sfjoe		if (!name || !(stream = fopen(name, "r"))) {
308152982Sdavidxu			free(fnamesave);
309146143Sharti			return (FALSE);
310152969Sfjoe		}
311146143Sharti		MAKEFILE = fname = name;
312146143Sharti		/*
313146143Sharti		 * set the MAKEFILE variable desired by System V fans -- the
314146143Sharti		 * placement of the setting here means it gets set to the last
315146143Sharti		 * makefile specified, as it is set by SysV make.
316146143Sharti		 */
317146143Shartifound:
318146143Sharti		if (setMAKEFILE)
319146145Sharti			Var_SetGlobal("MAKEFILE", MAKEFILE);
320146143Sharti		Parse_File(fname, stream);
321146143Sharti	}
322152982Sdavidxu	free(fnamesave);
323146143Sharti	return (TRUE);
324146143Sharti}
325146143Sharti
326146143Sharti/**
327167330Sfjoe * Open and parse the given makefile.
328167330Sfjoe * If open is successful add it to the list of makefiles.
329167330Sfjoe *
330167330Sfjoe * Results:
331167330Sfjoe *	TRUE if ok. FALSE if couldn't open file.
332167330Sfjoe */
333167330Sfjoestatic Boolean
334167330SfjoeTryReadMakefile(const char p[])
335167330Sfjoe{
336167330Sfjoe	char *data;
337167330Sfjoe	LstNode *last = Lst_Last(&source_makefiles);
338167330Sfjoe
339167330Sfjoe	if (!ReadMakefile(p))
340167330Sfjoe		return (FALSE);
341167330Sfjoe
342167330Sfjoe	data = estrdup(p);
343167330Sfjoe	if (last == NULL) {
344167330Sfjoe		LstNode *first = Lst_First(&source_makefiles);
345167330Sfjoe		Lst_Insert(&source_makefiles, first, data);
346167330Sfjoe	} else
347167330Sfjoe		Lst_Append(&source_makefiles, last, estrdup(p));
348167330Sfjoe	return (TRUE);
349167330Sfjoe}
350167330Sfjoe
351167330Sfjoe/**
352144475Sharti * MainParseArgs
3531590Srgrimes *	Parse a given argument vector. Called from main() and from
3541590Srgrimes *	Main_ParseArgLine() when the .MAKEFLAGS target is used.
3551590Srgrimes *
3561590Srgrimes *	XXX: Deal with command line overriding .MAKEFLAGS in makefile
3571590Srgrimes *
3581590Srgrimes * Side Effects:
3591590Srgrimes *	Various global and local flags will be set depending on the flags
3601590Srgrimes *	given
3611590Srgrimes */
3621590Srgrimesstatic void
363104696SjmallettMainParseArgs(int argc, char **argv)
3641590Srgrimes{
3655814Sjkh	int c;
366146038Sharti	Boolean	found_dd = FALSE;
3671590Srgrimes
368144896Shartirearg:
3691590Srgrimes	optind = 1;	/* since we're called more than once */
370144896Sharti	optreset = 1;
371145627Sharti#define OPTFLAGS "ABC:D:E:I:PSV:Xd:ef:ij:km:nqrstvx:"
372146038Sharti	for (;;) {
373146038Sharti		if ((optind < argc) && strcmp(argv[optind], "--") == 0) {
374146038Sharti			found_dd = TRUE;
375146038Sharti		}
376146038Sharti		if ((c = getopt(argc, argv, OPTFLAGS)) == -1) {
377146038Sharti			break;
378146038Sharti		}
3791590Srgrimes		switch(c) {
380144387Sharti
381144387Sharti		case 'A':
382144387Sharti			arch_fatal = FALSE;
383144387Sharti			MFLAGS_append("-A", NULL);
384144387Sharti			break;
385102393Sjmallett		case 'C':
386107964Sseanc			if (chdir(optarg) == -1)
387107964Sseanc				err(1, "chdir %s", optarg);
388102393Sjmallett			break;
3891590Srgrimes		case 'D':
390146145Sharti			Var_SetGlobal(optarg, "1");
391133085Sharti			MFLAGS_append("-D", optarg);
3921590Srgrimes			break;
3931590Srgrimes		case 'I':
3941590Srgrimes			Parse_AddIncludeDir(optarg);
395133085Sharti			MFLAGS_append("-I", optarg);
3961590Srgrimes			break;
39717193Sbde		case 'V':
398138920Sru			Lst_AtEnd(&variables, estrdup(optarg));
399133085Sharti			MFLAGS_append("-V", optarg);
40017193Sbde			break;
40166365Speter		case 'X':
40266365Speter			expandVars = FALSE;
40366365Speter			break;
4041590Srgrimes		case 'B':
4051590Srgrimes			compatMake = TRUE;
406133085Sharti			MFLAGS_append("-B", NULL);
407137626Sphk			unsetenv("MAKE_JOBS_FIFO");
4081590Srgrimes			break;
4091590Srgrimes		case 'P':
4101590Srgrimes			usePipes = FALSE;
411133085Sharti			MFLAGS_append("-P", NULL);
4121590Srgrimes			break;
4131590Srgrimes		case 'S':
4141590Srgrimes			keepgoing = FALSE;
415133085Sharti			MFLAGS_append("-S", NULL);
4161590Srgrimes			break;
4171590Srgrimes		case 'd': {
4181590Srgrimes			char *modules = optarg;
4191590Srgrimes
4201590Srgrimes			for (; *modules; ++modules)
4211590Srgrimes				switch (*modules) {
4221590Srgrimes				case 'A':
4231590Srgrimes					debug = ~0;
4241590Srgrimes					break;
4251590Srgrimes				case 'a':
4261590Srgrimes					debug |= DEBUG_ARCH;
4271590Srgrimes					break;
4281590Srgrimes				case 'c':
4291590Srgrimes					debug |= DEBUG_COND;
4301590Srgrimes					break;
4311590Srgrimes				case 'd':
4321590Srgrimes					debug |= DEBUG_DIR;
4331590Srgrimes					break;
4341590Srgrimes				case 'f':
4351590Srgrimes					debug |= DEBUG_FOR;
4361590Srgrimes					break;
4371590Srgrimes				case 'g':
4381590Srgrimes					if (modules[1] == '1') {
4391590Srgrimes						debug |= DEBUG_GRAPH1;
4401590Srgrimes						++modules;
4411590Srgrimes					}
4421590Srgrimes					else if (modules[1] == '2') {
4431590Srgrimes						debug |= DEBUG_GRAPH2;
4441590Srgrimes						++modules;
4451590Srgrimes					}
4461590Srgrimes					break;
4471590Srgrimes				case 'j':
4481590Srgrimes					debug |= DEBUG_JOB;
4491590Srgrimes					break;
45060569Swill				case 'l':
45160569Swill					debug |= DEBUG_LOUD;
45260569Swill					break;
4531590Srgrimes				case 'm':
4541590Srgrimes					debug |= DEBUG_MAKE;
4551590Srgrimes					break;
4561590Srgrimes				case 's':
4571590Srgrimes					debug |= DEBUG_SUFF;
4581590Srgrimes					break;
4591590Srgrimes				case 't':
4601590Srgrimes					debug |= DEBUG_TARG;
4611590Srgrimes					break;
4621590Srgrimes				case 'v':
4631590Srgrimes					debug |= DEBUG_VAR;
4641590Srgrimes					break;
4651590Srgrimes				default:
466144475Sharti					warnx("illegal argument to d option "
467144475Sharti					    "-- %c", *modules);
4681590Srgrimes					usage();
4691590Srgrimes				}
470133085Sharti			MFLAGS_append("-d", optarg);
4711590Srgrimes			break;
4721590Srgrimes		}
47349332Shoek		case 'E':
474138920Sru			Lst_AtEnd(&envFirstVars, estrdup(optarg));
475133085Sharti			MFLAGS_append("-E", optarg);
47649332Shoek			break;
4771590Srgrimes		case 'e':
4781590Srgrimes			checkEnvFirst = TRUE;
479133085Sharti			MFLAGS_append("-e", NULL);
4801590Srgrimes			break;
4811590Srgrimes		case 'f':
482138920Sru			Lst_AtEnd(&makefiles, estrdup(optarg));
4831590Srgrimes			break;
4841590Srgrimes		case 'i':
4851590Srgrimes			ignoreErrors = TRUE;
486133085Sharti			MFLAGS_append("-i", NULL);
4871590Srgrimes			break;
48849331Shoek		case 'j': {
48949331Shoek			char *endptr;
49049331Shoek
49118730Ssteve			forceJobs = TRUE;
492146140Sharti			jobLimit = strtol(optarg, &endptr, 10);
493146140Sharti			if (jobLimit <= 0 || *endptr != '\0') {
49449938Shoek				warnx("illegal number, -j argument -- %s",
49549938Shoek				    optarg);
49649938Shoek				usage();
49749331Shoek			}
498133085Sharti			MFLAGS_append("-j", optarg);
4991590Srgrimes			break;
50049331Shoek		}
5011590Srgrimes		case 'k':
5021590Srgrimes			keepgoing = TRUE;
503133085Sharti			MFLAGS_append("-k", NULL);
5041590Srgrimes			break;
50518730Ssteve		case 'm':
506144020Sharti			Path_AddDir(&sysIncPath, optarg);
507133085Sharti			MFLAGS_append("-m", optarg);
50818730Ssteve			break;
5091590Srgrimes		case 'n':
5101590Srgrimes			noExecute = TRUE;
511133085Sharti			MFLAGS_append("-n", NULL);
5121590Srgrimes			break;
5131590Srgrimes		case 'q':
5141590Srgrimes			queryFlag = TRUE;
5151590Srgrimes			/* Kind of nonsensical, wot? */
516133085Sharti			MFLAGS_append("-q", NULL);
5171590Srgrimes			break;
5181590Srgrimes		case 'r':
5191590Srgrimes			noBuiltins = TRUE;
520133085Sharti			MFLAGS_append("-r", NULL);
5211590Srgrimes			break;
5221590Srgrimes		case 's':
5231590Srgrimes			beSilent = TRUE;
524133085Sharti			MFLAGS_append("-s", NULL);
5251590Srgrimes			break;
5261590Srgrimes		case 't':
5271590Srgrimes			touchFlag = TRUE;
528133085Sharti			MFLAGS_append("-t", NULL);
5291590Srgrimes			break;
53041151Sdg		case 'v':
53141151Sdg			beVerbose = TRUE;
532133085Sharti			MFLAGS_append("-v", NULL);
53341151Sdg			break;
534145627Sharti		case 'x':
535145679Sharti			if (Main_ParseWarn(optarg, 1) != -1)
536145627Sharti				MFLAGS_append("-x", optarg);
537145627Sharti			break;
538167330Sfjoe
5391590Srgrimes		default:
5401590Srgrimes		case '?':
5411590Srgrimes			usage();
5421590Srgrimes		}
5431590Srgrimes	}
544144896Sharti	argv += optind;
545144896Sharti	argc -= optind;
5461590Srgrimes
5471590Srgrimes	oldVars = TRUE;
5481590Srgrimes
5491590Srgrimes	/*
550144896Sharti	 * Parse the rest of the arguments.
551144896Sharti	 *	o Check for variable assignments and perform them if so.
552144896Sharti	 *	o Check for more flags and restart getopt if so.
553160442Sobrien	 *	o Anything else is taken to be a target and added
554144896Sharti	 *	  to the end of the "create" list.
5551590Srgrimes	 */
556144896Sharti	for (; *argv != NULL; ++argv, --argc) {
557133562Sharti		if (Parse_IsVar(*argv)) {
558140870Sharti			char *ptr = MAKEFLAGS_quote(*argv);
559167330Sfjoe			char *v = estrdup(*argv);
560133562Sharti
561146146Sharti			Var_Append(".MAKEFLAGS", ptr, VAR_GLOBAL);
562167330Sfjoe			Parse_DoVar(v, VAR_CMD);
563133562Sharti			free(ptr);
564167330Sfjoe			free(v);
565133562Sharti
566144896Sharti		} else if ((*argv)[0] == '-') {
567144896Sharti			if ((*argv)[1] == '\0') {
568144896Sharti				/*
569144896Sharti				 * (*argv) is a single dash, so we
570144896Sharti				 * just ignore it.
571144896Sharti				 */
572146038Sharti			} else if (found_dd) {
573146038Sharti				/*
574146038Sharti				 * Double dash has been found, ignore
575146038Sharti				 * any more options.  But what do we do
576146038Sharti				 * with it?  For now treat it like a target.
577146038Sharti				 */
578146038Sharti				Lst_AtEnd(&create, estrdup(*argv));
579144896Sharti			} else {
580144896Sharti				/*
581146038Sharti				 * (*argv) is a -flag, so backup argv and
582146038Sharti				 * argc.  getopt() expects options to start
583146038Sharti				 * in the 2nd position.
584144896Sharti				 */
585144896Sharti				argc++;
586144896Sharti				argv--;
5871590Srgrimes				goto rearg;
5881590Srgrimes			}
589144896Sharti
590144896Sharti		} else if ((*argv)[0] == '\0') {
591144896Sharti			Punt("illegal (null) argument.");
592144896Sharti
593144896Sharti		} else {
594138916Sharti			Lst_AtEnd(&create, estrdup(*argv));
5951590Srgrimes		}
596144896Sharti	}
5971590Srgrimes}
5981590Srgrimes
599144475Sharti/**
600144475Sharti * Main_ParseArgLine
601160442Sobrien *	Used by the parse module when a .MFLAGS or .MAKEFLAGS target
6021590Srgrimes *	is encountered and by main() when reading the .MAKEFLAGS envariable.
6031590Srgrimes *	Takes a line of arguments and breaks it into its
604160442Sobrien *	component words and passes those words and the number of them to the
6051590Srgrimes *	MainParseArgs function.
6061590Srgrimes *	The line should have all its leading whitespace removed.
6071590Srgrimes *
6081590Srgrimes * Side Effects:
6091590Srgrimes *	Only those that come from the various arguments.
6101590Srgrimes */
6111590Srgrimesvoid
612140870ShartiMain_ParseArgLine(char *line, int mflags)
6131590Srgrimes{
614146345Sharti	ArgArray	aa;
6151590Srgrimes
6161590Srgrimes	if (line == NULL)
6171590Srgrimes		return;
6181590Srgrimes	for (; *line == ' '; ++line)
6191590Srgrimes		continue;
6201590Srgrimes	if (!*line)
6211590Srgrimes		return;
6221590Srgrimes
623140870Sharti	if (mflags)
624146345Sharti		MAKEFLAGS_break(&aa, line);
625140870Sharti	else
626146345Sharti		brk_string(&aa, line, TRUE);
627140870Sharti
628146345Sharti	MainParseArgs(aa.argc, aa.argv);
629146345Sharti	ArgArray_Done(&aa);
6301590Srgrimes}
6311590Srgrimes
632146146Shartistatic char *
633141252Shartichdir_verify_path(const char *path, char *obpath)
63418339Sswallace{
63518339Sswallace	struct stat sb;
63618339Sswallace
63718339Sswallace	if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
63875973Sru		if (chdir(path) == -1 || getcwd(obpath, MAXPATHLEN) == NULL) {
63927644Scharnier			warn("warning: %s", path);
640141252Sharti			return (NULL);
64118339Sswallace		}
642138232Sharti		return (obpath);
64318339Sswallace	}
64418339Sswallace
645141252Sharti	return (NULL);
64618339Sswallace}
64718339Sswallace
648146144Sharti/**
649146144Sharti * In lieu of a good way to prevent every possible looping in make(1), stop
650146144Sharti * there from being more than MKLVL_MAXVAL processes forked by make(1), to
651146144Sharti * prevent a forkbomb from happening, in a dumb and mechanical way.
652146144Sharti *
653146144Sharti * Side Effects:
654146144Sharti *	Creates or modifies enviornment variable MKLVL_ENVVAR via setenv().
655138071Sjmallett */
656138071Sjmallettstatic void
657138071Sjmallettcheck_make_level(void)
658138071Sjmallett{
659138071Sjmallett#ifdef WANT_ENV_MKLVL
660138071Sjmallett	char	*value = getenv(MKLVL_ENVVAR);
661138071Sjmallett	int	level = (value == NULL) ? 0 : atoi(value);
662138071Sjmallett
663138071Sjmallett	if (level < 0) {
664144475Sharti		errc(2, EAGAIN, "Invalid value for recursion level (%d).",
665144475Sharti		    level);
666138071Sjmallett	} else if (level > MKLVL_MAXVAL) {
667144475Sharti		errc(2, EAGAIN, "Max recursion level (%d) exceeded.",
668144475Sharti		    MKLVL_MAXVAL);
669138071Sjmallett	} else {
670138071Sjmallett		char new_value[32];
671138071Sjmallett		sprintf(new_value, "%d", level + 1);
672138071Sjmallett		setenv(MKLVL_ENVVAR, new_value, 1);
673138071Sjmallett	}
674138071Sjmallett#endif /* WANT_ENV_MKLVL */
675138071Sjmallett}
676138071Sjmallett
677144475Sharti/**
678167330Sfjoe * Main_AddSourceMakefile
679167330Sfjoe *	Add a file to the list of source makefiles
680167330Sfjoe */
681167330Sfjoevoid
682167330SfjoeMain_AddSourceMakefile(const char *name)
683167330Sfjoe{
684167330Sfjoe
685167330Sfjoe	Lst_AtEnd(&source_makefiles, estrdup(name));
686167330Sfjoe}
687167330Sfjoe
688167330Sfjoe/**
689167330Sfjoe * Remake_Makefiles
690167330Sfjoe *	Remake all the makefiles
691167330Sfjoe */
692167330Sfjoestatic void
693167330SfjoeRemake_Makefiles(void)
694167330Sfjoe{
695167330Sfjoe	LstNode *ln;
696167330Sfjoe	int error_cnt = 0;
697167330Sfjoe	int remade_cnt = 0;
698167330Sfjoe
699167330Sfjoe	Compat_InstallSignalHandlers();
700170179Sfjoe	if (curdir != objdir) {
701170179Sfjoe		if (chdir(curdir) < 0)
702170179Sfjoe			Fatal("Failed to change directory to %s.", curdir);
703170179Sfjoe	}
704167330Sfjoe
705167330Sfjoe	LST_FOREACH(ln, &source_makefiles) {
706167330Sfjoe		LstNode *ln2;
707167330Sfjoe		struct GNode *gn;
708167330Sfjoe		const char *name = Lst_Datum(ln);
709167330Sfjoe		Boolean saveTouchFlag = touchFlag;
710167330Sfjoe		Boolean saveQueryFlag = queryFlag;
711167330Sfjoe		Boolean saveNoExecute = noExecute;
712168892Sfjoe		int mtime;
713167330Sfjoe
714167330Sfjoe		/*
715167330Sfjoe		 * Create node
716167330Sfjoe		 */
717167330Sfjoe		gn = Targ_FindNode(name, TARG_CREATE);
718167330Sfjoe		DEBUGF(MAKE, ("Checking %s...", gn->name));
719167330Sfjoe		Suff_FindDeps(gn);
720167330Sfjoe
721167330Sfjoe		/*
722167330Sfjoe		 * ! dependencies as well as
723167330Sfjoe		 * dependencies with .FORCE, .EXEC and .PHONY attributes
724167330Sfjoe		 * are skipped to prevent infinite loops
725167330Sfjoe		 */
726167330Sfjoe		if (gn->type & (OP_FORCE | OP_EXEC | OP_PHONY)) {
727167330Sfjoe			DEBUGF(MAKE, ("skipping (force, exec or phony).\n",
728167330Sfjoe			    gn->name));
729167330Sfjoe			continue;
730167330Sfjoe		}
731167330Sfjoe
732167330Sfjoe		/*
733167330Sfjoe		 * Skip :: targets that have commands and no children
734167330Sfjoe		 * because such targets are always out-of-date
735167330Sfjoe		 */
736167330Sfjoe		if ((gn->type & OP_DOUBLEDEP) &&
737167330Sfjoe		    !Lst_IsEmpty(&gn->commands) &&
738167330Sfjoe		    Lst_IsEmpty(&gn->children)) {
739167330Sfjoe			DEBUGF(MAKE, ("skipping (doubledep, no sources "
740167330Sfjoe			    "and has commands).\n"));
741167330Sfjoe			continue;
742167330Sfjoe		}
743167330Sfjoe
744167330Sfjoe		/*
745167330Sfjoe		 * Skip targets without sources and without commands
746167330Sfjoe		 */
747167330Sfjoe		if (Lst_IsEmpty(&gn->commands) &&
748167330Sfjoe		    Lst_IsEmpty(&gn->children)) {
749167330Sfjoe			DEBUGF(MAKE,
750167330Sfjoe			    ("skipping (no sources and no commands).\n"));
751167330Sfjoe			continue;
752167330Sfjoe		}
753167330Sfjoe
754167330Sfjoe		DEBUGF(MAKE, ("\n"));
755167330Sfjoe
756167330Sfjoe		/*
757167330Sfjoe		 * -t, -q and -n has no effect unless the makefile is
758167330Sfjoe		 * specified as one of the targets explicitly in the
759167330Sfjoe		 * command line
760167330Sfjoe		 */
761167330Sfjoe		LST_FOREACH(ln2, &create) {
762167330Sfjoe			if (!strcmp(gn->name, Lst_Datum(ln2))) {
763167330Sfjoe				/* found as a target */
764167330Sfjoe				break;
765167330Sfjoe			}
766167330Sfjoe		}
767167330Sfjoe		if (ln2 == NULL) {
768167330Sfjoe			touchFlag = FALSE;
769167330Sfjoe			queryFlag = FALSE;
770167330Sfjoe			noExecute = FALSE;
771167330Sfjoe		}
772167330Sfjoe
773167330Sfjoe		/*
774167330Sfjoe		 * Check and remake the makefile
775167330Sfjoe		 */
776168892Sfjoe		mtime = Dir_MTime(gn);
777167330Sfjoe		Compat_Make(gn, gn);
778167330Sfjoe
779167330Sfjoe		/*
780167330Sfjoe		 * Restore -t, -q and -n behaviour
781167330Sfjoe		 */
782167330Sfjoe		touchFlag = saveTouchFlag;
783167330Sfjoe		queryFlag = saveQueryFlag;
784167330Sfjoe		noExecute = saveNoExecute;
785167330Sfjoe
786167330Sfjoe		/*
787167330Sfjoe		 * Compat_Make will leave the 'made' field of gn
788167330Sfjoe		 * in one of the following states:
789167330Sfjoe		 *	UPTODATE  gn was already up-to-date
790167330Sfjoe		 *	MADE	  gn was recreated successfully
791167330Sfjoe		 *	ERROR	  An error occurred while gn was being created
792167330Sfjoe		 *	ABORTED	  gn was not remade because one of its inferiors
793167330Sfjoe		 *		  could not be made due to errors.
794167330Sfjoe		 */
795168892Sfjoe		if (gn->made == MADE) {
796168892Sfjoe			if (mtime != Dir_MTime(gn)) {
797168892Sfjoe				DEBUGF(MAKE,
798168892Sfjoe				    ("%s updated (%d -> %d).\n",
799168892Sfjoe				     gn->name, mtime, gn->mtime));
800168892Sfjoe				remade_cnt++;
801168892Sfjoe			} else {
802168892Sfjoe				DEBUGF(MAKE,
803168892Sfjoe				    ("%s not updated: skipping restart.\n",
804168892Sfjoe				     gn->name));
805168892Sfjoe			}
806168892Sfjoe		} else if (gn->made == ERROR)
807167330Sfjoe			error_cnt++;
808167330Sfjoe		else if (gn->made == ABORTED) {
809167330Sfjoe			printf("`%s' not remade because of errors.\n",
810167330Sfjoe			    gn->name);
811167330Sfjoe			error_cnt++;
812173919Sfjoe		} else if (gn->made == UPTODATE) {
813173919Sfjoe			Lst examine;
814173919Sfjoe
815173919Sfjoe			Lst_Init(&examine);
816173919Sfjoe			Lst_EnQueue(&examine, gn);
817173919Sfjoe			while (!Lst_IsEmpty(&examine)) {
818173919Sfjoe				LstNode	*eln;
819173919Sfjoe				GNode *egn = Lst_DeQueue(&examine);
820173919Sfjoe
821173919Sfjoe				egn->make = FALSE;
822173919Sfjoe				LST_FOREACH(eln, &egn->children) {
823173919Sfjoe					GNode *cgn = Lst_Datum(eln);
824173919Sfjoe
825173919Sfjoe					Lst_EnQueue(&examine, cgn);
826173919Sfjoe				}
827173919Sfjoe			}
828167330Sfjoe		}
829167330Sfjoe	}
830167330Sfjoe
831167330Sfjoe	if (error_cnt > 0)
832167330Sfjoe		Fatal("Failed to remake Makefiles.");
833167330Sfjoe	if (remade_cnt > 0) {
834167330Sfjoe		DEBUGF(MAKE, ("Restarting `%s'.\n", save_argv[0]));
835167330Sfjoe
836167330Sfjoe		/*
837167330Sfjoe		 * Some of makefiles were remade -- restart from clean state
838167330Sfjoe		 */
839167330Sfjoe		if (save_makeflags != NULL)
840167330Sfjoe			setenv("MAKEFLAGS", save_makeflags, 1);
841167330Sfjoe		else
842167330Sfjoe			unsetenv("MAKEFLAGS");
843167330Sfjoe		if (execvp(save_argv[0], save_argv) < 0) {
844167330Sfjoe			Fatal("Can't restart `%s': %s.",
845167330Sfjoe			    save_argv[0], strerror(errno));
846167330Sfjoe		}
847167330Sfjoe	}
848170179Sfjoe
849170179Sfjoe	if (curdir != objdir) {
850170179Sfjoe		if (chdir(objdir) < 0)
851170179Sfjoe			Fatal("Failed to change directory to %s.", objdir);
852170179Sfjoe	}
853167330Sfjoe}
854167330Sfjoe
855167330Sfjoe/**
856144475Sharti * main
8571590Srgrimes *	The main function, for obvious reasons. Initializes variables
8581590Srgrimes *	and a few modules, then parses the arguments give it in the
8591590Srgrimes *	environment and on the command line. Reads the system makefile
8601590Srgrimes *	followed by either Makefile, makefile or the file given by the
8611590Srgrimes *	-f argument. Sets the .MAKEFLAGS PMake variable based on all the
8621590Srgrimes *	flags it has received by then uses either the Make or the Compat
8631590Srgrimes *	module to create the initial list of targets.
8641590Srgrimes *
8651590Srgrimes * Results:
8661590Srgrimes *	If -q was given, exits -1 if anything was out-of-date. Else it exits
8671590Srgrimes *	0.
8681590Srgrimes *
8691590Srgrimes * Side Effects:
8701590Srgrimes *	The program exits when done. Targets are created. etc. etc. etc.
8711590Srgrimes */
8721590Srgrimesint
873104696Sjmallettmain(int argc, char **argv)
8741590Srgrimes{
875160442Sobrien	const char *machine;
876146144Sharti	const char *machine_arch;
877146144Sharti	const char *machine_cpu;
878160442Sobrien	Boolean outOfDate = TRUE;	/* FALSE if all targets up to date */
879146581Sharti	const char *p;
880146157Sharti	const char *pathp;
881146157Sharti	const char *path;
88273262Simp	char mdpath[MAXPATHLEN];
88373262Simp	char obpath[MAXPATHLEN];
88473262Simp	char cdpath[MAXPATHLEN];
88518730Ssteve	char *cp = NULL, *start;
886141252Sharti
887167330Sfjoe	save_argv = argv;
888167330Sfjoe	save_makeflags = getenv("MAKEFLAGS");
889167330Sfjoe	if (save_makeflags != NULL)
890167330Sfjoe		save_makeflags = estrdup(save_makeflags);
891167330Sfjoe
892146146Sharti	/*
893146146Sharti	 * Initialize file global variables.
894146146Sharti	 */
895146146Sharti	expandVars = TRUE;
896146146Sharti	noBuiltins = FALSE;		/* Read the built-in rules */
897160442Sobrien	forceJobs = FALSE;		/* No -j flag */
898146146Sharti	curdir = cdpath;
899146146Sharti
900146146Sharti	/*
901146146Sharti	 * Initialize program global variables.
902146146Sharti	 */
903146146Sharti	beSilent = FALSE;		/* Print commands as executed */
904146146Sharti	ignoreErrors = FALSE;		/* Pay attention to non-zero returns */
905146146Sharti	noExecute = FALSE;		/* Execute all commands */
906146146Sharti	keepgoing = FALSE;		/* Stop on error */
907146146Sharti	allPrecious = FALSE;		/* Remove targets when interrupted */
908146146Sharti	queryFlag = FALSE;		/* This is not just a check-run */
909146146Sharti	touchFlag = FALSE;		/* Actually update targets */
910146146Sharti	usePipes = TRUE;		/* Catch child output in pipes */
911146146Sharti	debug = 0;			/* No debug verbosity, please. */
912146146Sharti	jobsRunning = FALSE;
913146146Sharti
914146146Sharti	jobLimit = DEFMAXJOBS;
915146146Sharti	compatMake = FALSE;		/* No compat mode */
916146146Sharti
917138071Sjmallett	check_make_level();
918104395Sjmallett
91918730Ssteve#ifdef RLIMIT_NOFILE
9201590Srgrimes	/*
92118730Ssteve	 * get rid of resource limit on file descriptors
92218730Ssteve	 */
92318730Ssteve	{
92418730Ssteve		struct rlimit rl;
925146144Sharti		if (getrlimit(RLIMIT_NOFILE, &rl) == -1) {
926146144Sharti			err(2, "getrlimit");
92718730Ssteve		}
928146144Sharti		rl.rlim_cur = rl.rlim_max;
929146144Sharti		if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
930146144Sharti			err(2, "setrlimit");
931146144Sharti		}
93218730Ssteve	}
93318730Ssteve#endif
9341590Srgrimes
9355814Sjkh	/*
936176786Simp	 * Prior to 7.0, FreeBSD/pc98 kernel used to set the
937176786Simp	 * utsname.machine to "i386", and MACHINE was defined as
938176786Simp	 * "i386", so it could not be distinguished from FreeBSD/i386.
939176786Simp	 * Therefore, we had to check machine.ispc98 and adjust the
940176786Simp	 * MACHINE variable.  NOTE: The code is still here to be able
941176786Simp	 * to compile new make binary on old FreeBSD/pc98 systems, and
942176786Simp	 * have the MACHINE variable set properly.
94339006Skato	 */
944146157Sharti	if ((machine = getenv("MACHINE")) == NULL) {
94539006Skato		int	ispc98;
94639006Skato		size_t	len;
94739006Skato
94839006Skato		len = sizeof(ispc98);
94939006Skato		if (!sysctlbyname("machdep.ispc98", &ispc98, &len, NULL, 0)) {
95039006Skato			if (ispc98)
95139006Skato				machine = "pc98";
95239006Skato		}
95339006Skato	}
95439006Skato
95539006Skato	/*
9565814Sjkh	 * Get the name of this type of MACHINE from utsname
9575814Sjkh	 * so we can share an executable for similar machines.
9585814Sjkh	 * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
9595814Sjkh	 *
960153115Sru	 * Note that both MACHINE and MACHINE_ARCH are decided at
961153115Sru	 * run-time.
9625814Sjkh	 */
963146157Sharti	if (machine == NULL) {
964144475Sharti		static struct utsname utsname;
96518730Ssteve
966144475Sharti		if (uname(&utsname) == -1)
967144475Sharti			err(2, "uname");
968144475Sharti		machine = utsname.machine;
9695814Sjkh	}
9701590Srgrimes
971146144Sharti	if ((machine_arch = getenv("MACHINE_ARCH")) == NULL) {
972146144Sharti#ifdef MACHINE_ARCH
973146144Sharti		machine_arch = MACHINE_ARCH;
974146144Sharti#else
97544362Simp		machine_arch = "unknown";
97644362Simp#endif
97744362Simp	}
97844362Simp
9791590Srgrimes	/*
98072679Skris	 * Set machine_cpu to the minumum supported CPU revision based
98172679Skris	 * on the target architecture, if not already set.
98272679Skris	 */
983146144Sharti	if ((machine_cpu = getenv("MACHINE_CPU")) == NULL) {
98472679Skris		if (!strcmp(machine_arch, "i386"))
98572679Skris			machine_cpu = "i386";
98672679Skris		else if (!strcmp(machine_arch, "alpha"))
98772679Skris			machine_cpu = "ev4";
98872679Skris		else
98972679Skris			machine_cpu = "unknown";
99072679Skris	}
9911590Srgrimes
9921590Srgrimes	/*
9931590Srgrimes	 * Initialize the parsing, directory and variable modules to prepare
9941590Srgrimes	 * for the reading of inclusion paths and variable settings on the
9951590Srgrimes	 * command line
9961590Srgrimes	 */
997146144Sharti	Proc_Init();
998146144Sharti
9991590Srgrimes	Dir_Init();		/* Initialize directory structures so -I flags
10001590Srgrimes				 * can be processed correctly */
1001145971Sharti	Var_Init(environ);	/* As well as the lists of variables for
10021590Srgrimes				 * parsing arguments */
1003146560Sharti
10041590Srgrimes	/*
1005146560Sharti	 * Initialize the Shell so that we have a shell for != assignments
1006146560Sharti	 * on the command line.
1007146560Sharti	 */
1008146560Sharti	Shell_Init();
1009146560Sharti
1010146560Sharti	/*
10111590Srgrimes	 * Initialize various variables.
10121590Srgrimes	 *	MAKE also gets this name, for compatibility
10131590Srgrimes	 *	.MAKEFLAGS gets set to the empty string just in case.
10141590Srgrimes	 *	MFLAGS also gets initialized empty, for compatibility.
10151590Srgrimes	 */
1016146145Sharti	Var_SetGlobal("MAKE", argv[0]);
1017146146Sharti	Var_SetGlobal(".MAKEFLAGS", "");
1018146145Sharti	Var_SetGlobal("MFLAGS", "");
1019146145Sharti	Var_SetGlobal("MACHINE", machine);
1020146145Sharti	Var_SetGlobal("MACHINE_ARCH", machine_arch);
1021146145Sharti	Var_SetGlobal("MACHINE_CPU", machine_cpu);
102297121Sru#ifdef MAKE_VERSION
1023146145Sharti	Var_SetGlobal("MAKE_VERSION", MAKE_VERSION);
102497121Sru#endif
10251590Srgrimes
10261590Srgrimes	/*
1027144896Sharti	 * First snag things out of the MAKEFLAGS environment
1028144896Sharti	 * variable.  Then parse the command line arguments.
10291590Srgrimes	 */
1030140870Sharti	Main_ParseArgLine(getenv("MAKEFLAGS"), 1);
10318874Srgrimes
10321590Srgrimes	MainParseArgs(argc, argv);
10331590Srgrimes
10341590Srgrimes	/*
1035120053Sru	 * Find where we are...
1036120053Sru	 */
1037120053Sru	if (getcwd(curdir, MAXPATHLEN) == NULL)
1038120053Sru		err(2, NULL);
1039120053Sru
1040141252Sharti	{
1041141252Sharti	struct stat sa;
1042141252Sharti
1043120053Sru	if (stat(curdir, &sa) == -1)
1044120053Sru	    err(2, "%s", curdir);
1045141252Sharti	}
1046120053Sru
1047120053Sru	/*
1048120053Sru	 * The object directory location is determined using the
1049120053Sru	 * following order of preference:
1050120053Sru	 *
1051120053Sru	 *	1. MAKEOBJDIRPREFIX`cwd`
1052120053Sru	 *	2. MAKEOBJDIR
1053143412Sharti	 *	3. PATH_OBJDIR.${MACHINE}
1054143412Sharti	 *	4. PATH_OBJDIR
1055143412Sharti	 *	5. PATH_OBJDIRPREFIX`cwd`
1056120053Sru	 *
1057120053Sru	 * If one of the first two fails, use the current directory.
1058120053Sru	 * If the remaining three all fail, use the current directory.
1059120053Sru	 *
1060120053Sru	 * Once things are initted,
1061120053Sru	 * have to add the original directory to the search path,
1062120053Sru	 * and modify the paths for the Makefiles apropriately.  The
1063120053Sru	 * current directory is also placed as a variable for make scripts.
1064120053Sru	 */
1065120053Sru	if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
1066120053Sru		if (!(path = getenv("MAKEOBJDIR"))) {
1067143412Sharti			path = PATH_OBJDIR;
1068143412Sharti			pathp = PATH_OBJDIRPREFIX;
1069146145Sharti			snprintf(mdpath, MAXPATHLEN, "%s.%s", path, machine);
1070120053Sru			if (!(objdir = chdir_verify_path(mdpath, obpath)))
1071120053Sru				if (!(objdir=chdir_verify_path(path, obpath))) {
1072138232Sharti					snprintf(mdpath, MAXPATHLEN,
1073120053Sru							"%s%s", pathp, curdir);
1074120053Sru					if (!(objdir=chdir_verify_path(mdpath,
1075120053Sru								       obpath)))
1076120053Sru						objdir = curdir;
1077120053Sru				}
1078120053Sru		}
1079120053Sru		else if (!(objdir = chdir_verify_path(path, obpath)))
1080120053Sru			objdir = curdir;
1081120053Sru	}
1082120053Sru	else {
1083138232Sharti		snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
1084120053Sru		if (!(objdir = chdir_verify_path(mdpath, obpath)))
1085120053Sru			objdir = curdir;
1086120053Sru	}
1087120053Sru	Dir_InitDot();		/* Initialize the "." directory */
1088120053Sru	if (objdir != curdir)
1089144020Sharti		Path_AddDir(&dirSearchPath, curdir);
1090146145Sharti	Var_SetGlobal(".ST_EXPORTVAR", "YES");
1091146145Sharti	Var_SetGlobal(".CURDIR", curdir);
1092146145Sharti	Var_SetGlobal(".OBJDIR", objdir);
1093120053Sru
1094137606Sphk	if (getenv("MAKE_JOBS_FIFO") != NULL)
1095137606Sphk		forceJobs = TRUE;
1096120053Sru	/*
109728228Sfsmp	 * Be compatible if user did not specify -j and did not explicitly
109828228Sfsmp	 * turned compatibility on
109928228Sfsmp	 */
110028228Sfsmp	if (!compatMake && !forceJobs)
110128228Sfsmp		compatMake = TRUE;
110228228Sfsmp
110328228Sfsmp	/*
1104144387Sharti	 * Initialize target and suffix modules in preparation for
11051590Srgrimes	 * parsing the makefile(s)
11061590Srgrimes	 */
11071590Srgrimes	Targ_Init();
11081590Srgrimes	Suff_Init();
11091590Srgrimes
111069527Swill	DEFAULT = NULL;
1111138232Sharti	time(&now);
11121590Srgrimes
11131590Srgrimes	/*
11141590Srgrimes	 * Set up the .TARGETS variable to contain the list of targets to be
11151590Srgrimes	 * created. If none specified, make the variable empty -- the parser
11161590Srgrimes	 * will fill the thing in with the default or .MAIN target.
11171590Srgrimes	 */
1118146145Sharti	if (Lst_IsEmpty(&create)) {
1119146145Sharti		Var_SetGlobal(".TARGETS", "");
1120146145Sharti	} else {
1121138512Sharti		LstNode *ln;
11221590Srgrimes
1123138916Sharti		for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) {
1124138264Sharti			char *name = Lst_Datum(ln);
11251590Srgrimes
11261590Srgrimes			Var_Append(".TARGETS", name, VAR_GLOBAL);
11271590Srgrimes		}
1128146145Sharti	}
11291590Srgrimes
113018730Ssteve
11311590Srgrimes	/*
113218730Ssteve	 * If no user-supplied system path was given (through the -m option)
113318730Ssteve	 * add the directories from the DEFSYSPATH (more than one may be given
113418730Ssteve	 * as dir1:...:dirn) to the system include path.
11351590Srgrimes	 */
1136144020Sharti	if (TAILQ_EMPTY(&sysIncPath)) {
1137146144Sharti		char syspath[] = PATH_DEFSYSPATH;
1138146144Sharti
113918730Ssteve		for (start = syspath; *start != '\0'; start = cp) {
114018730Ssteve			for (cp = start; *cp != '\0' && *cp != ':'; cp++)
114118730Ssteve				continue;
114218730Ssteve			if (*cp == '\0') {
1143144020Sharti				Path_AddDir(&sysIncPath, start);
114418730Ssteve			} else {
114518730Ssteve				*cp++ = '\0';
1146144020Sharti				Path_AddDir(&sysIncPath, start);
114718730Ssteve			}
114818730Ssteve		}
114918730Ssteve	}
11501590Srgrimes
115118730Ssteve	/*
115218730Ssteve	 * Read in the built-in rules first, followed by the specified
115318730Ssteve	 * makefile, if it was (makefile != (char *) NULL), or the default
115418730Ssteve	 * Makefile and makefile, in that order, if it wasn't.
115518730Ssteve	 */
115618730Ssteve	if (!noBuiltins) {
1157138916Sharti		/* Path of sys.mk */
1158138916Sharti		Lst sysMkPath = Lst_Initializer(sysMkPath);
1159138512Sharti		LstNode *ln;
1160146064Sharti		char	defsysmk[] = PATH_DEFSYSMK;
116118730Ssteve
1162146064Sharti		Path_Expand(defsysmk, &sysIncPath, &sysMkPath);
1163138916Sharti		if (Lst_IsEmpty(&sysMkPath))
1164143412Sharti			Fatal("make: no system rules (%s).", PATH_DEFSYSMK);
1165143808Sharti		LST_FOREACH(ln, &sysMkPath) {
1166143808Sharti			if (!ReadMakefile(Lst_Datum(ln)))
1167143808Sharti				break;
1168143808Sharti		}
116969527Swill		if (ln != NULL)
117018730Ssteve			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
1171138916Sharti		Lst_Destroy(&sysMkPath, free);
117218730Ssteve	}
117318730Ssteve
1174138916Sharti	if (!Lst_IsEmpty(&makefiles)) {
1175138512Sharti		LstNode *ln;
11761590Srgrimes
1177143808Sharti		LST_FOREACH(ln, &makefiles) {
1178167330Sfjoe			if (!TryReadMakefile(Lst_Datum(ln)))
1179143808Sharti				break;
1180143808Sharti		}
118169527Swill		if (ln != NULL)
11821590Srgrimes			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
1183167330Sfjoe	} else if (!TryReadMakefile("BSDmakefile"))
1184167330Sfjoe	    if (!TryReadMakefile("makefile"))
1185167330Sfjoe		TryReadMakefile("Makefile");
11861590Srgrimes
1187143808Sharti	ReadMakefile(".depend");
11881590Srgrimes
1189176842Syar	/* Install all the flags into the MAKEFLAGS envariable. */
1190146580Sharti	if (((p = Var_Value(".MAKEFLAGS", VAR_GLOBAL)) != NULL) && *p)
11911590Srgrimes		setenv("MAKEFLAGS", p, 1);
1192176839Syar	else
1193176839Syar		setenv("MAKEFLAGS", "", 1);
11941590Srgrimes
11951590Srgrimes	/*
11961590Srgrimes	 * For compatibility, look at the directories in the VPATH variable
11971590Srgrimes	 * and add them to the search path, if the variable is defined. The
11981590Srgrimes	 * variable's value is in the same format as the PATH envariable, i.e.
11991590Srgrimes	 * <directory>:<directory>:<directory>...
12001590Srgrimes	 */
12011590Srgrimes	if (Var_Exists("VPATH", VAR_CMD)) {
12021590Srgrimes		/*
12031590Srgrimes		 * GCC stores string constants in read-only memory, but
12041590Srgrimes		 * Var_Subst will want to write this thing, so store it
12051590Srgrimes		 * in an array
12061590Srgrimes		 */
12071590Srgrimes		static char VPATH[] = "${VPATH}";
1208142457Sharti		Buffer	*buf;
1209142457Sharti		char	*vpath;
1210142457Sharti		char	*ptr;
1211142457Sharti		char	savec;
12121590Srgrimes
1213146027Sharti		buf = Var_Subst(VPATH, VAR_CMD, FALSE);
1214142457Sharti
1215143959Sharti		vpath = Buf_Data(buf);
12161590Srgrimes		do {
12171590Srgrimes			/* skip to end of directory */
1218142457Sharti			for (ptr = vpath; *ptr != ':' && *ptr != '\0'; ptr++)
1219141969Sharti				;
1220141969Sharti
12211590Srgrimes			/* Save terminator character so know when to stop */
1222141969Sharti			savec = *ptr;
1223141969Sharti			*ptr = '\0';
1224141969Sharti
12251590Srgrimes			/* Add directory to search path */
1226144020Sharti			Path_AddDir(&dirSearchPath, vpath);
1227141969Sharti
1228142457Sharti			vpath = ptr + 1;
1229141969Sharti		} while (savec != '\0');
1230142457Sharti
1231142457Sharti		Buf_Destroy(buf, TRUE);
12321590Srgrimes	}
12331590Srgrimes
12341590Srgrimes	/*
12351590Srgrimes	 * Now that all search paths have been read for suffixes et al, it's
12361590Srgrimes	 * time to add the default search path to their lists...
12371590Srgrimes	 */
12381590Srgrimes	Suff_DoPaths();
12391590Srgrimes
12401590Srgrimes	/* print the initial graph, if the user requested it */
12411590Srgrimes	if (DEBUG(GRAPH1))
12421590Srgrimes		Targ_PrintGraph(1);
12431590Srgrimes
124417193Sbde	/* print the values of any variables requested by the user */
1245141974Sharti	if (Lst_IsEmpty(&variables)) {
12461590Srgrimes		/*
1247141974Sharti		 * Since the user has not requested that any variables
1248142008Sharti		 * be printed, we can build targets.
1249141974Sharti		 *
1250142008Sharti		 * Have read the entire graph and need to make a list of targets
1251141974Sharti		 * to create. If none was given on the command line, we consult
1252141974Sharti		 * the parsing module to find the main target(s) to create.
12531590Srgrimes		 */
1254138916Sharti		Lst targs = Lst_Initializer(targs);
1255138916Sharti
1256177101Sobrien		if (!is_posix && mfAutoDeps) {
1257167330Sfjoe			/*
1258167330Sfjoe			 * Check if any of the makefiles are out-of-date.
1259167330Sfjoe			 */
1260167330Sfjoe			Remake_Makefiles();
1261167330Sfjoe		}
1262167330Sfjoe
1263138916Sharti		if (Lst_IsEmpty(&create))
1264138916Sharti			Parse_MainName(&targs);
1265101460Sru		else
1266138916Sharti			Targ_FindList(&targs, &create, TARG_CREATE);
1267101460Sru
1268141974Sharti		if (compatMake) {
1269101460Sru			/*
1270141974Sharti			 * Compat_Init will take care of creating
1271141974Sharti			 * all the targets as well as initializing
1272141974Sharti			 * the module.
1273101460Sru			 */
1274141974Sharti			Compat_Run(&targs);
1275141974Sharti			outOfDate = 0;
1276141974Sharti		} else {
1277141974Sharti			/*
1278141974Sharti			 * Initialize job module before traversing
1279141974Sharti			 * the graph, now that any .BEGIN and .END
1280141974Sharti			 * targets have been read.  This is done
1281141974Sharti			 * only if the -q flag wasn't given (to
1282141974Sharti			 * prevent the .BEGIN from being executed
1283141974Sharti			 * should it exist).
1284141974Sharti			 */
1285101460Sru			if (!queryFlag) {
1286146140Sharti				Job_Init(jobLimit);
1287101460Sru				jobsRunning = TRUE;
1288101460Sru			}
1289101460Sru
1290101460Sru			/* Traverse the graph, checking on all the targets */
1291138916Sharti			outOfDate = Make_Run(&targs);
12921590Srgrimes		}
1293138916Sharti		Lst_Destroy(&targs, NOFREE);
1294141974Sharti
1295141974Sharti	} else {
1296146141Sharti		Var_Print(&variables, expandVars);
129717193Sbde	}
12988874Srgrimes
1299138920Sru	Lst_Destroy(&variables, free);
1300138920Sru	Lst_Destroy(&makefiles, free);
1301167330Sfjoe	Lst_Destroy(&source_makefiles, free);
1302138916Sharti	Lst_Destroy(&create, free);
13035814Sjkh
13041590Srgrimes	/* print the graph now it's been processed if the user requested it */
13051590Srgrimes	if (DEBUG(GRAPH2))
13061590Srgrimes		Targ_PrintGraph(2);
13071590Srgrimes
13081590Srgrimes	if (queryFlag && outOfDate)
1309138232Sharti		return (1);
13101590Srgrimes	else
1311138232Sharti		return (0);
13121590Srgrimes}
13131590Srgrimes
1314