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