main.c revision 181021
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 181021 2008-07-30 21:18:38Z ed $");
501590Srgrimes
51144475Sharti/*
52144475Sharti * main.c
531590Srgrimes *	The main file for this entire program. Exit routines etc
541590Srgrimes *	reside here.
551590Srgrimes *
561590Srgrimes * Utility functions defined in this file:
57144475Sharti *	Main_ParseArgLine
58144475Sharti *			Takes a line of arguments, breaks them and
59144475Sharti *			treats them as if they were given when first
60144475Sharti *			invoked. Used by the parse module to implement
61144475Sharti *			the .MFLAGS target.
621590Srgrimes */
631590Srgrimes
641590Srgrimes#include <sys/param.h>
651590Srgrimes#include <sys/stat.h>
6639006Skato#include <sys/sysctl.h>
67127880Sdes#include <sys/time.h>
68144020Sharti#include <sys/queue.h>
69127899Sru#include <sys/resource.h>
70153115Sru#include <sys/utsname.h>
7118730Ssteve#include <sys/wait.h>
7227644Scharnier#include <err.h>
731590Srgrimes#include <errno.h>
74127880Sdes#include <stdlib.h>
75141104Sharti#include <string.h>
7663955Simp#include <unistd.h>
77127880Sdes
78141104Sharti#include "arch.h"
79141133Sharti#include "buf.h"
80141104Sharti#include "config.h"
811590Srgrimes#include "dir.h"
82141104Sharti#include "globals.h"
83167330Sfjoe#include "GNode.h"
841590Srgrimes#include "job.h"
85141104Sharti#include "make.h"
86141104Sharti#include "parse.h"
871590Srgrimes#include "pathnames.h"
88146572Sharti#include "shell.h"
89141104Sharti#include "str.h"
90141104Sharti#include "suff.h"
91141104Sharti#include "targ.h"
92141104Sharti#include "util.h"
93141104Sharti#include "var.h"
941590Srgrimes
95146146Shartiextern char **environ;	/* XXX what header declares this variable? */
96146146Sharti
97160442Sobrien#define	WANT_ENV_MKLVL	1
98138071Sjmallett#define	MKLVL_MAXVAL	500
99138071Sjmallett#define	MKLVL_ENVVAR	"__MKLVL__"
100104395Sjmallett
101138916Sharti/* ordered list of makefiles to read */
102138916Shartistatic Lst makefiles = Lst_Initializer(makefiles);
103138916Sharti
104167330Sfjoe/* ordered list of source makefiles */
105167330Sfjoestatic Lst source_makefiles = Lst_Initializer(source_makefiles);
106167330Sfjoe
107138916Sharti/* list of variables to print */
108138916Shartistatic Lst variables = Lst_Initializer(variables);
109138916Sharti
110146146Shartistatic Boolean	expandVars;	/* fully expand printed variables */
111146146Shartistatic Boolean	noBuiltins;	/* -r flag */
112160442Sobrienstatic Boolean	forceJobs;	/* -j argument given */
113146146Shartistatic char	*curdir;	/* startup directory */
114146146Shartistatic char	*objdir;	/* where we chdir'ed to */
115167330Sfjoestatic char	**save_argv;	/* saved argv */
116167330Sfjoestatic char	*save_makeflags;/* saved MAKEFLAGS */
117146146Sharti
118146146Sharti/* (-E) vars to override from env */
119146146ShartiLst envFirstVars = Lst_Initializer(envFirstVars);
120146146Sharti
121146146Sharti/* Targets to be made */
122146146ShartiLst create = Lst_Initializer(create);
123146146Sharti
124146146ShartiBoolean		allPrecious;	/* .PRECIOUS given on line by itself */
125167330SfjoeBoolean		is_posix;	/* .POSIX target seen */
126177101SobrienBoolean		mfAutoDeps;	/* .MAKEFILEDEPS target seen */
127146146ShartiBoolean		beSilent;	/* -s flag */
128146146ShartiBoolean		beVerbose;	/* -v flag */
129144475ShartiBoolean		compatMake;	/* -B argument */
130149844Shartiint		debug;		/* -d flag */
131146146ShartiBoolean		ignoreErrors;	/* -i flag */
132146146Shartiint		jobLimit;	/* -j argument */
133146146ShartiBoolean		jobsRunning;	/* TRUE if the jobs might be running */
134146146ShartiBoolean		keepgoing;	/* -k flag */
135144475ShartiBoolean		noExecute;	/* -n flag */
136181021SedBoolean		printGraphOnly;	/* -p flag */
137144475ShartiBoolean		queryFlag;	/* -q flag */
138144475ShartiBoolean		touchFlag;	/* -t flag */
139144475ShartiBoolean		usePipes;	/* !-P flag */
140146146Shartiuint32_t	warn_cmd;	/* command line warning flags */
141146146Shartiuint32_t	warn_flags;	/* actual warning flags */
142146146Shartiuint32_t	warn_nocmd;	/* command line no-warning flags */
143138916Sharti
144146146Shartitime_t		now;		/* Time at start of make */
145146146Shartistruct GNode	*DEFAULT;	/* .DEFAULT node */
146138916Sharti
147144475Sharti/**
148146143Sharti * Exit with usage message.
149146143Sharti */
150146143Shartistatic void
151146143Shartiusage(void)
152146143Sharti{
153146143Sharti	fprintf(stderr,
154181021Sed	    "usage: make [-BPSXeiknpqrstv] [-C directory] [-D variable]\n"
155146143Sharti	    "\t[-d flags] [-E variable] [-f makefile] [-I directory]\n"
156146143Sharti	    "\t[-j max_jobs] [-m directory] [-V variable]\n"
157146143Sharti	    "\t[variable=value] [target ...]\n");
158146143Sharti	exit(2);
159146143Sharti}
160146143Sharti
161146143Sharti/**
162144475Sharti * MFLAGS_append
163144475Sharti *	Append a flag with an optional argument to MAKEFLAGS and MFLAGS
164133085Sharti */
165133085Shartistatic void
166141252ShartiMFLAGS_append(const char *flag, char *arg)
167133085Sharti{
168140870Sharti	char *str;
169138232Sharti
170146146Sharti	Var_Append(".MAKEFLAGS", flag, VAR_GLOBAL);
171140870Sharti	if (arg != NULL) {
172140870Sharti		str = MAKEFLAGS_quote(arg);
173146146Sharti		Var_Append(".MAKEFLAGS", str, VAR_GLOBAL);
174140870Sharti		free(str);
175140870Sharti	}
176133085Sharti
177133085Sharti	Var_Append("MFLAGS", flag, VAR_GLOBAL);
178140870Sharti	if (arg != NULL) {
179140870Sharti		str = MAKEFLAGS_quote(arg);
180140870Sharti		Var_Append("MFLAGS", str, VAR_GLOBAL);
181140870Sharti		free(str);
182140870Sharti	}
183133085Sharti}
184133085Sharti
185144475Sharti/**
186145679Sharti * Main_ParseWarn
187145679Sharti *
188145679Sharti *	Handle argument to warning option.
189145679Sharti */
190145679Shartiint
191145679ShartiMain_ParseWarn(const char *arg, int iscmd)
192145679Sharti{
193145679Sharti	int i, neg;
194145679Sharti
195145679Sharti	static const struct {
196145679Sharti		const char	*option;
197145679Sharti		uint32_t	flag;
198145679Sharti	} options[] = {
199145679Sharti		{ "dirsyntax",	WARN_DIRSYNTAX },
200145679Sharti		{ NULL,		0 }
201145679Sharti	};
202145679Sharti
203145679Sharti	neg = 0;
204145679Sharti	if (arg[0] == 'n' && arg[1] == 'o') {
205145679Sharti		neg = 1;
206145679Sharti		arg += 2;
207145679Sharti	}
208145679Sharti
209145679Sharti	for (i = 0; options[i].option != NULL; i++)
210145679Sharti		if (strcmp(arg, options[i].option) == 0)
211145679Sharti			break;
212145679Sharti
213145679Sharti	if (options[i].option == NULL)
214145679Sharti		/* unknown option */
215145679Sharti		return (-1);
216145679Sharti
217145679Sharti	if (iscmd) {
218145679Sharti		if (!neg) {
219145679Sharti			warn_cmd |= options[i].flag;
220145679Sharti			warn_nocmd &= ~options[i].flag;
221145679Sharti			warn_flags |= options[i].flag;
222145679Sharti		} else {
223145679Sharti			warn_nocmd |= options[i].flag;
224145679Sharti			warn_cmd &= ~options[i].flag;
225145679Sharti			warn_flags &= ~options[i].flag;
226145679Sharti		}
227145679Sharti	} else {
228145679Sharti		if (!neg) {
229145679Sharti			warn_flags |= (options[i].flag & ~warn_nocmd);
230145679Sharti		} else {
231145679Sharti			warn_flags &= ~(options[i].flag | warn_cmd);
232145679Sharti		}
233145679Sharti	}
234145679Sharti	return (0);
235145679Sharti}
236145679Sharti
237145679Sharti/**
238146143Sharti * Open and parse the given makefile.
239146143Sharti *
240146143Sharti * Results:
241146143Sharti *	TRUE if ok. FALSE if couldn't open file.
242146143Sharti */
243146143Shartistatic Boolean
244146143ShartiReadMakefile(const char p[])
245146143Sharti{
246152982Sdavidxu	char *fname, *fnamesave;	/* makefile to read */
247146143Sharti	FILE *stream;
248146143Sharti	char *name, path[MAXPATHLEN];
249146143Sharti	char *MAKEFILE;
250146143Sharti	int setMAKEFILE;
251146143Sharti
252146143Sharti	/* XXX - remove this once constification is done */
253152982Sdavidxu	fnamesave = fname = estrdup(p);
254146143Sharti
255146143Sharti	if (!strcmp(fname, "-")) {
256146143Sharti		Parse_File("(stdin)", stdin);
257146145Sharti		Var_SetGlobal("MAKEFILE", "");
258146143Sharti	} else {
259146143Sharti		setMAKEFILE = strcmp(fname, ".depend");
260146143Sharti
261146143Sharti		/* if we've chdir'd, rebuild the path name */
262146143Sharti		if (curdir != objdir && *fname != '/') {
263146143Sharti			snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname);
264146143Sharti			/*
265146143Sharti			 * XXX The realpath stuff breaks relative includes
266146143Sharti			 * XXX in some cases.   The problem likely is in
267146143Sharti			 * XXX parse.c where it does special things in
268146143Sharti			 * XXX ParseDoInclude if the file is relateive
269146143Sharti			 * XXX or absolute and not a system file.  There
270146143Sharti			 * XXX it assumes that if the current file that's
271146143Sharti			 * XXX being included is absolute, that any files
272146143Sharti			 * XXX that it includes shouldn't do the -I path
273146143Sharti			 * XXX stuff, which is inconsistant with historical
274146143Sharti			 * XXX behavior.  However, I can't pentrate the mists
275146143Sharti			 * XXX further, so I'm putting this workaround in
276146143Sharti			 * XXX here until such time as the underlying bug
277146143Sharti			 * XXX can be fixed.
278146143Sharti			 */
279146143Sharti#if THIS_BREAKS_THINGS
280146143Sharti			if (realpath(path, path) != NULL &&
281146143Sharti			    (stream = fopen(path, "r")) != NULL) {
282146143Sharti				MAKEFILE = fname;
283146143Sharti				fname = path;
284146143Sharti				goto found;
285146143Sharti			}
286146143Sharti		} else if (realpath(fname, path) != NULL) {
287146143Sharti			MAKEFILE = fname;
288146143Sharti			fname = path;
289146143Sharti			if ((stream = fopen(fname, "r")) != NULL)
290146143Sharti				goto found;
291146143Sharti		}
292146143Sharti#else
293146143Sharti			if ((stream = fopen(path, "r")) != NULL) {
294146143Sharti				MAKEFILE = fname;
295146143Sharti				fname = path;
296146143Sharti				goto found;
297146143Sharti			}
298146143Sharti		} else {
299146143Sharti			MAKEFILE = fname;
300146143Sharti			if ((stream = fopen(fname, "r")) != NULL)
301146143Sharti				goto found;
302146143Sharti		}
303146143Sharti#endif
304146143Sharti		/* look in -I and system include directories. */
305146143Sharti		name = Path_FindFile(fname, &parseIncPath);
306146143Sharti		if (!name)
307146143Sharti			name = Path_FindFile(fname, &sysIncPath);
308152969Sfjoe		if (!name || !(stream = fopen(name, "r"))) {
309152982Sdavidxu			free(fnamesave);
310146143Sharti			return (FALSE);
311152969Sfjoe		}
312146143Sharti		MAKEFILE = fname = name;
313146143Sharti		/*
314146143Sharti		 * set the MAKEFILE variable desired by System V fans -- the
315146143Sharti		 * placement of the setting here means it gets set to the last
316146143Sharti		 * makefile specified, as it is set by SysV make.
317146143Sharti		 */
318146143Shartifound:
319146143Sharti		if (setMAKEFILE)
320146145Sharti			Var_SetGlobal("MAKEFILE", MAKEFILE);
321146143Sharti		Parse_File(fname, stream);
322146143Sharti	}
323152982Sdavidxu	free(fnamesave);
324146143Sharti	return (TRUE);
325146143Sharti}
326146143Sharti
327146143Sharti/**
328167330Sfjoe * Open and parse the given makefile.
329167330Sfjoe * If open is successful add it to the list of makefiles.
330167330Sfjoe *
331167330Sfjoe * Results:
332167330Sfjoe *	TRUE if ok. FALSE if couldn't open file.
333167330Sfjoe */
334167330Sfjoestatic Boolean
335167330SfjoeTryReadMakefile(const char p[])
336167330Sfjoe{
337167330Sfjoe	char *data;
338167330Sfjoe	LstNode *last = Lst_Last(&source_makefiles);
339167330Sfjoe
340167330Sfjoe	if (!ReadMakefile(p))
341167330Sfjoe		return (FALSE);
342167330Sfjoe
343167330Sfjoe	data = estrdup(p);
344167330Sfjoe	if (last == NULL) {
345167330Sfjoe		LstNode *first = Lst_First(&source_makefiles);
346167330Sfjoe		Lst_Insert(&source_makefiles, first, data);
347167330Sfjoe	} else
348167330Sfjoe		Lst_Append(&source_makefiles, last, estrdup(p));
349167330Sfjoe	return (TRUE);
350167330Sfjoe}
351167330Sfjoe
352167330Sfjoe/**
353144475Sharti * MainParseArgs
3541590Srgrimes *	Parse a given argument vector. Called from main() and from
3551590Srgrimes *	Main_ParseArgLine() when the .MAKEFLAGS target is used.
3561590Srgrimes *
3571590Srgrimes *	XXX: Deal with command line overriding .MAKEFLAGS in makefile
3581590Srgrimes *
3591590Srgrimes * Side Effects:
3601590Srgrimes *	Various global and local flags will be set depending on the flags
3611590Srgrimes *	given
3621590Srgrimes */
3631590Srgrimesstatic void
364104696SjmallettMainParseArgs(int argc, char **argv)
3651590Srgrimes{
3665814Sjkh	int c;
367146038Sharti	Boolean	found_dd = FALSE;
3681590Srgrimes
369144896Shartirearg:
3701590Srgrimes	optind = 1;	/* since we're called more than once */
371144896Sharti	optreset = 1;
372181021Sed#define OPTFLAGS "ABC:D:E:I:PSV:Xd:ef:ij:km:npqrstvx:"
373146038Sharti	for (;;) {
374146038Sharti		if ((optind < argc) && strcmp(argv[optind], "--") == 0) {
375146038Sharti			found_dd = TRUE;
376146038Sharti		}
377146038Sharti		if ((c = getopt(argc, argv, OPTFLAGS)) == -1) {
378146038Sharti			break;
379146038Sharti		}
3801590Srgrimes		switch(c) {
381144387Sharti
382144387Sharti		case 'A':
383144387Sharti			arch_fatal = FALSE;
384144387Sharti			MFLAGS_append("-A", NULL);
385144387Sharti			break;
386102393Sjmallett		case 'C':
387107964Sseanc			if (chdir(optarg) == -1)
388107964Sseanc				err(1, "chdir %s", optarg);
389102393Sjmallett			break;
3901590Srgrimes		case 'D':
391146145Sharti			Var_SetGlobal(optarg, "1");
392133085Sharti			MFLAGS_append("-D", optarg);
3931590Srgrimes			break;
3941590Srgrimes		case 'I':
3951590Srgrimes			Parse_AddIncludeDir(optarg);
396133085Sharti			MFLAGS_append("-I", optarg);
3971590Srgrimes			break;
39817193Sbde		case 'V':
399138920Sru			Lst_AtEnd(&variables, estrdup(optarg));
400133085Sharti			MFLAGS_append("-V", optarg);
40117193Sbde			break;
40266365Speter		case 'X':
40366365Speter			expandVars = FALSE;
40466365Speter			break;
4051590Srgrimes		case 'B':
4061590Srgrimes			compatMake = TRUE;
407133085Sharti			MFLAGS_append("-B", NULL);
408137626Sphk			unsetenv("MAKE_JOBS_FIFO");
4091590Srgrimes			break;
4101590Srgrimes		case 'P':
4111590Srgrimes			usePipes = FALSE;
412133085Sharti			MFLAGS_append("-P", NULL);
4131590Srgrimes			break;
4141590Srgrimes		case 'S':
4151590Srgrimes			keepgoing = FALSE;
416133085Sharti			MFLAGS_append("-S", NULL);
4171590Srgrimes			break;
4181590Srgrimes		case 'd': {
4191590Srgrimes			char *modules = optarg;
4201590Srgrimes
4211590Srgrimes			for (; *modules; ++modules)
4221590Srgrimes				switch (*modules) {
4231590Srgrimes				case 'A':
4241590Srgrimes					debug = ~0;
4251590Srgrimes					break;
4261590Srgrimes				case 'a':
4271590Srgrimes					debug |= DEBUG_ARCH;
4281590Srgrimes					break;
4291590Srgrimes				case 'c':
4301590Srgrimes					debug |= DEBUG_COND;
4311590Srgrimes					break;
4321590Srgrimes				case 'd':
4331590Srgrimes					debug |= DEBUG_DIR;
4341590Srgrimes					break;
4351590Srgrimes				case 'f':
4361590Srgrimes					debug |= DEBUG_FOR;
4371590Srgrimes					break;
4381590Srgrimes				case 'g':
4391590Srgrimes					if (modules[1] == '1') {
4401590Srgrimes						debug |= DEBUG_GRAPH1;
4411590Srgrimes						++modules;
4421590Srgrimes					}
4431590Srgrimes					else if (modules[1] == '2') {
4441590Srgrimes						debug |= DEBUG_GRAPH2;
4451590Srgrimes						++modules;
4461590Srgrimes					}
4471590Srgrimes					break;
4481590Srgrimes				case 'j':
4491590Srgrimes					debug |= DEBUG_JOB;
4501590Srgrimes					break;
45160569Swill				case 'l':
45260569Swill					debug |= DEBUG_LOUD;
45360569Swill					break;
4541590Srgrimes				case 'm':
4551590Srgrimes					debug |= DEBUG_MAKE;
4561590Srgrimes					break;
4571590Srgrimes				case 's':
4581590Srgrimes					debug |= DEBUG_SUFF;
4591590Srgrimes					break;
4601590Srgrimes				case 't':
4611590Srgrimes					debug |= DEBUG_TARG;
4621590Srgrimes					break;
4631590Srgrimes				case 'v':
4641590Srgrimes					debug |= DEBUG_VAR;
4651590Srgrimes					break;
4661590Srgrimes				default:
467144475Sharti					warnx("illegal argument to d option "
468144475Sharti					    "-- %c", *modules);
4691590Srgrimes					usage();
4701590Srgrimes				}
471133085Sharti			MFLAGS_append("-d", optarg);
4721590Srgrimes			break;
4731590Srgrimes		}
47449332Shoek		case 'E':
475138920Sru			Lst_AtEnd(&envFirstVars, estrdup(optarg));
476133085Sharti			MFLAGS_append("-E", optarg);
47749332Shoek			break;
4781590Srgrimes		case 'e':
4791590Srgrimes			checkEnvFirst = TRUE;
480133085Sharti			MFLAGS_append("-e", NULL);
4811590Srgrimes			break;
4821590Srgrimes		case 'f':
483138920Sru			Lst_AtEnd(&makefiles, estrdup(optarg));
4841590Srgrimes			break;
4851590Srgrimes		case 'i':
4861590Srgrimes			ignoreErrors = TRUE;
487133085Sharti			MFLAGS_append("-i", NULL);
4881590Srgrimes			break;
48949331Shoek		case 'j': {
49049331Shoek			char *endptr;
49149331Shoek
49218730Ssteve			forceJobs = TRUE;
493146140Sharti			jobLimit = strtol(optarg, &endptr, 10);
494146140Sharti			if (jobLimit <= 0 || *endptr != '\0') {
49549938Shoek				warnx("illegal number, -j argument -- %s",
49649938Shoek				    optarg);
49749938Shoek				usage();
49849331Shoek			}
499133085Sharti			MFLAGS_append("-j", optarg);
5001590Srgrimes			break;
50149331Shoek		}
5021590Srgrimes		case 'k':
5031590Srgrimes			keepgoing = TRUE;
504133085Sharti			MFLAGS_append("-k", NULL);
5051590Srgrimes			break;
50618730Ssteve		case 'm':
507144020Sharti			Path_AddDir(&sysIncPath, optarg);
508133085Sharti			MFLAGS_append("-m", optarg);
50918730Ssteve			break;
5101590Srgrimes		case 'n':
5111590Srgrimes			noExecute = TRUE;
512133085Sharti			MFLAGS_append("-n", NULL);
5131590Srgrimes			break;
514181021Sed		case 'p':
515181021Sed			printGraphOnly = TRUE;
516181021Sed			debug |= DEBUG_GRAPH1;
517181021Sed			break;
5181590Srgrimes		case 'q':
5191590Srgrimes			queryFlag = TRUE;
5201590Srgrimes			/* Kind of nonsensical, wot? */
521133085Sharti			MFLAGS_append("-q", NULL);
5221590Srgrimes			break;
5231590Srgrimes		case 'r':
5241590Srgrimes			noBuiltins = TRUE;
525133085Sharti			MFLAGS_append("-r", NULL);
5261590Srgrimes			break;
5271590Srgrimes		case 's':
5281590Srgrimes			beSilent = TRUE;
529133085Sharti			MFLAGS_append("-s", NULL);
5301590Srgrimes			break;
5311590Srgrimes		case 't':
5321590Srgrimes			touchFlag = TRUE;
533133085Sharti			MFLAGS_append("-t", NULL);
5341590Srgrimes			break;
53541151Sdg		case 'v':
53641151Sdg			beVerbose = TRUE;
537133085Sharti			MFLAGS_append("-v", NULL);
53841151Sdg			break;
539145627Sharti		case 'x':
540145679Sharti			if (Main_ParseWarn(optarg, 1) != -1)
541145627Sharti				MFLAGS_append("-x", optarg);
542145627Sharti			break;
543167330Sfjoe
5441590Srgrimes		default:
5451590Srgrimes		case '?':
5461590Srgrimes			usage();
5471590Srgrimes		}
5481590Srgrimes	}
549144896Sharti	argv += optind;
550144896Sharti	argc -= optind;
5511590Srgrimes
5521590Srgrimes	oldVars = TRUE;
5531590Srgrimes
5541590Srgrimes	/*
555144896Sharti	 * Parse the rest of the arguments.
556144896Sharti	 *	o Check for variable assignments and perform them if so.
557144896Sharti	 *	o Check for more flags and restart getopt if so.
558160442Sobrien	 *	o Anything else is taken to be a target and added
559144896Sharti	 *	  to the end of the "create" list.
5601590Srgrimes	 */
561144896Sharti	for (; *argv != NULL; ++argv, --argc) {
562133562Sharti		if (Parse_IsVar(*argv)) {
563140870Sharti			char *ptr = MAKEFLAGS_quote(*argv);
564167330Sfjoe			char *v = estrdup(*argv);
565133562Sharti
566146146Sharti			Var_Append(".MAKEFLAGS", ptr, VAR_GLOBAL);
567167330Sfjoe			Parse_DoVar(v, VAR_CMD);
568133562Sharti			free(ptr);
569167330Sfjoe			free(v);
570133562Sharti
571144896Sharti		} else if ((*argv)[0] == '-') {
572144896Sharti			if ((*argv)[1] == '\0') {
573144896Sharti				/*
574144896Sharti				 * (*argv) is a single dash, so we
575144896Sharti				 * just ignore it.
576144896Sharti				 */
577146038Sharti			} else if (found_dd) {
578146038Sharti				/*
579146038Sharti				 * Double dash has been found, ignore
580146038Sharti				 * any more options.  But what do we do
581146038Sharti				 * with it?  For now treat it like a target.
582146038Sharti				 */
583146038Sharti				Lst_AtEnd(&create, estrdup(*argv));
584144896Sharti			} else {
585144896Sharti				/*
586146038Sharti				 * (*argv) is a -flag, so backup argv and
587146038Sharti				 * argc.  getopt() expects options to start
588146038Sharti				 * in the 2nd position.
589144896Sharti				 */
590144896Sharti				argc++;
591144896Sharti				argv--;
5921590Srgrimes				goto rearg;
5931590Srgrimes			}
594144896Sharti
595144896Sharti		} else if ((*argv)[0] == '\0') {
596144896Sharti			Punt("illegal (null) argument.");
597144896Sharti
598144896Sharti		} else {
599138916Sharti			Lst_AtEnd(&create, estrdup(*argv));
6001590Srgrimes		}
601144896Sharti	}
6021590Srgrimes}
6031590Srgrimes
604144475Sharti/**
605144475Sharti * Main_ParseArgLine
606160442Sobrien *	Used by the parse module when a .MFLAGS or .MAKEFLAGS target
6071590Srgrimes *	is encountered and by main() when reading the .MAKEFLAGS envariable.
6081590Srgrimes *	Takes a line of arguments and breaks it into its
609160442Sobrien *	component words and passes those words and the number of them to the
6101590Srgrimes *	MainParseArgs function.
6111590Srgrimes *	The line should have all its leading whitespace removed.
6121590Srgrimes *
6131590Srgrimes * Side Effects:
6141590Srgrimes *	Only those that come from the various arguments.
6151590Srgrimes */
6161590Srgrimesvoid
617140870ShartiMain_ParseArgLine(char *line, int mflags)
6181590Srgrimes{
619146345Sharti	ArgArray	aa;
6201590Srgrimes
6211590Srgrimes	if (line == NULL)
6221590Srgrimes		return;
6231590Srgrimes	for (; *line == ' '; ++line)
6241590Srgrimes		continue;
6251590Srgrimes	if (!*line)
6261590Srgrimes		return;
6271590Srgrimes
628140870Sharti	if (mflags)
629146345Sharti		MAKEFLAGS_break(&aa, line);
630140870Sharti	else
631146345Sharti		brk_string(&aa, line, TRUE);
632140870Sharti
633146345Sharti	MainParseArgs(aa.argc, aa.argv);
634146345Sharti	ArgArray_Done(&aa);
6351590Srgrimes}
6361590Srgrimes
637146146Shartistatic char *
638141252Shartichdir_verify_path(const char *path, char *obpath)
63918339Sswallace{
64018339Sswallace	struct stat sb;
64118339Sswallace
64218339Sswallace	if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
64375973Sru		if (chdir(path) == -1 || getcwd(obpath, MAXPATHLEN) == NULL) {
64427644Scharnier			warn("warning: %s", path);
645141252Sharti			return (NULL);
64618339Sswallace		}
647138232Sharti		return (obpath);
64818339Sswallace	}
64918339Sswallace
650141252Sharti	return (NULL);
65118339Sswallace}
65218339Sswallace
653146144Sharti/**
654146144Sharti * In lieu of a good way to prevent every possible looping in make(1), stop
655146144Sharti * there from being more than MKLVL_MAXVAL processes forked by make(1), to
656146144Sharti * prevent a forkbomb from happening, in a dumb and mechanical way.
657146144Sharti *
658146144Sharti * Side Effects:
659146144Sharti *	Creates or modifies enviornment variable MKLVL_ENVVAR via setenv().
660138071Sjmallett */
661138071Sjmallettstatic void
662138071Sjmallettcheck_make_level(void)
663138071Sjmallett{
664138071Sjmallett#ifdef WANT_ENV_MKLVL
665138071Sjmallett	char	*value = getenv(MKLVL_ENVVAR);
666138071Sjmallett	int	level = (value == NULL) ? 0 : atoi(value);
667138071Sjmallett
668138071Sjmallett	if (level < 0) {
669144475Sharti		errc(2, EAGAIN, "Invalid value for recursion level (%d).",
670144475Sharti		    level);
671138071Sjmallett	} else if (level > MKLVL_MAXVAL) {
672144475Sharti		errc(2, EAGAIN, "Max recursion level (%d) exceeded.",
673144475Sharti		    MKLVL_MAXVAL);
674138071Sjmallett	} else {
675138071Sjmallett		char new_value[32];
676138071Sjmallett		sprintf(new_value, "%d", level + 1);
677138071Sjmallett		setenv(MKLVL_ENVVAR, new_value, 1);
678138071Sjmallett	}
679138071Sjmallett#endif /* WANT_ENV_MKLVL */
680138071Sjmallett}
681138071Sjmallett
682144475Sharti/**
683167330Sfjoe * Main_AddSourceMakefile
684167330Sfjoe *	Add a file to the list of source makefiles
685167330Sfjoe */
686167330Sfjoevoid
687167330SfjoeMain_AddSourceMakefile(const char *name)
688167330Sfjoe{
689167330Sfjoe
690167330Sfjoe	Lst_AtEnd(&source_makefiles, estrdup(name));
691167330Sfjoe}
692167330Sfjoe
693167330Sfjoe/**
694167330Sfjoe * Remake_Makefiles
695167330Sfjoe *	Remake all the makefiles
696167330Sfjoe */
697167330Sfjoestatic void
698167330SfjoeRemake_Makefiles(void)
699167330Sfjoe{
700167330Sfjoe	LstNode *ln;
701167330Sfjoe	int error_cnt = 0;
702167330Sfjoe	int remade_cnt = 0;
703167330Sfjoe
704167330Sfjoe	Compat_InstallSignalHandlers();
705170179Sfjoe	if (curdir != objdir) {
706170179Sfjoe		if (chdir(curdir) < 0)
707170179Sfjoe			Fatal("Failed to change directory to %s.", curdir);
708170179Sfjoe	}
709167330Sfjoe
710167330Sfjoe	LST_FOREACH(ln, &source_makefiles) {
711167330Sfjoe		LstNode *ln2;
712167330Sfjoe		struct GNode *gn;
713167330Sfjoe		const char *name = Lst_Datum(ln);
714167330Sfjoe		Boolean saveTouchFlag = touchFlag;
715167330Sfjoe		Boolean saveQueryFlag = queryFlag;
716167330Sfjoe		Boolean saveNoExecute = noExecute;
717168892Sfjoe		int mtime;
718167330Sfjoe
719167330Sfjoe		/*
720167330Sfjoe		 * Create node
721167330Sfjoe		 */
722167330Sfjoe		gn = Targ_FindNode(name, TARG_CREATE);
723167330Sfjoe		DEBUGF(MAKE, ("Checking %s...", gn->name));
724167330Sfjoe		Suff_FindDeps(gn);
725167330Sfjoe
726167330Sfjoe		/*
727167330Sfjoe		 * ! dependencies as well as
728167330Sfjoe		 * dependencies with .FORCE, .EXEC and .PHONY attributes
729167330Sfjoe		 * are skipped to prevent infinite loops
730167330Sfjoe		 */
731167330Sfjoe		if (gn->type & (OP_FORCE | OP_EXEC | OP_PHONY)) {
732167330Sfjoe			DEBUGF(MAKE, ("skipping (force, exec or phony).\n",
733167330Sfjoe			    gn->name));
734167330Sfjoe			continue;
735167330Sfjoe		}
736167330Sfjoe
737167330Sfjoe		/*
738167330Sfjoe		 * Skip :: targets that have commands and no children
739167330Sfjoe		 * because such targets are always out-of-date
740167330Sfjoe		 */
741167330Sfjoe		if ((gn->type & OP_DOUBLEDEP) &&
742167330Sfjoe		    !Lst_IsEmpty(&gn->commands) &&
743167330Sfjoe		    Lst_IsEmpty(&gn->children)) {
744167330Sfjoe			DEBUGF(MAKE, ("skipping (doubledep, no sources "
745167330Sfjoe			    "and has commands).\n"));
746167330Sfjoe			continue;
747167330Sfjoe		}
748167330Sfjoe
749167330Sfjoe		/*
750167330Sfjoe		 * Skip targets without sources and without commands
751167330Sfjoe		 */
752167330Sfjoe		if (Lst_IsEmpty(&gn->commands) &&
753167330Sfjoe		    Lst_IsEmpty(&gn->children)) {
754167330Sfjoe			DEBUGF(MAKE,
755167330Sfjoe			    ("skipping (no sources and no commands).\n"));
756167330Sfjoe			continue;
757167330Sfjoe		}
758167330Sfjoe
759167330Sfjoe		DEBUGF(MAKE, ("\n"));
760167330Sfjoe
761167330Sfjoe		/*
762167330Sfjoe		 * -t, -q and -n has no effect unless the makefile is
763167330Sfjoe		 * specified as one of the targets explicitly in the
764167330Sfjoe		 * command line
765167330Sfjoe		 */
766167330Sfjoe		LST_FOREACH(ln2, &create) {
767167330Sfjoe			if (!strcmp(gn->name, Lst_Datum(ln2))) {
768167330Sfjoe				/* found as a target */
769167330Sfjoe				break;
770167330Sfjoe			}
771167330Sfjoe		}
772167330Sfjoe		if (ln2 == NULL) {
773167330Sfjoe			touchFlag = FALSE;
774167330Sfjoe			queryFlag = FALSE;
775167330Sfjoe			noExecute = FALSE;
776167330Sfjoe		}
777167330Sfjoe
778167330Sfjoe		/*
779167330Sfjoe		 * Check and remake the makefile
780167330Sfjoe		 */
781168892Sfjoe		mtime = Dir_MTime(gn);
782167330Sfjoe		Compat_Make(gn, gn);
783167330Sfjoe
784167330Sfjoe		/*
785167330Sfjoe		 * Restore -t, -q and -n behaviour
786167330Sfjoe		 */
787167330Sfjoe		touchFlag = saveTouchFlag;
788167330Sfjoe		queryFlag = saveQueryFlag;
789167330Sfjoe		noExecute = saveNoExecute;
790167330Sfjoe
791167330Sfjoe		/*
792167330Sfjoe		 * Compat_Make will leave the 'made' field of gn
793167330Sfjoe		 * in one of the following states:
794167330Sfjoe		 *	UPTODATE  gn was already up-to-date
795167330Sfjoe		 *	MADE	  gn was recreated successfully
796167330Sfjoe		 *	ERROR	  An error occurred while gn was being created
797167330Sfjoe		 *	ABORTED	  gn was not remade because one of its inferiors
798167330Sfjoe		 *		  could not be made due to errors.
799167330Sfjoe		 */
800168892Sfjoe		if (gn->made == MADE) {
801168892Sfjoe			if (mtime != Dir_MTime(gn)) {
802168892Sfjoe				DEBUGF(MAKE,
803168892Sfjoe				    ("%s updated (%d -> %d).\n",
804168892Sfjoe				     gn->name, mtime, gn->mtime));
805168892Sfjoe				remade_cnt++;
806168892Sfjoe			} else {
807168892Sfjoe				DEBUGF(MAKE,
808168892Sfjoe				    ("%s not updated: skipping restart.\n",
809168892Sfjoe				     gn->name));
810168892Sfjoe			}
811168892Sfjoe		} else if (gn->made == ERROR)
812167330Sfjoe			error_cnt++;
813167330Sfjoe		else if (gn->made == ABORTED) {
814167330Sfjoe			printf("`%s' not remade because of errors.\n",
815167330Sfjoe			    gn->name);
816167330Sfjoe			error_cnt++;
817173919Sfjoe		} else if (gn->made == UPTODATE) {
818173919Sfjoe			Lst examine;
819173919Sfjoe
820173919Sfjoe			Lst_Init(&examine);
821173919Sfjoe			Lst_EnQueue(&examine, gn);
822173919Sfjoe			while (!Lst_IsEmpty(&examine)) {
823173919Sfjoe				LstNode	*eln;
824173919Sfjoe				GNode *egn = Lst_DeQueue(&examine);
825173919Sfjoe
826173919Sfjoe				egn->make = FALSE;
827173919Sfjoe				LST_FOREACH(eln, &egn->children) {
828173919Sfjoe					GNode *cgn = Lst_Datum(eln);
829173919Sfjoe
830173919Sfjoe					Lst_EnQueue(&examine, cgn);
831173919Sfjoe				}
832173919Sfjoe			}
833167330Sfjoe		}
834167330Sfjoe	}
835167330Sfjoe
836167330Sfjoe	if (error_cnt > 0)
837167330Sfjoe		Fatal("Failed to remake Makefiles.");
838167330Sfjoe	if (remade_cnt > 0) {
839167330Sfjoe		DEBUGF(MAKE, ("Restarting `%s'.\n", save_argv[0]));
840167330Sfjoe
841167330Sfjoe		/*
842167330Sfjoe		 * Some of makefiles were remade -- restart from clean state
843167330Sfjoe		 */
844167330Sfjoe		if (save_makeflags != NULL)
845167330Sfjoe			setenv("MAKEFLAGS", save_makeflags, 1);
846167330Sfjoe		else
847167330Sfjoe			unsetenv("MAKEFLAGS");
848167330Sfjoe		if (execvp(save_argv[0], save_argv) < 0) {
849167330Sfjoe			Fatal("Can't restart `%s': %s.",
850167330Sfjoe			    save_argv[0], strerror(errno));
851167330Sfjoe		}
852167330Sfjoe	}
853170179Sfjoe
854170179Sfjoe	if (curdir != objdir) {
855170179Sfjoe		if (chdir(objdir) < 0)
856170179Sfjoe			Fatal("Failed to change directory to %s.", objdir);
857170179Sfjoe	}
858167330Sfjoe}
859167330Sfjoe
860167330Sfjoe/**
861144475Sharti * main
8621590Srgrimes *	The main function, for obvious reasons. Initializes variables
8631590Srgrimes *	and a few modules, then parses the arguments give it in the
8641590Srgrimes *	environment and on the command line. Reads the system makefile
8651590Srgrimes *	followed by either Makefile, makefile or the file given by the
8661590Srgrimes *	-f argument. Sets the .MAKEFLAGS PMake variable based on all the
8671590Srgrimes *	flags it has received by then uses either the Make or the Compat
8681590Srgrimes *	module to create the initial list of targets.
8691590Srgrimes *
8701590Srgrimes * Results:
8711590Srgrimes *	If -q was given, exits -1 if anything was out-of-date. Else it exits
8721590Srgrimes *	0.
8731590Srgrimes *
8741590Srgrimes * Side Effects:
8751590Srgrimes *	The program exits when done. Targets are created. etc. etc. etc.
8761590Srgrimes */
8771590Srgrimesint
878104696Sjmallettmain(int argc, char **argv)
8791590Srgrimes{
880160442Sobrien	const char *machine;
881146144Sharti	const char *machine_arch;
882146144Sharti	const char *machine_cpu;
883160442Sobrien	Boolean outOfDate = TRUE;	/* FALSE if all targets up to date */
884146581Sharti	const char *p;
885146157Sharti	const char *pathp;
886146157Sharti	const char *path;
88773262Simp	char mdpath[MAXPATHLEN];
88873262Simp	char obpath[MAXPATHLEN];
88973262Simp	char cdpath[MAXPATHLEN];
89018730Ssteve	char *cp = NULL, *start;
891141252Sharti
892167330Sfjoe	save_argv = argv;
893167330Sfjoe	save_makeflags = getenv("MAKEFLAGS");
894167330Sfjoe	if (save_makeflags != NULL)
895167330Sfjoe		save_makeflags = estrdup(save_makeflags);
896167330Sfjoe
897146146Sharti	/*
898146146Sharti	 * Initialize file global variables.
899146146Sharti	 */
900146146Sharti	expandVars = TRUE;
901146146Sharti	noBuiltins = FALSE;		/* Read the built-in rules */
902160442Sobrien	forceJobs = FALSE;		/* No -j flag */
903146146Sharti	curdir = cdpath;
904146146Sharti
905146146Sharti	/*
906146146Sharti	 * Initialize program global variables.
907146146Sharti	 */
908146146Sharti	beSilent = FALSE;		/* Print commands as executed */
909146146Sharti	ignoreErrors = FALSE;		/* Pay attention to non-zero returns */
910146146Sharti	noExecute = FALSE;		/* Execute all commands */
911181021Sed	printGraphOnly = FALSE;		/* Don't stop after printing graph */
912146146Sharti	keepgoing = FALSE;		/* Stop on error */
913146146Sharti	allPrecious = FALSE;		/* Remove targets when interrupted */
914146146Sharti	queryFlag = FALSE;		/* This is not just a check-run */
915146146Sharti	touchFlag = FALSE;		/* Actually update targets */
916146146Sharti	usePipes = TRUE;		/* Catch child output in pipes */
917146146Sharti	debug = 0;			/* No debug verbosity, please. */
918146146Sharti	jobsRunning = FALSE;
919146146Sharti
920146146Sharti	jobLimit = DEFMAXJOBS;
921146146Sharti	compatMake = FALSE;		/* No compat mode */
922146146Sharti
923138071Sjmallett	check_make_level();
924104395Sjmallett
92518730Ssteve#ifdef RLIMIT_NOFILE
9261590Srgrimes	/*
92718730Ssteve	 * get rid of resource limit on file descriptors
92818730Ssteve	 */
92918730Ssteve	{
93018730Ssteve		struct rlimit rl;
931146144Sharti		if (getrlimit(RLIMIT_NOFILE, &rl) == -1) {
932146144Sharti			err(2, "getrlimit");
93318730Ssteve		}
934146144Sharti		rl.rlim_cur = rl.rlim_max;
935146144Sharti		if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
936146144Sharti			err(2, "setrlimit");
937146144Sharti		}
93818730Ssteve	}
93918730Ssteve#endif
9401590Srgrimes
9415814Sjkh	/*
942176786Simp	 * Prior to 7.0, FreeBSD/pc98 kernel used to set the
943176786Simp	 * utsname.machine to "i386", and MACHINE was defined as
944176786Simp	 * "i386", so it could not be distinguished from FreeBSD/i386.
945176786Simp	 * Therefore, we had to check machine.ispc98 and adjust the
946176786Simp	 * MACHINE variable.  NOTE: The code is still here to be able
947176786Simp	 * to compile new make binary on old FreeBSD/pc98 systems, and
948176786Simp	 * have the MACHINE variable set properly.
94939006Skato	 */
950146157Sharti	if ((machine = getenv("MACHINE")) == NULL) {
95139006Skato		int	ispc98;
95239006Skato		size_t	len;
95339006Skato
95439006Skato		len = sizeof(ispc98);
95539006Skato		if (!sysctlbyname("machdep.ispc98", &ispc98, &len, NULL, 0)) {
95639006Skato			if (ispc98)
95739006Skato				machine = "pc98";
95839006Skato		}
95939006Skato	}
96039006Skato
96139006Skato	/*
9625814Sjkh	 * Get the name of this type of MACHINE from utsname
9635814Sjkh	 * so we can share an executable for similar machines.
9645814Sjkh	 * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
9655814Sjkh	 *
966153115Sru	 * Note that both MACHINE and MACHINE_ARCH are decided at
967153115Sru	 * run-time.
9685814Sjkh	 */
969146157Sharti	if (machine == NULL) {
970144475Sharti		static struct utsname utsname;
97118730Ssteve
972144475Sharti		if (uname(&utsname) == -1)
973144475Sharti			err(2, "uname");
974144475Sharti		machine = utsname.machine;
9755814Sjkh	}
9761590Srgrimes
977146144Sharti	if ((machine_arch = getenv("MACHINE_ARCH")) == NULL) {
978146144Sharti#ifdef MACHINE_ARCH
979146144Sharti		machine_arch = MACHINE_ARCH;
980146144Sharti#else
98144362Simp		machine_arch = "unknown";
98244362Simp#endif
98344362Simp	}
98444362Simp
9851590Srgrimes	/*
98672679Skris	 * Set machine_cpu to the minumum supported CPU revision based
98772679Skris	 * on the target architecture, if not already set.
98872679Skris	 */
989146144Sharti	if ((machine_cpu = getenv("MACHINE_CPU")) == NULL) {
99072679Skris		if (!strcmp(machine_arch, "i386"))
99172679Skris			machine_cpu = "i386";
99272679Skris		else if (!strcmp(machine_arch, "alpha"))
99372679Skris			machine_cpu = "ev4";
99472679Skris		else
99572679Skris			machine_cpu = "unknown";
99672679Skris	}
9971590Srgrimes
9981590Srgrimes	/*
9991590Srgrimes	 * Initialize the parsing, directory and variable modules to prepare
10001590Srgrimes	 * for the reading of inclusion paths and variable settings on the
10011590Srgrimes	 * command line
10021590Srgrimes	 */
1003146144Sharti	Proc_Init();
1004146144Sharti
10051590Srgrimes	Dir_Init();		/* Initialize directory structures so -I flags
10061590Srgrimes				 * can be processed correctly */
1007145971Sharti	Var_Init(environ);	/* As well as the lists of variables for
10081590Srgrimes				 * parsing arguments */
1009146560Sharti
10101590Srgrimes	/*
1011146560Sharti	 * Initialize the Shell so that we have a shell for != assignments
1012146560Sharti	 * on the command line.
1013146560Sharti	 */
1014146560Sharti	Shell_Init();
1015146560Sharti
1016146560Sharti	/*
10171590Srgrimes	 * Initialize various variables.
10181590Srgrimes	 *	MAKE also gets this name, for compatibility
10191590Srgrimes	 *	.MAKEFLAGS gets set to the empty string just in case.
10201590Srgrimes	 *	MFLAGS also gets initialized empty, for compatibility.
10211590Srgrimes	 */
1022146145Sharti	Var_SetGlobal("MAKE", argv[0]);
1023146146Sharti	Var_SetGlobal(".MAKEFLAGS", "");
1024146145Sharti	Var_SetGlobal("MFLAGS", "");
1025146145Sharti	Var_SetGlobal("MACHINE", machine);
1026146145Sharti	Var_SetGlobal("MACHINE_ARCH", machine_arch);
1027146145Sharti	Var_SetGlobal("MACHINE_CPU", machine_cpu);
102897121Sru#ifdef MAKE_VERSION
1029146145Sharti	Var_SetGlobal("MAKE_VERSION", MAKE_VERSION);
103097121Sru#endif
10311590Srgrimes
10321590Srgrimes	/*
1033144896Sharti	 * First snag things out of the MAKEFLAGS environment
1034144896Sharti	 * variable.  Then parse the command line arguments.
10351590Srgrimes	 */
1036140870Sharti	Main_ParseArgLine(getenv("MAKEFLAGS"), 1);
10378874Srgrimes
10381590Srgrimes	MainParseArgs(argc, argv);
10391590Srgrimes
10401590Srgrimes	/*
1041120053Sru	 * Find where we are...
1042120053Sru	 */
1043120053Sru	if (getcwd(curdir, MAXPATHLEN) == NULL)
1044120053Sru		err(2, NULL);
1045120053Sru
1046141252Sharti	{
1047141252Sharti	struct stat sa;
1048141252Sharti
1049120053Sru	if (stat(curdir, &sa) == -1)
1050120053Sru	    err(2, "%s", curdir);
1051141252Sharti	}
1052120053Sru
1053120053Sru	/*
1054120053Sru	 * The object directory location is determined using the
1055120053Sru	 * following order of preference:
1056120053Sru	 *
1057120053Sru	 *	1. MAKEOBJDIRPREFIX`cwd`
1058120053Sru	 *	2. MAKEOBJDIR
1059143412Sharti	 *	3. PATH_OBJDIR.${MACHINE}
1060143412Sharti	 *	4. PATH_OBJDIR
1061143412Sharti	 *	5. PATH_OBJDIRPREFIX`cwd`
1062120053Sru	 *
1063120053Sru	 * If one of the first two fails, use the current directory.
1064120053Sru	 * If the remaining three all fail, use the current directory.
1065120053Sru	 *
1066120053Sru	 * Once things are initted,
1067120053Sru	 * have to add the original directory to the search path,
1068120053Sru	 * and modify the paths for the Makefiles apropriately.  The
1069120053Sru	 * current directory is also placed as a variable for make scripts.
1070120053Sru	 */
1071120053Sru	if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
1072120053Sru		if (!(path = getenv("MAKEOBJDIR"))) {
1073143412Sharti			path = PATH_OBJDIR;
1074143412Sharti			pathp = PATH_OBJDIRPREFIX;
1075146145Sharti			snprintf(mdpath, MAXPATHLEN, "%s.%s", path, machine);
1076120053Sru			if (!(objdir = chdir_verify_path(mdpath, obpath)))
1077120053Sru				if (!(objdir=chdir_verify_path(path, obpath))) {
1078138232Sharti					snprintf(mdpath, MAXPATHLEN,
1079120053Sru							"%s%s", pathp, curdir);
1080120053Sru					if (!(objdir=chdir_verify_path(mdpath,
1081120053Sru								       obpath)))
1082120053Sru						objdir = curdir;
1083120053Sru				}
1084120053Sru		}
1085120053Sru		else if (!(objdir = chdir_verify_path(path, obpath)))
1086120053Sru			objdir = curdir;
1087120053Sru	}
1088120053Sru	else {
1089138232Sharti		snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
1090120053Sru		if (!(objdir = chdir_verify_path(mdpath, obpath)))
1091120053Sru			objdir = curdir;
1092120053Sru	}
1093120053Sru	Dir_InitDot();		/* Initialize the "." directory */
1094120053Sru	if (objdir != curdir)
1095144020Sharti		Path_AddDir(&dirSearchPath, curdir);
1096146145Sharti	Var_SetGlobal(".ST_EXPORTVAR", "YES");
1097146145Sharti	Var_SetGlobal(".CURDIR", curdir);
1098146145Sharti	Var_SetGlobal(".OBJDIR", objdir);
1099120053Sru
1100137606Sphk	if (getenv("MAKE_JOBS_FIFO") != NULL)
1101137606Sphk		forceJobs = TRUE;
1102120053Sru	/*
110328228Sfsmp	 * Be compatible if user did not specify -j and did not explicitly
110428228Sfsmp	 * turned compatibility on
110528228Sfsmp	 */
110628228Sfsmp	if (!compatMake && !forceJobs)
110728228Sfsmp		compatMake = TRUE;
110828228Sfsmp
110928228Sfsmp	/*
1110144387Sharti	 * Initialize target and suffix modules in preparation for
11111590Srgrimes	 * parsing the makefile(s)
11121590Srgrimes	 */
11131590Srgrimes	Targ_Init();
11141590Srgrimes	Suff_Init();
11151590Srgrimes
111669527Swill	DEFAULT = NULL;
1117138232Sharti	time(&now);
11181590Srgrimes
11191590Srgrimes	/*
11201590Srgrimes	 * Set up the .TARGETS variable to contain the list of targets to be
11211590Srgrimes	 * created. If none specified, make the variable empty -- the parser
11221590Srgrimes	 * will fill the thing in with the default or .MAIN target.
11231590Srgrimes	 */
1124146145Sharti	if (Lst_IsEmpty(&create)) {
1125146145Sharti		Var_SetGlobal(".TARGETS", "");
1126146145Sharti	} else {
1127138512Sharti		LstNode *ln;
11281590Srgrimes
1129138916Sharti		for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) {
1130138264Sharti			char *name = Lst_Datum(ln);
11311590Srgrimes
11321590Srgrimes			Var_Append(".TARGETS", name, VAR_GLOBAL);
11331590Srgrimes		}
1134146145Sharti	}
11351590Srgrimes
113618730Ssteve
11371590Srgrimes	/*
113818730Ssteve	 * If no user-supplied system path was given (through the -m option)
113918730Ssteve	 * add the directories from the DEFSYSPATH (more than one may be given
114018730Ssteve	 * as dir1:...:dirn) to the system include path.
11411590Srgrimes	 */
1142144020Sharti	if (TAILQ_EMPTY(&sysIncPath)) {
1143146144Sharti		char syspath[] = PATH_DEFSYSPATH;
1144146144Sharti
114518730Ssteve		for (start = syspath; *start != '\0'; start = cp) {
114618730Ssteve			for (cp = start; *cp != '\0' && *cp != ':'; cp++)
114718730Ssteve				continue;
114818730Ssteve			if (*cp == '\0') {
1149144020Sharti				Path_AddDir(&sysIncPath, start);
115018730Ssteve			} else {
115118730Ssteve				*cp++ = '\0';
1152144020Sharti				Path_AddDir(&sysIncPath, start);
115318730Ssteve			}
115418730Ssteve		}
115518730Ssteve	}
11561590Srgrimes
115718730Ssteve	/*
115818730Ssteve	 * Read in the built-in rules first, followed by the specified
115918730Ssteve	 * makefile, if it was (makefile != (char *) NULL), or the default
116018730Ssteve	 * Makefile and makefile, in that order, if it wasn't.
116118730Ssteve	 */
116218730Ssteve	if (!noBuiltins) {
1163138916Sharti		/* Path of sys.mk */
1164138916Sharti		Lst sysMkPath = Lst_Initializer(sysMkPath);
1165138512Sharti		LstNode *ln;
1166146064Sharti		char	defsysmk[] = PATH_DEFSYSMK;
116718730Ssteve
1168146064Sharti		Path_Expand(defsysmk, &sysIncPath, &sysMkPath);
1169138916Sharti		if (Lst_IsEmpty(&sysMkPath))
1170143412Sharti			Fatal("make: no system rules (%s).", PATH_DEFSYSMK);
1171143808Sharti		LST_FOREACH(ln, &sysMkPath) {
1172143808Sharti			if (!ReadMakefile(Lst_Datum(ln)))
1173143808Sharti				break;
1174143808Sharti		}
117569527Swill		if (ln != NULL)
117618730Ssteve			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
1177138916Sharti		Lst_Destroy(&sysMkPath, free);
117818730Ssteve	}
117918730Ssteve
1180138916Sharti	if (!Lst_IsEmpty(&makefiles)) {
1181138512Sharti		LstNode *ln;
11821590Srgrimes
1183143808Sharti		LST_FOREACH(ln, &makefiles) {
1184167330Sfjoe			if (!TryReadMakefile(Lst_Datum(ln)))
1185143808Sharti				break;
1186143808Sharti		}
118769527Swill		if (ln != NULL)
11881590Srgrimes			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
1189167330Sfjoe	} else if (!TryReadMakefile("BSDmakefile"))
1190167330Sfjoe	    if (!TryReadMakefile("makefile"))
1191167330Sfjoe		TryReadMakefile("Makefile");
11921590Srgrimes
1193143808Sharti	ReadMakefile(".depend");
11941590Srgrimes
1195176842Syar	/* Install all the flags into the MAKEFLAGS envariable. */
1196146580Sharti	if (((p = Var_Value(".MAKEFLAGS", VAR_GLOBAL)) != NULL) && *p)
11971590Srgrimes		setenv("MAKEFLAGS", p, 1);
1198176839Syar	else
1199176839Syar		setenv("MAKEFLAGS", "", 1);
12001590Srgrimes
12011590Srgrimes	/*
12021590Srgrimes	 * For compatibility, look at the directories in the VPATH variable
12031590Srgrimes	 * and add them to the search path, if the variable is defined. The
12041590Srgrimes	 * variable's value is in the same format as the PATH envariable, i.e.
12051590Srgrimes	 * <directory>:<directory>:<directory>...
12061590Srgrimes	 */
12071590Srgrimes	if (Var_Exists("VPATH", VAR_CMD)) {
12081590Srgrimes		/*
12091590Srgrimes		 * GCC stores string constants in read-only memory, but
12101590Srgrimes		 * Var_Subst will want to write this thing, so store it
12111590Srgrimes		 * in an array
12121590Srgrimes		 */
12131590Srgrimes		static char VPATH[] = "${VPATH}";
1214142457Sharti		Buffer	*buf;
1215142457Sharti		char	*vpath;
1216142457Sharti		char	*ptr;
1217142457Sharti		char	savec;
12181590Srgrimes
1219146027Sharti		buf = Var_Subst(VPATH, VAR_CMD, FALSE);
1220142457Sharti
1221143959Sharti		vpath = Buf_Data(buf);
12221590Srgrimes		do {
12231590Srgrimes			/* skip to end of directory */
1224142457Sharti			for (ptr = vpath; *ptr != ':' && *ptr != '\0'; ptr++)
1225141969Sharti				;
1226141969Sharti
12271590Srgrimes			/* Save terminator character so know when to stop */
1228141969Sharti			savec = *ptr;
1229141969Sharti			*ptr = '\0';
1230141969Sharti
12311590Srgrimes			/* Add directory to search path */
1232144020Sharti			Path_AddDir(&dirSearchPath, vpath);
1233141969Sharti
1234142457Sharti			vpath = ptr + 1;
1235141969Sharti		} while (savec != '\0');
1236142457Sharti
1237142457Sharti		Buf_Destroy(buf, TRUE);
12381590Srgrimes	}
12391590Srgrimes
12401590Srgrimes	/*
12411590Srgrimes	 * Now that all search paths have been read for suffixes et al, it's
12421590Srgrimes	 * time to add the default search path to their lists...
12431590Srgrimes	 */
12441590Srgrimes	Suff_DoPaths();
12451590Srgrimes
12461590Srgrimes	/* print the initial graph, if the user requested it */
12471590Srgrimes	if (DEBUG(GRAPH1))
12481590Srgrimes		Targ_PrintGraph(1);
12491590Srgrimes
125017193Sbde	/* print the values of any variables requested by the user */
1251181021Sed	if (Lst_IsEmpty(&variables) && !printGraphOnly) {
12521590Srgrimes		/*
1253141974Sharti		 * Since the user has not requested that any variables
1254142008Sharti		 * be printed, we can build targets.
1255141974Sharti		 *
1256142008Sharti		 * Have read the entire graph and need to make a list of targets
1257141974Sharti		 * to create. If none was given on the command line, we consult
1258141974Sharti		 * the parsing module to find the main target(s) to create.
12591590Srgrimes		 */
1260138916Sharti		Lst targs = Lst_Initializer(targs);
1261138916Sharti
1262177101Sobrien		if (!is_posix && mfAutoDeps) {
1263167330Sfjoe			/*
1264167330Sfjoe			 * Check if any of the makefiles are out-of-date.
1265167330Sfjoe			 */
1266167330Sfjoe			Remake_Makefiles();
1267167330Sfjoe		}
1268167330Sfjoe
1269138916Sharti		if (Lst_IsEmpty(&create))
1270138916Sharti			Parse_MainName(&targs);
1271101460Sru		else
1272138916Sharti			Targ_FindList(&targs, &create, TARG_CREATE);
1273101460Sru
1274141974Sharti		if (compatMake) {
1275101460Sru			/*
1276141974Sharti			 * Compat_Init will take care of creating
1277141974Sharti			 * all the targets as well as initializing
1278141974Sharti			 * the module.
1279101460Sru			 */
1280141974Sharti			Compat_Run(&targs);
1281141974Sharti			outOfDate = 0;
1282141974Sharti		} else {
1283141974Sharti			/*
1284141974Sharti			 * Initialize job module before traversing
1285141974Sharti			 * the graph, now that any .BEGIN and .END
1286141974Sharti			 * targets have been read.  This is done
1287141974Sharti			 * only if the -q flag wasn't given (to
1288141974Sharti			 * prevent the .BEGIN from being executed
1289141974Sharti			 * should it exist).
1290141974Sharti			 */
1291101460Sru			if (!queryFlag) {
1292146140Sharti				Job_Init(jobLimit);
1293101460Sru				jobsRunning = TRUE;
1294101460Sru			}
1295101460Sru
1296101460Sru			/* Traverse the graph, checking on all the targets */
1297138916Sharti			outOfDate = Make_Run(&targs);
12981590Srgrimes		}
1299138916Sharti		Lst_Destroy(&targs, NOFREE);
1300141974Sharti
1301141974Sharti	} else {
1302146141Sharti		Var_Print(&variables, expandVars);
130317193Sbde	}
13048874Srgrimes
1305138920Sru	Lst_Destroy(&variables, free);
1306138920Sru	Lst_Destroy(&makefiles, free);
1307167330Sfjoe	Lst_Destroy(&source_makefiles, free);
1308138916Sharti	Lst_Destroy(&create, free);
13095814Sjkh
13101590Srgrimes	/* print the graph now it's been processed if the user requested it */
13111590Srgrimes	if (DEBUG(GRAPH2))
13121590Srgrimes		Targ_PrintGraph(2);
13131590Srgrimes
13141590Srgrimes	if (queryFlag && outOfDate)
1315138232Sharti		return (1);
13161590Srgrimes	else
1317138232Sharti		return (0);
13181590Srgrimes}
13191590Srgrimes
1320