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