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