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