In case $MAKEOBJDIR is not a directory or we cannot stat it, then we
[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
a6c99206 20static char sccsid[] = "@(#)main.c 8.2 (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 }
a6c99206 392 else {
40a80f0c 393 setenv("PWD", curdir, 1);
a6c99206
KB
394 path = ".";
395 }
45250cd5 396
6c4ac3f1 397 create = Lst_Init(FALSE);
45250cd5
KB
398 makefiles = Lst_Init(FALSE);
399 beSilent = FALSE; /* Print commands as executed */
400 ignoreErrors = FALSE; /* Pay attention to non-zero returns */
401 noExecute = FALSE; /* Execute all commands */
402 keepgoing = FALSE; /* Stop on error */
403 allPrecious = FALSE; /* Remove targets when interrupted */
404 queryFlag = FALSE; /* This is not just a check-run */
405 noBuiltins = FALSE; /* Read the built-in rules */
406 touchFlag = FALSE; /* Actually update targets */
407 usePipes = TRUE; /* Catch child output in pipes */
408 debug = 0; /* No debug verbosity, please. */
45250cd5
KB
409 jobsRunning = FALSE;
410
411 maxJobs = DEFMAXJOBS; /* Set default max concurrency */
412 maxLocal = DEFMAXLOCAL; /* Set default local max concurrency */
40a80f0c
KB
413#ifdef notyet
414 compatMake = FALSE; /* No compat mode */
415#else
416 compatMake = TRUE; /* No compat mode */
417#endif
ab950546 418
40a80f0c 419
45250cd5
KB
420 /*
421 * Initialize the parsing, directory and variable modules to prepare
422 * for the reading of inclusion paths and variable settings on the
423 * command line
424 */
425 Dir_Init(); /* Initialize directory structures so -I flags
ab950546 426 * can be processed correctly */
45250cd5 427 Parse_Init(); /* Need to initialize the paths of #include
ab950546 428 * directories */
45250cd5 429 Var_Init(); /* As well as the lists of variables for
ab950546 430 * parsing arguments */
05a7e5b6
KB
431 if (curdir) {
432 Dir_AddDir(dirSearchPath, curdir);
433 Var_Set(".CURDIR", curdir, VAR_GLOBAL);
40a80f0c
KB
434 }
435 Var_Set(".OBJDIR", path, VAR_GLOBAL);
05a7e5b6 436
45250cd5
KB
437 /*
438 * Initialize various variables.
45250cd5
KB
439 * MAKE also gets this name, for compatibility
440 * .MAKEFLAGS gets set to the empty string just in case.
441 * MFLAGS also gets initialized empty, for compatibility.
442 */
45250cd5
KB
443 Var_Set("MAKE", argv[0], VAR_GLOBAL);
444 Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
445 Var_Set("MFLAGS", "", VAR_GLOBAL);
05a7e5b6 446 Var_Set("MACHINE", MACHINE, VAR_GLOBAL);
45250cd5
KB
447
448 /*
82fe1445 449 * First snag any flags out of the MAKE environment variable.
45250cd5
KB
450 * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
451 * in a different format).
452 */
ab950546 453#ifdef POSIX
45250cd5 454 Main_ParseArgLine(getenv("MAKEFLAGS"));
ab950546 455#else
82fe1445 456 Main_ParseArgLine(getenv("MAKE"));
ab950546
KB
457#endif
458
45250cd5 459 MainParseArgs(argc, argv);
ab950546 460
45250cd5
KB
461 /*
462 * Initialize archive, target and suffix modules in preparation for
463 * parsing the makefile(s)
464 */
465 Arch_Init();
466 Targ_Init();
467 Suff_Init();
ab950546 468
45250cd5
KB
469 DEFAULT = NILGNODE;
470 (void)time(&now);
ab950546 471
45250cd5
KB
472 /*
473 * Set up the .TARGETS variable to contain the list of targets to be
474 * created. If none specified, make the variable empty -- the parser
475 * will fill the thing in with the default or .MAIN target.
476 */
477 if (!Lst_IsEmpty(create)) {
478 LstNode ln;
ab950546 479
45250cd5
KB
480 for (ln = Lst_First(create); ln != NILLNODE;
481 ln = Lst_Succ(ln)) {
482 char *name = (char *)Lst_Datum(ln);
ab950546 483
45250cd5
KB
484 Var_Append(".TARGETS", name, VAR_GLOBAL);
485 }
486 } else
487 Var_Set(".TARGETS", "", VAR_GLOBAL);
ab950546 488
45250cd5
KB
489 /*
490 * Read in the built-in rules first, followed by the specified makefile,
491 * if it was (makefile != (char *) NULL), or the default Makefile and
492 * makefile, in that order, if it wasn't.
493 */
05a7e5b6
KB
494 if (!noBuiltins && !ReadMakefile(_PATH_DEFSYSMK))
495 Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
45250cd5
KB
496
497 if (!Lst_IsEmpty(makefiles)) {
498 LstNode ln;
499
500 ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile);
501 if (ln != NILLNODE)
6c4ac3f1 502 Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
b6cda174
KB
503 } else if (!ReadMakefile("makefile"))
504 (void)ReadMakefile("Makefile");
ab950546 505
aae0c546
KB
506 (void)ReadMakefile(".depend");
507
6c4ac3f1 508 Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL), VAR_GLOBAL);
ab950546 509
82fe1445 510 /* Install all the flags into the MAKE envariable. */
40a80f0c 511 if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL)) != NULL) && *p)
ab950546 512#ifdef POSIX
acf0797a 513 setenv("MAKEFLAGS", p, 1);
ab950546 514#else
acf0797a 515 setenv("MAKE", p, 1);
ab950546
KB
516#endif
517
ab950546 518 /*
45250cd5
KB
519 * For compatibility, look at the directories in the VPATH variable
520 * and add them to the search path, if the variable is defined. The
521 * variable's value is in the same format as the PATH envariable, i.e.
522 * <directory>:<directory>:<directory>...
ab950546 523 */
6c4ac3f1 524 if (Var_Exists("VPATH", VAR_CMD)) {
45250cd5
KB
525 char *vpath, *path, *cp, savec;
526 /*
527 * GCC stores string constants in read-only memory, but
528 * Var_Subst will want to write this thing, so store it
529 * in an array
530 */
531 static char VPATH[] = "${VPATH}";
532
40a80f0c 533 vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
45250cd5
KB
534 path = vpath;
535 do {
536 /* skip to end of directory */
40a80f0c
KB
537 for (cp = path; *cp != ':' && *cp != '\0'; cp++)
538 continue;
45250cd5
KB
539 /* Save terminator character so know when to stop */
540 savec = *cp;
541 *cp = '\0';
542 /* Add directory to search path */
543 Dir_AddDir(dirSearchPath, path);
544 *cp = savec;
545 path = cp + 1;
546 } while (savec == ':');
547 (void)free((Address)vpath);
ab950546 548 }
45250cd5 549
ab950546 550 /*
45250cd5
KB
551 * Now that all search paths have been read for suffixes et al, it's
552 * time to add the default search path to their lists...
ab950546 553 */
45250cd5
KB
554 Suff_DoPaths();
555
5f618604
KB
556 /* print the initial graph, if the user requested it */
557 if (DEBUG(GRAPH1))
45250cd5
KB
558 Targ_PrintGraph(1);
559
ab950546 560 /*
45250cd5
KB
561 * Have now read the entire graph and need to make a list of targets
562 * to create. If none was given on the command line, we consult the
563 * parsing module to find the main target(s) to create.
ab950546 564 */
45250cd5
KB
565 if (Lst_IsEmpty(create))
566 targs = Parse_MainName();
567 else
6c4ac3f1 568 targs = Targ_FindList(create, TARG_CREATE);
45250cd5 569
b6cda174
KB
570/*
571 * this was original amMake -- want to allow parallelism, so put this
572 * back in, eventually.
573 */
40a80f0c 574 if (!compatMake) {
45250cd5
KB
575 /*
576 * Initialize job module before traversing the graph, now that
577 * any .BEGIN and .END targets have been read. This is done
578 * only if the -q flag wasn't given (to prevent the .BEGIN from
579 * being executed should it exist).
580 */
581 if (!queryFlag) {
582 if (maxLocal == -1)
583 maxLocal = maxJobs;
6c4ac3f1 584 Job_Init(maxJobs, maxLocal);
45250cd5
KB
585 jobsRunning = TRUE;
586 }
587
588 /* Traverse the graph, checking on all the targets */
589 outOfDate = Make_Run(targs);
590 } else
591 /*
592 * Compat_Init will take care of creating all the targets as
593 * well as initializing the module.
594 */
595 Compat_Run(targs);
ab950546 596
5f618604
KB
597 /* print the graph now it's been processed if the user requested it */
598 if (DEBUG(GRAPH2))
45250cd5
KB
599 Targ_PrintGraph(2);
600
601 if (queryFlag && outOfDate)
40a80f0c 602 return(1);
45250cd5 603 else
40a80f0c 604 return(0);
ab950546 605}
aa5839c2 606
ab950546 607/*-
ab950546
KB
608 * ReadMakefile --
609 * Open and parse the given makefile.
610 *
611 * Results:
612 * TRUE if ok. FALSE if couldn't open file.
613 *
614 * Side Effects:
615 * lots
ab950546
KB
616 */
617static Boolean
45250cd5
KB
618ReadMakefile(fname)
619 char *fname; /* makefile to read */
ab950546 620{
05a7e5b6
KB
621 extern Lst parseIncPath, sysIncPath;
622 FILE *stream;
623 char *name, path[MAXPATHLEN + 1];
624
6c4ac3f1 625 if (!strcmp(fname, "-")) {
45250cd5
KB
626 Parse_File("(stdin)", stdin);
627 Var_Set("MAKEFILE", "", VAR_GLOBAL);
628 } else {
40a80f0c 629 if ((stream = fopen(fname, "r")) != NULL)
aae0c546 630 goto found;
05a7e5b6
KB
631 /* if we've chdir'd, rebuild the path name */
632 if (curdir && *fname != '/') {
633 (void)sprintf(path, "%s/%s", curdir, fname);
40a80f0c 634 if ((stream = fopen(path, "r")) != NULL) {
aae0c546
KB
635 fname = path;
636 goto found;
637 }
45250cd5 638 }
aae0c546
KB
639 /* look in -I and system include directories. */
640 name = Dir_FindFile(fname, parseIncPath);
641 if (!name)
642 name = Dir_FindFile(fname, sysIncPath);
643 if (!name || !(stream = fopen(name, "r")))
644 return(FALSE);
645 fname = name;
ab950546 646 /*
05a7e5b6
KB
647 * set the MAKEFILE variable desired by System V fans -- the
648 * placement of the setting here means it gets set to the last
649 * makefile specified, as it is set by SysV make.
ab950546 650 */
aae0c546 651found: Var_Set("MAKEFILE", fname, VAR_GLOBAL);
45250cd5
KB
652 Parse_File(fname, stream);
653 (void)fclose(stream);
ab950546 654 }
45250cd5 655 return(TRUE);
ab950546 656}
aa5839c2 657
ab950546 658/*-
ab950546 659 * Error --
b6cda174 660 * Print an error message given its format.
ab950546
KB
661 *
662 * Results:
663 * None.
664 *
665 * Side Effects:
666 * The message is printed.
ab950546 667 */
b6cda174 668/* VARARGS */
ab950546 669void
40a80f0c
KB
670#if __STDC__
671Error(const char *fmt, ...)
672#else
673Error(fmt, va_alist)
674 char *fmt;
b6cda174 675 va_dcl
40a80f0c 676#endif
ab950546 677{
b6cda174 678 va_list ap;
40a80f0c
KB
679#if __STDC__
680 va_start(ap, fmt);
681#else
b6cda174 682 va_start(ap);
40a80f0c 683#endif
b6cda174
KB
684 (void)vfprintf(stderr, fmt, ap);
685 va_end(ap);
686 (void)fprintf(stderr, "\n");
45250cd5 687 (void)fflush(stderr);
ab950546 688}
aa5839c2 689
ab950546 690/*-
ab950546
KB
691 * Fatal --
692 * Produce a Fatal error message. If jobs are running, waits for them
693 * to finish.
694 *
695 * Results:
696 * None
697 *
698 * Side Effects:
699 * The program exits
ab950546 700 */
b6cda174 701/* VARARGS */
ab950546 702void
40a80f0c
KB
703#if __STDC__
704Fatal(const char *fmt, ...)
705#else
706Fatal(fmt, va_alist)
707 char *fmt;
b6cda174 708 va_dcl
40a80f0c 709#endif
ab950546 710{
6c4ac3f1 711 va_list ap;
40a80f0c
KB
712#if __STDC__
713 va_start(ap, fmt);
714#else
715 va_start(ap);
716#endif
45250cd5
KB
717 if (jobsRunning)
718 Job_Wait();
6c4ac3f1 719
6c4ac3f1
KB
720 (void)vfprintf(stderr, fmt, ap);
721 va_end(ap);
722 (void)fprintf(stderr, "\n");
723 (void)fflush(stderr);
ab950546 724
5f618604 725 if (DEBUG(GRAPH2))
45250cd5
KB
726 Targ_PrintGraph(2);
727 exit(2); /* Not 1 so -q can distinguish error */
ab950546 728}
aa5839c2 729
ab950546 730/*
ab950546
KB
731 * Punt --
732 * Major exception once jobs are being created. Kills all jobs, prints
733 * a message and exits.
734 *
735 * Results:
736 * None
737 *
738 * Side Effects:
739 * All children are killed indiscriminately and the program Lib_Exits
ab950546 740 */
b6cda174 741/* VARARGS */
ab950546 742void
40a80f0c
KB
743#if __STDC__
744Punt(const char *fmt, ...)
745#else
746Punt(fmt, va_alist)
747 char *fmt;
b6cda174 748 va_dcl
40a80f0c 749#endif
ab950546 750{
6c4ac3f1 751 va_list ap;
40a80f0c
KB
752#if __STDC__
753 va_start(ap, fmt);
754#else
6c4ac3f1 755 va_start(ap);
40a80f0c
KB
756#endif
757 (void)fprintf(stderr, "make: ");
6c4ac3f1
KB
758 (void)vfprintf(stderr, fmt, ap);
759 va_end(ap);
760 (void)fprintf(stderr, "\n");
761 (void)fflush(stderr);
762
45250cd5 763 DieHorribly();
ab950546 764}
aa5839c2 765
ab950546 766/*-
ab950546
KB
767 * DieHorribly --
768 * Exit without giving a message.
769 *
770 * Results:
771 * None
772 *
773 * Side Effects:
774 * A big one...
ab950546
KB
775 */
776void
777DieHorribly()
778{
45250cd5
KB
779 if (jobsRunning)
780 Job_AbortAll();
5f618604 781 if (DEBUG(GRAPH2))
45250cd5
KB
782 Targ_PrintGraph(2);
783 exit(2); /* Not 1, so -q can distinguish error */
ab950546 784}
aa5839c2 785
ab950546 786/*
ab950546
KB
787 * Finish --
788 * Called when aborting due to errors in child shell to signal
789 * abnormal exit.
790 *
791 * Results:
792 * None
793 *
794 * Side Effects:
795 * The program exits
ab950546
KB
796 */
797void
45250cd5
KB
798Finish(errors)
799 int errors; /* number of errors encountered in Make_Make */
ab950546 800{
45250cd5 801 Fatal("%d error%s", errors, errors == 1 ? "" : "s");
ab950546 802}
b6cda174 803
05a7e5b6
KB
804/*
805 * emalloc --
806 * malloc, but die on error.
807 */
808char *
809emalloc(len)
810 u_int len;
811{
40a80f0c 812 char *p;
05a7e5b6
KB
813
814 if (!(p = malloc(len)))
815 enomem();
816 return(p);
817}
818
819/*
820 * enomem --
821 * die when out of memory.
822 */
40a80f0c 823void
05a7e5b6
KB
824enomem()
825{
826 (void)fprintf(stderr, "make: %s.\n", strerror(errno));
827 exit(2);
828}
829
830/*
831 * usage --
832 * exit with usage message
833 */
40a80f0c 834static void
b6cda174
KB
835usage()
836{
837 (void)fprintf(stderr,
f01a5a44
KB
838"usage: make [-eiknqrst] [-D variable] [-d flags] [-f makefile ]\n\
839 [-I directory] [-j max_jobs] [variable=value]\n");
b6cda174
KB
840 exit(2);
841}