main.c revision 28191
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 const 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 46#if 0 47static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94"; 48#endif 49static const char rcsid[] = 50 "$Id: main.c,v 1.18 1997/07/24 06:58:06 charnier Exp $"; 51#endif /* not lint */ 52 53/*- 54 * main.c -- 55 * The main file for this entire program. Exit routines etc 56 * reside here. 57 * 58 * Utility functions defined in this file: 59 * Main_ParseArgLine Takes a line of arguments, breaks them and 60 * treats them as if they were given when first 61 * invoked. Used by the parse module to implement 62 * the .MFLAGS target. 63 * 64 * Error Print a tagged error message. The global 65 * MAKE variable must have been defined. This 66 * takes a format string and two optional 67 * arguments for it. 68 * 69 * Fatal Print an error message and exit. Also takes 70 * a format string and two arguments. 71 * 72 * Punt Aborts all jobs and exits with a message. Also 73 * takes a format string and two arguments. 74 * 75 * Finish Finish things up by printing the number of 76 * errors which occured, as passed to it, and 77 * exiting. 78 */ 79 80#include <sys/types.h> 81#include <sys/time.h> 82#include <sys/param.h> 83#include <sys/resource.h> 84#include <sys/signal.h> 85#include <sys/stat.h> 86#ifndef MACHINE 87#include <sys/utsname.h> 88#endif 89#include <sys/wait.h> 90#include <err.h> 91#include <errno.h> 92#include <fcntl.h> 93#include <stdio.h> 94#if __STDC__ 95#include <stdarg.h> 96#else 97#include <varargs.h> 98#endif 99#include "make.h" 100#include "hash.h" 101#include "dir.h" 102#include "job.h" 103#include "pathnames.h" 104 105#ifndef DEFMAXLOCAL 106#define DEFMAXLOCAL DEFMAXJOBS 107#endif /* DEFMAXLOCAL */ 108 109#define MAKEFLAGS ".MAKEFLAGS" 110 111Lst create; /* Targets to be made */ 112time_t now; /* Time at start of make */ 113GNode *DEFAULT; /* .DEFAULT node */ 114Boolean allPrecious; /* .PRECIOUS given on line by itself */ 115 116static Boolean noBuiltins; /* -r flag */ 117static Lst makefiles; /* ordered list of makefiles to read */ 118static Boolean printVars; /* print value of one or more vars */ 119static Lst variables; /* list of variables to print */ 120int maxJobs; /* -j argument */ 121static int maxLocal; /* -L argument */ 122Boolean compatMake; /* -B argument */ 123Boolean debug; /* -d flag */ 124Boolean noExecute; /* -n flag */ 125Boolean keepgoing; /* -k flag */ 126Boolean queryFlag; /* -q flag */ 127Boolean touchFlag; /* -t flag */ 128Boolean usePipes; /* !-P flag */ 129Boolean ignoreErrors; /* -i flag */ 130Boolean beSilent; /* -s flag */ 131Boolean oldVars; /* variable substitution style */ 132Boolean checkEnvFirst; /* -e flag */ 133static Boolean jobsRunning; /* TRUE if the jobs might be running */ 134 135static void MainParseArgs __P((int, char **)); 136char * chdir_verify_path __P((char *, char *)); 137static int ReadMakefile __P((ClientData, ClientData)); 138static void usage __P((void)); 139 140static char *curdir; /* startup directory */ 141static char *objdir; /* where we chdir'ed to */ 142 143/*- 144 * MainParseArgs -- 145 * Parse a given argument vector. Called from main() and from 146 * Main_ParseArgLine() when the .MAKEFLAGS target is used. 147 * 148 * XXX: Deal with command line overriding .MAKEFLAGS in makefile 149 * 150 * Results: 151 * None 152 * 153 * Side Effects: 154 * Various global and local flags will be set depending on the flags 155 * given 156 */ 157static void 158MainParseArgs(argc, argv) 159 int argc; 160 char **argv; 161{ 162 extern int optind; 163 extern char *optarg; 164 int c; 165 int forceJobs = 0; 166 167 optind = 1; /* since we're called more than once */ 168#ifdef REMOTE 169# define OPTFLAGS "BD:I:L:PSV:d:ef:ij:km:nqrst" 170#else 171# define OPTFLAGS "BD:I:PSV:d:ef:ij:km:nqrst" 172#endif 173rearg: while((c = getopt(argc, argv, OPTFLAGS)) != -1) { 174 switch(c) { 175 case 'D': 176 Var_Set(optarg, "1", VAR_GLOBAL); 177 Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL); 178 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 179 break; 180 case 'I': 181 Parse_AddIncludeDir(optarg); 182 Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL); 183 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 184 break; 185 case 'V': 186 printVars = TRUE; 187 (void)Lst_AtEnd(variables, (ClientData)optarg); 188 Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL); 189 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 190 break; 191 case 'B': 192 compatMake = TRUE; 193 break; 194#ifdef REMOTE 195 case 'L': 196 maxLocal = atoi(optarg); 197 Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL); 198 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 199 break; 200#endif 201 case 'P': 202 usePipes = FALSE; 203 Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL); 204 break; 205 case 'S': 206 keepgoing = FALSE; 207 Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL); 208 break; 209 case 'd': { 210 char *modules = optarg; 211 212 for (; *modules; ++modules) 213 switch (*modules) { 214 case 'A': 215 debug = ~0; 216 break; 217 case 'a': 218 debug |= DEBUG_ARCH; 219 break; 220 case 'c': 221 debug |= DEBUG_COND; 222 break; 223 case 'd': 224 debug |= DEBUG_DIR; 225 break; 226 case 'f': 227 debug |= DEBUG_FOR; 228 break; 229 case 'g': 230 if (modules[1] == '1') { 231 debug |= DEBUG_GRAPH1; 232 ++modules; 233 } 234 else if (modules[1] == '2') { 235 debug |= DEBUG_GRAPH2; 236 ++modules; 237 } 238 break; 239 case 'j': 240 debug |= DEBUG_JOB; 241 break; 242 case 'm': 243 debug |= DEBUG_MAKE; 244 break; 245 case 's': 246 debug |= DEBUG_SUFF; 247 break; 248 case 't': 249 debug |= DEBUG_TARG; 250 break; 251 case 'v': 252 debug |= DEBUG_VAR; 253 break; 254 default: 255 warnx("illegal argument to d option -- %c", *modules); 256 usage(); 257 } 258 Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL); 259 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 260 break; 261 } 262 case 'e': 263 checkEnvFirst = TRUE; 264 Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL); 265 break; 266 case 'f': 267 (void)Lst_AtEnd(makefiles, (ClientData)optarg); 268 break; 269 case 'i': 270 ignoreErrors = TRUE; 271 Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL); 272 break; 273 case 'j': 274 forceJobs = TRUE; 275 maxJobs = atoi(optarg); 276#ifndef REMOTE 277 maxLocal = maxJobs; 278#endif 279 Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL); 280 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 281 break; 282 case 'k': 283 keepgoing = TRUE; 284 Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL); 285 break; 286 case 'm': 287 Dir_AddDir(sysIncPath, optarg); 288 Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL); 289 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 290 break; 291 case 'n': 292 noExecute = TRUE; 293 Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL); 294 break; 295 case 'q': 296 queryFlag = TRUE; 297 /* Kind of nonsensical, wot? */ 298 Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL); 299 break; 300 case 'r': 301 noBuiltins = TRUE; 302 Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL); 303 break; 304 case 's': 305 beSilent = TRUE; 306 Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL); 307 break; 308 case 't': 309 touchFlag = TRUE; 310 Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL); 311 break; 312 default: 313 case '?': 314 usage(); 315 } 316 } 317 318 oldVars = TRUE; 319 320 /* 321 * See if the rest of the arguments are variable assignments and 322 * perform them if so. Else take them to be targets and stuff them 323 * on the end of the "create" list. 324 */ 325 for (argv += optind, argc -= optind; *argv; ++argv, --argc) 326 if (Parse_IsVar(*argv)) 327 Parse_DoVar(*argv, VAR_CMD); 328 else { 329 if (!**argv) 330 Punt("illegal (null) argument."); 331 if (**argv == '-') { 332 if ((*argv)[1]) 333 optind = 0; /* -flag... */ 334 else 335 optind = 1; /* - */ 336 goto rearg; 337 } 338 (void)Lst_AtEnd(create, (ClientData)estrdup(*argv)); 339 } 340 341 /* 342 * Be compatible if user did not specify -j and did not explicitly 343 * turned compatibility on 344 */ 345 if (!compatMake && !forceJobs) 346 compatMake = TRUE; 347} 348 349/*- 350 * Main_ParseArgLine -- 351 * Used by the parse module when a .MFLAGS or .MAKEFLAGS target 352 * is encountered and by main() when reading the .MAKEFLAGS envariable. 353 * Takes a line of arguments and breaks it into its 354 * component words and passes those words and the number of them to the 355 * MainParseArgs function. 356 * The line should have all its leading whitespace removed. 357 * 358 * Results: 359 * None 360 * 361 * Side Effects: 362 * Only those that come from the various arguments. 363 */ 364void 365Main_ParseArgLine(line) 366 char *line; /* Line to fracture */ 367{ 368 char **argv; /* Manufactured argument vector */ 369 int argc; /* Number of arguments in argv */ 370 371 if (line == NULL) 372 return; 373 for (; *line == ' '; ++line) 374 continue; 375 if (!*line) 376 return; 377 378 argv = brk_string(line, &argc, TRUE); 379 MainParseArgs(argc, argv); 380} 381 382char * 383chdir_verify_path(path, obpath) 384 char *path; 385 char *obpath; 386{ 387 struct stat sb; 388 389 if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { 390 if (chdir(path)) { 391 warn("warning: %s", path); 392 return 0; 393 } 394 else { 395 if (path[0] != '/') { 396 (void) snprintf(obpath, MAXPATHLEN, "%s/%s", 397 curdir, path); 398 return obpath; 399 } 400 else 401 return path; 402 } 403 } 404 405 return 0; 406} 407 408 409/*- 410 * main -- 411 * The main function, for obvious reasons. Initializes variables 412 * and a few modules, then parses the arguments give it in the 413 * environment and on the command line. Reads the system makefile 414 * followed by either Makefile, makefile or the file given by the 415 * -f argument. Sets the .MAKEFLAGS PMake variable based on all the 416 * flags it has received by then uses either the Make or the Compat 417 * module to create the initial list of targets. 418 * 419 * Results: 420 * If -q was given, exits -1 if anything was out-of-date. Else it exits 421 * 0. 422 * 423 * Side Effects: 424 * The program exits when done. Targets are created. etc. etc. etc. 425 */ 426int 427main(argc, argv) 428 int argc; 429 char **argv; 430{ 431 Lst targs; /* target nodes to create -- passed to Make_Init */ 432 Boolean outOfDate = TRUE; /* FALSE if all targets up to date */ 433 struct stat sb, sa; 434 char *p, *p1, *path, *pathp, *pwd; 435 char mdpath[MAXPATHLEN + 1]; 436 char obpath[MAXPATHLEN + 1]; 437 char cdpath[MAXPATHLEN + 1]; 438 char *machine = getenv("MACHINE"); 439 Lst sysMkPath; /* Path of sys.mk */ 440 char *cp = NULL, *start; 441 /* avoid faults on read-only strings */ 442 static char syspath[] = _PATH_DEFSYSPATH; 443 444#ifdef RLIMIT_NOFILE 445 /* 446 * get rid of resource limit on file descriptors 447 */ 448 { 449 struct rlimit rl; 450 if (getrlimit(RLIMIT_NOFILE, &rl) != -1 && 451 rl.rlim_cur != rl.rlim_max) { 452 rl.rlim_cur = rl.rlim_max; 453 (void) setrlimit(RLIMIT_NOFILE, &rl); 454 } 455 } 456#endif 457 /* 458 * Find where we are and take care of PWD for the automounter... 459 * All this code is so that we know where we are when we start up 460 * on a different machine with pmake. 461 */ 462 curdir = cdpath; 463 if (getcwd(curdir, MAXPATHLEN) == NULL) 464 err(2, NULL); 465 466 if (stat(curdir, &sa) == -1) 467 err(2, "%s", curdir); 468 469 if ((pwd = getenv("PWD")) != NULL) { 470 if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino && 471 sa.st_dev == sb.st_dev) 472 (void) strcpy(curdir, pwd); 473 } 474 475 /* 476 * Get the name of this type of MACHINE from utsname 477 * so we can share an executable for similar machines. 478 * (i.e. m68k: amiga hp300, mac68k, sun3, ...) 479 * 480 * Note that while MACHINE is decided at run-time, 481 * MACHINE_ARCH is always known at compile time. 482 */ 483 if (!machine) { 484#ifndef MACHINE 485 struct utsname utsname; 486 487 if (uname(&utsname) == -1) { 488 perror("make: uname"); 489 exit(2); 490 } 491 machine = utsname.machine; 492#else 493 machine = MACHINE; 494#endif 495 } 496 497 /* 498 * The object directory location is determined using the 499 * following order of preference: 500 * 501 * 1. MAKEOBJDIRPREFIX`cwd` 502 * 2. MAKEOBJDIR 503 * 3. _PATH_OBJDIR.${MACHINE} 504 * 4. _PATH_OBJDIR 505 * 5. _PATH_OBJDIRPREFIX${MACHINE} 506 * 507 * If all fails, use the current directory to build. 508 * 509 * Once things are initted, 510 * have to add the original directory to the search path, 511 * and modify the paths for the Makefiles apropriately. The 512 * current directory is also placed as a variable for make scripts. 513 */ 514 if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) { 515 if (!(path = getenv("MAKEOBJDIR"))) { 516 path = _PATH_OBJDIR; 517 pathp = _PATH_OBJDIRPREFIX; 518 (void) snprintf(mdpath, MAXPATHLEN, "%s.%s", 519 path, machine); 520 if (!(objdir = chdir_verify_path(mdpath, obpath))) 521 if (!(objdir=chdir_verify_path(path, obpath))) { 522 (void) snprintf(mdpath, MAXPATHLEN, 523 "%s%s", pathp, curdir); 524 if (!(objdir=chdir_verify_path(mdpath, 525 obpath))) 526 objdir = curdir; 527 } 528 } 529 else if (!(objdir = chdir_verify_path(path, obpath))) 530 objdir = curdir; 531 } 532 else { 533 (void) snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir); 534 if (!(objdir = chdir_verify_path(mdpath, obpath))) 535 objdir = curdir; 536 } 537 538 setenv("PWD", objdir, 1); 539 540 create = Lst_Init(FALSE); 541 makefiles = Lst_Init(FALSE); 542 printVars = FALSE; 543 variables = Lst_Init(FALSE); 544 beSilent = FALSE; /* Print commands as executed */ 545 ignoreErrors = FALSE; /* Pay attention to non-zero returns */ 546 noExecute = FALSE; /* Execute all commands */ 547 keepgoing = FALSE; /* Stop on error */ 548 allPrecious = FALSE; /* Remove targets when interrupted */ 549 queryFlag = FALSE; /* This is not just a check-run */ 550 noBuiltins = FALSE; /* Read the built-in rules */ 551 touchFlag = FALSE; /* Actually update targets */ 552 usePipes = TRUE; /* Catch child output in pipes */ 553 debug = 0; /* No debug verbosity, please. */ 554 jobsRunning = FALSE; 555 556 maxLocal = DEFMAXLOCAL; /* Set default local max concurrency */ 557#ifdef REMOTE 558 maxJobs = DEFMAXJOBS; /* Set default max concurrency */ 559#else 560 maxJobs = maxLocal; 561#endif 562 compatMake = FALSE; /* No compat mode */ 563 564 565 /* 566 * Initialize the parsing, directory and variable modules to prepare 567 * for the reading of inclusion paths and variable settings on the 568 * command line 569 */ 570 Dir_Init(); /* Initialize directory structures so -I flags 571 * can be processed correctly */ 572 Parse_Init(); /* Need to initialize the paths of #include 573 * directories */ 574 Var_Init(); /* As well as the lists of variables for 575 * parsing arguments */ 576 str_init(); 577 if (objdir != curdir) 578 Dir_AddDir(dirSearchPath, curdir); 579 Var_Set(".CURDIR", curdir, VAR_GLOBAL); 580 Var_Set(".OBJDIR", objdir, VAR_GLOBAL); 581 582 /* 583 * Initialize various variables. 584 * MAKE also gets this name, for compatibility 585 * .MAKEFLAGS gets set to the empty string just in case. 586 * MFLAGS also gets initialized empty, for compatibility. 587 */ 588 Var_Set("MAKE", argv[0], VAR_GLOBAL); 589 Var_Set(MAKEFLAGS, "", VAR_GLOBAL); 590 Var_Set("MFLAGS", "", VAR_GLOBAL); 591 Var_Set("MACHINE", machine, VAR_GLOBAL); 592#ifdef MACHINE_ARCH 593 Var_Set("MACHINE_ARCH", MACHINE_ARCH, VAR_GLOBAL); 594#endif 595 596 /* 597 * First snag any flags out of the MAKE environment variable. 598 * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's 599 * in a different format). 600 */ 601#ifdef POSIX 602 Main_ParseArgLine(getenv("MAKEFLAGS")); 603#else 604 Main_ParseArgLine(getenv("MAKE")); 605#endif 606 607 MainParseArgs(argc, argv); 608 609 /* 610 * Initialize archive, target and suffix modules in preparation for 611 * parsing the makefile(s) 612 */ 613 Arch_Init(); 614 Targ_Init(); 615 Suff_Init(); 616 617 DEFAULT = NILGNODE; 618 (void)time(&now); 619 620 /* 621 * Set up the .TARGETS variable to contain the list of targets to be 622 * created. If none specified, make the variable empty -- the parser 623 * will fill the thing in with the default or .MAIN target. 624 */ 625 if (!Lst_IsEmpty(create)) { 626 LstNode ln; 627 628 for (ln = Lst_First(create); ln != NILLNODE; 629 ln = Lst_Succ(ln)) { 630 char *name = (char *)Lst_Datum(ln); 631 632 Var_Append(".TARGETS", name, VAR_GLOBAL); 633 } 634 } else 635 Var_Set(".TARGETS", "", VAR_GLOBAL); 636 637 638 /* 639 * If no user-supplied system path was given (through the -m option) 640 * add the directories from the DEFSYSPATH (more than one may be given 641 * as dir1:...:dirn) to the system include path. 642 */ 643 if (Lst_IsEmpty(sysIncPath)) { 644 for (start = syspath; *start != '\0'; start = cp) { 645 for (cp = start; *cp != '\0' && *cp != ':'; cp++) 646 continue; 647 if (*cp == '\0') { 648 Dir_AddDir(sysIncPath, start); 649 } else { 650 *cp++ = '\0'; 651 Dir_AddDir(sysIncPath, start); 652 } 653 } 654 } 655 656 /* 657 * Read in the built-in rules first, followed by the specified 658 * makefile, if it was (makefile != (char *) NULL), or the default 659 * Makefile and makefile, in that order, if it wasn't. 660 */ 661 if (!noBuiltins) { 662 LstNode ln; 663 664 sysMkPath = Lst_Init (FALSE); 665 Dir_Expand (_PATH_DEFSYSMK, sysIncPath, sysMkPath); 666 if (Lst_IsEmpty(sysMkPath)) 667 Fatal("make: no system rules (%s).", _PATH_DEFSYSMK); 668 ln = Lst_Find(sysMkPath, (ClientData)NULL, ReadMakefile); 669 if (ln != NILLNODE) 670 Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 671 } 672 673 if (!Lst_IsEmpty(makefiles)) { 674 LstNode ln; 675 676 ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile); 677 if (ln != NILLNODE) 678 Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 679 } else if (!ReadMakefile("makefile", NULL)) 680 (void)ReadMakefile("Makefile", NULL); 681 682 (void)ReadMakefile(".depend", NULL); 683 684 Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL); 685 if (p1) 686 free(p1); 687 688 /* Install all the flags into the MAKE envariable. */ 689 if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1)) != NULL) && *p) 690#ifdef POSIX 691 setenv("MAKEFLAGS", p, 1); 692#else 693 setenv("MAKE", p, 1); 694#endif 695 if (p1) 696 free(p1); 697 698 /* 699 * For compatibility, look at the directories in the VPATH variable 700 * and add them to the search path, if the variable is defined. The 701 * variable's value is in the same format as the PATH envariable, i.e. 702 * <directory>:<directory>:<directory>... 703 */ 704 if (Var_Exists("VPATH", VAR_CMD)) { 705 char *vpath, *path, *cp, savec; 706 /* 707 * GCC stores string constants in read-only memory, but 708 * Var_Subst will want to write this thing, so store it 709 * in an array 710 */ 711 static char VPATH[] = "${VPATH}"; 712 713 vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE); 714 path = vpath; 715 do { 716 /* skip to end of directory */ 717 for (cp = path; *cp != ':' && *cp != '\0'; cp++) 718 continue; 719 /* Save terminator character so know when to stop */ 720 savec = *cp; 721 *cp = '\0'; 722 /* Add directory to search path */ 723 Dir_AddDir(dirSearchPath, path); 724 *cp = savec; 725 path = cp + 1; 726 } while (savec == ':'); 727 (void)free((Address)vpath); 728 } 729 730 /* 731 * Now that all search paths have been read for suffixes et al, it's 732 * time to add the default search path to their lists... 733 */ 734 Suff_DoPaths(); 735 736 /* print the initial graph, if the user requested it */ 737 if (DEBUG(GRAPH1)) 738 Targ_PrintGraph(1); 739 740 /* print the values of any variables requested by the user */ 741 if (printVars) { 742 LstNode ln; 743 744 for (ln = Lst_First(variables); ln != NILLNODE; 745 ln = Lst_Succ(ln)) { 746 char *value = Var_Value((char *)Lst_Datum(ln), 747 VAR_GLOBAL, &p1); 748 749 printf("%s\n", value ? value : ""); 750 if (p1) 751 free(p1); 752 } 753 } 754 755 /* 756 * Have now read the entire graph and need to make a list of targets 757 * to create. If none was given on the command line, we consult the 758 * parsing module to find the main target(s) to create. 759 */ 760 if (Lst_IsEmpty(create)) 761 targs = Parse_MainName(); 762 else 763 targs = Targ_FindList(create, TARG_CREATE); 764 765 if (!compatMake && !printVars) { 766 /* 767 * Initialize job module before traversing the graph, now that 768 * any .BEGIN and .END targets have been read. This is done 769 * only if the -q flag wasn't given (to prevent the .BEGIN from 770 * being executed should it exist). 771 */ 772 if (!queryFlag) { 773 if (maxLocal == -1) 774 maxLocal = maxJobs; 775 Job_Init(maxJobs, maxLocal); 776 jobsRunning = TRUE; 777 } 778 779 /* Traverse the graph, checking on all the targets */ 780 outOfDate = Make_Run(targs); 781 } else if (!printVars) { 782 /* 783 * Compat_Init will take care of creating all the targets as 784 * well as initializing the module. 785 */ 786 Compat_Run(targs); 787 } 788 789 Lst_Destroy(targs, NOFREE); 790 Lst_Destroy(variables, NOFREE); 791 Lst_Destroy(makefiles, NOFREE); 792 Lst_Destroy(create, (void (*) __P((ClientData))) free); 793 794 /* print the graph now it's been processed if the user requested it */ 795 if (DEBUG(GRAPH2)) 796 Targ_PrintGraph(2); 797 798 Suff_End(); 799 Targ_End(); 800 Arch_End(); 801 str_end(); 802 Var_End(); 803 Parse_End(); 804 Dir_End(); 805 806 if (queryFlag && outOfDate) 807 return(1); 808 else 809 return(0); 810} 811 812/*- 813 * ReadMakefile -- 814 * Open and parse the given makefile. 815 * 816 * Results: 817 * TRUE if ok. FALSE if couldn't open file. 818 * 819 * Side Effects: 820 * lots 821 */ 822static Boolean 823ReadMakefile(p, q) 824 ClientData p, q; 825{ 826 char *fname = p; /* makefile to read */ 827 extern Lst parseIncPath; 828 FILE *stream; 829 char *name, path[MAXPATHLEN + 1]; 830 831 if (!strcmp(fname, "-")) { 832 Parse_File("(stdin)", stdin); 833 Var_Set("MAKEFILE", "", VAR_GLOBAL); 834 } else { 835 if ((stream = fopen(fname, "r")) != NULL) 836 goto found; 837 /* if we've chdir'd, rebuild the path name */ 838 if (curdir != objdir && *fname != '/') { 839 (void)sprintf(path, "%s/%s", curdir, fname); 840 if ((stream = fopen(path, "r")) != NULL) { 841 fname = path; 842 goto found; 843 } 844 } 845 /* look in -I and system include directories. */ 846 name = Dir_FindFile(fname, parseIncPath); 847 if (!name) 848 name = Dir_FindFile(fname, sysIncPath); 849 if (!name || !(stream = fopen(name, "r"))) 850 return(FALSE); 851 fname = name; 852 /* 853 * set the MAKEFILE variable desired by System V fans -- the 854 * placement of the setting here means it gets set to the last 855 * makefile specified, as it is set by SysV make. 856 */ 857found: Var_Set("MAKEFILE", fname, VAR_GLOBAL); 858 Parse_File(fname, stream); 859 (void)fclose(stream); 860 } 861 return(TRUE); 862} 863 864/*- 865 * Cmd_Exec -- 866 * Execute the command in cmd, and return the output of that command 867 * in a string. 868 * 869 * Results: 870 * A string containing the output of the command, or the empty string 871 * If err is not NULL, it contains the reason for the command failure 872 * 873 * Side Effects: 874 * The string must be freed by the caller. 875 */ 876char * 877Cmd_Exec(cmd, err) 878 char *cmd; 879 char **err; 880{ 881 char *args[4]; /* Args for invoking the shell */ 882 int fds[2]; /* Pipe streams */ 883 int cpid; /* Child PID */ 884 int pid; /* PID from wait() */ 885 char *res; /* result */ 886 int status; /* command exit status */ 887 Buffer buf; /* buffer to store the result */ 888 char *cp; 889 int cc; 890 891 892 *err = NULL; 893 894 /* 895 * Set up arguments for shell 896 */ 897 args[0] = "sh"; 898 args[1] = "-c"; 899 args[2] = cmd; 900 args[3] = NULL; 901 902 /* 903 * Open a pipe for fetching its output 904 */ 905 if (pipe(fds) == -1) { 906 *err = "Couldn't create pipe for \"%s\""; 907 goto bad; 908 } 909 910 /* 911 * Fork 912 */ 913 switch (cpid = vfork()) { 914 case 0: 915 /* 916 * Close input side of pipe 917 */ 918 (void) close(fds[0]); 919 920 /* 921 * Duplicate the output stream to the shell's output, then 922 * shut the extra thing down. Note we don't fetch the error 923 * stream...why not? Why? 924 */ 925 (void) dup2(fds[1], 1); 926 (void) close(fds[1]); 927 928 (void) execv("/bin/sh", args); 929 _exit(1); 930 /*NOTREACHED*/ 931 932 case -1: 933 *err = "Couldn't exec \"%s\""; 934 goto bad; 935 936 default: 937 /* 938 * No need for the writing half 939 */ 940 (void) close(fds[1]); 941 942 buf = Buf_Init (MAKE_BSIZE); 943 944 do { 945 char result[BUFSIZ]; 946 cc = read(fds[0], result, sizeof(result)); 947 if (cc > 0) 948 Buf_AddBytes(buf, cc, (Byte *) result); 949 } 950 while (cc > 0 || (cc == -1 && errno == EINTR)); 951 952 /* 953 * Close the input side of the pipe. 954 */ 955 (void) close(fds[0]); 956 957 /* 958 * Wait for the process to exit. 959 */ 960 while(((pid = wait(&status)) != cpid) && (pid >= 0)) 961 continue; 962 963 if (cc == -1) 964 *err = "Error reading shell's output for \"%s\""; 965 966 res = (char *)Buf_GetAll (buf, &cc); 967 Buf_Destroy (buf, FALSE); 968 969 if (status) 970 *err = "\"%s\" returned non-zero status"; 971 972 /* 973 * Null-terminate the result, convert newlines to spaces and 974 * install it in the variable. 975 */ 976 res[cc] = '\0'; 977 cp = &res[cc] - 1; 978 979 if (*cp == '\n') { 980 /* 981 * A final newline is just stripped 982 */ 983 *cp-- = '\0'; 984 } 985 while (cp >= res) { 986 if (*cp == '\n') { 987 *cp = ' '; 988 } 989 cp--; 990 } 991 break; 992 } 993 return res; 994bad: 995 res = emalloc(1); 996 *res = '\0'; 997 return res; 998} 999 1000/*- 1001 * Error -- 1002 * Print an error message given its format. 1003 * 1004 * Results: 1005 * None. 1006 * 1007 * Side Effects: 1008 * The message is printed. 1009 */ 1010/* VARARGS */ 1011void 1012#if __STDC__ 1013Error(char *fmt, ...) 1014#else 1015Error(va_alist) 1016 va_dcl 1017#endif 1018{ 1019 va_list ap; 1020#if __STDC__ 1021 va_start(ap, fmt); 1022#else 1023 char *fmt; 1024 1025 va_start(ap); 1026 fmt = va_arg(ap, char *); 1027#endif 1028 (void)vfprintf(stderr, fmt, ap); 1029 va_end(ap); 1030 (void)fprintf(stderr, "\n"); 1031 (void)fflush(stderr); 1032} 1033 1034/*- 1035 * Fatal -- 1036 * Produce a Fatal error message. If jobs are running, waits for them 1037 * to finish. 1038 * 1039 * Results: 1040 * None 1041 * 1042 * Side Effects: 1043 * The program exits 1044 */ 1045/* VARARGS */ 1046void 1047#if __STDC__ 1048Fatal(char *fmt, ...) 1049#else 1050Fatal(va_alist) 1051 va_dcl 1052#endif 1053{ 1054 va_list ap; 1055#if __STDC__ 1056 va_start(ap, fmt); 1057#else 1058 char *fmt; 1059 1060 va_start(ap); 1061 fmt = va_arg(ap, char *); 1062#endif 1063 if (jobsRunning) 1064 Job_Wait(); 1065 1066 (void)vfprintf(stderr, fmt, ap); 1067 va_end(ap); 1068 (void)fprintf(stderr, "\n"); 1069 (void)fflush(stderr); 1070 1071 if (DEBUG(GRAPH2)) 1072 Targ_PrintGraph(2); 1073 exit(2); /* Not 1 so -q can distinguish error */ 1074} 1075 1076/* 1077 * Punt -- 1078 * Major exception once jobs are being created. Kills all jobs, prints 1079 * a message and exits. 1080 * 1081 * Results: 1082 * None 1083 * 1084 * Side Effects: 1085 * All children are killed indiscriminately and the program Lib_Exits 1086 */ 1087/* VARARGS */ 1088void 1089#if __STDC__ 1090Punt(char *fmt, ...) 1091#else 1092Punt(va_alist) 1093 va_dcl 1094#endif 1095{ 1096 va_list ap; 1097#if __STDC__ 1098 va_start(ap, fmt); 1099#else 1100 char *fmt; 1101 1102 va_start(ap); 1103 fmt = va_arg(ap, char *); 1104#endif 1105 1106 (void)fprintf(stderr, "make: "); 1107 (void)vfprintf(stderr, fmt, ap); 1108 va_end(ap); 1109 (void)fprintf(stderr, "\n"); 1110 (void)fflush(stderr); 1111 1112 DieHorribly(); 1113} 1114 1115/*- 1116 * DieHorribly -- 1117 * Exit without giving a message. 1118 * 1119 * Results: 1120 * None 1121 * 1122 * Side Effects: 1123 * A big one... 1124 */ 1125void 1126DieHorribly() 1127{ 1128 if (jobsRunning) 1129 Job_AbortAll(); 1130 if (DEBUG(GRAPH2)) 1131 Targ_PrintGraph(2); 1132 exit(2); /* Not 1, so -q can distinguish error */ 1133} 1134 1135/* 1136 * Finish -- 1137 * Called when aborting due to errors in child shell to signal 1138 * abnormal exit. 1139 * 1140 * Results: 1141 * None 1142 * 1143 * Side Effects: 1144 * The program exits 1145 */ 1146void 1147Finish(errors) 1148 int errors; /* number of errors encountered in Make_Make */ 1149{ 1150 Fatal("%d error%s", errors, errors == 1 ? "" : "s"); 1151} 1152 1153/* 1154 * emalloc -- 1155 * malloc, but die on error. 1156 */ 1157void * 1158emalloc(len) 1159 size_t len; 1160{ 1161 void *p; 1162 1163 if ((p = malloc(len)) == NULL) 1164 enomem(); 1165 return(p); 1166} 1167 1168/* 1169 * estrdup -- 1170 * strdup, but die on error. 1171 */ 1172char * 1173estrdup(str) 1174 const char *str; 1175{ 1176 char *p; 1177 1178 if ((p = strdup(str)) == NULL) 1179 enomem(); 1180 return(p); 1181} 1182 1183/* 1184 * erealloc -- 1185 * realloc, but die on error. 1186 */ 1187void * 1188erealloc(ptr, size) 1189 void *ptr; 1190 size_t size; 1191{ 1192 if ((ptr = realloc(ptr, size)) == NULL) 1193 enomem(); 1194 return(ptr); 1195} 1196 1197/* 1198 * enomem -- 1199 * die when out of memory. 1200 */ 1201void 1202enomem() 1203{ 1204 err(2, NULL); 1205} 1206 1207/* 1208 * enunlink -- 1209 * Remove a file carefully, avoiding directories. 1210 */ 1211int 1212eunlink(file) 1213 const char *file; 1214{ 1215 struct stat st; 1216 1217 if (lstat(file, &st) == -1) 1218 return -1; 1219 1220 if (S_ISDIR(st.st_mode)) { 1221 errno = EISDIR; 1222 return -1; 1223 } 1224 return unlink(file); 1225} 1226 1227/* 1228 * usage -- 1229 * exit with usage message 1230 */ 1231static void 1232usage() 1233{ 1234 (void)fprintf(stderr, "%s\n%s\n%s\n", 1235"usage: make [-Beiknqrst] [-D variable] [-d flags] [-f makefile ]", 1236" [-I directory] [-j max_jobs] [-m directory] [-V variable]", 1237" [variable=value] [target ...]"); 1238 exit(2); 1239} 1240 1241 1242int 1243PrintAddr(a, b) 1244 ClientData a; 1245 ClientData b; 1246{ 1247 printf("%lx ", (unsigned long) a); 1248 return b ? 0 : 0; 1249} 1250