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$");
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>
66127880Sdes#include <sys/time.h>
67144020Sharti#include <sys/queue.h>
68127899Sru#include <sys/resource.h>
69153115Sru#include <sys/utsname.h>
7018730Ssteve#include <sys/wait.h>
7127644Scharnier#include <err.h>
721590Srgrimes#include <errno.h>
73127880Sdes#include <stdlib.h>
74141104Sharti#include <string.h>
7563955Simp#include <unistd.h>
76127880Sdes
77141104Sharti#include "arch.h"
78141133Sharti#include "buf.h"
79141104Sharti#include "config.h"
801590Srgrimes#include "dir.h"
81141104Sharti#include "globals.h"
82167330Sfjoe#include "GNode.h"
831590Srgrimes#include "job.h"
84141104Sharti#include "make.h"
85141104Sharti#include "parse.h"
861590Srgrimes#include "pathnames.h"
87146572Sharti#include "shell.h"
88141104Sharti#include "str.h"
89141104Sharti#include "suff.h"
90141104Sharti#include "targ.h"
91141104Sharti#include "util.h"
92141104Sharti#include "var.h"
931590Srgrimes
94146146Shartiextern char **environ;	/* XXX what header declares this variable? */
95146146Sharti
96160442Sobrien#define	WANT_ENV_MKLVL	1
97138071Sjmallett#define	MKLVL_MAXVAL	500
98138071Sjmallett#define	MKLVL_ENVVAR	"__MKLVL__"
99104395Sjmallett
100138916Sharti/* ordered list of makefiles to read */
101138916Shartistatic Lst makefiles = Lst_Initializer(makefiles);
102138916Sharti
103167330Sfjoe/* ordered list of source makefiles */
104167330Sfjoestatic Lst source_makefiles = Lst_Initializer(source_makefiles);
105167330Sfjoe
106138916Sharti/* list of variables to print */
107138916Shartistatic Lst variables = Lst_Initializer(variables);
108138916Sharti
109146146Shartistatic Boolean	expandVars;	/* fully expand printed variables */
110146146Shartistatic Boolean	noBuiltins;	/* -r flag */
111160442Sobrienstatic Boolean	forceJobs;	/* -j argument given */
112146146Shartistatic char	*curdir;	/* startup directory */
113146146Shartistatic char	*objdir;	/* where we chdir'ed to */
114167330Sfjoestatic char	**save_argv;	/* saved argv */
115167330Sfjoestatic char	*save_makeflags;/* saved MAKEFLAGS */
116146146Sharti
117146146Sharti/* (-E) vars to override from env */
118146146ShartiLst envFirstVars = Lst_Initializer(envFirstVars);
119146146Sharti
120146146Sharti/* Targets to be made */
121146146ShartiLst create = Lst_Initializer(create);
122146146Sharti
123146146ShartiBoolean		allPrecious;	/* .PRECIOUS given on line by itself */
124167330SfjoeBoolean		is_posix;	/* .POSIX target seen */
125177101SobrienBoolean		mfAutoDeps;	/* .MAKEFILEDEPS target seen */
126190821SfjoeBoolean		remakingMakefiles; /* True if remaking makefiles is in progress */
127146146ShartiBoolean		beSilent;	/* -s flag */
128146146ShartiBoolean		beVerbose;	/* -v flag */
129187132SobrienBoolean		beQuiet;	/* -Q flag */
130144475ShartiBoolean		compatMake;	/* -B argument */
131149844Shartiint		debug;		/* -d flag */
132146146ShartiBoolean		ignoreErrors;	/* -i flag */
133146146Shartiint		jobLimit;	/* -j argument */
134186279Sfjoeint		makeErrors;	/* Number of targets not remade due to errors */
135146146ShartiBoolean		jobsRunning;	/* TRUE if the jobs might be running */
136146146ShartiBoolean		keepgoing;	/* -k flag */
137144475ShartiBoolean		noExecute;	/* -n flag */
138181021SedBoolean		printGraphOnly;	/* -p flag */
139144475ShartiBoolean		queryFlag;	/* -q flag */
140144475ShartiBoolean		touchFlag;	/* -t flag */
141144475ShartiBoolean		usePipes;	/* !-P flag */
142146146Shartiuint32_t	warn_cmd;	/* command line warning flags */
143146146Shartiuint32_t	warn_flags;	/* actual warning flags */
144146146Shartiuint32_t	warn_nocmd;	/* command line no-warning flags */
145138916Sharti
146146146Shartitime_t		now;		/* Time at start of make */
147146146Shartistruct GNode	*DEFAULT;	/* .DEFAULT node */
148138916Sharti
149230392Srmhstatic struct {
150230392Srmh	const char *foreign_name;
151230392Srmh	const char *freebsd_name;
152230392Srmh} arch_aliases[] = {
153230392Srmh	{ "x86_64", "amd64" },
154230392Srmh	{ "mipsel", "mips" },
155230392Srmh};
156230392Srmh
157144475Sharti/**
158146143Sharti * Exit with usage message.
159146143Sharti */
160146143Shartistatic void
161146143Shartiusage(void)
162146143Sharti{
163146143Sharti	fprintf(stderr,
164181021Sed	    "usage: make [-BPSXeiknpqrstv] [-C directory] [-D variable]\n"
165146143Sharti	    "\t[-d flags] [-E variable] [-f makefile] [-I directory]\n"
166146143Sharti	    "\t[-j max_jobs] [-m directory] [-V variable]\n"
167146143Sharti	    "\t[variable=value] [target ...]\n");
168146143Sharti	exit(2);
169146143Sharti}
170146143Sharti
171146143Sharti/**
172144475Sharti * MFLAGS_append
173144475Sharti *	Append a flag with an optional argument to MAKEFLAGS and MFLAGS
174133085Sharti */
175133085Shartistatic void
176141252ShartiMFLAGS_append(const char *flag, char *arg)
177133085Sharti{
178140870Sharti	char *str;
179138232Sharti
180146146Sharti	Var_Append(".MAKEFLAGS", flag, VAR_GLOBAL);
181140870Sharti	if (arg != NULL) {
182140870Sharti		str = MAKEFLAGS_quote(arg);
183146146Sharti		Var_Append(".MAKEFLAGS", str, VAR_GLOBAL);
184140870Sharti		free(str);
185140870Sharti	}
186133085Sharti
187133085Sharti	Var_Append("MFLAGS", flag, VAR_GLOBAL);
188140870Sharti	if (arg != NULL) {
189140870Sharti		str = MAKEFLAGS_quote(arg);
190140870Sharti		Var_Append("MFLAGS", str, VAR_GLOBAL);
191140870Sharti		free(str);
192140870Sharti	}
193133085Sharti}
194133085Sharti
195144475Sharti/**
196145679Sharti * Main_ParseWarn
197145679Sharti *
198145679Sharti *	Handle argument to warning option.
199145679Sharti */
200145679Shartiint
201145679ShartiMain_ParseWarn(const char *arg, int iscmd)
202145679Sharti{
203145679Sharti	int i, neg;
204145679Sharti
205145679Sharti	static const struct {
206145679Sharti		const char	*option;
207145679Sharti		uint32_t	flag;
208145679Sharti	} options[] = {
209145679Sharti		{ "dirsyntax",	WARN_DIRSYNTAX },
210145679Sharti		{ NULL,		0 }
211145679Sharti	};
212145679Sharti
213145679Sharti	neg = 0;
214145679Sharti	if (arg[0] == 'n' && arg[1] == 'o') {
215145679Sharti		neg = 1;
216145679Sharti		arg += 2;
217145679Sharti	}
218145679Sharti
219145679Sharti	for (i = 0; options[i].option != NULL; i++)
220145679Sharti		if (strcmp(arg, options[i].option) == 0)
221145679Sharti			break;
222145679Sharti
223145679Sharti	if (options[i].option == NULL)
224145679Sharti		/* unknown option */
225145679Sharti		return (-1);
226145679Sharti
227145679Sharti	if (iscmd) {
228145679Sharti		if (!neg) {
229145679Sharti			warn_cmd |= options[i].flag;
230145679Sharti			warn_nocmd &= ~options[i].flag;
231145679Sharti			warn_flags |= options[i].flag;
232145679Sharti		} else {
233145679Sharti			warn_nocmd |= options[i].flag;
234145679Sharti			warn_cmd &= ~options[i].flag;
235145679Sharti			warn_flags &= ~options[i].flag;
236145679Sharti		}
237145679Sharti	} else {
238145679Sharti		if (!neg) {
239145679Sharti			warn_flags |= (options[i].flag & ~warn_nocmd);
240145679Sharti		} else {
241145679Sharti			warn_flags &= ~(options[i].flag | warn_cmd);
242145679Sharti		}
243145679Sharti	}
244145679Sharti	return (0);
245145679Sharti}
246145679Sharti
247145679Sharti/**
248146143Sharti * Open and parse the given makefile.
249146143Sharti *
250146143Sharti * Results:
251146143Sharti *	TRUE if ok. FALSE if couldn't open file.
252146143Sharti */
253146143Shartistatic Boolean
254146143ShartiReadMakefile(const char p[])
255146143Sharti{
256152982Sdavidxu	char *fname, *fnamesave;	/* makefile to read */
257146143Sharti	FILE *stream;
258146143Sharti	char *name, path[MAXPATHLEN];
259146143Sharti	char *MAKEFILE;
260146143Sharti	int setMAKEFILE;
261146143Sharti
262146143Sharti	/* XXX - remove this once constification is done */
263152982Sdavidxu	fnamesave = fname = estrdup(p);
264146143Sharti
265146143Sharti	if (!strcmp(fname, "-")) {
266146143Sharti		Parse_File("(stdin)", stdin);
267146145Sharti		Var_SetGlobal("MAKEFILE", "");
268146143Sharti	} else {
269146143Sharti		setMAKEFILE = strcmp(fname, ".depend");
270146143Sharti
271146143Sharti		/* if we've chdir'd, rebuild the path name */
272146143Sharti		if (curdir != objdir && *fname != '/') {
273146143Sharti			snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname);
274146143Sharti			/*
275146143Sharti			 * XXX The realpath stuff breaks relative includes
276146143Sharti			 * XXX in some cases.   The problem likely is in
277146143Sharti			 * XXX parse.c where it does special things in
278228992Suqs			 * XXX ParseDoInclude if the file is relative
279146143Sharti			 * XXX or absolute and not a system file.  There
280146143Sharti			 * XXX it assumes that if the current file that's
281146143Sharti			 * XXX being included is absolute, that any files
282146143Sharti			 * XXX that it includes shouldn't do the -I path
283228992Suqs			 * XXX stuff, which is inconsistent with historical
284228992Suqs			 * XXX behavior.  However, I can't penetrate the mists
285146143Sharti			 * XXX further, so I'm putting this workaround in
286146143Sharti			 * XXX here until such time as the underlying bug
287146143Sharti			 * XXX can be fixed.
288146143Sharti			 */
289146143Sharti#if THIS_BREAKS_THINGS
290146143Sharti			if (realpath(path, path) != NULL &&
291146143Sharti			    (stream = fopen(path, "r")) != NULL) {
292146143Sharti				MAKEFILE = fname;
293146143Sharti				fname = path;
294146143Sharti				goto found;
295146143Sharti			}
296146143Sharti		} else if (realpath(fname, path) != NULL) {
297146143Sharti			MAKEFILE = fname;
298146143Sharti			fname = path;
299146143Sharti			if ((stream = fopen(fname, "r")) != NULL)
300146143Sharti				goto found;
301146143Sharti		}
302146143Sharti#else
303146143Sharti			if ((stream = fopen(path, "r")) != NULL) {
304146143Sharti				MAKEFILE = fname;
305146143Sharti				fname = path;
306146143Sharti				goto found;
307146143Sharti			}
308146143Sharti		} else {
309146143Sharti			MAKEFILE = fname;
310146143Sharti			if ((stream = fopen(fname, "r")) != NULL)
311146143Sharti				goto found;
312146143Sharti		}
313146143Sharti#endif
314146143Sharti		/* look in -I and system include directories. */
315146143Sharti		name = Path_FindFile(fname, &parseIncPath);
316146143Sharti		if (!name)
317146143Sharti			name = Path_FindFile(fname, &sysIncPath);
318152969Sfjoe		if (!name || !(stream = fopen(name, "r"))) {
319152982Sdavidxu			free(fnamesave);
320146143Sharti			return (FALSE);
321152969Sfjoe		}
322146143Sharti		MAKEFILE = fname = name;
323146143Sharti		/*
324146143Sharti		 * set the MAKEFILE variable desired by System V fans -- the
325146143Sharti		 * placement of the setting here means it gets set to the last
326146143Sharti		 * makefile specified, as it is set by SysV make.
327146143Sharti		 */
328146143Shartifound:
329146143Sharti		if (setMAKEFILE)
330146145Sharti			Var_SetGlobal("MAKEFILE", MAKEFILE);
331146143Sharti		Parse_File(fname, stream);
332146143Sharti	}
333152982Sdavidxu	free(fnamesave);
334146143Sharti	return (TRUE);
335146143Sharti}
336146143Sharti
337146143Sharti/**
338167330Sfjoe * Open and parse the given makefile.
339167330Sfjoe * If open is successful add it to the list of makefiles.
340167330Sfjoe *
341167330Sfjoe * Results:
342167330Sfjoe *	TRUE if ok. FALSE if couldn't open file.
343167330Sfjoe */
344167330Sfjoestatic Boolean
345167330SfjoeTryReadMakefile(const char p[])
346167330Sfjoe{
347167330Sfjoe	char *data;
348167330Sfjoe	LstNode *last = Lst_Last(&source_makefiles);
349167330Sfjoe
350167330Sfjoe	if (!ReadMakefile(p))
351167330Sfjoe		return (FALSE);
352167330Sfjoe
353167330Sfjoe	data = estrdup(p);
354167330Sfjoe	if (last == NULL) {
355167330Sfjoe		LstNode *first = Lst_First(&source_makefiles);
356167330Sfjoe		Lst_Insert(&source_makefiles, first, data);
357167330Sfjoe	} else
358167330Sfjoe		Lst_Append(&source_makefiles, last, estrdup(p));
359167330Sfjoe	return (TRUE);
360167330Sfjoe}
361167330Sfjoe
362167330Sfjoe/**
363144475Sharti * MainParseArgs
3641590Srgrimes *	Parse a given argument vector. Called from main() and from
3651590Srgrimes *	Main_ParseArgLine() when the .MAKEFLAGS target is used.
3661590Srgrimes *
3671590Srgrimes *	XXX: Deal with command line overriding .MAKEFLAGS in makefile
3681590Srgrimes *
3691590Srgrimes * Side Effects:
3701590Srgrimes *	Various global and local flags will be set depending on the flags
3711590Srgrimes *	given
3721590Srgrimes */
3731590Srgrimesstatic void
374104696SjmallettMainParseArgs(int argc, char **argv)
3751590Srgrimes{
3765814Sjkh	int c;
377146038Sharti	Boolean	found_dd = FALSE;
378201526Sobrien	char found_dir[MAXPATHLEN + 1];	/* for searching for sys.mk */
3791590Srgrimes
380144896Shartirearg:
3811590Srgrimes	optind = 1;	/* since we're called more than once */
382144896Sharti	optreset = 1;
383187995Simp#define OPTFLAGS "ABC:D:d:E:ef:I:ij:km:nPpQqrSstV:vXx:"
384146038Sharti	for (;;) {
385146038Sharti		if ((optind < argc) && strcmp(argv[optind], "--") == 0) {
386146038Sharti			found_dd = TRUE;
387146038Sharti		}
388146038Sharti		if ((c = getopt(argc, argv, OPTFLAGS)) == -1) {
389146038Sharti			break;
390146038Sharti		}
3911590Srgrimes		switch(c) {
392144387Sharti
393144387Sharti		case 'A':
394144387Sharti			arch_fatal = FALSE;
395144387Sharti			MFLAGS_append("-A", NULL);
396144387Sharti			break;
397187995Simp		case 'B':
398187995Simp			compatMake = TRUE;
399187995Simp			MFLAGS_append("-B", NULL);
400187995Simp			unsetenv("MAKE_JOBS_FIFO");
401187995Simp			break;
402102393Sjmallett		case 'C':
403107964Sseanc			if (chdir(optarg) == -1)
404107964Sseanc				err(1, "chdir %s", optarg);
405201526Sobrien			if (getcwd(curdir, MAXPATHLEN) == NULL)
406201526Sobrien				err(2, NULL);
407102393Sjmallett			break;
4081590Srgrimes		case 'D':
409146145Sharti			Var_SetGlobal(optarg, "1");
410133085Sharti			MFLAGS_append("-D", optarg);
4111590Srgrimes			break;
4121590Srgrimes		case 'd': {
4131590Srgrimes			char *modules = optarg;
4141590Srgrimes
4151590Srgrimes			for (; *modules; ++modules)
4161590Srgrimes				switch (*modules) {
4171590Srgrimes				case 'A':
4181590Srgrimes					debug = ~0;
4191590Srgrimes					break;
4201590Srgrimes				case 'a':
4211590Srgrimes					debug |= DEBUG_ARCH;
4221590Srgrimes					break;
4231590Srgrimes				case 'c':
4241590Srgrimes					debug |= DEBUG_COND;
4251590Srgrimes					break;
4261590Srgrimes				case 'd':
4271590Srgrimes					debug |= DEBUG_DIR;
4281590Srgrimes					break;
4291590Srgrimes				case 'f':
4301590Srgrimes					debug |= DEBUG_FOR;
4311590Srgrimes					break;
4321590Srgrimes				case 'g':
4331590Srgrimes					if (modules[1] == '1') {
4341590Srgrimes						debug |= DEBUG_GRAPH1;
4351590Srgrimes						++modules;
4361590Srgrimes					}
4371590Srgrimes					else if (modules[1] == '2') {
4381590Srgrimes						debug |= DEBUG_GRAPH2;
4391590Srgrimes						++modules;
4401590Srgrimes					}
4411590Srgrimes					break;
4421590Srgrimes				case 'j':
4431590Srgrimes					debug |= DEBUG_JOB;
4441590Srgrimes					break;
44560569Swill				case 'l':
44660569Swill					debug |= DEBUG_LOUD;
44760569Swill					break;
4481590Srgrimes				case 'm':
4491590Srgrimes					debug |= DEBUG_MAKE;
4501590Srgrimes					break;
4511590Srgrimes				case 's':
4521590Srgrimes					debug |= DEBUG_SUFF;
4531590Srgrimes					break;
4541590Srgrimes				case 't':
4551590Srgrimes					debug |= DEBUG_TARG;
4561590Srgrimes					break;
4571590Srgrimes				case 'v':
4581590Srgrimes					debug |= DEBUG_VAR;
4591590Srgrimes					break;
4601590Srgrimes				default:
461144475Sharti					warnx("illegal argument to d option "
462144475Sharti					    "-- %c", *modules);
4631590Srgrimes					usage();
4641590Srgrimes				}
465133085Sharti			MFLAGS_append("-d", optarg);
4661590Srgrimes			break;
4671590Srgrimes		}
46849332Shoek		case 'E':
469138920Sru			Lst_AtEnd(&envFirstVars, estrdup(optarg));
470133085Sharti			MFLAGS_append("-E", optarg);
47149332Shoek			break;
4721590Srgrimes		case 'e':
4731590Srgrimes			checkEnvFirst = TRUE;
474133085Sharti			MFLAGS_append("-e", NULL);
4751590Srgrimes			break;
4761590Srgrimes		case 'f':
477138920Sru			Lst_AtEnd(&makefiles, estrdup(optarg));
4781590Srgrimes			break;
479187995Simp		case 'I':
480187995Simp			Parse_AddIncludeDir(optarg);
481187995Simp			MFLAGS_append("-I", optarg);
482187995Simp			break;
4831590Srgrimes		case 'i':
4841590Srgrimes			ignoreErrors = TRUE;
485133085Sharti			MFLAGS_append("-i", NULL);
4861590Srgrimes			break;
48749331Shoek		case 'j': {
48849331Shoek			char *endptr;
48949331Shoek
49018730Ssteve			forceJobs = TRUE;
491146140Sharti			jobLimit = strtol(optarg, &endptr, 10);
492146140Sharti			if (jobLimit <= 0 || *endptr != '\0') {
49349938Shoek				warnx("illegal number, -j argument -- %s",
49449938Shoek				    optarg);
49549938Shoek				usage();
49649331Shoek			}
497133085Sharti			MFLAGS_append("-j", optarg);
4981590Srgrimes			break;
49949331Shoek		}
5001590Srgrimes		case 'k':
5011590Srgrimes			keepgoing = TRUE;
502133085Sharti			MFLAGS_append("-k", NULL);
5031590Srgrimes			break;
50418730Ssteve		case 'm':
505201526Sobrien			/* look for magic parent directory search string */
506201526Sobrien			if (strncmp(".../", optarg, 4) == 0) {
507201526Sobrien				if (!Dir_FindHereOrAbove(curdir, optarg + 4,
508201526Sobrien				    found_dir, sizeof(found_dir)))
509201526Sobrien					break;		/* nothing doing */
510201526Sobrien				Path_AddDir(&sysIncPath, found_dir);
511201526Sobrien			} else {
512201526Sobrien				Path_AddDir(&sysIncPath, optarg);
513201526Sobrien			}
514133085Sharti			MFLAGS_append("-m", optarg);
51518730Ssteve			break;
5161590Srgrimes		case 'n':
5171590Srgrimes			noExecute = TRUE;
518133085Sharti			MFLAGS_append("-n", NULL);
5191590Srgrimes			break;
520187995Simp		case 'P':
521187995Simp			usePipes = FALSE;
522187995Simp			MFLAGS_append("-P", NULL);
523187995Simp			break;
524181021Sed		case 'p':
525181021Sed			printGraphOnly = TRUE;
526181021Sed			debug |= DEBUG_GRAPH1;
527181021Sed			break;
528186713Sobrien		case 'Q':
529186713Sobrien			beQuiet = TRUE;
530187132Sobrien			beVerbose = FALSE;
531186713Sobrien			MFLAGS_append("-Q", NULL);
532186713Sobrien			break;
5331590Srgrimes		case 'q':
5341590Srgrimes			queryFlag = TRUE;
5351590Srgrimes			/* Kind of nonsensical, wot? */
536133085Sharti			MFLAGS_append("-q", NULL);
5371590Srgrimes			break;
5381590Srgrimes		case 'r':
5391590Srgrimes			noBuiltins = TRUE;
540133085Sharti			MFLAGS_append("-r", NULL);
5411590Srgrimes			break;
542187995Simp		case 'S':
543187995Simp			keepgoing = FALSE;
544187995Simp			MFLAGS_append("-S", NULL);
545187995Simp			break;
5461590Srgrimes		case 's':
5471590Srgrimes			beSilent = TRUE;
548133085Sharti			MFLAGS_append("-s", NULL);
5491590Srgrimes			break;
5501590Srgrimes		case 't':
5511590Srgrimes			touchFlag = TRUE;
552133085Sharti			MFLAGS_append("-t", NULL);
5531590Srgrimes			break;
554187995Simp		case 'V':
555187995Simp			Lst_AtEnd(&variables, estrdup(optarg));
556187995Simp			MFLAGS_append("-V", optarg);
557187995Simp			break;
55841151Sdg		case 'v':
55941151Sdg			beVerbose = TRUE;
560186713Sobrien			beQuiet = FALSE;
561133085Sharti			MFLAGS_append("-v", NULL);
56241151Sdg			break;
563187995Simp		case 'X':
564187995Simp			expandVars = FALSE;
565187995Simp			break;
566145627Sharti		case 'x':
567145679Sharti			if (Main_ParseWarn(optarg, 1) != -1)
568145627Sharti				MFLAGS_append("-x", optarg);
569145627Sharti			break;
570167330Sfjoe
5711590Srgrimes		default:
5721590Srgrimes		case '?':
5731590Srgrimes			usage();
5741590Srgrimes		}
5751590Srgrimes	}
576144896Sharti	argv += optind;
577144896Sharti	argc -= optind;
5781590Srgrimes
5791590Srgrimes	oldVars = TRUE;
5801590Srgrimes
5811590Srgrimes	/*
582144896Sharti	 * Parse the rest of the arguments.
583144896Sharti	 *	o Check for variable assignments and perform them if so.
584144896Sharti	 *	o Check for more flags and restart getopt if so.
585160442Sobrien	 *	o Anything else is taken to be a target and added
586144896Sharti	 *	  to the end of the "create" list.
5871590Srgrimes	 */
588144896Sharti	for (; *argv != NULL; ++argv, --argc) {
589133562Sharti		if (Parse_IsVar(*argv)) {
590140870Sharti			char *ptr = MAKEFLAGS_quote(*argv);
591167330Sfjoe			char *v = estrdup(*argv);
592133562Sharti
593146146Sharti			Var_Append(".MAKEFLAGS", ptr, VAR_GLOBAL);
594167330Sfjoe			Parse_DoVar(v, VAR_CMD);
595133562Sharti			free(ptr);
596167330Sfjoe			free(v);
597133562Sharti
598144896Sharti		} else if ((*argv)[0] == '-') {
599144896Sharti			if ((*argv)[1] == '\0') {
600144896Sharti				/*
601144896Sharti				 * (*argv) is a single dash, so we
602144896Sharti				 * just ignore it.
603144896Sharti				 */
604146038Sharti			} else if (found_dd) {
605146038Sharti				/*
606146038Sharti				 * Double dash has been found, ignore
607146038Sharti				 * any more options.  But what do we do
608146038Sharti				 * with it?  For now treat it like a target.
609146038Sharti				 */
610146038Sharti				Lst_AtEnd(&create, estrdup(*argv));
611144896Sharti			} else {
612144896Sharti				/*
613146038Sharti				 * (*argv) is a -flag, so backup argv and
614146038Sharti				 * argc.  getopt() expects options to start
615146038Sharti				 * in the 2nd position.
616144896Sharti				 */
617144896Sharti				argc++;
618144896Sharti				argv--;
6191590Srgrimes				goto rearg;
6201590Srgrimes			}
621144896Sharti
622144896Sharti		} else if ((*argv)[0] == '\0') {
623144896Sharti			Punt("illegal (null) argument.");
624144896Sharti
625144896Sharti		} else {
626138916Sharti			Lst_AtEnd(&create, estrdup(*argv));
6271590Srgrimes		}
628144896Sharti	}
6291590Srgrimes}
6301590Srgrimes
631144475Sharti/**
632144475Sharti * Main_ParseArgLine
633160442Sobrien *	Used by the parse module when a .MFLAGS or .MAKEFLAGS target
6341590Srgrimes *	is encountered and by main() when reading the .MAKEFLAGS envariable.
6351590Srgrimes *	Takes a line of arguments and breaks it into its
636160442Sobrien *	component words and passes those words and the number of them to the
6371590Srgrimes *	MainParseArgs function.
6381590Srgrimes *	The line should have all its leading whitespace removed.
6391590Srgrimes *
6401590Srgrimes * Side Effects:
6411590Srgrimes *	Only those that come from the various arguments.
6421590Srgrimes */
6431590Srgrimesvoid
644140870ShartiMain_ParseArgLine(char *line, int mflags)
6451590Srgrimes{
646146345Sharti	ArgArray	aa;
6471590Srgrimes
6481590Srgrimes	if (line == NULL)
6491590Srgrimes		return;
6501590Srgrimes	for (; *line == ' '; ++line)
6511590Srgrimes		continue;
6521590Srgrimes	if (!*line)
6531590Srgrimes		return;
6541590Srgrimes
655140870Sharti	if (mflags)
656146345Sharti		MAKEFLAGS_break(&aa, line);
657140870Sharti	else
658146345Sharti		brk_string(&aa, line, TRUE);
659140870Sharti
660146345Sharti	MainParseArgs(aa.argc, aa.argv);
661146345Sharti	ArgArray_Done(&aa);
6621590Srgrimes}
6631590Srgrimes
664146146Shartistatic char *
665141252Shartichdir_verify_path(const char *path, char *obpath)
66618339Sswallace{
66718339Sswallace	struct stat sb;
66818339Sswallace
66918339Sswallace	if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
67075973Sru		if (chdir(path) == -1 || getcwd(obpath, MAXPATHLEN) == NULL) {
67127644Scharnier			warn("warning: %s", path);
672141252Sharti			return (NULL);
67318339Sswallace		}
674138232Sharti		return (obpath);
67518339Sswallace	}
67618339Sswallace
677141252Sharti	return (NULL);
67818339Sswallace}
67918339Sswallace
680146144Sharti/**
681146144Sharti * In lieu of a good way to prevent every possible looping in make(1), stop
682146144Sharti * there from being more than MKLVL_MAXVAL processes forked by make(1), to
683146144Sharti * prevent a forkbomb from happening, in a dumb and mechanical way.
684146144Sharti *
685146144Sharti * Side Effects:
686228992Suqs *	Creates or modifies environment variable MKLVL_ENVVAR via setenv().
687138071Sjmallett */
688138071Sjmallettstatic void
689138071Sjmallettcheck_make_level(void)
690138071Sjmallett{
691138071Sjmallett#ifdef WANT_ENV_MKLVL
692138071Sjmallett	char	*value = getenv(MKLVL_ENVVAR);
693138071Sjmallett	int	level = (value == NULL) ? 0 : atoi(value);
694138071Sjmallett
695138071Sjmallett	if (level < 0) {
696213493Simp		errx(2, "Invalid value for recursion level (%d).", level);
697138071Sjmallett	} else if (level > MKLVL_MAXVAL) {
698213493Simp		errx(2, "Max recursion level (%d) exceeded.", MKLVL_MAXVAL);
699138071Sjmallett	} else {
700138071Sjmallett		char new_value[32];
701138071Sjmallett		sprintf(new_value, "%d", level + 1);
702138071Sjmallett		setenv(MKLVL_ENVVAR, new_value, 1);
703138071Sjmallett	}
704138071Sjmallett#endif /* WANT_ENV_MKLVL */
705138071Sjmallett}
706138071Sjmallett
707144475Sharti/**
708167330Sfjoe * Main_AddSourceMakefile
709167330Sfjoe *	Add a file to the list of source makefiles
710167330Sfjoe */
711167330Sfjoevoid
712167330SfjoeMain_AddSourceMakefile(const char *name)
713167330Sfjoe{
714167330Sfjoe
715167330Sfjoe	Lst_AtEnd(&source_makefiles, estrdup(name));
716167330Sfjoe}
717167330Sfjoe
718167330Sfjoe/**
719167330Sfjoe * Remake_Makefiles
720167330Sfjoe *	Remake all the makefiles
721167330Sfjoe */
722167330Sfjoestatic void
723167330SfjoeRemake_Makefiles(void)
724167330Sfjoe{
725198199Sfjoe	Lst cleanup;
726167330Sfjoe	LstNode *ln;
727167330Sfjoe	int error_cnt = 0;
728167330Sfjoe	int remade_cnt = 0;
729167330Sfjoe
730167330Sfjoe	Compat_InstallSignalHandlers();
731170179Sfjoe	if (curdir != objdir) {
732170179Sfjoe		if (chdir(curdir) < 0)
733170179Sfjoe			Fatal("Failed to change directory to %s.", curdir);
734170179Sfjoe	}
735167330Sfjoe
736198199Sfjoe	Lst_Init(&cleanup);
737167330Sfjoe	LST_FOREACH(ln, &source_makefiles) {
738167330Sfjoe		LstNode *ln2;
739167330Sfjoe		struct GNode *gn;
740167330Sfjoe		const char *name = Lst_Datum(ln);
741167330Sfjoe		Boolean saveTouchFlag = touchFlag;
742167330Sfjoe		Boolean saveQueryFlag = queryFlag;
743167330Sfjoe		Boolean saveNoExecute = noExecute;
744168892Sfjoe		int mtime;
745167330Sfjoe
746167330Sfjoe		/*
747167330Sfjoe		 * Create node
748167330Sfjoe		 */
749167330Sfjoe		gn = Targ_FindNode(name, TARG_CREATE);
750167330Sfjoe		DEBUGF(MAKE, ("Checking %s...", gn->name));
751167330Sfjoe		Suff_FindDeps(gn);
752167330Sfjoe
753167330Sfjoe		/*
754167330Sfjoe		 * -t, -q and -n has no effect unless the makefile is
755167330Sfjoe		 * specified as one of the targets explicitly in the
756167330Sfjoe		 * command line
757167330Sfjoe		 */
758167330Sfjoe		LST_FOREACH(ln2, &create) {
759167330Sfjoe			if (!strcmp(gn->name, Lst_Datum(ln2))) {
760167330Sfjoe				/* found as a target */
761167330Sfjoe				break;
762167330Sfjoe			}
763167330Sfjoe		}
764167330Sfjoe		if (ln2 == NULL) {
765167330Sfjoe			touchFlag = FALSE;
766167330Sfjoe			queryFlag = FALSE;
767167330Sfjoe			noExecute = FALSE;
768167330Sfjoe		}
769167330Sfjoe
770167330Sfjoe		/*
771167330Sfjoe		 * Check and remake the makefile
772167330Sfjoe		 */
773168892Sfjoe		mtime = Dir_MTime(gn);
774190821Sfjoe		remakingMakefiles = TRUE;
775167330Sfjoe		Compat_Make(gn, gn);
776190821Sfjoe		remakingMakefiles = FALSE;
777167330Sfjoe
778167330Sfjoe		/*
779167330Sfjoe		 * Restore -t, -q and -n behaviour
780167330Sfjoe		 */
781167330Sfjoe		touchFlag = saveTouchFlag;
782167330Sfjoe		queryFlag = saveQueryFlag;
783167330Sfjoe		noExecute = saveNoExecute;
784167330Sfjoe
785167330Sfjoe		/*
786167330Sfjoe		 * Compat_Make will leave the 'made' field of gn
787167330Sfjoe		 * in one of the following states:
788167330Sfjoe		 *	UPTODATE  gn was already up-to-date
789167330Sfjoe		 *	MADE	  gn was recreated successfully
790167330Sfjoe		 *	ERROR	  An error occurred while gn was being created
791167330Sfjoe		 *	ABORTED	  gn was not remade because one of its inferiors
792167330Sfjoe		 *		  could not be made due to errors.
793167330Sfjoe		 */
794168892Sfjoe		if (gn->made == MADE) {
795168892Sfjoe			if (mtime != Dir_MTime(gn)) {
796168892Sfjoe				DEBUGF(MAKE,
797168892Sfjoe				    ("%s updated (%d -> %d).\n",
798168892Sfjoe				     gn->name, mtime, gn->mtime));
799168892Sfjoe				remade_cnt++;
800168892Sfjoe			} else {
801168892Sfjoe				DEBUGF(MAKE,
802168892Sfjoe				    ("%s not updated: skipping restart.\n",
803168892Sfjoe				     gn->name));
804168892Sfjoe			}
805168892Sfjoe		} else if (gn->made == ERROR)
806167330Sfjoe			error_cnt++;
807167330Sfjoe		else if (gn->made == ABORTED) {
808167330Sfjoe			printf("`%s' not remade because of errors.\n",
809167330Sfjoe			    gn->name);
810167330Sfjoe			error_cnt++;
811173919Sfjoe		} else if (gn->made == UPTODATE) {
812198199Sfjoe			Lst_EnQueue(&cleanup, gn);
813167330Sfjoe		}
814167330Sfjoe	}
815167330Sfjoe
816167330Sfjoe	if (error_cnt > 0)
817167330Sfjoe		Fatal("Failed to remake Makefiles.");
818167330Sfjoe	if (remade_cnt > 0) {
819167330Sfjoe		DEBUGF(MAKE, ("Restarting `%s'.\n", save_argv[0]));
820167330Sfjoe
821167330Sfjoe		/*
822167330Sfjoe		 * Some of makefiles were remade -- restart from clean state
823167330Sfjoe		 */
824167330Sfjoe		if (save_makeflags != NULL)
825167330Sfjoe			setenv("MAKEFLAGS", save_makeflags, 1);
826167330Sfjoe		else
827167330Sfjoe			unsetenv("MAKEFLAGS");
828167330Sfjoe		if (execvp(save_argv[0], save_argv) < 0) {
829167330Sfjoe			Fatal("Can't restart `%s': %s.",
830167330Sfjoe			    save_argv[0], strerror(errno));
831167330Sfjoe		}
832167330Sfjoe	}
833170179Sfjoe
834198199Sfjoe	while (!Lst_IsEmpty(&cleanup)) {
835198199Sfjoe		GNode *gn = Lst_DeQueue(&cleanup);
836198199Sfjoe
837198199Sfjoe		gn->unmade = 0;
838198199Sfjoe		gn->make = FALSE;
839198199Sfjoe		gn->made = UNMADE;
840198199Sfjoe		gn->childMade = FALSE;
841198199Sfjoe		gn->mtime = gn->cmtime = 0;
842198199Sfjoe		gn->cmtime_gn = NULL;
843198199Sfjoe
844198199Sfjoe		LST_FOREACH(ln, &gn->children) {
845198199Sfjoe			GNode *cgn = Lst_Datum(ln);
846198199Sfjoe
847198199Sfjoe			gn->unmade++;
848198199Sfjoe			Lst_EnQueue(&cleanup, cgn);
849198199Sfjoe		}
850198199Sfjoe	}
851198199Sfjoe
852170179Sfjoe	if (curdir != objdir) {
853170179Sfjoe		if (chdir(objdir) < 0)
854170179Sfjoe			Fatal("Failed to change directory to %s.", objdir);
855170179Sfjoe	}
856167330Sfjoe}
857167330Sfjoe
858167330Sfjoe/**
859144475Sharti * main
8601590Srgrimes *	The main function, for obvious reasons. Initializes variables
8611590Srgrimes *	and a few modules, then parses the arguments give it in the
8621590Srgrimes *	environment and on the command line. Reads the system makefile
8631590Srgrimes *	followed by either Makefile, makefile or the file given by the
8641590Srgrimes *	-f argument. Sets the .MAKEFLAGS PMake variable based on all the
8651590Srgrimes *	flags it has received by then uses either the Make or the Compat
8661590Srgrimes *	module to create the initial list of targets.
8671590Srgrimes *
8681590Srgrimes * Results:
8691590Srgrimes *	If -q was given, exits -1 if anything was out-of-date. Else it exits
8701590Srgrimes *	0.
8711590Srgrimes *
8721590Srgrimes * Side Effects:
8731590Srgrimes *	The program exits when done. Targets are created. etc. etc. etc.
8741590Srgrimes */
8751590Srgrimesint
876104696Sjmallettmain(int argc, char **argv)
8771590Srgrimes{
878160442Sobrien	const char *machine;
879146144Sharti	const char *machine_arch;
880146144Sharti	const char *machine_cpu;
881160442Sobrien	Boolean outOfDate = TRUE;	/* FALSE if all targets up to date */
882146581Sharti	const char *p;
883146157Sharti	const char *pathp;
884146157Sharti	const char *path;
88573262Simp	char mdpath[MAXPATHLEN];
88673262Simp	char obpath[MAXPATHLEN];
88773262Simp	char cdpath[MAXPATHLEN];
888201526Sobrien	char found_dir[MAXPATHLEN + 1];	/* for searching for sys.mk */
88918730Ssteve	char *cp = NULL, *start;
890141252Sharti
891167330Sfjoe	save_argv = argv;
892167330Sfjoe	save_makeflags = getenv("MAKEFLAGS");
893167330Sfjoe	if (save_makeflags != NULL)
894167330Sfjoe		save_makeflags = estrdup(save_makeflags);
895167330Sfjoe
896146146Sharti	/*
897146146Sharti	 * Initialize file global variables.
898146146Sharti	 */
899146146Sharti	expandVars = TRUE;
900146146Sharti	noBuiltins = FALSE;		/* Read the built-in rules */
901160442Sobrien	forceJobs = FALSE;		/* No -j flag */
902146146Sharti	curdir = cdpath;
903146146Sharti
904146146Sharti	/*
905146146Sharti	 * Initialize program global variables.
906146146Sharti	 */
907146146Sharti	beSilent = FALSE;		/* Print commands as executed */
908146146Sharti	ignoreErrors = FALSE;		/* Pay attention to non-zero returns */
909146146Sharti	noExecute = FALSE;		/* Execute all commands */
910181021Sed	printGraphOnly = FALSE;		/* Don't stop after printing graph */
911146146Sharti	keepgoing = FALSE;		/* Stop on error */
912146146Sharti	allPrecious = FALSE;		/* Remove targets when interrupted */
913146146Sharti	queryFlag = FALSE;		/* This is not just a check-run */
914146146Sharti	touchFlag = FALSE;		/* Actually update targets */
915146146Sharti	usePipes = TRUE;		/* Catch child output in pipes */
916146146Sharti	debug = 0;			/* No debug verbosity, please. */
917146146Sharti	jobsRunning = FALSE;
918146146Sharti
919146146Sharti	jobLimit = DEFMAXJOBS;
920146146Sharti	compatMake = FALSE;		/* No compat mode */
921146146Sharti
922138071Sjmallett	check_make_level();
923104395Sjmallett
92418730Ssteve#ifdef RLIMIT_NOFILE
9251590Srgrimes	/*
92618730Ssteve	 * get rid of resource limit on file descriptors
92718730Ssteve	 */
92818730Ssteve	{
92918730Ssteve		struct rlimit rl;
930146144Sharti		if (getrlimit(RLIMIT_NOFILE, &rl) == -1) {
931146144Sharti			err(2, "getrlimit");
93218730Ssteve		}
933146144Sharti		rl.rlim_cur = rl.rlim_max;
934146144Sharti		if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
935146144Sharti			err(2, "setrlimit");
936146144Sharti		}
93718730Ssteve	}
93818730Ssteve#endif
9391590Srgrimes
9405814Sjkh	/*
9415814Sjkh	 * Get the name of this type of MACHINE from utsname
9425814Sjkh	 * so we can share an executable for similar machines.
9435814Sjkh	 * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
9445814Sjkh	 *
945153115Sru	 * Note that both MACHINE and MACHINE_ARCH are decided at
946153115Sru	 * run-time.
9475814Sjkh	 */
948213494Simp	if ((machine = getenv("MACHINE")) == NULL) {
949144475Sharti		static struct utsname utsname;
950230392Srmh		unsigned int i;
95118730Ssteve
952144475Sharti		if (uname(&utsname) == -1)
953144475Sharti			err(2, "uname");
954144475Sharti		machine = utsname.machine;
955230392Srmh
956230392Srmh		/* Canonicalize non-FreeBSD naming conventions */
957230392Srmh		for (i = 0; i < sizeof(arch_aliases)
958230392Srmh		     / sizeof(arch_aliases[0]); i++)
959230392Srmh			if (!strcmp(machine, arch_aliases[i].foreign_name)) {
960230392Srmh				machine = arch_aliases[i].freebsd_name;
961230392Srmh				break;
962230392Srmh			}
9635814Sjkh	}
9641590Srgrimes
965146144Sharti	if ((machine_arch = getenv("MACHINE_ARCH")) == NULL) {
966146144Sharti#ifdef MACHINE_ARCH
967146144Sharti		machine_arch = MACHINE_ARCH;
968146144Sharti#else
96944362Simp		machine_arch = "unknown";
97044362Simp#endif
97144362Simp	}
97244362Simp
9731590Srgrimes	/*
974228992Suqs	 * Set machine_cpu to the minimum supported CPU revision based
97572679Skris	 * on the target architecture, if not already set.
97672679Skris	 */
977146144Sharti	if ((machine_cpu = getenv("MACHINE_CPU")) == NULL) {
97872679Skris		if (!strcmp(machine_arch, "i386"))
979243831Sjkim			machine_cpu = "i486";
98072679Skris		else
98172679Skris			machine_cpu = "unknown";
98272679Skris	}
9831590Srgrimes
9841590Srgrimes	/*
9851590Srgrimes	 * Initialize the parsing, directory and variable modules to prepare
9861590Srgrimes	 * for the reading of inclusion paths and variable settings on the
9871590Srgrimes	 * command line
9881590Srgrimes	 */
989146144Sharti	Proc_Init();
990146144Sharti
9911590Srgrimes	Dir_Init();		/* Initialize directory structures so -I flags
9921590Srgrimes				 * can be processed correctly */
993145971Sharti	Var_Init(environ);	/* As well as the lists of variables for
9941590Srgrimes				 * parsing arguments */
995146560Sharti
9961590Srgrimes	/*
997146560Sharti	 * Initialize the Shell so that we have a shell for != assignments
998146560Sharti	 * on the command line.
999146560Sharti	 */
1000146560Sharti	Shell_Init();
1001146560Sharti
1002146560Sharti	/*
10031590Srgrimes	 * Initialize various variables.
10041590Srgrimes	 *	MAKE also gets this name, for compatibility
10051590Srgrimes	 *	.MAKEFLAGS gets set to the empty string just in case.
10061590Srgrimes	 *	MFLAGS also gets initialized empty, for compatibility.
10071590Srgrimes	 */
1008146145Sharti	Var_SetGlobal("MAKE", argv[0]);
1009146146Sharti	Var_SetGlobal(".MAKEFLAGS", "");
1010146145Sharti	Var_SetGlobal("MFLAGS", "");
1011146145Sharti	Var_SetGlobal("MACHINE", machine);
1012146145Sharti	Var_SetGlobal("MACHINE_ARCH", machine_arch);
1013146145Sharti	Var_SetGlobal("MACHINE_CPU", machine_cpu);
101497121Sru#ifdef MAKE_VERSION
1015146145Sharti	Var_SetGlobal("MAKE_VERSION", MAKE_VERSION);
101697121Sru#endif
1017186559Sobrien	Var_SetGlobal(".newline", "\n");	/* handy for :@ loops */
1018186559Sobrien	{
1019186559Sobrien		char tmp[64];
10201590Srgrimes
1021186559Sobrien		snprintf(tmp, sizeof(tmp), "%u", getpid());
1022186559Sobrien		Var_SetGlobal(".MAKE.PID", tmp);
1023186559Sobrien		snprintf(tmp, sizeof(tmp), "%u", getppid());
1024186559Sobrien		Var_SetGlobal(".MAKE.PPID", tmp);
1025186559Sobrien	}
1026186559Sobrien	Job_SetPrefix();
1027186559Sobrien
10281590Srgrimes	/*
1029201526Sobrien	 * Find where we are...
1030201526Sobrien	 */
1031201526Sobrien	if (getcwd(curdir, MAXPATHLEN) == NULL)
1032201526Sobrien		err(2, NULL);
1033201526Sobrien
1034201526Sobrien	/*
1035144896Sharti	 * First snag things out of the MAKEFLAGS environment
1036144896Sharti	 * variable.  Then parse the command line arguments.
10371590Srgrimes	 */
1038140870Sharti	Main_ParseArgLine(getenv("MAKEFLAGS"), 1);
10398874Srgrimes
10401590Srgrimes	MainParseArgs(argc, argv);
10411590Srgrimes
10421590Srgrimes	/*
1043201526Sobrien	 * Verify that cwd is sane (after -C may have changed it).
1044120053Sru	 */
1045141252Sharti	{
1046141252Sharti	struct stat sa;
1047141252Sharti
1048120053Sru	if (stat(curdir, &sa) == -1)
1049120053Sru	    err(2, "%s", curdir);
1050141252Sharti	}
1051120053Sru
1052120053Sru	/*
1053120053Sru	 * The object directory location is determined using the
1054120053Sru	 * following order of preference:
1055120053Sru	 *
1056120053Sru	 *	1. MAKEOBJDIRPREFIX`cwd`
1057120053Sru	 *	2. MAKEOBJDIR
1058143412Sharti	 *	3. PATH_OBJDIR.${MACHINE}
1059143412Sharti	 *	4. PATH_OBJDIR
1060143412Sharti	 *	5. PATH_OBJDIRPREFIX`cwd`
1061120053Sru	 *
1062120053Sru	 * If one of the first two fails, use the current directory.
1063120053Sru	 * If the remaining three all fail, use the current directory.
1064120053Sru	 *
1065120053Sru	 * Once things are initted,
1066120053Sru	 * have to add the original directory to the search path,
1067228992Suqs	 * and modify the paths for the Makefiles appropriately.  The
1068120053Sru	 * current directory is also placed as a variable for make scripts.
1069120053Sru	 */
1070120053Sru	if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
1071120053Sru		if (!(path = getenv("MAKEOBJDIR"))) {
1072143412Sharti			path = PATH_OBJDIR;
1073143412Sharti			pathp = PATH_OBJDIRPREFIX;
1074146145Sharti			snprintf(mdpath, MAXPATHLEN, "%s.%s", path, machine);
1075120053Sru			if (!(objdir = chdir_verify_path(mdpath, obpath)))
1076120053Sru				if (!(objdir=chdir_verify_path(path, obpath))) {
1077138232Sharti					snprintf(mdpath, MAXPATHLEN,
1078120053Sru							"%s%s", pathp, curdir);
1079120053Sru					if (!(objdir=chdir_verify_path(mdpath,
1080120053Sru								       obpath)))
1081120053Sru						objdir = curdir;
1082120053Sru				}
1083120053Sru		}
1084120053Sru		else if (!(objdir = chdir_verify_path(path, obpath)))
1085120053Sru			objdir = curdir;
1086120053Sru	}
1087120053Sru	else {
1088138232Sharti		snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
1089120053Sru		if (!(objdir = chdir_verify_path(mdpath, obpath)))
1090120053Sru			objdir = curdir;
1091120053Sru	}
1092120053Sru	Dir_InitDot();		/* Initialize the "." directory */
1093120053Sru	if (objdir != curdir)
1094144020Sharti		Path_AddDir(&dirSearchPath, curdir);
1095146145Sharti	Var_SetGlobal(".ST_EXPORTVAR", "YES");
1096146145Sharti	Var_SetGlobal(".CURDIR", curdir);
1097146145Sharti	Var_SetGlobal(".OBJDIR", objdir);
1098120053Sru
1099137606Sphk	if (getenv("MAKE_JOBS_FIFO") != NULL)
1100137606Sphk		forceJobs = TRUE;
1101120053Sru	/*
110228228Sfsmp	 * Be compatible if user did not specify -j and did not explicitly
110328228Sfsmp	 * turned compatibility on
110428228Sfsmp	 */
110528228Sfsmp	if (!compatMake && !forceJobs)
110628228Sfsmp		compatMake = TRUE;
110728228Sfsmp
110828228Sfsmp	/*
1109144387Sharti	 * Initialize target and suffix modules in preparation for
11101590Srgrimes	 * parsing the makefile(s)
11111590Srgrimes	 */
11121590Srgrimes	Targ_Init();
11131590Srgrimes	Suff_Init();
11141590Srgrimes
111569527Swill	DEFAULT = NULL;
1116138232Sharti	time(&now);
11171590Srgrimes
11181590Srgrimes	/*
11191590Srgrimes	 * Set up the .TARGETS variable to contain the list of targets to be
11201590Srgrimes	 * created. If none specified, make the variable empty -- the parser
11211590Srgrimes	 * will fill the thing in with the default or .MAIN target.
11221590Srgrimes	 */
1123146145Sharti	if (Lst_IsEmpty(&create)) {
1124146145Sharti		Var_SetGlobal(".TARGETS", "");
1125146145Sharti	} else {
1126138512Sharti		LstNode *ln;
11271590Srgrimes
1128138916Sharti		for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) {
1129138264Sharti			char *name = Lst_Datum(ln);
11301590Srgrimes
11311590Srgrimes			Var_Append(".TARGETS", name, VAR_GLOBAL);
11321590Srgrimes		}
1133146145Sharti	}
11341590Srgrimes
113518730Ssteve
11361590Srgrimes	/*
113718730Ssteve	 * If no user-supplied system path was given (through the -m option)
113818730Ssteve	 * add the directories from the DEFSYSPATH (more than one may be given
113918730Ssteve	 * as dir1:...:dirn) to the system include path.
11401590Srgrimes	 */
1141144020Sharti	if (TAILQ_EMPTY(&sysIncPath)) {
1142201526Sobrien		char defsyspath[] = PATH_DEFSYSPATH;
1143201526Sobrien		char *syspath = getenv("MAKESYSPATH");
1144146144Sharti
1145201526Sobrien		/*
1146201526Sobrien		 * If no user-supplied system path was given (thru -m option)
1147201526Sobrien		 * add the directories from the DEFSYSPATH (more than one may
1148201526Sobrien		 * be given as dir1:...:dirn) to the system include path.
1149201526Sobrien		 */
1150201526Sobrien		if (syspath == NULL || *syspath == '\0')
1151201526Sobrien			syspath = defsyspath;
1152201526Sobrien		else
1153201526Sobrien			syspath = estrdup(syspath);
1154201526Sobrien
115518730Ssteve		for (start = syspath; *start != '\0'; start = cp) {
115618730Ssteve			for (cp = start; *cp != '\0' && *cp != ':'; cp++)
115718730Ssteve				continue;
1158201526Sobrien			if (*cp == ':') {
1159201526Sobrien				*cp++ = '\0';
1160201526Sobrien			}
1161201526Sobrien			/* look for magic parent directory search string */
1162201526Sobrien			if (strncmp(".../", start, 4) == 0) {
1163201526Sobrien				if (Dir_FindHereOrAbove(curdir, start + 4,
1164201526Sobrien				    found_dir, sizeof(found_dir))) {
1165201526Sobrien					Path_AddDir(&sysIncPath, found_dir);
1166201526Sobrien				}
116718730Ssteve			} else {
1168144020Sharti				Path_AddDir(&sysIncPath, start);
116918730Ssteve			}
117018730Ssteve		}
1171201526Sobrien		if (syspath != defsyspath)
1172201526Sobrien			free(syspath);
117318730Ssteve	}
11741590Srgrimes
117518730Ssteve	/*
117618730Ssteve	 * Read in the built-in rules first, followed by the specified
117718730Ssteve	 * makefile, if it was (makefile != (char *) NULL), or the default
117818730Ssteve	 * Makefile and makefile, in that order, if it wasn't.
117918730Ssteve	 */
118018730Ssteve	if (!noBuiltins) {
1181138916Sharti		/* Path of sys.mk */
1182138916Sharti		Lst sysMkPath = Lst_Initializer(sysMkPath);
1183138512Sharti		LstNode *ln;
1184146064Sharti		char	defsysmk[] = PATH_DEFSYSMK;
118518730Ssteve
1186146064Sharti		Path_Expand(defsysmk, &sysIncPath, &sysMkPath);
1187138916Sharti		if (Lst_IsEmpty(&sysMkPath))
1188143412Sharti			Fatal("make: no system rules (%s).", PATH_DEFSYSMK);
1189143808Sharti		LST_FOREACH(ln, &sysMkPath) {
1190143808Sharti			if (!ReadMakefile(Lst_Datum(ln)))
1191143808Sharti				break;
1192143808Sharti		}
119369527Swill		if (ln != NULL)
119418730Ssteve			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
1195138916Sharti		Lst_Destroy(&sysMkPath, free);
119618730Ssteve	}
119718730Ssteve
1198138916Sharti	if (!Lst_IsEmpty(&makefiles)) {
1199138512Sharti		LstNode *ln;
12001590Srgrimes
1201143808Sharti		LST_FOREACH(ln, &makefiles) {
1202167330Sfjoe			if (!TryReadMakefile(Lst_Datum(ln)))
1203143808Sharti				break;
1204143808Sharti		}
120569527Swill		if (ln != NULL)
12061590Srgrimes			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
1207167330Sfjoe	} else if (!TryReadMakefile("BSDmakefile"))
1208167330Sfjoe	    if (!TryReadMakefile("makefile"))
1209167330Sfjoe		TryReadMakefile("Makefile");
12101590Srgrimes
1211143808Sharti	ReadMakefile(".depend");
12121590Srgrimes
1213176842Syar	/* Install all the flags into the MAKEFLAGS envariable. */
1214146580Sharti	if (((p = Var_Value(".MAKEFLAGS", VAR_GLOBAL)) != NULL) && *p)
12151590Srgrimes		setenv("MAKEFLAGS", p, 1);
1216176839Syar	else
1217176839Syar		setenv("MAKEFLAGS", "", 1);
12181590Srgrimes
12191590Srgrimes	/*
12201590Srgrimes	 * For compatibility, look at the directories in the VPATH variable
12211590Srgrimes	 * and add them to the search path, if the variable is defined. The
12221590Srgrimes	 * variable's value is in the same format as the PATH envariable, i.e.
12231590Srgrimes	 * <directory>:<directory>:<directory>...
12241590Srgrimes	 */
12251590Srgrimes	if (Var_Exists("VPATH", VAR_CMD)) {
12261590Srgrimes		/*
12271590Srgrimes		 * GCC stores string constants in read-only memory, but
12281590Srgrimes		 * Var_Subst will want to write this thing, so store it
12291590Srgrimes		 * in an array
12301590Srgrimes		 */
12311590Srgrimes		static char VPATH[] = "${VPATH}";
1232142457Sharti		Buffer	*buf;
1233142457Sharti		char	*vpath;
1234142457Sharti		char	*ptr;
1235142457Sharti		char	savec;
12361590Srgrimes
1237146027Sharti		buf = Var_Subst(VPATH, VAR_CMD, FALSE);
1238142457Sharti
1239143959Sharti		vpath = Buf_Data(buf);
12401590Srgrimes		do {
12411590Srgrimes			/* skip to end of directory */
1242142457Sharti			for (ptr = vpath; *ptr != ':' && *ptr != '\0'; ptr++)
1243141969Sharti				;
1244141969Sharti
12451590Srgrimes			/* Save terminator character so know when to stop */
1246141969Sharti			savec = *ptr;
1247141969Sharti			*ptr = '\0';
1248141969Sharti
12491590Srgrimes			/* Add directory to search path */
1250144020Sharti			Path_AddDir(&dirSearchPath, vpath);
1251141969Sharti
1252142457Sharti			vpath = ptr + 1;
1253141969Sharti		} while (savec != '\0');
1254142457Sharti
1255142457Sharti		Buf_Destroy(buf, TRUE);
12561590Srgrimes	}
12571590Srgrimes
12581590Srgrimes	/*
12591590Srgrimes	 * Now that all search paths have been read for suffixes et al, it's
12601590Srgrimes	 * time to add the default search path to their lists...
12611590Srgrimes	 */
12621590Srgrimes	Suff_DoPaths();
12631590Srgrimes
12641590Srgrimes	/* print the initial graph, if the user requested it */
12651590Srgrimes	if (DEBUG(GRAPH1))
12661590Srgrimes		Targ_PrintGraph(1);
12671590Srgrimes
126817193Sbde	/* print the values of any variables requested by the user */
1269181021Sed	if (Lst_IsEmpty(&variables) && !printGraphOnly) {
12701590Srgrimes		/*
1271141974Sharti		 * Since the user has not requested that any variables
1272142008Sharti		 * be printed, we can build targets.
1273141974Sharti		 *
1274142008Sharti		 * Have read the entire graph and need to make a list of targets
1275141974Sharti		 * to create. If none was given on the command line, we consult
1276141974Sharti		 * the parsing module to find the main target(s) to create.
12771590Srgrimes		 */
1278138916Sharti		Lst targs = Lst_Initializer(targs);
1279138916Sharti
1280177101Sobrien		if (!is_posix && mfAutoDeps) {
1281167330Sfjoe			/*
1282167330Sfjoe			 * Check if any of the makefiles are out-of-date.
1283167330Sfjoe			 */
1284167330Sfjoe			Remake_Makefiles();
1285167330Sfjoe		}
1286167330Sfjoe
1287138916Sharti		if (Lst_IsEmpty(&create))
1288138916Sharti			Parse_MainName(&targs);
1289101460Sru		else
1290138916Sharti			Targ_FindList(&targs, &create, TARG_CREATE);
1291101460Sru
1292141974Sharti		if (compatMake) {
1293101460Sru			/*
1294141974Sharti			 * Compat_Init will take care of creating
1295141974Sharti			 * all the targets as well as initializing
1296141974Sharti			 * the module.
1297101460Sru			 */
1298141974Sharti			Compat_Run(&targs);
1299141974Sharti			outOfDate = 0;
1300141974Sharti		} else {
1301141974Sharti			/*
1302141974Sharti			 * Initialize job module before traversing
1303141974Sharti			 * the graph, now that any .BEGIN and .END
1304141974Sharti			 * targets have been read.  This is done
1305141974Sharti			 * only if the -q flag wasn't given (to
1306141974Sharti			 * prevent the .BEGIN from being executed
1307141974Sharti			 * should it exist).
1308141974Sharti			 */
1309101460Sru			if (!queryFlag) {
1310146140Sharti				Job_Init(jobLimit);
1311101460Sru				jobsRunning = TRUE;
1312101460Sru			}
1313101460Sru
1314101460Sru			/* Traverse the graph, checking on all the targets */
1315138916Sharti			outOfDate = Make_Run(&targs);
13161590Srgrimes		}
1317138916Sharti		Lst_Destroy(&targs, NOFREE);
1318141974Sharti
1319141974Sharti	} else {
1320146141Sharti		Var_Print(&variables, expandVars);
132117193Sbde	}
13228874Srgrimes
1323138920Sru	Lst_Destroy(&variables, free);
1324138920Sru	Lst_Destroy(&makefiles, free);
1325167330Sfjoe	Lst_Destroy(&source_makefiles, free);
1326138916Sharti	Lst_Destroy(&create, free);
13275814Sjkh
13281590Srgrimes	/* print the graph now it's been processed if the user requested it */
13291590Srgrimes	if (DEBUG(GRAPH2))
13301590Srgrimes		Targ_PrintGraph(2);
13311590Srgrimes
1332186279Sfjoe	if (queryFlag)
1333186279Sfjoe		return (outOfDate);
1334186279Sfjoe
1335186279Sfjoe	if (makeErrors != 0)
1336186279Sfjoe		Finish(makeErrors);
1337186279Sfjoe
1338186279Sfjoe	return (0);
13391590Srgrimes}
1340