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