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