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