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