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