Home | History | Annotate | Line # | Download | only in make
main.c revision 1.52
      1 /*	$NetBSD: main.c,v 1.52 2000/04/14 06:11:09 simonb Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1988, 1989, 1990, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  * Copyright (c) 1989 by Berkeley Softworks
      7  * All rights reserved.
      8  *
      9  * This code is derived from software contributed to Berkeley by
     10  * Adam de Boor.
     11  *
     12  * Redistribution and use in source and binary forms, with or without
     13  * modification, are permitted provided that the following conditions
     14  * are met:
     15  * 1. Redistributions of source code must retain the above copyright
     16  *    notice, this list of conditions and the following disclaimer.
     17  * 2. Redistributions in binary form must reproduce the above copyright
     18  *    notice, this list of conditions and the following disclaimer in the
     19  *    documentation and/or other materials provided with the distribution.
     20  * 3. All advertising materials mentioning features or use of this software
     21  *    must display the following acknowledgement:
     22  *	This product includes software developed by the University of
     23  *	California, Berkeley and its contributors.
     24  * 4. Neither the name of the University nor the names of its contributors
     25  *    may be used to endorse or promote products derived from this software
     26  *    without specific prior written permission.
     27  *
     28  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     38  * SUCH DAMAGE.
     39  */
     40 
     41 #ifdef MAKE_BOOTSTRAP
     42 static char rcsid[] = "$NetBSD: main.c,v 1.52 2000/04/14 06:11:09 simonb Exp $";
     43 #else
     44 #include <sys/cdefs.h>
     45 #ifndef lint
     46 __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\n\
     47 	The Regents of the University of California.  All rights reserved.\n");
     48 #endif /* not lint */
     49 
     50 #ifndef lint
     51 #if 0
     52 static char sccsid[] = "@(#)main.c	8.3 (Berkeley) 3/19/94";
     53 #else
     54 __RCSID("$NetBSD: main.c,v 1.52 2000/04/14 06:11:09 simonb Exp $");
     55 #endif
     56 #endif /* not lint */
     57 #endif
     58 
     59 /*-
     60  * main.c --
     61  *	The main file for this entire program. Exit routines etc
     62  *	reside here.
     63  *
     64  * Utility functions defined in this file:
     65  *	Main_ParseArgLine	Takes a line of arguments, breaks them and
     66  *				treats them as if they were given when first
     67  *				invoked. Used by the parse module to implement
     68  *				the .MFLAGS target.
     69  *
     70  *	Error			Print a tagged error message. The global
     71  *				MAKE variable must have been defined. This
     72  *				takes a format string and two optional
     73  *				arguments for it.
     74  *
     75  *	Fatal			Print an error message and exit. Also takes
     76  *				a format string and two arguments.
     77  *
     78  *	Punt			Aborts all jobs and exits with a message. Also
     79  *				takes a format string and two arguments.
     80  *
     81  *	Finish			Finish things up by printing the number of
     82  *				errors which occured, as passed to it, and
     83  *				exiting.
     84  */
     85 
     86 #include <sys/types.h>
     87 #include <sys/time.h>
     88 #include <sys/param.h>
     89 #include <sys/resource.h>
     90 #include <sys/signal.h>
     91 #include <sys/stat.h>
     92 #ifndef MAKE_BOOTSTRAP
     93 #include <sys/utsname.h>
     94 #endif
     95 #include <sys/wait.h>
     96 #include <errno.h>
     97 #include <fcntl.h>
     98 #include <stdio.h>
     99 #include <stdlib.h>
    100 #include <time.h>
    101 #ifdef __STDC__
    102 #include <stdarg.h>
    103 #else
    104 #include <varargs.h>
    105 #endif
    106 #include "make.h"
    107 #include "hash.h"
    108 #include "dir.h"
    109 #include "job.h"
    110 #include "pathnames.h"
    111 
    112 #ifndef	DEFMAXLOCAL
    113 #define	DEFMAXLOCAL DEFMAXJOBS
    114 #endif	/* DEFMAXLOCAL */
    115 
    116 #define	MAKEFLAGS	".MAKEFLAGS"
    117 
    118 Lst			create;		/* Targets to be made */
    119 time_t			now;		/* Time at start of make */
    120 GNode			*DEFAULT;	/* .DEFAULT node */
    121 Boolean			allPrecious;	/* .PRECIOUS given on line by itself */
    122 
    123 static Boolean		noBuiltins;	/* -r flag */
    124 static Lst		makefiles;	/* ordered list of makefiles to read */
    125 static Boolean		printVars;	/* print value of one or more vars */
    126 static Lst		variables;	/* list of variables to print */
    127 int			maxJobs;	/* -j argument */
    128 static int		maxLocal;	/* -L argument */
    129 Boolean			compatMake;	/* -B argument */
    130 Boolean			debug;		/* -d flag */
    131 Boolean			noExecute;	/* -n flag */
    132 Boolean			keepgoing;	/* -k flag */
    133 Boolean			queryFlag;	/* -q flag */
    134 Boolean			touchFlag;	/* -t flag */
    135 Boolean			usePipes;	/* !-P flag */
    136 Boolean			ignoreErrors;	/* -i flag */
    137 Boolean			beSilent;	/* -s flag */
    138 Boolean			oldVars;	/* variable substitution style */
    139 Boolean			checkEnvFirst;	/* -e flag */
    140 Boolean			mkIncPath;	/* -m flag */
    141 static Boolean		jobsRunning;	/* TRUE if the jobs might be running */
    142 
    143 static void		MainParseArgs __P((int, char **));
    144 char *			chdir_verify_path __P((char *, char *));
    145 static int		ReadMakefile __P((ClientData, ClientData));
    146 static void		usage __P((void));
    147 
    148 static char *curdir;			/* startup directory */
    149 static char *objdir;			/* where we chdir'ed to */
    150 
    151 /*-
    152  * MainParseArgs --
    153  *	Parse a given argument vector. Called from main() and from
    154  *	Main_ParseArgLine() when the .MAKEFLAGS target is used.
    155  *
    156  *	XXX: Deal with command line overriding .MAKEFLAGS in makefile
    157  *
    158  * Results:
    159  *	None
    160  *
    161  * Side Effects:
    162  *	Various global and local flags will be set depending on the flags
    163  *	given
    164  */
    165 static void
    166 MainParseArgs(argc, argv)
    167 	int argc;
    168 	char **argv;
    169 {
    170 	char *p;
    171 	int c;
    172 	int forceJobs = 0;
    173 
    174 	optind = 1;	/* since we're called more than once */
    175 #ifdef REMOTE
    176 # define OPTFLAGS "BD:I:L:PSV:d:ef:ij:km:nqrst"
    177 #else
    178 # define OPTFLAGS "BD:I:PSV:d:ef:ij:km:nqrst"
    179 #endif
    180 rearg:	while((c = getopt(argc, argv, OPTFLAGS)) != -1) {
    181 		switch(c) {
    182 		case 'D':
    183 			Var_Set(optarg, "1", VAR_GLOBAL);
    184 			Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
    185 			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
    186 			break;
    187 		case 'I':
    188 			Parse_AddIncludeDir(optarg);
    189 			Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
    190 			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
    191 			break;
    192 		case 'V':
    193 			printVars = TRUE;
    194 			(void)Lst_AtEnd(variables, (ClientData)optarg);
    195 			Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
    196 			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
    197 			break;
    198 		case 'B':
    199 			compatMake = TRUE;
    200 			break;
    201 #ifdef REMOTE
    202 		case 'L':
    203 			maxLocal = strtol(optarg, &p, 0);
    204 			if (*p != '\0' || maxLocal < 1) {
    205 				(void) fprintf(stderr, "make: illegal argument to -L -- must be positive integer!\n");
    206 				exit(1);
    207 			}
    208 			Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
    209 			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
    210 			break;
    211 #endif
    212 		case 'P':
    213 			usePipes = FALSE;
    214 			Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
    215 			break;
    216 		case 'S':
    217 			keepgoing = FALSE;
    218 			Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
    219 			break;
    220 		case 'd': {
    221 			char *modules = optarg;
    222 
    223 			for (; *modules; ++modules)
    224 				switch (*modules) {
    225 				case 'A':
    226 					debug = ~0;
    227 					break;
    228 				case 'a':
    229 					debug |= DEBUG_ARCH;
    230 					break;
    231 				case 'c':
    232 					debug |= DEBUG_COND;
    233 					break;
    234 				case 'd':
    235 					debug |= DEBUG_DIR;
    236 					break;
    237 				case 'f':
    238 					debug |= DEBUG_FOR;
    239 					break;
    240 				case 'g':
    241 					if (modules[1] == '1') {
    242 						debug |= DEBUG_GRAPH1;
    243 						++modules;
    244 					}
    245 					else if (modules[1] == '2') {
    246 						debug |= DEBUG_GRAPH2;
    247 						++modules;
    248 					}
    249 					break;
    250 				case 'j':
    251 					debug |= DEBUG_JOB;
    252 					break;
    253 				case 'm':
    254 					debug |= DEBUG_MAKE;
    255 					break;
    256 				case 's':
    257 					debug |= DEBUG_SUFF;
    258 					break;
    259 				case 't':
    260 					debug |= DEBUG_TARG;
    261 					break;
    262 				case 'v':
    263 					debug |= DEBUG_VAR;
    264 					break;
    265 				default:
    266 					(void)fprintf(stderr,
    267 				"make: illegal argument to d option -- %c\n",
    268 					    *modules);
    269 					usage();
    270 				}
    271 			Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
    272 			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
    273 			break;
    274 		}
    275 		case 'e':
    276 			checkEnvFirst = TRUE;
    277 			Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
    278 			break;
    279 		case 'f':
    280 			(void)Lst_AtEnd(makefiles, (ClientData)optarg);
    281 			break;
    282 		case 'i':
    283 			ignoreErrors = TRUE;
    284 			Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
    285 			break;
    286 		case 'j':
    287 			forceJobs = TRUE;
    288 			maxJobs = strtol(optarg, &p, 0);
    289 			if (*p != '\0' || maxJobs < 1) {
    290 				(void) fprintf(stderr, "make: illegal argument to -j -- must be positive integer!\n");
    291 				exit(1);
    292 			}
    293 #ifndef REMOTE
    294 			maxLocal = maxJobs;
    295 #endif
    296 			Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
    297 			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
    298 			break;
    299 		case 'k':
    300 			keepgoing = TRUE;
    301 			Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
    302 			break;
    303 		case 'm':
    304 			mkIncPath = TRUE;
    305 			(void) Dir_AddDir(sysIncPath, optarg);
    306 			Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
    307 			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
    308 			break;
    309 		case 'n':
    310 			noExecute = TRUE;
    311 			Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
    312 			break;
    313 		case 'q':
    314 			queryFlag = TRUE;
    315 			/* Kind of nonsensical, wot? */
    316 			Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
    317 			break;
    318 		case 'r':
    319 			noBuiltins = TRUE;
    320 			Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
    321 			break;
    322 		case 's':
    323 			beSilent = TRUE;
    324 			Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
    325 			break;
    326 		case 't':
    327 			touchFlag = TRUE;
    328 			Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
    329 			break;
    330 		default:
    331 		case '?':
    332 			usage();
    333 		}
    334 	}
    335 
    336 	/*
    337 	 * Be compatible if user did not specify -j and did not explicitly
    338 	 * turned compatibility on
    339 	 */
    340 	if (!compatMake && !forceJobs)
    341 		compatMake = TRUE;
    342 
    343 	oldVars = TRUE;
    344 
    345 	/*
    346 	 * See if the rest of the arguments are variable assignments and
    347 	 * perform them if so. Else take them to be targets and stuff them
    348 	 * on the end of the "create" list.
    349 	 */
    350 	for (argv += optind, argc -= optind; *argv; ++argv, --argc)
    351 		if (Parse_IsVar(*argv))
    352 			Parse_DoVar(*argv, VAR_CMD);
    353 		else {
    354 			if (!**argv)
    355 				Punt("illegal (null) argument.");
    356 			if (**argv == '-') {
    357 				if ((*argv)[1])
    358 					optind = 0;     /* -flag... */
    359 				else
    360 					optind = 1;     /* - */
    361 				goto rearg;
    362 			}
    363 			(void)Lst_AtEnd(create, (ClientData)estrdup(*argv));
    364 		}
    365 }
    366 
    367 /*-
    368  * Main_ParseArgLine --
    369  *  	Used by the parse module when a .MFLAGS or .MAKEFLAGS target
    370  *	is encountered and by main() when reading the .MAKEFLAGS envariable.
    371  *	Takes a line of arguments and breaks it into its
    372  * 	component words and passes those words and the number of them to the
    373  *	MainParseArgs function.
    374  *	The line should have all its leading whitespace removed.
    375  *
    376  * Results:
    377  *	None
    378  *
    379  * Side Effects:
    380  *	Only those that come from the various arguments.
    381  */
    382 void
    383 Main_ParseArgLine(line)
    384 	char *line;			/* Line to fracture */
    385 {
    386 	char **argv;			/* Manufactured argument vector */
    387 	int argc;			/* Number of arguments in argv */
    388 	char *args;			/* Space used by the args */
    389 	char *buf, *p1;
    390 	char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &p1);
    391 	size_t len;
    392 
    393 	if (line == NULL)
    394 		return;
    395 	for (; *line == ' '; ++line)
    396 		continue;
    397 	if (!*line)
    398 		return;
    399 
    400 	buf = emalloc(len = strlen(line) + strlen(argv0) + 2);
    401 	(void)snprintf(buf, len, "%s %s", argv0, line);
    402 	if (p1)
    403 		free(p1);
    404 
    405 	argv = brk_string(buf, &argc, TRUE, &args);
    406 	free(buf);
    407 	MainParseArgs(argc, argv);
    408 
    409 	free(args);
    410 	free(argv);
    411 }
    412 
    413 char *
    414 chdir_verify_path(path, obpath)
    415 	char *path;
    416 	char *obpath;
    417 {
    418 	struct stat sb;
    419 
    420 	if (strchr(path, '$') != 0) {
    421 		path = Var_Subst(NULL, path, VAR_GLOBAL, 0);
    422 	}
    423 	if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
    424 		if (chdir(path)) {
    425 			(void)fprintf(stderr, "make warning: %s: %s.\n",
    426 				      path, strerror(errno));
    427 			return 0;
    428 		}
    429 		else {
    430 			if (path[0] != '/') {
    431 				(void) snprintf(obpath, MAXPATHLEN, "%s/%s",
    432 						curdir, path);
    433 				return obpath;
    434 			}
    435 			else
    436 				return path;
    437 		}
    438 	}
    439 
    440 	return 0;
    441 }
    442 
    443 
    444 /*-
    445  * main --
    446  *	The main function, for obvious reasons. Initializes variables
    447  *	and a few modules, then parses the arguments give it in the
    448  *	environment and on the command line. Reads the system makefile
    449  *	followed by either Makefile, makefile or the file given by the
    450  *	-f argument. Sets the .MAKEFLAGS PMake variable based on all the
    451  *	flags it has received by then uses either the Make or the Compat
    452  *	module to create the initial list of targets.
    453  *
    454  * Results:
    455  *	If -q was given, exits -1 if anything was out-of-date. Else it exits
    456  *	0.
    457  *
    458  * Side Effects:
    459  *	The program exits when done. Targets are created. etc. etc. etc.
    460  */
    461 int
    462 main(argc, argv)
    463 	int argc;
    464 	char **argv;
    465 {
    466 	Lst targs;	/* target nodes to create -- passed to Make_Init */
    467 	Boolean outOfDate = TRUE; 	/* FALSE if all targets up to date */
    468 	struct stat sb, sa;
    469 	char *p, *p1, *path, *pathp, *pwd;
    470 	char mdpath[MAXPATHLEN + 1];
    471 	char obpath[MAXPATHLEN + 1];
    472 	char cdpath[MAXPATHLEN + 1];
    473     	char *machine = getenv("MACHINE");
    474 	char *machine_arch = getenv("MACHINE_ARCH");
    475 	Lst sysMkPath;			/* Path of sys.mk */
    476 	char *cp = NULL, *start;
    477 					/* avoid faults on read-only strings */
    478 	static char syspath[] = _PATH_DEFSYSPATH;
    479 
    480 #ifdef RLIMIT_NOFILE
    481 	/*
    482 	 * get rid of resource limit on file descriptors
    483 	 */
    484 	{
    485 		struct rlimit rl;
    486 		if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
    487 		    rl.rlim_cur != rl.rlim_max) {
    488 			rl.rlim_cur = rl.rlim_max;
    489 			(void) setrlimit(RLIMIT_NOFILE, &rl);
    490 		}
    491 	}
    492 #endif
    493 	/*
    494 	 * Find where we are and take care of PWD for the automounter...
    495 	 * All this code is so that we know where we are when we start up
    496 	 * on a different machine with pmake.
    497 	 */
    498 	curdir = cdpath;
    499 	if (getcwd(curdir, MAXPATHLEN) == NULL) {
    500 		(void)fprintf(stderr, "make: %s.\n", strerror(errno));
    501 		exit(2);
    502 	}
    503 
    504 	if (stat(curdir, &sa) == -1) {
    505 	    (void)fprintf(stderr, "make: %s: %s.\n",
    506 			  curdir, strerror(errno));
    507 	    exit(2);
    508 	}
    509 
    510 	if ((pwd = getenv("PWD")) != NULL) {
    511 	    if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
    512 		sa.st_dev == sb.st_dev)
    513 		(void) strcpy(curdir, pwd);
    514 	}
    515 
    516 	/*
    517 	 * Get the name of this type of MACHINE from utsname
    518 	 * so we can share an executable for similar machines.
    519 	 * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
    520 	 *
    521 	 * Note that both MACHINE and MACHINE_ARCH are decided at
    522 	 * run-time.
    523 	 */
    524 	if (!machine) {
    525 #ifndef MAKE_BOOTSTRAP
    526 	    struct utsname utsname;
    527 
    528 	    if (uname(&utsname) == -1) {
    529 		    perror("make: uname");
    530 		    exit(2);
    531 	    }
    532 	    machine = utsname.machine;
    533 #else
    534 	    machine = MACHINE;
    535 #endif
    536 	}
    537 
    538 	if (!machine_arch) {
    539 #ifndef MACHINE_ARCH
    540 #ifdef __ARCHITECTURE__
    541             machine_arch = __ARCHITECTURE__;
    542 #else
    543 	    machine_arch = "unknown";	/* XXX: no uname -p yet */
    544 #endif
    545 #else
    546 	    machine_arch = MACHINE_ARCH;
    547 #endif
    548 	}
    549 
    550 	/*
    551 	 * Just in case MAKEOBJDIR wants us to do something tricky.
    552 	 */
    553 	Var_Init();		/* Initialize the lists of variables for
    554 				 * parsing arguments */
    555 	Var_Set(".CURDIR", curdir, VAR_GLOBAL);
    556 	Var_Set("MACHINE", machine, VAR_GLOBAL);
    557 	Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL);
    558 
    559 	/*
    560 	 * If the MAKEOBJDIR (or by default, the _PATH_OBJDIR) directory
    561 	 * exists, change into it and build there.  (If a .${MACHINE} suffix
    562 	 * exists, use that directory instead).
    563 	 * Otherwise check MAKEOBJDIRPREFIX`cwd` (or by default,
    564 	 * _PATH_OBJDIRPREFIX`cwd`) and build there if it exists.
    565 	 * If all fails, use the current directory to build.
    566 	 *
    567 	 * Once things are initted,
    568 	 * have to add the original directory to the search path,
    569 	 * and modify the paths for the Makefiles apropriately.  The
    570 	 * current directory is also placed as a variable for make scripts.
    571 	 */
    572 	if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
    573 		if (!(path = getenv("MAKEOBJDIR"))) {
    574 			path = _PATH_OBJDIR;
    575 			pathp = _PATH_OBJDIRPREFIX;
    576 			(void) snprintf(mdpath, MAXPATHLEN, "%s.%s",
    577 					path, machine);
    578 			if (!(objdir = chdir_verify_path(mdpath, obpath)))
    579 				if (!(objdir=chdir_verify_path(path, obpath))) {
    580 					(void) snprintf(mdpath, MAXPATHLEN,
    581 							"%s%s", pathp, curdir);
    582 					if (!(objdir=chdir_verify_path(mdpath,
    583 								       obpath)))
    584 						objdir = curdir;
    585 				}
    586 		}
    587 		else if (!(objdir = chdir_verify_path(path, obpath)))
    588 			objdir = curdir;
    589 	}
    590 	else {
    591 		(void) snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
    592 		if (!(objdir = chdir_verify_path(mdpath, obpath)))
    593 			objdir = curdir;
    594 	}
    595 
    596 	setenv("PWD", objdir, 1);
    597 
    598 	create = Lst_Init(FALSE);
    599 	makefiles = Lst_Init(FALSE);
    600 	printVars = FALSE;
    601 	variables = Lst_Init(FALSE);
    602 	beSilent = FALSE;		/* Print commands as executed */
    603 	ignoreErrors = FALSE;		/* Pay attention to non-zero returns */
    604 	noExecute = FALSE;		/* Execute all commands */
    605 	keepgoing = FALSE;		/* Stop on error */
    606 	allPrecious = FALSE;		/* Remove targets when interrupted */
    607 	queryFlag = FALSE;		/* This is not just a check-run */
    608 	noBuiltins = FALSE;		/* Read the built-in rules */
    609 	touchFlag = FALSE;		/* Actually update targets */
    610 	usePipes = TRUE;		/* Catch child output in pipes */
    611 	debug = 0;			/* No debug verbosity, please. */
    612 	jobsRunning = FALSE;
    613 
    614 	maxLocal = DEFMAXLOCAL;		/* Set default local max concurrency */
    615 #ifdef REMOTE
    616 	maxJobs = DEFMAXJOBS;		/* Set default max concurrency */
    617 #else
    618 	maxJobs = maxLocal;
    619 #endif
    620 	compatMake = FALSE;		/* No compat mode */
    621 
    622 
    623 	/*
    624 	 * Initialize the parsing, directory and variable modules to prepare
    625 	 * for the reading of inclusion paths and variable settings on the
    626 	 * command line
    627 	 */
    628 
    629 	/*
    630 	 * Initialize directory structures so -I flags can be processed
    631 	 * correctly, if we have a different objdir, then let the directory
    632 	 * know our curdir.
    633 	 */
    634 	Dir_Init(curdir != objdir ? curdir : NULL);
    635 	Parse_Init();		/* Need to initialize the paths of #include
    636 				 * directories */
    637 	Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
    638 
    639 	/*
    640 	 * Initialize various variables.
    641 	 *	MAKE also gets this name, for compatibility
    642 	 *	.MAKEFLAGS gets set to the empty string just in case.
    643 	 *	MFLAGS also gets initialized empty, for compatibility.
    644 	 */
    645 	Var_Set("MAKE", argv[0], VAR_GLOBAL);
    646 	Var_Set(".MAKE", argv[0], VAR_GLOBAL);
    647 	Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
    648 	Var_Set("MFLAGS", "", VAR_GLOBAL);
    649 
    650 	/*
    651 	 * First snag any flags out of the MAKE environment variable.
    652 	 * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
    653 	 * in a different format).
    654 	 */
    655 #ifdef POSIX
    656 	Main_ParseArgLine(getenv("MAKEFLAGS"));
    657 #else
    658 	Main_ParseArgLine(getenv("MAKE"));
    659 #endif
    660 
    661 	MainParseArgs(argc, argv);
    662 
    663 	/*
    664 	 * Initialize archive, target and suffix modules in preparation for
    665 	 * parsing the makefile(s)
    666 	 */
    667 	Arch_Init();
    668 	Targ_Init();
    669 	Suff_Init();
    670 
    671 	DEFAULT = NILGNODE;
    672 	(void)time(&now);
    673 
    674 	/*
    675 	 * Set up the .TARGETS variable to contain the list of targets to be
    676 	 * created. If none specified, make the variable empty -- the parser
    677 	 * will fill the thing in with the default or .MAIN target.
    678 	 */
    679 	if (!Lst_IsEmpty(create)) {
    680 		LstNode ln;
    681 
    682 		for (ln = Lst_First(create); ln != NILLNODE;
    683 		    ln = Lst_Succ(ln)) {
    684 			char *name = (char *)Lst_Datum(ln);
    685 
    686 			Var_Append(".TARGETS", name, VAR_GLOBAL);
    687 		}
    688 	} else
    689 		Var_Set(".TARGETS", "", VAR_GLOBAL);
    690 
    691 
    692 	/*
    693 	 * If no user-supplied system path was given (through the -m option)
    694 	 * add the directories from the DEFSYSPATH (more than one may be given
    695 	 * as dir1:...:dirn) to the system include path.
    696 	 */
    697 	if (!mkIncPath) {
    698 		for (start = syspath; *start != '\0'; start = cp) {
    699 			for (cp = start; *cp != '\0' && *cp != ':'; cp++)
    700 				continue;
    701 			if (*cp == '\0') {
    702 				(void) Dir_AddDir(sysIncPath, start);
    703 			} else {
    704 				*cp++ = '\0';
    705 				(void) Dir_AddDir(sysIncPath, start);
    706 			}
    707 		}
    708 	}
    709 
    710 	/*
    711 	 * Read in the built-in rules first, followed by the specified
    712 	 * makefile, if it was (makefile != (char *) NULL), or the default
    713 	 * Makefile and makefile, in that order, if it wasn't.
    714 	 */
    715 	if (!noBuiltins) {
    716 		LstNode ln;
    717 
    718 		sysMkPath = Lst_Init (FALSE);
    719 		Dir_Expand (_PATH_DEFSYSMK, sysIncPath, sysMkPath);
    720 		if (Lst_IsEmpty(sysMkPath))
    721 			Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
    722 		ln = Lst_Find(sysMkPath, (ClientData)NULL, ReadMakefile);
    723 		if (ln != NILLNODE)
    724 			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
    725 	}
    726 
    727 	if (!Lst_IsEmpty(makefiles)) {
    728 		LstNode ln;
    729 
    730 		ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile);
    731 		if (ln != NILLNODE)
    732 			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
    733 	} else if (!ReadMakefile("makefile", NULL))
    734 		(void)ReadMakefile("Makefile", NULL);
    735 
    736 	(void)ReadMakefile(".depend", NULL);
    737 
    738 	Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
    739 	if (p1)
    740 	    free(p1);
    741 
    742 	/* Install all the flags into the MAKE envariable. */
    743 	if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1)) != NULL) && *p)
    744 #ifdef POSIX
    745 		setenv("MAKEFLAGS", p, 1);
    746 #else
    747 		setenv("MAKE", p, 1);
    748 #endif
    749 	if (p1)
    750 	    free(p1);
    751 
    752 	/*
    753 	 * For compatibility, look at the directories in the VPATH variable
    754 	 * and add them to the search path, if the variable is defined. The
    755 	 * variable's value is in the same format as the PATH envariable, i.e.
    756 	 * <directory>:<directory>:<directory>...
    757 	 */
    758 	if (Var_Exists("VPATH", VAR_CMD)) {
    759 		char *vpath, *path, *cp, savec;
    760 		/*
    761 		 * GCC stores string constants in read-only memory, but
    762 		 * Var_Subst will want to write this thing, so store it
    763 		 * in an array
    764 		 */
    765 		static char VPATH[] = "${VPATH}";
    766 
    767 		vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
    768 		path = vpath;
    769 		do {
    770 			/* skip to end of directory */
    771 			for (cp = path; *cp != ':' && *cp != '\0'; cp++)
    772 				continue;
    773 			/* Save terminator character so know when to stop */
    774 			savec = *cp;
    775 			*cp = '\0';
    776 			/* Add directory to search path */
    777 			(void) Dir_AddDir(dirSearchPath, path);
    778 			*cp = savec;
    779 			path = cp + 1;
    780 		} while (savec == ':');
    781 		(void)free((Address)vpath);
    782 	}
    783 
    784 	/*
    785 	 * Now that all search paths have been read for suffixes et al, it's
    786 	 * time to add the default search path to their lists...
    787 	 */
    788 	Suff_DoPaths();
    789 
    790 	/*
    791 	 * Propagate attributes through :: dependency lists.
    792 	 */
    793 	Targ_Propagate();
    794 
    795 	/* print the initial graph, if the user requested it */
    796 	if (DEBUG(GRAPH1))
    797 		Targ_PrintGraph(1);
    798 
    799 	/* print the values of any variables requested by the user */
    800 	if (printVars) {
    801 		LstNode ln;
    802 
    803 		for (ln = Lst_First(variables); ln != NILLNODE;
    804 		    ln = Lst_Succ(ln)) {
    805 			char *value = Var_Value((char *)Lst_Datum(ln),
    806 					  VAR_GLOBAL, &p1);
    807 
    808 			printf("%s\n", value ? value : "");
    809 			if (p1)
    810 				free(p1);
    811 		}
    812 	}
    813 
    814 	/*
    815 	 * Have now read the entire graph and need to make a list of targets
    816 	 * to create. If none was given on the command line, we consult the
    817 	 * parsing module to find the main target(s) to create.
    818 	 */
    819 	if (Lst_IsEmpty(create))
    820 		targs = Parse_MainName();
    821 	else
    822 		targs = Targ_FindList(create, TARG_CREATE);
    823 
    824 	if (!compatMake && !printVars) {
    825 		/*
    826 		 * Initialize job module before traversing the graph, now that
    827 		 * any .BEGIN and .END targets have been read.  This is done
    828 		 * only if the -q flag wasn't given (to prevent the .BEGIN from
    829 		 * being executed should it exist).
    830 		 */
    831 		if (!queryFlag) {
    832 			if (maxLocal == -1)
    833 				maxLocal = maxJobs;
    834 			Job_Init(maxJobs, maxLocal);
    835 			jobsRunning = TRUE;
    836 		}
    837 
    838 		/* Traverse the graph, checking on all the targets */
    839 		outOfDate = Make_Run(targs);
    840 	} else if (!printVars) {
    841 		/*
    842 		 * Compat_Init will take care of creating all the targets as
    843 		 * well as initializing the module.
    844 		 */
    845 		Compat_Run(targs);
    846 	}
    847 
    848 #ifdef CLEANUP
    849 	Lst_Destroy(targs, NOFREE);
    850 	Lst_Destroy(variables, NOFREE);
    851 	Lst_Destroy(makefiles, NOFREE);
    852 	Lst_Destroy(create, (void (*) __P((ClientData))) free);
    853 #endif
    854 
    855 	/* print the graph now it's been processed if the user requested it */
    856 	if (DEBUG(GRAPH2))
    857 		Targ_PrintGraph(2);
    858 
    859 	Suff_End();
    860         Targ_End();
    861 	Arch_End();
    862 	Var_End();
    863 	Parse_End();
    864 	Dir_End();
    865 	Job_End();
    866 
    867 	if (queryFlag && outOfDate)
    868 		return(1);
    869 	else
    870 		return(0);
    871 }
    872 
    873 /*-
    874  * ReadMakefile  --
    875  *	Open and parse the given makefile.
    876  *
    877  * Results:
    878  *	TRUE if ok. FALSE if couldn't open file.
    879  *
    880  * Side Effects:
    881  *	lots
    882  */
    883 static Boolean
    884 ReadMakefile(p, q)
    885 	ClientData p, q;
    886 {
    887 	char *fname = p;		/* makefile to read */
    888 	extern Lst parseIncPath;
    889 	FILE *stream;
    890 	size_t len = MAXPATHLEN;
    891 	char *name, *path = emalloc(len);
    892 
    893 	if (!strcmp(fname, "-")) {
    894 		Parse_File("(stdin)", stdin);
    895 		Var_Set("MAKEFILE", "", VAR_GLOBAL);
    896 	} else {
    897 		if ((stream = fopen(fname, "r")) != NULL)
    898 			goto found;
    899 		/* if we've chdir'd, rebuild the path name */
    900 		if (curdir != objdir && *fname != '/') {
    901 			size_t plen = strlen(curdir) + strlen(fname) + 2;
    902 			if (len < plen)
    903 				path = erealloc(path, len = 2 * plen);
    904 
    905 			(void)snprintf(path, len, "%s/%s", curdir, fname);
    906 			if ((stream = fopen(path, "r")) != NULL) {
    907 				fname = path;
    908 				goto found;
    909 			}
    910 		}
    911 		/* look in -I and system include directories. */
    912 		name = Dir_FindFile(fname, parseIncPath);
    913 		if (!name)
    914 			name = Dir_FindFile(fname, sysIncPath);
    915 		if (!name || !(stream = fopen(name, "r"))) {
    916 			free(path);
    917 			return(FALSE);
    918 		}
    919 		fname = name;
    920 		/*
    921 		 * set the MAKEFILE variable desired by System V fans -- the
    922 		 * placement of the setting here means it gets set to the last
    923 		 * makefile specified, as it is set by SysV make.
    924 		 */
    925 found:		Var_Set("MAKEFILE", fname, VAR_GLOBAL);
    926 		Parse_File(fname, stream);
    927 		(void)fclose(stream);
    928 	}
    929 	free(path);
    930 	return(TRUE);
    931 }
    932 
    933 /*-
    934  * Cmd_Exec --
    935  *	Execute the command in cmd, and return the output of that command
    936  *	in a string.
    937  *
    938  * Results:
    939  *	A string containing the output of the command, or the empty string
    940  *	If err is not NULL, it contains the reason for the command failure
    941  *
    942  * Side Effects:
    943  *	The string must be freed by the caller.
    944  */
    945 char *
    946 Cmd_Exec(cmd, err)
    947     char *cmd;
    948     char **err;
    949 {
    950     char	*args[4];   	/* Args for invoking the shell */
    951     int 	fds[2];	    	/* Pipe streams */
    952     int 	cpid;	    	/* Child PID */
    953     int 	pid;	    	/* PID from wait() */
    954     char	*res;		/* result */
    955     int		status;		/* command exit status */
    956     Buffer	buf;		/* buffer to store the result */
    957     char	*cp;
    958     int		cc;
    959 
    960 
    961     *err = NULL;
    962 
    963     /*
    964      * Set up arguments for shell
    965      */
    966     args[0] = "sh";
    967     args[1] = "-c";
    968     args[2] = cmd;
    969     args[3] = NULL;
    970 
    971     /*
    972      * Open a pipe for fetching its output
    973      */
    974     if (pipe(fds) == -1) {
    975 	*err = "Couldn't create pipe for \"%s\"";
    976 	goto bad;
    977     }
    978 
    979     /*
    980      * Fork
    981      */
    982     switch (cpid = vfork()) {
    983     case 0:
    984 	/*
    985 	 * Close input side of pipe
    986 	 */
    987 	(void) close(fds[0]);
    988 
    989 	/*
    990 	 * Duplicate the output stream to the shell's output, then
    991 	 * shut the extra thing down. Note we don't fetch the error
    992 	 * stream...why not? Why?
    993 	 */
    994 	(void) dup2(fds[1], 1);
    995 	(void) close(fds[1]);
    996 
    997 	(void) execv("/bin/sh", args);
    998 	_exit(1);
    999 	/*NOTREACHED*/
   1000 
   1001     case -1:
   1002 	*err = "Couldn't exec \"%s\"";
   1003 	goto bad;
   1004 
   1005     default:
   1006 	/*
   1007 	 * No need for the writing half
   1008 	 */
   1009 	(void) close(fds[1]);
   1010 
   1011 	buf = Buf_Init (MAKE_BSIZE);
   1012 
   1013 	do {
   1014 	    char   result[BUFSIZ];
   1015 	    cc = read(fds[0], result, sizeof(result));
   1016 	    if (cc > 0)
   1017 		Buf_AddBytes(buf, cc, (Byte *) result);
   1018 	}
   1019 	while (cc > 0 || (cc == -1 && errno == EINTR));
   1020 
   1021 	/*
   1022 	 * Close the input side of the pipe.
   1023 	 */
   1024 	(void) close(fds[0]);
   1025 
   1026 	/*
   1027 	 * Wait for the process to exit.
   1028 	 */
   1029 	while(((pid = wait(&status)) != cpid) && (pid >= 0))
   1030 	    continue;
   1031 
   1032 	res = (char *)Buf_GetAll (buf, &cc);
   1033 	Buf_Destroy (buf, FALSE);
   1034 
   1035 	if (cc == 0)
   1036 	    *err = "Couldn't read shell's output for \"%s\"";
   1037 
   1038 	if (status)
   1039 	    *err = "\"%s\" returned non-zero status";
   1040 
   1041 	/*
   1042 	 * Null-terminate the result, convert newlines to spaces and
   1043 	 * install it in the variable.
   1044 	 */
   1045 	res[cc] = '\0';
   1046 	cp = &res[cc];
   1047 
   1048 	if (cc > 0 && *--cp == '\n') {
   1049 	    /*
   1050 	     * A final newline is just stripped
   1051 	     */
   1052 	    *cp-- = '\0';
   1053 	}
   1054 	while (cp >= res) {
   1055 	    if (*cp == '\n') {
   1056 		*cp = ' ';
   1057 	    }
   1058 	    cp--;
   1059 	}
   1060 	break;
   1061     }
   1062     return res;
   1063 bad:
   1064     res = emalloc(1);
   1065     *res = '\0';
   1066     return res;
   1067 }
   1068 
   1069 /*-
   1070  * Error --
   1071  *	Print an error message given its format.
   1072  *
   1073  * Results:
   1074  *	None.
   1075  *
   1076  * Side Effects:
   1077  *	The message is printed.
   1078  */
   1079 /* VARARGS */
   1080 void
   1081 #ifdef __STDC__
   1082 Error(char *fmt, ...)
   1083 #else
   1084 Error(va_alist)
   1085 	va_dcl
   1086 #endif
   1087 {
   1088 	va_list ap;
   1089 #ifdef __STDC__
   1090 	va_start(ap, fmt);
   1091 #else
   1092 	char *fmt;
   1093 
   1094 	va_start(ap);
   1095 	fmt = va_arg(ap, char *);
   1096 #endif
   1097 	(void)vfprintf(stderr, fmt, ap);
   1098 	va_end(ap);
   1099 	(void)fprintf(stderr, "\n");
   1100 	(void)fflush(stderr);
   1101 }
   1102 
   1103 /*-
   1104  * Fatal --
   1105  *	Produce a Fatal error message. If jobs are running, waits for them
   1106  *	to finish.
   1107  *
   1108  * Results:
   1109  *	None
   1110  *
   1111  * Side Effects:
   1112  *	The program exits
   1113  */
   1114 /* VARARGS */
   1115 void
   1116 #ifdef __STDC__
   1117 Fatal(char *fmt, ...)
   1118 #else
   1119 Fatal(va_alist)
   1120 	va_dcl
   1121 #endif
   1122 {
   1123 	va_list ap;
   1124 #ifdef __STDC__
   1125 	va_start(ap, fmt);
   1126 #else
   1127 	char *fmt;
   1128 
   1129 	va_start(ap);
   1130 	fmt = va_arg(ap, char *);
   1131 #endif
   1132 	if (jobsRunning)
   1133 		Job_Wait();
   1134 
   1135 	(void)vfprintf(stderr, fmt, ap);
   1136 	va_end(ap);
   1137 	(void)fprintf(stderr, "\n");
   1138 	(void)fflush(stderr);
   1139 
   1140 	if (DEBUG(GRAPH2))
   1141 		Targ_PrintGraph(2);
   1142 	exit(2);		/* Not 1 so -q can distinguish error */
   1143 }
   1144 
   1145 /*
   1146  * Punt --
   1147  *	Major exception once jobs are being created. Kills all jobs, prints
   1148  *	a message and exits.
   1149  *
   1150  * Results:
   1151  *	None
   1152  *
   1153  * Side Effects:
   1154  *	All children are killed indiscriminately and the program Lib_Exits
   1155  */
   1156 /* VARARGS */
   1157 void
   1158 #ifdef __STDC__
   1159 Punt(char *fmt, ...)
   1160 #else
   1161 Punt(va_alist)
   1162 	va_dcl
   1163 #endif
   1164 {
   1165 	va_list ap;
   1166 #ifdef __STDC__
   1167 	va_start(ap, fmt);
   1168 #else
   1169 	char *fmt;
   1170 
   1171 	va_start(ap);
   1172 	fmt = va_arg(ap, char *);
   1173 #endif
   1174 
   1175 	(void)fprintf(stderr, "make: ");
   1176 	(void)vfprintf(stderr, fmt, ap);
   1177 	va_end(ap);
   1178 	(void)fprintf(stderr, "\n");
   1179 	(void)fflush(stderr);
   1180 
   1181 	DieHorribly();
   1182 }
   1183 
   1184 /*-
   1185  * DieHorribly --
   1186  *	Exit without giving a message.
   1187  *
   1188  * Results:
   1189  *	None
   1190  *
   1191  * Side Effects:
   1192  *	A big one...
   1193  */
   1194 void
   1195 DieHorribly()
   1196 {
   1197 	if (jobsRunning)
   1198 		Job_AbortAll();
   1199 	if (DEBUG(GRAPH2))
   1200 		Targ_PrintGraph(2);
   1201 	exit(2);		/* Not 1, so -q can distinguish error */
   1202 }
   1203 
   1204 /*
   1205  * Finish --
   1206  *	Called when aborting due to errors in child shell to signal
   1207  *	abnormal exit.
   1208  *
   1209  * Results:
   1210  *	None
   1211  *
   1212  * Side Effects:
   1213  *	The program exits
   1214  */
   1215 void
   1216 Finish(errors)
   1217 	int errors;	/* number of errors encountered in Make_Make */
   1218 {
   1219 	Fatal("%d error%s", errors, errors == 1 ? "" : "s");
   1220 }
   1221 
   1222 /*
   1223  * emalloc --
   1224  *	malloc, but die on error.
   1225  */
   1226 void *
   1227 emalloc(len)
   1228 	size_t len;
   1229 {
   1230 	void *p;
   1231 
   1232 	if ((p = malloc(len)) == NULL)
   1233 		enomem();
   1234 	return(p);
   1235 }
   1236 
   1237 /*
   1238  * estrdup --
   1239  *	strdup, but die on error.
   1240  */
   1241 char *
   1242 estrdup(str)
   1243 	const char *str;
   1244 {
   1245 	char *p;
   1246 
   1247 	if ((p = strdup(str)) == NULL)
   1248 		enomem();
   1249 	return(p);
   1250 }
   1251 
   1252 /*
   1253  * erealloc --
   1254  *	realloc, but die on error.
   1255  */
   1256 void *
   1257 erealloc(ptr, size)
   1258 	void *ptr;
   1259 	size_t size;
   1260 {
   1261 	if ((ptr = realloc(ptr, size)) == NULL)
   1262 		enomem();
   1263 	return(ptr);
   1264 }
   1265 
   1266 /*
   1267  * enomem --
   1268  *	die when out of memory.
   1269  */
   1270 void
   1271 enomem()
   1272 {
   1273 	(void)fprintf(stderr, "make: %s.\n", strerror(errno));
   1274 	exit(2);
   1275 }
   1276 
   1277 /*
   1278  * enunlink --
   1279  *	Remove a file carefully, avoiding directories.
   1280  */
   1281 int
   1282 eunlink(file)
   1283 	const char *file;
   1284 {
   1285 	struct stat st;
   1286 
   1287 	if (lstat(file, &st) == -1)
   1288 		return -1;
   1289 
   1290 	if (S_ISDIR(st.st_mode)) {
   1291 		errno = EISDIR;
   1292 		return -1;
   1293 	}
   1294 	return unlink(file);
   1295 }
   1296 
   1297 /*
   1298  * usage --
   1299  *	exit with usage message
   1300  */
   1301 static void
   1302 usage()
   1303 {
   1304 	(void)fprintf(stderr,
   1305 "usage: make [-Beiknqrst] [-D variable] [-d flags] [-f makefile ]\n\
   1306             [-I directory] [-j max_jobs] [-m directory] [-V variable]\n\
   1307             [variable=value] [target ...]\n");
   1308 	exit(2);
   1309 }
   1310 
   1311 
   1312 int
   1313 PrintAddr(a, b)
   1314     ClientData a;
   1315     ClientData b;
   1316 {
   1317     printf("%lx ", (unsigned long) a);
   1318     return b ? 0 : 0;
   1319 }
   1320