main.c revision 146060
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#if 0 43static char copyright[] = 44"@(#) Copyright (c) 1988, 1989, 1990, 1993\n\ 45 The Regents of the University of California. All rights reserved.\n"; 46#endif 47#endif /* not lint */ 48#include <sys/cdefs.h> 49__FBSDID("$FreeBSD: head/usr.bin/make/main.c 146060 2005-05-10 14:10:44Z harti $"); 50 51/* 52 * main.c 53 * The main file for this entire program. Exit routines etc 54 * reside here. 55 * 56 * Utility functions defined in this file: 57 * Main_ParseArgLine 58 * Takes a line of arguments, breaks them and 59 * treats them as if they were given when first 60 * invoked. Used by the parse module to implement 61 * the .MFLAGS target. 62 */ 63 64#ifndef MACHINE 65#include <sys/utsname.h> 66#endif 67#include <sys/param.h> 68#include <sys/stat.h> 69#include <sys/sysctl.h> 70#include <sys/time.h> 71#include <sys/queue.h> 72#include <sys/resource.h> 73#include <sys/wait.h> 74#include <err.h> 75#include <errno.h> 76#include <signal.h> 77#include <stdlib.h> 78#include <string.h> 79#include <unistd.h> 80 81#include "arch.h" 82#include "buf.h" 83#include "config.h" 84#include "dir.h" 85#include "globals.h" 86#include "job.h" 87#include "make.h" 88#include "parse.h" 89#include "pathnames.h" 90#include "str.h" 91#include "suff.h" 92#include "targ.h" 93#include "util.h" 94#include "var.h" 95 96#define WANT_ENV_MKLVL 1 97#define MKLVL_MAXVAL 500 98#define MKLVL_ENVVAR "__MKLVL__" 99 100#define MAKEFLAGS ".MAKEFLAGS" 101 102extern char **environ; /* XXX what header declares this variable? */ 103 104/* Targets to be made */ 105Lst create = Lst_Initializer(create); 106 107time_t now; /* Time at start of make */ 108struct GNode *DEFAULT; /* .DEFAULT node */ 109Boolean allPrecious; /* .PRECIOUS given on line by itself */ 110uint32_t warn_flags; /* actual warning flags */ 111uint32_t warn_cmd; /* command line warning flags */ 112uint32_t warn_nocmd; /* command line no-warning flags */ 113 114static Boolean noBuiltins; /* -r flag */ 115 116/* ordered list of makefiles to read */ 117static Lst makefiles = Lst_Initializer(makefiles); 118 119static Boolean expandVars; /* fully expand printed variables */ 120 121/* list of variables to print */ 122static Lst variables = Lst_Initializer(variables); 123 124int maxJobs; /* -j argument */ 125static Boolean forceJobs; /* -j argument given */ 126Boolean compatMake; /* -B argument */ 127Boolean debug; /* -d flag */ 128Boolean noExecute; /* -n flag */ 129Boolean keepgoing; /* -k flag */ 130Boolean queryFlag; /* -q flag */ 131Boolean touchFlag; /* -t flag */ 132Boolean usePipes; /* !-P flag */ 133Boolean ignoreErrors; /* -i flag */ 134Boolean beSilent; /* -s flag */ 135Boolean beVerbose; /* -v flag */ 136Boolean oldVars; /* variable substitution style */ 137Boolean checkEnvFirst; /* -e flag */ 138 139/* (-E) vars to override from env */ 140Lst envFirstVars = Lst_Initializer(envFirstVars); 141 142Boolean jobsRunning; /* TRUE if the jobs might be running */ 143 144char *chdir_verify_path(const char *, char *); 145static int ReadMakefile(const char *); 146static void usage(void); 147 148static char *curdir; /* startup directory */ 149static char *objdir; /* where we chdir'ed to */ 150 151/** 152 * MFLAGS_append 153 * Append a flag with an optional argument to MAKEFLAGS and MFLAGS 154 */ 155static void 156MFLAGS_append(const char *flag, char *arg) 157{ 158 char *str; 159 160 Var_Append(MAKEFLAGS, flag, VAR_GLOBAL); 161 if (arg != NULL) { 162 str = MAKEFLAGS_quote(arg); 163 Var_Append(MAKEFLAGS, str, VAR_GLOBAL); 164 free(str); 165 } 166 167 Var_Append("MFLAGS", flag, VAR_GLOBAL); 168 if (arg != NULL) { 169 str = MAKEFLAGS_quote(arg); 170 Var_Append("MFLAGS", str, VAR_GLOBAL); 171 free(str); 172 } 173} 174 175/** 176 * Main_ParseWarn 177 * 178 * Handle argument to warning option. 179 */ 180int 181Main_ParseWarn(const char *arg, int iscmd) 182{ 183 int i, neg; 184 185 static const struct { 186 const char *option; 187 uint32_t flag; 188 } options[] = { 189 { "dirsyntax", WARN_DIRSYNTAX }, 190 { NULL, 0 } 191 }; 192 193 neg = 0; 194 if (arg[0] == 'n' && arg[1] == 'o') { 195 neg = 1; 196 arg += 2; 197 } 198 199 for (i = 0; options[i].option != NULL; i++) 200 if (strcmp(arg, options[i].option) == 0) 201 break; 202 203 if (options[i].option == NULL) 204 /* unknown option */ 205 return (-1); 206 207 if (iscmd) { 208 if (!neg) { 209 warn_cmd |= options[i].flag; 210 warn_nocmd &= ~options[i].flag; 211 warn_flags |= options[i].flag; 212 } else { 213 warn_nocmd |= options[i].flag; 214 warn_cmd &= ~options[i].flag; 215 warn_flags &= ~options[i].flag; 216 } 217 } else { 218 if (!neg) { 219 warn_flags |= (options[i].flag & ~warn_nocmd); 220 } else { 221 warn_flags &= ~(options[i].flag | warn_cmd); 222 } 223 } 224 return (0); 225} 226 227/** 228 * MainParseArgs 229 * Parse a given argument vector. Called from main() and from 230 * Main_ParseArgLine() when the .MAKEFLAGS target is used. 231 * 232 * XXX: Deal with command line overriding .MAKEFLAGS in makefile 233 * 234 * Side Effects: 235 * Various global and local flags will be set depending on the flags 236 * given 237 */ 238static void 239MainParseArgs(int argc, char **argv) 240{ 241 int c; 242 Boolean found_dd = FALSE; 243 244rearg: 245 optind = 1; /* since we're called more than once */ 246 optreset = 1; 247#define OPTFLAGS "ABC:D:E:I:PSV:Xd:ef:ij:km:nqrstvx:" 248 for (;;) { 249 if ((optind < argc) && strcmp(argv[optind], "--") == 0) { 250 found_dd = TRUE; 251 } 252 if ((c = getopt(argc, argv, OPTFLAGS)) == -1) { 253 break; 254 } 255 switch(c) { 256 257 case 'A': 258 arch_fatal = FALSE; 259 MFLAGS_append("-A", NULL); 260 break; 261 case 'C': 262 if (chdir(optarg) == -1) 263 err(1, "chdir %s", optarg); 264 break; 265 case 'D': 266 Var_Set(optarg, "1", VAR_GLOBAL); 267 MFLAGS_append("-D", optarg); 268 break; 269 case 'I': 270 Parse_AddIncludeDir(optarg); 271 MFLAGS_append("-I", optarg); 272 break; 273 case 'V': 274 Lst_AtEnd(&variables, estrdup(optarg)); 275 MFLAGS_append("-V", optarg); 276 break; 277 case 'X': 278 expandVars = FALSE; 279 break; 280 case 'B': 281 compatMake = TRUE; 282 MFLAGS_append("-B", NULL); 283 unsetenv("MAKE_JOBS_FIFO"); 284 break; 285 case 'P': 286 usePipes = FALSE; 287 MFLAGS_append("-P", NULL); 288 break; 289 case 'S': 290 keepgoing = FALSE; 291 MFLAGS_append("-S", NULL); 292 break; 293 case 'd': { 294 char *modules = optarg; 295 296 for (; *modules; ++modules) 297 switch (*modules) { 298 case 'A': 299 debug = ~0; 300 break; 301 case 'a': 302 debug |= DEBUG_ARCH; 303 break; 304 case 'c': 305 debug |= DEBUG_COND; 306 break; 307 case 'd': 308 debug |= DEBUG_DIR; 309 break; 310 case 'f': 311 debug |= DEBUG_FOR; 312 break; 313 case 'g': 314 if (modules[1] == '1') { 315 debug |= DEBUG_GRAPH1; 316 ++modules; 317 } 318 else if (modules[1] == '2') { 319 debug |= DEBUG_GRAPH2; 320 ++modules; 321 } 322 break; 323 case 'j': 324 debug |= DEBUG_JOB; 325 break; 326 case 'l': 327 debug |= DEBUG_LOUD; 328 break; 329 case 'm': 330 debug |= DEBUG_MAKE; 331 break; 332 case 's': 333 debug |= DEBUG_SUFF; 334 break; 335 case 't': 336 debug |= DEBUG_TARG; 337 break; 338 case 'v': 339 debug |= DEBUG_VAR; 340 break; 341 default: 342 warnx("illegal argument to d option " 343 "-- %c", *modules); 344 usage(); 345 } 346 MFLAGS_append("-d", optarg); 347 break; 348 } 349 case 'E': 350 Lst_AtEnd(&envFirstVars, estrdup(optarg)); 351 MFLAGS_append("-E", optarg); 352 break; 353 case 'e': 354 checkEnvFirst = TRUE; 355 MFLAGS_append("-e", NULL); 356 break; 357 case 'f': 358 Lst_AtEnd(&makefiles, estrdup(optarg)); 359 break; 360 case 'i': 361 ignoreErrors = TRUE; 362 MFLAGS_append("-i", NULL); 363 break; 364 case 'j': { 365 char *endptr; 366 367 forceJobs = TRUE; 368 maxJobs = strtol(optarg, &endptr, 10); 369 if (maxJobs <= 0 || *endptr != '\0') { 370 warnx("illegal number, -j argument -- %s", 371 optarg); 372 usage(); 373 } 374 MFLAGS_append("-j", optarg); 375 break; 376 } 377 case 'k': 378 keepgoing = TRUE; 379 MFLAGS_append("-k", NULL); 380 break; 381 case 'm': 382 Path_AddDir(&sysIncPath, optarg); 383 MFLAGS_append("-m", optarg); 384 break; 385 case 'n': 386 noExecute = TRUE; 387 MFLAGS_append("-n", NULL); 388 break; 389 case 'q': 390 queryFlag = TRUE; 391 /* Kind of nonsensical, wot? */ 392 MFLAGS_append("-q", NULL); 393 break; 394 case 'r': 395 noBuiltins = TRUE; 396 MFLAGS_append("-r", NULL); 397 break; 398 case 's': 399 beSilent = TRUE; 400 MFLAGS_append("-s", NULL); 401 break; 402 case 't': 403 touchFlag = TRUE; 404 MFLAGS_append("-t", NULL); 405 break; 406 case 'v': 407 beVerbose = TRUE; 408 MFLAGS_append("-v", NULL); 409 break; 410 case 'x': 411 if (Main_ParseWarn(optarg, 1) != -1) 412 MFLAGS_append("-x", optarg); 413 break; 414 415 default: 416 case '?': 417 usage(); 418 } 419 } 420 argv += optind; 421 argc -= optind; 422 423 oldVars = TRUE; 424 425 /* 426 * Parse the rest of the arguments. 427 * o Check for variable assignments and perform them if so. 428 * o Check for more flags and restart getopt if so. 429 * o Anything else is taken to be a target and added 430 * to the end of the "create" list. 431 */ 432 for (; *argv != NULL; ++argv, --argc) { 433 if (Parse_IsVar(*argv)) { 434 char *ptr = MAKEFLAGS_quote(*argv); 435 436 Var_Append(MAKEFLAGS, ptr, VAR_GLOBAL); 437 Parse_DoVar(*argv, VAR_CMD); 438 free(ptr); 439 440 } else if ((*argv)[0] == '-') { 441 if ((*argv)[1] == '\0') { 442 /* 443 * (*argv) is a single dash, so we 444 * just ignore it. 445 */ 446 } else if (found_dd) { 447 /* 448 * Double dash has been found, ignore 449 * any more options. But what do we do 450 * with it? For now treat it like a target. 451 */ 452 Lst_AtEnd(&create, estrdup(*argv)); 453 } else { 454 /* 455 * (*argv) is a -flag, so backup argv and 456 * argc. getopt() expects options to start 457 * in the 2nd position. 458 */ 459 argc++; 460 argv--; 461 goto rearg; 462 } 463 464 } else if ((*argv)[0] == '\0') { 465 Punt("illegal (null) argument."); 466 467 } else { 468 Lst_AtEnd(&create, estrdup(*argv)); 469 } 470 } 471} 472 473/** 474 * Main_ParseArgLine 475 * Used by the parse module when a .MFLAGS or .MAKEFLAGS target 476 * is encountered and by main() when reading the .MAKEFLAGS envariable. 477 * Takes a line of arguments and breaks it into its 478 * component words and passes those words and the number of them to the 479 * MainParseArgs function. 480 * The line should have all its leading whitespace removed. 481 * 482 * Side Effects: 483 * Only those that come from the various arguments. 484 */ 485void 486Main_ParseArgLine(char *line, int mflags) 487{ 488 char **argv; /* Manufactured argument vector */ 489 int argc; /* Number of arguments in argv */ 490 491 if (line == NULL) 492 return; 493 for (; *line == ' '; ++line) 494 continue; 495 if (!*line) 496 return; 497 498 if (mflags) 499 argv = MAKEFLAGS_break(line, &argc); 500 else 501 argv = brk_string(line, &argc, TRUE); 502 503 MainParseArgs(argc, argv); 504} 505 506char * 507chdir_verify_path(const char *path, char *obpath) 508{ 509 struct stat sb; 510 511 if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { 512 if (chdir(path) == -1 || getcwd(obpath, MAXPATHLEN) == NULL) { 513 warn("warning: %s", path); 514 return (NULL); 515 } 516 return (obpath); 517 } 518 519 return (NULL); 520} 521 522static void 523catch_child(int sig __unused) 524{ 525} 526 527/* 528 * In lieu of a good way to prevent every possible looping in 529 * make(1), stop there from being more than MKLVL_MAXVAL processes forked 530 * by make(1), to prevent a forkbomb from happening, in a dumb and 531 * mechanical way. 532 */ 533static void 534check_make_level(void) 535{ 536#ifdef WANT_ENV_MKLVL 537 char *value = getenv(MKLVL_ENVVAR); 538 int level = (value == NULL) ? 0 : atoi(value); 539 540 if (level < 0) { 541 errc(2, EAGAIN, "Invalid value for recursion level (%d).", 542 level); 543 } else if (level > MKLVL_MAXVAL) { 544 errc(2, EAGAIN, "Max recursion level (%d) exceeded.", 545 MKLVL_MAXVAL); 546 } else { 547 char new_value[32]; 548 sprintf(new_value, "%d", level + 1); 549 setenv(MKLVL_ENVVAR, new_value, 1); 550 } 551#endif /* WANT_ENV_MKLVL */ 552} 553 554/** 555 * main 556 * The main function, for obvious reasons. Initializes variables 557 * and a few modules, then parses the arguments give it in the 558 * environment and on the command line. Reads the system makefile 559 * followed by either Makefile, makefile or the file given by the 560 * -f argument. Sets the .MAKEFLAGS PMake variable based on all the 561 * flags it has received by then uses either the Make or the Compat 562 * module to create the initial list of targets. 563 * 564 * Results: 565 * If -q was given, exits -1 if anything was out-of-date. Else it exits 566 * 0. 567 * 568 * Side Effects: 569 * The program exits when done. Targets are created. etc. etc. etc. 570 */ 571int 572main(int argc, char **argv) 573{ 574 Boolean outOfDate = TRUE; /* FALSE if all targets up to date */ 575 char *p, *p1, *pathp; 576 char *path; 577 char mdpath[MAXPATHLEN]; 578 char obpath[MAXPATHLEN]; 579 char cdpath[MAXPATHLEN]; 580 const char *machine = getenv("MACHINE"); 581 const char *machine_arch = getenv("MACHINE_ARCH"); 582 const char *machine_cpu = getenv("MACHINE_CPU"); 583 char *cp = NULL, *start; 584 585 /* avoid faults on read-only strings */ 586 static char syspath[] = PATH_DEFSYSPATH; 587 588 { 589 /* 590 * Catch SIGCHLD so that we get kicked out of select() when we 591 * need to look at a child. This is only known to matter for the 592 * -j case (perhaps without -P). 593 * 594 * XXX this is intentionally misplaced. 595 */ 596 struct sigaction sa; 597 598 sigemptyset(&sa.sa_mask); 599 sa.sa_flags = SA_RESTART | SA_NOCLDSTOP; 600 sa.sa_handler = catch_child; 601 sigaction(SIGCHLD, &sa, NULL); 602 } 603 604 check_make_level(); 605 606#if DEFSHELL == 2 607 /* 608 * Turn off ENV to make ksh happier. 609 */ 610 unsetenv("ENV"); 611#endif 612 613#ifdef RLIMIT_NOFILE 614 /* 615 * get rid of resource limit on file descriptors 616 */ 617 { 618 struct rlimit rl; 619 if (getrlimit(RLIMIT_NOFILE, &rl) != -1 && 620 rl.rlim_cur != rl.rlim_max) { 621 rl.rlim_cur = rl.rlim_max; 622 setrlimit(RLIMIT_NOFILE, &rl); 623 } 624 } 625#endif 626 627 /* 628 * PC-98 kernel sets the `i386' string to the utsname.machine and 629 * it cannot be distinguished from IBM-PC by uname(3). Therefore, 630 * we check machine.ispc98 and adjust the machine variable before 631 * using usname(3) below. 632 * NOTE: machdep.ispc98 was defined on 1998/8/31. At that time, 633 * __FreeBSD_version was defined as 300003. So, this check can 634 * safely be done with any kernel with version > 300003. 635 */ 636 if (!machine) { 637 int ispc98; 638 size_t len; 639 640 len = sizeof(ispc98); 641 if (!sysctlbyname("machdep.ispc98", &ispc98, &len, NULL, 0)) { 642 if (ispc98) 643 machine = "pc98"; 644 } 645 } 646 647 /* 648 * Get the name of this type of MACHINE from utsname 649 * so we can share an executable for similar machines. 650 * (i.e. m68k: amiga hp300, mac68k, sun3, ...) 651 * 652 * Note that while MACHINE is decided at run-time, 653 * MACHINE_ARCH is always known at compile time. 654 */ 655 if (!machine) { 656#ifndef MACHINE 657 static struct utsname utsname; 658 659 if (uname(&utsname) == -1) 660 err(2, "uname"); 661 machine = utsname.machine; 662#else 663 machine = MACHINE; 664#endif 665 } 666 667 if (!machine_arch) { 668#ifndef MACHINE_ARCH 669 machine_arch = "unknown"; 670#else 671 machine_arch = MACHINE_ARCH; 672#endif 673 } 674 675 /* 676 * Set machine_cpu to the minumum supported CPU revision based 677 * on the target architecture, if not already set. 678 */ 679 if (!machine_cpu) { 680 if (!strcmp(machine_arch, "i386")) 681 machine_cpu = "i386"; 682 else if (!strcmp(machine_arch, "alpha")) 683 machine_cpu = "ev4"; 684 else 685 machine_cpu = "unknown"; 686 } 687 688 expandVars = TRUE; 689 beSilent = FALSE; /* Print commands as executed */ 690 ignoreErrors = FALSE; /* Pay attention to non-zero returns */ 691 noExecute = FALSE; /* Execute all commands */ 692 keepgoing = FALSE; /* Stop on error */ 693 allPrecious = FALSE; /* Remove targets when interrupted */ 694 queryFlag = FALSE; /* This is not just a check-run */ 695 noBuiltins = FALSE; /* Read the built-in rules */ 696 touchFlag = FALSE; /* Actually update targets */ 697 usePipes = TRUE; /* Catch child output in pipes */ 698 debug = 0; /* No debug verbosity, please. */ 699 jobsRunning = FALSE; 700 701 maxJobs = DEFMAXJOBS; 702 forceJobs = FALSE; /* No -j flag */ 703 compatMake = FALSE; /* No compat mode */ 704 705 /* 706 * Initialize the parsing, directory and variable modules to prepare 707 * for the reading of inclusion paths and variable settings on the 708 * command line 709 */ 710 Dir_Init(); /* Initialize directory structures so -I flags 711 * can be processed correctly */ 712 Var_Init(environ); /* As well as the lists of variables for 713 * parsing arguments */ 714 str_init(); 715 716 /* 717 * Initialize various variables. 718 * MAKE also gets this name, for compatibility 719 * .MAKEFLAGS gets set to the empty string just in case. 720 * MFLAGS also gets initialized empty, for compatibility. 721 */ 722 Var_Set("MAKE", argv[0], VAR_GLOBAL); 723 Var_Set(MAKEFLAGS, "", VAR_GLOBAL); 724 Var_Set("MFLAGS", "", VAR_GLOBAL); 725 Var_Set("MACHINE", machine, VAR_GLOBAL); 726 Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL); 727 Var_Set("MACHINE_CPU", machine_cpu, VAR_GLOBAL); 728#ifdef MAKE_VERSION 729 Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL); 730#endif 731 732 /* 733 * First snag things out of the MAKEFLAGS environment 734 * variable. Then parse the command line arguments. 735 */ 736 Main_ParseArgLine(getenv("MAKEFLAGS"), 1); 737 738 MainParseArgs(argc, argv); 739 740 /* 741 * Find where we are... 742 */ 743 curdir = cdpath; 744 if (getcwd(curdir, MAXPATHLEN) == NULL) 745 err(2, NULL); 746 747 { 748 struct stat sa; 749 750 if (stat(curdir, &sa) == -1) 751 err(2, "%s", curdir); 752 } 753 754 /* 755 * The object directory location is determined using the 756 * following order of preference: 757 * 758 * 1. MAKEOBJDIRPREFIX`cwd` 759 * 2. MAKEOBJDIR 760 * 3. PATH_OBJDIR.${MACHINE} 761 * 4. PATH_OBJDIR 762 * 5. PATH_OBJDIRPREFIX`cwd` 763 * 764 * If one of the first two fails, use the current directory. 765 * If the remaining three all fail, use the current directory. 766 * 767 * Once things are initted, 768 * have to add the original directory to the search path, 769 * and modify the paths for the Makefiles apropriately. The 770 * current directory is also placed as a variable for make scripts. 771 */ 772 if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) { 773 if (!(path = getenv("MAKEOBJDIR"))) { 774 path = PATH_OBJDIR; 775 pathp = PATH_OBJDIRPREFIX; 776 snprintf(mdpath, MAXPATHLEN, "%s.%s", 777 path, machine); 778 if (!(objdir = chdir_verify_path(mdpath, obpath))) 779 if (!(objdir=chdir_verify_path(path, obpath))) { 780 snprintf(mdpath, MAXPATHLEN, 781 "%s%s", pathp, curdir); 782 if (!(objdir=chdir_verify_path(mdpath, 783 obpath))) 784 objdir = curdir; 785 } 786 } 787 else if (!(objdir = chdir_verify_path(path, obpath))) 788 objdir = curdir; 789 } 790 else { 791 snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir); 792 if (!(objdir = chdir_verify_path(mdpath, obpath))) 793 objdir = curdir; 794 } 795 Dir_InitDot(); /* Initialize the "." directory */ 796 if (objdir != curdir) 797 Path_AddDir(&dirSearchPath, curdir); 798 Var_Set(".ST_EXPORTVAR", "YES", VAR_GLOBAL); 799 Var_Set(".CURDIR", curdir, VAR_GLOBAL); 800 Var_Set(".OBJDIR", objdir, VAR_GLOBAL); 801 802 if (getenv("MAKE_JOBS_FIFO") != NULL) 803 forceJobs = TRUE; 804 /* 805 * Be compatible if user did not specify -j and did not explicitly 806 * turned compatibility on 807 */ 808 if (!compatMake && !forceJobs) 809 compatMake = TRUE; 810 811 /* 812 * Initialize target and suffix modules in preparation for 813 * parsing the makefile(s) 814 */ 815 Targ_Init(); 816 Suff_Init(); 817 818 DEFAULT = NULL; 819 time(&now); 820 821 /* 822 * Set up the .TARGETS variable to contain the list of targets to be 823 * created. If none specified, make the variable empty -- the parser 824 * will fill the thing in with the default or .MAIN target. 825 */ 826 if (!Lst_IsEmpty(&create)) { 827 LstNode *ln; 828 829 for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) { 830 char *name = Lst_Datum(ln); 831 832 Var_Append(".TARGETS", name, VAR_GLOBAL); 833 } 834 } else 835 Var_Set(".TARGETS", "", VAR_GLOBAL); 836 837 838 /* 839 * If no user-supplied system path was given (through the -m option) 840 * add the directories from the DEFSYSPATH (more than one may be given 841 * as dir1:...:dirn) to the system include path. 842 */ 843 if (TAILQ_EMPTY(&sysIncPath)) { 844 for (start = syspath; *start != '\0'; start = cp) { 845 for (cp = start; *cp != '\0' && *cp != ':'; cp++) 846 continue; 847 if (*cp == '\0') { 848 Path_AddDir(&sysIncPath, start); 849 } else { 850 *cp++ = '\0'; 851 Path_AddDir(&sysIncPath, start); 852 } 853 } 854 } 855 856 /* 857 * Read in the built-in rules first, followed by the specified 858 * makefile, if it was (makefile != (char *) NULL), or the default 859 * Makefile and makefile, in that order, if it wasn't. 860 */ 861 if (!noBuiltins) { 862 /* Path of sys.mk */ 863 Lst sysMkPath = Lst_Initializer(sysMkPath); 864 LstNode *ln; 865 866 Path_Expand(PATH_DEFSYSMK, &sysIncPath, &sysMkPath); 867 if (Lst_IsEmpty(&sysMkPath)) 868 Fatal("make: no system rules (%s).", PATH_DEFSYSMK); 869 LST_FOREACH(ln, &sysMkPath) { 870 if (!ReadMakefile(Lst_Datum(ln))) 871 break; 872 } 873 if (ln != NULL) 874 Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 875 Lst_Destroy(&sysMkPath, free); 876 } 877 878 if (!Lst_IsEmpty(&makefiles)) { 879 LstNode *ln; 880 881 LST_FOREACH(ln, &makefiles) { 882 if (!ReadMakefile(Lst_Datum(ln))) 883 break; 884 } 885 if (ln != NULL) 886 Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 887 } else if (!ReadMakefile("BSDmakefile")) 888 if (!ReadMakefile("makefile")) 889 ReadMakefile("Makefile"); 890 891 ReadMakefile(".depend"); 892 893 /* Install all the flags into the MAKE envariable. */ 894 if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1)) != NULL) && *p) 895 setenv("MAKEFLAGS", p, 1); 896 free(p1); 897 898 /* 899 * For compatibility, look at the directories in the VPATH variable 900 * and add them to the search path, if the variable is defined. The 901 * variable's value is in the same format as the PATH envariable, i.e. 902 * <directory>:<directory>:<directory>... 903 */ 904 if (Var_Exists("VPATH", VAR_CMD)) { 905 /* 906 * GCC stores string constants in read-only memory, but 907 * Var_Subst will want to write this thing, so store it 908 * in an array 909 */ 910 static char VPATH[] = "${VPATH}"; 911 Buffer *buf; 912 char *vpath; 913 char *ptr; 914 char savec; 915 916 buf = Var_Subst(VPATH, VAR_CMD, FALSE); 917 918 vpath = Buf_Data(buf); 919 do { 920 /* skip to end of directory */ 921 for (ptr = vpath; *ptr != ':' && *ptr != '\0'; ptr++) 922 ; 923 924 /* Save terminator character so know when to stop */ 925 savec = *ptr; 926 *ptr = '\0'; 927 928 /* Add directory to search path */ 929 Path_AddDir(&dirSearchPath, vpath); 930 931 vpath = ptr + 1; 932 } while (savec != '\0'); 933 934 Buf_Destroy(buf, TRUE); 935 } 936 937 /* 938 * Now that all search paths have been read for suffixes et al, it's 939 * time to add the default search path to their lists... 940 */ 941 Suff_DoPaths(); 942 943 /* print the initial graph, if the user requested it */ 944 if (DEBUG(GRAPH1)) 945 Targ_PrintGraph(1); 946 947 /* print the values of any variables requested by the user */ 948 if (Lst_IsEmpty(&variables)) { 949 /* 950 * Since the user has not requested that any variables 951 * be printed, we can build targets. 952 * 953 * Have read the entire graph and need to make a list of targets 954 * to create. If none was given on the command line, we consult 955 * the parsing module to find the main target(s) to create. 956 */ 957 Lst targs = Lst_Initializer(targs); 958 959 if (Lst_IsEmpty(&create)) 960 Parse_MainName(&targs); 961 else 962 Targ_FindList(&targs, &create, TARG_CREATE); 963 964 if (compatMake) { 965 /* 966 * Compat_Init will take care of creating 967 * all the targets as well as initializing 968 * the module. 969 */ 970 Compat_Run(&targs); 971 outOfDate = 0; 972 } else { 973 /* 974 * Initialize job module before traversing 975 * the graph, now that any .BEGIN and .END 976 * targets have been read. This is done 977 * only if the -q flag wasn't given (to 978 * prevent the .BEGIN from being executed 979 * should it exist). 980 */ 981 if (!queryFlag) { 982 Job_Init(maxJobs); 983 jobsRunning = TRUE; 984 } 985 986 /* Traverse the graph, checking on all the targets */ 987 outOfDate = Make_Run(&targs); 988 } 989 Lst_Destroy(&targs, NOFREE); 990 991 } else { 992 /* 993 * Print the values of any variables requested by 994 * the user. 995 */ 996 LstNode *n; 997 const char *name; 998 char *v; 999 char *value; 1000 1001 LST_FOREACH(n, &variables) { 1002 name = Lst_Datum(n); 1003 if (expandVars) { 1004 v = emalloc(strlen(name) + 1 + 3); 1005 sprintf(v, "${%s}", name); 1006 1007 value = Buf_Peel(Var_Subst(v, 1008 VAR_GLOBAL, FALSE)); 1009 printf("%s\n", value); 1010 1011 free(v); 1012 free(value); 1013 } else { 1014 value = Var_Value(name, VAR_GLOBAL, &v); 1015 printf("%s\n", value != NULL ? value : ""); 1016 if (v != NULL) 1017 free(v); 1018 } 1019 } 1020 } 1021 1022 Lst_Destroy(&variables, free); 1023 Lst_Destroy(&makefiles, free); 1024 Lst_Destroy(&create, free); 1025 1026 /* print the graph now it's been processed if the user requested it */ 1027 if (DEBUG(GRAPH2)) 1028 Targ_PrintGraph(2); 1029 1030 if (queryFlag && outOfDate) 1031 return (1); 1032 else 1033 return (0); 1034} 1035 1036/** 1037 * ReadMakefile 1038 * Open and parse the given makefile. 1039 * 1040 * Results: 1041 * TRUE if ok. FALSE if couldn't open file. 1042 * 1043 * Side Effects: 1044 * lots 1045 */ 1046static Boolean 1047ReadMakefile(const char *p) 1048{ 1049 char *fname; /* makefile to read */ 1050 FILE *stream; 1051 char *name, path[MAXPATHLEN]; 1052 char *MAKEFILE; 1053 int setMAKEFILE; 1054 1055 /* XXX - remove this once constification is done */ 1056 fname = estrdup(p); 1057 1058 if (!strcmp(fname, "-")) { 1059 Parse_File("(stdin)", stdin); 1060 Var_Set("MAKEFILE", "", VAR_GLOBAL); 1061 } else { 1062 setMAKEFILE = strcmp(fname, ".depend"); 1063 1064 /* if we've chdir'd, rebuild the path name */ 1065 if (curdir != objdir && *fname != '/') { 1066 snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname); 1067 /* 1068 * XXX The realpath stuff breaks relative includes 1069 * XXX in some cases. The problem likely is in 1070 * XXX parse.c where it does special things in 1071 * XXX ParseDoInclude if the file is relateive 1072 * XXX or absolute and not a system file. There 1073 * XXX it assumes that if the current file that's 1074 * XXX being included is absolute, that any files 1075 * XXX that it includes shouldn't do the -I path 1076 * XXX stuff, which is inconsistant with historical 1077 * XXX behavior. However, I can't pentrate the mists 1078 * XXX further, so I'm putting this workaround in 1079 * XXX here until such time as the underlying bug 1080 * XXX can be fixed. 1081 */ 1082#if THIS_BREAKS_THINGS 1083 if (realpath(path, path) != NULL && 1084 (stream = fopen(path, "r")) != NULL) { 1085 MAKEFILE = fname; 1086 fname = path; 1087 goto found; 1088 } 1089 } else if (realpath(fname, path) != NULL) { 1090 MAKEFILE = fname; 1091 fname = path; 1092 if ((stream = fopen(fname, "r")) != NULL) 1093 goto found; 1094 } 1095#else 1096 if ((stream = fopen(path, "r")) != NULL) { 1097 MAKEFILE = fname; 1098 fname = path; 1099 goto found; 1100 } 1101 } else { 1102 MAKEFILE = fname; 1103 if ((stream = fopen(fname, "r")) != NULL) 1104 goto found; 1105 } 1106#endif 1107 /* look in -I and system include directories. */ 1108 name = Path_FindFile(fname, &parseIncPath); 1109 if (!name) 1110 name = Path_FindFile(fname, &sysIncPath); 1111 if (!name || !(stream = fopen(name, "r"))) 1112 return (FALSE); 1113 MAKEFILE = fname = name; 1114 /* 1115 * set the MAKEFILE variable desired by System V fans -- the 1116 * placement of the setting here means it gets set to the last 1117 * makefile specified, as it is set by SysV make. 1118 */ 1119found: 1120 if (setMAKEFILE) 1121 Var_Set("MAKEFILE", MAKEFILE, VAR_GLOBAL); 1122 Parse_File(fname, stream); 1123 fclose(stream); 1124 } 1125 return (TRUE); 1126} 1127 1128/* 1129 * usage -- 1130 * exit with usage message 1131 */ 1132static void 1133usage(void) 1134{ 1135 fprintf(stderr, "%s\n%s\n%s\n%s\n", 1136"usage: make [-ABPSXeiknqrstv] [-C directory] [-D variable] [-d flags]", 1137" [-E variable] [-f makefile] [-I directory] [-j max_jobs]", 1138" [-m directory] [-V variable] [variable=value] [-x warn_flag]", 1139" [target ...]"); 1140 exit(2); 1141} 1142