main.c revision 198199
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 198199 2009-10-18 11:28:31Z fjoe $");
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;
3711590Srgrimes
372144896Shartirearg:
3731590Srgrimes	optind = 1;	/* since we're called more than once */
374144896Sharti	optreset = 1;
375187995Simp#define OPTFLAGS "ABC:D:d:E:ef:I:ij:km:nPpQqrSstV:vXx:"
376146038Sharti	for (;;) {
377146038Sharti		if ((optind < argc) && strcmp(argv[optind], "--") == 0) {
378146038Sharti			found_dd = TRUE;
379146038Sharti		}
380146038Sharti		if ((c = getopt(argc, argv, OPTFLAGS)) == -1) {
381146038Sharti			break;
382146038Sharti		}
3831590Srgrimes		switch(c) {
384144387Sharti
385144387Sharti		case 'A':
386144387Sharti			arch_fatal = FALSE;
387144387Sharti			MFLAGS_append("-A", NULL);
388144387Sharti			break;
389187995Simp		case 'B':
390187995Simp			compatMake = TRUE;
391187995Simp			MFLAGS_append("-B", NULL);
392187995Simp			unsetenv("MAKE_JOBS_FIFO");
393187995Simp			break;
394102393Sjmallett		case 'C':
395107964Sseanc			if (chdir(optarg) == -1)
396107964Sseanc				err(1, "chdir %s", optarg);
397102393Sjmallett			break;
3981590Srgrimes		case 'D':
399146145Sharti			Var_SetGlobal(optarg, "1");
400133085Sharti			MFLAGS_append("-D", optarg);
4011590Srgrimes			break;
4021590Srgrimes		case 'd': {
4031590Srgrimes			char *modules = optarg;
4041590Srgrimes
4051590Srgrimes			for (; *modules; ++modules)
4061590Srgrimes				switch (*modules) {
4071590Srgrimes				case 'A':
4081590Srgrimes					debug = ~0;
4091590Srgrimes					break;
4101590Srgrimes				case 'a':
4111590Srgrimes					debug |= DEBUG_ARCH;
4121590Srgrimes					break;
4131590Srgrimes				case 'c':
4141590Srgrimes					debug |= DEBUG_COND;
4151590Srgrimes					break;
4161590Srgrimes				case 'd':
4171590Srgrimes					debug |= DEBUG_DIR;
4181590Srgrimes					break;
4191590Srgrimes				case 'f':
4201590Srgrimes					debug |= DEBUG_FOR;
4211590Srgrimes					break;
4221590Srgrimes				case 'g':
4231590Srgrimes					if (modules[1] == '1') {
4241590Srgrimes						debug |= DEBUG_GRAPH1;
4251590Srgrimes						++modules;
4261590Srgrimes					}
4271590Srgrimes					else if (modules[1] == '2') {
4281590Srgrimes						debug |= DEBUG_GRAPH2;
4291590Srgrimes						++modules;
4301590Srgrimes					}
4311590Srgrimes					break;
4321590Srgrimes				case 'j':
4331590Srgrimes					debug |= DEBUG_JOB;
4341590Srgrimes					break;
43560569Swill				case 'l':
43660569Swill					debug |= DEBUG_LOUD;
43760569Swill					break;
4381590Srgrimes				case 'm':
4391590Srgrimes					debug |= DEBUG_MAKE;
4401590Srgrimes					break;
4411590Srgrimes				case 's':
4421590Srgrimes					debug |= DEBUG_SUFF;
4431590Srgrimes					break;
4441590Srgrimes				case 't':
4451590Srgrimes					debug |= DEBUG_TARG;
4461590Srgrimes					break;
4471590Srgrimes				case 'v':
4481590Srgrimes					debug |= DEBUG_VAR;
4491590Srgrimes					break;
4501590Srgrimes				default:
451144475Sharti					warnx("illegal argument to d option "
452144475Sharti					    "-- %c", *modules);
4531590Srgrimes					usage();
4541590Srgrimes				}
455133085Sharti			MFLAGS_append("-d", optarg);
4561590Srgrimes			break;
4571590Srgrimes		}
45849332Shoek		case 'E':
459138920Sru			Lst_AtEnd(&envFirstVars, estrdup(optarg));
460133085Sharti			MFLAGS_append("-E", optarg);
46149332Shoek			break;
4621590Srgrimes		case 'e':
4631590Srgrimes			checkEnvFirst = TRUE;
464133085Sharti			MFLAGS_append("-e", NULL);
4651590Srgrimes			break;
4661590Srgrimes		case 'f':
467138920Sru			Lst_AtEnd(&makefiles, estrdup(optarg));
4681590Srgrimes			break;
469187995Simp		case 'I':
470187995Simp			Parse_AddIncludeDir(optarg);
471187995Simp			MFLAGS_append("-I", optarg);
472187995Simp			break;
4731590Srgrimes		case 'i':
4741590Srgrimes			ignoreErrors = TRUE;
475133085Sharti			MFLAGS_append("-i", NULL);
4761590Srgrimes			break;
47749331Shoek		case 'j': {
47849331Shoek			char *endptr;
47949331Shoek
48018730Ssteve			forceJobs = TRUE;
481146140Sharti			jobLimit = strtol(optarg, &endptr, 10);
482146140Sharti			if (jobLimit <= 0 || *endptr != '\0') {
48349938Shoek				warnx("illegal number, -j argument -- %s",
48449938Shoek				    optarg);
48549938Shoek				usage();
48649331Shoek			}
487133085Sharti			MFLAGS_append("-j", optarg);
4881590Srgrimes			break;
48949331Shoek		}
4901590Srgrimes		case 'k':
4911590Srgrimes			keepgoing = TRUE;
492133085Sharti			MFLAGS_append("-k", NULL);
4931590Srgrimes			break;
49418730Ssteve		case 'm':
495144020Sharti			Path_AddDir(&sysIncPath, optarg);
496133085Sharti			MFLAGS_append("-m", optarg);
49718730Ssteve			break;
4981590Srgrimes		case 'n':
4991590Srgrimes			noExecute = TRUE;
500133085Sharti			MFLAGS_append("-n", NULL);
5011590Srgrimes			break;
502187995Simp		case 'P':
503187995Simp			usePipes = FALSE;
504187995Simp			MFLAGS_append("-P", NULL);
505187995Simp			break;
506181021Sed		case 'p':
507181021Sed			printGraphOnly = TRUE;
508181021Sed			debug |= DEBUG_GRAPH1;
509181021Sed			break;
510186713Sobrien		case 'Q':
511186713Sobrien			beQuiet = TRUE;
512187132Sobrien			beVerbose = FALSE;
513186713Sobrien			MFLAGS_append("-Q", NULL);
514186713Sobrien			break;
5151590Srgrimes		case 'q':
5161590Srgrimes			queryFlag = TRUE;
5171590Srgrimes			/* Kind of nonsensical, wot? */
518133085Sharti			MFLAGS_append("-q", NULL);
5191590Srgrimes			break;
5201590Srgrimes		case 'r':
5211590Srgrimes			noBuiltins = TRUE;
522133085Sharti			MFLAGS_append("-r", NULL);
5231590Srgrimes			break;
524187995Simp		case 'S':
525187995Simp			keepgoing = FALSE;
526187995Simp			MFLAGS_append("-S", NULL);
527187995Simp			break;
5281590Srgrimes		case 's':
5291590Srgrimes			beSilent = TRUE;
530133085Sharti			MFLAGS_append("-s", NULL);
5311590Srgrimes			break;
5321590Srgrimes		case 't':
5331590Srgrimes			touchFlag = TRUE;
534133085Sharti			MFLAGS_append("-t", NULL);
5351590Srgrimes			break;
536187995Simp		case 'V':
537187995Simp			Lst_AtEnd(&variables, estrdup(optarg));
538187995Simp			MFLAGS_append("-V", optarg);
539187995Simp			break;
54041151Sdg		case 'v':
54141151Sdg			beVerbose = TRUE;
542186713Sobrien			beQuiet = FALSE;
543133085Sharti			MFLAGS_append("-v", NULL);
54441151Sdg			break;
545187995Simp		case 'X':
546187995Simp			expandVars = FALSE;
547187995Simp			break;
548145627Sharti		case 'x':
549145679Sharti			if (Main_ParseWarn(optarg, 1) != -1)
550145627Sharti				MFLAGS_append("-x", optarg);
551145627Sharti			break;
552167330Sfjoe
5531590Srgrimes		default:
5541590Srgrimes		case '?':
5551590Srgrimes			usage();
5561590Srgrimes		}
5571590Srgrimes	}
558144896Sharti	argv += optind;
559144896Sharti	argc -= optind;
5601590Srgrimes
5611590Srgrimes	oldVars = TRUE;
5621590Srgrimes
5631590Srgrimes	/*
564144896Sharti	 * Parse the rest of the arguments.
565144896Sharti	 *	o Check for variable assignments and perform them if so.
566144896Sharti	 *	o Check for more flags and restart getopt if so.
567160442Sobrien	 *	o Anything else is taken to be a target and added
568144896Sharti	 *	  to the end of the "create" list.
5691590Srgrimes	 */
570144896Sharti	for (; *argv != NULL; ++argv, --argc) {
571133562Sharti		if (Parse_IsVar(*argv)) {
572140870Sharti			char *ptr = MAKEFLAGS_quote(*argv);
573167330Sfjoe			char *v = estrdup(*argv);
574133562Sharti
575146146Sharti			Var_Append(".MAKEFLAGS", ptr, VAR_GLOBAL);
576167330Sfjoe			Parse_DoVar(v, VAR_CMD);
577133562Sharti			free(ptr);
578167330Sfjoe			free(v);
579133562Sharti
580144896Sharti		} else if ((*argv)[0] == '-') {
581144896Sharti			if ((*argv)[1] == '\0') {
582144896Sharti				/*
583144896Sharti				 * (*argv) is a single dash, so we
584144896Sharti				 * just ignore it.
585144896Sharti				 */
586146038Sharti			} else if (found_dd) {
587146038Sharti				/*
588146038Sharti				 * Double dash has been found, ignore
589146038Sharti				 * any more options.  But what do we do
590146038Sharti				 * with it?  For now treat it like a target.
591146038Sharti				 */
592146038Sharti				Lst_AtEnd(&create, estrdup(*argv));
593144896Sharti			} else {
594144896Sharti				/*
595146038Sharti				 * (*argv) is a -flag, so backup argv and
596146038Sharti				 * argc.  getopt() expects options to start
597146038Sharti				 * in the 2nd position.
598144896Sharti				 */
599144896Sharti				argc++;
600144896Sharti				argv--;
6011590Srgrimes				goto rearg;
6021590Srgrimes			}
603144896Sharti
604144896Sharti		} else if ((*argv)[0] == '\0') {
605144896Sharti			Punt("illegal (null) argument.");
606144896Sharti
607144896Sharti		} else {
608138916Sharti			Lst_AtEnd(&create, estrdup(*argv));
6091590Srgrimes		}
610144896Sharti	}
6111590Srgrimes}
6121590Srgrimes
613144475Sharti/**
614144475Sharti * Main_ParseArgLine
615160442Sobrien *	Used by the parse module when a .MFLAGS or .MAKEFLAGS target
6161590Srgrimes *	is encountered and by main() when reading the .MAKEFLAGS envariable.
6171590Srgrimes *	Takes a line of arguments and breaks it into its
618160442Sobrien *	component words and passes those words and the number of them to the
6191590Srgrimes *	MainParseArgs function.
6201590Srgrimes *	The line should have all its leading whitespace removed.
6211590Srgrimes *
6221590Srgrimes * Side Effects:
6231590Srgrimes *	Only those that come from the various arguments.
6241590Srgrimes */
6251590Srgrimesvoid
626140870ShartiMain_ParseArgLine(char *line, int mflags)
6271590Srgrimes{
628146345Sharti	ArgArray	aa;
6291590Srgrimes
6301590Srgrimes	if (line == NULL)
6311590Srgrimes		return;
6321590Srgrimes	for (; *line == ' '; ++line)
6331590Srgrimes		continue;
6341590Srgrimes	if (!*line)
6351590Srgrimes		return;
6361590Srgrimes
637140870Sharti	if (mflags)
638146345Sharti		MAKEFLAGS_break(&aa, line);
639140870Sharti	else
640146345Sharti		brk_string(&aa, line, TRUE);
641140870Sharti
642146345Sharti	MainParseArgs(aa.argc, aa.argv);
643146345Sharti	ArgArray_Done(&aa);
6441590Srgrimes}
6451590Srgrimes
646146146Shartistatic char *
647141252Shartichdir_verify_path(const char *path, char *obpath)
64818339Sswallace{
64918339Sswallace	struct stat sb;
65018339Sswallace
65118339Sswallace	if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
65275973Sru		if (chdir(path) == -1 || getcwd(obpath, MAXPATHLEN) == NULL) {
65327644Scharnier			warn("warning: %s", path);
654141252Sharti			return (NULL);
65518339Sswallace		}
656138232Sharti		return (obpath);
65718339Sswallace	}
65818339Sswallace
659141252Sharti	return (NULL);
66018339Sswallace}
66118339Sswallace
662146144Sharti/**
663146144Sharti * In lieu of a good way to prevent every possible looping in make(1), stop
664146144Sharti * there from being more than MKLVL_MAXVAL processes forked by make(1), to
665146144Sharti * prevent a forkbomb from happening, in a dumb and mechanical way.
666146144Sharti *
667146144Sharti * Side Effects:
668146144Sharti *	Creates or modifies enviornment variable MKLVL_ENVVAR via setenv().
669138071Sjmallett */
670138071Sjmallettstatic void
671138071Sjmallettcheck_make_level(void)
672138071Sjmallett{
673138071Sjmallett#ifdef WANT_ENV_MKLVL
674138071Sjmallett	char	*value = getenv(MKLVL_ENVVAR);
675138071Sjmallett	int	level = (value == NULL) ? 0 : atoi(value);
676138071Sjmallett
677138071Sjmallett	if (level < 0) {
678144475Sharti		errc(2, EAGAIN, "Invalid value for recursion level (%d).",
679144475Sharti		    level);
680138071Sjmallett	} else if (level > MKLVL_MAXVAL) {
681144475Sharti		errc(2, EAGAIN, "Max recursion level (%d) exceeded.",
682144475Sharti		    MKLVL_MAXVAL);
683138071Sjmallett	} else {
684138071Sjmallett		char new_value[32];
685138071Sjmallett		sprintf(new_value, "%d", level + 1);
686138071Sjmallett		setenv(MKLVL_ENVVAR, new_value, 1);
687138071Sjmallett	}
688138071Sjmallett#endif /* WANT_ENV_MKLVL */
689138071Sjmallett}
690138071Sjmallett
691144475Sharti/**
692167330Sfjoe * Main_AddSourceMakefile
693167330Sfjoe *	Add a file to the list of source makefiles
694167330Sfjoe */
695167330Sfjoevoid
696167330SfjoeMain_AddSourceMakefile(const char *name)
697167330Sfjoe{
698167330Sfjoe
699167330Sfjoe	Lst_AtEnd(&source_makefiles, estrdup(name));
700167330Sfjoe}
701167330Sfjoe
702167330Sfjoe/**
703167330Sfjoe * Remake_Makefiles
704167330Sfjoe *	Remake all the makefiles
705167330Sfjoe */
706167330Sfjoestatic void
707167330SfjoeRemake_Makefiles(void)
708167330Sfjoe{
709198199Sfjoe	Lst cleanup;
710167330Sfjoe	LstNode *ln;
711167330Sfjoe	int error_cnt = 0;
712167330Sfjoe	int remade_cnt = 0;
713167330Sfjoe
714167330Sfjoe	Compat_InstallSignalHandlers();
715170179Sfjoe	if (curdir != objdir) {
716170179Sfjoe		if (chdir(curdir) < 0)
717170179Sfjoe			Fatal("Failed to change directory to %s.", curdir);
718170179Sfjoe	}
719167330Sfjoe
720198199Sfjoe	Lst_Init(&cleanup);
721167330Sfjoe	LST_FOREACH(ln, &source_makefiles) {
722167330Sfjoe		LstNode *ln2;
723167330Sfjoe		struct GNode *gn;
724167330Sfjoe		const char *name = Lst_Datum(ln);
725167330Sfjoe		Boolean saveTouchFlag = touchFlag;
726167330Sfjoe		Boolean saveQueryFlag = queryFlag;
727167330Sfjoe		Boolean saveNoExecute = noExecute;
728168892Sfjoe		int mtime;
729167330Sfjoe
730167330Sfjoe		/*
731167330Sfjoe		 * Create node
732167330Sfjoe		 */
733167330Sfjoe		gn = Targ_FindNode(name, TARG_CREATE);
734167330Sfjoe		DEBUGF(MAKE, ("Checking %s...", gn->name));
735167330Sfjoe		Suff_FindDeps(gn);
736167330Sfjoe
737167330Sfjoe		/*
738167330Sfjoe		 * -t, -q and -n has no effect unless the makefile is
739167330Sfjoe		 * specified as one of the targets explicitly in the
740167330Sfjoe		 * command line
741167330Sfjoe		 */
742167330Sfjoe		LST_FOREACH(ln2, &create) {
743167330Sfjoe			if (!strcmp(gn->name, Lst_Datum(ln2))) {
744167330Sfjoe				/* found as a target */
745167330Sfjoe				break;
746167330Sfjoe			}
747167330Sfjoe		}
748167330Sfjoe		if (ln2 == NULL) {
749167330Sfjoe			touchFlag = FALSE;
750167330Sfjoe			queryFlag = FALSE;
751167330Sfjoe			noExecute = FALSE;
752167330Sfjoe		}
753167330Sfjoe
754167330Sfjoe		/*
755167330Sfjoe		 * Check and remake the makefile
756167330Sfjoe		 */
757168892Sfjoe		mtime = Dir_MTime(gn);
758190821Sfjoe		remakingMakefiles = TRUE;
759167330Sfjoe		Compat_Make(gn, gn);
760190821Sfjoe		remakingMakefiles = FALSE;
761167330Sfjoe
762167330Sfjoe		/*
763167330Sfjoe		 * Restore -t, -q and -n behaviour
764167330Sfjoe		 */
765167330Sfjoe		touchFlag = saveTouchFlag;
766167330Sfjoe		queryFlag = saveQueryFlag;
767167330Sfjoe		noExecute = saveNoExecute;
768167330Sfjoe
769167330Sfjoe		/*
770167330Sfjoe		 * Compat_Make will leave the 'made' field of gn
771167330Sfjoe		 * in one of the following states:
772167330Sfjoe		 *	UPTODATE  gn was already up-to-date
773167330Sfjoe		 *	MADE	  gn was recreated successfully
774167330Sfjoe		 *	ERROR	  An error occurred while gn was being created
775167330Sfjoe		 *	ABORTED	  gn was not remade because one of its inferiors
776167330Sfjoe		 *		  could not be made due to errors.
777167330Sfjoe		 */
778168892Sfjoe		if (gn->made == MADE) {
779168892Sfjoe			if (mtime != Dir_MTime(gn)) {
780168892Sfjoe				DEBUGF(MAKE,
781168892Sfjoe				    ("%s updated (%d -> %d).\n",
782168892Sfjoe				     gn->name, mtime, gn->mtime));
783168892Sfjoe				remade_cnt++;
784168892Sfjoe			} else {
785168892Sfjoe				DEBUGF(MAKE,
786168892Sfjoe				    ("%s not updated: skipping restart.\n",
787168892Sfjoe				     gn->name));
788168892Sfjoe			}
789168892Sfjoe		} else if (gn->made == ERROR)
790167330Sfjoe			error_cnt++;
791167330Sfjoe		else if (gn->made == ABORTED) {
792167330Sfjoe			printf("`%s' not remade because of errors.\n",
793167330Sfjoe			    gn->name);
794167330Sfjoe			error_cnt++;
795173919Sfjoe		} else if (gn->made == UPTODATE) {
796198199Sfjoe			Lst_EnQueue(&cleanup, gn);
797167330Sfjoe		}
798167330Sfjoe	}
799167330Sfjoe
800167330Sfjoe	if (error_cnt > 0)
801167330Sfjoe		Fatal("Failed to remake Makefiles.");
802167330Sfjoe	if (remade_cnt > 0) {
803167330Sfjoe		DEBUGF(MAKE, ("Restarting `%s'.\n", save_argv[0]));
804167330Sfjoe
805167330Sfjoe		/*
806167330Sfjoe		 * Some of makefiles were remade -- restart from clean state
807167330Sfjoe		 */
808167330Sfjoe		if (save_makeflags != NULL)
809167330Sfjoe			setenv("MAKEFLAGS", save_makeflags, 1);
810167330Sfjoe		else
811167330Sfjoe			unsetenv("MAKEFLAGS");
812167330Sfjoe		if (execvp(save_argv[0], save_argv) < 0) {
813167330Sfjoe			Fatal("Can't restart `%s': %s.",
814167330Sfjoe			    save_argv[0], strerror(errno));
815167330Sfjoe		}
816167330Sfjoe	}
817170179Sfjoe
818198199Sfjoe	while (!Lst_IsEmpty(&cleanup)) {
819198199Sfjoe		GNode *gn = Lst_DeQueue(&cleanup);
820198199Sfjoe
821198199Sfjoe		gn->unmade = 0;
822198199Sfjoe		gn->make = FALSE;
823198199Sfjoe		gn->made = UNMADE;
824198199Sfjoe		gn->childMade = FALSE;
825198199Sfjoe		gn->mtime = gn->cmtime = 0;
826198199Sfjoe		gn->cmtime_gn = NULL;
827198199Sfjoe
828198199Sfjoe		LST_FOREACH(ln, &gn->children) {
829198199Sfjoe			GNode *cgn = Lst_Datum(ln);
830198199Sfjoe
831198199Sfjoe			gn->unmade++;
832198199Sfjoe			Lst_EnQueue(&cleanup, cgn);
833198199Sfjoe		}
834198199Sfjoe	}
835198199Sfjoe
836170179Sfjoe	if (curdir != objdir) {
837170179Sfjoe		if (chdir(objdir) < 0)
838170179Sfjoe			Fatal("Failed to change directory to %s.", objdir);
839170179Sfjoe	}
840167330Sfjoe}
841167330Sfjoe
842167330Sfjoe/**
843144475Sharti * main
8441590Srgrimes *	The main function, for obvious reasons. Initializes variables
8451590Srgrimes *	and a few modules, then parses the arguments give it in the
8461590Srgrimes *	environment and on the command line. Reads the system makefile
8471590Srgrimes *	followed by either Makefile, makefile or the file given by the
8481590Srgrimes *	-f argument. Sets the .MAKEFLAGS PMake variable based on all the
8491590Srgrimes *	flags it has received by then uses either the Make or the Compat
8501590Srgrimes *	module to create the initial list of targets.
8511590Srgrimes *
8521590Srgrimes * Results:
8531590Srgrimes *	If -q was given, exits -1 if anything was out-of-date. Else it exits
8541590Srgrimes *	0.
8551590Srgrimes *
8561590Srgrimes * Side Effects:
8571590Srgrimes *	The program exits when done. Targets are created. etc. etc. etc.
8581590Srgrimes */
8591590Srgrimesint
860104696Sjmallettmain(int argc, char **argv)
8611590Srgrimes{
862160442Sobrien	const char *machine;
863146144Sharti	const char *machine_arch;
864146144Sharti	const char *machine_cpu;
865160442Sobrien	Boolean outOfDate = TRUE;	/* FALSE if all targets up to date */
866146581Sharti	const char *p;
867146157Sharti	const char *pathp;
868146157Sharti	const char *path;
86973262Simp	char mdpath[MAXPATHLEN];
87073262Simp	char obpath[MAXPATHLEN];
87173262Simp	char cdpath[MAXPATHLEN];
87218730Ssteve	char *cp = NULL, *start;
873141252Sharti
874167330Sfjoe	save_argv = argv;
875167330Sfjoe	save_makeflags = getenv("MAKEFLAGS");
876167330Sfjoe	if (save_makeflags != NULL)
877167330Sfjoe		save_makeflags = estrdup(save_makeflags);
878167330Sfjoe
879146146Sharti	/*
880146146Sharti	 * Initialize file global variables.
881146146Sharti	 */
882146146Sharti	expandVars = TRUE;
883146146Sharti	noBuiltins = FALSE;		/* Read the built-in rules */
884160442Sobrien	forceJobs = FALSE;		/* No -j flag */
885146146Sharti	curdir = cdpath;
886146146Sharti
887146146Sharti	/*
888146146Sharti	 * Initialize program global variables.
889146146Sharti	 */
890146146Sharti	beSilent = FALSE;		/* Print commands as executed */
891146146Sharti	ignoreErrors = FALSE;		/* Pay attention to non-zero returns */
892146146Sharti	noExecute = FALSE;		/* Execute all commands */
893181021Sed	printGraphOnly = FALSE;		/* Don't stop after printing graph */
894146146Sharti	keepgoing = FALSE;		/* Stop on error */
895146146Sharti	allPrecious = FALSE;		/* Remove targets when interrupted */
896146146Sharti	queryFlag = FALSE;		/* This is not just a check-run */
897146146Sharti	touchFlag = FALSE;		/* Actually update targets */
898146146Sharti	usePipes = TRUE;		/* Catch child output in pipes */
899146146Sharti	debug = 0;			/* No debug verbosity, please. */
900146146Sharti	jobsRunning = FALSE;
901146146Sharti
902146146Sharti	jobLimit = DEFMAXJOBS;
903146146Sharti	compatMake = FALSE;		/* No compat mode */
904146146Sharti
905138071Sjmallett	check_make_level();
906104395Sjmallett
90718730Ssteve#ifdef RLIMIT_NOFILE
9081590Srgrimes	/*
90918730Ssteve	 * get rid of resource limit on file descriptors
91018730Ssteve	 */
91118730Ssteve	{
91218730Ssteve		struct rlimit rl;
913146144Sharti		if (getrlimit(RLIMIT_NOFILE, &rl) == -1) {
914146144Sharti			err(2, "getrlimit");
91518730Ssteve		}
916146144Sharti		rl.rlim_cur = rl.rlim_max;
917146144Sharti		if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
918146144Sharti			err(2, "setrlimit");
919146144Sharti		}
92018730Ssteve	}
92118730Ssteve#endif
9221590Srgrimes
9235814Sjkh	/*
924176786Simp	 * Prior to 7.0, FreeBSD/pc98 kernel used to set the
925176786Simp	 * utsname.machine to "i386", and MACHINE was defined as
926176786Simp	 * "i386", so it could not be distinguished from FreeBSD/i386.
927176786Simp	 * Therefore, we had to check machine.ispc98 and adjust the
928176786Simp	 * MACHINE variable.  NOTE: The code is still here to be able
929176786Simp	 * to compile new make binary on old FreeBSD/pc98 systems, and
930176786Simp	 * have the MACHINE variable set properly.
93139006Skato	 */
932146157Sharti	if ((machine = getenv("MACHINE")) == NULL) {
93339006Skato		int	ispc98;
93439006Skato		size_t	len;
93539006Skato
93639006Skato		len = sizeof(ispc98);
93739006Skato		if (!sysctlbyname("machdep.ispc98", &ispc98, &len, NULL, 0)) {
93839006Skato			if (ispc98)
93939006Skato				machine = "pc98";
94039006Skato		}
94139006Skato	}
94239006Skato
94339006Skato	/*
9445814Sjkh	 * Get the name of this type of MACHINE from utsname
9455814Sjkh	 * so we can share an executable for similar machines.
9465814Sjkh	 * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
9475814Sjkh	 *
948153115Sru	 * Note that both MACHINE and MACHINE_ARCH are decided at
949153115Sru	 * run-time.
9505814Sjkh	 */
951146157Sharti	if (machine == NULL) {
952144475Sharti		static struct utsname utsname;
95318730Ssteve
954144475Sharti		if (uname(&utsname) == -1)
955144475Sharti			err(2, "uname");
956144475Sharti		machine = utsname.machine;
9575814Sjkh	}
9581590Srgrimes
959146144Sharti	if ((machine_arch = getenv("MACHINE_ARCH")) == NULL) {
960146144Sharti#ifdef MACHINE_ARCH
961146144Sharti		machine_arch = MACHINE_ARCH;
962146144Sharti#else
96344362Simp		machine_arch = "unknown";
96444362Simp#endif
96544362Simp	}
96644362Simp
9671590Srgrimes	/*
96872679Skris	 * Set machine_cpu to the minumum supported CPU revision based
96972679Skris	 * on the target architecture, if not already set.
97072679Skris	 */
971146144Sharti	if ((machine_cpu = getenv("MACHINE_CPU")) == NULL) {
97272679Skris		if (!strcmp(machine_arch, "i386"))
97372679Skris			machine_cpu = "i386";
97472679Skris		else if (!strcmp(machine_arch, "alpha"))
97572679Skris			machine_cpu = "ev4";
97672679Skris		else
97772679Skris			machine_cpu = "unknown";
97872679Skris	}
9791590Srgrimes
9801590Srgrimes	/*
9811590Srgrimes	 * Initialize the parsing, directory and variable modules to prepare
9821590Srgrimes	 * for the reading of inclusion paths and variable settings on the
9831590Srgrimes	 * command line
9841590Srgrimes	 */
985146144Sharti	Proc_Init();
986146144Sharti
9871590Srgrimes	Dir_Init();		/* Initialize directory structures so -I flags
9881590Srgrimes				 * can be processed correctly */
989145971Sharti	Var_Init(environ);	/* As well as the lists of variables for
9901590Srgrimes				 * parsing arguments */
991146560Sharti
9921590Srgrimes	/*
993146560Sharti	 * Initialize the Shell so that we have a shell for != assignments
994146560Sharti	 * on the command line.
995146560Sharti	 */
996146560Sharti	Shell_Init();
997146560Sharti
998146560Sharti	/*
9991590Srgrimes	 * Initialize various variables.
10001590Srgrimes	 *	MAKE also gets this name, for compatibility
10011590Srgrimes	 *	.MAKEFLAGS gets set to the empty string just in case.
10021590Srgrimes	 *	MFLAGS also gets initialized empty, for compatibility.
10031590Srgrimes	 */
1004146145Sharti	Var_SetGlobal("MAKE", argv[0]);
1005146146Sharti	Var_SetGlobal(".MAKEFLAGS", "");
1006146145Sharti	Var_SetGlobal("MFLAGS", "");
1007146145Sharti	Var_SetGlobal("MACHINE", machine);
1008146145Sharti	Var_SetGlobal("MACHINE_ARCH", machine_arch);
1009146145Sharti	Var_SetGlobal("MACHINE_CPU", machine_cpu);
101097121Sru#ifdef MAKE_VERSION
1011146145Sharti	Var_SetGlobal("MAKE_VERSION", MAKE_VERSION);
101297121Sru#endif
1013186559Sobrien	Var_SetGlobal(".newline", "\n");	/* handy for :@ loops */
1014186559Sobrien	{
1015186559Sobrien		char tmp[64];
10161590Srgrimes
1017186559Sobrien		snprintf(tmp, sizeof(tmp), "%u", getpid());
1018186559Sobrien		Var_SetGlobal(".MAKE.PID", tmp);
1019186559Sobrien		snprintf(tmp, sizeof(tmp), "%u", getppid());
1020186559Sobrien		Var_SetGlobal(".MAKE.PPID", tmp);
1021186559Sobrien	}
1022186559Sobrien	Job_SetPrefix();
1023186559Sobrien
10241590Srgrimes	/*
1025144896Sharti	 * First snag things out of the MAKEFLAGS environment
1026144896Sharti	 * variable.  Then parse the command line arguments.
10271590Srgrimes	 */
1028140870Sharti	Main_ParseArgLine(getenv("MAKEFLAGS"), 1);
10298874Srgrimes
10301590Srgrimes	MainParseArgs(argc, argv);
10311590Srgrimes
10321590Srgrimes	/*
1033120053Sru	 * Find where we are...
1034120053Sru	 */
1035120053Sru	if (getcwd(curdir, MAXPATHLEN) == NULL)
1036120053Sru		err(2, NULL);
1037120053Sru
1038141252Sharti	{
1039141252Sharti	struct stat sa;
1040141252Sharti
1041120053Sru	if (stat(curdir, &sa) == -1)
1042120053Sru	    err(2, "%s", curdir);
1043141252Sharti	}
1044120053Sru
1045120053Sru	/*
1046120053Sru	 * The object directory location is determined using the
1047120053Sru	 * following order of preference:
1048120053Sru	 *
1049120053Sru	 *	1. MAKEOBJDIRPREFIX`cwd`
1050120053Sru	 *	2. MAKEOBJDIR
1051143412Sharti	 *	3. PATH_OBJDIR.${MACHINE}
1052143412Sharti	 *	4. PATH_OBJDIR
1053143412Sharti	 *	5. PATH_OBJDIRPREFIX`cwd`
1054120053Sru	 *
1055120053Sru	 * If one of the first two fails, use the current directory.
1056120053Sru	 * If the remaining three all fail, use the current directory.
1057120053Sru	 *
1058120053Sru	 * Once things are initted,
1059120053Sru	 * have to add the original directory to the search path,
1060120053Sru	 * and modify the paths for the Makefiles apropriately.  The
1061120053Sru	 * current directory is also placed as a variable for make scripts.
1062120053Sru	 */
1063120053Sru	if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
1064120053Sru		if (!(path = getenv("MAKEOBJDIR"))) {
1065143412Sharti			path = PATH_OBJDIR;
1066143412Sharti			pathp = PATH_OBJDIRPREFIX;
1067146145Sharti			snprintf(mdpath, MAXPATHLEN, "%s.%s", path, machine);
1068120053Sru			if (!(objdir = chdir_verify_path(mdpath, obpath)))
1069120053Sru				if (!(objdir=chdir_verify_path(path, obpath))) {
1070138232Sharti					snprintf(mdpath, MAXPATHLEN,
1071120053Sru							"%s%s", pathp, curdir);
1072120053Sru					if (!(objdir=chdir_verify_path(mdpath,
1073120053Sru								       obpath)))
1074120053Sru						objdir = curdir;
1075120053Sru				}
1076120053Sru		}
1077120053Sru		else if (!(objdir = chdir_verify_path(path, obpath)))
1078120053Sru			objdir = curdir;
1079120053Sru	}
1080120053Sru	else {
1081138232Sharti		snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
1082120053Sru		if (!(objdir = chdir_verify_path(mdpath, obpath)))
1083120053Sru			objdir = curdir;
1084120053Sru	}
1085120053Sru	Dir_InitDot();		/* Initialize the "." directory */
1086120053Sru	if (objdir != curdir)
1087144020Sharti		Path_AddDir(&dirSearchPath, curdir);
1088146145Sharti	Var_SetGlobal(".ST_EXPORTVAR", "YES");
1089146145Sharti	Var_SetGlobal(".CURDIR", curdir);
1090146145Sharti	Var_SetGlobal(".OBJDIR", objdir);
1091120053Sru
1092137606Sphk	if (getenv("MAKE_JOBS_FIFO") != NULL)
1093137606Sphk		forceJobs = TRUE;
1094120053Sru	/*
109528228Sfsmp	 * Be compatible if user did not specify -j and did not explicitly
109628228Sfsmp	 * turned compatibility on
109728228Sfsmp	 */
109828228Sfsmp	if (!compatMake && !forceJobs)
109928228Sfsmp		compatMake = TRUE;
110028228Sfsmp
110128228Sfsmp	/*
1102144387Sharti	 * Initialize target and suffix modules in preparation for
11031590Srgrimes	 * parsing the makefile(s)
11041590Srgrimes	 */
11051590Srgrimes	Targ_Init();
11061590Srgrimes	Suff_Init();
11071590Srgrimes
110869527Swill	DEFAULT = NULL;
1109138232Sharti	time(&now);
11101590Srgrimes
11111590Srgrimes	/*
11121590Srgrimes	 * Set up the .TARGETS variable to contain the list of targets to be
11131590Srgrimes	 * created. If none specified, make the variable empty -- the parser
11141590Srgrimes	 * will fill the thing in with the default or .MAIN target.
11151590Srgrimes	 */
1116146145Sharti	if (Lst_IsEmpty(&create)) {
1117146145Sharti		Var_SetGlobal(".TARGETS", "");
1118146145Sharti	} else {
1119138512Sharti		LstNode *ln;
11201590Srgrimes
1121138916Sharti		for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) {
1122138264Sharti			char *name = Lst_Datum(ln);
11231590Srgrimes
11241590Srgrimes			Var_Append(".TARGETS", name, VAR_GLOBAL);
11251590Srgrimes		}
1126146145Sharti	}
11271590Srgrimes
112818730Ssteve
11291590Srgrimes	/*
113018730Ssteve	 * If no user-supplied system path was given (through the -m option)
113118730Ssteve	 * add the directories from the DEFSYSPATH (more than one may be given
113218730Ssteve	 * as dir1:...:dirn) to the system include path.
11331590Srgrimes	 */
1134144020Sharti	if (TAILQ_EMPTY(&sysIncPath)) {
1135146144Sharti		char syspath[] = PATH_DEFSYSPATH;
1136146144Sharti
113718730Ssteve		for (start = syspath; *start != '\0'; start = cp) {
113818730Ssteve			for (cp = start; *cp != '\0' && *cp != ':'; cp++)
113918730Ssteve				continue;
114018730Ssteve			if (*cp == '\0') {
1141144020Sharti				Path_AddDir(&sysIncPath, start);
114218730Ssteve			} else {
114318730Ssteve				*cp++ = '\0';
1144144020Sharti				Path_AddDir(&sysIncPath, start);
114518730Ssteve			}
114618730Ssteve		}
114718730Ssteve	}
11481590Srgrimes
114918730Ssteve	/*
115018730Ssteve	 * Read in the built-in rules first, followed by the specified
115118730Ssteve	 * makefile, if it was (makefile != (char *) NULL), or the default
115218730Ssteve	 * Makefile and makefile, in that order, if it wasn't.
115318730Ssteve	 */
115418730Ssteve	if (!noBuiltins) {
1155138916Sharti		/* Path of sys.mk */
1156138916Sharti		Lst sysMkPath = Lst_Initializer(sysMkPath);
1157138512Sharti		LstNode *ln;
1158146064Sharti		char	defsysmk[] = PATH_DEFSYSMK;
115918730Ssteve
1160146064Sharti		Path_Expand(defsysmk, &sysIncPath, &sysMkPath);
1161138916Sharti		if (Lst_IsEmpty(&sysMkPath))
1162143412Sharti			Fatal("make: no system rules (%s).", PATH_DEFSYSMK);
1163143808Sharti		LST_FOREACH(ln, &sysMkPath) {
1164143808Sharti			if (!ReadMakefile(Lst_Datum(ln)))
1165143808Sharti				break;
1166143808Sharti		}
116769527Swill		if (ln != NULL)
116818730Ssteve			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
1169138916Sharti		Lst_Destroy(&sysMkPath, free);
117018730Ssteve	}
117118730Ssteve
1172138916Sharti	if (!Lst_IsEmpty(&makefiles)) {
1173138512Sharti		LstNode *ln;
11741590Srgrimes
1175143808Sharti		LST_FOREACH(ln, &makefiles) {
1176167330Sfjoe			if (!TryReadMakefile(Lst_Datum(ln)))
1177143808Sharti				break;
1178143808Sharti		}
117969527Swill		if (ln != NULL)
11801590Srgrimes			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
1181167330Sfjoe	} else if (!TryReadMakefile("BSDmakefile"))
1182167330Sfjoe	    if (!TryReadMakefile("makefile"))
1183167330Sfjoe		TryReadMakefile("Makefile");
11841590Srgrimes
1185143808Sharti	ReadMakefile(".depend");
11861590Srgrimes
1187176842Syar	/* Install all the flags into the MAKEFLAGS envariable. */
1188146580Sharti	if (((p = Var_Value(".MAKEFLAGS", VAR_GLOBAL)) != NULL) && *p)
11891590Srgrimes		setenv("MAKEFLAGS", p, 1);
1190176839Syar	else
1191176839Syar		setenv("MAKEFLAGS", "", 1);
11921590Srgrimes
11931590Srgrimes	/*
11941590Srgrimes	 * For compatibility, look at the directories in the VPATH variable
11951590Srgrimes	 * and add them to the search path, if the variable is defined. The
11961590Srgrimes	 * variable's value is in the same format as the PATH envariable, i.e.
11971590Srgrimes	 * <directory>:<directory>:<directory>...
11981590Srgrimes	 */
11991590Srgrimes	if (Var_Exists("VPATH", VAR_CMD)) {
12001590Srgrimes		/*
12011590Srgrimes		 * GCC stores string constants in read-only memory, but
12021590Srgrimes		 * Var_Subst will want to write this thing, so store it
12031590Srgrimes		 * in an array
12041590Srgrimes		 */
12051590Srgrimes		static char VPATH[] = "${VPATH}";
1206142457Sharti		Buffer	*buf;
1207142457Sharti		char	*vpath;
1208142457Sharti		char	*ptr;
1209142457Sharti		char	savec;
12101590Srgrimes
1211146027Sharti		buf = Var_Subst(VPATH, VAR_CMD, FALSE);
1212142457Sharti
1213143959Sharti		vpath = Buf_Data(buf);
12141590Srgrimes		do {
12151590Srgrimes			/* skip to end of directory */
1216142457Sharti			for (ptr = vpath; *ptr != ':' && *ptr != '\0'; ptr++)
1217141969Sharti				;
1218141969Sharti
12191590Srgrimes			/* Save terminator character so know when to stop */
1220141969Sharti			savec = *ptr;
1221141969Sharti			*ptr = '\0';
1222141969Sharti
12231590Srgrimes			/* Add directory to search path */
1224144020Sharti			Path_AddDir(&dirSearchPath, vpath);
1225141969Sharti
1226142457Sharti			vpath = ptr + 1;
1227141969Sharti		} while (savec != '\0');
1228142457Sharti
1229142457Sharti		Buf_Destroy(buf, TRUE);
12301590Srgrimes	}
12311590Srgrimes
12321590Srgrimes	/*
12331590Srgrimes	 * Now that all search paths have been read for suffixes et al, it's
12341590Srgrimes	 * time to add the default search path to their lists...
12351590Srgrimes	 */
12361590Srgrimes	Suff_DoPaths();
12371590Srgrimes
12381590Srgrimes	/* print the initial graph, if the user requested it */
12391590Srgrimes	if (DEBUG(GRAPH1))
12401590Srgrimes		Targ_PrintGraph(1);
12411590Srgrimes
124217193Sbde	/* print the values of any variables requested by the user */
1243181021Sed	if (Lst_IsEmpty(&variables) && !printGraphOnly) {
12441590Srgrimes		/*
1245141974Sharti		 * Since the user has not requested that any variables
1246142008Sharti		 * be printed, we can build targets.
1247141974Sharti		 *
1248142008Sharti		 * Have read the entire graph and need to make a list of targets
1249141974Sharti		 * to create. If none was given on the command line, we consult
1250141974Sharti		 * the parsing module to find the main target(s) to create.
12511590Srgrimes		 */
1252138916Sharti		Lst targs = Lst_Initializer(targs);
1253138916Sharti
1254177101Sobrien		if (!is_posix && mfAutoDeps) {
1255167330Sfjoe			/*
1256167330Sfjoe			 * Check if any of the makefiles are out-of-date.
1257167330Sfjoe			 */
1258167330Sfjoe			Remake_Makefiles();
1259167330Sfjoe		}
1260167330Sfjoe
1261138916Sharti		if (Lst_IsEmpty(&create))
1262138916Sharti			Parse_MainName(&targs);
1263101460Sru		else
1264138916Sharti			Targ_FindList(&targs, &create, TARG_CREATE);
1265101460Sru
1266141974Sharti		if (compatMake) {
1267101460Sru			/*
1268141974Sharti			 * Compat_Init will take care of creating
1269141974Sharti			 * all the targets as well as initializing
1270141974Sharti			 * the module.
1271101460Sru			 */
1272141974Sharti			Compat_Run(&targs);
1273141974Sharti			outOfDate = 0;
1274141974Sharti		} else {
1275141974Sharti			/*
1276141974Sharti			 * Initialize job module before traversing
1277141974Sharti			 * the graph, now that any .BEGIN and .END
1278141974Sharti			 * targets have been read.  This is done
1279141974Sharti			 * only if the -q flag wasn't given (to
1280141974Sharti			 * prevent the .BEGIN from being executed
1281141974Sharti			 * should it exist).
1282141974Sharti			 */
1283101460Sru			if (!queryFlag) {
1284146140Sharti				Job_Init(jobLimit);
1285101460Sru				jobsRunning = TRUE;
1286101460Sru			}
1287101460Sru
1288101460Sru			/* Traverse the graph, checking on all the targets */
1289138916Sharti			outOfDate = Make_Run(&targs);
12901590Srgrimes		}
1291138916Sharti		Lst_Destroy(&targs, NOFREE);
1292141974Sharti
1293141974Sharti	} else {
1294146141Sharti		Var_Print(&variables, expandVars);
129517193Sbde	}
12968874Srgrimes
1297138920Sru	Lst_Destroy(&variables, free);
1298138920Sru	Lst_Destroy(&makefiles, free);
1299167330Sfjoe	Lst_Destroy(&source_makefiles, free);
1300138916Sharti	Lst_Destroy(&create, free);
13015814Sjkh
13021590Srgrimes	/* print the graph now it's been processed if the user requested it */
13031590Srgrimes	if (DEBUG(GRAPH2))
13041590Srgrimes		Targ_PrintGraph(2);
13051590Srgrimes
1306186279Sfjoe	if (queryFlag)
1307186279Sfjoe		return (outOfDate);
1308186279Sfjoe
1309186279Sfjoe	if (makeErrors != 0)
1310186279Sfjoe		Finish(makeErrors);
1311186279Sfjoe
1312186279Sfjoe	return (0);
13131590Srgrimes}
1314