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