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