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