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