main.c revision 146064
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 146064 2005-05-10 14:23:31Z harti $");
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
64141104Sharti#ifndef MACHINE
65141104Sharti#include <sys/utsname.h>
66141104Sharti#endif
671590Srgrimes#include <sys/param.h>
681590Srgrimes#include <sys/stat.h>
6939006Skato#include <sys/sysctl.h>
70127880Sdes#include <sys/time.h>
71144020Sharti#include <sys/queue.h>
72127899Sru#include <sys/resource.h>
7318730Ssteve#include <sys/wait.h>
7427644Scharnier#include <err.h>
751590Srgrimes#include <errno.h>
76127880Sdes#include <signal.h>
77127880Sdes#include <stdlib.h>
78141104Sharti#include <string.h>
7963955Simp#include <unistd.h>
80127880Sdes
81141104Sharti#include "arch.h"
82141133Sharti#include "buf.h"
83141104Sharti#include "config.h"
841590Srgrimes#include "dir.h"
85141104Sharti#include "globals.h"
861590Srgrimes#include "job.h"
87141104Sharti#include "make.h"
88141104Sharti#include "parse.h"
891590Srgrimes#include "pathnames.h"
90141104Sharti#include "str.h"
91141104Sharti#include "suff.h"
92141104Sharti#include "targ.h"
93141104Sharti#include "util.h"
94141104Sharti#include "var.h"
951590Srgrimes
96104395Sjmallett#define WANT_ENV_MKLVL	1
97138071Sjmallett#define	MKLVL_MAXVAL	500
98138071Sjmallett#define	MKLVL_ENVVAR	"__MKLVL__"
99104395Sjmallett
1001590Srgrimes#define	MAKEFLAGS	".MAKEFLAGS"
1011590Srgrimes
102145971Shartiextern char **environ;	/* XXX what header declares this variable? */
103145971Sharti
104138916Sharti/* Targets to be made */
105138916ShartiLst create = Lst_Initializer(create);
106138916Sharti
107144475Shartitime_t		now;		/* Time at start of make */
108144475Shartistruct GNode	*DEFAULT;	/* .DEFAULT node */
109144475ShartiBoolean		allPrecious;	/* .PRECIOUS given on line by itself */
110145679Shartiuint32_t	warn_flags;	/* actual warning flags */
111145679Shartiuint32_t	warn_cmd;	/* command line warning flags */
112145679Shartiuint32_t	warn_nocmd;	/* command line no-warning flags */
1131590Srgrimes
114144475Shartistatic Boolean	noBuiltins;	/* -r flag */
115138916Sharti
116138916Sharti/* ordered list of makefiles to read */
117138916Shartistatic Lst makefiles = Lst_Initializer(makefiles);
118138916Sharti
119144475Shartistatic Boolean	expandVars;	/* fully expand printed variables */
120138916Sharti
121138916Sharti/* list of variables to print */
122138916Shartistatic Lst variables = Lst_Initializer(variables);
123138916Sharti
124144475Shartiint		maxJobs;	/* -j argument */
125144475Shartistatic Boolean	forceJobs;      /* -j argument given */
126144475ShartiBoolean		compatMake;	/* -B argument */
127144475ShartiBoolean		debug;		/* -d flag */
128144475ShartiBoolean		noExecute;	/* -n flag */
129144475ShartiBoolean		keepgoing;	/* -k flag */
130144475ShartiBoolean		queryFlag;	/* -q flag */
131144475ShartiBoolean		touchFlag;	/* -t flag */
132144475ShartiBoolean		usePipes;	/* !-P flag */
133144475ShartiBoolean		ignoreErrors;	/* -i flag */
134144475ShartiBoolean		beSilent;	/* -s flag */
135144475ShartiBoolean		beVerbose;	/* -v flag */
136144475ShartiBoolean		oldVars;	/* variable substitution style */
137144475ShartiBoolean		checkEnvFirst;	/* -e flag */
138138916Sharti
139138916Sharti/* (-E) vars to override from env */
140138916ShartiLst envFirstVars = Lst_Initializer(envFirstVars);
141138916Sharti
142144475ShartiBoolean		jobsRunning;	/* TRUE if the jobs might be running */
1431590Srgrimes
144144475Shartichar		*chdir_verify_path(const char *, char *);
145144475Shartistatic int	ReadMakefile(const char *);
146144475Shartistatic void	usage(void);
1471590Srgrimes
148144475Shartistatic char	*curdir;	/* startup directory */
149144475Shartistatic char	*objdir;	/* where we chdir'ed to */
1501590Srgrimes
151144475Sharti/**
152144475Sharti * MFLAGS_append
153144475Sharti *	Append a flag with an optional argument to MAKEFLAGS and MFLAGS
154133085Sharti */
155133085Shartistatic void
156141252ShartiMFLAGS_append(const char *flag, char *arg)
157133085Sharti{
158140870Sharti	char *str;
159138232Sharti
160133085Sharti	Var_Append(MAKEFLAGS, flag, VAR_GLOBAL);
161140870Sharti	if (arg != NULL) {
162140870Sharti		str = MAKEFLAGS_quote(arg);
163140870Sharti		Var_Append(MAKEFLAGS, str, VAR_GLOBAL);
164140870Sharti		free(str);
165140870Sharti	}
166133085Sharti
167133085Sharti	Var_Append("MFLAGS", flag, VAR_GLOBAL);
168140870Sharti	if (arg != NULL) {
169140870Sharti		str = MAKEFLAGS_quote(arg);
170140870Sharti		Var_Append("MFLAGS", str, VAR_GLOBAL);
171140870Sharti		free(str);
172140870Sharti	}
173133085Sharti}
174133085Sharti
175144475Sharti/**
176145679Sharti * Main_ParseWarn
177145679Sharti *
178145679Sharti *	Handle argument to warning option.
179145679Sharti */
180145679Shartiint
181145679ShartiMain_ParseWarn(const char *arg, int iscmd)
182145679Sharti{
183145679Sharti	int i, neg;
184145679Sharti
185145679Sharti	static const struct {
186145679Sharti		const char	*option;
187145679Sharti		uint32_t	flag;
188145679Sharti	} options[] = {
189145679Sharti		{ "dirsyntax",	WARN_DIRSYNTAX },
190145679Sharti		{ NULL,		0 }
191145679Sharti	};
192145679Sharti
193145679Sharti	neg = 0;
194145679Sharti	if (arg[0] == 'n' && arg[1] == 'o') {
195145679Sharti		neg = 1;
196145679Sharti		arg += 2;
197145679Sharti	}
198145679Sharti
199145679Sharti	for (i = 0; options[i].option != NULL; i++)
200145679Sharti		if (strcmp(arg, options[i].option) == 0)
201145679Sharti			break;
202145679Sharti
203145679Sharti	if (options[i].option == NULL)
204145679Sharti		/* unknown option */
205145679Sharti		return (-1);
206145679Sharti
207145679Sharti	if (iscmd) {
208145679Sharti		if (!neg) {
209145679Sharti			warn_cmd |= options[i].flag;
210145679Sharti			warn_nocmd &= ~options[i].flag;
211145679Sharti			warn_flags |= options[i].flag;
212145679Sharti		} else {
213145679Sharti			warn_nocmd |= options[i].flag;
214145679Sharti			warn_cmd &= ~options[i].flag;
215145679Sharti			warn_flags &= ~options[i].flag;
216145679Sharti		}
217145679Sharti	} else {
218145679Sharti		if (!neg) {
219145679Sharti			warn_flags |= (options[i].flag & ~warn_nocmd);
220145679Sharti		} else {
221145679Sharti			warn_flags &= ~(options[i].flag | warn_cmd);
222145679Sharti		}
223145679Sharti	}
224145679Sharti	return (0);
225145679Sharti}
226145679Sharti
227145679Sharti/**
228144475Sharti * MainParseArgs
2291590Srgrimes *	Parse a given argument vector. Called from main() and from
2301590Srgrimes *	Main_ParseArgLine() when the .MAKEFLAGS target is used.
2311590Srgrimes *
2321590Srgrimes *	XXX: Deal with command line overriding .MAKEFLAGS in makefile
2331590Srgrimes *
2341590Srgrimes * Side Effects:
2351590Srgrimes *	Various global and local flags will be set depending on the flags
2361590Srgrimes *	given
2371590Srgrimes */
2381590Srgrimesstatic void
239104696SjmallettMainParseArgs(int argc, char **argv)
2401590Srgrimes{
2415814Sjkh	int c;
242146038Sharti	Boolean	found_dd = FALSE;
2431590Srgrimes
244144896Shartirearg:
2451590Srgrimes	optind = 1;	/* since we're called more than once */
246144896Sharti	optreset = 1;
247145627Sharti#define OPTFLAGS "ABC:D:E:I:PSV:Xd:ef:ij:km:nqrstvx:"
248146038Sharti	for (;;) {
249146038Sharti		if ((optind < argc) && strcmp(argv[optind], "--") == 0) {
250146038Sharti			found_dd = TRUE;
251146038Sharti		}
252146038Sharti		if ((c = getopt(argc, argv, OPTFLAGS)) == -1) {
253146038Sharti			break;
254146038Sharti		}
2551590Srgrimes		switch(c) {
256144387Sharti
257144387Sharti		case 'A':
258144387Sharti			arch_fatal = FALSE;
259144387Sharti			MFLAGS_append("-A", NULL);
260144387Sharti			break;
261102393Sjmallett		case 'C':
262107964Sseanc			if (chdir(optarg) == -1)
263107964Sseanc				err(1, "chdir %s", optarg);
264102393Sjmallett			break;
2651590Srgrimes		case 'D':
2661590Srgrimes			Var_Set(optarg, "1", VAR_GLOBAL);
267133085Sharti			MFLAGS_append("-D", optarg);
2681590Srgrimes			break;
2691590Srgrimes		case 'I':
2701590Srgrimes			Parse_AddIncludeDir(optarg);
271133085Sharti			MFLAGS_append("-I", optarg);
2721590Srgrimes			break;
27317193Sbde		case 'V':
274138920Sru			Lst_AtEnd(&variables, estrdup(optarg));
275133085Sharti			MFLAGS_append("-V", optarg);
27617193Sbde			break;
27766365Speter		case 'X':
27866365Speter			expandVars = FALSE;
27966365Speter			break;
2801590Srgrimes		case 'B':
2811590Srgrimes			compatMake = TRUE;
282133085Sharti			MFLAGS_append("-B", NULL);
283137626Sphk			unsetenv("MAKE_JOBS_FIFO");
2841590Srgrimes			break;
2851590Srgrimes		case 'P':
2861590Srgrimes			usePipes = FALSE;
287133085Sharti			MFLAGS_append("-P", NULL);
2881590Srgrimes			break;
2891590Srgrimes		case 'S':
2901590Srgrimes			keepgoing = FALSE;
291133085Sharti			MFLAGS_append("-S", NULL);
2921590Srgrimes			break;
2931590Srgrimes		case 'd': {
2941590Srgrimes			char *modules = optarg;
2951590Srgrimes
2961590Srgrimes			for (; *modules; ++modules)
2971590Srgrimes				switch (*modules) {
2981590Srgrimes				case 'A':
2991590Srgrimes					debug = ~0;
3001590Srgrimes					break;
3011590Srgrimes				case 'a':
3021590Srgrimes					debug |= DEBUG_ARCH;
3031590Srgrimes					break;
3041590Srgrimes				case 'c':
3051590Srgrimes					debug |= DEBUG_COND;
3061590Srgrimes					break;
3071590Srgrimes				case 'd':
3081590Srgrimes					debug |= DEBUG_DIR;
3091590Srgrimes					break;
3101590Srgrimes				case 'f':
3111590Srgrimes					debug |= DEBUG_FOR;
3121590Srgrimes					break;
3131590Srgrimes				case 'g':
3141590Srgrimes					if (modules[1] == '1') {
3151590Srgrimes						debug |= DEBUG_GRAPH1;
3161590Srgrimes						++modules;
3171590Srgrimes					}
3181590Srgrimes					else if (modules[1] == '2') {
3191590Srgrimes						debug |= DEBUG_GRAPH2;
3201590Srgrimes						++modules;
3211590Srgrimes					}
3221590Srgrimes					break;
3231590Srgrimes				case 'j':
3241590Srgrimes					debug |= DEBUG_JOB;
3251590Srgrimes					break;
32660569Swill				case 'l':
32760569Swill					debug |= DEBUG_LOUD;
32860569Swill					break;
3291590Srgrimes				case 'm':
3301590Srgrimes					debug |= DEBUG_MAKE;
3311590Srgrimes					break;
3321590Srgrimes				case 's':
3331590Srgrimes					debug |= DEBUG_SUFF;
3341590Srgrimes					break;
3351590Srgrimes				case 't':
3361590Srgrimes					debug |= DEBUG_TARG;
3371590Srgrimes					break;
3381590Srgrimes				case 'v':
3391590Srgrimes					debug |= DEBUG_VAR;
3401590Srgrimes					break;
3411590Srgrimes				default:
342144475Sharti					warnx("illegal argument to d option "
343144475Sharti					    "-- %c", *modules);
3441590Srgrimes					usage();
3451590Srgrimes				}
346133085Sharti			MFLAGS_append("-d", optarg);
3471590Srgrimes			break;
3481590Srgrimes		}
34949332Shoek		case 'E':
350138920Sru			Lst_AtEnd(&envFirstVars, estrdup(optarg));
351133085Sharti			MFLAGS_append("-E", optarg);
35249332Shoek			break;
3531590Srgrimes		case 'e':
3541590Srgrimes			checkEnvFirst = TRUE;
355133085Sharti			MFLAGS_append("-e", NULL);
3561590Srgrimes			break;
3571590Srgrimes		case 'f':
358138920Sru			Lst_AtEnd(&makefiles, estrdup(optarg));
3591590Srgrimes			break;
3601590Srgrimes		case 'i':
3611590Srgrimes			ignoreErrors = TRUE;
362133085Sharti			MFLAGS_append("-i", NULL);
3631590Srgrimes			break;
36449331Shoek		case 'j': {
36549331Shoek			char *endptr;
36649331Shoek
36718730Ssteve			forceJobs = TRUE;
36849331Shoek			maxJobs = strtol(optarg, &endptr, 10);
36949331Shoek			if (maxJobs <= 0 || *endptr != '\0') {
37049938Shoek				warnx("illegal number, -j argument -- %s",
37149938Shoek				    optarg);
37249938Shoek				usage();
37349331Shoek			}
374133085Sharti			MFLAGS_append("-j", optarg);
3751590Srgrimes			break;
37649331Shoek		}
3771590Srgrimes		case 'k':
3781590Srgrimes			keepgoing = TRUE;
379133085Sharti			MFLAGS_append("-k", NULL);
3801590Srgrimes			break;
38118730Ssteve		case 'm':
382144020Sharti			Path_AddDir(&sysIncPath, optarg);
383133085Sharti			MFLAGS_append("-m", optarg);
38418730Ssteve			break;
3851590Srgrimes		case 'n':
3861590Srgrimes			noExecute = TRUE;
387133085Sharti			MFLAGS_append("-n", NULL);
3881590Srgrimes			break;
3891590Srgrimes		case 'q':
3901590Srgrimes			queryFlag = TRUE;
3911590Srgrimes			/* Kind of nonsensical, wot? */
392133085Sharti			MFLAGS_append("-q", NULL);
3931590Srgrimes			break;
3941590Srgrimes		case 'r':
3951590Srgrimes			noBuiltins = TRUE;
396133085Sharti			MFLAGS_append("-r", NULL);
3971590Srgrimes			break;
3981590Srgrimes		case 's':
3991590Srgrimes			beSilent = TRUE;
400133085Sharti			MFLAGS_append("-s", NULL);
4011590Srgrimes			break;
4021590Srgrimes		case 't':
4031590Srgrimes			touchFlag = TRUE;
404133085Sharti			MFLAGS_append("-t", NULL);
4051590Srgrimes			break;
40641151Sdg		case 'v':
40741151Sdg			beVerbose = TRUE;
408133085Sharti			MFLAGS_append("-v", NULL);
40941151Sdg			break;
410145627Sharti		case 'x':
411145679Sharti			if (Main_ParseWarn(optarg, 1) != -1)
412145627Sharti				MFLAGS_append("-x", optarg);
413145627Sharti			break;
414145627Sharti
4151590Srgrimes		default:
4161590Srgrimes		case '?':
4171590Srgrimes			usage();
4181590Srgrimes		}
4191590Srgrimes	}
420144896Sharti	argv += optind;
421144896Sharti	argc -= optind;
4221590Srgrimes
4231590Srgrimes	oldVars = TRUE;
4241590Srgrimes
4251590Srgrimes	/*
426144896Sharti	 * Parse the rest of the arguments.
427144896Sharti	 *	o Check for variable assignments and perform them if so.
428144896Sharti	 *	o Check for more flags and restart getopt if so.
429144896Sharti	 *      o Anything else is taken to be a target and added
430144896Sharti	 *	  to the end of the "create" list.
4311590Srgrimes	 */
432144896Sharti	for (; *argv != NULL; ++argv, --argc) {
433133562Sharti		if (Parse_IsVar(*argv)) {
434140870Sharti			char *ptr = MAKEFLAGS_quote(*argv);
435133562Sharti
436133562Sharti			Var_Append(MAKEFLAGS, ptr, VAR_GLOBAL);
437144896Sharti			Parse_DoVar(*argv, VAR_CMD);
438133562Sharti			free(ptr);
439133562Sharti
440144896Sharti		} else if ((*argv)[0] == '-') {
441144896Sharti			if ((*argv)[1] == '\0') {
442144896Sharti				/*
443144896Sharti				 * (*argv) is a single dash, so we
444144896Sharti				 * just ignore it.
445144896Sharti				 */
446146038Sharti			} else if (found_dd) {
447146038Sharti				/*
448146038Sharti				 * Double dash has been found, ignore
449146038Sharti				 * any more options.  But what do we do
450146038Sharti				 * with it?  For now treat it like a target.
451146038Sharti				 */
452146038Sharti				Lst_AtEnd(&create, estrdup(*argv));
453144896Sharti			} else {
454144896Sharti				/*
455146038Sharti				 * (*argv) is a -flag, so backup argv and
456146038Sharti				 * argc.  getopt() expects options to start
457146038Sharti				 * in the 2nd position.
458144896Sharti				 */
459144896Sharti				argc++;
460144896Sharti				argv--;
4611590Srgrimes				goto rearg;
4621590Srgrimes			}
463144896Sharti
464144896Sharti		} else if ((*argv)[0] == '\0') {
465144896Sharti			Punt("illegal (null) argument.");
466144896Sharti
467144896Sharti		} else {
468138916Sharti			Lst_AtEnd(&create, estrdup(*argv));
4691590Srgrimes		}
470144896Sharti	}
4711590Srgrimes}
4721590Srgrimes
473144475Sharti/**
474144475Sharti * Main_ParseArgLine
4751590Srgrimes *  	Used by the parse module when a .MFLAGS or .MAKEFLAGS target
4761590Srgrimes *	is encountered and by main() when reading the .MAKEFLAGS envariable.
4771590Srgrimes *	Takes a line of arguments and breaks it into its
4781590Srgrimes * 	component words and passes those words and the number of them to the
4791590Srgrimes *	MainParseArgs function.
4801590Srgrimes *	The line should have all its leading whitespace removed.
4811590Srgrimes *
4821590Srgrimes * Side Effects:
4831590Srgrimes *	Only those that come from the various arguments.
4841590Srgrimes */
4851590Srgrimesvoid
486140870ShartiMain_ParseArgLine(char *line, int mflags)
4871590Srgrimes{
4881590Srgrimes	char **argv;			/* Manufactured argument vector */
4891590Srgrimes	int argc;			/* Number of arguments in argv */
4901590Srgrimes
4911590Srgrimes	if (line == NULL)
4921590Srgrimes		return;
4931590Srgrimes	for (; *line == ' '; ++line)
4941590Srgrimes		continue;
4951590Srgrimes	if (!*line)
4961590Srgrimes		return;
4971590Srgrimes
498140870Sharti	if (mflags)
499140870Sharti		argv = MAKEFLAGS_break(line, &argc);
500140870Sharti	else
501140870Sharti		argv = brk_string(line, &argc, TRUE);
502140870Sharti
5031590Srgrimes	MainParseArgs(argc, argv);
5041590Srgrimes}
5051590Srgrimes
50618339Sswallacechar *
507141252Shartichdir_verify_path(const char *path, char *obpath)
50818339Sswallace{
50918339Sswallace	struct stat sb;
51018339Sswallace
51118339Sswallace	if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
51275973Sru		if (chdir(path) == -1 || getcwd(obpath, MAXPATHLEN) == NULL) {
51327644Scharnier			warn("warning: %s", path);
514141252Sharti			return (NULL);
51518339Sswallace		}
516138232Sharti		return (obpath);
51718339Sswallace	}
51818339Sswallace
519141252Sharti	return (NULL);
52018339Sswallace}
52118339Sswallace
522133082Shartistatic void
523133082Sharticatch_child(int sig __unused)
524123513Sdes{
525123513Sdes}
52618339Sswallace
527138071Sjmallett/*
528138071Sjmallett * In lieu of a good way to prevent every possible looping in
529138071Sjmallett * make(1), stop there from being more than MKLVL_MAXVAL processes forked
530138071Sjmallett * by make(1), to prevent a forkbomb from happening, in a dumb and
531138071Sjmallett * mechanical way.
532138071Sjmallett */
533138071Sjmallettstatic void
534138071Sjmallettcheck_make_level(void)
535138071Sjmallett{
536138071Sjmallett#ifdef WANT_ENV_MKLVL
537138071Sjmallett	char	*value = getenv(MKLVL_ENVVAR);
538138071Sjmallett	int	level = (value == NULL) ? 0 : atoi(value);
539138071Sjmallett
540138071Sjmallett	if (level < 0) {
541144475Sharti		errc(2, EAGAIN, "Invalid value for recursion level (%d).",
542144475Sharti		    level);
543138071Sjmallett	} else if (level > MKLVL_MAXVAL) {
544144475Sharti		errc(2, EAGAIN, "Max recursion level (%d) exceeded.",
545144475Sharti		    MKLVL_MAXVAL);
546138071Sjmallett	} else {
547138071Sjmallett		char new_value[32];
548138071Sjmallett		sprintf(new_value, "%d", level + 1);
549138071Sjmallett		setenv(MKLVL_ENVVAR, new_value, 1);
550138071Sjmallett	}
551138071Sjmallett#endif /* WANT_ENV_MKLVL */
552138071Sjmallett}
553138071Sjmallett
554144475Sharti/**
555144475Sharti * main
5561590Srgrimes *	The main function, for obvious reasons. Initializes variables
5571590Srgrimes *	and a few modules, then parses the arguments give it in the
5581590Srgrimes *	environment and on the command line. Reads the system makefile
5591590Srgrimes *	followed by either Makefile, makefile or the file given by the
5601590Srgrimes *	-f argument. Sets the .MAKEFLAGS PMake variable based on all the
5611590Srgrimes *	flags it has received by then uses either the Make or the Compat
5621590Srgrimes *	module to create the initial list of targets.
5631590Srgrimes *
5641590Srgrimes * Results:
5651590Srgrimes *	If -q was given, exits -1 if anything was out-of-date. Else it exits
5661590Srgrimes *	0.
5671590Srgrimes *
5681590Srgrimes * Side Effects:
5691590Srgrimes *	The program exits when done. Targets are created. etc. etc. etc.
5701590Srgrimes */
5711590Srgrimesint
572104696Sjmallettmain(int argc, char **argv)
5731590Srgrimes{
5741590Srgrimes	Boolean outOfDate = TRUE; 	/* FALSE if all targets up to date */
575141252Sharti	char *p, *p1, *pathp;
576141252Sharti	char *path;
57773262Simp	char mdpath[MAXPATHLEN];
57873262Simp	char obpath[MAXPATHLEN];
57973262Simp	char cdpath[MAXPATHLEN];
580141252Sharti    	const char *machine = getenv("MACHINE");
581141252Sharti	const char *machine_arch = getenv("MACHINE_ARCH");
582141252Sharti	const char *machine_cpu = getenv("MACHINE_CPU");
58318730Ssteve	char *cp = NULL, *start;
584141252Sharti
585144475Sharti	/* avoid faults on read-only strings */
586143412Sharti	static char syspath[] = PATH_DEFSYSPATH;
5871590Srgrimes
588123513Sdes	{
589123513Sdes	/*
590123513Sdes	 * Catch SIGCHLD so that we get kicked out of select() when we
591123513Sdes	 * need to look at a child.  This is only known to matter for the
592123513Sdes	 * -j case (perhaps without -P).
593123513Sdes	 *
594123513Sdes	 * XXX this is intentionally misplaced.
595123513Sdes	 */
596123513Sdes	struct sigaction sa;
597123513Sdes
598123513Sdes	sigemptyset(&sa.sa_mask);
599123513Sdes	sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
600123513Sdes	sa.sa_handler = catch_child;
601123513Sdes	sigaction(SIGCHLD, &sa, NULL);
602123513Sdes	}
603123513Sdes
604138071Sjmallett	check_make_level();
605104395Sjmallett
60664739Sgreen#if DEFSHELL == 2
60764739Sgreen	/*
60864739Sgreen	 * Turn off ENV to make ksh happier.
60964739Sgreen	 */
61064739Sgreen	unsetenv("ENV");
61164739Sgreen#endif
61264739Sgreen
61318730Ssteve#ifdef RLIMIT_NOFILE
6141590Srgrimes	/*
61518730Ssteve	 * get rid of resource limit on file descriptors
61618730Ssteve	 */
61718730Ssteve	{
61818730Ssteve		struct rlimit rl;
61918730Ssteve		if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
62018730Ssteve		    rl.rlim_cur != rl.rlim_max) {
62118730Ssteve			rl.rlim_cur = rl.rlim_max;
622138232Sharti			setrlimit(RLIMIT_NOFILE, &rl);
62318730Ssteve		}
62418730Ssteve	}
62518730Ssteve#endif
6261590Srgrimes
6275814Sjkh	/*
62839006Skato	 * PC-98 kernel sets the `i386' string to the utsname.machine and
62939006Skato	 * it cannot be distinguished from IBM-PC by uname(3).  Therefore,
63039006Skato	 * we check machine.ispc98 and adjust the machine variable before
63139006Skato	 * using usname(3) below.
63253631Smarcel	 * NOTE: machdep.ispc98 was defined on 1998/8/31. At that time,
63353631Smarcel	 * __FreeBSD_version was defined as 300003. So, this check can
63453631Smarcel	 * safely be done with any kernel with version > 300003.
63539006Skato	 */
63639006Skato	if (!machine) {
63739006Skato		int	ispc98;
63839006Skato		size_t	len;
63939006Skato
64039006Skato		len = sizeof(ispc98);
64139006Skato		if (!sysctlbyname("machdep.ispc98", &ispc98, &len, NULL, 0)) {
64239006Skato			if (ispc98)
64339006Skato				machine = "pc98";
64439006Skato		}
64539006Skato	}
64639006Skato
64739006Skato	/*
6485814Sjkh	 * Get the name of this type of MACHINE from utsname
6495814Sjkh	 * so we can share an executable for similar machines.
6505814Sjkh	 * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
6515814Sjkh	 *
6525814Sjkh	 * Note that while MACHINE is decided at run-time,
6535814Sjkh	 * MACHINE_ARCH is always known at compile time.
6545814Sjkh	 */
65518864Ssteve	if (!machine) {
65618339Sswallace#ifndef MACHINE
657144475Sharti		static struct utsname utsname;
65818730Ssteve
659144475Sharti		if (uname(&utsname) == -1)
660144475Sharti			err(2, "uname");
661144475Sharti		machine = utsname.machine;
66218339Sswallace#else
663144475Sharti		machine = MACHINE;
66418339Sswallace#endif
6655814Sjkh	}
6661590Srgrimes
66744362Simp	if (!machine_arch) {
66844362Simp#ifndef MACHINE_ARCH
66944362Simp		machine_arch = "unknown";
67044362Simp#else
67144362Simp		machine_arch = MACHINE_ARCH;
67244362Simp#endif
67344362Simp	}
67444362Simp
6751590Srgrimes	/*
67672679Skris	 * Set machine_cpu to the minumum supported CPU revision based
67772679Skris	 * on the target architecture, if not already set.
67872679Skris	 */
67972679Skris	if (!machine_cpu) {
68072679Skris		if (!strcmp(machine_arch, "i386"))
68172679Skris			machine_cpu = "i386";
68272679Skris		else if (!strcmp(machine_arch, "alpha"))
68372679Skris			machine_cpu = "ev4";
68472679Skris		else
68572679Skris			machine_cpu = "unknown";
68672679Skris	}
6871590Srgrimes
68866365Speter	expandVars = TRUE;
6891590Srgrimes	beSilent = FALSE;		/* Print commands as executed */
6901590Srgrimes	ignoreErrors = FALSE;		/* Pay attention to non-zero returns */
6911590Srgrimes	noExecute = FALSE;		/* Execute all commands */
6921590Srgrimes	keepgoing = FALSE;		/* Stop on error */
6931590Srgrimes	allPrecious = FALSE;		/* Remove targets when interrupted */
6941590Srgrimes	queryFlag = FALSE;		/* This is not just a check-run */
6951590Srgrimes	noBuiltins = FALSE;		/* Read the built-in rules */
6961590Srgrimes	touchFlag = FALSE;		/* Actually update targets */
6971590Srgrimes	usePipes = TRUE;		/* Catch child output in pipes */
6981590Srgrimes	debug = 0;			/* No debug verbosity, please. */
6991590Srgrimes	jobsRunning = FALSE;
7001590Srgrimes
701137571Sphk	maxJobs = DEFMAXJOBS;
70228228Sfsmp	forceJobs = FALSE;              /* No -j flag */
70318730Ssteve	compatMake = FALSE;		/* No compat mode */
7041590Srgrimes
7051590Srgrimes	/*
7061590Srgrimes	 * Initialize the parsing, directory and variable modules to prepare
7071590Srgrimes	 * for the reading of inclusion paths and variable settings on the
7081590Srgrimes	 * command line
7091590Srgrimes	 */
7101590Srgrimes	Dir_Init();		/* Initialize directory structures so -I flags
7111590Srgrimes				 * can be processed correctly */
712145971Sharti	Var_Init(environ);	/* As well as the lists of variables for
7131590Srgrimes				 * parsing arguments */
7145814Sjkh        str_init();
7151590Srgrimes
7161590Srgrimes	/*
7171590Srgrimes	 * Initialize various variables.
7181590Srgrimes	 *	MAKE also gets this name, for compatibility
7191590Srgrimes	 *	.MAKEFLAGS gets set to the empty string just in case.
7201590Srgrimes	 *	MFLAGS also gets initialized empty, for compatibility.
7211590Srgrimes	 */
7221590Srgrimes	Var_Set("MAKE", argv[0], VAR_GLOBAL);
7231590Srgrimes	Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
7241590Srgrimes	Var_Set("MFLAGS", "", VAR_GLOBAL);
7255814Sjkh	Var_Set("MACHINE", machine, VAR_GLOBAL);
72644362Simp	Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL);
72772679Skris	Var_Set("MACHINE_CPU", machine_cpu, VAR_GLOBAL);
72897121Sru#ifdef MAKE_VERSION
72997121Sru	Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL);
73097121Sru#endif
7311590Srgrimes
7321590Srgrimes	/*
733144896Sharti	 * First snag things out of the MAKEFLAGS environment
734144896Sharti	 * variable.  Then parse the command line arguments.
7351590Srgrimes	 */
736140870Sharti	Main_ParseArgLine(getenv("MAKEFLAGS"), 1);
7378874Srgrimes
7381590Srgrimes	MainParseArgs(argc, argv);
7391590Srgrimes
7401590Srgrimes	/*
741120053Sru	 * Find where we are...
742120053Sru	 */
743120053Sru	curdir = cdpath;
744120053Sru	if (getcwd(curdir, MAXPATHLEN) == NULL)
745120053Sru		err(2, NULL);
746120053Sru
747141252Sharti	{
748141252Sharti	struct stat sa;
749141252Sharti
750120053Sru	if (stat(curdir, &sa) == -1)
751120053Sru	    err(2, "%s", curdir);
752141252Sharti	}
753120053Sru
754120053Sru	/*
755120053Sru	 * The object directory location is determined using the
756120053Sru	 * following order of preference:
757120053Sru	 *
758120053Sru	 *	1. MAKEOBJDIRPREFIX`cwd`
759120053Sru	 *	2. MAKEOBJDIR
760143412Sharti	 *	3. PATH_OBJDIR.${MACHINE}
761143412Sharti	 *	4. PATH_OBJDIR
762143412Sharti	 *	5. PATH_OBJDIRPREFIX`cwd`
763120053Sru	 *
764120053Sru	 * If one of the first two fails, use the current directory.
765120053Sru	 * If the remaining three all fail, use the current directory.
766120053Sru	 *
767120053Sru	 * Once things are initted,
768120053Sru	 * have to add the original directory to the search path,
769120053Sru	 * and modify the paths for the Makefiles apropriately.  The
770120053Sru	 * current directory is also placed as a variable for make scripts.
771120053Sru	 */
772120053Sru	if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
773120053Sru		if (!(path = getenv("MAKEOBJDIR"))) {
774143412Sharti			path = PATH_OBJDIR;
775143412Sharti			pathp = PATH_OBJDIRPREFIX;
776138232Sharti			snprintf(mdpath, MAXPATHLEN, "%s.%s",
777120053Sru					path, machine);
778120053Sru			if (!(objdir = chdir_verify_path(mdpath, obpath)))
779120053Sru				if (!(objdir=chdir_verify_path(path, obpath))) {
780138232Sharti					snprintf(mdpath, MAXPATHLEN,
781120053Sru							"%s%s", pathp, curdir);
782120053Sru					if (!(objdir=chdir_verify_path(mdpath,
783120053Sru								       obpath)))
784120053Sru						objdir = curdir;
785120053Sru				}
786120053Sru		}
787120053Sru		else if (!(objdir = chdir_verify_path(path, obpath)))
788120053Sru			objdir = curdir;
789120053Sru	}
790120053Sru	else {
791138232Sharti		snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
792120053Sru		if (!(objdir = chdir_verify_path(mdpath, obpath)))
793120053Sru			objdir = curdir;
794120053Sru	}
795120053Sru	Dir_InitDot();		/* Initialize the "." directory */
796120053Sru	if (objdir != curdir)
797144020Sharti		Path_AddDir(&dirSearchPath, curdir);
798145971Sharti	Var_Set(".ST_EXPORTVAR", "YES", VAR_GLOBAL);
799120053Sru	Var_Set(".CURDIR", curdir, VAR_GLOBAL);
800120053Sru	Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
801120053Sru
802137606Sphk	if (getenv("MAKE_JOBS_FIFO") != NULL)
803137606Sphk		forceJobs = TRUE;
804120053Sru	/*
80528228Sfsmp	 * Be compatible if user did not specify -j and did not explicitly
80628228Sfsmp	 * turned compatibility on
80728228Sfsmp	 */
80828228Sfsmp	if (!compatMake && !forceJobs)
80928228Sfsmp		compatMake = TRUE;
81028228Sfsmp
81128228Sfsmp	/*
812144387Sharti	 * Initialize target and suffix modules in preparation for
8131590Srgrimes	 * parsing the makefile(s)
8141590Srgrimes	 */
8151590Srgrimes	Targ_Init();
8161590Srgrimes	Suff_Init();
8171590Srgrimes
81869527Swill	DEFAULT = NULL;
819138232Sharti	time(&now);
8201590Srgrimes
8211590Srgrimes	/*
8221590Srgrimes	 * Set up the .TARGETS variable to contain the list of targets to be
8231590Srgrimes	 * created. If none specified, make the variable empty -- the parser
8241590Srgrimes	 * will fill the thing in with the default or .MAIN target.
8251590Srgrimes	 */
826138916Sharti	if (!Lst_IsEmpty(&create)) {
827138512Sharti		LstNode *ln;
8281590Srgrimes
829138916Sharti		for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) {
830138264Sharti			char *name = Lst_Datum(ln);
8311590Srgrimes
8321590Srgrimes			Var_Append(".TARGETS", name, VAR_GLOBAL);
8331590Srgrimes		}
8341590Srgrimes	} else
8351590Srgrimes		Var_Set(".TARGETS", "", VAR_GLOBAL);
8361590Srgrimes
83718730Ssteve
8381590Srgrimes	/*
83918730Ssteve	 * If no user-supplied system path was given (through the -m option)
84018730Ssteve	 * add the directories from the DEFSYSPATH (more than one may be given
84118730Ssteve	 * as dir1:...:dirn) to the system include path.
8421590Srgrimes	 */
843144020Sharti	if (TAILQ_EMPTY(&sysIncPath)) {
84418730Ssteve		for (start = syspath; *start != '\0'; start = cp) {
84518730Ssteve			for (cp = start; *cp != '\0' && *cp != ':'; cp++)
84618730Ssteve				continue;
84718730Ssteve			if (*cp == '\0') {
848144020Sharti				Path_AddDir(&sysIncPath, start);
84918730Ssteve			} else {
85018730Ssteve				*cp++ = '\0';
851144020Sharti				Path_AddDir(&sysIncPath, start);
85218730Ssteve			}
85318730Ssteve		}
85418730Ssteve	}
8551590Srgrimes
85618730Ssteve	/*
85718730Ssteve	 * Read in the built-in rules first, followed by the specified
85818730Ssteve	 * makefile, if it was (makefile != (char *) NULL), or the default
85918730Ssteve	 * Makefile and makefile, in that order, if it wasn't.
86018730Ssteve	 */
86118730Ssteve	if (!noBuiltins) {
862138916Sharti		/* Path of sys.mk */
863138916Sharti		Lst sysMkPath = Lst_Initializer(sysMkPath);
864138512Sharti		LstNode *ln;
865146064Sharti		char	defsysmk[] = PATH_DEFSYSMK;
86618730Ssteve
867146064Sharti		Path_Expand(defsysmk, &sysIncPath, &sysMkPath);
868138916Sharti		if (Lst_IsEmpty(&sysMkPath))
869143412Sharti			Fatal("make: no system rules (%s).", PATH_DEFSYSMK);
870143808Sharti		LST_FOREACH(ln, &sysMkPath) {
871143808Sharti			if (!ReadMakefile(Lst_Datum(ln)))
872143808Sharti				break;
873143808Sharti		}
87469527Swill		if (ln != NULL)
87518730Ssteve			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
876138916Sharti		Lst_Destroy(&sysMkPath, free);
87718730Ssteve	}
87818730Ssteve
879138916Sharti	if (!Lst_IsEmpty(&makefiles)) {
880138512Sharti		LstNode *ln;
8811590Srgrimes
882143808Sharti		LST_FOREACH(ln, &makefiles) {
883143808Sharti			if (!ReadMakefile(Lst_Datum(ln)))
884143808Sharti				break;
885143808Sharti		}
88669527Swill		if (ln != NULL)
8871590Srgrimes			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
888143808Sharti	} else if (!ReadMakefile("BSDmakefile"))
889143808Sharti	    if (!ReadMakefile("makefile"))
890143808Sharti		ReadMakefile("Makefile");
8911590Srgrimes
892143808Sharti	ReadMakefile(".depend");
8931590Srgrimes
8941590Srgrimes	/* Install all the flags into the MAKE envariable. */
8955814Sjkh	if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1)) != NULL) && *p)
8961590Srgrimes		setenv("MAKEFLAGS", p, 1);
897105826Sjmallett	free(p1);
8981590Srgrimes
8991590Srgrimes	/*
9001590Srgrimes	 * For compatibility, look at the directories in the VPATH variable
9011590Srgrimes	 * and add them to the search path, if the variable is defined. The
9021590Srgrimes	 * variable's value is in the same format as the PATH envariable, i.e.
9031590Srgrimes	 * <directory>:<directory>:<directory>...
9041590Srgrimes	 */
9051590Srgrimes	if (Var_Exists("VPATH", VAR_CMD)) {
9061590Srgrimes		/*
9071590Srgrimes		 * GCC stores string constants in read-only memory, but
9081590Srgrimes		 * Var_Subst will want to write this thing, so store it
9091590Srgrimes		 * in an array
9101590Srgrimes		 */
9111590Srgrimes		static char VPATH[] = "${VPATH}";
912142457Sharti		Buffer	*buf;
913142457Sharti		char	*vpath;
914142457Sharti		char	*ptr;
915142457Sharti		char	savec;
9161590Srgrimes
917146027Sharti		buf = Var_Subst(VPATH, VAR_CMD, FALSE);
918142457Sharti
919143959Sharti		vpath = Buf_Data(buf);
9201590Srgrimes		do {
9211590Srgrimes			/* skip to end of directory */
922142457Sharti			for (ptr = vpath; *ptr != ':' && *ptr != '\0'; ptr++)
923141969Sharti				;
924141969Sharti
9251590Srgrimes			/* Save terminator character so know when to stop */
926141969Sharti			savec = *ptr;
927141969Sharti			*ptr = '\0';
928141969Sharti
9291590Srgrimes			/* Add directory to search path */
930144020Sharti			Path_AddDir(&dirSearchPath, vpath);
931141969Sharti
932142457Sharti			vpath = ptr + 1;
933141969Sharti		} while (savec != '\0');
934142457Sharti
935142457Sharti		Buf_Destroy(buf, TRUE);
9361590Srgrimes	}
9371590Srgrimes
9381590Srgrimes	/*
9391590Srgrimes	 * Now that all search paths have been read for suffixes et al, it's
9401590Srgrimes	 * time to add the default search path to their lists...
9411590Srgrimes	 */
9421590Srgrimes	Suff_DoPaths();
9431590Srgrimes
9441590Srgrimes	/* print the initial graph, if the user requested it */
9451590Srgrimes	if (DEBUG(GRAPH1))
9461590Srgrimes		Targ_PrintGraph(1);
9471590Srgrimes
94817193Sbde	/* print the values of any variables requested by the user */
949141974Sharti	if (Lst_IsEmpty(&variables)) {
9501590Srgrimes		/*
951141974Sharti		 * Since the user has not requested that any variables
952142008Sharti		 * be printed, we can build targets.
953141974Sharti		 *
954142008Sharti		 * Have read the entire graph and need to make a list of targets
955141974Sharti		 * to create. If none was given on the command line, we consult
956141974Sharti		 * the parsing module to find the main target(s) to create.
9571590Srgrimes		 */
958138916Sharti		Lst targs = Lst_Initializer(targs);
959138916Sharti
960138916Sharti		if (Lst_IsEmpty(&create))
961138916Sharti			Parse_MainName(&targs);
962101460Sru		else
963138916Sharti			Targ_FindList(&targs, &create, TARG_CREATE);
964101460Sru
965141974Sharti		if (compatMake) {
966101460Sru			/*
967141974Sharti			 * Compat_Init will take care of creating
968141974Sharti			 * all the targets as well as initializing
969141974Sharti			 * the module.
970101460Sru			 */
971141974Sharti			Compat_Run(&targs);
972141974Sharti			outOfDate = 0;
973141974Sharti		} else {
974141974Sharti			/*
975141974Sharti			 * Initialize job module before traversing
976141974Sharti			 * the graph, now that any .BEGIN and .END
977141974Sharti			 * targets have been read.  This is done
978141974Sharti			 * only if the -q flag wasn't given (to
979141974Sharti			 * prevent the .BEGIN from being executed
980141974Sharti			 * should it exist).
981141974Sharti			 */
982101460Sru			if (!queryFlag) {
983137572Sphk				Job_Init(maxJobs);
984101460Sru				jobsRunning = TRUE;
985101460Sru			}
986101460Sru
987101460Sru			/* Traverse the graph, checking on all the targets */
988138916Sharti			outOfDate = Make_Run(&targs);
9891590Srgrimes		}
990138916Sharti		Lst_Destroy(&targs, NOFREE);
991141974Sharti
992141974Sharti	} else {
993141974Sharti		/*
994141974Sharti		 * Print the values of any variables requested by
995141974Sharti		 * the user.
996141974Sharti		 */
997142457Sharti		LstNode		*n;
998142457Sharti		const char	*name;
999142457Sharti		char		*v;
1000142457Sharti		char		*value;
1001141974Sharti
1002142457Sharti		LST_FOREACH(n, &variables) {
1003142457Sharti			name = Lst_Datum(n);
1004141974Sharti			if (expandVars) {
1005141974Sharti				v = emalloc(strlen(name) + 1 + 3);
1006141974Sharti				sprintf(v, "${%s}", name);
1007141974Sharti
1008146027Sharti				value = Buf_Peel(Var_Subst(v,
1009143292Sharti				    VAR_GLOBAL, FALSE));
1010142457Sharti				printf("%s\n", value);
1011142457Sharti
1012142457Sharti				free(v);
1013143292Sharti				free(value);
1014141974Sharti			} else {
1015141974Sharti				value = Var_Value(name, VAR_GLOBAL, &v);
1016142457Sharti				printf("%s\n", value != NULL ? value : "");
1017142457Sharti				if (v != NULL)
1018142457Sharti					free(v);
1019141974Sharti			}
1020141974Sharti		}
102117193Sbde	}
10228874Srgrimes
1023138920Sru	Lst_Destroy(&variables, free);
1024138920Sru	Lst_Destroy(&makefiles, free);
1025138916Sharti	Lst_Destroy(&create, free);
10265814Sjkh
10271590Srgrimes	/* print the graph now it's been processed if the user requested it */
10281590Srgrimes	if (DEBUG(GRAPH2))
10291590Srgrimes		Targ_PrintGraph(2);
10301590Srgrimes
10311590Srgrimes	if (queryFlag && outOfDate)
1032138232Sharti		return (1);
10331590Srgrimes	else
1034138232Sharti		return (0);
10351590Srgrimes}
10361590Srgrimes
1037144475Sharti/**
1038144475Sharti * ReadMakefile
10391590Srgrimes *	Open and parse the given makefile.
10401590Srgrimes *
10411590Srgrimes * Results:
10421590Srgrimes *	TRUE if ok. FALSE if couldn't open file.
10431590Srgrimes *
10441590Srgrimes * Side Effects:
10451590Srgrimes *	lots
10461590Srgrimes */
10471590Srgrimesstatic Boolean
1048143808ShartiReadMakefile(const char *p)
10491590Srgrimes{
1050104696Sjmallett	char *fname;			/* makefile to read */
10511590Srgrimes	FILE *stream;
105273262Simp	char *name, path[MAXPATHLEN];
105397163Sjmallett	char *MAKEFILE;
105494990Sru	int setMAKEFILE;
10551590Srgrimes
1056138561Sharti	/* XXX - remove this once constification is done */
1057138561Sharti	fname = estrdup(p);
1058104696Sjmallett
10591590Srgrimes	if (!strcmp(fname, "-")) {
10601590Srgrimes		Parse_File("(stdin)", stdin);
10611590Srgrimes		Var_Set("MAKEFILE", "", VAR_GLOBAL);
10621590Srgrimes	} else {
106394990Sru		setMAKEFILE = strcmp(fname, ".depend");
106494990Sru
10651590Srgrimes		/* if we've chdir'd, rebuild the path name */
10661590Srgrimes		if (curdir != objdir && *fname != '/') {
1067138232Sharti			snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname);
1068100733Simp			/*
1069100733Simp			 * XXX The realpath stuff breaks relative includes
1070100733Simp			 * XXX in some cases.   The problem likely is in
1071100733Simp			 * XXX parse.c where it does special things in
1072100733Simp			 * XXX ParseDoInclude if the file is relateive
1073100733Simp			 * XXX or absolute and not a system file.  There
1074100733Simp			 * XXX it assumes that if the current file that's
1075100733Simp			 * XXX being included is absolute, that any files
1076100733Simp			 * XXX that it includes shouldn't do the -I path
1077100733Simp			 * XXX stuff, which is inconsistant with historical
1078100733Simp			 * XXX behavior.  However, I can't pentrate the mists
1079100733Simp			 * XXX further, so I'm putting this workaround in
1080100733Simp			 * XXX here until such time as the underlying bug
1081100733Simp			 * XXX can be fixed.
1082100733Simp			 */
1083100733Simp#if THIS_BREAKS_THINGS
108497077Sjmallett			if (realpath(path, path) != NULL &&
108597077Sjmallett			    (stream = fopen(path, "r")) != NULL) {
108697163Sjmallett				MAKEFILE = fname;
10871590Srgrimes				fname = path;
10881590Srgrimes				goto found;
10891590Srgrimes			}
109097077Sjmallett		} else if (realpath(fname, path) != NULL) {
109197163Sjmallett			MAKEFILE = fname;
109297077Sjmallett			fname = path;
109397077Sjmallett			if ((stream = fopen(fname, "r")) != NULL)
109497077Sjmallett				goto found;
109597077Sjmallett		}
1096100733Simp#else
1097100733Simp			if ((stream = fopen(path, "r")) != NULL) {
1098100733Simp				MAKEFILE = fname;
1099100733Simp				fname = path;
1100100733Simp				goto found;
1101100733Simp			}
1102100733Simp		} else {
1103100733Simp			MAKEFILE = fname;
1104100733Simp			if ((stream = fopen(fname, "r")) != NULL)
1105100733Simp				goto found;
1106100733Simp		}
1107100733Simp#endif
11081590Srgrimes		/* look in -I and system include directories. */
1109144020Sharti		name = Path_FindFile(fname, &parseIncPath);
11101590Srgrimes		if (!name)
1111144020Sharti			name = Path_FindFile(fname, &sysIncPath);
11121590Srgrimes		if (!name || !(stream = fopen(name, "r")))
1113138232Sharti			return (FALSE);
111497163Sjmallett		MAKEFILE = fname = name;
11151590Srgrimes		/*
11161590Srgrimes		 * set the MAKEFILE variable desired by System V fans -- the
11171590Srgrimes		 * placement of the setting here means it gets set to the last
11181590Srgrimes		 * makefile specified, as it is set by SysV make.
11191590Srgrimes		 */
112094990Srufound:
112194990Sru		if (setMAKEFILE)
112297163Sjmallett			Var_Set("MAKEFILE", MAKEFILE, VAR_GLOBAL);
11231590Srgrimes		Parse_File(fname, stream);
1124138232Sharti		fclose(stream);
11251590Srgrimes	}
1126138232Sharti	return (TRUE);
11271590Srgrimes}
11281590Srgrimes
11291590Srgrimes/*
11301590Srgrimes * usage --
11311590Srgrimes *	exit with usage message
11321590Srgrimes */
11331590Srgrimesstatic void
1134104696Sjmallettusage(void)
11351590Srgrimes{
1136145627Sharti	fprintf(stderr, "%s\n%s\n%s\n%s\n",
1137145627Sharti"usage: make [-ABPSXeiknqrstv] [-C directory] [-D variable] [-d flags]",
1138113512Sru"            [-E variable] [-f makefile] [-I directory] [-j max_jobs]",
1139145627Sharti"            [-m directory] [-V variable] [variable=value] [-x warn_flag]",
1140145627Sharti"            [target ...]");
11411590Srgrimes	exit(2);
11421590Srgrimes}
1143