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