main.c revision 201526
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 201526 2010-01-04 18:57:22Z 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 */
127190821SfjoeBoolean		remakingMakefiles; /* True if remaking makefiles is in progress */
128146146ShartiBoolean		beSilent;	/* -s flag */
129146146ShartiBoolean		beVerbose;	/* -v flag */
130187132SobrienBoolean		beQuiet;	/* -Q flag */
131144475ShartiBoolean		compatMake;	/* -B argument */
132149844Shartiint		debug;		/* -d flag */
133146146ShartiBoolean		ignoreErrors;	/* -i flag */
134146146Shartiint		jobLimit;	/* -j argument */
135186279Sfjoeint		makeErrors;	/* Number of targets not remade due to errors */
136146146ShartiBoolean		jobsRunning;	/* TRUE if the jobs might be running */
137146146ShartiBoolean		keepgoing;	/* -k flag */
138144475ShartiBoolean		noExecute;	/* -n flag */
139181021SedBoolean		printGraphOnly;	/* -p flag */
140144475ShartiBoolean		queryFlag;	/* -q flag */
141144475ShartiBoolean		touchFlag;	/* -t flag */
142144475ShartiBoolean		usePipes;	/* !-P flag */
143146146Shartiuint32_t	warn_cmd;	/* command line warning flags */
144146146Shartiuint32_t	warn_flags;	/* actual warning flags */
145146146Shartiuint32_t	warn_nocmd;	/* command line no-warning flags */
146138916Sharti
147146146Shartitime_t		now;		/* Time at start of make */
148146146Shartistruct GNode	*DEFAULT;	/* .DEFAULT node */
149138916Sharti
150144475Sharti/**
151146143Sharti * Exit with usage message.
152146143Sharti */
153146143Shartistatic void
154146143Shartiusage(void)
155146143Sharti{
156146143Sharti	fprintf(stderr,
157181021Sed	    "usage: make [-BPSXeiknpqrstv] [-C directory] [-D variable]\n"
158146143Sharti	    "\t[-d flags] [-E variable] [-f makefile] [-I directory]\n"
159146143Sharti	    "\t[-j max_jobs] [-m directory] [-V variable]\n"
160146143Sharti	    "\t[variable=value] [target ...]\n");
161146143Sharti	exit(2);
162146143Sharti}
163146143Sharti
164146143Sharti/**
165144475Sharti * MFLAGS_append
166144475Sharti *	Append a flag with an optional argument to MAKEFLAGS and MFLAGS
167133085Sharti */
168133085Shartistatic void
169141252ShartiMFLAGS_append(const char *flag, char *arg)
170133085Sharti{
171140870Sharti	char *str;
172138232Sharti
173146146Sharti	Var_Append(".MAKEFLAGS", flag, VAR_GLOBAL);
174140870Sharti	if (arg != NULL) {
175140870Sharti		str = MAKEFLAGS_quote(arg);
176146146Sharti		Var_Append(".MAKEFLAGS", str, VAR_GLOBAL);
177140870Sharti		free(str);
178140870Sharti	}
179133085Sharti
180133085Sharti	Var_Append("MFLAGS", flag, VAR_GLOBAL);
181140870Sharti	if (arg != NULL) {
182140870Sharti		str = MAKEFLAGS_quote(arg);
183140870Sharti		Var_Append("MFLAGS", str, VAR_GLOBAL);
184140870Sharti		free(str);
185140870Sharti	}
186133085Sharti}
187133085Sharti
188144475Sharti/**
189145679Sharti * Main_ParseWarn
190145679Sharti *
191145679Sharti *	Handle argument to warning option.
192145679Sharti */
193145679Shartiint
194145679ShartiMain_ParseWarn(const char *arg, int iscmd)
195145679Sharti{
196145679Sharti	int i, neg;
197145679Sharti
198145679Sharti	static const struct {
199145679Sharti		const char	*option;
200145679Sharti		uint32_t	flag;
201145679Sharti	} options[] = {
202145679Sharti		{ "dirsyntax",	WARN_DIRSYNTAX },
203145679Sharti		{ NULL,		0 }
204145679Sharti	};
205145679Sharti
206145679Sharti	neg = 0;
207145679Sharti	if (arg[0] == 'n' && arg[1] == 'o') {
208145679Sharti		neg = 1;
209145679Sharti		arg += 2;
210145679Sharti	}
211145679Sharti
212145679Sharti	for (i = 0; options[i].option != NULL; i++)
213145679Sharti		if (strcmp(arg, options[i].option) == 0)
214145679Sharti			break;
215145679Sharti
216145679Sharti	if (options[i].option == NULL)
217145679Sharti		/* unknown option */
218145679Sharti		return (-1);
219145679Sharti
220145679Sharti	if (iscmd) {
221145679Sharti		if (!neg) {
222145679Sharti			warn_cmd |= options[i].flag;
223145679Sharti			warn_nocmd &= ~options[i].flag;
224145679Sharti			warn_flags |= options[i].flag;
225145679Sharti		} else {
226145679Sharti			warn_nocmd |= options[i].flag;
227145679Sharti			warn_cmd &= ~options[i].flag;
228145679Sharti			warn_flags &= ~options[i].flag;
229145679Sharti		}
230145679Sharti	} else {
231145679Sharti		if (!neg) {
232145679Sharti			warn_flags |= (options[i].flag & ~warn_nocmd);
233145679Sharti		} else {
234145679Sharti			warn_flags &= ~(options[i].flag | warn_cmd);
235145679Sharti		}
236145679Sharti	}
237145679Sharti	return (0);
238145679Sharti}
239145679Sharti
240145679Sharti/**
241146143Sharti * Open and parse the given makefile.
242146143Sharti *
243146143Sharti * Results:
244146143Sharti *	TRUE if ok. FALSE if couldn't open file.
245146143Sharti */
246146143Shartistatic Boolean
247146143ShartiReadMakefile(const char p[])
248146143Sharti{
249152982Sdavidxu	char *fname, *fnamesave;	/* makefile to read */
250146143Sharti	FILE *stream;
251146143Sharti	char *name, path[MAXPATHLEN];
252146143Sharti	char *MAKEFILE;
253146143Sharti	int setMAKEFILE;
254146143Sharti
255146143Sharti	/* XXX - remove this once constification is done */
256152982Sdavidxu	fnamesave = fname = estrdup(p);
257146143Sharti
258146143Sharti	if (!strcmp(fname, "-")) {
259146143Sharti		Parse_File("(stdin)", stdin);
260146145Sharti		Var_SetGlobal("MAKEFILE", "");
261146143Sharti	} else {
262146143Sharti		setMAKEFILE = strcmp(fname, ".depend");
263146143Sharti
264146143Sharti		/* if we've chdir'd, rebuild the path name */
265146143Sharti		if (curdir != objdir && *fname != '/') {
266146143Sharti			snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname);
267146143Sharti			/*
268146143Sharti			 * XXX The realpath stuff breaks relative includes
269146143Sharti			 * XXX in some cases.   The problem likely is in
270146143Sharti			 * XXX parse.c where it does special things in
271146143Sharti			 * XXX ParseDoInclude if the file is relateive
272146143Sharti			 * XXX or absolute and not a system file.  There
273146143Sharti			 * XXX it assumes that if the current file that's
274146143Sharti			 * XXX being included is absolute, that any files
275146143Sharti			 * XXX that it includes shouldn't do the -I path
276146143Sharti			 * XXX stuff, which is inconsistant with historical
277146143Sharti			 * XXX behavior.  However, I can't pentrate the mists
278146143Sharti			 * XXX further, so I'm putting this workaround in
279146143Sharti			 * XXX here until such time as the underlying bug
280146143Sharti			 * XXX can be fixed.
281146143Sharti			 */
282146143Sharti#if THIS_BREAKS_THINGS
283146143Sharti			if (realpath(path, path) != NULL &&
284146143Sharti			    (stream = fopen(path, "r")) != NULL) {
285146143Sharti				MAKEFILE = fname;
286146143Sharti				fname = path;
287146143Sharti				goto found;
288146143Sharti			}
289146143Sharti		} else if (realpath(fname, path) != NULL) {
290146143Sharti			MAKEFILE = fname;
291146143Sharti			fname = path;
292146143Sharti			if ((stream = fopen(fname, "r")) != NULL)
293146143Sharti				goto found;
294146143Sharti		}
295146143Sharti#else
296146143Sharti			if ((stream = fopen(path, "r")) != NULL) {
297146143Sharti				MAKEFILE = fname;
298146143Sharti				fname = path;
299146143Sharti				goto found;
300146143Sharti			}
301146143Sharti		} else {
302146143Sharti			MAKEFILE = fname;
303146143Sharti			if ((stream = fopen(fname, "r")) != NULL)
304146143Sharti				goto found;
305146143Sharti		}
306146143Sharti#endif
307146143Sharti		/* look in -I and system include directories. */
308146143Sharti		name = Path_FindFile(fname, &parseIncPath);
309146143Sharti		if (!name)
310146143Sharti			name = Path_FindFile(fname, &sysIncPath);
311152969Sfjoe		if (!name || !(stream = fopen(name, "r"))) {
312152982Sdavidxu			free(fnamesave);
313146143Sharti			return (FALSE);
314152969Sfjoe		}
315146143Sharti		MAKEFILE = fname = name;
316146143Sharti		/*
317146143Sharti		 * set the MAKEFILE variable desired by System V fans -- the
318146143Sharti		 * placement of the setting here means it gets set to the last
319146143Sharti		 * makefile specified, as it is set by SysV make.
320146143Sharti		 */
321146143Shartifound:
322146143Sharti		if (setMAKEFILE)
323146145Sharti			Var_SetGlobal("MAKEFILE", MAKEFILE);
324146143Sharti		Parse_File(fname, stream);
325146143Sharti	}
326152982Sdavidxu	free(fnamesave);
327146143Sharti	return (TRUE);
328146143Sharti}
329146143Sharti
330146143Sharti/**
331167330Sfjoe * Open and parse the given makefile.
332167330Sfjoe * If open is successful add it to the list of makefiles.
333167330Sfjoe *
334167330Sfjoe * Results:
335167330Sfjoe *	TRUE if ok. FALSE if couldn't open file.
336167330Sfjoe */
337167330Sfjoestatic Boolean
338167330SfjoeTryReadMakefile(const char p[])
339167330Sfjoe{
340167330Sfjoe	char *data;
341167330Sfjoe	LstNode *last = Lst_Last(&source_makefiles);
342167330Sfjoe
343167330Sfjoe	if (!ReadMakefile(p))
344167330Sfjoe		return (FALSE);
345167330Sfjoe
346167330Sfjoe	data = estrdup(p);
347167330Sfjoe	if (last == NULL) {
348167330Sfjoe		LstNode *first = Lst_First(&source_makefiles);
349167330Sfjoe		Lst_Insert(&source_makefiles, first, data);
350167330Sfjoe	} else
351167330Sfjoe		Lst_Append(&source_makefiles, last, estrdup(p));
352167330Sfjoe	return (TRUE);
353167330Sfjoe}
354167330Sfjoe
355167330Sfjoe/**
356144475Sharti * MainParseArgs
3571590Srgrimes *	Parse a given argument vector. Called from main() and from
3581590Srgrimes *	Main_ParseArgLine() when the .MAKEFLAGS target is used.
3591590Srgrimes *
3601590Srgrimes *	XXX: Deal with command line overriding .MAKEFLAGS in makefile
3611590Srgrimes *
3621590Srgrimes * Side Effects:
3631590Srgrimes *	Various global and local flags will be set depending on the flags
3641590Srgrimes *	given
3651590Srgrimes */
3661590Srgrimesstatic void
367104696SjmallettMainParseArgs(int argc, char **argv)
3681590Srgrimes{
3695814Sjkh	int c;
370146038Sharti	Boolean	found_dd = FALSE;
371201526Sobrien	char found_dir[MAXPATHLEN + 1];	/* for searching for sys.mk */
3721590Srgrimes
373144896Shartirearg:
3741590Srgrimes	optind = 1;	/* since we're called more than once */
375144896Sharti	optreset = 1;
376187995Simp#define OPTFLAGS "ABC:D:d:E:ef:I:ij:km:nPpQqrSstV:vXx:"
377146038Sharti	for (;;) {
378146038Sharti		if ((optind < argc) && strcmp(argv[optind], "--") == 0) {
379146038Sharti			found_dd = TRUE;
380146038Sharti		}
381146038Sharti		if ((c = getopt(argc, argv, OPTFLAGS)) == -1) {
382146038Sharti			break;
383146038Sharti		}
3841590Srgrimes		switch(c) {
385144387Sharti
386144387Sharti		case 'A':
387144387Sharti			arch_fatal = FALSE;
388144387Sharti			MFLAGS_append("-A", NULL);
389144387Sharti			break;
390187995Simp		case 'B':
391187995Simp			compatMake = TRUE;
392187995Simp			MFLAGS_append("-B", NULL);
393187995Simp			unsetenv("MAKE_JOBS_FIFO");
394187995Simp			break;
395102393Sjmallett		case 'C':
396107964Sseanc			if (chdir(optarg) == -1)
397107964Sseanc				err(1, "chdir %s", optarg);
398201526Sobrien			if (getcwd(curdir, MAXPATHLEN) == NULL)
399201526Sobrien				err(2, NULL);
400102393Sjmallett			break;
4011590Srgrimes		case 'D':
402146145Sharti			Var_SetGlobal(optarg, "1");
403133085Sharti			MFLAGS_append("-D", optarg);
4041590Srgrimes			break;
4051590Srgrimes		case 'd': {
4061590Srgrimes			char *modules = optarg;
4071590Srgrimes
4081590Srgrimes			for (; *modules; ++modules)
4091590Srgrimes				switch (*modules) {
4101590Srgrimes				case 'A':
4111590Srgrimes					debug = ~0;
4121590Srgrimes					break;
4131590Srgrimes				case 'a':
4141590Srgrimes					debug |= DEBUG_ARCH;
4151590Srgrimes					break;
4161590Srgrimes				case 'c':
4171590Srgrimes					debug |= DEBUG_COND;
4181590Srgrimes					break;
4191590Srgrimes				case 'd':
4201590Srgrimes					debug |= DEBUG_DIR;
4211590Srgrimes					break;
4221590Srgrimes				case 'f':
4231590Srgrimes					debug |= DEBUG_FOR;
4241590Srgrimes					break;
4251590Srgrimes				case 'g':
4261590Srgrimes					if (modules[1] == '1') {
4271590Srgrimes						debug |= DEBUG_GRAPH1;
4281590Srgrimes						++modules;
4291590Srgrimes					}
4301590Srgrimes					else if (modules[1] == '2') {
4311590Srgrimes						debug |= DEBUG_GRAPH2;
4321590Srgrimes						++modules;
4331590Srgrimes					}
4341590Srgrimes					break;
4351590Srgrimes				case 'j':
4361590Srgrimes					debug |= DEBUG_JOB;
4371590Srgrimes					break;
43860569Swill				case 'l':
43960569Swill					debug |= DEBUG_LOUD;
44060569Swill					break;
4411590Srgrimes				case 'm':
4421590Srgrimes					debug |= DEBUG_MAKE;
4431590Srgrimes					break;
4441590Srgrimes				case 's':
4451590Srgrimes					debug |= DEBUG_SUFF;
4461590Srgrimes					break;
4471590Srgrimes				case 't':
4481590Srgrimes					debug |= DEBUG_TARG;
4491590Srgrimes					break;
4501590Srgrimes				case 'v':
4511590Srgrimes					debug |= DEBUG_VAR;
4521590Srgrimes					break;
4531590Srgrimes				default:
454144475Sharti					warnx("illegal argument to d option "
455144475Sharti					    "-- %c", *modules);
4561590Srgrimes					usage();
4571590Srgrimes				}
458133085Sharti			MFLAGS_append("-d", optarg);
4591590Srgrimes			break;
4601590Srgrimes		}
46149332Shoek		case 'E':
462138920Sru			Lst_AtEnd(&envFirstVars, estrdup(optarg));
463133085Sharti			MFLAGS_append("-E", optarg);
46449332Shoek			break;
4651590Srgrimes		case 'e':
4661590Srgrimes			checkEnvFirst = TRUE;
467133085Sharti			MFLAGS_append("-e", NULL);
4681590Srgrimes			break;
4691590Srgrimes		case 'f':
470138920Sru			Lst_AtEnd(&makefiles, estrdup(optarg));
4711590Srgrimes			break;
472187995Simp		case 'I':
473187995Simp			Parse_AddIncludeDir(optarg);
474187995Simp			MFLAGS_append("-I", optarg);
475187995Simp			break;
4761590Srgrimes		case 'i':
4771590Srgrimes			ignoreErrors = TRUE;
478133085Sharti			MFLAGS_append("-i", NULL);
4791590Srgrimes			break;
48049331Shoek		case 'j': {
48149331Shoek			char *endptr;
48249331Shoek
48318730Ssteve			forceJobs = TRUE;
484146140Sharti			jobLimit = strtol(optarg, &endptr, 10);
485146140Sharti			if (jobLimit <= 0 || *endptr != '\0') {
48649938Shoek				warnx("illegal number, -j argument -- %s",
48749938Shoek				    optarg);
48849938Shoek				usage();
48949331Shoek			}
490133085Sharti			MFLAGS_append("-j", optarg);
4911590Srgrimes			break;
49249331Shoek		}
4931590Srgrimes		case 'k':
4941590Srgrimes			keepgoing = TRUE;
495133085Sharti			MFLAGS_append("-k", NULL);
4961590Srgrimes			break;
49718730Ssteve		case 'm':
498201526Sobrien			/* look for magic parent directory search string */
499201526Sobrien			if (strncmp(".../", optarg, 4) == 0) {
500201526Sobrien				if (!Dir_FindHereOrAbove(curdir, optarg + 4,
501201526Sobrien				    found_dir, sizeof(found_dir)))
502201526Sobrien					break;		/* nothing doing */
503201526Sobrien				Path_AddDir(&sysIncPath, found_dir);
504201526Sobrien			} else {
505201526Sobrien				Path_AddDir(&sysIncPath, optarg);
506201526Sobrien			}
507133085Sharti			MFLAGS_append("-m", optarg);
50818730Ssteve			break;
5091590Srgrimes		case 'n':
5101590Srgrimes			noExecute = TRUE;
511133085Sharti			MFLAGS_append("-n", NULL);
5121590Srgrimes			break;
513187995Simp		case 'P':
514187995Simp			usePipes = FALSE;
515187995Simp			MFLAGS_append("-P", NULL);
516187995Simp			break;
517181021Sed		case 'p':
518181021Sed			printGraphOnly = TRUE;
519181021Sed			debug |= DEBUG_GRAPH1;
520181021Sed			break;
521186713Sobrien		case 'Q':
522186713Sobrien			beQuiet = TRUE;
523187132Sobrien			beVerbose = FALSE;
524186713Sobrien			MFLAGS_append("-Q", NULL);
525186713Sobrien			break;
5261590Srgrimes		case 'q':
5271590Srgrimes			queryFlag = TRUE;
5281590Srgrimes			/* Kind of nonsensical, wot? */
529133085Sharti			MFLAGS_append("-q", NULL);
5301590Srgrimes			break;
5311590Srgrimes		case 'r':
5321590Srgrimes			noBuiltins = TRUE;
533133085Sharti			MFLAGS_append("-r", NULL);
5341590Srgrimes			break;
535187995Simp		case 'S':
536187995Simp			keepgoing = FALSE;
537187995Simp			MFLAGS_append("-S", NULL);
538187995Simp			break;
5391590Srgrimes		case 's':
5401590Srgrimes			beSilent = TRUE;
541133085Sharti			MFLAGS_append("-s", NULL);
5421590Srgrimes			break;
5431590Srgrimes		case 't':
5441590Srgrimes			touchFlag = TRUE;
545133085Sharti			MFLAGS_append("-t", NULL);
5461590Srgrimes			break;
547187995Simp		case 'V':
548187995Simp			Lst_AtEnd(&variables, estrdup(optarg));
549187995Simp			MFLAGS_append("-V", optarg);
550187995Simp			break;
55141151Sdg		case 'v':
55241151Sdg			beVerbose = TRUE;
553186713Sobrien			beQuiet = FALSE;
554133085Sharti			MFLAGS_append("-v", NULL);
55541151Sdg			break;
556187995Simp		case 'X':
557187995Simp			expandVars = FALSE;
558187995Simp			break;
559145627Sharti		case 'x':
560145679Sharti			if (Main_ParseWarn(optarg, 1) != -1)
561145627Sharti				MFLAGS_append("-x", optarg);
562145627Sharti			break;
563167330Sfjoe
5641590Srgrimes		default:
5651590Srgrimes		case '?':
5661590Srgrimes			usage();
5671590Srgrimes		}
5681590Srgrimes	}
569144896Sharti	argv += optind;
570144896Sharti	argc -= optind;
5711590Srgrimes
5721590Srgrimes	oldVars = TRUE;
5731590Srgrimes
5741590Srgrimes	/*
575144896Sharti	 * Parse the rest of the arguments.
576144896Sharti	 *	o Check for variable assignments and perform them if so.
577144896Sharti	 *	o Check for more flags and restart getopt if so.
578160442Sobrien	 *	o Anything else is taken to be a target and added
579144896Sharti	 *	  to the end of the "create" list.
5801590Srgrimes	 */
581144896Sharti	for (; *argv != NULL; ++argv, --argc) {
582133562Sharti		if (Parse_IsVar(*argv)) {
583140870Sharti			char *ptr = MAKEFLAGS_quote(*argv);
584167330Sfjoe			char *v = estrdup(*argv);
585133562Sharti
586146146Sharti			Var_Append(".MAKEFLAGS", ptr, VAR_GLOBAL);
587167330Sfjoe			Parse_DoVar(v, VAR_CMD);
588133562Sharti			free(ptr);
589167330Sfjoe			free(v);
590133562Sharti
591144896Sharti		} else if ((*argv)[0] == '-') {
592144896Sharti			if ((*argv)[1] == '\0') {
593144896Sharti				/*
594144896Sharti				 * (*argv) is a single dash, so we
595144896Sharti				 * just ignore it.
596144896Sharti				 */
597146038Sharti			} else if (found_dd) {
598146038Sharti				/*
599146038Sharti				 * Double dash has been found, ignore
600146038Sharti				 * any more options.  But what do we do
601146038Sharti				 * with it?  For now treat it like a target.
602146038Sharti				 */
603146038Sharti				Lst_AtEnd(&create, estrdup(*argv));
604144896Sharti			} else {
605144896Sharti				/*
606146038Sharti				 * (*argv) is a -flag, so backup argv and
607146038Sharti				 * argc.  getopt() expects options to start
608146038Sharti				 * in the 2nd position.
609144896Sharti				 */
610144896Sharti				argc++;
611144896Sharti				argv--;
6121590Srgrimes				goto rearg;
6131590Srgrimes			}
614144896Sharti
615144896Sharti		} else if ((*argv)[0] == '\0') {
616144896Sharti			Punt("illegal (null) argument.");
617144896Sharti
618144896Sharti		} else {
619138916Sharti			Lst_AtEnd(&create, estrdup(*argv));
6201590Srgrimes		}
621144896Sharti	}
6221590Srgrimes}
6231590Srgrimes
624144475Sharti/**
625144475Sharti * Main_ParseArgLine
626160442Sobrien *	Used by the parse module when a .MFLAGS or .MAKEFLAGS target
6271590Srgrimes *	is encountered and by main() when reading the .MAKEFLAGS envariable.
6281590Srgrimes *	Takes a line of arguments and breaks it into its
629160442Sobrien *	component words and passes those words and the number of them to the
6301590Srgrimes *	MainParseArgs function.
6311590Srgrimes *	The line should have all its leading whitespace removed.
6321590Srgrimes *
6331590Srgrimes * Side Effects:
6341590Srgrimes *	Only those that come from the various arguments.
6351590Srgrimes */
6361590Srgrimesvoid
637140870ShartiMain_ParseArgLine(char *line, int mflags)
6381590Srgrimes{
639146345Sharti	ArgArray	aa;
6401590Srgrimes
6411590Srgrimes	if (line == NULL)
6421590Srgrimes		return;
6431590Srgrimes	for (; *line == ' '; ++line)
6441590Srgrimes		continue;
6451590Srgrimes	if (!*line)
6461590Srgrimes		return;
6471590Srgrimes
648140870Sharti	if (mflags)
649146345Sharti		MAKEFLAGS_break(&aa, line);
650140870Sharti	else
651146345Sharti		brk_string(&aa, line, TRUE);
652140870Sharti
653146345Sharti	MainParseArgs(aa.argc, aa.argv);
654146345Sharti	ArgArray_Done(&aa);
6551590Srgrimes}
6561590Srgrimes
657146146Shartistatic char *
658141252Shartichdir_verify_path(const char *path, char *obpath)
65918339Sswallace{
66018339Sswallace	struct stat sb;
66118339Sswallace
66218339Sswallace	if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
66375973Sru		if (chdir(path) == -1 || getcwd(obpath, MAXPATHLEN) == NULL) {
66427644Scharnier			warn("warning: %s", path);
665141252Sharti			return (NULL);
66618339Sswallace		}
667138232Sharti		return (obpath);
66818339Sswallace	}
66918339Sswallace
670141252Sharti	return (NULL);
67118339Sswallace}
67218339Sswallace
673146144Sharti/**
674146144Sharti * In lieu of a good way to prevent every possible looping in make(1), stop
675146144Sharti * there from being more than MKLVL_MAXVAL processes forked by make(1), to
676146144Sharti * prevent a forkbomb from happening, in a dumb and mechanical way.
677146144Sharti *
678146144Sharti * Side Effects:
679146144Sharti *	Creates or modifies enviornment variable MKLVL_ENVVAR via setenv().
680138071Sjmallett */
681138071Sjmallettstatic void
682138071Sjmallettcheck_make_level(void)
683138071Sjmallett{
684138071Sjmallett#ifdef WANT_ENV_MKLVL
685138071Sjmallett	char	*value = getenv(MKLVL_ENVVAR);
686138071Sjmallett	int	level = (value == NULL) ? 0 : atoi(value);
687138071Sjmallett
688138071Sjmallett	if (level < 0) {
689144475Sharti		errc(2, EAGAIN, "Invalid value for recursion level (%d).",
690144475Sharti		    level);
691138071Sjmallett	} else if (level > MKLVL_MAXVAL) {
692144475Sharti		errc(2, EAGAIN, "Max recursion level (%d) exceeded.",
693144475Sharti		    MKLVL_MAXVAL);
694138071Sjmallett	} else {
695138071Sjmallett		char new_value[32];
696138071Sjmallett		sprintf(new_value, "%d", level + 1);
697138071Sjmallett		setenv(MKLVL_ENVVAR, new_value, 1);
698138071Sjmallett	}
699138071Sjmallett#endif /* WANT_ENV_MKLVL */
700138071Sjmallett}
701138071Sjmallett
702144475Sharti/**
703167330Sfjoe * Main_AddSourceMakefile
704167330Sfjoe *	Add a file to the list of source makefiles
705167330Sfjoe */
706167330Sfjoevoid
707167330SfjoeMain_AddSourceMakefile(const char *name)
708167330Sfjoe{
709167330Sfjoe
710167330Sfjoe	Lst_AtEnd(&source_makefiles, estrdup(name));
711167330Sfjoe}
712167330Sfjoe
713167330Sfjoe/**
714167330Sfjoe * Remake_Makefiles
715167330Sfjoe *	Remake all the makefiles
716167330Sfjoe */
717167330Sfjoestatic void
718167330SfjoeRemake_Makefiles(void)
719167330Sfjoe{
720198199Sfjoe	Lst cleanup;
721167330Sfjoe	LstNode *ln;
722167330Sfjoe	int error_cnt = 0;
723167330Sfjoe	int remade_cnt = 0;
724167330Sfjoe
725167330Sfjoe	Compat_InstallSignalHandlers();
726170179Sfjoe	if (curdir != objdir) {
727170179Sfjoe		if (chdir(curdir) < 0)
728170179Sfjoe			Fatal("Failed to change directory to %s.", curdir);
729170179Sfjoe	}
730167330Sfjoe
731198199Sfjoe	Lst_Init(&cleanup);
732167330Sfjoe	LST_FOREACH(ln, &source_makefiles) {
733167330Sfjoe		LstNode *ln2;
734167330Sfjoe		struct GNode *gn;
735167330Sfjoe		const char *name = Lst_Datum(ln);
736167330Sfjoe		Boolean saveTouchFlag = touchFlag;
737167330Sfjoe		Boolean saveQueryFlag = queryFlag;
738167330Sfjoe		Boolean saveNoExecute = noExecute;
739168892Sfjoe		int mtime;
740167330Sfjoe
741167330Sfjoe		/*
742167330Sfjoe		 * Create node
743167330Sfjoe		 */
744167330Sfjoe		gn = Targ_FindNode(name, TARG_CREATE);
745167330Sfjoe		DEBUGF(MAKE, ("Checking %s...", gn->name));
746167330Sfjoe		Suff_FindDeps(gn);
747167330Sfjoe
748167330Sfjoe		/*
749167330Sfjoe		 * -t, -q and -n has no effect unless the makefile is
750167330Sfjoe		 * specified as one of the targets explicitly in the
751167330Sfjoe		 * command line
752167330Sfjoe		 */
753167330Sfjoe		LST_FOREACH(ln2, &create) {
754167330Sfjoe			if (!strcmp(gn->name, Lst_Datum(ln2))) {
755167330Sfjoe				/* found as a target */
756167330Sfjoe				break;
757167330Sfjoe			}
758167330Sfjoe		}
759167330Sfjoe		if (ln2 == NULL) {
760167330Sfjoe			touchFlag = FALSE;
761167330Sfjoe			queryFlag = FALSE;
762167330Sfjoe			noExecute = FALSE;
763167330Sfjoe		}
764167330Sfjoe
765167330Sfjoe		/*
766167330Sfjoe		 * Check and remake the makefile
767167330Sfjoe		 */
768168892Sfjoe		mtime = Dir_MTime(gn);
769190821Sfjoe		remakingMakefiles = TRUE;
770167330Sfjoe		Compat_Make(gn, gn);
771190821Sfjoe		remakingMakefiles = FALSE;
772167330Sfjoe
773167330Sfjoe		/*
774167330Sfjoe		 * Restore -t, -q and -n behaviour
775167330Sfjoe		 */
776167330Sfjoe		touchFlag = saveTouchFlag;
777167330Sfjoe		queryFlag = saveQueryFlag;
778167330Sfjoe		noExecute = saveNoExecute;
779167330Sfjoe
780167330Sfjoe		/*
781167330Sfjoe		 * Compat_Make will leave the 'made' field of gn
782167330Sfjoe		 * in one of the following states:
783167330Sfjoe		 *	UPTODATE  gn was already up-to-date
784167330Sfjoe		 *	MADE	  gn was recreated successfully
785167330Sfjoe		 *	ERROR	  An error occurred while gn was being created
786167330Sfjoe		 *	ABORTED	  gn was not remade because one of its inferiors
787167330Sfjoe		 *		  could not be made due to errors.
788167330Sfjoe		 */
789168892Sfjoe		if (gn->made == MADE) {
790168892Sfjoe			if (mtime != Dir_MTime(gn)) {
791168892Sfjoe				DEBUGF(MAKE,
792168892Sfjoe				    ("%s updated (%d -> %d).\n",
793168892Sfjoe				     gn->name, mtime, gn->mtime));
794168892Sfjoe				remade_cnt++;
795168892Sfjoe			} else {
796168892Sfjoe				DEBUGF(MAKE,
797168892Sfjoe				    ("%s not updated: skipping restart.\n",
798168892Sfjoe				     gn->name));
799168892Sfjoe			}
800168892Sfjoe		} else if (gn->made == ERROR)
801167330Sfjoe			error_cnt++;
802167330Sfjoe		else if (gn->made == ABORTED) {
803167330Sfjoe			printf("`%s' not remade because of errors.\n",
804167330Sfjoe			    gn->name);
805167330Sfjoe			error_cnt++;
806173919Sfjoe		} else if (gn->made == UPTODATE) {
807198199Sfjoe			Lst_EnQueue(&cleanup, gn);
808167330Sfjoe		}
809167330Sfjoe	}
810167330Sfjoe
811167330Sfjoe	if (error_cnt > 0)
812167330Sfjoe		Fatal("Failed to remake Makefiles.");
813167330Sfjoe	if (remade_cnt > 0) {
814167330Sfjoe		DEBUGF(MAKE, ("Restarting `%s'.\n", save_argv[0]));
815167330Sfjoe
816167330Sfjoe		/*
817167330Sfjoe		 * Some of makefiles were remade -- restart from clean state
818167330Sfjoe		 */
819167330Sfjoe		if (save_makeflags != NULL)
820167330Sfjoe			setenv("MAKEFLAGS", save_makeflags, 1);
821167330Sfjoe		else
822167330Sfjoe			unsetenv("MAKEFLAGS");
823167330Sfjoe		if (execvp(save_argv[0], save_argv) < 0) {
824167330Sfjoe			Fatal("Can't restart `%s': %s.",
825167330Sfjoe			    save_argv[0], strerror(errno));
826167330Sfjoe		}
827167330Sfjoe	}
828170179Sfjoe
829198199Sfjoe	while (!Lst_IsEmpty(&cleanup)) {
830198199Sfjoe		GNode *gn = Lst_DeQueue(&cleanup);
831198199Sfjoe
832198199Sfjoe		gn->unmade = 0;
833198199Sfjoe		gn->make = FALSE;
834198199Sfjoe		gn->made = UNMADE;
835198199Sfjoe		gn->childMade = FALSE;
836198199Sfjoe		gn->mtime = gn->cmtime = 0;
837198199Sfjoe		gn->cmtime_gn = NULL;
838198199Sfjoe
839198199Sfjoe		LST_FOREACH(ln, &gn->children) {
840198199Sfjoe			GNode *cgn = Lst_Datum(ln);
841198199Sfjoe
842198199Sfjoe			gn->unmade++;
843198199Sfjoe			Lst_EnQueue(&cleanup, cgn);
844198199Sfjoe		}
845198199Sfjoe	}
846198199Sfjoe
847170179Sfjoe	if (curdir != objdir) {
848170179Sfjoe		if (chdir(objdir) < 0)
849170179Sfjoe			Fatal("Failed to change directory to %s.", objdir);
850170179Sfjoe	}
851167330Sfjoe}
852167330Sfjoe
853167330Sfjoe/**
854144475Sharti * main
8551590Srgrimes *	The main function, for obvious reasons. Initializes variables
8561590Srgrimes *	and a few modules, then parses the arguments give it in the
8571590Srgrimes *	environment and on the command line. Reads the system makefile
8581590Srgrimes *	followed by either Makefile, makefile or the file given by the
8591590Srgrimes *	-f argument. Sets the .MAKEFLAGS PMake variable based on all the
8601590Srgrimes *	flags it has received by then uses either the Make or the Compat
8611590Srgrimes *	module to create the initial list of targets.
8621590Srgrimes *
8631590Srgrimes * Results:
8641590Srgrimes *	If -q was given, exits -1 if anything was out-of-date. Else it exits
8651590Srgrimes *	0.
8661590Srgrimes *
8671590Srgrimes * Side Effects:
8681590Srgrimes *	The program exits when done. Targets are created. etc. etc. etc.
8691590Srgrimes */
8701590Srgrimesint
871104696Sjmallettmain(int argc, char **argv)
8721590Srgrimes{
873160442Sobrien	const char *machine;
874146144Sharti	const char *machine_arch;
875146144Sharti	const char *machine_cpu;
876160442Sobrien	Boolean outOfDate = TRUE;	/* FALSE if all targets up to date */
877146581Sharti	const char *p;
878146157Sharti	const char *pathp;
879146157Sharti	const char *path;
88073262Simp	char mdpath[MAXPATHLEN];
88173262Simp	char obpath[MAXPATHLEN];
88273262Simp	char cdpath[MAXPATHLEN];
883201526Sobrien	char found_dir[MAXPATHLEN + 1];	/* for searching for sys.mk */
88418730Ssteve	char *cp = NULL, *start;
885141252Sharti
886167330Sfjoe	save_argv = argv;
887167330Sfjoe	save_makeflags = getenv("MAKEFLAGS");
888167330Sfjoe	if (save_makeflags != NULL)
889167330Sfjoe		save_makeflags = estrdup(save_makeflags);
890167330Sfjoe
891146146Sharti	/*
892146146Sharti	 * Initialize file global variables.
893146146Sharti	 */
894146146Sharti	expandVars = TRUE;
895146146Sharti	noBuiltins = FALSE;		/* Read the built-in rules */
896160442Sobrien	forceJobs = FALSE;		/* No -j flag */
897146146Sharti	curdir = cdpath;
898146146Sharti
899146146Sharti	/*
900146146Sharti	 * Initialize program global variables.
901146146Sharti	 */
902146146Sharti	beSilent = FALSE;		/* Print commands as executed */
903146146Sharti	ignoreErrors = FALSE;		/* Pay attention to non-zero returns */
904146146Sharti	noExecute = FALSE;		/* Execute all commands */
905181021Sed	printGraphOnly = FALSE;		/* Don't stop after printing graph */
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
1025186559Sobrien	Var_SetGlobal(".newline", "\n");	/* handy for :@ loops */
1026186559Sobrien	{
1027186559Sobrien		char tmp[64];
10281590Srgrimes
1029186559Sobrien		snprintf(tmp, sizeof(tmp), "%u", getpid());
1030186559Sobrien		Var_SetGlobal(".MAKE.PID", tmp);
1031186559Sobrien		snprintf(tmp, sizeof(tmp), "%u", getppid());
1032186559Sobrien		Var_SetGlobal(".MAKE.PPID", tmp);
1033186559Sobrien	}
1034186559Sobrien	Job_SetPrefix();
1035186559Sobrien
10361590Srgrimes	/*
1037201526Sobrien	 * Find where we are...
1038201526Sobrien	 */
1039201526Sobrien	if (getcwd(curdir, MAXPATHLEN) == NULL)
1040201526Sobrien		err(2, NULL);
1041201526Sobrien
1042201526Sobrien	/*
1043144896Sharti	 * First snag things out of the MAKEFLAGS environment
1044144896Sharti	 * variable.  Then parse the command line arguments.
10451590Srgrimes	 */
1046140870Sharti	Main_ParseArgLine(getenv("MAKEFLAGS"), 1);
10478874Srgrimes
10481590Srgrimes	MainParseArgs(argc, argv);
10491590Srgrimes
10501590Srgrimes	/*
1051201526Sobrien	 * Verify that cwd is sane (after -C may have changed it).
1052120053Sru	 */
1053141252Sharti	{
1054141252Sharti	struct stat sa;
1055141252Sharti
1056120053Sru	if (stat(curdir, &sa) == -1)
1057120053Sru	    err(2, "%s", curdir);
1058141252Sharti	}
1059120053Sru
1060120053Sru	/*
1061120053Sru	 * The object directory location is determined using the
1062120053Sru	 * following order of preference:
1063120053Sru	 *
1064120053Sru	 *	1. MAKEOBJDIRPREFIX`cwd`
1065120053Sru	 *	2. MAKEOBJDIR
1066143412Sharti	 *	3. PATH_OBJDIR.${MACHINE}
1067143412Sharti	 *	4. PATH_OBJDIR
1068143412Sharti	 *	5. PATH_OBJDIRPREFIX`cwd`
1069120053Sru	 *
1070120053Sru	 * If one of the first two fails, use the current directory.
1071120053Sru	 * If the remaining three all fail, use the current directory.
1072120053Sru	 *
1073120053Sru	 * Once things are initted,
1074120053Sru	 * have to add the original directory to the search path,
1075120053Sru	 * and modify the paths for the Makefiles apropriately.  The
1076120053Sru	 * current directory is also placed as a variable for make scripts.
1077120053Sru	 */
1078120053Sru	if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
1079120053Sru		if (!(path = getenv("MAKEOBJDIR"))) {
1080143412Sharti			path = PATH_OBJDIR;
1081143412Sharti			pathp = PATH_OBJDIRPREFIX;
1082146145Sharti			snprintf(mdpath, MAXPATHLEN, "%s.%s", path, machine);
1083120053Sru			if (!(objdir = chdir_verify_path(mdpath, obpath)))
1084120053Sru				if (!(objdir=chdir_verify_path(path, obpath))) {
1085138232Sharti					snprintf(mdpath, MAXPATHLEN,
1086120053Sru							"%s%s", pathp, curdir);
1087120053Sru					if (!(objdir=chdir_verify_path(mdpath,
1088120053Sru								       obpath)))
1089120053Sru						objdir = curdir;
1090120053Sru				}
1091120053Sru		}
1092120053Sru		else if (!(objdir = chdir_verify_path(path, obpath)))
1093120053Sru			objdir = curdir;
1094120053Sru	}
1095120053Sru	else {
1096138232Sharti		snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
1097120053Sru		if (!(objdir = chdir_verify_path(mdpath, obpath)))
1098120053Sru			objdir = curdir;
1099120053Sru	}
1100120053Sru	Dir_InitDot();		/* Initialize the "." directory */
1101120053Sru	if (objdir != curdir)
1102144020Sharti		Path_AddDir(&dirSearchPath, curdir);
1103146145Sharti	Var_SetGlobal(".ST_EXPORTVAR", "YES");
1104146145Sharti	Var_SetGlobal(".CURDIR", curdir);
1105146145Sharti	Var_SetGlobal(".OBJDIR", objdir);
1106120053Sru
1107137606Sphk	if (getenv("MAKE_JOBS_FIFO") != NULL)
1108137606Sphk		forceJobs = TRUE;
1109120053Sru	/*
111028228Sfsmp	 * Be compatible if user did not specify -j and did not explicitly
111128228Sfsmp	 * turned compatibility on
111228228Sfsmp	 */
111328228Sfsmp	if (!compatMake && !forceJobs)
111428228Sfsmp		compatMake = TRUE;
111528228Sfsmp
111628228Sfsmp	/*
1117144387Sharti	 * Initialize target and suffix modules in preparation for
11181590Srgrimes	 * parsing the makefile(s)
11191590Srgrimes	 */
11201590Srgrimes	Targ_Init();
11211590Srgrimes	Suff_Init();
11221590Srgrimes
112369527Swill	DEFAULT = NULL;
1124138232Sharti	time(&now);
11251590Srgrimes
11261590Srgrimes	/*
11271590Srgrimes	 * Set up the .TARGETS variable to contain the list of targets to be
11281590Srgrimes	 * created. If none specified, make the variable empty -- the parser
11291590Srgrimes	 * will fill the thing in with the default or .MAIN target.
11301590Srgrimes	 */
1131146145Sharti	if (Lst_IsEmpty(&create)) {
1132146145Sharti		Var_SetGlobal(".TARGETS", "");
1133146145Sharti	} else {
1134138512Sharti		LstNode *ln;
11351590Srgrimes
1136138916Sharti		for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) {
1137138264Sharti			char *name = Lst_Datum(ln);
11381590Srgrimes
11391590Srgrimes			Var_Append(".TARGETS", name, VAR_GLOBAL);
11401590Srgrimes		}
1141146145Sharti	}
11421590Srgrimes
114318730Ssteve
11441590Srgrimes	/*
114518730Ssteve	 * If no user-supplied system path was given (through the -m option)
114618730Ssteve	 * add the directories from the DEFSYSPATH (more than one may be given
114718730Ssteve	 * as dir1:...:dirn) to the system include path.
11481590Srgrimes	 */
1149144020Sharti	if (TAILQ_EMPTY(&sysIncPath)) {
1150201526Sobrien		char defsyspath[] = PATH_DEFSYSPATH;
1151201526Sobrien		char *syspath = getenv("MAKESYSPATH");
1152146144Sharti
1153201526Sobrien		/*
1154201526Sobrien		 * If no user-supplied system path was given (thru -m option)
1155201526Sobrien		 * add the directories from the DEFSYSPATH (more than one may
1156201526Sobrien		 * be given as dir1:...:dirn) to the system include path.
1157201526Sobrien		 */
1158201526Sobrien		if (syspath == NULL || *syspath == '\0')
1159201526Sobrien			syspath = defsyspath;
1160201526Sobrien		else
1161201526Sobrien			syspath = estrdup(syspath);
1162201526Sobrien
116318730Ssteve		for (start = syspath; *start != '\0'; start = cp) {
116418730Ssteve			for (cp = start; *cp != '\0' && *cp != ':'; cp++)
116518730Ssteve				continue;
1166201526Sobrien			if (*cp == ':') {
1167201526Sobrien				*cp++ = '\0';
1168201526Sobrien			}
1169201526Sobrien			/* look for magic parent directory search string */
1170201526Sobrien			if (strncmp(".../", start, 4) == 0) {
1171201526Sobrien				if (Dir_FindHereOrAbove(curdir, start + 4,
1172201526Sobrien				    found_dir, sizeof(found_dir))) {
1173201526Sobrien					Path_AddDir(&sysIncPath, found_dir);
1174201526Sobrien				}
117518730Ssteve			} else {
1176144020Sharti				Path_AddDir(&sysIncPath, start);
117718730Ssteve			}
117818730Ssteve		}
1179201526Sobrien		if (syspath != defsyspath)
1180201526Sobrien			free(syspath);
118118730Ssteve	}
11821590Srgrimes
118318730Ssteve	/*
118418730Ssteve	 * Read in the built-in rules first, followed by the specified
118518730Ssteve	 * makefile, if it was (makefile != (char *) NULL), or the default
118618730Ssteve	 * Makefile and makefile, in that order, if it wasn't.
118718730Ssteve	 */
118818730Ssteve	if (!noBuiltins) {
1189138916Sharti		/* Path of sys.mk */
1190138916Sharti		Lst sysMkPath = Lst_Initializer(sysMkPath);
1191138512Sharti		LstNode *ln;
1192146064Sharti		char	defsysmk[] = PATH_DEFSYSMK;
119318730Ssteve
1194146064Sharti		Path_Expand(defsysmk, &sysIncPath, &sysMkPath);
1195138916Sharti		if (Lst_IsEmpty(&sysMkPath))
1196143412Sharti			Fatal("make: no system rules (%s).", PATH_DEFSYSMK);
1197143808Sharti		LST_FOREACH(ln, &sysMkPath) {
1198143808Sharti			if (!ReadMakefile(Lst_Datum(ln)))
1199143808Sharti				break;
1200143808Sharti		}
120169527Swill		if (ln != NULL)
120218730Ssteve			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
1203138916Sharti		Lst_Destroy(&sysMkPath, free);
120418730Ssteve	}
120518730Ssteve
1206138916Sharti	if (!Lst_IsEmpty(&makefiles)) {
1207138512Sharti		LstNode *ln;
12081590Srgrimes
1209143808Sharti		LST_FOREACH(ln, &makefiles) {
1210167330Sfjoe			if (!TryReadMakefile(Lst_Datum(ln)))
1211143808Sharti				break;
1212143808Sharti		}
121369527Swill		if (ln != NULL)
12141590Srgrimes			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
1215167330Sfjoe	} else if (!TryReadMakefile("BSDmakefile"))
1216167330Sfjoe	    if (!TryReadMakefile("makefile"))
1217167330Sfjoe		TryReadMakefile("Makefile");
12181590Srgrimes
1219143808Sharti	ReadMakefile(".depend");
12201590Srgrimes
1221176842Syar	/* Install all the flags into the MAKEFLAGS envariable. */
1222146580Sharti	if (((p = Var_Value(".MAKEFLAGS", VAR_GLOBAL)) != NULL) && *p)
12231590Srgrimes		setenv("MAKEFLAGS", p, 1);
1224176839Syar	else
1225176839Syar		setenv("MAKEFLAGS", "", 1);
12261590Srgrimes
12271590Srgrimes	/*
12281590Srgrimes	 * For compatibility, look at the directories in the VPATH variable
12291590Srgrimes	 * and add them to the search path, if the variable is defined. The
12301590Srgrimes	 * variable's value is in the same format as the PATH envariable, i.e.
12311590Srgrimes	 * <directory>:<directory>:<directory>...
12321590Srgrimes	 */
12331590Srgrimes	if (Var_Exists("VPATH", VAR_CMD)) {
12341590Srgrimes		/*
12351590Srgrimes		 * GCC stores string constants in read-only memory, but
12361590Srgrimes		 * Var_Subst will want to write this thing, so store it
12371590Srgrimes		 * in an array
12381590Srgrimes		 */
12391590Srgrimes		static char VPATH[] = "${VPATH}";
1240142457Sharti		Buffer	*buf;
1241142457Sharti		char	*vpath;
1242142457Sharti		char	*ptr;
1243142457Sharti		char	savec;
12441590Srgrimes
1245146027Sharti		buf = Var_Subst(VPATH, VAR_CMD, FALSE);
1246142457Sharti
1247143959Sharti		vpath = Buf_Data(buf);
12481590Srgrimes		do {
12491590Srgrimes			/* skip to end of directory */
1250142457Sharti			for (ptr = vpath; *ptr != ':' && *ptr != '\0'; ptr++)
1251141969Sharti				;
1252141969Sharti
12531590Srgrimes			/* Save terminator character so know when to stop */
1254141969Sharti			savec = *ptr;
1255141969Sharti			*ptr = '\0';
1256141969Sharti
12571590Srgrimes			/* Add directory to search path */
1258144020Sharti			Path_AddDir(&dirSearchPath, vpath);
1259141969Sharti
1260142457Sharti			vpath = ptr + 1;
1261141969Sharti		} while (savec != '\0');
1262142457Sharti
1263142457Sharti		Buf_Destroy(buf, TRUE);
12641590Srgrimes	}
12651590Srgrimes
12661590Srgrimes	/*
12671590Srgrimes	 * Now that all search paths have been read for suffixes et al, it's
12681590Srgrimes	 * time to add the default search path to their lists...
12691590Srgrimes	 */
12701590Srgrimes	Suff_DoPaths();
12711590Srgrimes
12721590Srgrimes	/* print the initial graph, if the user requested it */
12731590Srgrimes	if (DEBUG(GRAPH1))
12741590Srgrimes		Targ_PrintGraph(1);
12751590Srgrimes
127617193Sbde	/* print the values of any variables requested by the user */
1277181021Sed	if (Lst_IsEmpty(&variables) && !printGraphOnly) {
12781590Srgrimes		/*
1279141974Sharti		 * Since the user has not requested that any variables
1280142008Sharti		 * be printed, we can build targets.
1281141974Sharti		 *
1282142008Sharti		 * Have read the entire graph and need to make a list of targets
1283141974Sharti		 * to create. If none was given on the command line, we consult
1284141974Sharti		 * the parsing module to find the main target(s) to create.
12851590Srgrimes		 */
1286138916Sharti		Lst targs = Lst_Initializer(targs);
1287138916Sharti
1288177101Sobrien		if (!is_posix && mfAutoDeps) {
1289167330Sfjoe			/*
1290167330Sfjoe			 * Check if any of the makefiles are out-of-date.
1291167330Sfjoe			 */
1292167330Sfjoe			Remake_Makefiles();
1293167330Sfjoe		}
1294167330Sfjoe
1295138916Sharti		if (Lst_IsEmpty(&create))
1296138916Sharti			Parse_MainName(&targs);
1297101460Sru		else
1298138916Sharti			Targ_FindList(&targs, &create, TARG_CREATE);
1299101460Sru
1300141974Sharti		if (compatMake) {
1301101460Sru			/*
1302141974Sharti			 * Compat_Init will take care of creating
1303141974Sharti			 * all the targets as well as initializing
1304141974Sharti			 * the module.
1305101460Sru			 */
1306141974Sharti			Compat_Run(&targs);
1307141974Sharti			outOfDate = 0;
1308141974Sharti		} else {
1309141974Sharti			/*
1310141974Sharti			 * Initialize job module before traversing
1311141974Sharti			 * the graph, now that any .BEGIN and .END
1312141974Sharti			 * targets have been read.  This is done
1313141974Sharti			 * only if the -q flag wasn't given (to
1314141974Sharti			 * prevent the .BEGIN from being executed
1315141974Sharti			 * should it exist).
1316141974Sharti			 */
1317101460Sru			if (!queryFlag) {
1318146140Sharti				Job_Init(jobLimit);
1319101460Sru				jobsRunning = TRUE;
1320101460Sru			}
1321101460Sru
1322101460Sru			/* Traverse the graph, checking on all the targets */
1323138916Sharti			outOfDate = Make_Run(&targs);
13241590Srgrimes		}
1325138916Sharti		Lst_Destroy(&targs, NOFREE);
1326141974Sharti
1327141974Sharti	} else {
1328146141Sharti		Var_Print(&variables, expandVars);
132917193Sbde	}
13308874Srgrimes
1331138920Sru	Lst_Destroy(&variables, free);
1332138920Sru	Lst_Destroy(&makefiles, free);
1333167330Sfjoe	Lst_Destroy(&source_makefiles, free);
1334138916Sharti	Lst_Destroy(&create, free);
13355814Sjkh
13361590Srgrimes	/* print the graph now it's been processed if the user requested it */
13371590Srgrimes	if (DEBUG(GRAPH2))
13381590Srgrimes		Targ_PrintGraph(2);
13391590Srgrimes
1340186279Sfjoe	if (queryFlag)
1341186279Sfjoe		return (outOfDate);
1342186279Sfjoe
1343186279Sfjoe	if (makeErrors != 0)
1344186279Sfjoe		Finish(makeErrors);
1345186279Sfjoe
1346186279Sfjoe	return (0);
13471590Srgrimes}
1348