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