4.4BSD snapshot (revision 8.1); add 1993 to copyright
[unix-history] / usr / src / usr.bin / make / main.c
CommitLineData
9320ab9e 1/*
8db0b741
KB
2 * Copyright (c) 1988, 1989, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
9320ab9e
KB
4 * Copyright (c) 1989 by Berkeley Softworks
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor.
9 *
87198c0c 10 * %sccs.include.redist.c%
9320ab9e
KB
11 */
12
13#ifndef lint
8db0b741
KB
14static char copyright[] =
15"@(#) Copyright (c) 1988, 1989, 1990, 1993\n\
16 The Regents of the University of California. All rights reserved.\n";
9320ab9e
KB
17#endif /* not lint */
18
19#ifndef lint
8db0b741 20static char sccsid[] = "@(#)main.c 8.1 (Berkeley) %G%";
9320ab9e
KB
21#endif /* not lint */
22
ab950546
KB
23/*-
24 * main.c --
25 * The main file for this entire program. Exit routines etc
26 * reside here.
27 *
ab950546 28 * Utility functions defined in this file:
45250cd5
KB
29 * Main_ParseArgLine Takes a line of arguments, breaks them and
30 * treats them as if they were given when first
31 * invoked. Used by the parse module to implement
32 * the .MFLAGS target.
ab950546 33 *
45250cd5
KB
34 * Error Print a tagged error message. The global
35 * MAKE variable must have been defined. This
36 * takes a format string and two optional
37 * arguments for it.
ab950546 38 *
45250cd5
KB
39 * Fatal Print an error message and exit. Also takes
40 * a format string and two arguments.
ab950546 41 *
45250cd5
KB
42 * Punt Aborts all jobs and exits with a message. Also
43 * takes a format string and two arguments.
ab950546 44 *
45250cd5
KB
45 * Finish Finish things up by printing the number of
46 * errors which occured, as passed to it, and
47 * exiting.
ab950546 48 */
ab950546 49
40a80f0c
KB
50#include <sys/types.h>
51#include <sys/time.h>
83b53e32 52#include <sys/param.h>
40a80f0c 53#include <sys/resource.h>
45250cd5
KB
54#include <sys/signal.h>
55#include <sys/stat.h>
98eb476c 56#include <errno.h>
45250cd5 57#include <fcntl.h>
45250cd5 58#include <stdio.h>
40a80f0c
KB
59#if __STDC__
60#include <stdarg.h>
61#else
b6cda174 62#include <varargs.h>
40a80f0c 63#endif
45250cd5 64#include "make.h"
40a80f0c
KB
65#include "hash.h"
66#include "dir.h"
67#include "job.h"
05a7e5b6 68#include "pathnames.h"
ab950546 69
45250cd5
KB
70#ifndef DEFMAXLOCAL
71#define DEFMAXLOCAL DEFMAXJOBS
72#endif DEFMAXLOCAL
ab950546 73
45250cd5 74#define MAKEFLAGS ".MAKEFLAGS"
ab950546 75
45250cd5
KB
76Lst create; /* Targets to be made */
77time_t now; /* Time at start of make */
78GNode *DEFAULT; /* .DEFAULT node */
79Boolean allPrecious; /* .PRECIOUS given on line by itself */
ab950546 80
45250cd5 81static Boolean noBuiltins; /* -r flag */
6c4ac3f1 82static Lst makefiles; /* ordered list of makefiles to read */
45250cd5
KB
83int maxJobs; /* -J argument */
84static int maxLocal; /* -L argument */
40a80f0c 85Boolean compatMake; /* -B argument */
45250cd5 86Boolean debug; /* -d flag */
45250cd5
KB
87Boolean noExecute; /* -n flag */
88Boolean keepgoing; /* -k flag */
89Boolean queryFlag; /* -q flag */
90Boolean touchFlag; /* -t flag */
91Boolean usePipes; /* !-P flag */
ab950546 92Boolean ignoreErrors; /* -i flag */
45250cd5 93Boolean beSilent; /* -s flag */
45250cd5
KB
94Boolean oldVars; /* variable substitution style */
95Boolean checkEnvFirst; /* -e flag */
96static Boolean jobsRunning; /* TRUE if the jobs might be running */
ab950546 97
45250cd5 98static Boolean ReadMakefile();
40a80f0c 99static void usage();
ab950546 100
05a7e5b6
KB
101static char *curdir; /* if chdir'd for an architecture */
102
ab950546 103/*-
ab950546
KB
104 * MainParseArgs --
105 * Parse a given argument vector. Called from main() and from
106 * Main_ParseArgLine() when the .MAKEFLAGS target is used.
107 *
108 * XXX: Deal with command line overriding .MAKEFLAGS in makefile
109 *
110 * Results:
111 * None
112 *
113 * Side Effects:
114 * Various global and local flags will be set depending on the flags
115 * given
ab950546
KB
116 */
117static void
45250cd5
KB
118MainParseArgs(argc, argv)
119 int argc;
120 char **argv;
ab950546 121{
45250cd5
KB
122 extern int optind;
123 extern char *optarg;
b3c4b5a7 124 int c;
45250cd5 125
f0fbb401 126 optind = 1; /* since we're called more than once */
40a80f0c
KB
127#ifdef notyet
128# define OPTFLAGS "BD:I:L:PSd:ef:ij:knqrst"
129#else
130# define OPTFLAGS "D:I:d:ef:ij:knqrst"
131#endif
b3c4b5a7 132rearg: while ((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
45250cd5 133 switch(c) {
45250cd5
KB
134 case 'D':
135 Var_Set(optarg, "1", VAR_GLOBAL);
136 Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
137 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
138 break;
139 case 'I':
140 Parse_AddIncludeDir(optarg);
141 Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
142 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
143 break;
40a80f0c
KB
144#ifdef notyet
145 case 'B':
146 compatMake = TRUE;
147 break;
45250cd5
KB
148 case 'L':
149 maxLocal = atoi(optarg);
150 Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
151 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
152 break;
45250cd5
KB
153 case 'P':
154 usePipes = FALSE;
155 Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
156 break;
157 case 'S':
158 keepgoing = FALSE;
159 Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
160 break;
5f618604 161#endif
45250cd5
KB
162 case 'd': {
163 char *modules = optarg;
164
5f618604 165 for (; *modules; ++modules)
45250cd5 166 switch (*modules) {
5f618604 167 case 'A':
45250cd5
KB
168 debug = ~0;
169 break;
170 case 'a':
171 debug |= DEBUG_ARCH;
172 break;
173 case 'c':
174 debug |= DEBUG_COND;
175 break;
176 case 'd':
177 debug |= DEBUG_DIR;
178 break;
40a80f0c
KB
179 case 'f':
180 debug |= DEBUG_FOR;
181 break;
5f618604
KB
182 case 'g':
183 if (modules[1] == '1') {
184 debug |= DEBUG_GRAPH1;
185 ++modules;
186 }
187 else if (modules[1] == '2') {
188 debug |= DEBUG_GRAPH2;
189 ++modules;
190 }
191 break;
45250cd5
KB
192 case 'j':
193 debug |= DEBUG_JOB;
194 break;
195 case 'm':
196 debug |= DEBUG_MAKE;
197 break;
45250cd5
KB
198 case 's':
199 debug |= DEBUG_SUFF;
200 break;
201 case 't':
202 debug |= DEBUG_TARG;
203 break;
204 case 'v':
205 debug |= DEBUG_VAR;
206 break;
f01a5a44
KB
207 default:
208 (void)fprintf(stderr,
209 "make: illegal argument to d option -- %c\n",
210 *modules);
211 usage();
45250cd5 212 }
45250cd5
KB
213 Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
214 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
215 break;
216 }
217 case 'e':
218 checkEnvFirst = TRUE;
219 Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
220 break;
221 case 'f':
222 (void)Lst_AtEnd(makefiles, (ClientData)optarg);
223 break;
224 case 'i':
225 ignoreErrors = TRUE;
226 Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
227 break;
5f618604
KB
228 case 'j':
229 maxJobs = atoi(optarg);
230 Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
231 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
232 break;
45250cd5
KB
233 case 'k':
234 keepgoing = TRUE;
235 Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
236 break;
237 case 'n':
238 noExecute = TRUE;
239 Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
240 break;
45250cd5
KB
241 case 'q':
242 queryFlag = TRUE;
243 /* Kind of nonsensical, wot? */
244 Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
245 break;
246 case 'r':
247 noBuiltins = TRUE;
248 Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
249 break;
250 case 's':
251 beSilent = TRUE;
252 Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
253 break;
254 case 't':
255 touchFlag = TRUE;
256 Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
257 break;
b6cda174
KB
258 default:
259 case '?':
260 usage();
ab950546 261 }
ab950546 262 }
45250cd5 263
45250cd5
KB
264 oldVars = TRUE;
265
266 /*
267 * See if the rest of the arguments are variable assignments and
268 * perform them if so. Else take them to be targets and stuff them
269 * on the end of the "create" list.
270 */
fbd260e1 271 for (argv += optind, argc -= optind; *argv; ++argv, --argc)
b6cda174
KB
272 if (Parse_IsVar(*argv))
273 Parse_DoVar(*argv, VAR_CMD);
274 else {
947ddcac 275 if (!*argv[0] || *argv[0] == '-' && !(*argv)[1])
acf0797a 276 Punt("illegal (null) argument.");
fbd260e1
KB
277 if (**argv == '-') {
278 optind = 0;
279 goto rearg;
280 }
b6cda174 281 (void)Lst_AtEnd(create, (ClientData)*argv);
45250cd5 282 }
ab950546 283}
aa5839c2 284
ab950546 285/*-
ab950546
KB
286 * Main_ParseArgLine --
287 * Used by the parse module when a .MFLAGS or .MAKEFLAGS target
288 * is encountered and by main() when reading the .MAKEFLAGS envariable.
289 * Takes a line of arguments and breaks it into its
290 * component words and passes those words and the number of them to the
291 * MainParseArgs function.
292 * The line should have all its leading whitespace removed.
293 *
294 * Results:
295 * None
296 *
297 * Side Effects:
298 * Only those that come from the various arguments.
ab950546
KB
299 */
300void
45250cd5
KB
301Main_ParseArgLine(line)
302 char *line; /* Line to fracture */
ab950546 303{
45250cd5
KB
304 char **argv; /* Manufactured argument vector */
305 int argc; /* Number of arguments in argv */
ab950546 306
45250cd5
KB
307 if (line == NULL)
308 return;
40a80f0c
KB
309 for (; *line == ' '; ++line)
310 continue;
acf0797a
KB
311 if (!*line)
312 return;
ab950546 313
05a7e5b6 314 argv = brk_string(line, &argc);
45250cd5 315 MainParseArgs(argc, argv);
ab950546 316}
aa5839c2 317
ab950546 318/*-
ab950546
KB
319 * main --
320 * The main function, for obvious reasons. Initializes variables
321 * and a few modules, then parses the arguments give it in the
322 * environment and on the command line. Reads the system makefile
323 * followed by either Makefile, makefile or the file given by the
324 * -f argument. Sets the .MAKEFLAGS PMake variable based on all the
325 * flags it has received by then uses either the Make or the Compat
326 * module to create the initial list of targets.
327 *
328 * Results:
329 * If -q was given, exits -1 if anything was out-of-date. Else it exits
330 * 0.
331 *
332 * Side Effects:
333 * The program exits when done. Targets are created. etc. etc. etc.
ab950546 334 */
40a80f0c 335int
45250cd5
KB
336main(argc, argv)
337 int argc;
338 char **argv;
ab950546 339{
45250cd5 340 Lst targs; /* target nodes to create -- passed to Make_Init */
40a80f0c
KB
341 Boolean outOfDate = TRUE; /* FALSE if all targets up to date */
342 struct stat sb, sa;
343 char *p, *path, *pwd, *getenv();
344
345 /*
346 * Find where we are and take care of PWD for the automounter...
347 */
348 curdir = emalloc((u_int)MAXPATHLEN + 1);
349 if (!getwd(curdir)) {
350 (void)fprintf(stderr, "make: %s.\n", curdir);
351 exit(2);
352 }
353
354 if (stat(curdir, &sa) == -1) {
355 (void)fprintf(stderr, "make: %s: %s.\n",
356 curdir, strerror(errno));
357 exit(2);
358 }
359
360 if ((pwd = getenv("PWD")) != NULL) {
361 if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
362 sa.st_dev == sb.st_dev)
363 (void) strcpy(curdir, pwd);
364 }
365
05a7e5b6
KB
366
367 /*
368 * if the MAKEOBJDIR (or by default, the _PATH_OBJDIR) directory
369 * exists, change into it and build there. Once things are
370 * initted, have to add the original directory to the search path,
371 * and modify the paths for the Makefiles apropriately. The
372 * current directory is also placed as a variable for make scripts.
373 */
374 if (!(path = getenv("MAKEOBJDIR")))
375 path = _PATH_OBJDIR;
40a80f0c 376
8b4899ab
KB
377 if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode) &&
378 lstat(path, &sb) == 0) {
05a7e5b6 379 if (chdir(path)) {
05a7e5b6
KB
380 (void)fprintf(stderr, "make: %s: %s.\n",
381 path, strerror(errno));
382 exit(2);
383 }
40a80f0c
KB
384 if (path[0] != '/') {
385 char cwd[MAXPATHLEN];
386 (void) sprintf(cwd, "%s/%s", curdir, path);
387 setenv("PWD", cwd, 1);
388 }
389 else
390 setenv("PWD", path, 1);
05a7e5b6 391 }
40a80f0c
KB
392 else
393 setenv("PWD", curdir, 1);
45250cd5 394
6c4ac3f1 395 create = Lst_Init(FALSE);
45250cd5
KB
396 makefiles = Lst_Init(FALSE);
397 beSilent = FALSE; /* Print commands as executed */
398 ignoreErrors = FALSE; /* Pay attention to non-zero returns */
399 noExecute = FALSE; /* Execute all commands */
400 keepgoing = FALSE; /* Stop on error */
401 allPrecious = FALSE; /* Remove targets when interrupted */
402 queryFlag = FALSE; /* This is not just a check-run */
403 noBuiltins = FALSE; /* Read the built-in rules */
404 touchFlag = FALSE; /* Actually update targets */
405 usePipes = TRUE; /* Catch child output in pipes */
406 debug = 0; /* No debug verbosity, please. */
45250cd5
KB
407 jobsRunning = FALSE;
408
409 maxJobs = DEFMAXJOBS; /* Set default max concurrency */
410 maxLocal = DEFMAXLOCAL; /* Set default local max concurrency */
40a80f0c
KB
411#ifdef notyet
412 compatMake = FALSE; /* No compat mode */
413#else
414 compatMake = TRUE; /* No compat mode */
415#endif
ab950546 416
40a80f0c 417
45250cd5
KB
418 /*
419 * Initialize the parsing, directory and variable modules to prepare
420 * for the reading of inclusion paths and variable settings on the
421 * command line
422 */
423 Dir_Init(); /* Initialize directory structures so -I flags
ab950546 424 * can be processed correctly */
45250cd5 425 Parse_Init(); /* Need to initialize the paths of #include
ab950546 426 * directories */
45250cd5 427 Var_Init(); /* As well as the lists of variables for
ab950546 428 * parsing arguments */
05a7e5b6
KB
429 if (curdir) {
430 Dir_AddDir(dirSearchPath, curdir);
431 Var_Set(".CURDIR", curdir, VAR_GLOBAL);
40a80f0c
KB
432 }
433 Var_Set(".OBJDIR", path, VAR_GLOBAL);
05a7e5b6 434
45250cd5
KB
435 /*
436 * Initialize various variables.
45250cd5
KB
437 * MAKE also gets this name, for compatibility
438 * .MAKEFLAGS gets set to the empty string just in case.
439 * MFLAGS also gets initialized empty, for compatibility.
440 */
45250cd5
KB
441 Var_Set("MAKE", argv[0], VAR_GLOBAL);
442 Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
443 Var_Set("MFLAGS", "", VAR_GLOBAL);
05a7e5b6 444 Var_Set("MACHINE", MACHINE, VAR_GLOBAL);
45250cd5
KB
445
446 /*
82fe1445 447 * First snag any flags out of the MAKE environment variable.
45250cd5
KB
448 * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
449 * in a different format).
450 */
ab950546 451#ifdef POSIX
45250cd5 452 Main_ParseArgLine(getenv("MAKEFLAGS"));
ab950546 453#else
82fe1445 454 Main_ParseArgLine(getenv("MAKE"));
ab950546
KB
455#endif
456
45250cd5 457 MainParseArgs(argc, argv);
ab950546 458
45250cd5
KB
459 /*
460 * Initialize archive, target and suffix modules in preparation for
461 * parsing the makefile(s)
462 */
463 Arch_Init();
464 Targ_Init();
465 Suff_Init();
ab950546 466
45250cd5
KB
467 DEFAULT = NILGNODE;
468 (void)time(&now);
ab950546 469
45250cd5
KB
470 /*
471 * Set up the .TARGETS variable to contain the list of targets to be
472 * created. If none specified, make the variable empty -- the parser
473 * will fill the thing in with the default or .MAIN target.
474 */
475 if (!Lst_IsEmpty(create)) {
476 LstNode ln;
ab950546 477
45250cd5
KB
478 for (ln = Lst_First(create); ln != NILLNODE;
479 ln = Lst_Succ(ln)) {
480 char *name = (char *)Lst_Datum(ln);
ab950546 481
45250cd5
KB
482 Var_Append(".TARGETS", name, VAR_GLOBAL);
483 }
484 } else
485 Var_Set(".TARGETS", "", VAR_GLOBAL);
ab950546 486
45250cd5
KB
487 /*
488 * Read in the built-in rules first, followed by the specified makefile,
489 * if it was (makefile != (char *) NULL), or the default Makefile and
490 * makefile, in that order, if it wasn't.
491 */
05a7e5b6
KB
492 if (!noBuiltins && !ReadMakefile(_PATH_DEFSYSMK))
493 Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
45250cd5
KB
494
495 if (!Lst_IsEmpty(makefiles)) {
496 LstNode ln;
497
498 ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile);
499 if (ln != NILLNODE)
6c4ac3f1 500 Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
b6cda174
KB
501 } else if (!ReadMakefile("makefile"))
502 (void)ReadMakefile("Makefile");
ab950546 503
aae0c546
KB
504 (void)ReadMakefile(".depend");
505
6c4ac3f1 506 Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL), VAR_GLOBAL);
ab950546 507
82fe1445 508 /* Install all the flags into the MAKE envariable. */
40a80f0c 509 if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL)) != NULL) && *p)
ab950546 510#ifdef POSIX
acf0797a 511 setenv("MAKEFLAGS", p, 1);
ab950546 512#else
acf0797a 513 setenv("MAKE", p, 1);
ab950546
KB
514#endif
515
ab950546 516 /*
45250cd5
KB
517 * For compatibility, look at the directories in the VPATH variable
518 * and add them to the search path, if the variable is defined. The
519 * variable's value is in the same format as the PATH envariable, i.e.
520 * <directory>:<directory>:<directory>...
ab950546 521 */
6c4ac3f1 522 if (Var_Exists("VPATH", VAR_CMD)) {
45250cd5
KB
523 char *vpath, *path, *cp, savec;
524 /*
525 * GCC stores string constants in read-only memory, but
526 * Var_Subst will want to write this thing, so store it
527 * in an array
528 */
529 static char VPATH[] = "${VPATH}";
530
40a80f0c 531 vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
45250cd5
KB
532 path = vpath;
533 do {
534 /* skip to end of directory */
40a80f0c
KB
535 for (cp = path; *cp != ':' && *cp != '\0'; cp++)
536 continue;
45250cd5
KB
537 /* Save terminator character so know when to stop */
538 savec = *cp;
539 *cp = '\0';
540 /* Add directory to search path */
541 Dir_AddDir(dirSearchPath, path);
542 *cp = savec;
543 path = cp + 1;
544 } while (savec == ':');
545 (void)free((Address)vpath);
ab950546 546 }
45250cd5 547
ab950546 548 /*
45250cd5
KB
549 * Now that all search paths have been read for suffixes et al, it's
550 * time to add the default search path to their lists...
ab950546 551 */
45250cd5
KB
552 Suff_DoPaths();
553
5f618604
KB
554 /* print the initial graph, if the user requested it */
555 if (DEBUG(GRAPH1))
45250cd5
KB
556 Targ_PrintGraph(1);
557
ab950546 558 /*
45250cd5
KB
559 * Have now read the entire graph and need to make a list of targets
560 * to create. If none was given on the command line, we consult the
561 * parsing module to find the main target(s) to create.
ab950546 562 */
45250cd5
KB
563 if (Lst_IsEmpty(create))
564 targs = Parse_MainName();
565 else
6c4ac3f1 566 targs = Targ_FindList(create, TARG_CREATE);
45250cd5 567
b6cda174
KB
568/*
569 * this was original amMake -- want to allow parallelism, so put this
570 * back in, eventually.
571 */
40a80f0c 572 if (!compatMake) {
45250cd5
KB
573 /*
574 * Initialize job module before traversing the graph, now that
575 * any .BEGIN and .END targets have been read. This is done
576 * only if the -q flag wasn't given (to prevent the .BEGIN from
577 * being executed should it exist).
578 */
579 if (!queryFlag) {
580 if (maxLocal == -1)
581 maxLocal = maxJobs;
6c4ac3f1 582 Job_Init(maxJobs, maxLocal);
45250cd5
KB
583 jobsRunning = TRUE;
584 }
585
586 /* Traverse the graph, checking on all the targets */
587 outOfDate = Make_Run(targs);
588 } else
589 /*
590 * Compat_Init will take care of creating all the targets as
591 * well as initializing the module.
592 */
593 Compat_Run(targs);
ab950546 594
5f618604
KB
595 /* print the graph now it's been processed if the user requested it */
596 if (DEBUG(GRAPH2))
45250cd5
KB
597 Targ_PrintGraph(2);
598
599 if (queryFlag && outOfDate)
40a80f0c 600 return(1);
45250cd5 601 else
40a80f0c 602 return(0);
ab950546 603}
aa5839c2 604
ab950546 605/*-
ab950546
KB
606 * ReadMakefile --
607 * Open and parse the given makefile.
608 *
609 * Results:
610 * TRUE if ok. FALSE if couldn't open file.
611 *
612 * Side Effects:
613 * lots
ab950546
KB
614 */
615static Boolean
45250cd5
KB
616ReadMakefile(fname)
617 char *fname; /* makefile to read */
ab950546 618{
05a7e5b6
KB
619 extern Lst parseIncPath, sysIncPath;
620 FILE *stream;
621 char *name, path[MAXPATHLEN + 1];
622
6c4ac3f1 623 if (!strcmp(fname, "-")) {
45250cd5
KB
624 Parse_File("(stdin)", stdin);
625 Var_Set("MAKEFILE", "", VAR_GLOBAL);
626 } else {
40a80f0c 627 if ((stream = fopen(fname, "r")) != NULL)
aae0c546 628 goto found;
05a7e5b6
KB
629 /* if we've chdir'd, rebuild the path name */
630 if (curdir && *fname != '/') {
631 (void)sprintf(path, "%s/%s", curdir, fname);
40a80f0c 632 if ((stream = fopen(path, "r")) != NULL) {
aae0c546
KB
633 fname = path;
634 goto found;
635 }
45250cd5 636 }
aae0c546
KB
637 /* look in -I and system include directories. */
638 name = Dir_FindFile(fname, parseIncPath);
639 if (!name)
640 name = Dir_FindFile(fname, sysIncPath);
641 if (!name || !(stream = fopen(name, "r")))
642 return(FALSE);
643 fname = name;
ab950546 644 /*
05a7e5b6
KB
645 * set the MAKEFILE variable desired by System V fans -- the
646 * placement of the setting here means it gets set to the last
647 * makefile specified, as it is set by SysV make.
ab950546 648 */
aae0c546 649found: Var_Set("MAKEFILE", fname, VAR_GLOBAL);
45250cd5
KB
650 Parse_File(fname, stream);
651 (void)fclose(stream);
ab950546 652 }
45250cd5 653 return(TRUE);
ab950546 654}
aa5839c2 655
ab950546 656/*-
ab950546 657 * Error --
b6cda174 658 * Print an error message given its format.
ab950546
KB
659 *
660 * Results:
661 * None.
662 *
663 * Side Effects:
664 * The message is printed.
ab950546 665 */
b6cda174 666/* VARARGS */
ab950546 667void
40a80f0c
KB
668#if __STDC__
669Error(const char *fmt, ...)
670#else
671Error(fmt, va_alist)
672 char *fmt;
b6cda174 673 va_dcl
40a80f0c 674#endif
ab950546 675{
b6cda174 676 va_list ap;
40a80f0c
KB
677#if __STDC__
678 va_start(ap, fmt);
679#else
b6cda174 680 va_start(ap);
40a80f0c 681#endif
b6cda174
KB
682 (void)vfprintf(stderr, fmt, ap);
683 va_end(ap);
684 (void)fprintf(stderr, "\n");
45250cd5 685 (void)fflush(stderr);
ab950546 686}
aa5839c2 687
ab950546 688/*-
ab950546
KB
689 * Fatal --
690 * Produce a Fatal error message. If jobs are running, waits for them
691 * to finish.
692 *
693 * Results:
694 * None
695 *
696 * Side Effects:
697 * The program exits
ab950546 698 */
b6cda174 699/* VARARGS */
ab950546 700void
40a80f0c
KB
701#if __STDC__
702Fatal(const char *fmt, ...)
703#else
704Fatal(fmt, va_alist)
705 char *fmt;
b6cda174 706 va_dcl
40a80f0c 707#endif
ab950546 708{
6c4ac3f1 709 va_list ap;
40a80f0c
KB
710#if __STDC__
711 va_start(ap, fmt);
712#else
713 va_start(ap);
714#endif
45250cd5
KB
715 if (jobsRunning)
716 Job_Wait();
6c4ac3f1 717
6c4ac3f1
KB
718 (void)vfprintf(stderr, fmt, ap);
719 va_end(ap);
720 (void)fprintf(stderr, "\n");
721 (void)fflush(stderr);
ab950546 722
5f618604 723 if (DEBUG(GRAPH2))
45250cd5
KB
724 Targ_PrintGraph(2);
725 exit(2); /* Not 1 so -q can distinguish error */
ab950546 726}
aa5839c2 727
ab950546 728/*
ab950546
KB
729 * Punt --
730 * Major exception once jobs are being created. Kills all jobs, prints
731 * a message and exits.
732 *
733 * Results:
734 * None
735 *
736 * Side Effects:
737 * All children are killed indiscriminately and the program Lib_Exits
ab950546 738 */
b6cda174 739/* VARARGS */
ab950546 740void
40a80f0c
KB
741#if __STDC__
742Punt(const char *fmt, ...)
743#else
744Punt(fmt, va_alist)
745 char *fmt;
b6cda174 746 va_dcl
40a80f0c 747#endif
ab950546 748{
6c4ac3f1 749 va_list ap;
40a80f0c
KB
750#if __STDC__
751 va_start(ap, fmt);
752#else
6c4ac3f1 753 va_start(ap);
40a80f0c
KB
754#endif
755 (void)fprintf(stderr, "make: ");
6c4ac3f1
KB
756 (void)vfprintf(stderr, fmt, ap);
757 va_end(ap);
758 (void)fprintf(stderr, "\n");
759 (void)fflush(stderr);
760
45250cd5 761 DieHorribly();
ab950546 762}
aa5839c2 763
ab950546 764/*-
ab950546
KB
765 * DieHorribly --
766 * Exit without giving a message.
767 *
768 * Results:
769 * None
770 *
771 * Side Effects:
772 * A big one...
ab950546
KB
773 */
774void
775DieHorribly()
776{
45250cd5
KB
777 if (jobsRunning)
778 Job_AbortAll();
5f618604 779 if (DEBUG(GRAPH2))
45250cd5
KB
780 Targ_PrintGraph(2);
781 exit(2); /* Not 1, so -q can distinguish error */
ab950546 782}
aa5839c2 783
ab950546 784/*
ab950546
KB
785 * Finish --
786 * Called when aborting due to errors in child shell to signal
787 * abnormal exit.
788 *
789 * Results:
790 * None
791 *
792 * Side Effects:
793 * The program exits
ab950546
KB
794 */
795void
45250cd5
KB
796Finish(errors)
797 int errors; /* number of errors encountered in Make_Make */
ab950546 798{
45250cd5 799 Fatal("%d error%s", errors, errors == 1 ? "" : "s");
ab950546 800}
b6cda174 801
05a7e5b6
KB
802/*
803 * emalloc --
804 * malloc, but die on error.
805 */
806char *
807emalloc(len)
808 u_int len;
809{
40a80f0c 810 char *p;
05a7e5b6
KB
811
812 if (!(p = malloc(len)))
813 enomem();
814 return(p);
815}
816
817/*
818 * enomem --
819 * die when out of memory.
820 */
40a80f0c 821void
05a7e5b6
KB
822enomem()
823{
824 (void)fprintf(stderr, "make: %s.\n", strerror(errno));
825 exit(2);
826}
827
828/*
829 * usage --
830 * exit with usage message
831 */
40a80f0c 832static void
b6cda174
KB
833usage()
834{
835 (void)fprintf(stderr,
f01a5a44
KB
836"usage: make [-eiknqrst] [-D variable] [-d flags] [-f makefile ]\n\
837 [-I directory] [-j max_jobs] [variable=value]\n");
b6cda174
KB
838 exit(2);
839}