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