main.c revision 29957
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.22 1997/08/27 06:31:27 jkh 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 <stdlib.h> 92#include <errno.h> 93#include <fcntl.h> 94#include <stdio.h> 95#if __STDC__ 96#include <stdarg.h> 97#else 98#include <varargs.h> 99#endif 100#include "make.h" 101#include "hash.h" 102#include "dir.h" 103#include "job.h" 104#include "pathnames.h" 105 106#ifndef DEFMAXLOCAL 107#define DEFMAXLOCAL DEFMAXJOBS 108#endif /* DEFMAXLOCAL */ 109 110#define MAKEFLAGS ".MAKEFLAGS" 111 112Lst create; /* Targets to be made */ 113time_t now; /* Time at start of make */ 114GNode *DEFAULT; /* .DEFAULT node */ 115Boolean allPrecious; /* .PRECIOUS given on line by itself */ 116 117static Boolean noBuiltins; /* -r flag */ 118static Lst makefiles; /* ordered list of makefiles to read */ 119static Boolean printVars; /* print value of one or more vars */ 120static Lst variables; /* list of variables to print */ 121int maxJobs; /* -j argument */ 122static Boolean forceJobs; /* -j argument given */ 123static int maxLocal; /* -L argument */ 124Boolean compatMake; /* -B argument */ 125Boolean debug; /* -d flag */ 126Boolean noExecute; /* -n flag */ 127Boolean keepgoing; /* -k flag */ 128Boolean queryFlag; /* -q flag */ 129Boolean touchFlag; /* -t flag */ 130Boolean usePipes; /* !-P flag */ 131Boolean ignoreErrors; /* -i flag */ 132Boolean beSilent; /* -s flag */ 133Boolean oldVars; /* variable substitution style */ 134Boolean checkEnvFirst; /* -e flag */ 135static Boolean jobsRunning; /* TRUE if the jobs might be running */ 136 137static void MainParseArgs __P((int, char **)); 138char * chdir_verify_path __P((char *, char *)); 139static int ReadMakefile __P((ClientData, ClientData)); 140static void usage __P((void)); 141 142static char *curdir; /* startup directory */ 143static char *objdir; /* where we chdir'ed to */ 144 145/*- 146 * MainParseArgs -- 147 * Parse a given argument vector. Called from main() and from 148 * Main_ParseArgLine() when the .MAKEFLAGS target is used. 149 * 150 * XXX: Deal with command line overriding .MAKEFLAGS in makefile 151 * 152 * Results: 153 * None 154 * 155 * Side Effects: 156 * Various global and local flags will be set depending on the flags 157 * given 158 */ 159static void 160MainParseArgs(argc, argv) 161 int argc; 162 char **argv; 163{ 164 extern int optind; 165 extern char *optarg; 166 int c; 167 168 optind = 1; /* since we're called more than once */ 169#ifdef REMOTE 170# define OPTFLAGS "BD:I:L:PSV:d:ef:ij:km:nqrst" 171#else 172# define OPTFLAGS "BD:I:PSV:d:ef:ij:km:nqrst" 173#endif 174rearg: while((c = getopt(argc, argv, OPTFLAGS)) != -1) { 175 switch(c) { 176 case 'D': 177 Var_Set(optarg, "1", VAR_GLOBAL); 178 Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL); 179 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 180 break; 181 case 'I': 182 Parse_AddIncludeDir(optarg); 183 Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL); 184 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 185 break; 186 case 'V': 187 printVars = TRUE; 188 (void)Lst_AtEnd(variables, (ClientData)optarg); 189 Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL); 190 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 191 break; 192 case 'B': 193 compatMake = TRUE; 194 Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL); 195 break; 196#ifdef REMOTE 197 case 'L': 198 maxLocal = atoi(optarg); 199 Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL); 200 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 201 break; 202#endif 203 case 'P': 204 usePipes = FALSE; 205 Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL); 206 break; 207 case 'S': 208 keepgoing = FALSE; 209 Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL); 210 break; 211 case 'd': { 212 char *modules = optarg; 213 214 for (; *modules; ++modules) 215 switch (*modules) { 216 case 'A': 217 debug = ~0; 218 break; 219 case 'a': 220 debug |= DEBUG_ARCH; 221 break; 222 case 'c': 223 debug |= DEBUG_COND; 224 break; 225 case 'd': 226 debug |= DEBUG_DIR; 227 break; 228 case 'f': 229 debug |= DEBUG_FOR; 230 break; 231 case 'g': 232 if (modules[1] == '1') { 233 debug |= DEBUG_GRAPH1; 234 ++modules; 235 } 236 else if (modules[1] == '2') { 237 debug |= DEBUG_GRAPH2; 238 ++modules; 239 } 240 break; 241 case 'j': 242 debug |= DEBUG_JOB; 243 break; 244 case 'm': 245 debug |= DEBUG_MAKE; 246 break; 247 case 's': 248 debug |= DEBUG_SUFF; 249 break; 250 case 't': 251 debug |= DEBUG_TARG; 252 break; 253 case 'v': 254 debug |= DEBUG_VAR; 255 break; 256 default: 257 warnx("illegal argument to d option -- %c", *modules); 258 usage(); 259 } 260 Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL); 261 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 262 break; 263 } 264 case 'e': 265 checkEnvFirst = TRUE; 266 Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL); 267 break; 268 case 'f': 269 (void)Lst_AtEnd(makefiles, (ClientData)optarg); 270 break; 271 case 'i': 272 ignoreErrors = TRUE; 273 Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL); 274 break; 275 case 'j': 276 forceJobs = TRUE; 277 maxJobs = atoi(optarg); 278#ifndef REMOTE 279 maxLocal = maxJobs; 280#endif 281 Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL); 282 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 283 break; 284 case 'k': 285 keepgoing = TRUE; 286 Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL); 287 break; 288 case 'm': 289 Dir_AddDir(sysIncPath, optarg); 290 Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL); 291 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 292 break; 293 case 'n': 294 noExecute = TRUE; 295 Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL); 296 break; 297 case 'q': 298 queryFlag = TRUE; 299 /* Kind of nonsensical, wot? */ 300 Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL); 301 break; 302 case 'r': 303 noBuiltins = TRUE; 304 Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL); 305 break; 306 case 's': 307 beSilent = TRUE; 308 Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL); 309 break; 310 case 't': 311 touchFlag = TRUE; 312 Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL); 313 break; 314 default: 315 case '?': 316 usage(); 317 } 318 } 319 320 oldVars = TRUE; 321 322 /* 323 * See if the rest of the arguments are variable assignments and 324 * perform them if so. Else take them to be targets and stuff them 325 * on the end of the "create" list. 326 */ 327 for (argv += optind, argc -= optind; *argv; ++argv, --argc) 328 if (Parse_IsVar(*argv)) 329 Parse_DoVar(*argv, VAR_CMD); 330 else { 331 if (!**argv) 332 Punt("illegal (null) argument."); 333 if (**argv == '-') { 334 if ((*argv)[1]) 335 optind = 0; /* -flag... */ 336 else 337 optind = 1; /* - */ 338 goto rearg; 339 } 340 (void)Lst_AtEnd(create, (ClientData)estrdup(*argv)); 341 } 342} 343 344/*- 345 * Main_ParseArgLine -- 346 * Used by the parse module when a .MFLAGS or .MAKEFLAGS target 347 * is encountered and by main() when reading the .MAKEFLAGS envariable. 348 * Takes a line of arguments and breaks it into its 349 * component words and passes those words and the number of them to the 350 * MainParseArgs function. 351 * The line should have all its leading whitespace removed. 352 * 353 * Results: 354 * None 355 * 356 * Side Effects: 357 * Only those that come from the various arguments. 358 */ 359void 360Main_ParseArgLine(line) 361 char *line; /* Line to fracture */ 362{ 363 char **argv; /* Manufactured argument vector */ 364 int argc; /* Number of arguments in argv */ 365 366 if (line == NULL) 367 return; 368 for (; *line == ' '; ++line) 369 continue; 370 if (!*line) 371 return; 372 373 argv = brk_string(line, &argc, TRUE); 374 MainParseArgs(argc, argv); 375} 376 377char * 378chdir_verify_path(path, obpath) 379 char *path; 380 char *obpath; 381{ 382 struct stat sb; 383 384 if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { 385 if (chdir(path)) { 386 warn("warning: %s", path); 387 return 0; 388 } 389 else { 390 if (path[0] != '/') { 391 (void) snprintf(obpath, MAXPATHLEN, "%s/%s", 392 curdir, path); 393 return obpath; 394 } 395 else 396 return path; 397 } 398 } 399 400 return 0; 401} 402 403 404/*- 405 * main -- 406 * The main function, for obvious reasons. Initializes variables 407 * and a few modules, then parses the arguments give it in the 408 * environment and on the command line. Reads the system makefile 409 * followed by either Makefile, makefile or the file given by the 410 * -f argument. Sets the .MAKEFLAGS PMake variable based on all the 411 * flags it has received by then uses either the Make or the Compat 412 * module to create the initial list of targets. 413 * 414 * Results: 415 * If -q was given, exits -1 if anything was out-of-date. Else it exits 416 * 0. 417 * 418 * Side Effects: 419 * The program exits when done. Targets are created. etc. etc. etc. 420 */ 421int 422main(argc, argv) 423 int argc; 424 char **argv; 425{ 426 Lst targs; /* target nodes to create -- passed to Make_Init */ 427 Boolean outOfDate = TRUE; /* FALSE if all targets up to date */ 428 struct stat sb, sa; 429 char *p, *p1, *path, *pathp, *pwd; 430 char mdpath[MAXPATHLEN + 1]; 431 char obpath[MAXPATHLEN + 1]; 432 char cdpath[MAXPATHLEN + 1]; 433 char *machine = getenv("MACHINE"); 434 Lst sysMkPath; /* Path of sys.mk */ 435 char *cp = NULL, *start; 436 /* avoid faults on read-only strings */ 437 static char syspath[] = _PATH_DEFSYSPATH; 438 439#ifdef RLIMIT_NOFILE 440 /* 441 * get rid of resource limit on file descriptors 442 */ 443 { 444 struct rlimit rl; 445 if (getrlimit(RLIMIT_NOFILE, &rl) != -1 && 446 rl.rlim_cur != rl.rlim_max) { 447 rl.rlim_cur = rl.rlim_max; 448 (void) setrlimit(RLIMIT_NOFILE, &rl); 449 } 450 } 451#endif 452 /* 453 * Find where we are and take care of PWD for the automounter... 454 * All this code is so that we know where we are when we start up 455 * on a different machine with pmake. 456 */ 457 curdir = cdpath; 458 if (getcwd(curdir, MAXPATHLEN) == NULL) 459 err(2, NULL); 460 461 if (stat(curdir, &sa) == -1) 462 err(2, "%s", curdir); 463 464 if ((pwd = getenv("PWD")) != NULL) { 465 if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino && 466 sa.st_dev == sb.st_dev) 467 (void) strcpy(curdir, pwd); 468 } 469 470 /* 471 * Get the name of this type of MACHINE from utsname 472 * so we can share an executable for similar machines. 473 * (i.e. m68k: amiga hp300, mac68k, sun3, ...) 474 * 475 * Note that while MACHINE is decided at run-time, 476 * MACHINE_ARCH is always known at compile time. 477 */ 478 if (!machine) { 479#ifndef MACHINE 480 struct utsname utsname; 481 482 if (uname(&utsname) == -1) { 483 perror("make: uname"); 484 exit(2); 485 } 486 machine = utsname.machine; 487#else 488 machine = MACHINE; 489#endif 490 } 491 492 /* 493 * The object directory location is determined using the 494 * following order of preference: 495 * 496 * 1. MAKEOBJDIRPREFIX`cwd` 497 * 2. MAKEOBJDIR 498 * 3. _PATH_OBJDIR.${MACHINE} 499 * 4. _PATH_OBJDIR 500 * 5. _PATH_OBJDIRPREFIX${MACHINE} 501 * 502 * If all fails, use the current directory to build. 503 * 504 * Once things are initted, 505 * have to add the original directory to the search path, 506 * and modify the paths for the Makefiles apropriately. The 507 * current directory is also placed as a variable for make scripts. 508 */ 509 if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) { 510 if (!(path = getenv("MAKEOBJDIR"))) { 511 path = _PATH_OBJDIR; 512 pathp = _PATH_OBJDIRPREFIX; 513 (void) snprintf(mdpath, MAXPATHLEN, "%s.%s", 514 path, machine); 515 if (!(objdir = chdir_verify_path(mdpath, obpath))) 516 if (!(objdir=chdir_verify_path(path, obpath))) { 517 (void) snprintf(mdpath, MAXPATHLEN, 518 "%s%s", pathp, curdir); 519 if (!(objdir=chdir_verify_path(mdpath, 520 obpath))) 521 objdir = curdir; 522 } 523 } 524 else if (!(objdir = chdir_verify_path(path, obpath))) 525 objdir = curdir; 526 } 527 else { 528 (void) snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir); 529 if (!(objdir = chdir_verify_path(mdpath, obpath))) 530 objdir = curdir; 531 } 532 533 setenv("PWD", objdir, 1); 534 535 create = Lst_Init(FALSE); 536 makefiles = Lst_Init(FALSE); 537 printVars = FALSE; 538 variables = Lst_Init(FALSE); 539 beSilent = FALSE; /* Print commands as executed */ 540 ignoreErrors = FALSE; /* Pay attention to non-zero returns */ 541 noExecute = FALSE; /* Execute all commands */ 542 keepgoing = FALSE; /* Stop on error */ 543 allPrecious = FALSE; /* Remove targets when interrupted */ 544 queryFlag = FALSE; /* This is not just a check-run */ 545 noBuiltins = FALSE; /* Read the built-in rules */ 546 touchFlag = FALSE; /* Actually update targets */ 547 usePipes = TRUE; /* Catch child output in pipes */ 548 debug = 0; /* No debug verbosity, please. */ 549 jobsRunning = FALSE; 550 551 maxLocal = DEFMAXLOCAL; /* Set default local max concurrency */ 552#ifdef REMOTE 553 maxJobs = DEFMAXJOBS; /* Set default max concurrency */ 554#else 555 maxJobs = maxLocal; 556#endif 557 forceJobs = FALSE; /* No -j flag */ 558 compatMake = FALSE; /* No compat mode */ 559 560 561 /* 562 * Initialize the parsing, directory and variable modules to prepare 563 * for the reading of inclusion paths and variable settings on the 564 * command line 565 */ 566 Dir_Init(); /* Initialize directory structures so -I flags 567 * can be processed correctly */ 568 Parse_Init(); /* Need to initialize the paths of #include 569 * directories */ 570 Var_Init(); /* As well as the lists of variables for 571 * parsing arguments */ 572 str_init(); 573 if (objdir != curdir) 574 Dir_AddDir(dirSearchPath, curdir); 575 Var_Set(".CURDIR", curdir, VAR_GLOBAL); 576 Var_Set(".OBJDIR", objdir, VAR_GLOBAL); 577 578 /* 579 * Initialize various variables. 580 * MAKE also gets this name, for compatibility 581 * .MAKEFLAGS gets set to the empty string just in case. 582 * MFLAGS also gets initialized empty, for compatibility. 583 */ 584 Var_Set("MAKE", argv[0], VAR_GLOBAL); 585 Var_Set(MAKEFLAGS, "", VAR_GLOBAL); 586 Var_Set("MFLAGS", "", VAR_GLOBAL); 587 Var_Set("MACHINE", machine, VAR_GLOBAL); 588#ifdef MACHINE_ARCH 589 Var_Set("MACHINE_ARCH", MACHINE_ARCH, VAR_GLOBAL); 590#endif 591 592 /* 593 * First snag any flags out of the MAKE environment variable. 594 * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's 595 * in a different format). 596 */ 597#ifdef POSIX 598 Main_ParseArgLine(getenv("MAKEFLAGS")); 599#else 600 Main_ParseArgLine(getenv("MAKE")); 601#endif 602 603 MainParseArgs(argc, argv); 604 605 /* 606 * Be compatible if user did not specify -j and did not explicitly 607 * turned compatibility on 608 */ 609 if (!compatMake && !forceJobs) 610 compatMake = TRUE; 611 612 /* 613 * Initialize archive, target and suffix modules in preparation for 614 * parsing the makefile(s) 615 */ 616 Arch_Init(); 617 Targ_Init(); 618 Suff_Init(); 619 620 DEFAULT = NILGNODE; 621 (void)time(&now); 622 623 /* 624 * Set up the .TARGETS variable to contain the list of targets to be 625 * created. If none specified, make the variable empty -- the parser 626 * will fill the thing in with the default or .MAIN target. 627 */ 628 if (!Lst_IsEmpty(create)) { 629 LstNode ln; 630 631 for (ln = Lst_First(create); ln != NILLNODE; 632 ln = Lst_Succ(ln)) { 633 char *name = (char *)Lst_Datum(ln); 634 635 Var_Append(".TARGETS", name, VAR_GLOBAL); 636 } 637 } else 638 Var_Set(".TARGETS", "", VAR_GLOBAL); 639 640 641 /* 642 * If no user-supplied system path was given (through the -m option) 643 * add the directories from the DEFSYSPATH (more than one may be given 644 * as dir1:...:dirn) to the system include path. 645 */ 646 if (Lst_IsEmpty(sysIncPath)) { 647 for (start = syspath; *start != '\0'; start = cp) { 648 for (cp = start; *cp != '\0' && *cp != ':'; cp++) 649 continue; 650 if (*cp == '\0') { 651 Dir_AddDir(sysIncPath, start); 652 } else { 653 *cp++ = '\0'; 654 Dir_AddDir(sysIncPath, start); 655 } 656 } 657 } 658 659 /* 660 * Read in the built-in rules first, followed by the specified 661 * makefile, if it was (makefile != (char *) NULL), or the default 662 * Makefile and makefile, in that order, if it wasn't. 663 */ 664 if (!noBuiltins) { 665 LstNode ln; 666 667 sysMkPath = Lst_Init (FALSE); 668 Dir_Expand (_PATH_DEFSYSMK, sysIncPath, sysMkPath); 669 if (Lst_IsEmpty(sysMkPath)) 670 Fatal("make: no system rules (%s).", _PATH_DEFSYSMK); 671 ln = Lst_Find(sysMkPath, (ClientData)NULL, ReadMakefile); 672 if (ln != NILLNODE) 673 Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 674 } 675 676 if (!Lst_IsEmpty(makefiles)) { 677 LstNode ln; 678 679 ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile); 680 if (ln != NILLNODE) 681 Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 682 } else if (!ReadMakefile("makefile", NULL)) 683 (void)ReadMakefile("Makefile", NULL); 684 685 (void)ReadMakefile(".depend", NULL); 686 687 Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL); 688 if (p1) 689 free(p1); 690 691 /* Install all the flags into the MAKE envariable. */ 692 if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1)) != NULL) && *p) 693#ifdef POSIX 694 setenv("MAKEFLAGS", p, 1); 695#else 696 setenv("MAKE", p, 1); 697#endif 698 if (p1) 699 free(p1); 700 701 /* 702 * For compatibility, look at the directories in the VPATH variable 703 * and add them to the search path, if the variable is defined. The 704 * variable's value is in the same format as the PATH envariable, i.e. 705 * <directory>:<directory>:<directory>... 706 */ 707 if (Var_Exists("VPATH", VAR_CMD)) { 708 char *vpath, *path, *cp, savec; 709 /* 710 * GCC stores string constants in read-only memory, but 711 * Var_Subst will want to write this thing, so store it 712 * in an array 713 */ 714 static char VPATH[] = "${VPATH}"; 715 716 vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE); 717 path = vpath; 718 do { 719 /* skip to end of directory */ 720 for (cp = path; *cp != ':' && *cp != '\0'; cp++) 721 continue; 722 /* Save terminator character so know when to stop */ 723 savec = *cp; 724 *cp = '\0'; 725 /* Add directory to search path */ 726 Dir_AddDir(dirSearchPath, path); 727 *cp = savec; 728 path = cp + 1; 729 } while (savec == ':'); 730 (void)free((Address)vpath); 731 } 732 733 /* 734 * Now that all search paths have been read for suffixes et al, it's 735 * time to add the default search path to their lists... 736 */ 737 Suff_DoPaths(); 738 739 /* print the initial graph, if the user requested it */ 740 if (DEBUG(GRAPH1)) 741 Targ_PrintGraph(1); 742 743 /* print the values of any variables requested by the user */ 744 if (printVars) { 745 LstNode ln; 746 747 for (ln = Lst_First(variables); ln != NILLNODE; 748 ln = Lst_Succ(ln)) { 749 char *value = Var_Value((char *)Lst_Datum(ln), 750 VAR_GLOBAL, &p1); 751 752 printf("%s\n", value ? value : ""); 753 if (p1) 754 free(p1); 755 } 756 } 757 758 /* 759 * Have now read the entire graph and need to make a list of targets 760 * to create. If none was given on the command line, we consult the 761 * parsing module to find the main target(s) to create. 762 */ 763 if (Lst_IsEmpty(create)) 764 targs = Parse_MainName(); 765 else 766 targs = Targ_FindList(create, TARG_CREATE); 767 768 if (!compatMake && !printVars) { 769 /* 770 * Initialize job module before traversing the graph, now that 771 * any .BEGIN and .END targets have been read. This is done 772 * only if the -q flag wasn't given (to prevent the .BEGIN from 773 * being executed should it exist). 774 */ 775 if (!queryFlag) { 776 if (maxLocal == -1) 777 maxLocal = maxJobs; 778 Job_Init(maxJobs, maxLocal); 779 jobsRunning = TRUE; 780 } 781 782 /* Traverse the graph, checking on all the targets */ 783 outOfDate = Make_Run(targs); 784 } else if (!printVars) { 785 /* 786 * Compat_Init will take care of creating all the targets as 787 * well as initializing the module. 788 */ 789 Compat_Run(targs); 790 } 791 792 Lst_Destroy(targs, NOFREE); 793 Lst_Destroy(variables, NOFREE); 794 Lst_Destroy(makefiles, NOFREE); 795 Lst_Destroy(create, (void (*) __P((ClientData))) free); 796 797 /* print the graph now it's been processed if the user requested it */ 798 if (DEBUG(GRAPH2)) 799 Targ_PrintGraph(2); 800 801 Suff_End(); 802 Targ_End(); 803 Arch_End(); 804 str_end(); 805 Var_End(); 806 Parse_End(); 807 Dir_End(); 808 809 if (queryFlag && outOfDate) 810 return(1); 811 else 812 return(0); 813} 814 815/*- 816 * ReadMakefile -- 817 * Open and parse the given makefile. 818 * 819 * Results: 820 * TRUE if ok. FALSE if couldn't open file. 821 * 822 * Side Effects: 823 * lots 824 */ 825static Boolean 826ReadMakefile(p, q) 827 ClientData p, q; 828{ 829 char *fname = p; /* makefile to read */ 830 extern Lst parseIncPath; 831 FILE *stream; 832 char *name, path[MAXPATHLEN + 1]; 833 834 if (!strcmp(fname, "-")) { 835 Parse_File("(stdin)", stdin); 836 Var_Set("MAKEFILE", "", VAR_GLOBAL); 837 } else { 838 /* if we've chdir'd, rebuild the path name */ 839 if (curdir != objdir && *fname != '/') { 840 (void)sprintf(path, "%s/%s", curdir, fname); 841 if ((stream = fopen(path, "r")) != NULL) { 842 fname = path; 843 goto found; 844 } 845 } else if ((stream = fopen(fname, "r")) != NULL) 846 goto found; 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