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