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 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 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 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 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__ 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__ 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__ 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 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 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 * 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 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 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 922 PrintAddr(a, b) 923 ClientData a; 924 ClientData b; 925 { 926 printf("%lx ", (unsigned long) a); 927 return b ? 0 : 0; 928 } 929