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