main.c revision 53631
1/* 2 * Copyright (c) 1988, 1989, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * Copyright (c) 1989 by Berkeley Softworks 5 * 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. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 */ 38 39#ifndef lint 40static const char copyright[] = 41"@(#) Copyright (c) 1988, 1989, 1990, 1993\n\ 42 The Regents of the University of California. All rights reserved.\n"; 43#endif /* not lint */ 44 45#ifndef lint 46#if 0 47static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94"; 48#else 49static const char rcsid[] = 50 "$FreeBSD: head/usr.bin/make/main.c 53631 1999-11-23 10:35:24Z marcel $"; 51#endif 52#endif /* not lint */ 53 54/*- 55 * main.c -- 56 * The main file for this entire program. Exit routines etc 57 * reside here. 58 * 59 * Utility functions defined in this file: 60 * Main_ParseArgLine Takes a line of arguments, breaks them and 61 * treats them as if they were given when first 62 * invoked. Used by the parse module to implement 63 * the .MFLAGS target. 64 * 65 * Error Print a tagged error message. The global 66 * MAKE variable must have been defined. This 67 * takes a format string and two optional 68 * arguments for it. 69 * 70 * Fatal Print an error message and exit. Also takes 71 * a format string and two arguments. 72 * 73 * Punt Aborts all jobs and exits with a message. Also 74 * takes a format string and two arguments. 75 * 76 * Finish Finish things up by printing the number of 77 * errors which occured, as passed to it, and 78 * exiting. 79 */ 80 81#include <sys/types.h> 82#include <sys/time.h> 83#include <sys/param.h> 84#include <sys/resource.h> 85#include <sys/signal.h> 86#include <sys/stat.h> 87#if defined(__i386__) 88#include <sys/sysctl.h> 89#endif 90#ifndef MACHINE 91#include <sys/utsname.h> 92#endif 93#include <sys/wait.h> 94#include <err.h> 95#include <stdlib.h> 96#include <errno.h> 97#include <fcntl.h> 98#include <stdio.h> 99#include <sysexits.h> 100#ifdef __STDC__ 101#include <stdarg.h> 102#else 103#include <varargs.h> 104#endif 105#include "make.h" 106#include "hash.h" 107#include "dir.h" 108#include "job.h" 109#include "pathnames.h" 110 111#ifndef DEFMAXLOCAL 112#define DEFMAXLOCAL DEFMAXJOBS 113#endif /* DEFMAXLOCAL */ 114 115#define MAKEFLAGS ".MAKEFLAGS" 116 117Lst create; /* Targets to be made */ 118time_t now; /* Time at start of make */ 119GNode *DEFAULT; /* .DEFAULT node */ 120Boolean allPrecious; /* .PRECIOUS given on line by itself */ 121 122static Boolean noBuiltins; /* -r flag */ 123static Lst makefiles; /* ordered list of makefiles to read */ 124static Boolean printVars; /* print value of one or more vars */ 125static Lst variables; /* list of variables to print */ 126int maxJobs; /* -j argument */ 127static Boolean forceJobs; /* -j argument given */ 128static int maxLocal; /* -L argument */ 129Boolean compatMake; /* -B argument */ 130Boolean debug; /* -d flag */ 131Boolean noExecute; /* -n flag */ 132Boolean keepgoing; /* -k flag */ 133Boolean queryFlag; /* -q flag */ 134Boolean touchFlag; /* -t flag */ 135Boolean usePipes; /* !-P flag */ 136Boolean ignoreErrors; /* -i flag */ 137Boolean beSilent; /* -s flag */ 138Boolean beVerbose; /* -v flag */ 139Boolean oldVars; /* variable substitution style */ 140Boolean checkEnvFirst; /* -e flag */ 141Lst envFirstVars; /* (-E) vars to override from env */ 142static Boolean jobsRunning; /* TRUE if the jobs might be running */ 143 144static void MainParseArgs __P((int, char **)); 145char * chdir_verify_path __P((char *, char *)); 146static int ReadMakefile __P((ClientData, ClientData)); 147static void usage __P((void)); 148 149static char *curdir; /* startup directory */ 150static char *objdir; /* where we chdir'ed to */ 151 152/*- 153 * MainParseArgs -- 154 * Parse a given argument vector. Called from main() and from 155 * Main_ParseArgLine() when the .MAKEFLAGS target is used. 156 * 157 * XXX: Deal with command line overriding .MAKEFLAGS in makefile 158 * 159 * Results: 160 * None 161 * 162 * Side Effects: 163 * Various global and local flags will be set depending on the flags 164 * given 165 */ 166static void 167MainParseArgs(argc, argv) 168 int argc; 169 char **argv; 170{ 171 extern int optind; 172 extern char *optarg; 173 char *p; 174 int c; 175 176 optind = 1; /* since we're called more than once */ 177#ifdef REMOTE 178# define OPTFLAGS "BD:E:I:L:PSV:d:ef:ij:km:nqrstv" 179#else 180# define OPTFLAGS "BD:E:I:PSV:d:ef:ij:km:nqrstv" 181#endif 182rearg: while((c = getopt(argc, argv, OPTFLAGS)) != -1) { 183 switch(c) { 184 case 'D': 185 Var_Set(optarg, "1", VAR_GLOBAL); 186 Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL); 187 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 188 break; 189 case 'I': 190 Parse_AddIncludeDir(optarg); 191 Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL); 192 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 193 break; 194 case 'V': 195 printVars = TRUE; 196 p = malloc(strlen(optarg) + 1 + 3); 197 if (!p) 198 Punt("make: cannot allocate memory."); 199 /* This sprintf is safe, because of the malloc above */ 200 (void)sprintf(p, "${%s}", optarg); 201 (void)Lst_AtEnd(variables, (ClientData)p); 202 Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL); 203 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 204 break; 205 case 'B': 206 compatMake = TRUE; 207 Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL); 208 break; 209#ifdef REMOTE 210 case 'L': { 211 char *endptr; 212 213 maxLocal = strtol(optarg, &endptr, 10); 214 if (maxLocal < 0 || *endptr != '\0') { 215 warnx("illegal number, -L argument -- %s", 216 optarg); 217 usage(); 218 } 219 Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL); 220 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 221 break; 222 } 223#endif 224 case 'P': 225 usePipes = FALSE; 226 Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL); 227 break; 228 case 'S': 229 keepgoing = FALSE; 230 Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL); 231 break; 232 case 'd': { 233 char *modules = optarg; 234 235 for (; *modules; ++modules) 236 switch (*modules) { 237 case 'A': 238 debug = ~0; 239 break; 240 case 'a': 241 debug |= DEBUG_ARCH; 242 break; 243 case 'c': 244 debug |= DEBUG_COND; 245 break; 246 case 'd': 247 debug |= DEBUG_DIR; 248 break; 249 case 'f': 250 debug |= DEBUG_FOR; 251 break; 252 case 'g': 253 if (modules[1] == '1') { 254 debug |= DEBUG_GRAPH1; 255 ++modules; 256 } 257 else if (modules[1] == '2') { 258 debug |= DEBUG_GRAPH2; 259 ++modules; 260 } 261 break; 262 case 'j': 263 debug |= DEBUG_JOB; 264 break; 265 case 'm': 266 debug |= DEBUG_MAKE; 267 break; 268 case 's': 269 debug |= DEBUG_SUFF; 270 break; 271 case 't': 272 debug |= DEBUG_TARG; 273 break; 274 case 'v': 275 debug |= DEBUG_VAR; 276 break; 277 default: 278 warnx("illegal argument to d option -- %c", *modules); 279 usage(); 280 } 281 Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL); 282 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 283 break; 284 } 285 case 'E': 286 p = malloc(strlen(optarg) + 1); 287 if (!p) 288 Punt("make: cannot allocate memory."); 289 (void)strcpy(p, optarg); 290 (void)Lst_AtEnd(envFirstVars, (ClientData)p); 291 Var_Append(MAKEFLAGS, "-E", VAR_GLOBAL); 292 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 293 break; 294 case 'e': 295 checkEnvFirst = TRUE; 296 Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL); 297 break; 298 case 'f': 299 (void)Lst_AtEnd(makefiles, (ClientData)optarg); 300 break; 301 case 'i': 302 ignoreErrors = TRUE; 303 Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL); 304 break; 305 case 'j': { 306 char *endptr; 307 308 forceJobs = TRUE; 309 maxJobs = strtol(optarg, &endptr, 10); 310 if (maxJobs <= 0 || *endptr != '\0') { 311 warnx("illegal number, -j argument -- %s", 312 optarg); 313 usage(); 314 } 315#ifndef REMOTE 316 maxLocal = maxJobs; 317#endif 318 Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL); 319 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 320 break; 321 } 322 case 'k': 323 keepgoing = TRUE; 324 Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL); 325 break; 326 case 'm': 327 Dir_AddDir(sysIncPath, optarg); 328 Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL); 329 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); 330 break; 331 case 'n': 332 noExecute = TRUE; 333 Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL); 334 break; 335 case 'q': 336 queryFlag = TRUE; 337 /* Kind of nonsensical, wot? */ 338 Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL); 339 break; 340 case 'r': 341 noBuiltins = TRUE; 342 Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL); 343 break; 344 case 's': 345 beSilent = TRUE; 346 Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL); 347 break; 348 case 't': 349 touchFlag = TRUE; 350 Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL); 351 break; 352 case 'v': 353 beVerbose = TRUE; 354 Var_Append(MAKEFLAGS, "-v", VAR_GLOBAL); 355 break; 356 default: 357 case '?': 358 usage(); 359 } 360 } 361 362 oldVars = TRUE; 363 364 /* 365 * See if the rest of the arguments are variable assignments and 366 * perform them if so. Else take them to be targets and stuff them 367 * on the end of the "create" list. 368 */ 369 for (argv += optind, argc -= optind; *argv; ++argv, --argc) 370 if (Parse_IsVar(*argv)) 371 Parse_DoVar(*argv, VAR_CMD); 372 else { 373 if (!**argv) 374 Punt("illegal (null) argument."); 375 if (**argv == '-') { 376 if ((*argv)[1]) 377 optind = 0; /* -flag... */ 378 else 379 optind = 1; /* - */ 380 goto rearg; 381 } 382 (void)Lst_AtEnd(create, (ClientData)estrdup(*argv)); 383 } 384} 385 386/*- 387 * Main_ParseArgLine -- 388 * Used by the parse module when a .MFLAGS or .MAKEFLAGS target 389 * is encountered and by main() when reading the .MAKEFLAGS envariable. 390 * Takes a line of arguments and breaks it into its 391 * component words and passes those words and the number of them to the 392 * MainParseArgs function. 393 * The line should have all its leading whitespace removed. 394 * 395 * Results: 396 * None 397 * 398 * Side Effects: 399 * Only those that come from the various arguments. 400 */ 401void 402Main_ParseArgLine(line) 403 char *line; /* Line to fracture */ 404{ 405 char **argv; /* Manufactured argument vector */ 406 int argc; /* Number of arguments in argv */ 407 408 if (line == NULL) 409 return; 410 for (; *line == ' '; ++line) 411 continue; 412 if (!*line) 413 return; 414 415 argv = brk_string(line, &argc, TRUE); 416 MainParseArgs(argc, argv); 417} 418 419char * 420chdir_verify_path(path, obpath) 421 char *path; 422 char *obpath; 423{ 424 struct stat sb; 425 426 if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { 427 if (chdir(path)) { 428 warn("warning: %s", path); 429 return 0; 430 } 431 else { 432 if (path[0] != '/') { 433 (void) snprintf(obpath, MAXPATHLEN, "%s/%s", 434 curdir, path); 435 return obpath; 436 } 437 else 438 return path; 439 } 440 } 441 442 return 0; 443} 444 445 446/*- 447 * main -- 448 * The main function, for obvious reasons. Initializes variables 449 * and a few modules, then parses the arguments give it in the 450 * environment and on the command line. Reads the system makefile 451 * followed by either Makefile, makefile or the file given by the 452 * -f argument. Sets the .MAKEFLAGS PMake variable based on all the 453 * flags it has received by then uses either the Make or the Compat 454 * module to create the initial list of targets. 455 * 456 * Results: 457 * If -q was given, exits -1 if anything was out-of-date. Else it exits 458 * 0. 459 * 460 * Side Effects: 461 * The program exits when done. Targets are created. etc. etc. etc. 462 */ 463int 464main(argc, argv) 465 int argc; 466 char **argv; 467{ 468 Lst targs; /* target nodes to create -- passed to Make_Init */ 469 Boolean outOfDate = TRUE; /* FALSE if all targets up to date */ 470 struct stat sa; 471 char *p, *p1, *path, *pathp; 472#ifdef WANT_ENV_PWD 473 struct stat sb; 474 char *pwd; 475#endif 476 char mdpath[MAXPATHLEN + 1]; 477 char obpath[MAXPATHLEN + 1]; 478 char cdpath[MAXPATHLEN + 1]; 479 char *machine = getenv("MACHINE"); 480 char *machine_arch = getenv("MACHINE_ARCH"); 481 Lst sysMkPath; /* Path of sys.mk */ 482 char *cp = NULL, *start; 483 /* avoid faults on read-only strings */ 484 static char syspath[] = _PATH_DEFSYSPATH; 485 486#ifdef RLIMIT_NOFILE 487 /* 488 * get rid of resource limit on file descriptors 489 */ 490 { 491 struct rlimit rl; 492 if (getrlimit(RLIMIT_NOFILE, &rl) != -1 && 493 rl.rlim_cur != rl.rlim_max) { 494 rl.rlim_cur = rl.rlim_max; 495 (void) setrlimit(RLIMIT_NOFILE, &rl); 496 } 497 } 498#endif 499 /* 500 * Find where we are and take care of PWD for the automounter... 501 * All this code is so that we know where we are when we start up 502 * on a different machine with pmake. 503 */ 504 curdir = cdpath; 505 if (getcwd(curdir, MAXPATHLEN) == NULL) 506 err(2, NULL); 507 508 if (stat(curdir, &sa) == -1) 509 err(2, "%s", curdir); 510 511#ifdef WANT_ENV_PWD 512 if ((pwd = getenv("PWD")) != NULL) { 513 if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino && 514 sa.st_dev == sb.st_dev) 515 (void) strcpy(curdir, pwd); 516 } 517#endif 518 519#if defined(__i386__) && defined(__FreeBSD_version) && \ 520 __FreeBSD_version > 300003 521 /* 522 * PC-98 kernel sets the `i386' string to the utsname.machine and 523 * it cannot be distinguished from IBM-PC by uname(3). Therefore, 524 * we check machine.ispc98 and adjust the machine variable before 525 * using usname(3) below. 526 * NOTE: machdep.ispc98 was defined on 1998/8/31. At that time, 527 * __FreeBSD_version was defined as 300003. So, this check can 528 * safely be done with any kernel with version > 300003. 529 */ 530 if (!machine) { 531 int ispc98; 532 size_t len; 533 534 len = sizeof(ispc98); 535 if (!sysctlbyname("machdep.ispc98", &ispc98, &len, NULL, 0)) { 536 if (ispc98) 537 machine = "pc98"; 538 } 539 } 540#endif 541 542 /* 543 * Get the name of this type of MACHINE from utsname 544 * so we can share an executable for similar machines. 545 * (i.e. m68k: amiga hp300, mac68k, sun3, ...) 546 * 547 * Note that while MACHINE is decided at run-time, 548 * MACHINE_ARCH is always known at compile time. 549 */ 550 if (!machine) { 551#ifndef MACHINE 552 struct utsname utsname; 553 554 if (uname(&utsname) == -1) { 555 perror("make: uname"); 556 exit(2); 557 } 558 machine = utsname.machine; 559#else 560 machine = MACHINE; 561#endif 562 } 563 564 if (!machine_arch) { 565#ifndef MACHINE_ARCH 566 machine_arch = "unknown"; 567#else 568 machine_arch = MACHINE_ARCH; 569#endif 570 } 571 572 /* 573 * The object directory location is determined using the 574 * following order of preference: 575 * 576 * 1. MAKEOBJDIRPREFIX`cwd` 577 * 2. MAKEOBJDIR 578 * 3. _PATH_OBJDIR.${MACHINE} 579 * 4. _PATH_OBJDIR 580 * 5. _PATH_OBJDIRPREFIX`cwd` 581 * 582 * If one of the first two fails, use the current directory. 583 * If the remaining three all fail, use the current directory. 584 * 585 * Once things are initted, 586 * have to add the original directory to the search path, 587 * and modify the paths for the Makefiles apropriately. The 588 * current directory is also placed as a variable for make scripts. 589 */ 590 if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) { 591 if (!(path = getenv("MAKEOBJDIR"))) { 592 path = _PATH_OBJDIR; 593 pathp = _PATH_OBJDIRPREFIX; 594 (void) snprintf(mdpath, MAXPATHLEN, "%s.%s", 595 path, machine); 596 if (!(objdir = chdir_verify_path(mdpath, obpath))) 597 if (!(objdir=chdir_verify_path(path, obpath))) { 598 (void) snprintf(mdpath, MAXPATHLEN, 599 "%s%s", pathp, curdir); 600 if (!(objdir=chdir_verify_path(mdpath, 601 obpath))) 602 objdir = curdir; 603 } 604 } 605 else if (!(objdir = chdir_verify_path(path, obpath))) 606 objdir = curdir; 607 } 608 else { 609 (void) snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir); 610 if (!(objdir = chdir_verify_path(mdpath, obpath))) 611 objdir = curdir; 612 } 613 614#ifdef WANT_ENV_PWD 615 setenv("PWD", objdir, 1); 616#endif 617 618 create = Lst_Init(FALSE); 619 makefiles = Lst_Init(FALSE); 620 envFirstVars = Lst_Init(FALSE); 621 printVars = FALSE; 622 variables = Lst_Init(FALSE); 623 beSilent = FALSE; /* Print commands as executed */ 624 ignoreErrors = FALSE; /* Pay attention to non-zero returns */ 625 noExecute = FALSE; /* Execute all commands */ 626 keepgoing = FALSE; /* Stop on error */ 627 allPrecious = FALSE; /* Remove targets when interrupted */ 628 queryFlag = FALSE; /* This is not just a check-run */ 629 noBuiltins = FALSE; /* Read the built-in rules */ 630 touchFlag = FALSE; /* Actually update targets */ 631 usePipes = TRUE; /* Catch child output in pipes */ 632 debug = 0; /* No debug verbosity, please. */ 633 jobsRunning = FALSE; 634 635 maxLocal = DEFMAXLOCAL; /* Set default local max concurrency */ 636#ifdef REMOTE 637 maxJobs = DEFMAXJOBS; /* Set default max concurrency */ 638#else 639 maxJobs = maxLocal; 640#endif 641 forceJobs = FALSE; /* No -j flag */ 642 compatMake = FALSE; /* No compat mode */ 643 644 645 /* 646 * Initialize the parsing, directory and variable modules to prepare 647 * for the reading of inclusion paths and variable settings on the 648 * command line 649 */ 650 Dir_Init(); /* Initialize directory structures so -I flags 651 * can be processed correctly */ 652 Parse_Init(); /* Need to initialize the paths of #include 653 * directories */ 654 Var_Init(); /* As well as the lists of variables for 655 * parsing arguments */ 656 str_init(); 657 if (objdir != curdir) 658 Dir_AddDir(dirSearchPath, curdir); 659 Var_Set(".CURDIR", curdir, VAR_GLOBAL); 660 Var_Set(".OBJDIR", objdir, VAR_GLOBAL); 661 662 /* 663 * Initialize various variables. 664 * MAKE also gets this name, for compatibility 665 * .MAKEFLAGS gets set to the empty string just in case. 666 * MFLAGS also gets initialized empty, for compatibility. 667 */ 668 Var_Set("MAKE", argv[0], VAR_GLOBAL); 669 Var_Set(MAKEFLAGS, "", VAR_GLOBAL); 670 Var_Set("MFLAGS", "", VAR_GLOBAL); 671 Var_Set("MACHINE", machine, VAR_GLOBAL); 672 Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL); 673 674 /* 675 * First snag any flags out of the MAKE environment variable. 676 * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's 677 * in a different format). 678 */ 679#ifdef POSIX 680 Main_ParseArgLine(getenv("MAKEFLAGS")); 681#else 682 Main_ParseArgLine(getenv("MAKE")); 683#endif 684 685 MainParseArgs(argc, argv); 686 687 /* 688 * Be compatible if user did not specify -j and did not explicitly 689 * turned compatibility on 690 */ 691 if (!compatMake && !forceJobs) 692 compatMake = TRUE; 693 694 /* 695 * Initialize archive, target and suffix modules in preparation for 696 * parsing the makefile(s) 697 */ 698 Arch_Init(); 699 Targ_Init(); 700 Suff_Init(); 701 702 DEFAULT = NILGNODE; 703 (void)time(&now); 704 705 /* 706 * Set up the .TARGETS variable to contain the list of targets to be 707 * created. If none specified, make the variable empty -- the parser 708 * will fill the thing in with the default or .MAIN target. 709 */ 710 if (!Lst_IsEmpty(create)) { 711 LstNode ln; 712 713 for (ln = Lst_First(create); ln != NILLNODE; 714 ln = Lst_Succ(ln)) { 715 char *name = (char *)Lst_Datum(ln); 716 717 Var_Append(".TARGETS", name, VAR_GLOBAL); 718 } 719 } else 720 Var_Set(".TARGETS", "", VAR_GLOBAL); 721 722 723 /* 724 * If no user-supplied system path was given (through the -m option) 725 * add the directories from the DEFSYSPATH (more than one may be given 726 * as dir1:...:dirn) to the system include path. 727 */ 728 if (Lst_IsEmpty(sysIncPath)) { 729 for (start = syspath; *start != '\0'; start = cp) { 730 for (cp = start; *cp != '\0' && *cp != ':'; cp++) 731 continue; 732 if (*cp == '\0') { 733 Dir_AddDir(sysIncPath, start); 734 } else { 735 *cp++ = '\0'; 736 Dir_AddDir(sysIncPath, start); 737 } 738 } 739 } 740 741 /* 742 * Read in the built-in rules first, followed by the specified 743 * makefile, if it was (makefile != (char *) NULL), or the default 744 * Makefile and makefile, in that order, if it wasn't. 745 */ 746 if (!noBuiltins) { 747 LstNode ln; 748 749 sysMkPath = Lst_Init (FALSE); 750 Dir_Expand (_PATH_DEFSYSMK, sysIncPath, sysMkPath); 751 if (Lst_IsEmpty(sysMkPath)) 752 Fatal("make: no system rules (%s).", _PATH_DEFSYSMK); 753 ln = Lst_Find(sysMkPath, (ClientData)NULL, ReadMakefile); 754 if (ln != NILLNODE) 755 Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 756 } 757 758 if (!Lst_IsEmpty(makefiles)) { 759 LstNode ln; 760 761 ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile); 762 if (ln != NILLNODE) 763 Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 764 } else if (!ReadMakefile("makefile", NULL)) 765 (void)ReadMakefile("Makefile", NULL); 766 767 (void)ReadMakefile(".depend", NULL); 768 769 Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL); 770 efree(p1); 771 772 /* Install all the flags into the MAKE envariable. */ 773 if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1)) != NULL) && *p) 774#ifdef POSIX 775 setenv("MAKEFLAGS", p, 1); 776#else 777 setenv("MAKE", p, 1); 778#endif 779 efree(p1); 780 781 /* 782 * For compatibility, look at the directories in the VPATH variable 783 * and add them to the search path, if the variable is defined. The 784 * variable's value is in the same format as the PATH envariable, i.e. 785 * <directory>:<directory>:<directory>... 786 */ 787 if (Var_Exists("VPATH", VAR_CMD)) { 788 char *vpath, *path, *cp, savec; 789 /* 790 * GCC stores string constants in read-only memory, but 791 * Var_Subst will want to write this thing, so store it 792 * in an array 793 */ 794 static char VPATH[] = "${VPATH}"; 795 796 vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE); 797 path = vpath; 798 do { 799 /* skip to end of directory */ 800 for (cp = path; *cp != ':' && *cp != '\0'; cp++) 801 continue; 802 /* Save terminator character so know when to stop */ 803 savec = *cp; 804 *cp = '\0'; 805 /* Add directory to search path */ 806 Dir_AddDir(dirSearchPath, path); 807 *cp = savec; 808 path = cp + 1; 809 } while (savec == ':'); 810 (void)free((Address)vpath); 811 } 812 813 /* 814 * Now that all search paths have been read for suffixes et al, it's 815 * time to add the default search path to their lists... 816 */ 817 Suff_DoPaths(); 818 819 /* print the initial graph, if the user requested it */ 820 if (DEBUG(GRAPH1)) 821 Targ_PrintGraph(1); 822 823 /* print the values of any variables requested by the user */ 824 if (printVars) { 825 LstNode ln; 826 827 for (ln = Lst_First(variables); ln != NILLNODE; 828 ln = Lst_Succ(ln)) { 829 char *value = Var_Subst(NULL, (char *)Lst_Datum(ln), 830 VAR_GLOBAL, FALSE); 831 832 printf("%s\n", value ? value : ""); 833 } 834 } 835 836 /* 837 * Have now read the entire graph and need to make a list of targets 838 * to create. If none was given on the command line, we consult the 839 * parsing module to find the main target(s) to create. 840 */ 841 if (Lst_IsEmpty(create)) 842 targs = Parse_MainName(); 843 else 844 targs = Targ_FindList(create, TARG_CREATE); 845 846 if (!compatMake && !printVars) { 847 /* 848 * Initialize job module before traversing the graph, now that 849 * any .BEGIN and .END targets have been read. This is done 850 * only if the -q flag wasn't given (to prevent the .BEGIN from 851 * being executed should it exist). 852 */ 853 if (!queryFlag) { 854 if (maxLocal == -1) 855 maxLocal = maxJobs; 856 Job_Init(maxJobs, maxLocal); 857 jobsRunning = TRUE; 858 } 859 860 /* Traverse the graph, checking on all the targets */ 861 outOfDate = Make_Run(targs); 862 } else if (!printVars) { 863 /* 864 * Compat_Init will take care of creating all the targets as 865 * well as initializing the module. 866 */ 867 Compat_Run(targs); 868 } 869 870 Lst_Destroy(targs, NOFREE); 871 Lst_Destroy(variables, NOFREE); 872 Lst_Destroy(makefiles, NOFREE); 873 Lst_Destroy(create, (void (*) __P((ClientData))) free); 874 875 /* print the graph now it's been processed if the user requested it */ 876 if (DEBUG(GRAPH2)) 877 Targ_PrintGraph(2); 878 879 Suff_End(); 880 Targ_End(); 881 Arch_End(); 882 str_end(); 883 Var_End(); 884 Parse_End(); 885 Dir_End(); 886 887 if (queryFlag && outOfDate) 888 return(1); 889 else 890 return(0); 891} 892 893/*- 894 * ReadMakefile -- 895 * Open and parse the given makefile. 896 * 897 * Results: 898 * TRUE if ok. FALSE if couldn't open file. 899 * 900 * Side Effects: 901 * lots 902 */ 903static Boolean 904ReadMakefile(p, q) 905 ClientData p, q; 906{ 907 char *fname = p; /* makefile to read */ 908 extern Lst parseIncPath; 909 FILE *stream; 910 char *name, path[MAXPATHLEN + 1]; 911 912 if (!strcmp(fname, "-")) { 913 Parse_File("(stdin)", stdin); 914 Var_Set("MAKEFILE", "", VAR_GLOBAL); 915 } else { 916 /* if we've chdir'd, rebuild the path name */ 917 if (curdir != objdir && *fname != '/') { 918 (void)sprintf(path, "%s/%s", curdir, fname); 919 if ((stream = fopen(path, "r")) != NULL) { 920 fname = path; 921 goto found; 922 } 923 } else if ((stream = fopen(fname, "r")) != NULL) 924 goto found; 925 /* look in -I and system include directories. */ 926 name = Dir_FindFile(fname, parseIncPath); 927 if (!name) 928 name = Dir_FindFile(fname, sysIncPath); 929 if (!name || !(stream = fopen(name, "r"))) 930 return(FALSE); 931 fname = name; 932 /* 933 * set the MAKEFILE variable desired by System V fans -- the 934 * placement of the setting here means it gets set to the last 935 * makefile specified, as it is set by SysV make. 936 */ 937found: Var_Set("MAKEFILE", fname, VAR_GLOBAL); 938 Parse_File(fname, stream); 939 (void)fclose(stream); 940 } 941 return(TRUE); 942} 943 944/*- 945 * Cmd_Exec -- 946 * Execute the command in cmd, and return the output of that command 947 * in a string. 948 * 949 * Results: 950 * A string containing the output of the command, or the empty string 951 * If err is not NULL, it contains the reason for the command failure 952 * 953 * Side Effects: 954 * The string must be freed by the caller. 955 */ 956char * 957Cmd_Exec(cmd, err) 958 char *cmd; 959 char **err; 960{ 961 char *args[4]; /* Args for invoking the shell */ 962 int fds[2]; /* Pipe streams */ 963 int cpid; /* Child PID */ 964 int pid; /* PID from wait() */ 965 char *res; /* result */ 966 int status; /* command exit status */ 967 Buffer buf; /* buffer to store the result */ 968 char *cp; 969 int cc; 970 971 972 *err = NULL; 973 974 /* 975 * Set up arguments for shell 976 */ 977 args[0] = "sh"; 978 args[1] = "-c"; 979 args[2] = cmd; 980 args[3] = NULL; 981 982 /* 983 * Open a pipe for fetching its output 984 */ 985 if (pipe(fds) == -1) { 986 *err = "Couldn't create pipe for \"%s\""; 987 goto bad; 988 } 989 990 /* 991 * Fork 992 */ 993 switch (cpid = vfork()) { 994 case 0: 995 /* 996 * Close input side of pipe 997 */ 998 (void) close(fds[0]); 999 1000 /* 1001 * Duplicate the output stream to the shell's output, then 1002 * shut the extra thing down. Note we don't fetch the error 1003 * stream...why not? Why? 1004 */ 1005 (void) dup2(fds[1], 1); 1006 (void) close(fds[1]); 1007 1008 (void) execv("/bin/sh", args); 1009 _exit(1); 1010 /*NOTREACHED*/ 1011 1012 case -1: 1013 *err = "Couldn't exec \"%s\""; 1014 goto bad; 1015 1016 default: 1017 /* 1018 * No need for the writing half 1019 */ 1020 (void) close(fds[1]); 1021 1022 buf = Buf_Init (MAKE_BSIZE); 1023 1024 do { 1025 char result[BUFSIZ]; 1026 cc = read(fds[0], result, sizeof(result)); 1027 if (cc > 0) 1028 Buf_AddBytes(buf, cc, (Byte *) result); 1029 } 1030 while (cc > 0 || (cc == -1 && errno == EINTR)); 1031 1032 /* 1033 * Close the input side of the pipe. 1034 */ 1035 (void) close(fds[0]); 1036 1037 /* 1038 * Wait for the process to exit. 1039 */ 1040 while(((pid = wait(&status)) != cpid) && (pid >= 0)) 1041 continue; 1042 1043 if (cc == -1) 1044 *err = "Error reading shell's output for \"%s\""; 1045 1046 res = (char *)Buf_GetAll (buf, &cc); 1047 Buf_Destroy (buf, FALSE); 1048 1049 if (status) 1050 *err = "\"%s\" returned non-zero status"; 1051 1052 /* 1053 * Null-terminate the result, convert newlines to spaces and 1054 * install it in the variable. 1055 */ 1056 res[cc] = '\0'; 1057 cp = &res[cc] - 1; 1058 1059 if (*cp == '\n') { 1060 /* 1061 * A final newline is just stripped 1062 */ 1063 *cp-- = '\0'; 1064 } 1065 while (cp >= res) { 1066 if (*cp == '\n') { 1067 *cp = ' '; 1068 } 1069 cp--; 1070 } 1071 break; 1072 } 1073 return res; 1074bad: 1075 res = emalloc(1); 1076 *res = '\0'; 1077 return res; 1078} 1079 1080/*- 1081 * Error -- 1082 * Print an error message given its format. 1083 * 1084 * Results: 1085 * None. 1086 * 1087 * Side Effects: 1088 * The message is printed. 1089 */ 1090/* VARARGS */ 1091void 1092#ifdef __STDC__ 1093Error(char *fmt, ...) 1094#else 1095Error(va_alist) 1096 va_dcl 1097#endif 1098{ 1099 va_list ap; 1100#ifdef __STDC__ 1101 va_start(ap, fmt); 1102#else 1103 char *fmt; 1104 1105 va_start(ap); 1106 fmt = va_arg(ap, char *); 1107#endif 1108 (void)vfprintf(stderr, fmt, ap); 1109 va_end(ap); 1110 (void)fprintf(stderr, "\n"); 1111 (void)fflush(stderr); 1112} 1113 1114/*- 1115 * Fatal -- 1116 * Produce a Fatal error message. If jobs are running, waits for them 1117 * to finish. 1118 * 1119 * Results: 1120 * None 1121 * 1122 * Side Effects: 1123 * The program exits 1124 */ 1125/* VARARGS */ 1126void 1127#ifdef __STDC__ 1128Fatal(char *fmt, ...) 1129#else 1130Fatal(va_alist) 1131 va_dcl 1132#endif 1133{ 1134 va_list ap; 1135#ifdef __STDC__ 1136 va_start(ap, fmt); 1137#else 1138 char *fmt; 1139 1140 va_start(ap); 1141 fmt = va_arg(ap, char *); 1142#endif 1143 if (jobsRunning) 1144 Job_Wait(); 1145 1146 (void)vfprintf(stderr, fmt, ap); 1147 va_end(ap); 1148 (void)fprintf(stderr, "\n"); 1149 (void)fflush(stderr); 1150 1151 if (DEBUG(GRAPH2)) 1152 Targ_PrintGraph(2); 1153 exit(2); /* Not 1 so -q can distinguish error */ 1154} 1155 1156/* 1157 * Punt -- 1158 * Major exception once jobs are being created. Kills all jobs, prints 1159 * a message and exits. 1160 * 1161 * Results: 1162 * None 1163 * 1164 * Side Effects: 1165 * All children are killed indiscriminately and the program Lib_Exits 1166 */ 1167/* VARARGS */ 1168void 1169#ifdef __STDC__ 1170Punt(char *fmt, ...) 1171#else 1172Punt(va_alist) 1173 va_dcl 1174#endif 1175{ 1176 va_list ap; 1177#if __STDC__ 1178 va_start(ap, fmt); 1179#else 1180 char *fmt; 1181 1182 va_start(ap); 1183 fmt = va_arg(ap, char *); 1184#endif 1185 1186 (void)fprintf(stderr, "make: "); 1187 (void)vfprintf(stderr, fmt, ap); 1188 va_end(ap); 1189 (void)fprintf(stderr, "\n"); 1190 (void)fflush(stderr); 1191 1192 DieHorribly(); 1193} 1194 1195/*- 1196 * DieHorribly -- 1197 * Exit without giving a message. 1198 * 1199 * Results: 1200 * None 1201 * 1202 * Side Effects: 1203 * A big one... 1204 */ 1205void 1206DieHorribly() 1207{ 1208 if (jobsRunning) 1209 Job_AbortAll(); 1210 if (DEBUG(GRAPH2)) 1211 Targ_PrintGraph(2); 1212 exit(2); /* Not 1, so -q can distinguish error */ 1213} 1214 1215/* 1216 * Finish -- 1217 * Called when aborting due to errors in child shell to signal 1218 * abnormal exit. 1219 * 1220 * Results: 1221 * None 1222 * 1223 * Side Effects: 1224 * The program exits 1225 */ 1226void 1227Finish(errors) 1228 int errors; /* number of errors encountered in Make_Make */ 1229{ 1230 Fatal("%d error%s", errors, errors == 1 ? "" : "s"); 1231} 1232 1233/* 1234 * emalloc -- 1235 * malloc, but die on error. 1236 */ 1237void * 1238emalloc(len) 1239 size_t len; 1240{ 1241 void *p; 1242 1243 if ((p = malloc(len)) == NULL) 1244 enomem(); 1245 return(p); 1246} 1247 1248/* 1249 * estrdup -- 1250 * strdup, but die on error. 1251 */ 1252char * 1253estrdup(str) 1254 const char *str; 1255{ 1256 char *p; 1257 1258 if ((p = strdup(str)) == NULL) 1259 enomem(); 1260 return(p); 1261} 1262 1263/* 1264 * erealloc -- 1265 * realloc, but die on error. 1266 */ 1267void * 1268erealloc(ptr, size) 1269 void *ptr; 1270 size_t size; 1271{ 1272 if ((ptr = realloc(ptr, size)) == NULL) 1273 enomem(); 1274 return(ptr); 1275} 1276 1277/* 1278 * enomem -- 1279 * die when out of memory. 1280 */ 1281void 1282enomem() 1283{ 1284 err(2, NULL); 1285} 1286 1287/* 1288 * enunlink -- 1289 * Remove a file carefully, avoiding directories. 1290 */ 1291int 1292eunlink(file) 1293 const char *file; 1294{ 1295 struct stat st; 1296 1297 if (lstat(file, &st) == -1) 1298 return -1; 1299 1300 if (S_ISDIR(st.st_mode)) { 1301 errno = EISDIR; 1302 return -1; 1303 } 1304 return unlink(file); 1305} 1306 1307/* 1308 * usage -- 1309 * exit with usage message 1310 */ 1311static void 1312usage() 1313{ 1314 (void)fprintf(stderr, "%s\n%s\n%s\n", 1315"usage: make [-Beiknqrstv] [-D variable] [-d flags] [-E variable] [-f makefile]", 1316" [-I directory] [-j max_jobs] [-m directory] [-V variable]", 1317" [variable=value] [target ...]"); 1318 exit(2); 1319} 1320 1321 1322int 1323PrintAddr(a, b) 1324 ClientData a; 1325 ClientData b; 1326{ 1327 printf("%lx ", (unsigned long) a); 1328 return b ? 0 : 0; 1329} 1330