main.c revision 146064
1141104Sharti/*- 21590Srgrimes * Copyright (c) 1988, 1989, 1990, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * Copyright (c) 1989 by Berkeley Softworks 51590Srgrimes * All rights reserved. 61590Srgrimes * 71590Srgrimes * This code is derived from software contributed to Berkeley by 81590Srgrimes * Adam de Boor. 91590Srgrimes * 101590Srgrimes * Redistribution and use in source and binary forms, with or without 111590Srgrimes * modification, are permitted provided that the following conditions 121590Srgrimes * are met: 131590Srgrimes * 1. Redistributions of source code must retain the above copyright 141590Srgrimes * notice, this list of conditions and the following disclaimer. 151590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 161590Srgrimes * notice, this list of conditions and the following disclaimer in the 171590Srgrimes * documentation and/or other materials provided with the distribution. 181590Srgrimes * 3. All advertising materials mentioning features or use of this software 191590Srgrimes * must display the following acknowledgement: 201590Srgrimes * This product includes software developed by the University of 211590Srgrimes * California, Berkeley and its contributors. 221590Srgrimes * 4. Neither the name of the University nor the names of its contributors 231590Srgrimes * may be used to endorse or promote products derived from this software 241590Srgrimes * without specific prior written permission. 251590Srgrimes * 261590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 271590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 281590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 291590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 301590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 311590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 321590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 331590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 341590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 351590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 361590Srgrimes * SUCH DAMAGE. 3762833Swsanchez * 3862833Swsanchez * @(#)main.c 8.3 (Berkeley) 3/19/94 391590Srgrimes */ 401590Srgrimes 411590Srgrimes#ifndef lint 4294595Sobrien#if 0 4394589Sobrienstatic char copyright[] = 4494589Sobrien"@(#) Copyright (c) 1988, 1989, 1990, 1993\n\ 4594589Sobrien The Regents of the University of California. All rights reserved.\n"; 4694595Sobrien#endif 471590Srgrimes#endif /* not lint */ 4894589Sobrien#include <sys/cdefs.h> 4994587Sobrien__FBSDID("$FreeBSD: head/usr.bin/make/main.c 146064 2005-05-10 14:23:31Z harti $"); 501590Srgrimes 51144475Sharti/* 52144475Sharti * main.c 531590Srgrimes * The main file for this entire program. Exit routines etc 541590Srgrimes * reside here. 551590Srgrimes * 561590Srgrimes * Utility functions defined in this file: 57144475Sharti * Main_ParseArgLine 58144475Sharti * Takes a line of arguments, breaks them and 59144475Sharti * treats them as if they were given when first 60144475Sharti * invoked. Used by the parse module to implement 61144475Sharti * the .MFLAGS target. 621590Srgrimes */ 631590Srgrimes 64141104Sharti#ifndef MACHINE 65141104Sharti#include <sys/utsname.h> 66141104Sharti#endif 671590Srgrimes#include <sys/param.h> 681590Srgrimes#include <sys/stat.h> 6939006Skato#include <sys/sysctl.h> 70127880Sdes#include <sys/time.h> 71144020Sharti#include <sys/queue.h> 72127899Sru#include <sys/resource.h> 7318730Ssteve#include <sys/wait.h> 7427644Scharnier#include <err.h> 751590Srgrimes#include <errno.h> 76127880Sdes#include <signal.h> 77127880Sdes#include <stdlib.h> 78141104Sharti#include <string.h> 7963955Simp#include <unistd.h> 80127880Sdes 81141104Sharti#include "arch.h" 82141133Sharti#include "buf.h" 83141104Sharti#include "config.h" 841590Srgrimes#include "dir.h" 85141104Sharti#include "globals.h" 861590Srgrimes#include "job.h" 87141104Sharti#include "make.h" 88141104Sharti#include "parse.h" 891590Srgrimes#include "pathnames.h" 90141104Sharti#include "str.h" 91141104Sharti#include "suff.h" 92141104Sharti#include "targ.h" 93141104Sharti#include "util.h" 94141104Sharti#include "var.h" 951590Srgrimes 96104395Sjmallett#define WANT_ENV_MKLVL 1 97138071Sjmallett#define MKLVL_MAXVAL 500 98138071Sjmallett#define MKLVL_ENVVAR "__MKLVL__" 99104395Sjmallett 1001590Srgrimes#define MAKEFLAGS ".MAKEFLAGS" 1011590Srgrimes 102145971Shartiextern char **environ; /* XXX what header declares this variable? */ 103145971Sharti 104138916Sharti/* Targets to be made */ 105138916ShartiLst create = Lst_Initializer(create); 106138916Sharti 107144475Shartitime_t now; /* Time at start of make */ 108144475Shartistruct GNode *DEFAULT; /* .DEFAULT node */ 109144475ShartiBoolean allPrecious; /* .PRECIOUS given on line by itself */ 110145679Shartiuint32_t warn_flags; /* actual warning flags */ 111145679Shartiuint32_t warn_cmd; /* command line warning flags */ 112145679Shartiuint32_t warn_nocmd; /* command line no-warning flags */ 1131590Srgrimes 114144475Shartistatic Boolean noBuiltins; /* -r flag */ 115138916Sharti 116138916Sharti/* ordered list of makefiles to read */ 117138916Shartistatic Lst makefiles = Lst_Initializer(makefiles); 118138916Sharti 119144475Shartistatic Boolean expandVars; /* fully expand printed variables */ 120138916Sharti 121138916Sharti/* list of variables to print */ 122138916Shartistatic Lst variables = Lst_Initializer(variables); 123138916Sharti 124144475Shartiint maxJobs; /* -j argument */ 125144475Shartistatic Boolean forceJobs; /* -j argument given */ 126144475ShartiBoolean compatMake; /* -B argument */ 127144475ShartiBoolean debug; /* -d flag */ 128144475ShartiBoolean noExecute; /* -n flag */ 129144475ShartiBoolean keepgoing; /* -k flag */ 130144475ShartiBoolean queryFlag; /* -q flag */ 131144475ShartiBoolean touchFlag; /* -t flag */ 132144475ShartiBoolean usePipes; /* !-P flag */ 133144475ShartiBoolean ignoreErrors; /* -i flag */ 134144475ShartiBoolean beSilent; /* -s flag */ 135144475ShartiBoolean beVerbose; /* -v flag */ 136144475ShartiBoolean oldVars; /* variable substitution style */ 137144475ShartiBoolean checkEnvFirst; /* -e flag */ 138138916Sharti 139138916Sharti/* (-E) vars to override from env */ 140138916ShartiLst envFirstVars = Lst_Initializer(envFirstVars); 141138916Sharti 142144475ShartiBoolean jobsRunning; /* TRUE if the jobs might be running */ 1431590Srgrimes 144144475Shartichar *chdir_verify_path(const char *, char *); 145144475Shartistatic int ReadMakefile(const char *); 146144475Shartistatic void usage(void); 1471590Srgrimes 148144475Shartistatic char *curdir; /* startup directory */ 149144475Shartistatic char *objdir; /* where we chdir'ed to */ 1501590Srgrimes 151144475Sharti/** 152144475Sharti * MFLAGS_append 153144475Sharti * Append a flag with an optional argument to MAKEFLAGS and MFLAGS 154133085Sharti */ 155133085Shartistatic void 156141252ShartiMFLAGS_append(const char *flag, char *arg) 157133085Sharti{ 158140870Sharti char *str; 159138232Sharti 160133085Sharti Var_Append(MAKEFLAGS, flag, VAR_GLOBAL); 161140870Sharti if (arg != NULL) { 162140870Sharti str = MAKEFLAGS_quote(arg); 163140870Sharti Var_Append(MAKEFLAGS, str, VAR_GLOBAL); 164140870Sharti free(str); 165140870Sharti } 166133085Sharti 167133085Sharti Var_Append("MFLAGS", flag, VAR_GLOBAL); 168140870Sharti if (arg != NULL) { 169140870Sharti str = MAKEFLAGS_quote(arg); 170140870Sharti Var_Append("MFLAGS", str, VAR_GLOBAL); 171140870Sharti free(str); 172140870Sharti } 173133085Sharti} 174133085Sharti 175144475Sharti/** 176145679Sharti * Main_ParseWarn 177145679Sharti * 178145679Sharti * Handle argument to warning option. 179145679Sharti */ 180145679Shartiint 181145679ShartiMain_ParseWarn(const char *arg, int iscmd) 182145679Sharti{ 183145679Sharti int i, neg; 184145679Sharti 185145679Sharti static const struct { 186145679Sharti const char *option; 187145679Sharti uint32_t flag; 188145679Sharti } options[] = { 189145679Sharti { "dirsyntax", WARN_DIRSYNTAX }, 190145679Sharti { NULL, 0 } 191145679Sharti }; 192145679Sharti 193145679Sharti neg = 0; 194145679Sharti if (arg[0] == 'n' && arg[1] == 'o') { 195145679Sharti neg = 1; 196145679Sharti arg += 2; 197145679Sharti } 198145679Sharti 199145679Sharti for (i = 0; options[i].option != NULL; i++) 200145679Sharti if (strcmp(arg, options[i].option) == 0) 201145679Sharti break; 202145679Sharti 203145679Sharti if (options[i].option == NULL) 204145679Sharti /* unknown option */ 205145679Sharti return (-1); 206145679Sharti 207145679Sharti if (iscmd) { 208145679Sharti if (!neg) { 209145679Sharti warn_cmd |= options[i].flag; 210145679Sharti warn_nocmd &= ~options[i].flag; 211145679Sharti warn_flags |= options[i].flag; 212145679Sharti } else { 213145679Sharti warn_nocmd |= options[i].flag; 214145679Sharti warn_cmd &= ~options[i].flag; 215145679Sharti warn_flags &= ~options[i].flag; 216145679Sharti } 217145679Sharti } else { 218145679Sharti if (!neg) { 219145679Sharti warn_flags |= (options[i].flag & ~warn_nocmd); 220145679Sharti } else { 221145679Sharti warn_flags &= ~(options[i].flag | warn_cmd); 222145679Sharti } 223145679Sharti } 224145679Sharti return (0); 225145679Sharti} 226145679Sharti 227145679Sharti/** 228144475Sharti * MainParseArgs 2291590Srgrimes * Parse a given argument vector. Called from main() and from 2301590Srgrimes * Main_ParseArgLine() when the .MAKEFLAGS target is used. 2311590Srgrimes * 2321590Srgrimes * XXX: Deal with command line overriding .MAKEFLAGS in makefile 2331590Srgrimes * 2341590Srgrimes * Side Effects: 2351590Srgrimes * Various global and local flags will be set depending on the flags 2361590Srgrimes * given 2371590Srgrimes */ 2381590Srgrimesstatic void 239104696SjmallettMainParseArgs(int argc, char **argv) 2401590Srgrimes{ 2415814Sjkh int c; 242146038Sharti Boolean found_dd = FALSE; 2431590Srgrimes 244144896Shartirearg: 2451590Srgrimes optind = 1; /* since we're called more than once */ 246144896Sharti optreset = 1; 247145627Sharti#define OPTFLAGS "ABC:D:E:I:PSV:Xd:ef:ij:km:nqrstvx:" 248146038Sharti for (;;) { 249146038Sharti if ((optind < argc) && strcmp(argv[optind], "--") == 0) { 250146038Sharti found_dd = TRUE; 251146038Sharti } 252146038Sharti if ((c = getopt(argc, argv, OPTFLAGS)) == -1) { 253146038Sharti break; 254146038Sharti } 2551590Srgrimes switch(c) { 256144387Sharti 257144387Sharti case 'A': 258144387Sharti arch_fatal = FALSE; 259144387Sharti MFLAGS_append("-A", NULL); 260144387Sharti break; 261102393Sjmallett case 'C': 262107964Sseanc if (chdir(optarg) == -1) 263107964Sseanc err(1, "chdir %s", optarg); 264102393Sjmallett break; 2651590Srgrimes case 'D': 2661590Srgrimes Var_Set(optarg, "1", VAR_GLOBAL); 267133085Sharti MFLAGS_append("-D", optarg); 2681590Srgrimes break; 2691590Srgrimes case 'I': 2701590Srgrimes Parse_AddIncludeDir(optarg); 271133085Sharti MFLAGS_append("-I", optarg); 2721590Srgrimes break; 27317193Sbde case 'V': 274138920Sru Lst_AtEnd(&variables, estrdup(optarg)); 275133085Sharti MFLAGS_append("-V", optarg); 27617193Sbde break; 27766365Speter case 'X': 27866365Speter expandVars = FALSE; 27966365Speter break; 2801590Srgrimes case 'B': 2811590Srgrimes compatMake = TRUE; 282133085Sharti MFLAGS_append("-B", NULL); 283137626Sphk unsetenv("MAKE_JOBS_FIFO"); 2841590Srgrimes break; 2851590Srgrimes case 'P': 2861590Srgrimes usePipes = FALSE; 287133085Sharti MFLAGS_append("-P", NULL); 2881590Srgrimes break; 2891590Srgrimes case 'S': 2901590Srgrimes keepgoing = FALSE; 291133085Sharti MFLAGS_append("-S", NULL); 2921590Srgrimes break; 2931590Srgrimes case 'd': { 2941590Srgrimes char *modules = optarg; 2951590Srgrimes 2961590Srgrimes for (; *modules; ++modules) 2971590Srgrimes switch (*modules) { 2981590Srgrimes case 'A': 2991590Srgrimes debug = ~0; 3001590Srgrimes break; 3011590Srgrimes case 'a': 3021590Srgrimes debug |= DEBUG_ARCH; 3031590Srgrimes break; 3041590Srgrimes case 'c': 3051590Srgrimes debug |= DEBUG_COND; 3061590Srgrimes break; 3071590Srgrimes case 'd': 3081590Srgrimes debug |= DEBUG_DIR; 3091590Srgrimes break; 3101590Srgrimes case 'f': 3111590Srgrimes debug |= DEBUG_FOR; 3121590Srgrimes break; 3131590Srgrimes case 'g': 3141590Srgrimes if (modules[1] == '1') { 3151590Srgrimes debug |= DEBUG_GRAPH1; 3161590Srgrimes ++modules; 3171590Srgrimes } 3181590Srgrimes else if (modules[1] == '2') { 3191590Srgrimes debug |= DEBUG_GRAPH2; 3201590Srgrimes ++modules; 3211590Srgrimes } 3221590Srgrimes break; 3231590Srgrimes case 'j': 3241590Srgrimes debug |= DEBUG_JOB; 3251590Srgrimes break; 32660569Swill case 'l': 32760569Swill debug |= DEBUG_LOUD; 32860569Swill break; 3291590Srgrimes case 'm': 3301590Srgrimes debug |= DEBUG_MAKE; 3311590Srgrimes break; 3321590Srgrimes case 's': 3331590Srgrimes debug |= DEBUG_SUFF; 3341590Srgrimes break; 3351590Srgrimes case 't': 3361590Srgrimes debug |= DEBUG_TARG; 3371590Srgrimes break; 3381590Srgrimes case 'v': 3391590Srgrimes debug |= DEBUG_VAR; 3401590Srgrimes break; 3411590Srgrimes default: 342144475Sharti warnx("illegal argument to d option " 343144475Sharti "-- %c", *modules); 3441590Srgrimes usage(); 3451590Srgrimes } 346133085Sharti MFLAGS_append("-d", optarg); 3471590Srgrimes break; 3481590Srgrimes } 34949332Shoek case 'E': 350138920Sru Lst_AtEnd(&envFirstVars, estrdup(optarg)); 351133085Sharti MFLAGS_append("-E", optarg); 35249332Shoek break; 3531590Srgrimes case 'e': 3541590Srgrimes checkEnvFirst = TRUE; 355133085Sharti MFLAGS_append("-e", NULL); 3561590Srgrimes break; 3571590Srgrimes case 'f': 358138920Sru Lst_AtEnd(&makefiles, estrdup(optarg)); 3591590Srgrimes break; 3601590Srgrimes case 'i': 3611590Srgrimes ignoreErrors = TRUE; 362133085Sharti MFLAGS_append("-i", NULL); 3631590Srgrimes break; 36449331Shoek case 'j': { 36549331Shoek char *endptr; 36649331Shoek 36718730Ssteve forceJobs = TRUE; 36849331Shoek maxJobs = strtol(optarg, &endptr, 10); 36949331Shoek if (maxJobs <= 0 || *endptr != '\0') { 37049938Shoek warnx("illegal number, -j argument -- %s", 37149938Shoek optarg); 37249938Shoek usage(); 37349331Shoek } 374133085Sharti MFLAGS_append("-j", optarg); 3751590Srgrimes break; 37649331Shoek } 3771590Srgrimes case 'k': 3781590Srgrimes keepgoing = TRUE; 379133085Sharti MFLAGS_append("-k", NULL); 3801590Srgrimes break; 38118730Ssteve case 'm': 382144020Sharti Path_AddDir(&sysIncPath, optarg); 383133085Sharti MFLAGS_append("-m", optarg); 38418730Ssteve break; 3851590Srgrimes case 'n': 3861590Srgrimes noExecute = TRUE; 387133085Sharti MFLAGS_append("-n", NULL); 3881590Srgrimes break; 3891590Srgrimes case 'q': 3901590Srgrimes queryFlag = TRUE; 3911590Srgrimes /* Kind of nonsensical, wot? */ 392133085Sharti MFLAGS_append("-q", NULL); 3931590Srgrimes break; 3941590Srgrimes case 'r': 3951590Srgrimes noBuiltins = TRUE; 396133085Sharti MFLAGS_append("-r", NULL); 3971590Srgrimes break; 3981590Srgrimes case 's': 3991590Srgrimes beSilent = TRUE; 400133085Sharti MFLAGS_append("-s", NULL); 4011590Srgrimes break; 4021590Srgrimes case 't': 4031590Srgrimes touchFlag = TRUE; 404133085Sharti MFLAGS_append("-t", NULL); 4051590Srgrimes break; 40641151Sdg case 'v': 40741151Sdg beVerbose = TRUE; 408133085Sharti MFLAGS_append("-v", NULL); 40941151Sdg break; 410145627Sharti case 'x': 411145679Sharti if (Main_ParseWarn(optarg, 1) != -1) 412145627Sharti MFLAGS_append("-x", optarg); 413145627Sharti break; 414145627Sharti 4151590Srgrimes default: 4161590Srgrimes case '?': 4171590Srgrimes usage(); 4181590Srgrimes } 4191590Srgrimes } 420144896Sharti argv += optind; 421144896Sharti argc -= optind; 4221590Srgrimes 4231590Srgrimes oldVars = TRUE; 4241590Srgrimes 4251590Srgrimes /* 426144896Sharti * Parse the rest of the arguments. 427144896Sharti * o Check for variable assignments and perform them if so. 428144896Sharti * o Check for more flags and restart getopt if so. 429144896Sharti * o Anything else is taken to be a target and added 430144896Sharti * to the end of the "create" list. 4311590Srgrimes */ 432144896Sharti for (; *argv != NULL; ++argv, --argc) { 433133562Sharti if (Parse_IsVar(*argv)) { 434140870Sharti char *ptr = MAKEFLAGS_quote(*argv); 435133562Sharti 436133562Sharti Var_Append(MAKEFLAGS, ptr, VAR_GLOBAL); 437144896Sharti Parse_DoVar(*argv, VAR_CMD); 438133562Sharti free(ptr); 439133562Sharti 440144896Sharti } else if ((*argv)[0] == '-') { 441144896Sharti if ((*argv)[1] == '\0') { 442144896Sharti /* 443144896Sharti * (*argv) is a single dash, so we 444144896Sharti * just ignore it. 445144896Sharti */ 446146038Sharti } else if (found_dd) { 447146038Sharti /* 448146038Sharti * Double dash has been found, ignore 449146038Sharti * any more options. But what do we do 450146038Sharti * with it? For now treat it like a target. 451146038Sharti */ 452146038Sharti Lst_AtEnd(&create, estrdup(*argv)); 453144896Sharti } else { 454144896Sharti /* 455146038Sharti * (*argv) is a -flag, so backup argv and 456146038Sharti * argc. getopt() expects options to start 457146038Sharti * in the 2nd position. 458144896Sharti */ 459144896Sharti argc++; 460144896Sharti argv--; 4611590Srgrimes goto rearg; 4621590Srgrimes } 463144896Sharti 464144896Sharti } else if ((*argv)[0] == '\0') { 465144896Sharti Punt("illegal (null) argument."); 466144896Sharti 467144896Sharti } else { 468138916Sharti Lst_AtEnd(&create, estrdup(*argv)); 4691590Srgrimes } 470144896Sharti } 4711590Srgrimes} 4721590Srgrimes 473144475Sharti/** 474144475Sharti * Main_ParseArgLine 4751590Srgrimes * Used by the parse module when a .MFLAGS or .MAKEFLAGS target 4761590Srgrimes * is encountered and by main() when reading the .MAKEFLAGS envariable. 4771590Srgrimes * Takes a line of arguments and breaks it into its 4781590Srgrimes * component words and passes those words and the number of them to the 4791590Srgrimes * MainParseArgs function. 4801590Srgrimes * The line should have all its leading whitespace removed. 4811590Srgrimes * 4821590Srgrimes * Side Effects: 4831590Srgrimes * Only those that come from the various arguments. 4841590Srgrimes */ 4851590Srgrimesvoid 486140870ShartiMain_ParseArgLine(char *line, int mflags) 4871590Srgrimes{ 4881590Srgrimes char **argv; /* Manufactured argument vector */ 4891590Srgrimes int argc; /* Number of arguments in argv */ 4901590Srgrimes 4911590Srgrimes if (line == NULL) 4921590Srgrimes return; 4931590Srgrimes for (; *line == ' '; ++line) 4941590Srgrimes continue; 4951590Srgrimes if (!*line) 4961590Srgrimes return; 4971590Srgrimes 498140870Sharti if (mflags) 499140870Sharti argv = MAKEFLAGS_break(line, &argc); 500140870Sharti else 501140870Sharti argv = brk_string(line, &argc, TRUE); 502140870Sharti 5031590Srgrimes MainParseArgs(argc, argv); 5041590Srgrimes} 5051590Srgrimes 50618339Sswallacechar * 507141252Shartichdir_verify_path(const char *path, char *obpath) 50818339Sswallace{ 50918339Sswallace struct stat sb; 51018339Sswallace 51118339Sswallace if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { 51275973Sru if (chdir(path) == -1 || getcwd(obpath, MAXPATHLEN) == NULL) { 51327644Scharnier warn("warning: %s", path); 514141252Sharti return (NULL); 51518339Sswallace } 516138232Sharti return (obpath); 51718339Sswallace } 51818339Sswallace 519141252Sharti return (NULL); 52018339Sswallace} 52118339Sswallace 522133082Shartistatic void 523133082Sharticatch_child(int sig __unused) 524123513Sdes{ 525123513Sdes} 52618339Sswallace 527138071Sjmallett/* 528138071Sjmallett * In lieu of a good way to prevent every possible looping in 529138071Sjmallett * make(1), stop there from being more than MKLVL_MAXVAL processes forked 530138071Sjmallett * by make(1), to prevent a forkbomb from happening, in a dumb and 531138071Sjmallett * mechanical way. 532138071Sjmallett */ 533138071Sjmallettstatic void 534138071Sjmallettcheck_make_level(void) 535138071Sjmallett{ 536138071Sjmallett#ifdef WANT_ENV_MKLVL 537138071Sjmallett char *value = getenv(MKLVL_ENVVAR); 538138071Sjmallett int level = (value == NULL) ? 0 : atoi(value); 539138071Sjmallett 540138071Sjmallett if (level < 0) { 541144475Sharti errc(2, EAGAIN, "Invalid value for recursion level (%d).", 542144475Sharti level); 543138071Sjmallett } else if (level > MKLVL_MAXVAL) { 544144475Sharti errc(2, EAGAIN, "Max recursion level (%d) exceeded.", 545144475Sharti MKLVL_MAXVAL); 546138071Sjmallett } else { 547138071Sjmallett char new_value[32]; 548138071Sjmallett sprintf(new_value, "%d", level + 1); 549138071Sjmallett setenv(MKLVL_ENVVAR, new_value, 1); 550138071Sjmallett } 551138071Sjmallett#endif /* WANT_ENV_MKLVL */ 552138071Sjmallett} 553138071Sjmallett 554144475Sharti/** 555144475Sharti * main 5561590Srgrimes * The main function, for obvious reasons. Initializes variables 5571590Srgrimes * and a few modules, then parses the arguments give it in the 5581590Srgrimes * environment and on the command line. Reads the system makefile 5591590Srgrimes * followed by either Makefile, makefile or the file given by the 5601590Srgrimes * -f argument. Sets the .MAKEFLAGS PMake variable based on all the 5611590Srgrimes * flags it has received by then uses either the Make or the Compat 5621590Srgrimes * module to create the initial list of targets. 5631590Srgrimes * 5641590Srgrimes * Results: 5651590Srgrimes * If -q was given, exits -1 if anything was out-of-date. Else it exits 5661590Srgrimes * 0. 5671590Srgrimes * 5681590Srgrimes * Side Effects: 5691590Srgrimes * The program exits when done. Targets are created. etc. etc. etc. 5701590Srgrimes */ 5711590Srgrimesint 572104696Sjmallettmain(int argc, char **argv) 5731590Srgrimes{ 5741590Srgrimes Boolean outOfDate = TRUE; /* FALSE if all targets up to date */ 575141252Sharti char *p, *p1, *pathp; 576141252Sharti char *path; 57773262Simp char mdpath[MAXPATHLEN]; 57873262Simp char obpath[MAXPATHLEN]; 57973262Simp char cdpath[MAXPATHLEN]; 580141252Sharti const char *machine = getenv("MACHINE"); 581141252Sharti const char *machine_arch = getenv("MACHINE_ARCH"); 582141252Sharti const char *machine_cpu = getenv("MACHINE_CPU"); 58318730Ssteve char *cp = NULL, *start; 584141252Sharti 585144475Sharti /* avoid faults on read-only strings */ 586143412Sharti static char syspath[] = PATH_DEFSYSPATH; 5871590Srgrimes 588123513Sdes { 589123513Sdes /* 590123513Sdes * Catch SIGCHLD so that we get kicked out of select() when we 591123513Sdes * need to look at a child. This is only known to matter for the 592123513Sdes * -j case (perhaps without -P). 593123513Sdes * 594123513Sdes * XXX this is intentionally misplaced. 595123513Sdes */ 596123513Sdes struct sigaction sa; 597123513Sdes 598123513Sdes sigemptyset(&sa.sa_mask); 599123513Sdes sa.sa_flags = SA_RESTART | SA_NOCLDSTOP; 600123513Sdes sa.sa_handler = catch_child; 601123513Sdes sigaction(SIGCHLD, &sa, NULL); 602123513Sdes } 603123513Sdes 604138071Sjmallett check_make_level(); 605104395Sjmallett 60664739Sgreen#if DEFSHELL == 2 60764739Sgreen /* 60864739Sgreen * Turn off ENV to make ksh happier. 60964739Sgreen */ 61064739Sgreen unsetenv("ENV"); 61164739Sgreen#endif 61264739Sgreen 61318730Ssteve#ifdef RLIMIT_NOFILE 6141590Srgrimes /* 61518730Ssteve * get rid of resource limit on file descriptors 61618730Ssteve */ 61718730Ssteve { 61818730Ssteve struct rlimit rl; 61918730Ssteve if (getrlimit(RLIMIT_NOFILE, &rl) != -1 && 62018730Ssteve rl.rlim_cur != rl.rlim_max) { 62118730Ssteve rl.rlim_cur = rl.rlim_max; 622138232Sharti setrlimit(RLIMIT_NOFILE, &rl); 62318730Ssteve } 62418730Ssteve } 62518730Ssteve#endif 6261590Srgrimes 6275814Sjkh /* 62839006Skato * PC-98 kernel sets the `i386' string to the utsname.machine and 62939006Skato * it cannot be distinguished from IBM-PC by uname(3). Therefore, 63039006Skato * we check machine.ispc98 and adjust the machine variable before 63139006Skato * using usname(3) below. 63253631Smarcel * NOTE: machdep.ispc98 was defined on 1998/8/31. At that time, 63353631Smarcel * __FreeBSD_version was defined as 300003. So, this check can 63453631Smarcel * safely be done with any kernel with version > 300003. 63539006Skato */ 63639006Skato if (!machine) { 63739006Skato int ispc98; 63839006Skato size_t len; 63939006Skato 64039006Skato len = sizeof(ispc98); 64139006Skato if (!sysctlbyname("machdep.ispc98", &ispc98, &len, NULL, 0)) { 64239006Skato if (ispc98) 64339006Skato machine = "pc98"; 64439006Skato } 64539006Skato } 64639006Skato 64739006Skato /* 6485814Sjkh * Get the name of this type of MACHINE from utsname 6495814Sjkh * so we can share an executable for similar machines. 6505814Sjkh * (i.e. m68k: amiga hp300, mac68k, sun3, ...) 6515814Sjkh * 6525814Sjkh * Note that while MACHINE is decided at run-time, 6535814Sjkh * MACHINE_ARCH is always known at compile time. 6545814Sjkh */ 65518864Ssteve if (!machine) { 65618339Sswallace#ifndef MACHINE 657144475Sharti static struct utsname utsname; 65818730Ssteve 659144475Sharti if (uname(&utsname) == -1) 660144475Sharti err(2, "uname"); 661144475Sharti machine = utsname.machine; 66218339Sswallace#else 663144475Sharti machine = MACHINE; 66418339Sswallace#endif 6655814Sjkh } 6661590Srgrimes 66744362Simp if (!machine_arch) { 66844362Simp#ifndef MACHINE_ARCH 66944362Simp machine_arch = "unknown"; 67044362Simp#else 67144362Simp machine_arch = MACHINE_ARCH; 67244362Simp#endif 67344362Simp } 67444362Simp 6751590Srgrimes /* 67672679Skris * Set machine_cpu to the minumum supported CPU revision based 67772679Skris * on the target architecture, if not already set. 67872679Skris */ 67972679Skris if (!machine_cpu) { 68072679Skris if (!strcmp(machine_arch, "i386")) 68172679Skris machine_cpu = "i386"; 68272679Skris else if (!strcmp(machine_arch, "alpha")) 68372679Skris machine_cpu = "ev4"; 68472679Skris else 68572679Skris machine_cpu = "unknown"; 68672679Skris } 6871590Srgrimes 68866365Speter expandVars = TRUE; 6891590Srgrimes beSilent = FALSE; /* Print commands as executed */ 6901590Srgrimes ignoreErrors = FALSE; /* Pay attention to non-zero returns */ 6911590Srgrimes noExecute = FALSE; /* Execute all commands */ 6921590Srgrimes keepgoing = FALSE; /* Stop on error */ 6931590Srgrimes allPrecious = FALSE; /* Remove targets when interrupted */ 6941590Srgrimes queryFlag = FALSE; /* This is not just a check-run */ 6951590Srgrimes noBuiltins = FALSE; /* Read the built-in rules */ 6961590Srgrimes touchFlag = FALSE; /* Actually update targets */ 6971590Srgrimes usePipes = TRUE; /* Catch child output in pipes */ 6981590Srgrimes debug = 0; /* No debug verbosity, please. */ 6991590Srgrimes jobsRunning = FALSE; 7001590Srgrimes 701137571Sphk maxJobs = DEFMAXJOBS; 70228228Sfsmp forceJobs = FALSE; /* No -j flag */ 70318730Ssteve compatMake = FALSE; /* No compat mode */ 7041590Srgrimes 7051590Srgrimes /* 7061590Srgrimes * Initialize the parsing, directory and variable modules to prepare 7071590Srgrimes * for the reading of inclusion paths and variable settings on the 7081590Srgrimes * command line 7091590Srgrimes */ 7101590Srgrimes Dir_Init(); /* Initialize directory structures so -I flags 7111590Srgrimes * can be processed correctly */ 712145971Sharti Var_Init(environ); /* As well as the lists of variables for 7131590Srgrimes * parsing arguments */ 7145814Sjkh str_init(); 7151590Srgrimes 7161590Srgrimes /* 7171590Srgrimes * Initialize various variables. 7181590Srgrimes * MAKE also gets this name, for compatibility 7191590Srgrimes * .MAKEFLAGS gets set to the empty string just in case. 7201590Srgrimes * MFLAGS also gets initialized empty, for compatibility. 7211590Srgrimes */ 7221590Srgrimes Var_Set("MAKE", argv[0], VAR_GLOBAL); 7231590Srgrimes Var_Set(MAKEFLAGS, "", VAR_GLOBAL); 7241590Srgrimes Var_Set("MFLAGS", "", VAR_GLOBAL); 7255814Sjkh Var_Set("MACHINE", machine, VAR_GLOBAL); 72644362Simp Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL); 72772679Skris Var_Set("MACHINE_CPU", machine_cpu, VAR_GLOBAL); 72897121Sru#ifdef MAKE_VERSION 72997121Sru Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL); 73097121Sru#endif 7311590Srgrimes 7321590Srgrimes /* 733144896Sharti * First snag things out of the MAKEFLAGS environment 734144896Sharti * variable. Then parse the command line arguments. 7351590Srgrimes */ 736140870Sharti Main_ParseArgLine(getenv("MAKEFLAGS"), 1); 7378874Srgrimes 7381590Srgrimes MainParseArgs(argc, argv); 7391590Srgrimes 7401590Srgrimes /* 741120053Sru * Find where we are... 742120053Sru */ 743120053Sru curdir = cdpath; 744120053Sru if (getcwd(curdir, MAXPATHLEN) == NULL) 745120053Sru err(2, NULL); 746120053Sru 747141252Sharti { 748141252Sharti struct stat sa; 749141252Sharti 750120053Sru if (stat(curdir, &sa) == -1) 751120053Sru err(2, "%s", curdir); 752141252Sharti } 753120053Sru 754120053Sru /* 755120053Sru * The object directory location is determined using the 756120053Sru * following order of preference: 757120053Sru * 758120053Sru * 1. MAKEOBJDIRPREFIX`cwd` 759120053Sru * 2. MAKEOBJDIR 760143412Sharti * 3. PATH_OBJDIR.${MACHINE} 761143412Sharti * 4. PATH_OBJDIR 762143412Sharti * 5. PATH_OBJDIRPREFIX`cwd` 763120053Sru * 764120053Sru * If one of the first two fails, use the current directory. 765120053Sru * If the remaining three all fail, use the current directory. 766120053Sru * 767120053Sru * Once things are initted, 768120053Sru * have to add the original directory to the search path, 769120053Sru * and modify the paths for the Makefiles apropriately. The 770120053Sru * current directory is also placed as a variable for make scripts. 771120053Sru */ 772120053Sru if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) { 773120053Sru if (!(path = getenv("MAKEOBJDIR"))) { 774143412Sharti path = PATH_OBJDIR; 775143412Sharti pathp = PATH_OBJDIRPREFIX; 776138232Sharti snprintf(mdpath, MAXPATHLEN, "%s.%s", 777120053Sru path, machine); 778120053Sru if (!(objdir = chdir_verify_path(mdpath, obpath))) 779120053Sru if (!(objdir=chdir_verify_path(path, obpath))) { 780138232Sharti snprintf(mdpath, MAXPATHLEN, 781120053Sru "%s%s", pathp, curdir); 782120053Sru if (!(objdir=chdir_verify_path(mdpath, 783120053Sru obpath))) 784120053Sru objdir = curdir; 785120053Sru } 786120053Sru } 787120053Sru else if (!(objdir = chdir_verify_path(path, obpath))) 788120053Sru objdir = curdir; 789120053Sru } 790120053Sru else { 791138232Sharti snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir); 792120053Sru if (!(objdir = chdir_verify_path(mdpath, obpath))) 793120053Sru objdir = curdir; 794120053Sru } 795120053Sru Dir_InitDot(); /* Initialize the "." directory */ 796120053Sru if (objdir != curdir) 797144020Sharti Path_AddDir(&dirSearchPath, curdir); 798145971Sharti Var_Set(".ST_EXPORTVAR", "YES", VAR_GLOBAL); 799120053Sru Var_Set(".CURDIR", curdir, VAR_GLOBAL); 800120053Sru Var_Set(".OBJDIR", objdir, VAR_GLOBAL); 801120053Sru 802137606Sphk if (getenv("MAKE_JOBS_FIFO") != NULL) 803137606Sphk forceJobs = TRUE; 804120053Sru /* 80528228Sfsmp * Be compatible if user did not specify -j and did not explicitly 80628228Sfsmp * turned compatibility on 80728228Sfsmp */ 80828228Sfsmp if (!compatMake && !forceJobs) 80928228Sfsmp compatMake = TRUE; 81028228Sfsmp 81128228Sfsmp /* 812144387Sharti * Initialize target and suffix modules in preparation for 8131590Srgrimes * parsing the makefile(s) 8141590Srgrimes */ 8151590Srgrimes Targ_Init(); 8161590Srgrimes Suff_Init(); 8171590Srgrimes 81869527Swill DEFAULT = NULL; 819138232Sharti time(&now); 8201590Srgrimes 8211590Srgrimes /* 8221590Srgrimes * Set up the .TARGETS variable to contain the list of targets to be 8231590Srgrimes * created. If none specified, make the variable empty -- the parser 8241590Srgrimes * will fill the thing in with the default or .MAIN target. 8251590Srgrimes */ 826138916Sharti if (!Lst_IsEmpty(&create)) { 827138512Sharti LstNode *ln; 8281590Srgrimes 829138916Sharti for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) { 830138264Sharti char *name = Lst_Datum(ln); 8311590Srgrimes 8321590Srgrimes Var_Append(".TARGETS", name, VAR_GLOBAL); 8331590Srgrimes } 8341590Srgrimes } else 8351590Srgrimes Var_Set(".TARGETS", "", VAR_GLOBAL); 8361590Srgrimes 83718730Ssteve 8381590Srgrimes /* 83918730Ssteve * If no user-supplied system path was given (through the -m option) 84018730Ssteve * add the directories from the DEFSYSPATH (more than one may be given 84118730Ssteve * as dir1:...:dirn) to the system include path. 8421590Srgrimes */ 843144020Sharti if (TAILQ_EMPTY(&sysIncPath)) { 84418730Ssteve for (start = syspath; *start != '\0'; start = cp) { 84518730Ssteve for (cp = start; *cp != '\0' && *cp != ':'; cp++) 84618730Ssteve continue; 84718730Ssteve if (*cp == '\0') { 848144020Sharti Path_AddDir(&sysIncPath, start); 84918730Ssteve } else { 85018730Ssteve *cp++ = '\0'; 851144020Sharti Path_AddDir(&sysIncPath, start); 85218730Ssteve } 85318730Ssteve } 85418730Ssteve } 8551590Srgrimes 85618730Ssteve /* 85718730Ssteve * Read in the built-in rules first, followed by the specified 85818730Ssteve * makefile, if it was (makefile != (char *) NULL), or the default 85918730Ssteve * Makefile and makefile, in that order, if it wasn't. 86018730Ssteve */ 86118730Ssteve if (!noBuiltins) { 862138916Sharti /* Path of sys.mk */ 863138916Sharti Lst sysMkPath = Lst_Initializer(sysMkPath); 864138512Sharti LstNode *ln; 865146064Sharti char defsysmk[] = PATH_DEFSYSMK; 86618730Ssteve 867146064Sharti Path_Expand(defsysmk, &sysIncPath, &sysMkPath); 868138916Sharti if (Lst_IsEmpty(&sysMkPath)) 869143412Sharti Fatal("make: no system rules (%s).", PATH_DEFSYSMK); 870143808Sharti LST_FOREACH(ln, &sysMkPath) { 871143808Sharti if (!ReadMakefile(Lst_Datum(ln))) 872143808Sharti break; 873143808Sharti } 87469527Swill if (ln != NULL) 87518730Ssteve Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 876138916Sharti Lst_Destroy(&sysMkPath, free); 87718730Ssteve } 87818730Ssteve 879138916Sharti if (!Lst_IsEmpty(&makefiles)) { 880138512Sharti LstNode *ln; 8811590Srgrimes 882143808Sharti LST_FOREACH(ln, &makefiles) { 883143808Sharti if (!ReadMakefile(Lst_Datum(ln))) 884143808Sharti break; 885143808Sharti } 88669527Swill if (ln != NULL) 8871590Srgrimes Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 888143808Sharti } else if (!ReadMakefile("BSDmakefile")) 889143808Sharti if (!ReadMakefile("makefile")) 890143808Sharti ReadMakefile("Makefile"); 8911590Srgrimes 892143808Sharti ReadMakefile(".depend"); 8931590Srgrimes 8941590Srgrimes /* Install all the flags into the MAKE envariable. */ 8955814Sjkh if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1)) != NULL) && *p) 8961590Srgrimes setenv("MAKEFLAGS", p, 1); 897105826Sjmallett free(p1); 8981590Srgrimes 8991590Srgrimes /* 9001590Srgrimes * For compatibility, look at the directories in the VPATH variable 9011590Srgrimes * and add them to the search path, if the variable is defined. The 9021590Srgrimes * variable's value is in the same format as the PATH envariable, i.e. 9031590Srgrimes * <directory>:<directory>:<directory>... 9041590Srgrimes */ 9051590Srgrimes if (Var_Exists("VPATH", VAR_CMD)) { 9061590Srgrimes /* 9071590Srgrimes * GCC stores string constants in read-only memory, but 9081590Srgrimes * Var_Subst will want to write this thing, so store it 9091590Srgrimes * in an array 9101590Srgrimes */ 9111590Srgrimes static char VPATH[] = "${VPATH}"; 912142457Sharti Buffer *buf; 913142457Sharti char *vpath; 914142457Sharti char *ptr; 915142457Sharti char savec; 9161590Srgrimes 917146027Sharti buf = Var_Subst(VPATH, VAR_CMD, FALSE); 918142457Sharti 919143959Sharti vpath = Buf_Data(buf); 9201590Srgrimes do { 9211590Srgrimes /* skip to end of directory */ 922142457Sharti for (ptr = vpath; *ptr != ':' && *ptr != '\0'; ptr++) 923141969Sharti ; 924141969Sharti 9251590Srgrimes /* Save terminator character so know when to stop */ 926141969Sharti savec = *ptr; 927141969Sharti *ptr = '\0'; 928141969Sharti 9291590Srgrimes /* Add directory to search path */ 930144020Sharti Path_AddDir(&dirSearchPath, vpath); 931141969Sharti 932142457Sharti vpath = ptr + 1; 933141969Sharti } while (savec != '\0'); 934142457Sharti 935142457Sharti Buf_Destroy(buf, TRUE); 9361590Srgrimes } 9371590Srgrimes 9381590Srgrimes /* 9391590Srgrimes * Now that all search paths have been read for suffixes et al, it's 9401590Srgrimes * time to add the default search path to their lists... 9411590Srgrimes */ 9421590Srgrimes Suff_DoPaths(); 9431590Srgrimes 9441590Srgrimes /* print the initial graph, if the user requested it */ 9451590Srgrimes if (DEBUG(GRAPH1)) 9461590Srgrimes Targ_PrintGraph(1); 9471590Srgrimes 94817193Sbde /* print the values of any variables requested by the user */ 949141974Sharti if (Lst_IsEmpty(&variables)) { 9501590Srgrimes /* 951141974Sharti * Since the user has not requested that any variables 952142008Sharti * be printed, we can build targets. 953141974Sharti * 954142008Sharti * Have read the entire graph and need to make a list of targets 955141974Sharti * to create. If none was given on the command line, we consult 956141974Sharti * the parsing module to find the main target(s) to create. 9571590Srgrimes */ 958138916Sharti Lst targs = Lst_Initializer(targs); 959138916Sharti 960138916Sharti if (Lst_IsEmpty(&create)) 961138916Sharti Parse_MainName(&targs); 962101460Sru else 963138916Sharti Targ_FindList(&targs, &create, TARG_CREATE); 964101460Sru 965141974Sharti if (compatMake) { 966101460Sru /* 967141974Sharti * Compat_Init will take care of creating 968141974Sharti * all the targets as well as initializing 969141974Sharti * the module. 970101460Sru */ 971141974Sharti Compat_Run(&targs); 972141974Sharti outOfDate = 0; 973141974Sharti } else { 974141974Sharti /* 975141974Sharti * Initialize job module before traversing 976141974Sharti * the graph, now that any .BEGIN and .END 977141974Sharti * targets have been read. This is done 978141974Sharti * only if the -q flag wasn't given (to 979141974Sharti * prevent the .BEGIN from being executed 980141974Sharti * should it exist). 981141974Sharti */ 982101460Sru if (!queryFlag) { 983137572Sphk Job_Init(maxJobs); 984101460Sru jobsRunning = TRUE; 985101460Sru } 986101460Sru 987101460Sru /* Traverse the graph, checking on all the targets */ 988138916Sharti outOfDate = Make_Run(&targs); 9891590Srgrimes } 990138916Sharti Lst_Destroy(&targs, NOFREE); 991141974Sharti 992141974Sharti } else { 993141974Sharti /* 994141974Sharti * Print the values of any variables requested by 995141974Sharti * the user. 996141974Sharti */ 997142457Sharti LstNode *n; 998142457Sharti const char *name; 999142457Sharti char *v; 1000142457Sharti char *value; 1001141974Sharti 1002142457Sharti LST_FOREACH(n, &variables) { 1003142457Sharti name = Lst_Datum(n); 1004141974Sharti if (expandVars) { 1005141974Sharti v = emalloc(strlen(name) + 1 + 3); 1006141974Sharti sprintf(v, "${%s}", name); 1007141974Sharti 1008146027Sharti value = Buf_Peel(Var_Subst(v, 1009143292Sharti VAR_GLOBAL, FALSE)); 1010142457Sharti printf("%s\n", value); 1011142457Sharti 1012142457Sharti free(v); 1013143292Sharti free(value); 1014141974Sharti } else { 1015141974Sharti value = Var_Value(name, VAR_GLOBAL, &v); 1016142457Sharti printf("%s\n", value != NULL ? value : ""); 1017142457Sharti if (v != NULL) 1018142457Sharti free(v); 1019141974Sharti } 1020141974Sharti } 102117193Sbde } 10228874Srgrimes 1023138920Sru Lst_Destroy(&variables, free); 1024138920Sru Lst_Destroy(&makefiles, free); 1025138916Sharti Lst_Destroy(&create, free); 10265814Sjkh 10271590Srgrimes /* print the graph now it's been processed if the user requested it */ 10281590Srgrimes if (DEBUG(GRAPH2)) 10291590Srgrimes Targ_PrintGraph(2); 10301590Srgrimes 10311590Srgrimes if (queryFlag && outOfDate) 1032138232Sharti return (1); 10331590Srgrimes else 1034138232Sharti return (0); 10351590Srgrimes} 10361590Srgrimes 1037144475Sharti/** 1038144475Sharti * ReadMakefile 10391590Srgrimes * Open and parse the given makefile. 10401590Srgrimes * 10411590Srgrimes * Results: 10421590Srgrimes * TRUE if ok. FALSE if couldn't open file. 10431590Srgrimes * 10441590Srgrimes * Side Effects: 10451590Srgrimes * lots 10461590Srgrimes */ 10471590Srgrimesstatic Boolean 1048143808ShartiReadMakefile(const char *p) 10491590Srgrimes{ 1050104696Sjmallett char *fname; /* makefile to read */ 10511590Srgrimes FILE *stream; 105273262Simp char *name, path[MAXPATHLEN]; 105397163Sjmallett char *MAKEFILE; 105494990Sru int setMAKEFILE; 10551590Srgrimes 1056138561Sharti /* XXX - remove this once constification is done */ 1057138561Sharti fname = estrdup(p); 1058104696Sjmallett 10591590Srgrimes if (!strcmp(fname, "-")) { 10601590Srgrimes Parse_File("(stdin)", stdin); 10611590Srgrimes Var_Set("MAKEFILE", "", VAR_GLOBAL); 10621590Srgrimes } else { 106394990Sru setMAKEFILE = strcmp(fname, ".depend"); 106494990Sru 10651590Srgrimes /* if we've chdir'd, rebuild the path name */ 10661590Srgrimes if (curdir != objdir && *fname != '/') { 1067138232Sharti snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname); 1068100733Simp /* 1069100733Simp * XXX The realpath stuff breaks relative includes 1070100733Simp * XXX in some cases. The problem likely is in 1071100733Simp * XXX parse.c where it does special things in 1072100733Simp * XXX ParseDoInclude if the file is relateive 1073100733Simp * XXX or absolute and not a system file. There 1074100733Simp * XXX it assumes that if the current file that's 1075100733Simp * XXX being included is absolute, that any files 1076100733Simp * XXX that it includes shouldn't do the -I path 1077100733Simp * XXX stuff, which is inconsistant with historical 1078100733Simp * XXX behavior. However, I can't pentrate the mists 1079100733Simp * XXX further, so I'm putting this workaround in 1080100733Simp * XXX here until such time as the underlying bug 1081100733Simp * XXX can be fixed. 1082100733Simp */ 1083100733Simp#if THIS_BREAKS_THINGS 108497077Sjmallett if (realpath(path, path) != NULL && 108597077Sjmallett (stream = fopen(path, "r")) != NULL) { 108697163Sjmallett MAKEFILE = fname; 10871590Srgrimes fname = path; 10881590Srgrimes goto found; 10891590Srgrimes } 109097077Sjmallett } else if (realpath(fname, path) != NULL) { 109197163Sjmallett MAKEFILE = fname; 109297077Sjmallett fname = path; 109397077Sjmallett if ((stream = fopen(fname, "r")) != NULL) 109497077Sjmallett goto found; 109597077Sjmallett } 1096100733Simp#else 1097100733Simp if ((stream = fopen(path, "r")) != NULL) { 1098100733Simp MAKEFILE = fname; 1099100733Simp fname = path; 1100100733Simp goto found; 1101100733Simp } 1102100733Simp } else { 1103100733Simp MAKEFILE = fname; 1104100733Simp if ((stream = fopen(fname, "r")) != NULL) 1105100733Simp goto found; 1106100733Simp } 1107100733Simp#endif 11081590Srgrimes /* look in -I and system include directories. */ 1109144020Sharti name = Path_FindFile(fname, &parseIncPath); 11101590Srgrimes if (!name) 1111144020Sharti name = Path_FindFile(fname, &sysIncPath); 11121590Srgrimes if (!name || !(stream = fopen(name, "r"))) 1113138232Sharti return (FALSE); 111497163Sjmallett MAKEFILE = fname = name; 11151590Srgrimes /* 11161590Srgrimes * set the MAKEFILE variable desired by System V fans -- the 11171590Srgrimes * placement of the setting here means it gets set to the last 11181590Srgrimes * makefile specified, as it is set by SysV make. 11191590Srgrimes */ 112094990Srufound: 112194990Sru if (setMAKEFILE) 112297163Sjmallett Var_Set("MAKEFILE", MAKEFILE, VAR_GLOBAL); 11231590Srgrimes Parse_File(fname, stream); 1124138232Sharti fclose(stream); 11251590Srgrimes } 1126138232Sharti return (TRUE); 11271590Srgrimes} 11281590Srgrimes 11291590Srgrimes/* 11301590Srgrimes * usage -- 11311590Srgrimes * exit with usage message 11321590Srgrimes */ 11331590Srgrimesstatic void 1134104696Sjmallettusage(void) 11351590Srgrimes{ 1136145627Sharti fprintf(stderr, "%s\n%s\n%s\n%s\n", 1137145627Sharti"usage: make [-ABPSXeiknqrstv] [-C directory] [-D variable] [-d flags]", 1138113512Sru" [-E variable] [-f makefile] [-I directory] [-j max_jobs]", 1139145627Sharti" [-m directory] [-V variable] [variable=value] [-x warn_flag]", 1140145627Sharti" [target ...]"); 11411590Srgrimes exit(2); 11421590Srgrimes} 1143