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; 800 #ifndef NO_PWD_OVERRIDE 801 char *pwd; 802 #endif 803 char mdpath[MAXPATHLEN]; 804 #ifdef FORCE_MACHINE 805 const char *machine = FORCE_MACHINE; 806 #else 807 const char *machine = getenv("MACHINE"); 808 #endif 809 const char *machine_arch = getenv("MACHINE_ARCH"); 810 char *syspath = getenv("MAKESYSPATH"); 811 Lst sysMkPath; /* Path of sys.mk */ 812 char *cp = NULL, *start; 813 /* avoid faults on read-only strings */ 814 static char defsyspath[] = _PATH_DEFSYSPATH; 815 char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */ 816 struct timeval rightnow; /* to initialize random seed */ 817 struct utsname utsname; 818 819 /* default to writing debug to stderr */ 820 debug_file = stderr; 821 822 #ifdef SIGINFO 823 (void)bmake_signal(SIGINFO, siginfo); 824 #endif 825 /* 826 * Set the seed to produce a different random sequence 827 * on each program execution. 828 */ 829 gettimeofday(&rightnow, NULL); 830 srandom(rightnow.tv_sec + rightnow.tv_usec); 831 832 if ((progname = strrchr(argv[0], '/')) != NULL) 833 progname++; 834 else 835 progname = argv[0]; 836 #if defined(MAKE_NATIVE) || (defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)) 837 /* 838 * get rid of resource limit on file descriptors 839 */ 840 { 841 struct rlimit rl; 842 if (getrlimit(RLIMIT_NOFILE, &rl) != -1 && 843 rl.rlim_cur != rl.rlim_max) { 844 rl.rlim_cur = rl.rlim_max; 845 (void)setrlimit(RLIMIT_NOFILE, &rl); 846 } 847 } 848 #endif 849 850 if (uname(&utsname) == -1) { 851 (void)fprintf(stderr, "%s: uname failed (%s).\n", progname, 852 strerror(errno)); 853 exit(2); 854 } 855 856 /* 857 * Get the name of this type of MACHINE from utsname 858 * so we can share an executable for similar machines. 859 * (i.e. m68k: amiga hp300, mac68k, sun3, ...) 860 * 861 * Note that both MACHINE and MACHINE_ARCH are decided at 862 * run-time. 863 */ 864 if (!machine) { 865 #ifdef MAKE_NATIVE 866 machine = utsname.machine; 867 #else 868 #ifdef MAKE_MACHINE 869 machine = MAKE_MACHINE; 870 #else 871 machine = "unknown"; 872 #endif 873 #endif 874 } 875 876 if (!machine_arch) { 877 #ifndef MACHINE_ARCH 878 #ifdef MAKE_MACHINE_ARCH 879 machine_arch = MAKE_MACHINE_ARCH; 880 #else 881 machine_arch = "unknown"; 882 #endif 883 #else 884 machine_arch = MACHINE_ARCH; 885 #endif 886 } 887 888 myPid = getpid(); /* remember this for vFork() */ 889 890 /* 891 * Just in case MAKEOBJDIR wants us to do something tricky. 892 */ 893 Var_Init(); /* Initialize the lists of variables for 894 * parsing arguments */ 895 Var_Set(".MAKE.OS", utsname.sysname, VAR_GLOBAL, 0); 896 Var_Set("MACHINE", machine, VAR_GLOBAL, 0); 897 Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL, 0); 898 #ifdef MAKE_VERSION 899 Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL, 0); 900 #endif 901 Var_Set(".newline", "\n", VAR_GLOBAL, 0); /* handy for :@ loops */ 902 /* 903 * This is the traditional preference for makefiles. 904 */ 905 #ifndef MAKEFILE_PREFERENCE_LIST 906 # define MAKEFILE_PREFERENCE_LIST "makefile Makefile" 907 #endif 908 Var_Set(MAKEFILE_PREFERENCE, MAKEFILE_PREFERENCE_LIST, 909 VAR_GLOBAL, 0); 910 Var_Set(MAKE_DEPENDFILE, ".depend", VAR_GLOBAL, 0); 911 912 create = Lst_Init(FALSE); 913 makefiles = Lst_Init(FALSE); 914 printVars = FALSE; 915 debugVflag = FALSE; 916 variables = Lst_Init(FALSE); 917 beSilent = FALSE; /* Print commands as executed */ 918 ignoreErrors = FALSE; /* Pay attention to non-zero returns */ 919 noExecute = FALSE; /* Execute all commands */ 920 noRecursiveExecute = FALSE; /* Execute all .MAKE targets */ 921 keepgoing = FALSE; /* Stop on error */ 922 allPrecious = FALSE; /* Remove targets when interrupted */ 923 queryFlag = FALSE; /* This is not just a check-run */ 924 noBuiltins = FALSE; /* Read the built-in rules */ 925 touchFlag = FALSE; /* Actually update targets */ 926 debug = 0; /* No debug verbosity, please. */ 927 jobsRunning = FALSE; 928 929 maxJobs = DEFMAXLOCAL; /* Set default local max concurrency */ 930 maxJobTokens = maxJobs; 931 compatMake = FALSE; /* No compat mode */ 932 ignorePWD = FALSE; 933 934 /* 935 * Initialize the parsing, directory and variable modules to prepare 936 * for the reading of inclusion paths and variable settings on the 937 * command line 938 */ 939 940 /* 941 * Initialize various variables. 942 * MAKE also gets this name, for compatibility 943 * .MAKEFLAGS gets set to the empty string just in case. 944 * MFLAGS also gets initialized empty, for compatibility. 945 */ 946 Parse_Init(); 947 if (argv[0][0] == '/' || strchr(argv[0], '/') == NULL) { 948 /* 949 * Leave alone if it is an absolute path, or if it does 950 * not contain a '/' in which case we need to find it in 951 * the path, like execvp(3) and the shells do. 952 */ 953 p1 = argv[0]; 954 } else { 955 /* 956 * A relative path, canonicalize it. 957 */ 958 p1 = realpath(argv[0], mdpath); 959 if (!p1 || *p1 != '/' || stat(p1, &sb) < 0) { 960 p1 = argv[0]; /* realpath failed */ 961 } 962 } 963 Var_Set("MAKE", p1, VAR_GLOBAL, 0); 964 Var_Set(".MAKE", p1, VAR_GLOBAL, 0); 965 Var_Set(MAKEFLAGS, "", VAR_GLOBAL, 0); 966 Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL, 0); 967 Var_Set("MFLAGS", "", VAR_GLOBAL, 0); 968 Var_Set(".ALLTARGETS", "", VAR_GLOBAL, 0); 969 970 /* 971 * Set some other useful macros 972 */ 973 { 974 char tmp[64]; 975 const char *ep; 976 977 if (!(ep = getenv(MAKE_LEVEL))) { 978 #ifdef MAKE_LEVEL_SAFE 979 if (!(ep = getenv(MAKE_LEVEL_SAFE))) 980 #endif 981 ep = "0"; 982 } 983 Var_Set(MAKE_LEVEL, ep, VAR_GLOBAL, 0); 984 snprintf(tmp, sizeof(tmp), "%u", myPid); 985 Var_Set(".MAKE.PID", tmp, VAR_GLOBAL, 0); 986 snprintf(tmp, sizeof(tmp), "%u", getppid()); 987 Var_Set(".MAKE.PPID", tmp, VAR_GLOBAL, 0); 988 } 989 Job_SetPrefix(); 990 991 #ifdef USE_META 992 meta_init(); 993 #endif 994 /* 995 * First snag any flags out of the MAKE environment variable. 996 * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's 997 * in a different format). 998 */ 999 #ifdef POSIX 1000 Main_ParseArgLine(getenv("MAKEFLAGS")); 1001 #else 1002 Main_ParseArgLine(getenv("MAKE")); 1003 #endif 1004 1005 /* 1006 * Find where we are (now). 1007 * We take care of PWD for the automounter below... 1008 */ 1009 if (getcwd(curdir, MAXPATHLEN) == NULL) { 1010 (void)fprintf(stderr, "%s: getcwd: %s.\n", 1011 progname, strerror(errno)); 1012 exit(2); 1013 } 1014 1015 MainParseArgs(argc, argv); 1016 1017 /* 1018 * Verify that cwd is sane. 1019 */ 1020 if (stat(curdir, &sa) == -1) { 1021 (void)fprintf(stderr, "%s: %s: %s.\n", 1022 progname, curdir, strerror(errno)); 1023 exit(2); 1024 } 1025 1026 /* 1027 * All this code is so that we know where we are when we start up 1028 * on a different machine with pmake. 1029 * Overriding getcwd() with $PWD totally breaks MAKEOBJDIRPREFIX 1030 * since the value of curdir can vary depending on how we got 1031 * here. Ie sitting at a shell prompt (shell that provides $PWD) 1032 * or via subdir.mk in which case its likely a shell which does 1033 * not provide it. 1034 * So, to stop it breaking this case only, we ignore PWD if 1035 * MAKEOBJDIRPREFIX is set or MAKEOBJDIR contains a transform. 1036 */ 1037 #ifndef NO_PWD_OVERRIDE 1038 if (!ignorePWD && 1039 (pwd = getenv("PWD")) != NULL && 1040 getenv("MAKEOBJDIRPREFIX") == NULL) { 1041 const char *makeobjdir = getenv("MAKEOBJDIR"); 1042 1043 if (makeobjdir == NULL || !strchr(makeobjdir, '$')) { 1044 if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino && 1045 sa.st_dev == sb.st_dev) 1046 (void)strncpy(curdir, pwd, MAXPATHLEN); 1047 } 1048 } 1049 #endif 1050 Var_Set(".CURDIR", curdir, VAR_GLOBAL, 0); 1051 1052 /* 1053 * Find the .OBJDIR. If MAKEOBJDIRPREFIX, or failing that, 1054 * MAKEOBJDIR is set in the environment, try only that value 1055 * and fall back to .CURDIR if it does not exist. 1056 * 1057 * Otherwise, try _PATH_OBJDIR.MACHINE, _PATH_OBJDIR, and 1058 * finally _PATH_OBJDIRPREFIX`pwd`, in that order. If none 1059 * of these paths exist, just use .CURDIR. 1060 */ 1061 Dir_Init(curdir); 1062 (void)Main_SetObjdir(curdir); 1063 1064 if ((path = getenv("MAKEOBJDIRPREFIX")) != NULL) { 1065 (void)snprintf(mdpath, MAXPATHLEN, "%s%s", path, curdir); 1066 (void)Main_SetObjdir(mdpath); 1067 } else if ((path = getenv("MAKEOBJDIR")) != NULL) { 1068 (void)Main_SetObjdir(path); 1069 } else { 1070 (void)snprintf(mdpath, MAXPATHLEN, "%s.%s", _PATH_OBJDIR, machine); 1071 if (!Main_SetObjdir(mdpath) && !Main_SetObjdir(_PATH_OBJDIR)) { 1072 (void)snprintf(mdpath, MAXPATHLEN, "%s%s", 1073 _PATH_OBJDIRPREFIX, curdir); 1074 (void)Main_SetObjdir(mdpath); 1075 } 1076 } 1077 1078 /* 1079 * Be compatible if user did not specify -j and did not explicitly 1080 * turned compatibility on 1081 */ 1082 if (!compatMake && !forceJobs) { 1083 compatMake = TRUE; 1084 } 1085 1086 /* 1087 * Initialize archive, target and suffix modules in preparation for 1088 * parsing the makefile(s) 1089 */ 1090 Arch_Init(); 1091 Targ_Init(); 1092 Suff_Init(); 1093 Trace_Init(tracefile); 1094 1095 DEFAULT = NULL; 1096 (void)time(&now); 1097 1098 Trace_Log(MAKESTART, NULL); 1099 1100 /* 1101 * Set up the .TARGETS variable to contain the list of targets to be 1102 * created. If none specified, make the variable empty -- the parser 1103 * will fill the thing in with the default or .MAIN target. 1104 */ 1105 if (!Lst_IsEmpty(create)) { 1106 LstNode ln; 1107 1108 for (ln = Lst_First(create); ln != NULL; 1109 ln = Lst_Succ(ln)) { 1110 char *name = (char *)Lst_Datum(ln); 1111 1112 Var_Append(".TARGETS", name, VAR_GLOBAL); 1113 } 1114 } else 1115 Var_Set(".TARGETS", "", VAR_GLOBAL, 0); 1116 1117 1118 /* 1119 * If no user-supplied system path was given (through the -m option) 1120 * add the directories from the DEFSYSPATH (more than one may be given 1121 * as dir1:...:dirn) to the system include path. 1122 */ 1123 if (syspath == NULL || *syspath == '\0') 1124 syspath = defsyspath; 1125 else 1126 syspath = bmake_strdup(syspath); 1127 1128 for (start = syspath; *start != '\0'; start = cp) { 1129 for (cp = start; *cp != '\0' && *cp != ':'; cp++) 1130 continue; 1131 if (*cp == ':') { 1132 *cp++ = '\0'; 1133 } 1134 /* look for magic parent directory search string */ 1135 if (strncmp(".../", start, 4) != 0) { 1136 (void)Dir_AddDir(defIncPath, start); 1137 } else { 1138 if (Dir_FindHereOrAbove(curdir, start+4, 1139 found_path, sizeof(found_path))) { 1140 (void)Dir_AddDir(defIncPath, found_path); 1141 } 1142 } 1143 } 1144 if (syspath != defsyspath) 1145 free(syspath); 1146 1147 /* 1148 * Read in the built-in rules first, followed by the specified 1149 * makefile, if it was (makefile != NULL), or the default 1150 * makefile and Makefile, in that order, if it wasn't. 1151 */ 1152 if (!noBuiltins) { 1153 LstNode ln; 1154 1155 sysMkPath = Lst_Init(FALSE); 1156 Dir_Expand(_PATH_DEFSYSMK, 1157 Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath, 1158 sysMkPath); 1159 if (Lst_IsEmpty(sysMkPath)) 1160 Fatal("%s: no system rules (%s).", progname, 1161 _PATH_DEFSYSMK); 1162 ln = Lst_Find(sysMkPath, NULL, ReadMakefile); 1163 if (ln == NULL) 1164 Fatal("%s: cannot open %s.", progname, 1165 (char *)Lst_Datum(ln)); 1166 } 1167 1168 if (!Lst_IsEmpty(makefiles)) { 1169 LstNode ln; 1170 1171 ln = Lst_Find(makefiles, NULL, ReadAllMakefiles); 1172 if (ln != NULL) 1173 Fatal("%s: cannot open %s.", progname, 1174 (char *)Lst_Datum(ln)); 1175 } else { 1176 p1 = Var_Subst(NULL, "${" MAKEFILE_PREFERENCE "}", 1177 VAR_CMD, 0); 1178 if (p1) { 1179 (void)str2Lst_Append(makefiles, p1, NULL); 1180 (void)Lst_Find(makefiles, NULL, ReadMakefile); 1181 free(p1); 1182 } 1183 } 1184 1185 /* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */ 1186 if (!noBuiltins || !printVars) { 1187 makeDependfile = Var_Subst(NULL, "${.MAKE.DEPENDFILE:T}", 1188 VAR_CMD, 0); 1189 doing_depend = TRUE; 1190 (void)ReadMakefile(makeDependfile, NULL); 1191 doing_depend = FALSE; 1192 } 1193 1194 MakeMode(NULL); 1195 1196 Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL); 1197 if (p1) 1198 free(p1); 1199 1200 if (!compatMake) 1201 Job_ServerStart(maxJobTokens, jp_0, jp_1); 1202 if (DEBUG(JOB)) 1203 fprintf(debug_file, "job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n", 1204 jp_0, jp_1, maxJobs, maxJobTokens, compatMake); 1205 1206 Main_ExportMAKEFLAGS(TRUE); /* initial export */ 1207 1208 /* 1209 * For compatibility, look at the directories in the VPATH variable 1210 * and add them to the search path, if the variable is defined. The 1211 * variable's value is in the same format as the PATH envariable, i.e. 1212 * <directory>:<directory>:<directory>... 1213 */ 1214 if (Var_Exists("VPATH", VAR_CMD)) { 1215 char *vpath, savec; 1216 /* 1217 * GCC stores string constants in read-only memory, but 1218 * Var_Subst will want to write this thing, so store it 1219 * in an array 1220 */ 1221 static char VPATH[] = "${VPATH}"; 1222 1223 vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE); 1224 path = vpath; 1225 do { 1226 /* skip to end of directory */ 1227 for (cp = path; *cp != ':' && *cp != '\0'; cp++) 1228 continue; 1229 /* Save terminator character so know when to stop */ 1230 savec = *cp; 1231 *cp = '\0'; 1232 /* Add directory to search path */ 1233 (void)Dir_AddDir(dirSearchPath, path); 1234 *cp = savec; 1235 path = cp + 1; 1236 } while (savec == ':'); 1237 free(vpath); 1238 } 1239 1240 /* 1241 * Now that all search paths have been read for suffixes et al, it's 1242 * time to add the default search path to their lists... 1243 */ 1244 Suff_DoPaths(); 1245 1246 /* 1247 * Propagate attributes through :: dependency lists. 1248 */ 1249 Targ_Propagate(); 1250 1251 /* print the initial graph, if the user requested it */ 1252 if (DEBUG(GRAPH1)) 1253 Targ_PrintGraph(1); 1254 1255 /* print the values of any variables requested by the user */ 1256 if (printVars) { 1257 LstNode ln; 1258 Boolean expandVars; 1259 1260 if (debugVflag) 1261 expandVars = FALSE; 1262 else 1263 expandVars = getBoolean(".MAKE.EXPAND_VARIABLES", FALSE); 1264 for (ln = Lst_First(variables); ln != NULL; 1265 ln = Lst_Succ(ln)) { 1266 char *var = (char *)Lst_Datum(ln); 1267 char *value; 1268 1269 if (strchr(var, '$')) { 1270 value = p1 = Var_Subst(NULL, var, VAR_GLOBAL, 0); 1271 } else if (expandVars) { 1272 char tmp[128]; 1273 1274 if (snprintf(tmp, sizeof(tmp), "${%s}", var) >= (int)(sizeof(tmp))) 1275 Fatal("%s: variable name too big: %s", 1276 progname, var); 1277 value = p1 = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); 1278 } else { 1279 value = Var_Value(var, VAR_GLOBAL, &p1); 1280 } 1281 printf("%s\n", value ? value : ""); 1282 if (p1) 1283 free(p1); 1284 } 1285 } else { 1286 /* 1287 * Have now read the entire graph and need to make a list of 1288 * targets to create. If none was given on the command line, 1289 * we consult the parsing module to find the main target(s) 1290 * to create. 1291 */ 1292 if (Lst_IsEmpty(create)) 1293 targs = Parse_MainName(); 1294 else 1295 targs = Targ_FindList(create, TARG_CREATE); 1296 1297 if (!compatMake) { 1298 /* 1299 * Initialize job module before traversing the graph 1300 * now that any .BEGIN and .END targets have been read. 1301 * This is done only if the -q flag wasn't given 1302 * (to prevent the .BEGIN from being executed should 1303 * it exist). 1304 */ 1305 if (!queryFlag) { 1306 Job_Init(); 1307 jobsRunning = TRUE; 1308 } 1309 1310 /* Traverse the graph, checking on all the targets */ 1311 outOfDate = Make_Run(targs); 1312 } else { 1313 /* 1314 * Compat_Init will take care of creating all the 1315 * targets as well as initializing the module. 1316 */ 1317 Compat_Run(targs); 1318 } 1319 } 1320 1321 #ifdef CLEANUP 1322 Lst_Destroy(targs, NULL); 1323 Lst_Destroy(variables, NULL); 1324 Lst_Destroy(makefiles, NULL); 1325 Lst_Destroy(create, (FreeProc *)free); 1326 #endif 1327 1328 /* print the graph now it's been processed if the user requested it */ 1329 if (DEBUG(GRAPH2)) 1330 Targ_PrintGraph(2); 1331 1332 Trace_Log(MAKEEND, 0); 1333 1334 Suff_End(); 1335 Targ_End(); 1336 Arch_End(); 1337 Var_End(); 1338 Parse_End(); 1339 Dir_End(); 1340 Job_End(); 1341 Trace_End(); 1342 1343 return outOfDate ? 1 : 0; 1344 } 1345 1346 /*- 1347 * ReadMakefile -- 1348 * Open and parse the given makefile. 1349 * 1350 * Results: 1351 * 0 if ok. -1 if couldn't open file. 1352 * 1353 * Side Effects: 1354 * lots 1355 */ 1356 static int 1357 ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED) 1358 { 1359 const char *fname = p; /* makefile to read */ 1360 int fd; 1361 size_t len = MAXPATHLEN; 1362 char *name, *path = bmake_malloc(len); 1363 1364 if (!strcmp(fname, "-")) { 1365 Parse_File(NULL /*stdin*/, -1); 1366 Var_Set("MAKEFILE", "", VAR_GLOBAL, 0); 1367 } else { 1368 /* if we've chdir'd, rebuild the path name */ 1369 if (strcmp(curdir, objdir) && *fname != '/') { 1370 size_t plen = strlen(curdir) + strlen(fname) + 2; 1371 if (len < plen) 1372 path = bmake_realloc(path, len = 2 * plen); 1373 1374 (void)snprintf(path, len, "%s/%s", curdir, fname); 1375 fd = open(path, O_RDONLY); 1376 if (fd != -1) { 1377 fname = path; 1378 goto found; 1379 } 1380 1381 /* If curdir failed, try objdir (ala .depend) */ 1382 plen = strlen(objdir) + strlen(fname) + 2; 1383 if (len < plen) 1384 path = bmake_realloc(path, len = 2 * plen); 1385 (void)snprintf(path, len, "%s/%s", objdir, fname); 1386 fd = open(path, O_RDONLY); 1387 if (fd != -1) { 1388 fname = path; 1389 goto found; 1390 } 1391 } else { 1392 fd = open(fname, O_RDONLY); 1393 if (fd != -1) 1394 goto found; 1395 } 1396 /* look in -I and system include directories. */ 1397 name = Dir_FindFile(fname, parseIncPath); 1398 if (!name) 1399 name = Dir_FindFile(fname, 1400 Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath); 1401 if (!name || (fd = open(name, O_RDONLY)) == -1) { 1402 if (name) 1403 free(name); 1404 free(path); 1405 return(-1); 1406 } 1407 fname = name; 1408 /* 1409 * set the MAKEFILE variable desired by System V fans -- the 1410 * placement of the setting here means it gets set to the last 1411 * makefile specified, as it is set by SysV make. 1412 */ 1413 found: 1414 if (!doing_depend) 1415 Var_Set("MAKEFILE", fname, VAR_GLOBAL, 0); 1416 Parse_File(fname, fd); 1417 } 1418 free(path); 1419 return(0); 1420 } 1421 1422 1423 1424 /*- 1425 * Cmd_Exec -- 1426 * Execute the command in cmd, and return the output of that command 1427 * in a string. 1428 * 1429 * Results: 1430 * A string containing the output of the command, or the empty string 1431 * If errnum is not NULL, it contains the reason for the command failure 1432 * 1433 * Side Effects: 1434 * The string must be freed by the caller. 1435 */ 1436 char * 1437 Cmd_Exec(const char *cmd, const char **errnum) 1438 { 1439 const char *args[4]; /* Args for invoking the shell */ 1440 int fds[2]; /* Pipe streams */ 1441 int cpid; /* Child PID */ 1442 int pid; /* PID from wait() */ 1443 char *res; /* result */ 1444 WAIT_T status; /* command exit status */ 1445 Buffer buf; /* buffer to store the result */ 1446 char *cp; 1447 int cc; 1448 1449 1450 *errnum = NULL; 1451 1452 if (!shellName) 1453 Shell_Init(); 1454 /* 1455 * Set up arguments for shell 1456 */ 1457 args[0] = shellName; 1458 args[1] = "-c"; 1459 args[2] = cmd; 1460 args[3] = NULL; 1461 1462 /* 1463 * Open a pipe for fetching its output 1464 */ 1465 if (pipe(fds) == -1) { 1466 *errnum = "Couldn't create pipe for \"%s\""; 1467 goto bad; 1468 } 1469 1470 /* 1471 * Fork 1472 */ 1473 switch (cpid = vFork()) { 1474 case 0: 1475 /* 1476 * Close input side of pipe 1477 */ 1478 (void)close(fds[0]); 1479 1480 /* 1481 * Duplicate the output stream to the shell's output, then 1482 * shut the extra thing down. Note we don't fetch the error 1483 * stream...why not? Why? 1484 */ 1485 (void)dup2(fds[1], 1); 1486 (void)close(fds[1]); 1487 1488 Var_ExportVars(); 1489 1490 (void)execv(shellPath, UNCONST(args)); 1491 _exit(1); 1492 /*NOTREACHED*/ 1493 1494 case -1: 1495 *errnum = "Couldn't exec \"%s\""; 1496 goto bad; 1497 1498 default: 1499 /* 1500 * No need for the writing half 1501 */ 1502 (void)close(fds[1]); 1503 1504 Buf_Init(&buf, 0); 1505 1506 do { 1507 char result[BUFSIZ]; 1508 cc = read(fds[0], result, sizeof(result)); 1509 if (cc > 0) 1510 Buf_AddBytes(&buf, cc, result); 1511 } 1512 while (cc > 0 || (cc == -1 && errno == EINTR)); 1513 1514 /* 1515 * Close the input side of the pipe. 1516 */ 1517 (void)close(fds[0]); 1518 1519 /* 1520 * Wait for the process to exit. 1521 */ 1522 while(((pid = waitpid(cpid, &status, 0)) != cpid) && (pid >= 0)) { 1523 JobReapChild(pid, status, FALSE); 1524 continue; 1525 } 1526 cc = Buf_Size(&buf); 1527 res = Buf_Destroy(&buf, FALSE); 1528 1529 if (cc == 0) 1530 *errnum = "Couldn't read shell's output for \"%s\""; 1531 1532 if (WIFSIGNALED(status)) 1533 *errnum = "\"%s\" exited on a signal"; 1534 else if (WEXITSTATUS(status) != 0) 1535 *errnum = "\"%s\" returned non-zero status"; 1536 1537 /* 1538 * Null-terminate the result, convert newlines to spaces and 1539 * install it in the variable. 1540 */ 1541 res[cc] = '\0'; 1542 cp = &res[cc]; 1543 1544 if (cc > 0 && *--cp == '\n') { 1545 /* 1546 * A final newline is just stripped 1547 */ 1548 *cp-- = '\0'; 1549 } 1550 while (cp >= res) { 1551 if (*cp == '\n') { 1552 *cp = ' '; 1553 } 1554 cp--; 1555 } 1556 break; 1557 } 1558 return res; 1559 bad: 1560 res = bmake_malloc(1); 1561 *res = '\0'; 1562 return res; 1563 } 1564 1565 /*- 1566 * Error -- 1567 * Print an error message given its format. 1568 * 1569 * Results: 1570 * None. 1571 * 1572 * Side Effects: 1573 * The message is printed. 1574 */ 1575 /* VARARGS */ 1576 void 1577 Error(const char *fmt, ...) 1578 { 1579 va_list ap; 1580 FILE *err_file; 1581 1582 err_file = debug_file; 1583 if (err_file == stdout) 1584 err_file = stderr; 1585 (void)fflush(stdout); 1586 for (;;) { 1587 va_start(ap, fmt); 1588 fprintf(err_file, "%s: ", progname); 1589 (void)vfprintf(err_file, fmt, ap); 1590 va_end(ap); 1591 (void)fprintf(err_file, "\n"); 1592 (void)fflush(err_file); 1593 if (err_file == stderr) 1594 break; 1595 err_file = stderr; 1596 } 1597 } 1598 1599 /*- 1600 * Fatal -- 1601 * Produce a Fatal error message. If jobs are running, waits for them 1602 * to finish. 1603 * 1604 * Results: 1605 * None 1606 * 1607 * Side Effects: 1608 * The program exits 1609 */ 1610 /* VARARGS */ 1611 void 1612 Fatal(const char *fmt, ...) 1613 { 1614 va_list ap; 1615 1616 va_start(ap, fmt); 1617 if (jobsRunning) 1618 Job_Wait(); 1619 1620 (void)fflush(stdout); 1621 (void)vfprintf(stderr, fmt, ap); 1622 va_end(ap); 1623 (void)fprintf(stderr, "\n"); 1624 (void)fflush(stderr); 1625 1626 PrintOnError(NULL, NULL); 1627 1628 if (DEBUG(GRAPH2) || DEBUG(GRAPH3)) 1629 Targ_PrintGraph(2); 1630 Trace_Log(MAKEERROR, 0); 1631 exit(2); /* Not 1 so -q can distinguish error */ 1632 } 1633 1634 /* 1635 * Punt -- 1636 * Major exception once jobs are being created. Kills all jobs, prints 1637 * a message and exits. 1638 * 1639 * Results: 1640 * None 1641 * 1642 * Side Effects: 1643 * All children are killed indiscriminately and the program Lib_Exits 1644 */ 1645 /* VARARGS */ 1646 void 1647 Punt(const char *fmt, ...) 1648 { 1649 va_list ap; 1650 1651 va_start(ap, fmt); 1652 (void)fflush(stdout); 1653 (void)fprintf(stderr, "%s: ", progname); 1654 (void)vfprintf(stderr, fmt, ap); 1655 va_end(ap); 1656 (void)fprintf(stderr, "\n"); 1657 (void)fflush(stderr); 1658 1659 PrintOnError(NULL, NULL); 1660 1661 DieHorribly(); 1662 } 1663 1664 /*- 1665 * DieHorribly -- 1666 * Exit without giving a message. 1667 * 1668 * Results: 1669 * None 1670 * 1671 * Side Effects: 1672 * A big one... 1673 */ 1674 void 1675 DieHorribly(void) 1676 { 1677 if (jobsRunning) 1678 Job_AbortAll(); 1679 if (DEBUG(GRAPH2)) 1680 Targ_PrintGraph(2); 1681 Trace_Log(MAKEERROR, 0); 1682 exit(2); /* Not 1, so -q can distinguish error */ 1683 } 1684 1685 /* 1686 * Finish -- 1687 * Called when aborting due to errors in child shell to signal 1688 * abnormal exit. 1689 * 1690 * Results: 1691 * None 1692 * 1693 * Side Effects: 1694 * The program exits 1695 */ 1696 void 1697 Finish(int errors) 1698 /* number of errors encountered in Make_Make */ 1699 { 1700 Fatal("%d error%s", errors, errors == 1 ? "" : "s"); 1701 } 1702 1703 /* 1704 * eunlink -- 1705 * Remove a file carefully, avoiding directories. 1706 */ 1707 int 1708 eunlink(const char *file) 1709 { 1710 struct stat st; 1711 1712 if (lstat(file, &st) == -1) 1713 return -1; 1714 1715 if (S_ISDIR(st.st_mode)) { 1716 errno = EISDIR; 1717 return -1; 1718 } 1719 return unlink(file); 1720 } 1721 1722 /* 1723 * execError -- 1724 * Print why exec failed, avoiding stdio. 1725 */ 1726 void 1727 execError(const char *af, const char *av) 1728 { 1729 #ifdef USE_IOVEC 1730 int i = 0; 1731 struct iovec iov[8]; 1732 #define IOADD(s) \ 1733 (void)(iov[i].iov_base = UNCONST(s), \ 1734 iov[i].iov_len = strlen(iov[i].iov_base), \ 1735 i++) 1736 #else 1737 #define IOADD(s) (void)write(2, s, strlen(s)) 1738 #endif 1739 1740 IOADD(progname); 1741 IOADD(": "); 1742 IOADD(af); 1743 IOADD("("); 1744 IOADD(av); 1745 IOADD(") failed ("); 1746 IOADD(strerror(errno)); 1747 IOADD(")\n"); 1748 1749 #ifdef USE_IOVEC 1750 while (writev(2, iov, 8) == -1 && errno == EAGAIN) 1751 continue; 1752 #endif 1753 } 1754 1755 /* 1756 * usage -- 1757 * exit with usage message 1758 */ 1759 static void 1760 usage(void) 1761 { 1762 (void)fprintf(stderr, 1763 "usage: %s [-BeikNnqrstWX] \n\ 1764 [-C directory] [-D variable] [-d flags] [-f makefile]\n\ 1765 [-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]\n\ 1766 [-V variable] [variable=value] [target ...]\n", progname); 1767 exit(2); 1768 } 1769 1770 1771 int 1772 PrintAddr(void *a, void *b) 1773 { 1774 printf("%lx ", (unsigned long) a); 1775 return b ? 0 : 0; 1776 } 1777 1778 1779 1780 void 1781 PrintOnError(GNode *gn, const char *s) 1782 { 1783 static GNode *en = NULL; 1784 char tmp[64]; 1785 char *cp; 1786 1787 if (s) 1788 printf("%s", s); 1789 1790 printf("\n%s: stopped in %s\n", progname, curdir); 1791 1792 if (en) 1793 return; /* we've been here! */ 1794 if (gn) { 1795 /* 1796 * We can print this even if there is no .ERROR target. 1797 */ 1798 Var_Set(".ERROR_TARGET", gn->name, VAR_GLOBAL, 0); 1799 } 1800 strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}", 1801 sizeof(tmp) - 1); 1802 cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); 1803 if (cp) { 1804 if (*cp) 1805 printf("%s", cp); 1806 free(cp); 1807 } 1808 /* 1809 * Finally, see if there is a .ERROR target, and run it if so. 1810 */ 1811 en = Targ_FindNode(".ERROR", TARG_NOCREATE); 1812 if (en) { 1813 en->type |= OP_SPECIAL; 1814 Compat_Make(en, en); 1815 } 1816 } 1817 1818 void 1819 Main_ExportMAKEFLAGS(Boolean first) 1820 { 1821 static int once = 1; 1822 char tmp[64]; 1823 char *s; 1824 1825 if (once != first) 1826 return; 1827 once = 0; 1828 1829 strncpy(tmp, "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}", 1830 sizeof(tmp)); 1831 s = Var_Subst(NULL, tmp, VAR_CMD, 0); 1832 if (s && *s) { 1833 #ifdef POSIX 1834 setenv("MAKEFLAGS", s, 1); 1835 #else 1836 setenv("MAKE", s, 1); 1837 #endif 1838 } 1839 } 1840 1841 char * 1842 getTmpdir(void) 1843 { 1844 static char *tmpdir = NULL; 1845 1846 if (!tmpdir) { 1847 struct stat st; 1848 1849 /* 1850 * Honor $TMPDIR but only if it is valid. 1851 * Ensure it ends with /. 1852 */ 1853 tmpdir = Var_Subst(NULL, "${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL, 0); 1854 if (stat(tmpdir, &st) < 0 || !S_ISDIR(st.st_mode)) { 1855 free(tmpdir); 1856 tmpdir = bmake_strdup(_PATH_TMP); 1857 } 1858 } 1859 return tmpdir; 1860 } 1861 1862 /* 1863 * Create and open a temp file using "pattern". 1864 * If "fnamep" is provided set it to a copy of the filename created. 1865 * Otherwise unlink the file once open. 1866 */ 1867 int 1868 mkTempFile(const char *pattern, char **fnamep) 1869 { 1870 static char *tmpdir = NULL; 1871 char tfile[MAXPATHLEN]; 1872 int fd; 1873 1874 if (!pattern) 1875 pattern = TMPPAT; 1876 if (!tmpdir) 1877 tmpdir = getTmpdir(); 1878 if (pattern[0] == '/') { 1879 snprintf(tfile, sizeof(tfile), "%s", pattern); 1880 } else { 1881 snprintf(tfile, sizeof(tfile), "%s%s", tmpdir, pattern); 1882 } 1883 if ((fd = mkstemp(tfile)) < 0) 1884 Punt("Could not create temporary file %s: %s", tfile, strerror(errno)); 1885 if (fnamep) { 1886 *fnamep = bmake_strdup(tfile); 1887 } else { 1888 unlink(tfile); /* we just want the descriptor */ 1889 } 1890 return fd; 1891 } 1892 1893 1894 /* 1895 * Return a Boolean based on setting of a knob. 1896 * 1897 * If the knob is not set, the supplied default is the return value. 1898 * If set, anything that looks or smells like "No", "False", "Off", "0" etc, 1899 * is FALSE, otherwise TRUE. 1900 */ 1901 Boolean 1902 getBoolean(const char *name, Boolean bf) 1903 { 1904 char tmp[64]; 1905 char *cp; 1906 1907 if (snprintf(tmp, sizeof(tmp), "${%s:tl}", name) < (int)(sizeof(tmp))) { 1908 cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); 1909 1910 if (cp) { 1911 switch(*cp) { 1912 case '\0': /* not set - the default wins */ 1913 break; 1914 case '0': 1915 case 'f': 1916 case 'n': 1917 bf = FALSE; 1918 break; 1919 case 'o': 1920 switch (cp[1]) { 1921 case 'f': 1922 bf = FALSE; 1923 break; 1924 default: 1925 bf = TRUE; 1926 break; 1927 } 1928 break; 1929 default: 1930 bf = TRUE; 1931 break; 1932 } 1933 free(cp); 1934 } 1935 } 1936 return (bf); 1937 } 1938