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