1 /* $NetBSD: main.c,v 1.210 2013/03/23 05:31:29 sjg Exp $ */ 2 3 /* 4 * Copyright (c) 1988, 1989, 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Adam de Boor. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 /* 36 * Copyright (c) 1989 by Berkeley Softworks 37 * All rights reserved. 38 * 39 * This code is derived from software contributed to Berkeley by 40 * Adam de Boor. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 3. All advertising materials mentioning features or use of this software 51 * must display the following acknowledgement: 52 * This product includes software developed by the University of 53 * California, Berkeley and its contributors. 54 * 4. Neither the name of the University nor the names of its contributors 55 * may be used to endorse or promote products derived from this software 56 * without specific prior written permission. 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 68 * SUCH DAMAGE. 69 */ 70 71 #ifndef MAKE_NATIVE 72 static char rcsid[] = "$NetBSD: main.c,v 1.210 2013/03/23 05:31:29 sjg Exp $"; 73 #else 74 #include <sys/cdefs.h> 75 #ifndef lint 76 __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\ 77 The Regents of the University of California. All rights reserved."); 78 #endif /* not lint */ 79 80 #ifndef lint 81 #if 0 82 static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94"; 83 #else 84 __RCSID("$NetBSD: main.c,v 1.210 2013/03/23 05:31:29 sjg Exp $"); 85 #endif 86 #endif /* not lint */ 87 #endif 88 89 /*- 90 * main.c -- 91 * The main file for this entire program. Exit routines etc 92 * reside here. 93 * 94 * Utility functions defined in this file: 95 * Main_ParseArgLine Takes a line of arguments, breaks them and 96 * treats them as if they were given when first 97 * invoked. Used by the parse module to implement 98 * the .MFLAGS target. 99 * 100 * Error Print a tagged error message. The global 101 * MAKE variable must have been defined. This 102 * takes a format string and two optional 103 * arguments for it. 104 * 105 * Fatal Print an error message and exit. Also takes 106 * a format string and two arguments. 107 * 108 * Punt Aborts all jobs and exits with a message. Also 109 * takes a format string and two arguments. 110 * 111 * Finish Finish things up by printing the number of 112 * errors which occurred, as passed to it, and 113 * exiting. 114 */ 115 116 #include <sys/types.h> 117 #include <sys/time.h> 118 #include <sys/param.h> 119 #include <sys/resource.h> 120 #include <signal.h> 121 #include <sys/stat.h> 122 #include <sys/utsname.h> 123 #include "wait.h" 124 125 #include <errno.h> 126 #include <fcntl.h> 127 #include <stdarg.h> 128 #include <stdio.h> 129 #include <stdlib.h> 130 #include <time.h> 131 132 #include "make.h" 133 #include "hash.h" 134 #include "dir.h" 135 #include "job.h" 136 #include "pathnames.h" 137 #include "trace.h" 138 139 #ifdef USE_IOVEC 140 #include <sys/uio.h> 141 #endif 142 143 #ifndef DEFMAXLOCAL 144 #define DEFMAXLOCAL DEFMAXJOBS 145 #endif /* DEFMAXLOCAL */ 146 147 Lst create; /* Targets to be made */ 148 time_t now; /* Time at start of make */ 149 GNode *DEFAULT; /* .DEFAULT node */ 150 Boolean allPrecious; /* .PRECIOUS given on line by itself */ 151 152 static Boolean noBuiltins; /* -r flag */ 153 static Lst makefiles; /* ordered list of makefiles to read */ 154 static Boolean printVars; /* print value of one or more vars */ 155 static Lst variables; /* list of variables to print */ 156 int maxJobs; /* -j argument */ 157 static int maxJobTokens; /* -j argument */ 158 Boolean compatMake; /* -B argument */ 159 int debug; /* -d argument */ 160 Boolean debugVflag; /* -dV */ 161 Boolean noExecute; /* -n flag */ 162 Boolean noRecursiveExecute; /* -N flag */ 163 Boolean keepgoing; /* -k flag */ 164 Boolean queryFlag; /* -q flag */ 165 Boolean touchFlag; /* -t flag */ 166 Boolean ignoreErrors; /* -i flag */ 167 Boolean beSilent; /* -s flag */ 168 Boolean oldVars; /* variable substitution style */ 169 Boolean checkEnvFirst; /* -e flag */ 170 Boolean parseWarnFatal; /* -W flag */ 171 Boolean jobServer; /* -J flag */ 172 static int jp_0 = -1, jp_1 = -1; /* ends of parent job pipe */ 173 Boolean varNoExportEnv; /* -X flag */ 174 Boolean doing_depend; /* Set while reading .depend */ 175 static Boolean jobsRunning; /* TRUE if the jobs might be running */ 176 static const char * tracefile; 177 static void MainParseArgs(int, char **); 178 static int ReadMakefile(const void *, const void *); 179 static void usage(void) MAKE_ATTR_DEAD; 180 181 static Boolean ignorePWD; /* if we use -C, PWD is meaningless */ 182 static char objdir[MAXPATHLEN + 1]; /* where we chdir'ed to */ 183 char curdir[MAXPATHLEN + 1]; /* Startup directory */ 184 char *progname; /* the program name */ 185 char *makeDependfile; 186 pid_t myPid; 187 188 Boolean forceJobs = FALSE; 189 190 /* 191 * On some systems MACHINE is defined as something other than 192 * what we want. 193 */ 194 #ifdef FORCE_MACHINE 195 # undef MACHINE 196 # define MACHINE FORCE_MACHINE 197 #endif 198 199 extern Lst parseIncPath; 200 201 static void 202 parse_debug_options(const char *argvalue) 203 { 204 const char *modules; 205 const char *mode; 206 char *fname; 207 int len; 208 209 for (modules = argvalue; *modules; ++modules) { 210 switch (*modules) { 211 case 'A': 212 debug = ~0; 213 break; 214 case 'a': 215 debug |= DEBUG_ARCH; 216 break; 217 case 'C': 218 debug |= DEBUG_CWD; 219 break; 220 case 'c': 221 debug |= DEBUG_COND; 222 break; 223 case 'd': 224 debug |= DEBUG_DIR; 225 break; 226 case 'e': 227 debug |= DEBUG_ERROR; 228 break; 229 case 'f': 230 debug |= DEBUG_FOR; 231 break; 232 case 'g': 233 if (modules[1] == '1') { 234 debug |= DEBUG_GRAPH1; 235 ++modules; 236 } 237 else if (modules[1] == '2') { 238 debug |= DEBUG_GRAPH2; 239 ++modules; 240 } 241 else if (modules[1] == '3') { 242 debug |= DEBUG_GRAPH3; 243 ++modules; 244 } 245 break; 246 case 'j': 247 debug |= DEBUG_JOB; 248 break; 249 case 'l': 250 debug |= DEBUG_LOUD; 251 break; 252 case 'M': 253 debug |= DEBUG_META; 254 break; 255 case 'm': 256 debug |= DEBUG_MAKE; 257 break; 258 case 'n': 259 debug |= DEBUG_SCRIPT; 260 break; 261 case 'p': 262 debug |= DEBUG_PARSE; 263 break; 264 case 's': 265 debug |= DEBUG_SUFF; 266 break; 267 case 't': 268 debug |= DEBUG_TARG; 269 break; 270 case 'V': 271 debugVflag = TRUE; 272 break; 273 case 'v': 274 debug |= DEBUG_VAR; 275 break; 276 case 'x': 277 debug |= DEBUG_SHELL; 278 break; 279 case 'F': 280 if (debug_file != stdout && debug_file != stderr) 281 fclose(debug_file); 282 if (*++modules == '+') { 283 modules++; 284 mode = "a"; 285 } else 286 mode = "w"; 287 if (strcmp(modules, "stdout") == 0) { 288 debug_file = stdout; 289 goto debug_setbuf; 290 } 291 if (strcmp(modules, "stderr") == 0) { 292 debug_file = stderr; 293 goto debug_setbuf; 294 } 295 len = strlen(modules); 296 fname = malloc(len + 20); 297 memcpy(fname, modules, len + 1); 298 /* Let the filename be modified by the pid */ 299 if (strcmp(fname + len - 3, ".%d") == 0) 300 snprintf(fname + len - 2, 20, "%d", getpid()); 301 debug_file = fopen(fname, mode); 302 if (!debug_file) { 303 fprintf(stderr, "Cannot open debug file %s\n", 304 fname); 305 usage(); 306 } 307 free(fname); 308 goto debug_setbuf; 309 default: 310 (void)fprintf(stderr, 311 "%s: illegal argument to d option -- %c\n", 312 progname, *modules); 313 usage(); 314 } 315 } 316 debug_setbuf: 317 /* 318 * Make the debug_file unbuffered, and make 319 * stdout line buffered (unless debugfile == stdout). 320 */ 321 setvbuf(debug_file, NULL, _IONBF, 0); 322 if (debug_file != stdout) { 323 setvbuf(stdout, NULL, _IOLBF, 0); 324 } 325 } 326 327 /*- 328 * MainParseArgs -- 329 * Parse a given argument vector. Called from main() and from 330 * Main_ParseArgLine() when the .MAKEFLAGS target is used. 331 * 332 * XXX: Deal with command line overriding .MAKEFLAGS in makefile 333 * 334 * Results: 335 * None 336 * 337 * Side Effects: 338 * Various global and local flags will be set depending on the flags 339 * given 340 */ 341 static void 342 MainParseArgs(int argc, char **argv) 343 { 344 char *p; 345 int c = '?'; 346 int arginc; 347 char *argvalue; 348 const char *getopt_def; 349 char *optscan; 350 Boolean inOption, dashDash = FALSE; 351 char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */ 352 353 #define OPTFLAGS "BC:D:I:J:NST:V:WXd:ef:ij:km:nqrst" 354 /* Can't actually use getopt(3) because rescanning is not portable */ 355 356 getopt_def = OPTFLAGS; 357 rearg: 358 inOption = FALSE; 359 optscan = NULL; 360 while(argc > 1) { 361 char *getopt_spec; 362 if(!inOption) 363 optscan = argv[1]; 364 c = *optscan++; 365 arginc = 0; 366 if(inOption) { 367 if(c == '\0') { 368 ++argv; 369 --argc; 370 inOption = FALSE; 371 continue; 372 } 373 } else { 374 if (c != '-' || dashDash) 375 break; 376 inOption = TRUE; 377 c = *optscan++; 378 } 379 /* '-' found at some earlier point */ 380 getopt_spec = strchr(getopt_def, c); 381 if(c != '\0' && getopt_spec != NULL && getopt_spec[1] == ':') { 382 /* -<something> found, and <something> should have an arg */ 383 inOption = FALSE; 384 arginc = 1; 385 argvalue = optscan; 386 if(*argvalue == '\0') { 387 if (argc < 3) 388 goto noarg; 389 argvalue = argv[2]; 390 arginc = 2; 391 } 392 } else { 393 argvalue = NULL; 394 } 395 switch(c) { 396 case '\0': 397 arginc = 1; 398 inOption = FALSE; 399 break; 400 case 'B': 401 compatMake = TRUE; 402 Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL); 403 Var_Set(MAKE_MODE, "compat", VAR_GLOBAL, 0); 404 break; 405 case 'C': 406 if (chdir(argvalue) == -1) { 407 (void)fprintf(stderr, 408 "%s: chdir %s: %s\n", 409 progname, argvalue, 410 strerror(errno)); 411 exit(1); 412 } 413 if (getcwd(curdir, MAXPATHLEN) == NULL) { 414 (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno)); 415 exit(2); 416 } 417 ignorePWD = TRUE; 418 break; 419 case 'D': 420 if (argvalue == NULL || argvalue[0] == 0) goto noarg; 421 Var_Set(argvalue, "1", VAR_GLOBAL, 0); 422 Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL); 423 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); 424 break; 425 case 'I': 426 if (argvalue == NULL) goto noarg; 427 Parse_AddIncludeDir(argvalue); 428 Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL); 429 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); 430 break; 431 case 'J': 432 if (argvalue == NULL) goto noarg; 433 if (sscanf(argvalue, "%d,%d", &jp_0, &jp_1) != 2) { 434 (void)fprintf(stderr, 435 "%s: internal error -- J option malformed (%s)\n", 436 progname, argvalue); 437 usage(); 438 } 439 if ((fcntl(jp_0, F_GETFD, 0) < 0) || 440 (fcntl(jp_1, F_GETFD, 0) < 0)) { 441 #if 0 442 (void)fprintf(stderr, 443 "%s: ###### warning -- J descriptors were closed!\n", 444 progname); 445 exit(2); 446 #endif 447 jp_0 = -1; 448 jp_1 = -1; 449 compatMake = TRUE; 450 } else { 451 Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL); 452 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); 453 jobServer = TRUE; 454 } 455 break; 456 case 'N': 457 noExecute = TRUE; 458 noRecursiveExecute = TRUE; 459 Var_Append(MAKEFLAGS, "-N", VAR_GLOBAL); 460 break; 461 case 'S': 462 keepgoing = FALSE; 463 Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL); 464 break; 465 case 'T': 466 if (argvalue == NULL) goto noarg; 467 tracefile = bmake_strdup(argvalue); 468 Var_Append(MAKEFLAGS, "-T", VAR_GLOBAL); 469 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); 470 break; 471 case 'V': 472 if (argvalue == NULL) goto noarg; 473 printVars = TRUE; 474 (void)Lst_AtEnd(variables, argvalue); 475 Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL); 476 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); 477 break; 478 case 'W': 479 parseWarnFatal = TRUE; 480 break; 481 case 'X': 482 varNoExportEnv = TRUE; 483 Var_Append(MAKEFLAGS, "-X", VAR_GLOBAL); 484 break; 485 case 'd': 486 if (argvalue == NULL) goto noarg; 487 /* If '-d-opts' don't pass to children */ 488 if (argvalue[0] == '-') 489 argvalue++; 490 else { 491 Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL); 492 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); 493 } 494 parse_debug_options(argvalue); 495 break; 496 case 'e': 497 checkEnvFirst = TRUE; 498 Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL); 499 break; 500 case 'f': 501 if (argvalue == NULL) goto noarg; 502 (void)Lst_AtEnd(makefiles, argvalue); 503 break; 504 case 'i': 505 ignoreErrors = TRUE; 506 Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL); 507 break; 508 case 'j': 509 if (argvalue == NULL) goto noarg; 510 forceJobs = TRUE; 511 maxJobs = strtol(argvalue, &p, 0); 512 if (*p != '\0' || maxJobs < 1) { 513 (void)fprintf(stderr, "%s: illegal argument to -j -- must be positive integer!\n", 514 progname); 515 exit(1); 516 } 517 Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL); 518 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); 519 Var_Set(".MAKE.JOBS", argvalue, VAR_GLOBAL, 0); 520 maxJobTokens = maxJobs; 521 break; 522 case 'k': 523 keepgoing = TRUE; 524 Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL); 525 break; 526 case 'm': 527 if (argvalue == NULL) goto noarg; 528 /* look for magic parent directory search string */ 529 if (strncmp(".../", argvalue, 4) == 0) { 530 if (!Dir_FindHereOrAbove(curdir, argvalue+4, 531 found_path, sizeof(found_path))) 532 break; /* nothing doing */ 533 (void)Dir_AddDir(sysIncPath, found_path); 534 } else { 535 (void)Dir_AddDir(sysIncPath, argvalue); 536 } 537 Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL); 538 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); 539 break; 540 case 'n': 541 noExecute = TRUE; 542 Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL); 543 break; 544 case 'q': 545 queryFlag = TRUE; 546 /* Kind of nonsensical, wot? */ 547 Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL); 548 break; 549 case 'r': 550 noBuiltins = TRUE; 551 Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL); 552 break; 553 case 's': 554 beSilent = TRUE; 555 Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL); 556 break; 557 case 't': 558 touchFlag = TRUE; 559 Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL); 560 break; 561 case '-': 562 dashDash = TRUE; 563 break; 564 default: 565 case '?': 566 #ifndef MAKE_NATIVE 567 fprintf(stderr, "getopt(%s) -> %d (%c)\n", 568 OPTFLAGS, c, c); 569 #endif 570 usage(); 571 } 572 argv += arginc; 573 argc -= arginc; 574 } 575 576 oldVars = TRUE; 577 578 /* 579 * See if the rest of the arguments are variable assignments and 580 * perform them if so. Else take them to be targets and stuff them 581 * on the end of the "create" list. 582 */ 583 for (; argc > 1; ++argv, --argc) 584 if (Parse_IsVar(argv[1])) { 585 Parse_DoVar(argv[1], VAR_CMD); 586 } else { 587 if (!*argv[1]) 588 Punt("illegal (null) argument."); 589 if (*argv[1] == '-' && !dashDash) 590 goto rearg; 591 (void)Lst_AtEnd(create, bmake_strdup(argv[1])); 592 } 593 594 return; 595 noarg: 596 (void)fprintf(stderr, "%s: option requires an argument -- %c\n", 597 progname, c); 598 usage(); 599 } 600 601 /*- 602 * Main_ParseArgLine -- 603 * Used by the parse module when a .MFLAGS or .MAKEFLAGS target 604 * is encountered and by main() when reading the .MAKEFLAGS envariable. 605 * Takes a line of arguments and breaks it into its 606 * component words and passes those words and the number of them to the 607 * MainParseArgs function. 608 * The line should have all its leading whitespace removed. 609 * 610 * Input: 611 * line Line to fracture 612 * 613 * Results: 614 * None 615 * 616 * Side Effects: 617 * Only those that come from the various arguments. 618 */ 619 void 620 Main_ParseArgLine(const char *line) 621 { 622 char **argv; /* Manufactured argument vector */ 623 int argc; /* Number of arguments in argv */ 624 char *args; /* Space used by the args */ 625 char *buf, *p1; 626 char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &p1); 627 size_t len; 628 629 if (line == NULL) 630 return; 631 for (; *line == ' '; ++line) 632 continue; 633 if (!*line) 634 return; 635 636 #ifndef POSIX 637 { 638 /* 639 * $MAKE may simply be naming the make(1) binary 640 */ 641 char *cp; 642 643 if (!(cp = strrchr(line, '/'))) 644 cp = line; 645 if ((cp = strstr(cp, "make")) && 646 strcmp(cp, "make") == 0) 647 return; 648 } 649 #endif 650 buf = bmake_malloc(len = strlen(line) + strlen(argv0) + 2); 651 (void)snprintf(buf, len, "%s %s", argv0, line); 652 if (p1) 653 free(p1); 654 655 argv = brk_string(buf, &argc, TRUE, &args); 656 if (argv == NULL) { 657 Error("Unterminated quoted string [%s]", buf); 658 free(buf); 659 return; 660 } 661 free(buf); 662 MainParseArgs(argc, argv); 663 664 free(args); 665 free(argv); 666 } 667 668 Boolean 669 Main_SetObjdir(const char *path) 670 { 671 struct stat sb; 672 char *p = NULL; 673 char buf[MAXPATHLEN + 1]; 674 Boolean rc = FALSE; 675 676 /* expand variable substitutions */ 677 if (strchr(path, '$') != 0) { 678 snprintf(buf, MAXPATHLEN, "%s", path); 679 path = p = Var_Subst(NULL, buf, VAR_GLOBAL, 0); 680 } 681 682 if (path[0] != '/') { 683 snprintf(buf, MAXPATHLEN, "%s/%s", curdir, path); 684 path = buf; 685 } 686 687 /* look for the directory and try to chdir there */ 688 if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { 689 if (chdir(path)) { 690 (void)fprintf(stderr, "make warning: %s: %s.\n", 691 path, strerror(errno)); 692 } else { 693 strncpy(objdir, path, MAXPATHLEN); 694 Var_Set(".OBJDIR", objdir, VAR_GLOBAL, 0); 695 setenv("PWD", objdir, 1); 696 Dir_InitDot(); 697 rc = TRUE; 698 } 699 } 700 701 if (p) 702 free(p); 703 return rc; 704 } 705 706 /*- 707 * ReadAllMakefiles -- 708 * wrapper around ReadMakefile() to read all. 709 * 710 * Results: 711 * TRUE if ok, FALSE on error 712 */ 713 static int 714 ReadAllMakefiles(const void *p, const void *q) 715 { 716 return (ReadMakefile(p, q) == 0); 717 } 718 719 int 720 str2Lst_Append(Lst lp, char *str, const char *sep) 721 { 722 char *cp; 723 int n; 724 725 if (!sep) 726 sep = " \t"; 727 728 for (n = 0, cp = strtok(str, sep); cp; cp = strtok(NULL, sep)) { 729 (void)Lst_AtEnd(lp, cp); 730 n++; 731 } 732 return (n); 733 } 734 735 #ifdef SIGINFO 736 /*ARGSUSED*/ 737 static void 738 siginfo(int signo MAKE_ATTR_UNUSED) 739 { 740 char dir[MAXPATHLEN]; 741 char str[2 * MAXPATHLEN]; 742 int len; 743 if (getcwd(dir, sizeof(dir)) == NULL) 744 return; 745 len = snprintf(str, sizeof(str), "%s: Working in: %s\n", progname, dir); 746 if (len > 0) 747 (void)write(STDERR_FILENO, str, (size_t)len); 748 } 749 #endif 750 751 /* 752 * Allow makefiles some control over the mode we run in. 753 */ 754 void 755 MakeMode(const char *mode) 756 { 757 char *mp = NULL; 758 759 if (!mode) 760 mode = mp = Var_Subst(NULL, "${" MAKE_MODE ":tl}", VAR_GLOBAL, 0); 761 762 if (mode && *mode) { 763 if (strstr(mode, "compat")) { 764 compatMake = TRUE; 765 forceJobs = FALSE; 766 } 767 #if USE_META 768 if (strstr(mode, "meta")) 769 meta_mode_init(mode); 770 #endif 771 } 772 if (mp) 773 free(mp); 774 } 775 776 /*- 777 * main -- 778 * The main function, for obvious reasons. Initializes variables 779 * and a few modules, then parses the arguments give it in the 780 * environment and on the command line. Reads the system makefile 781 * followed by either Makefile, makefile or the file given by the 782 * -f argument. Sets the .MAKEFLAGS PMake variable based on all the 783 * flags it has received by then uses either the Make or the Compat 784 * module to create the initial list of targets. 785 * 786 * Results: 787 * If -q was given, exits -1 if anything was out-of-date. Else it exits 788 * 0. 789 * 790 * Side Effects: 791 * The program exits when done. Targets are created. etc. etc. etc. 792 */ 793 int 794 main(int argc, char **argv) 795 { 796 Lst targs; /* target nodes to create -- passed to Make_Init */ 797 Boolean outOfDate = FALSE; /* FALSE if all targets up to date */ 798 struct stat sb, sa; 799 char *p1, *path, *pwd; 800 char mdpath[MAXPATHLEN]; 801 #ifdef FORCE_MACHINE 802 const char *machine = FORCE_MACHINE; 803 #else 804 const char *machine = getenv("MACHINE"); 805 #endif 806 const char *machine_arch = getenv("MACHINE_ARCH"); 807 char *syspath = getenv("MAKESYSPATH"); 808 Lst sysMkPath; /* Path of sys.mk */ 809 char *cp = NULL, *start; 810 /* avoid faults on read-only strings */ 811 static char defsyspath[] = _PATH_DEFSYSPATH; 812 char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */ 813 struct timeval rightnow; /* to initialize random seed */ 814 struct utsname utsname; 815 816 /* default to writing debug to stderr */ 817 debug_file = stderr; 818 819 #ifdef SIGINFO 820 (void)bmake_signal(SIGINFO, siginfo); 821 #endif 822 /* 823 * Set the seed to produce a different random sequence 824 * on each program execution. 825 */ 826 gettimeofday(&rightnow, NULL); 827 srandom(rightnow.tv_sec + rightnow.tv_usec); 828 829 if ((progname = strrchr(argv[0], '/')) != NULL) 830 progname++; 831 else 832 progname = argv[0]; 833 #if defined(MAKE_NATIVE) || (defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)) 834 /* 835 * get rid of resource limit on file descriptors 836 */ 837 { 838 struct rlimit rl; 839 if (getrlimit(RLIMIT_NOFILE, &rl) != -1 && 840 rl.rlim_cur != rl.rlim_max) { 841 rl.rlim_cur = rl.rlim_max; 842 (void)setrlimit(RLIMIT_NOFILE, &rl); 843 } 844 } 845 #endif 846 847 if (uname(&utsname) == -1) { 848 (void)fprintf(stderr, "%s: uname failed (%s).\n", progname, 849 strerror(errno)); 850 exit(2); 851 } 852 853 /* 854 * Get the name of this type of MACHINE from utsname 855 * so we can share an executable for similar machines. 856 * (i.e. m68k: amiga hp300, mac68k, sun3, ...) 857 * 858 * Note that both MACHINE and MACHINE_ARCH are decided at 859 * run-time. 860 */ 861 if (!machine) { 862 #ifdef MAKE_NATIVE 863 machine = utsname.machine; 864 #else 865 #ifdef MAKE_MACHINE 866 machine = MAKE_MACHINE; 867 #else 868 machine = "unknown"; 869 #endif 870 #endif 871 } 872 873 if (!machine_arch) { 874 #ifndef MACHINE_ARCH 875 #ifdef MAKE_MACHINE_ARCH 876 machine_arch = MAKE_MACHINE_ARCH; 877 #else 878 machine_arch = "unknown"; 879 #endif 880 #else 881 machine_arch = MACHINE_ARCH; 882 #endif 883 } 884 885 myPid = getpid(); /* remember this for vFork() */ 886 887 /* 888 * Just in case MAKEOBJDIR wants us to do something tricky. 889 */ 890 Var_Init(); /* Initialize the lists of variables for 891 * parsing arguments */ 892 Var_Set(".MAKE.OS", utsname.sysname, VAR_GLOBAL, 0); 893 Var_Set("MACHINE", machine, VAR_GLOBAL, 0); 894 Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL, 0); 895 #ifdef MAKE_VERSION 896 Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL, 0); 897 #endif 898 Var_Set(".newline", "\n", VAR_GLOBAL, 0); /* handy for :@ loops */ 899 /* 900 * This is the traditional preference for makefiles. 901 */ 902 #ifndef MAKEFILE_PREFERENCE_LIST 903 # define MAKEFILE_PREFERENCE_LIST "makefile Makefile" 904 #endif 905 Var_Set(MAKEFILE_PREFERENCE, MAKEFILE_PREFERENCE_LIST, 906 VAR_GLOBAL, 0); 907 Var_Set(MAKE_DEPENDFILE, ".depend", VAR_GLOBAL, 0); 908 909 create = Lst_Init(FALSE); 910 makefiles = Lst_Init(FALSE); 911 printVars = FALSE; 912 debugVflag = FALSE; 913 variables = Lst_Init(FALSE); 914 beSilent = FALSE; /* Print commands as executed */ 915 ignoreErrors = FALSE; /* Pay attention to non-zero returns */ 916 noExecute = FALSE; /* Execute all commands */ 917 noRecursiveExecute = FALSE; /* Execute all .MAKE targets */ 918 keepgoing = FALSE; /* Stop on error */ 919 allPrecious = FALSE; /* Remove targets when interrupted */ 920 queryFlag = FALSE; /* This is not just a check-run */ 921 noBuiltins = FALSE; /* Read the built-in rules */ 922 touchFlag = FALSE; /* Actually update targets */ 923 debug = 0; /* No debug verbosity, please. */ 924 jobsRunning = FALSE; 925 926 maxJobs = DEFMAXLOCAL; /* Set default local max concurrency */ 927 maxJobTokens = maxJobs; 928 compatMake = FALSE; /* No compat mode */ 929 ignorePWD = FALSE; 930 931 /* 932 * Initialize the parsing, directory and variable modules to prepare 933 * for the reading of inclusion paths and variable settings on the 934 * command line 935 */ 936 937 /* 938 * Initialize various variables. 939 * MAKE also gets this name, for compatibility 940 * .MAKEFLAGS gets set to the empty string just in case. 941 * MFLAGS also gets initialized empty, for compatibility. 942 */ 943 Parse_Init(); 944 if (argv[0][0] == '/' || strchr(argv[0], '/') == NULL) { 945 /* 946 * Leave alone if it is an absolute path, or if it does 947 * not contain a '/' in which case we need to find it in 948 * the path, like execvp(3) and the shells do. 949 */ 950 p1 = argv[0]; 951 } else { 952 /* 953 * A relative path, canonicalize it. 954 */ 955 p1 = realpath(argv[0], mdpath); 956 if (!p1 || *p1 != '/' || stat(p1, &sb) < 0) { 957 p1 = argv[0]; /* realpath failed */ 958 } 959 } 960 Var_Set("MAKE", p1, VAR_GLOBAL, 0); 961 Var_Set(".MAKE", p1, VAR_GLOBAL, 0); 962 Var_Set(MAKEFLAGS, "", VAR_GLOBAL, 0); 963 Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL, 0); 964 Var_Set("MFLAGS", "", VAR_GLOBAL, 0); 965 Var_Set(".ALLTARGETS", "", VAR_GLOBAL, 0); 966 967 /* 968 * Set some other useful macros 969 */ 970 { 971 char tmp[64]; 972 const char *ep; 973 974 if (!(ep = getenv(MAKE_LEVEL))) { 975 #ifdef MAKE_LEVEL_SAFE 976 if (!(ep = getenv(MAKE_LEVEL_SAFE))) 977 #endif 978 ep = "0"; 979 } 980 Var_Set(MAKE_LEVEL, ep, VAR_GLOBAL, 0); 981 snprintf(tmp, sizeof(tmp), "%u", myPid); 982 Var_Set(".MAKE.PID", tmp, VAR_GLOBAL, 0); 983 snprintf(tmp, sizeof(tmp), "%u", getppid()); 984 Var_Set(".MAKE.PPID", tmp, VAR_GLOBAL, 0); 985 } 986 Job_SetPrefix(); 987 988 #ifdef USE_META 989 meta_init(); 990 #endif 991 /* 992 * First snag any flags out of the MAKE environment variable. 993 * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's 994 * in a different format). 995 */ 996 #ifdef POSIX 997 Main_ParseArgLine(getenv("MAKEFLAGS")); 998 #else 999 Main_ParseArgLine(getenv("MAKE")); 1000 #endif 1001 1002 /* 1003 * Find where we are (now). 1004 * We take care of PWD for the automounter below... 1005 */ 1006 if (getcwd(curdir, MAXPATHLEN) == NULL) { 1007 (void)fprintf(stderr, "%s: getcwd: %s.\n", 1008 progname, strerror(errno)); 1009 exit(2); 1010 } 1011 1012 MainParseArgs(argc, argv); 1013 1014 /* 1015 * Verify that cwd is sane. 1016 */ 1017 if (stat(curdir, &sa) == -1) { 1018 (void)fprintf(stderr, "%s: %s: %s.\n", 1019 progname, curdir, strerror(errno)); 1020 exit(2); 1021 } 1022 1023 /* 1024 * All this code is so that we know where we are when we start up 1025 * on a different machine with pmake. 1026 * Overriding getcwd() with $PWD totally breaks MAKEOBJDIRPREFIX 1027 * since the value of curdir can vary depending on how we got 1028 * here. Ie sitting at a shell prompt (shell that provides $PWD) 1029 * or via subdir.mk in which case its likely a shell which does 1030 * not provide it. 1031 * So, to stop it breaking this case only, we ignore PWD if 1032 * MAKEOBJDIRPREFIX is set or MAKEOBJDIR contains a transform. 1033 */ 1034 #ifndef NO_PWD_OVERRIDE 1035 if (!ignorePWD && 1036 (pwd = getenv("PWD")) != NULL && 1037 getenv("MAKEOBJDIRPREFIX") == NULL) { 1038 const char *makeobjdir = getenv("MAKEOBJDIR"); 1039 1040 if (makeobjdir == NULL || !strchr(makeobjdir, '$')) { 1041 if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino && 1042 sa.st_dev == sb.st_dev) 1043 (void)strncpy(curdir, pwd, MAXPATHLEN); 1044 } 1045 } 1046 #endif 1047 Var_Set(".CURDIR", curdir, VAR_GLOBAL, 0); 1048 1049 /* 1050 * Find the .OBJDIR. If MAKEOBJDIRPREFIX, or failing that, 1051 * MAKEOBJDIR is set in the environment, try only that value 1052 * and fall back to .CURDIR if it does not exist. 1053 * 1054 * Otherwise, try _PATH_OBJDIR.MACHINE, _PATH_OBJDIR, and 1055 * finally _PATH_OBJDIRPREFIX`pwd`, in that order. If none 1056 * of these paths exist, just use .CURDIR. 1057 */ 1058 Dir_Init(curdir); 1059 (void)Main_SetObjdir(curdir); 1060 1061 if ((path = getenv("MAKEOBJDIRPREFIX")) != NULL) { 1062 (void)snprintf(mdpath, MAXPATHLEN, "%s%s", path, curdir); 1063 (void)Main_SetObjdir(mdpath); 1064 } else if ((path = getenv("MAKEOBJDIR")) != NULL) { 1065 (void)Main_SetObjdir(path); 1066 } else { 1067 (void)snprintf(mdpath, MAXPATHLEN, "%s.%s", _PATH_OBJDIR, machine); 1068 if (!Main_SetObjdir(mdpath) && !Main_SetObjdir(_PATH_OBJDIR)) { 1069 (void)snprintf(mdpath, MAXPATHLEN, "%s%s", 1070 _PATH_OBJDIRPREFIX, curdir); 1071 (void)Main_SetObjdir(mdpath); 1072 } 1073 } 1074 1075 /* 1076 * Be compatible if user did not specify -j and did not explicitly 1077 * turned compatibility on 1078 */ 1079 if (!compatMake && !forceJobs) { 1080 compatMake = TRUE; 1081 } 1082 1083 /* 1084 * Initialize archive, target and suffix modules in preparation for 1085 * parsing the makefile(s) 1086 */ 1087 Arch_Init(); 1088 Targ_Init(); 1089 Suff_Init(); 1090 Trace_Init(tracefile); 1091 1092 DEFAULT = NULL; 1093 (void)time(&now); 1094 1095 Trace_Log(MAKESTART, NULL); 1096 1097 /* 1098 * Set up the .TARGETS variable to contain the list of targets to be 1099 * created. If none specified, make the variable empty -- the parser 1100 * will fill the thing in with the default or .MAIN target. 1101 */ 1102 if (!Lst_IsEmpty(create)) { 1103 LstNode ln; 1104 1105 for (ln = Lst_First(create); ln != NULL; 1106 ln = Lst_Succ(ln)) { 1107 char *name = (char *)Lst_Datum(ln); 1108 1109 Var_Append(".TARGETS", name, VAR_GLOBAL); 1110 } 1111 } else 1112 Var_Set(".TARGETS", "", VAR_GLOBAL, 0); 1113 1114 1115 /* 1116 * If no user-supplied system path was given (through the -m option) 1117 * add the directories from the DEFSYSPATH (more than one may be given 1118 * as dir1:...:dirn) to the system include path. 1119 */ 1120 if (syspath == NULL || *syspath == '\0') 1121 syspath = defsyspath; 1122 else 1123 syspath = bmake_strdup(syspath); 1124 1125 for (start = syspath; *start != '\0'; start = cp) { 1126 for (cp = start; *cp != '\0' && *cp != ':'; cp++) 1127 continue; 1128 if (*cp == ':') { 1129 *cp++ = '\0'; 1130 } 1131 /* look for magic parent directory search string */ 1132 if (strncmp(".../", start, 4) != 0) { 1133 (void)Dir_AddDir(defIncPath, start); 1134 } else { 1135 if (Dir_FindHereOrAbove(curdir, start+4, 1136 found_path, sizeof(found_path))) { 1137 (void)Dir_AddDir(defIncPath, found_path); 1138 } 1139 } 1140 } 1141 if (syspath != defsyspath) 1142 free(syspath); 1143 1144 /* 1145 * Read in the built-in rules first, followed by the specified 1146 * makefile, if it was (makefile != NULL), or the default 1147 * makefile and Makefile, in that order, if it wasn't. 1148 */ 1149 if (!noBuiltins) { 1150 LstNode ln; 1151 1152 sysMkPath = Lst_Init(FALSE); 1153 Dir_Expand(_PATH_DEFSYSMK, 1154 Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath, 1155 sysMkPath); 1156 if (Lst_IsEmpty(sysMkPath)) 1157 Fatal("%s: no system rules (%s).", progname, 1158 _PATH_DEFSYSMK); 1159 ln = Lst_Find(sysMkPath, NULL, ReadMakefile); 1160 if (ln == NULL) 1161 Fatal("%s: cannot open %s.", progname, 1162 (char *)Lst_Datum(ln)); 1163 } 1164 1165 if (!Lst_IsEmpty(makefiles)) { 1166 LstNode ln; 1167 1168 ln = Lst_Find(makefiles, NULL, ReadAllMakefiles); 1169 if (ln != NULL) 1170 Fatal("%s: cannot open %s.", progname, 1171 (char *)Lst_Datum(ln)); 1172 } else { 1173 p1 = Var_Subst(NULL, "${" MAKEFILE_PREFERENCE "}", 1174 VAR_CMD, 0); 1175 if (p1) { 1176 (void)str2Lst_Append(makefiles, p1, NULL); 1177 (void)Lst_Find(makefiles, NULL, ReadMakefile); 1178 free(p1); 1179 } 1180 } 1181 1182 /* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */ 1183 if (!noBuiltins || !printVars) { 1184 makeDependfile = Var_Subst(NULL, "${.MAKE.DEPENDFILE:T}", 1185 VAR_CMD, 0); 1186 doing_depend = TRUE; 1187 (void)ReadMakefile(makeDependfile, NULL); 1188 doing_depend = FALSE; 1189 } 1190 1191 MakeMode(NULL); 1192 1193 Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL); 1194 if (p1) 1195 free(p1); 1196 1197 if (!compatMake) 1198 Job_ServerStart(maxJobTokens, jp_0, jp_1); 1199 if (DEBUG(JOB)) 1200 fprintf(debug_file, "job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n", 1201 jp_0, jp_1, maxJobs, maxJobTokens, compatMake); 1202 1203 Main_ExportMAKEFLAGS(TRUE); /* initial export */ 1204 1205 /* 1206 * For compatibility, look at the directories in the VPATH variable 1207 * and add them to the search path, if the variable is defined. The 1208 * variable's value is in the same format as the PATH envariable, i.e. 1209 * <directory>:<directory>:<directory>... 1210 */ 1211 if (Var_Exists("VPATH", VAR_CMD)) { 1212 char *vpath, savec; 1213 /* 1214 * GCC stores string constants in read-only memory, but 1215 * Var_Subst will want to write this thing, so store it 1216 * in an array 1217 */ 1218 static char VPATH[] = "${VPATH}"; 1219 1220 vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE); 1221 path = vpath; 1222 do { 1223 /* skip to end of directory */ 1224 for (cp = path; *cp != ':' && *cp != '\0'; cp++) 1225 continue; 1226 /* Save terminator character so know when to stop */ 1227 savec = *cp; 1228 *cp = '\0'; 1229 /* Add directory to search path */ 1230 (void)Dir_AddDir(dirSearchPath, path); 1231 *cp = savec; 1232 path = cp + 1; 1233 } while (savec == ':'); 1234 free(vpath); 1235 } 1236 1237 /* 1238 * Now that all search paths have been read for suffixes et al, it's 1239 * time to add the default search path to their lists... 1240 */ 1241 Suff_DoPaths(); 1242 1243 /* 1244 * Propagate attributes through :: dependency lists. 1245 */ 1246 Targ_Propagate(); 1247 1248 /* print the initial graph, if the user requested it */ 1249 if (DEBUG(GRAPH1)) 1250 Targ_PrintGraph(1); 1251 1252 /* print the values of any variables requested by the user */ 1253 if (printVars) { 1254 LstNode ln; 1255 Boolean expandVars; 1256 1257 if (debugVflag) 1258 expandVars = FALSE; 1259 else 1260 expandVars = getBoolean(".MAKE.EXPAND_VARIABLES", FALSE); 1261 for (ln = Lst_First(variables); ln != NULL; 1262 ln = Lst_Succ(ln)) { 1263 char *var = (char *)Lst_Datum(ln); 1264 char *value; 1265 1266 if (strchr(var, '$')) { 1267 value = p1 = Var_Subst(NULL, var, VAR_GLOBAL, 0); 1268 } else if (expandVars) { 1269 char tmp[128]; 1270 1271 if (snprintf(tmp, sizeof(tmp), "${%s}", var) >= (int)(sizeof(tmp))) 1272 Fatal("%s: variable name too big: %s", 1273 progname, var); 1274 value = p1 = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); 1275 } else { 1276 value = Var_Value(var, VAR_GLOBAL, &p1); 1277 } 1278 printf("%s\n", value ? value : ""); 1279 if (p1) 1280 free(p1); 1281 } 1282 } else { 1283 /* 1284 * Have now read the entire graph and need to make a list of 1285 * targets to create. If none was given on the command line, 1286 * we consult the parsing module to find the main target(s) 1287 * to create. 1288 */ 1289 if (Lst_IsEmpty(create)) 1290 targs = Parse_MainName(); 1291 else 1292 targs = Targ_FindList(create, TARG_CREATE); 1293 1294 if (!compatMake) { 1295 /* 1296 * Initialize job module before traversing the graph 1297 * now that any .BEGIN and .END targets have been read. 1298 * This is done only if the -q flag wasn't given 1299 * (to prevent the .BEGIN from being executed should 1300 * it exist). 1301 */ 1302 if (!queryFlag) { 1303 Job_Init(); 1304 jobsRunning = TRUE; 1305 } 1306 1307 /* Traverse the graph, checking on all the targets */ 1308 outOfDate = Make_Run(targs); 1309 } else { 1310 /* 1311 * Compat_Init will take care of creating all the 1312 * targets as well as initializing the module. 1313 */ 1314 Compat_Run(targs); 1315 } 1316 } 1317 1318 #ifdef CLEANUP 1319 Lst_Destroy(targs, NULL); 1320 Lst_Destroy(variables, NULL); 1321 Lst_Destroy(makefiles, NULL); 1322 Lst_Destroy(create, (FreeProc *)free); 1323 #endif 1324 1325 /* print the graph now it's been processed if the user requested it */ 1326 if (DEBUG(GRAPH2)) 1327 Targ_PrintGraph(2); 1328 1329 Trace_Log(MAKEEND, 0); 1330 1331 Suff_End(); 1332 Targ_End(); 1333 Arch_End(); 1334 Var_End(); 1335 Parse_End(); 1336 Dir_End(); 1337 Job_End(); 1338 Trace_End(); 1339 1340 return outOfDate ? 1 : 0; 1341 } 1342 1343 /*- 1344 * ReadMakefile -- 1345 * Open and parse the given makefile. 1346 * 1347 * Results: 1348 * 0 if ok. -1 if couldn't open file. 1349 * 1350 * Side Effects: 1351 * lots 1352 */ 1353 static int 1354 ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED) 1355 { 1356 const char *fname = p; /* makefile to read */ 1357 int fd; 1358 size_t len = MAXPATHLEN; 1359 char *name, *path = bmake_malloc(len); 1360 1361 if (!strcmp(fname, "-")) { 1362 Parse_File(NULL /*stdin*/, -1); 1363 Var_Set("MAKEFILE", "", VAR_GLOBAL, 0); 1364 } else { 1365 /* if we've chdir'd, rebuild the path name */ 1366 if (strcmp(curdir, objdir) && *fname != '/') { 1367 size_t plen = strlen(curdir) + strlen(fname) + 2; 1368 if (len < plen) 1369 path = bmake_realloc(path, len = 2 * plen); 1370 1371 (void)snprintf(path, len, "%s/%s", curdir, fname); 1372 fd = open(path, O_RDONLY); 1373 if (fd != -1) { 1374 fname = path; 1375 goto found; 1376 } 1377 1378 /* If curdir failed, try objdir (ala .depend) */ 1379 plen = strlen(objdir) + strlen(fname) + 2; 1380 if (len < plen) 1381 path = bmake_realloc(path, len = 2 * plen); 1382 (void)snprintf(path, len, "%s/%s", objdir, fname); 1383 fd = open(path, O_RDONLY); 1384 if (fd != -1) { 1385 fname = path; 1386 goto found; 1387 } 1388 } else { 1389 fd = open(fname, O_RDONLY); 1390 if (fd != -1) 1391 goto found; 1392 } 1393 /* look in -I and system include directories. */ 1394 name = Dir_FindFile(fname, parseIncPath); 1395 if (!name) 1396 name = Dir_FindFile(fname, 1397 Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath); 1398 if (!name || (fd = open(name, O_RDONLY)) == -1) { 1399 if (name) 1400 free(name); 1401 free(path); 1402 return(-1); 1403 } 1404 fname = name; 1405 /* 1406 * set the MAKEFILE variable desired by System V fans -- the 1407 * placement of the setting here means it gets set to the last 1408 * makefile specified, as it is set by SysV make. 1409 */ 1410 found: 1411 if (!doing_depend) 1412 Var_Set("MAKEFILE", fname, VAR_GLOBAL, 0); 1413 Parse_File(fname, fd); 1414 } 1415 free(path); 1416 return(0); 1417 } 1418 1419 1420 1421 /*- 1422 * Cmd_Exec -- 1423 * Execute the command in cmd, and return the output of that command 1424 * in a string. 1425 * 1426 * Results: 1427 * A string containing the output of the command, or the empty string 1428 * If errnum is not NULL, it contains the reason for the command failure 1429 * 1430 * Side Effects: 1431 * The string must be freed by the caller. 1432 */ 1433 char * 1434 Cmd_Exec(const char *cmd, const char **errnum) 1435 { 1436 const char *args[4]; /* Args for invoking the shell */ 1437 int fds[2]; /* Pipe streams */ 1438 int cpid; /* Child PID */ 1439 int pid; /* PID from wait() */ 1440 char *res; /* result */ 1441 WAIT_T status; /* command exit status */ 1442 Buffer buf; /* buffer to store the result */ 1443 char *cp; 1444 int cc; 1445 1446 1447 *errnum = NULL; 1448 1449 if (!shellName) 1450 Shell_Init(); 1451 /* 1452 * Set up arguments for shell 1453 */ 1454 args[0] = shellName; 1455 args[1] = "-c"; 1456 args[2] = cmd; 1457 args[3] = NULL; 1458 1459 /* 1460 * Open a pipe for fetching its output 1461 */ 1462 if (pipe(fds) == -1) { 1463 *errnum = "Couldn't create pipe for \"%s\""; 1464 goto bad; 1465 } 1466 1467 /* 1468 * Fork 1469 */ 1470 switch (cpid = vFork()) { 1471 case 0: 1472 /* 1473 * Close input side of pipe 1474 */ 1475 (void)close(fds[0]); 1476 1477 /* 1478 * Duplicate the output stream to the shell's output, then 1479 * shut the extra thing down. Note we don't fetch the error 1480 * stream...why not? Why? 1481 */ 1482 (void)dup2(fds[1], 1); 1483 (void)close(fds[1]); 1484 1485 Var_ExportVars(); 1486 1487 (void)execv(shellPath, UNCONST(args)); 1488 _exit(1); 1489 /*NOTREACHED*/ 1490 1491 case -1: 1492 *errnum = "Couldn't exec \"%s\""; 1493 goto bad; 1494 1495 default: 1496 /* 1497 * No need for the writing half 1498 */ 1499 (void)close(fds[1]); 1500 1501 Buf_Init(&buf, 0); 1502 1503 do { 1504 char result[BUFSIZ]; 1505 cc = read(fds[0], result, sizeof(result)); 1506 if (cc > 0) 1507 Buf_AddBytes(&buf, cc, result); 1508 } 1509 while (cc > 0 || (cc == -1 && errno == EINTR)); 1510 1511 /* 1512 * Close the input side of the pipe. 1513 */ 1514 (void)close(fds[0]); 1515 1516 /* 1517 * Wait for the process to exit. 1518 */ 1519 while(((pid = waitpid(cpid, &status, 0)) != cpid) && (pid >= 0)) { 1520 JobReapChild(pid, status, FALSE); 1521 continue; 1522 } 1523 cc = Buf_Size(&buf); 1524 res = Buf_Destroy(&buf, FALSE); 1525 1526 if (cc == 0) 1527 *errnum = "Couldn't read shell's output for \"%s\""; 1528 1529 if (WIFSIGNALED(status)) 1530 *errnum = "\"%s\" exited on a signal"; 1531 else if (WEXITSTATUS(status) != 0) 1532 *errnum = "\"%s\" returned non-zero status"; 1533 1534 /* 1535 * Null-terminate the result, convert newlines to spaces and 1536 * install it in the variable. 1537 */ 1538 res[cc] = '\0'; 1539 cp = &res[cc]; 1540 1541 if (cc > 0 && *--cp == '\n') { 1542 /* 1543 * A final newline is just stripped 1544 */ 1545 *cp-- = '\0'; 1546 } 1547 while (cp >= res) { 1548 if (*cp == '\n') { 1549 *cp = ' '; 1550 } 1551 cp--; 1552 } 1553 break; 1554 } 1555 return res; 1556 bad: 1557 res = bmake_malloc(1); 1558 *res = '\0'; 1559 return res; 1560 } 1561 1562 /*- 1563 * Error -- 1564 * Print an error message given its format. 1565 * 1566 * Results: 1567 * None. 1568 * 1569 * Side Effects: 1570 * The message is printed. 1571 */ 1572 /* VARARGS */ 1573 void 1574 Error(const char *fmt, ...) 1575 { 1576 va_list ap; 1577 FILE *err_file; 1578 1579 err_file = debug_file; 1580 if (err_file == stdout) 1581 err_file = stderr; 1582 (void)fflush(stdout); 1583 for (;;) { 1584 va_start(ap, fmt); 1585 fprintf(err_file, "%s: ", progname); 1586 (void)vfprintf(err_file, fmt, ap); 1587 va_end(ap); 1588 (void)fprintf(err_file, "\n"); 1589 (void)fflush(err_file); 1590 if (err_file == stderr) 1591 break; 1592 err_file = stderr; 1593 } 1594 } 1595 1596 /*- 1597 * Fatal -- 1598 * Produce a Fatal error message. If jobs are running, waits for them 1599 * to finish. 1600 * 1601 * Results: 1602 * None 1603 * 1604 * Side Effects: 1605 * The program exits 1606 */ 1607 /* VARARGS */ 1608 void 1609 Fatal(const char *fmt, ...) 1610 { 1611 va_list ap; 1612 1613 va_start(ap, fmt); 1614 if (jobsRunning) 1615 Job_Wait(); 1616 1617 (void)fflush(stdout); 1618 (void)vfprintf(stderr, fmt, ap); 1619 va_end(ap); 1620 (void)fprintf(stderr, "\n"); 1621 (void)fflush(stderr); 1622 1623 PrintOnError(NULL, NULL); 1624 1625 if (DEBUG(GRAPH2) || DEBUG(GRAPH3)) 1626 Targ_PrintGraph(2); 1627 Trace_Log(MAKEERROR, 0); 1628 exit(2); /* Not 1 so -q can distinguish error */ 1629 } 1630 1631 /* 1632 * Punt -- 1633 * Major exception once jobs are being created. Kills all jobs, prints 1634 * a message and exits. 1635 * 1636 * Results: 1637 * None 1638 * 1639 * Side Effects: 1640 * All children are killed indiscriminately and the program Lib_Exits 1641 */ 1642 /* VARARGS */ 1643 void 1644 Punt(const char *fmt, ...) 1645 { 1646 va_list ap; 1647 1648 va_start(ap, fmt); 1649 (void)fflush(stdout); 1650 (void)fprintf(stderr, "%s: ", progname); 1651 (void)vfprintf(stderr, fmt, ap); 1652 va_end(ap); 1653 (void)fprintf(stderr, "\n"); 1654 (void)fflush(stderr); 1655 1656 PrintOnError(NULL, NULL); 1657 1658 DieHorribly(); 1659 } 1660 1661 /*- 1662 * DieHorribly -- 1663 * Exit without giving a message. 1664 * 1665 * Results: 1666 * None 1667 * 1668 * Side Effects: 1669 * A big one... 1670 */ 1671 void 1672 DieHorribly(void) 1673 { 1674 if (jobsRunning) 1675 Job_AbortAll(); 1676 if (DEBUG(GRAPH2)) 1677 Targ_PrintGraph(2); 1678 Trace_Log(MAKEERROR, 0); 1679 exit(2); /* Not 1, so -q can distinguish error */ 1680 } 1681 1682 /* 1683 * Finish -- 1684 * Called when aborting due to errors in child shell to signal 1685 * abnormal exit. 1686 * 1687 * Results: 1688 * None 1689 * 1690 * Side Effects: 1691 * The program exits 1692 */ 1693 void 1694 Finish(int errors) 1695 /* number of errors encountered in Make_Make */ 1696 { 1697 Fatal("%d error%s", errors, errors == 1 ? "" : "s"); 1698 } 1699 1700 /* 1701 * eunlink -- 1702 * Remove a file carefully, avoiding directories. 1703 */ 1704 int 1705 eunlink(const char *file) 1706 { 1707 struct stat st; 1708 1709 if (lstat(file, &st) == -1) 1710 return -1; 1711 1712 if (S_ISDIR(st.st_mode)) { 1713 errno = EISDIR; 1714 return -1; 1715 } 1716 return unlink(file); 1717 } 1718 1719 /* 1720 * execError -- 1721 * Print why exec failed, avoiding stdio. 1722 */ 1723 void 1724 execError(const char *af, const char *av) 1725 { 1726 #ifdef USE_IOVEC 1727 int i = 0; 1728 struct iovec iov[8]; 1729 #define IOADD(s) \ 1730 (void)(iov[i].iov_base = UNCONST(s), \ 1731 iov[i].iov_len = strlen(iov[i].iov_base), \ 1732 i++) 1733 #else 1734 #define IOADD(s) (void)write(2, s, strlen(s)) 1735 #endif 1736 1737 IOADD(progname); 1738 IOADD(": "); 1739 IOADD(af); 1740 IOADD("("); 1741 IOADD(av); 1742 IOADD(") failed ("); 1743 IOADD(strerror(errno)); 1744 IOADD(")\n"); 1745 1746 #ifdef USE_IOVEC 1747 while (writev(2, iov, 8) == -1 && errno == EAGAIN) 1748 continue; 1749 #endif 1750 } 1751 1752 /* 1753 * usage -- 1754 * exit with usage message 1755 */ 1756 static void 1757 usage(void) 1758 { 1759 (void)fprintf(stderr, 1760 "usage: %s [-BeikNnqrstWX] \n\ 1761 [-C directory] [-D variable] [-d flags] [-f makefile]\n\ 1762 [-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]\n\ 1763 [-V variable] [variable=value] [target ...]\n", progname); 1764 exit(2); 1765 } 1766 1767 1768 int 1769 PrintAddr(void *a, void *b) 1770 { 1771 printf("%lx ", (unsigned long) a); 1772 return b ? 0 : 0; 1773 } 1774 1775 1776 1777 void 1778 PrintOnError(GNode *gn, const char *s) 1779 { 1780 static GNode *en = NULL; 1781 char tmp[64]; 1782 char *cp; 1783 1784 if (s) 1785 printf("%s", s); 1786 1787 printf("\n%s: stopped in %s\n", progname, curdir); 1788 1789 if (en) 1790 return; /* we've been here! */ 1791 if (gn) { 1792 /* 1793 * We can print this even if there is no .ERROR target. 1794 */ 1795 Var_Set(".ERROR_TARGET", gn->name, VAR_GLOBAL, 0); 1796 } 1797 strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}", 1798 sizeof(tmp) - 1); 1799 cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); 1800 if (cp) { 1801 if (*cp) 1802 printf("%s", cp); 1803 free(cp); 1804 } 1805 /* 1806 * Finally, see if there is a .ERROR target, and run it if so. 1807 */ 1808 en = Targ_FindNode(".ERROR", TARG_NOCREATE); 1809 if (en) { 1810 en->type |= OP_SPECIAL; 1811 Compat_Make(en, en); 1812 } 1813 } 1814 1815 void 1816 Main_ExportMAKEFLAGS(Boolean first) 1817 { 1818 static int once = 1; 1819 char tmp[64]; 1820 char *s; 1821 1822 if (once != first) 1823 return; 1824 once = 0; 1825 1826 strncpy(tmp, "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}", 1827 sizeof(tmp)); 1828 s = Var_Subst(NULL, tmp, VAR_CMD, 0); 1829 if (s && *s) { 1830 #ifdef POSIX 1831 setenv("MAKEFLAGS", s, 1); 1832 #else 1833 setenv("MAKE", s, 1); 1834 #endif 1835 } 1836 } 1837 1838 char * 1839 getTmpdir(void) 1840 { 1841 static char *tmpdir = NULL; 1842 1843 if (!tmpdir) { 1844 struct stat st; 1845 1846 /* 1847 * Honor $TMPDIR but only if it is valid. 1848 * Ensure it ends with /. 1849 */ 1850 tmpdir = Var_Subst(NULL, "${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL, 0); 1851 if (stat(tmpdir, &st) < 0 || !S_ISDIR(st.st_mode)) { 1852 free(tmpdir); 1853 tmpdir = bmake_strdup(_PATH_TMP); 1854 } 1855 } 1856 return tmpdir; 1857 } 1858 1859 /* 1860 * Create and open a temp file using "pattern". 1861 * If "fnamep" is provided set it to a copy of the filename created. 1862 * Otherwise unlink the file once open. 1863 */ 1864 int 1865 mkTempFile(const char *pattern, char **fnamep) 1866 { 1867 static char *tmpdir = NULL; 1868 char tfile[MAXPATHLEN]; 1869 int fd; 1870 1871 if (!pattern) 1872 pattern = TMPPAT; 1873 if (!tmpdir) 1874 tmpdir = getTmpdir(); 1875 if (pattern[0] == '/') { 1876 snprintf(tfile, sizeof(tfile), "%s", pattern); 1877 } else { 1878 snprintf(tfile, sizeof(tfile), "%s%s", tmpdir, pattern); 1879 } 1880 if ((fd = mkstemp(tfile)) < 0) 1881 Punt("Could not create temporary file %s: %s", tfile, strerror(errno)); 1882 if (fnamep) { 1883 *fnamep = bmake_strdup(tfile); 1884 } else { 1885 unlink(tfile); /* we just want the descriptor */ 1886 } 1887 return fd; 1888 } 1889 1890 1891 /* 1892 * Return a Boolean based on setting of a knob. 1893 * 1894 * If the knob is not set, the supplied default is the return value. 1895 * If set, anything that looks or smells like "No", "False", "Off", "0" etc, 1896 * is FALSE, otherwise TRUE. 1897 */ 1898 Boolean 1899 getBoolean(const char *name, Boolean bf) 1900 { 1901 char tmp[64]; 1902 char *cp; 1903 1904 if (snprintf(tmp, sizeof(tmp), "${%s:tl}", name) < (int)(sizeof(tmp))) { 1905 cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); 1906 1907 if (cp) { 1908 switch(*cp) { 1909 case '\0': /* not set - the default wins */ 1910 break; 1911 case '0': 1912 case 'f': 1913 case 'n': 1914 bf = FALSE; 1915 break; 1916 case 'o': 1917 switch (cp[1]) { 1918 case 'f': 1919 bf = FALSE; 1920 break; 1921 default: 1922 bf = TRUE; 1923 break; 1924 } 1925 break; 1926 default: 1927 bf = TRUE; 1928 break; 1929 } 1930 free(cp); 1931 } 1932 } 1933 return (bf); 1934 } 1935