main.c revision 187921
183553Smurray/*- 283553Smurray * Copyright (c) 1988, 1989, 1990, 1993 383553Smurray * The Regents of the University of California. All rights reserved. 483553Smurray * Copyright (c) 1989 by Berkeley Softworks 583553Smurray * All rights reserved. 683553Smurray * 783553Smurray * This code is derived from software contributed to Berkeley by 883553Smurray * Adam de Boor. 983553Smurray * 1083553Smurray * Redistribution and use in source and binary forms, with or without 1183553Smurray * modification, are permitted provided that the following conditions 1283553Smurray * are met: 1383553Smurray * 1. Redistributions of source code must retain the above copyright 1483553Smurray * notice, this list of conditions and the following disclaimer. 1583553Smurray * 2. Redistributions in binary form must reproduce the above copyright 1683553Smurray * notice, this list of conditions and the following disclaimer in the 1783553Smurray * documentation and/or other materials provided with the distribution. 1883553Smurray * 3. All advertising materials mentioning features or use of this software 1983553Smurray * must display the following acknowledgement: 2083553Smurray * This product includes software developed by the University of 2183553Smurray * California, Berkeley and its contributors. 2283553Smurray * 4. Neither the name of the University nor the names of its contributors 2383553Smurray * may be used to endorse or promote products derived from this software 2483553Smurray * without specific prior written permission. 2583553Smurray * 2683553Smurray * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2783553Smurray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2883553Smurray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2983553Smurray * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3083553Smurray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3183553Smurray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3283553Smurray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3383553Smurray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3483553Smurray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35116192Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36116192Sobrien * SUCH DAMAGE. 37116192Sobrien * 3883553Smurray * @(#)main.c 8.3 (Berkeley) 3/19/94 39165951Sjhb */ 4083553Smurray 41165951Sjhb#ifndef lint 42165951Sjhb#if 0 43165951Sjhbstatic char copyright[] = 4483553Smurray"@(#) Copyright (c) 1988, 1989, 1990, 1993\n\ 4583553Smurray The Regents of the University of California. All rights reserved.\n"; 4683553Smurray#endif 4783553Smurray#endif /* not lint */ 4883553Smurray#include <sys/cdefs.h> 4983553Smurray__FBSDID("$FreeBSD: head/usr.bin/make/main.c 187921 2009-01-30 16:12:32Z imp $"); 50119288Simp 51119288Simp/* 5283553Smurray * main.c 5383553Smurray * The main file for this entire program. Exit routines etc 5483553Smurray * reside here. 5583553Smurray * 5683553Smurray * Utility functions defined in this file: 5783553Smurray * Main_ParseArgLine 5883553Smurray * Takes a line of arguments, breaks them and 5983553Smurray * treats them as if they were given when first 6083553Smurray * invoked. Used by the parse module to implement 6183553Smurray * the .MFLAGS target. 6283553Smurray */ 6383553Smurray 6483553Smurray#include <sys/param.h> 6583553Smurray#include <sys/stat.h> 66119655Sdfr#include <sys/sysctl.h> 67119655Sdfr#include <sys/time.h> 68153479Sru#include <sys/queue.h> 6983553Smurray#include <sys/resource.h> 70103764Snsouch#include <sys/utsname.h> 71103764Snsouch#include <sys/wait.h> 72103764Snsouch#include <err.h> 73103764Snsouch#include <errno.h> 7483553Smurray#include <stdlib.h> 7583553Smurray#include <string.h> 76103764Snsouch#include <unistd.h> 7783553Smurray 7883553Smurray#include "arch.h" 7983553Smurray#include "buf.h" 8083553Smurray#include "config.h" 8183553Smurray#include "dir.h" 8283553Smurray#include "globals.h" 8383553Smurray#include "GNode.h" 8483553Smurray#include "job.h" 8583553Smurray#include "make.h" 8683553Smurray#include "parse.h" 8783553Smurray#include "pathnames.h" 8883553Smurray#include "shell.h" 8983553Smurray#include "str.h" 90103764Snsouch#include "suff.h" 91119796Sdfr#include "targ.h" 9283553Smurray#include "util.h" 9383553Smurray#include "var.h" 9483553Smurray 9583553Smurrayextern char **environ; /* XXX what header declares this variable? */ 9683553Smurray 9783553Smurray#define WANT_ENV_MKLVL 1 9883553Smurray#define MKLVL_MAXVAL 500 9983553Smurray#define MKLVL_ENVVAR "__MKLVL__" 100119796Sdfr 10183553Smurray/* ordered list of makefiles to read */ 10283553Smurraystatic Lst makefiles = Lst_Initializer(makefiles); 10383553Smurray 10483553Smurray/* ordered list of source makefiles */ 10583553Smurraystatic Lst source_makefiles = Lst_Initializer(source_makefiles); 10683553Smurray 10783553Smurray/* list of variables to print */ 10883553Smurraystatic Lst variables = Lst_Initializer(variables); 10983553Smurray 11083553Smurraystatic Boolean expandVars; /* fully expand printed variables */ 111165951Sjhbstatic Boolean noBuiltins; /* -r flag */ 112165951Sjhbstatic Boolean forceJobs; /* -j argument given */ 113119796Sdfrstatic char *curdir; /* startup directory */ 114119796Sdfrstatic char *objdir; /* where we chdir'ed to */ 115119796Sdfrstatic char **save_argv; /* saved argv */ 116119796Sdfrstatic char *save_makeflags;/* saved MAKEFLAGS */ 117119796Sdfr 118119796Sdfr/* (-E) vars to override from env */ 119119796SdfrLst envFirstVars = Lst_Initializer(envFirstVars); 120119796Sdfr 12183553Smurray/* Targets to be made */ 12283553SmurrayLst create = Lst_Initializer(create); 12383553Smurray 12483553SmurrayBoolean allPrecious; /* .PRECIOUS given on line by itself */ 12583553SmurrayBoolean is_posix; /* .POSIX target seen */ 126103764SnsouchBoolean mfAutoDeps; /* .MAKEFILEDEPS target seen */ 127103764SnsouchBoolean beSilent; /* -s flag */ 12883553SmurrayBoolean beVerbose; /* -v flag */ 129165951SjhbBoolean beQuiet; /* -Q flag */ 13083553SmurrayBoolean compatMake; /* -B argument */ 13183553Smurrayint debug; /* -d flag */ 132165951SjhbBoolean ignoreErrors; /* -i flag */ 133165951Sjhbint jobLimit; /* -j argument */ 134165951Sjhbint makeErrors; /* Number of targets not remade due to errors */ 135165951SjhbBoolean jobsRunning; /* TRUE if the jobs might be running */ 136103764SnsouchBoolean keepgoing; /* -k flag */ 137103764SnsouchBoolean noExecute; /* -n flag */ 138103764SnsouchBoolean printGraphOnly; /* -p flag */ 139103764SnsouchBoolean queryFlag; /* -q flag */ 140103764SnsouchBoolean touchFlag; /* -t flag */ 141103764SnsouchBoolean usePipes; /* !-P flag */ 142103764Snsouchuint32_t warn_cmd; /* command line warning flags */ 143103764Snsouchuint32_t warn_flags; /* actual warning flags */ 14483553Smurrayuint32_t warn_nocmd; /* command line no-warning flags */ 145165951Sjhb 146165951Sjhbtime_t now; /* Time at start of make */ 14783553Smurraystruct GNode *DEFAULT; /* .DEFAULT node */ 14883553Smurray 14983553Smurray/** 15083553Smurray * Exit with usage message. 151119796Sdfr */ 152119655Sdfrstatic void 153119655Sdfrusage(void) 154119796Sdfr{ 155119655Sdfr fprintf(stderr, 156119796Sdfr "usage: make [-BPSXeiknpqrstv] [-C directory] [-D variable]\n" 157119655Sdfr "\t[-d flags] [-E variable] [-f makefile] [-I directory]\n" 158119655Sdfr "\t[-j max_jobs] [-m directory] [-V variable]\n" 159128472Sobrien "\t[variable=value] [target ...]\n"); 160128472Sobrien exit(2); 161128472Sobrien} 162119798Sdfr 163153491Sru/** 164119798Sdfr * MFLAGS_append 165119798Sdfr * Append a flag with an optional argument to MAKEFLAGS and MFLAGS 166119798Sdfr */ 167119798Sdfrstatic void 168119798SdfrMFLAGS_append(const char *flag, char *arg) 169119798Sdfr{ 170119798Sdfr char *str; 171142398Simp 17283553Smurray Var_Append(".MAKEFLAGS", flag, VAR_GLOBAL); 173119796Sdfr if (arg != NULL) { 174153491Sru str = MAKEFLAGS_quote(arg); 175153491Sru Var_Append(".MAKEFLAGS", str, VAR_GLOBAL); 176153491Sru free(str); 177119796Sdfr } 178153491Sru 179153491Sru Var_Append("MFLAGS", flag, VAR_GLOBAL); 180153491Sru if (arg != NULL) { 181153491Sru str = MAKEFLAGS_quote(arg); 182153491Sru Var_Append("MFLAGS", str, VAR_GLOBAL); 183153491Sru free(str); 184153491Sru } 185153491Sru} 186119796Sdfr 187153491Sru/** 188119796Sdfr * Main_ParseWarn 189119796Sdfr * 19083553Smurray * Handle argument to warning option. 19183553Smurray */ 19283553Smurrayint 19383553SmurrayMain_ParseWarn(const char *arg, int iscmd) 19483553Smurray{ 19583553Smurray int i, neg; 19683553Smurray 19783553Smurray static const struct { 198153491Sru const char *option; 19983553Smurray uint32_t flag; 20083553Smurray } options[] = { 20183553Smurray { "dirsyntax", WARN_DIRSYNTAX }, 20283553Smurray { NULL, 0 } 20383553Smurray }; 204119796Sdfr 205119796Sdfr neg = 0; 206153491Sru if (arg[0] == 'n' && arg[1] == 'o') { 207153419Sjhb neg = 1; 208127135Snjl arg += 2; 209127135Snjl } 210153491Sru 21183553Smurray for (i = 0; options[i].option != NULL; i++) 21283553Smurray if (strcmp(arg, options[i].option) == 0) 21383553Smurray break; 214153491Sru 21583553Smurray if (options[i].option == NULL) 21683553Smurray /* unknown option */ 21783553Smurray return (-1); 218165951Sjhb 21983553Smurray if (iscmd) { 220103764Snsouch if (!neg) { 221103764Snsouch warn_cmd |= options[i].flag; 222165951Sjhb warn_nocmd &= ~options[i].flag; 223165951Sjhb warn_flags |= options[i].flag; 224119798Sdfr } else { 225165951Sjhb warn_nocmd |= options[i].flag; 226103764Snsouch warn_cmd &= ~options[i].flag; 227103764Snsouch warn_flags &= ~options[i].flag; 228103764Snsouch } 22983553Smurray } else { 23083553Smurray if (!neg) { 23183553Smurray warn_flags |= (options[i].flag & ~warn_nocmd); 23283553Smurray } else { 233103764Snsouch warn_flags &= ~(options[i].flag | warn_cmd); 23483553Smurray } 235103764Snsouch } 23683553Smurray return (0); 237103764Snsouch} 238119798Sdfr 239119798Sdfr/** 240103764Snsouch * Open and parse the given makefile. 24193040Snsouch * 242165951Sjhb * Results: 243103764Snsouch * TRUE if ok. FALSE if couldn't open file. 244119798Sdfr */ 245119798Sdfrstatic Boolean 24683553SmurrayReadMakefile(const char p[]) 24783553Smurray{ 24883553Smurray char *fname, *fnamesave; /* makefile to read */ 24983553Smurray FILE *stream; 25083553Smurray char *name, path[MAXPATHLEN]; 251162234Sjhb char *MAKEFILE; 25283553Smurray int setMAKEFILE; 25383553Smurray 25483553Smurray /* XXX - remove this once constification is done */ 25583553Smurray fnamesave = fname = estrdup(p); 25683553Smurray 25783553Smurray if (!strcmp(fname, "-")) { 25883553Smurray Parse_File("(stdin)", stdin); 25983553Smurray Var_SetGlobal("MAKEFILE", ""); 26083553Smurray } else { 26183553Smurray setMAKEFILE = strcmp(fname, ".depend"); 26283553Smurray 26383553Smurray /* if we've chdir'd, rebuild the path name */ 26483553Smurray if (curdir != objdir && *fname != '/') { 26583553Smurray snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname); 26683553Smurray /* 267103764Snsouch * XXX The realpath stuff breaks relative includes 26883553Smurray * XXX in some cases. The problem likely is in 269165951Sjhb * XXX parse.c where it does special things in 270165951Sjhb * XXX ParseDoInclude if the file is relateive 27183553Smurray * XXX or absolute and not a system file. There 27283553Smurray * XXX it assumes that if the current file that's 27383553Smurray * XXX being included is absolute, that any files 27483553Smurray * XXX that it includes shouldn't do the -I path 27583553Smurray * XXX stuff, which is inconsistant with historical 27683553Smurray * XXX behavior. However, I can't pentrate the mists 27791265Speter * XXX further, so I'm putting this workaround in 27883553Smurray * XXX here until such time as the underlying bug 279103764Snsouch * XXX can be fixed. 28083553Smurray */ 28183553Smurray#if THIS_BREAKS_THINGS 282153491Sru if (realpath(path, path) != NULL && 28383553Smurray (stream = fopen(path, "r")) != NULL) { 28483553Smurray MAKEFILE = fname; 28583553Smurray fname = path; 28683553Smurray goto found; 28783553Smurray } 28891265Speter } else if (realpath(fname, path) != NULL) { 28983553Smurray MAKEFILE = fname; 29083553Smurray fname = path; 291103764Snsouch if ((stream = fopen(fname, "r")) != NULL) 29283553Smurray goto found; 29383553Smurray } 29483553Smurray#else 295165951Sjhb if ((stream = fopen(path, "r")) != NULL) { 29683553Smurray MAKEFILE = fname; 29783553Smurray fname = path; 29883553Smurray goto found; 29983553Smurray } 30083553Smurray } else { 30183553Smurray MAKEFILE = fname; 30283553Smurray if ((stream = fopen(fname, "r")) != NULL) 30383553Smurray goto found; 30483553Smurray } 30583553Smurray#endif 30683553Smurray /* look in -I and system include directories. */ 307103764Snsouch name = Path_FindFile(fname, &parseIncPath); 30883553Smurray if (!name) 30983553Smurray name = Path_FindFile(fname, &sysIncPath); 31083553Smurray if (!name || !(stream = fopen(name, "r"))) { 31183553Smurray free(fnamesave); 31283553Smurray return (FALSE); 313165951Sjhb } 31483553Smurray MAKEFILE = fname = name; 31583553Smurray /* 31683553Smurray * set the MAKEFILE variable desired by System V fans -- the 31783553Smurray * placement of the setting here means it gets set to the last 31883553Smurray * makefile specified, as it is set by SysV make. 31983553Smurray */ 32083553Smurrayfound: 32183553Smurray if (setMAKEFILE) 32283553Smurray Var_SetGlobal("MAKEFILE", MAKEFILE); 32383553Smurray Parse_File(fname, stream); 32483553Smurray } 32583553Smurray free(fnamesave); 32683553Smurray return (TRUE); 32783553Smurray} 32883553Smurray 32983553Smurray/** 33083553Smurray * Open and parse the given makefile. 33183553Smurray * If open is successful add it to the list of makefiles. 33283553Smurray * 33383553Smurray * Results: 33483553Smurray * TRUE if ok. FALSE if couldn't open file. 33583553Smurray */ 33683553Smurraystatic Boolean 33783553SmurrayTryReadMakefile(const char p[]) 33883553Smurray{ 339103764Snsouch char *data; 34083553Smurray LstNode *last = Lst_Last(&source_makefiles); 34183553Smurray 34283553Smurray if (!ReadMakefile(p)) 34383553Smurray return (FALSE); 34483553Smurray 345103764Snsouch data = estrdup(p); 34683553Smurray if (last == NULL) { 347103764Snsouch LstNode *first = Lst_First(&source_makefiles); 34883553Smurray Lst_Insert(&source_makefiles, first, data); 34983553Smurray } else 35083553Smurray Lst_Append(&source_makefiles, last, estrdup(p)); 351165951Sjhb return (TRUE); 352103764Snsouch} 353165951Sjhb 354165951Sjhb/** 35583553Smurray * MainParseArgs 356165951Sjhb * Parse a given argument vector. Called from main() and from 35783553Smurray * Main_ParseArgLine() when the .MAKEFLAGS target is used. 35883553Smurray * 35983553Smurray * XXX: Deal with command line overriding .MAKEFLAGS in makefile 36083553Smurray * 36183553Smurray * Side Effects: 36283553Smurray * Various global and local flags will be set depending on the flags 36383553Smurray * given 36483553Smurray */ 36583553Smurraystatic void 36683553SmurrayMainParseArgs(int argc, char **argv) 36783553Smurray{ 36887599Sobrien int c; 36983553Smurray Boolean found_dd = FALSE; 37083553Smurray 37183553Smurrayrearg: 37283553Smurray optind = 1; /* since we're called more than once */ 373103764Snsouch optreset = 1; 37483553Smurray#define OPTFLAGS "ABC:D:E:I:PSV:Xd:ef:ij:km:nQpqrstvx:" 37583553Smurray for (;;) { 376165951Sjhb if ((optind < argc) && strcmp(argv[optind], "--") == 0) { 37783553Smurray found_dd = TRUE; 37883553Smurray } 37983553Smurray if ((c = getopt(argc, argv, OPTFLAGS)) == -1) { 38083553Smurray break; 38183553Smurray } 382103764Snsouch switch(c) { 38383553Smurray 384103764Snsouch case 'A': 38583553Smurray arch_fatal = FALSE; 38683553Smurray MFLAGS_append("-A", NULL); 38783553Smurray break; 388165951Sjhb case 'C': 389103764Snsouch if (chdir(optarg) == -1) 390165951Sjhb err(1, "chdir %s", optarg); 391165951Sjhb break; 39283553Smurray case 'D': 393165951Sjhb Var_SetGlobal(optarg, "1"); 39483553Smurray MFLAGS_append("-D", optarg); 39583553Smurray break; 39683553Smurray case 'I': 39783553Smurray Parse_AddIncludeDir(optarg); 39883553Smurray MFLAGS_append("-I", optarg); 39983553Smurray break; 400103764Snsouch case 'V': 40183553Smurray Lst_AtEnd(&variables, estrdup(optarg)); 40283553Smurray MFLAGS_append("-V", optarg); 403165951Sjhb break; 40483553Smurray case 'X': 40583553Smurray expandVars = FALSE; 40683553Smurray break; 40783553Smurray case 'B': 40883553Smurray compatMake = TRUE; 409103764Snsouch MFLAGS_append("-B", NULL); 41083553Smurray unsetenv("MAKE_JOBS_FIFO"); 411103764Snsouch break; 41283553Smurray case 'P': 41383553Smurray usePipes = FALSE; 41483553Smurray MFLAGS_append("-P", NULL); 415165951Sjhb break; 416103764Snsouch case 'S': 417165951Sjhb keepgoing = FALSE; 418165951Sjhb MFLAGS_append("-S", NULL); 41983553Smurray break; 420165951Sjhb case 'd': { 42183553Smurray char *modules = optarg; 42283553Smurray 42383553Smurray for (; *modules; ++modules) 42483553Smurray switch (*modules) { 42583553Smurray case 'A': 426103764Snsouch debug = ~0; 42783553Smurray break; 42883553Smurray case 'a': 42983553Smurray debug |= DEBUG_ARCH; 430165951Sjhb break; 43183553Smurray case 'c': 43283553Smurray debug |= DEBUG_COND; 43383553Smurray break; 43483553Smurray case 'd': 43583553Smurray debug |= DEBUG_DIR; 436103764Snsouch break; 43783553Smurray case 'f': 438103764Snsouch debug |= DEBUG_FOR; 43983553Smurray break; 44083553Smurray case 'g': 44183553Smurray if (modules[1] == '1') { 442165951Sjhb debug |= DEBUG_GRAPH1; 443103764Snsouch ++modules; 444165951Sjhb } 445165951Sjhb else if (modules[1] == '2') { 44683553Smurray debug |= DEBUG_GRAPH2; 447165951Sjhb ++modules; 44883553Smurray } 44983553Smurray break; 45083553Smurray case 'j': 45183553Smurray debug |= DEBUG_JOB; 45283553Smurray break; 45383553Smurray case 'l': 45483553Smurray debug |= DEBUG_LOUD; 455103764Snsouch break; 45683553Smurray case 'm': 45783553Smurray debug |= DEBUG_MAKE; 458165951Sjhb break; 45983553Smurray case 's': 46083553Smurray debug |= DEBUG_SUFF; 46183553Smurray break; 46283553Smurray case 't': 46383553Smurray debug |= DEBUG_TARG; 464103764Snsouch break; 46583553Smurray case 'v': 466103764Snsouch debug |= DEBUG_VAR; 46783553Smurray break; 46883553Smurray default: 46983553Smurray warnx("illegal argument to d option " 470165951Sjhb "-- %c", *modules); 471103764Snsouch usage(); 472165951Sjhb } 473165951Sjhb MFLAGS_append("-d", optarg); 47483553Smurray break; 475165951Sjhb } 47683553Smurray case 'E': 47783553Smurray Lst_AtEnd(&envFirstVars, estrdup(optarg)); 47883553Smurray MFLAGS_append("-E", optarg); 47983553Smurray break; 48083553Smurray case 'e': 48183553Smurray checkEnvFirst = TRUE; 482103764Snsouch MFLAGS_append("-e", NULL); 48383553Smurray break; 48483553Smurray case 'f': 48583553Smurray Lst_AtEnd(&makefiles, estrdup(optarg)); 486165951Sjhb break; 48783553Smurray case 'i': 48883553Smurray ignoreErrors = TRUE; 48983553Smurray MFLAGS_append("-i", NULL); 49083553Smurray break; 49183553Smurray case 'j': { 492103764Snsouch char *endptr; 49383553Smurray 494103764Snsouch forceJobs = TRUE; 49583553Smurray jobLimit = strtol(optarg, &endptr, 10); 49683553Smurray if (jobLimit <= 0 || *endptr != '\0') { 49783553Smurray warnx("illegal number, -j argument -- %s", 498165951Sjhb optarg); 499103764Snsouch usage(); 500165951Sjhb } 501165951Sjhb MFLAGS_append("-j", optarg); 50283553Smurray break; 503165951Sjhb } 50483553Smurray case 'k': 50583553Smurray keepgoing = TRUE; 50683553Smurray MFLAGS_append("-k", NULL); 50783553Smurray break; 50883553Smurray case 'm': 50983553Smurray Path_AddDir(&sysIncPath, optarg); 51083553Smurray MFLAGS_append("-m", optarg); 511103764Snsouch break; 51283553Smurray case 'n': 51383553Smurray noExecute = TRUE; 514165951Sjhb MFLAGS_append("-n", NULL); 51583553Smurray break; 51683553Smurray case 'p': 51783553Smurray printGraphOnly = TRUE; 51883553Smurray debug |= DEBUG_GRAPH1; 51983553Smurray break; 520103764Snsouch case 'Q': 52183553Smurray beQuiet = TRUE; 522103764Snsouch beVerbose = FALSE; 52383553Smurray MFLAGS_append("-Q", NULL); 52483553Smurray break; 52583553Smurray case 'q': 526165951Sjhb queryFlag = TRUE; 527103764Snsouch /* Kind of nonsensical, wot? */ 528165951Sjhb MFLAGS_append("-q", NULL); 529165951Sjhb break; 53083553Smurray case 'r': 531165951Sjhb noBuiltins = TRUE; 53283553Smurray MFLAGS_append("-r", NULL); 53383553Smurray break; 53483553Smurray case 's': 53583553Smurray beQuiet = TRUE; 53683553Smurray beSilent = TRUE; 53783553Smurray MFLAGS_append("-s", NULL); 538103764Snsouch break; 53983553Smurray case 't': 54083553Smurray touchFlag = TRUE; 54183553Smurray MFLAGS_append("-t", NULL); 542165951Sjhb break; 54383553Smurray case 'v': 54483553Smurray beVerbose = TRUE; 54583553Smurray beQuiet = FALSE; 54683553Smurray MFLAGS_append("-v", NULL); 54783553Smurray break; 548103764Snsouch case 'x': 54983553Smurray if (Main_ParseWarn(optarg, 1) != -1) 550103764Snsouch MFLAGS_append("-x", optarg); 551162234Sjhb break; 552162234Sjhb 55383553Smurray default: 55483553Smurray case '?': 555162234Sjhb usage(); 556162234Sjhb } 557165951Sjhb } 558165951Sjhb argv += optind; 559103764Snsouch argc -= optind; 560165951Sjhb 561165951Sjhb oldVars = TRUE; 56283553Smurray 563165951Sjhb /* 56483553Smurray * Parse the rest of the arguments. 565162234Sjhb * o Check for variable assignments and perform them if so. 566153491Sru * o Check for more flags and restart getopt if so. 567162234Sjhb * o Anything else is taken to be a target and added 568162234Sjhb * to the end of the "create" list. 569162234Sjhb */ 570162234Sjhb for (; *argv != NULL; ++argv, --argc) { 571162234Sjhb if (Parse_IsVar(*argv)) { 57283553Smurray char *ptr = MAKEFLAGS_quote(*argv); 573162234Sjhb char *v = estrdup(*argv); 574162234Sjhb 575162234Sjhb Var_Append(".MAKEFLAGS", ptr, VAR_GLOBAL); 576162234Sjhb Parse_DoVar(v, VAR_CMD); 577162234Sjhb free(ptr); 578162234Sjhb free(v); 579162234Sjhb 580162234Sjhb } else if ((*argv)[0] == '-') { 581162234Sjhb if ((*argv)[1] == '\0') { 58283553Smurray /* 583162234Sjhb * (*argv) is a single dash, so we 58483553Smurray * just ignore it. 58583553Smurray */ 586165951Sjhb } else if (found_dd) { 58783553Smurray /* 58883553Smurray * Double dash has been found, ignore 58983553Smurray * any more options. But what do we do 59083553Smurray * with it? For now treat it like a target. 59183553Smurray */ 592162234Sjhb Lst_AtEnd(&create, estrdup(*argv)); 59383553Smurray } else { 594103764Snsouch /* 595162234Sjhb * (*argv) is a -flag, so backup argv and 596162234Sjhb * argc. getopt() expects options to start 59783553Smurray * in the 2nd position. 59883553Smurray */ 599162234Sjhb argc++; 600162234Sjhb argv--; 601165951Sjhb goto rearg; 602165951Sjhb } 603103764Snsouch 604165951Sjhb } else if ((*argv)[0] == '\0') { 605165951Sjhb Punt("illegal (null) argument."); 60683553Smurray 607165951Sjhb } else { 60883553Smurray Lst_AtEnd(&create, estrdup(*argv)); 609162234Sjhb } 610153491Sru } 611162234Sjhb} 61283553Smurray 613162234Sjhb/** 614162234Sjhb * Main_ParseArgLine 615162234Sjhb * Used by the parse module when a .MFLAGS or .MAKEFLAGS target 616153491Sru * is encountered and by main() when reading the .MAKEFLAGS envariable. 617162234Sjhb * Takes a line of arguments and breaks it into its 618162234Sjhb * component words and passes those words and the number of them to the 61983553Smurray * MainParseArgs function. 620162234Sjhb * The line should have all its leading whitespace removed. 62183553Smurray * 622162234Sjhb * Side Effects: 623162234Sjhb * Only those that come from the various arguments. 624162234Sjhb */ 625162234Sjhbvoid 626162234SjhbMain_ParseArgLine(char *line, int mflags) 627162234Sjhb{ 628162234Sjhb ArgArray aa; 629162234Sjhb 63083553Smurray if (line == NULL) 63183553Smurray return; 632162234Sjhb for (; *line == ' '; ++line) 633165951Sjhb continue; 63483553Smurray if (!*line) 63583553Smurray return; 63683553Smurray 63783553Smurray if (mflags) 638153491Sru MAKEFLAGS_break(&aa, line); 63983553Smurray else 64083553Smurray brk_string(&aa, line, TRUE); 64183553Smurray 64283553Smurray MainParseArgs(aa.argc, aa.argv); 64383553Smurray ArgArray_Done(&aa); 644103764Snsouch} 645153491Sru 646103764Snsouchstatic char * 647103764Snsouchchdir_verify_path(const char *path, char *obpath) 648103764Snsouch{ 649103764Snsouch struct stat sb; 650103764Snsouch 651103764Snsouch if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { 652103764Snsouch if (chdir(path) == -1 || getcwd(obpath, MAXPATHLEN) == NULL) { 653103764Snsouch warn("warning: %s", path); 654103764Snsouch return (NULL); 655103764Snsouch } 656103764Snsouch return (obpath); 657153491Sru } 65883553Smurray 65983553Smurray return (NULL); 66083553Smurray} 66183553Smurray 66283553Smurray/** 66383553Smurray * In lieu of a good way to prevent every possible looping in make(1), stop 66483553Smurray * there from being more than MKLVL_MAXVAL processes forked by make(1), to 66583553Smurray * prevent a forkbomb from happening, in a dumb and mechanical way. 66683553Smurray * 66783553Smurray * Side Effects: 668162234Sjhb * Creates or modifies enviornment variable MKLVL_ENVVAR via setenv(). 669103764Snsouch */ 670113506Smdoddstatic void 67193040Snsouchcheck_make_level(void) 67293040Snsouch{ 673#ifdef WANT_ENV_MKLVL 674 char *value = getenv(MKLVL_ENVVAR); 675 int level = (value == NULL) ? 0 : atoi(value); 676 677 if (level < 0) { 678 errc(2, EAGAIN, "Invalid value for recursion level (%d).", 679 level); 680 } else if (level > MKLVL_MAXVAL) { 681 errc(2, EAGAIN, "Max recursion level (%d) exceeded.", 682 MKLVL_MAXVAL); 683 } else { 684 char new_value[32]; 685 sprintf(new_value, "%d", level + 1); 686 setenv(MKLVL_ENVVAR, new_value, 1); 687 } 688#endif /* WANT_ENV_MKLVL */ 689} 690 691/** 692 * Main_AddSourceMakefile 693 * Add a file to the list of source makefiles 694 */ 695void 696Main_AddSourceMakefile(const char *name) 697{ 698 699 Lst_AtEnd(&source_makefiles, estrdup(name)); 700} 701 702/** 703 * Remake_Makefiles 704 * Remake all the makefiles 705 */ 706static void 707Remake_Makefiles(void) 708{ 709 LstNode *ln; 710 int error_cnt = 0; 711 int remade_cnt = 0; 712 713 Compat_InstallSignalHandlers(); 714 if (curdir != objdir) { 715 if (chdir(curdir) < 0) 716 Fatal("Failed to change directory to %s.", curdir); 717 } 718 719 LST_FOREACH(ln, &source_makefiles) { 720 LstNode *ln2; 721 struct GNode *gn; 722 const char *name = Lst_Datum(ln); 723 Boolean saveTouchFlag = touchFlag; 724 Boolean saveQueryFlag = queryFlag; 725 Boolean saveNoExecute = noExecute; 726 int mtime; 727 728 /* 729 * Create node 730 */ 731 gn = Targ_FindNode(name, TARG_CREATE); 732 DEBUGF(MAKE, ("Checking %s...", gn->name)); 733 Suff_FindDeps(gn); 734 735 /* 736 * ! dependencies as well as 737 * dependencies with .FORCE, .EXEC and .PHONY attributes 738 * are skipped to prevent infinite loops 739 */ 740 if (gn->type & (OP_FORCE | OP_EXEC | OP_PHONY)) { 741 DEBUGF(MAKE, ("skipping (force, exec or phony).\n", 742 gn->name)); 743 continue; 744 } 745 746 /* 747 * Skip :: targets that have commands and no children 748 * because such targets are always out-of-date 749 */ 750 if ((gn->type & OP_DOUBLEDEP) && 751 !Lst_IsEmpty(&gn->commands) && 752 Lst_IsEmpty(&gn->children)) { 753 DEBUGF(MAKE, ("skipping (doubledep, no sources " 754 "and has commands).\n")); 755 continue; 756 } 757 758 /* 759 * Skip targets without sources and without commands 760 */ 761 if (Lst_IsEmpty(&gn->commands) && 762 Lst_IsEmpty(&gn->children)) { 763 DEBUGF(MAKE, 764 ("skipping (no sources and no commands).\n")); 765 continue; 766 } 767 768 DEBUGF(MAKE, ("\n")); 769 770 /* 771 * -t, -q and -n has no effect unless the makefile is 772 * specified as one of the targets explicitly in the 773 * command line 774 */ 775 LST_FOREACH(ln2, &create) { 776 if (!strcmp(gn->name, Lst_Datum(ln2))) { 777 /* found as a target */ 778 break; 779 } 780 } 781 if (ln2 == NULL) { 782 touchFlag = FALSE; 783 queryFlag = FALSE; 784 noExecute = FALSE; 785 } 786 787 /* 788 * Check and remake the makefile 789 */ 790 mtime = Dir_MTime(gn); 791 Compat_Make(gn, gn); 792 793 /* 794 * Restore -t, -q and -n behaviour 795 */ 796 touchFlag = saveTouchFlag; 797 queryFlag = saveQueryFlag; 798 noExecute = saveNoExecute; 799 800 /* 801 * Compat_Make will leave the 'made' field of gn 802 * in one of the following states: 803 * UPTODATE gn was already up-to-date 804 * MADE gn was recreated successfully 805 * ERROR An error occurred while gn was being created 806 * ABORTED gn was not remade because one of its inferiors 807 * could not be made due to errors. 808 */ 809 if (gn->made == MADE) { 810 if (mtime != Dir_MTime(gn)) { 811 DEBUGF(MAKE, 812 ("%s updated (%d -> %d).\n", 813 gn->name, mtime, gn->mtime)); 814 remade_cnt++; 815 } else { 816 DEBUGF(MAKE, 817 ("%s not updated: skipping restart.\n", 818 gn->name)); 819 } 820 } else if (gn->made == ERROR) 821 error_cnt++; 822 else if (gn->made == ABORTED) { 823 printf("`%s' not remade because of errors.\n", 824 gn->name); 825 error_cnt++; 826 } else if (gn->made == UPTODATE) { 827 Lst examine; 828 829 Lst_Init(&examine); 830 Lst_EnQueue(&examine, gn); 831 while (!Lst_IsEmpty(&examine)) { 832 LstNode *eln; 833 GNode *egn = Lst_DeQueue(&examine); 834 835 egn->make = FALSE; 836 LST_FOREACH(eln, &egn->children) { 837 GNode *cgn = Lst_Datum(eln); 838 839 Lst_EnQueue(&examine, cgn); 840 } 841 } 842 } 843 } 844 845 if (error_cnt > 0) 846 Fatal("Failed to remake Makefiles."); 847 if (remade_cnt > 0) { 848 DEBUGF(MAKE, ("Restarting `%s'.\n", save_argv[0])); 849 850 /* 851 * Some of makefiles were remade -- restart from clean state 852 */ 853 if (save_makeflags != NULL) 854 setenv("MAKEFLAGS", save_makeflags, 1); 855 else 856 unsetenv("MAKEFLAGS"); 857 if (execvp(save_argv[0], save_argv) < 0) { 858 Fatal("Can't restart `%s': %s.", 859 save_argv[0], strerror(errno)); 860 } 861 } 862 863 if (curdir != objdir) { 864 if (chdir(objdir) < 0) 865 Fatal("Failed to change directory to %s.", objdir); 866 } 867} 868 869/** 870 * main 871 * The main function, for obvious reasons. Initializes variables 872 * and a few modules, then parses the arguments give it in the 873 * environment and on the command line. Reads the system makefile 874 * followed by either Makefile, makefile or the file given by the 875 * -f argument. Sets the .MAKEFLAGS PMake variable based on all the 876 * flags it has received by then uses either the Make or the Compat 877 * module to create the initial list of targets. 878 * 879 * Results: 880 * If -q was given, exits -1 if anything was out-of-date. Else it exits 881 * 0. 882 * 883 * Side Effects: 884 * The program exits when done. Targets are created. etc. etc. etc. 885 */ 886int 887main(int argc, char **argv) 888{ 889 const char *machine; 890 const char *machine_arch; 891 const char *machine_cpu; 892 Boolean outOfDate = TRUE; /* FALSE if all targets up to date */ 893 const char *p; 894 const char *pathp; 895 const char *path; 896 char mdpath[MAXPATHLEN]; 897 char obpath[MAXPATHLEN]; 898 char cdpath[MAXPATHLEN]; 899 char *cp = NULL, *start; 900 901 save_argv = argv; 902 save_makeflags = getenv("MAKEFLAGS"); 903 if (save_makeflags != NULL) 904 save_makeflags = estrdup(save_makeflags); 905 906 /* 907 * Initialize file global variables. 908 */ 909 expandVars = TRUE; 910 noBuiltins = FALSE; /* Read the built-in rules */ 911 forceJobs = FALSE; /* No -j flag */ 912 curdir = cdpath; 913 914 /* 915 * Initialize program global variables. 916 */ 917 beSilent = FALSE; /* Print commands as executed */ 918 ignoreErrors = FALSE; /* Pay attention to non-zero returns */ 919 noExecute = FALSE; /* Execute all commands */ 920 printGraphOnly = FALSE; /* Don't stop after printing graph */ 921 keepgoing = FALSE; /* Stop on error */ 922 allPrecious = FALSE; /* Remove targets when interrupted */ 923 queryFlag = FALSE; /* This is not just a check-run */ 924 touchFlag = FALSE; /* Actually update targets */ 925 usePipes = TRUE; /* Catch child output in pipes */ 926 debug = 0; /* No debug verbosity, please. */ 927 jobsRunning = FALSE; 928 929 jobLimit = DEFMAXJOBS; 930 compatMake = FALSE; /* No compat mode */ 931 932 check_make_level(); 933 934#ifdef RLIMIT_NOFILE 935 /* 936 * get rid of resource limit on file descriptors 937 */ 938 { 939 struct rlimit rl; 940 if (getrlimit(RLIMIT_NOFILE, &rl) == -1) { 941 err(2, "getrlimit"); 942 } 943 rl.rlim_cur = rl.rlim_max; 944 if (setrlimit(RLIMIT_NOFILE, &rl) == -1) { 945 err(2, "setrlimit"); 946 } 947 } 948#endif 949 950 /* 951 * Prior to 7.0, FreeBSD/pc98 kernel used to set the 952 * utsname.machine to "i386", and MACHINE was defined as 953 * "i386", so it could not be distinguished from FreeBSD/i386. 954 * Therefore, we had to check machine.ispc98 and adjust the 955 * MACHINE variable. NOTE: The code is still here to be able 956 * to compile new make binary on old FreeBSD/pc98 systems, and 957 * have the MACHINE variable set properly. 958 */ 959 if ((machine = getenv("MACHINE")) == NULL) { 960 int ispc98; 961 size_t len; 962 963 len = sizeof(ispc98); 964 if (!sysctlbyname("machdep.ispc98", &ispc98, &len, NULL, 0)) { 965 if (ispc98) 966 machine = "pc98"; 967 } 968 } 969 970 /* 971 * Get the name of this type of MACHINE from utsname 972 * so we can share an executable for similar machines. 973 * (i.e. m68k: amiga hp300, mac68k, sun3, ...) 974 * 975 * Note that both MACHINE and MACHINE_ARCH are decided at 976 * run-time. 977 */ 978 if (machine == NULL) { 979 static struct utsname utsname; 980 981 if (uname(&utsname) == -1) 982 err(2, "uname"); 983 machine = utsname.machine; 984 } 985 986 if ((machine_arch = getenv("MACHINE_ARCH")) == NULL) { 987#ifdef MACHINE_ARCH 988 machine_arch = MACHINE_ARCH; 989#else 990 machine_arch = "unknown"; 991#endif 992 } 993 994 /* 995 * Set machine_cpu to the minumum supported CPU revision based 996 * on the target architecture, if not already set. 997 */ 998 if ((machine_cpu = getenv("MACHINE_CPU")) == NULL) { 999 if (!strcmp(machine_arch, "i386")) 1000 machine_cpu = "i386"; 1001 else if (!strcmp(machine_arch, "alpha")) 1002 machine_cpu = "ev4"; 1003 else 1004 machine_cpu = "unknown"; 1005 } 1006 1007 /* 1008 * Initialize the parsing, directory and variable modules to prepare 1009 * for the reading of inclusion paths and variable settings on the 1010 * command line 1011 */ 1012 Proc_Init(); 1013 1014 Dir_Init(); /* Initialize directory structures so -I flags 1015 * can be processed correctly */ 1016 Var_Init(environ); /* As well as the lists of variables for 1017 * parsing arguments */ 1018 1019 /* 1020 * Initialize the Shell so that we have a shell for != assignments 1021 * on the command line. 1022 */ 1023 Shell_Init(); 1024 1025 /* 1026 * Initialize various variables. 1027 * MAKE also gets this name, for compatibility 1028 * .MAKEFLAGS gets set to the empty string just in case. 1029 * MFLAGS also gets initialized empty, for compatibility. 1030 */ 1031 Var_SetGlobal("MAKE", argv[0]); 1032 Var_SetGlobal(".MAKEFLAGS", ""); 1033 Var_SetGlobal("MFLAGS", ""); 1034 Var_SetGlobal("MACHINE", machine); 1035 Var_SetGlobal("MACHINE_ARCH", machine_arch); 1036 Var_SetGlobal("MACHINE_CPU", machine_cpu); 1037#ifdef MAKE_VERSION 1038 Var_SetGlobal("MAKE_VERSION", MAKE_VERSION); 1039#endif 1040 Var_SetGlobal(".newline", "\n"); /* handy for :@ loops */ 1041 { 1042 char tmp[64]; 1043 1044 snprintf(tmp, sizeof(tmp), "%u", getpid()); 1045 Var_SetGlobal(".MAKE.PID", tmp); 1046 snprintf(tmp, sizeof(tmp), "%u", getppid()); 1047 Var_SetGlobal(".MAKE.PPID", tmp); 1048 } 1049 Job_SetPrefix(); 1050 1051 /* 1052 * First snag things out of the MAKEFLAGS environment 1053 * variable. Then parse the command line arguments. 1054 */ 1055 Main_ParseArgLine(getenv("MAKEFLAGS"), 1); 1056 1057 MainParseArgs(argc, argv); 1058 1059 /* 1060 * Find where we are... 1061 */ 1062 if (getcwd(curdir, MAXPATHLEN) == NULL) 1063 err(2, NULL); 1064 1065 { 1066 struct stat sa; 1067 1068 if (stat(curdir, &sa) == -1) 1069 err(2, "%s", curdir); 1070 } 1071 1072 /* 1073 * The object directory location is determined using the 1074 * following order of preference: 1075 * 1076 * 1. MAKEOBJDIRPREFIX`cwd` 1077 * 2. MAKEOBJDIR 1078 * 3. PATH_OBJDIR.${MACHINE} 1079 * 4. PATH_OBJDIR 1080 * 5. PATH_OBJDIRPREFIX`cwd` 1081 * 1082 * If one of the first two fails, use the current directory. 1083 * If the remaining three all fail, use the current directory. 1084 * 1085 * Once things are initted, 1086 * have to add the original directory to the search path, 1087 * and modify the paths for the Makefiles apropriately. The 1088 * current directory is also placed as a variable for make scripts. 1089 */ 1090 if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) { 1091 if (!(path = getenv("MAKEOBJDIR"))) { 1092 path = PATH_OBJDIR; 1093 pathp = PATH_OBJDIRPREFIX; 1094 snprintf(mdpath, MAXPATHLEN, "%s.%s", path, machine); 1095 if (!(objdir = chdir_verify_path(mdpath, obpath))) 1096 if (!(objdir=chdir_verify_path(path, obpath))) { 1097 snprintf(mdpath, MAXPATHLEN, 1098 "%s%s", pathp, curdir); 1099 if (!(objdir=chdir_verify_path(mdpath, 1100 obpath))) 1101 objdir = curdir; 1102 } 1103 } 1104 else if (!(objdir = chdir_verify_path(path, obpath))) 1105 objdir = curdir; 1106 } 1107 else { 1108 snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir); 1109 if (!(objdir = chdir_verify_path(mdpath, obpath))) 1110 objdir = curdir; 1111 } 1112 Dir_InitDot(); /* Initialize the "." directory */ 1113 if (objdir != curdir) 1114 Path_AddDir(&dirSearchPath, curdir); 1115 Var_SetGlobal(".ST_EXPORTVAR", "YES"); 1116 Var_SetGlobal(".CURDIR", curdir); 1117 Var_SetGlobal(".OBJDIR", objdir); 1118 1119 if (getenv("MAKE_JOBS_FIFO") != NULL) 1120 forceJobs = TRUE; 1121 /* 1122 * Be compatible if user did not specify -j and did not explicitly 1123 * turned compatibility on 1124 */ 1125 if (!compatMake && !forceJobs) 1126 compatMake = TRUE; 1127 1128 /* 1129 * Initialize target and suffix modules in preparation for 1130 * parsing the makefile(s) 1131 */ 1132 Targ_Init(); 1133 Suff_Init(); 1134 1135 DEFAULT = NULL; 1136 time(&now); 1137 1138 /* 1139 * Set up the .TARGETS variable to contain the list of targets to be 1140 * created. If none specified, make the variable empty -- the parser 1141 * will fill the thing in with the default or .MAIN target. 1142 */ 1143 if (Lst_IsEmpty(&create)) { 1144 Var_SetGlobal(".TARGETS", ""); 1145 } else { 1146 LstNode *ln; 1147 1148 for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) { 1149 char *name = Lst_Datum(ln); 1150 1151 Var_Append(".TARGETS", name, VAR_GLOBAL); 1152 } 1153 } 1154 1155 1156 /* 1157 * If no user-supplied system path was given (through the -m option) 1158 * add the directories from the DEFSYSPATH (more than one may be given 1159 * as dir1:...:dirn) to the system include path. 1160 */ 1161 if (TAILQ_EMPTY(&sysIncPath)) { 1162 char syspath[] = PATH_DEFSYSPATH; 1163 1164 for (start = syspath; *start != '\0'; start = cp) { 1165 for (cp = start; *cp != '\0' && *cp != ':'; cp++) 1166 continue; 1167 if (*cp == '\0') { 1168 Path_AddDir(&sysIncPath, start); 1169 } else { 1170 *cp++ = '\0'; 1171 Path_AddDir(&sysIncPath, start); 1172 } 1173 } 1174 } 1175 1176 /* 1177 * Read in the built-in rules first, followed by the specified 1178 * makefile, if it was (makefile != (char *) NULL), or the default 1179 * Makefile and makefile, in that order, if it wasn't. 1180 */ 1181 if (!noBuiltins) { 1182 /* Path of sys.mk */ 1183 Lst sysMkPath = Lst_Initializer(sysMkPath); 1184 LstNode *ln; 1185 char defsysmk[] = PATH_DEFSYSMK; 1186 1187 Path_Expand(defsysmk, &sysIncPath, &sysMkPath); 1188 if (Lst_IsEmpty(&sysMkPath)) 1189 Fatal("make: no system rules (%s).", PATH_DEFSYSMK); 1190 LST_FOREACH(ln, &sysMkPath) { 1191 if (!ReadMakefile(Lst_Datum(ln))) 1192 break; 1193 } 1194 if (ln != NULL) 1195 Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 1196 Lst_Destroy(&sysMkPath, free); 1197 } 1198 1199 if (!Lst_IsEmpty(&makefiles)) { 1200 LstNode *ln; 1201 1202 LST_FOREACH(ln, &makefiles) { 1203 if (!TryReadMakefile(Lst_Datum(ln))) 1204 break; 1205 } 1206 if (ln != NULL) 1207 Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 1208 } else if (!TryReadMakefile("BSDmakefile")) 1209 if (!TryReadMakefile("makefile")) 1210 TryReadMakefile("Makefile"); 1211 1212 ReadMakefile(".depend"); 1213 1214 /* Install all the flags into the MAKEFLAGS envariable. */ 1215 if (((p = Var_Value(".MAKEFLAGS", VAR_GLOBAL)) != NULL) && *p) 1216 setenv("MAKEFLAGS", p, 1); 1217 else 1218 setenv("MAKEFLAGS", "", 1); 1219 1220 /* 1221 * For compatibility, look at the directories in the VPATH variable 1222 * and add them to the search path, if the variable is defined. The 1223 * variable's value is in the same format as the PATH envariable, i.e. 1224 * <directory>:<directory>:<directory>... 1225 */ 1226 if (Var_Exists("VPATH", VAR_CMD)) { 1227 /* 1228 * GCC stores string constants in read-only memory, but 1229 * Var_Subst will want to write this thing, so store it 1230 * in an array 1231 */ 1232 static char VPATH[] = "${VPATH}"; 1233 Buffer *buf; 1234 char *vpath; 1235 char *ptr; 1236 char savec; 1237 1238 buf = Var_Subst(VPATH, VAR_CMD, FALSE); 1239 1240 vpath = Buf_Data(buf); 1241 do { 1242 /* skip to end of directory */ 1243 for (ptr = vpath; *ptr != ':' && *ptr != '\0'; ptr++) 1244 ; 1245 1246 /* Save terminator character so know when to stop */ 1247 savec = *ptr; 1248 *ptr = '\0'; 1249 1250 /* Add directory to search path */ 1251 Path_AddDir(&dirSearchPath, vpath); 1252 1253 vpath = ptr + 1; 1254 } while (savec != '\0'); 1255 1256 Buf_Destroy(buf, TRUE); 1257 } 1258 1259 /* 1260 * Now that all search paths have been read for suffixes et al, it's 1261 * time to add the default search path to their lists... 1262 */ 1263 Suff_DoPaths(); 1264 1265 /* print the initial graph, if the user requested it */ 1266 if (DEBUG(GRAPH1)) 1267 Targ_PrintGraph(1); 1268 1269 /* print the values of any variables requested by the user */ 1270 if (Lst_IsEmpty(&variables) && !printGraphOnly) { 1271 /* 1272 * Since the user has not requested that any variables 1273 * be printed, we can build targets. 1274 * 1275 * Have read the entire graph and need to make a list of targets 1276 * to create. If none was given on the command line, we consult 1277 * the parsing module to find the main target(s) to create. 1278 */ 1279 Lst targs = Lst_Initializer(targs); 1280 1281 if (!is_posix && mfAutoDeps) { 1282 /* 1283 * Check if any of the makefiles are out-of-date. 1284 */ 1285 Remake_Makefiles(); 1286 } 1287 1288 if (Lst_IsEmpty(&create)) 1289 Parse_MainName(&targs); 1290 else 1291 Targ_FindList(&targs, &create, TARG_CREATE); 1292 1293 if (compatMake) { 1294 /* 1295 * Compat_Init will take care of creating 1296 * all the targets as well as initializing 1297 * the module. 1298 */ 1299 Compat_Run(&targs); 1300 outOfDate = 0; 1301 } else { 1302 /* 1303 * Initialize job module before traversing 1304 * the graph, now that any .BEGIN and .END 1305 * targets have been read. This is done 1306 * only if the -q flag wasn't given (to 1307 * prevent the .BEGIN from being executed 1308 * should it exist). 1309 */ 1310 if (!queryFlag) { 1311 Job_Init(jobLimit); 1312 jobsRunning = TRUE; 1313 } 1314 1315 /* Traverse the graph, checking on all the targets */ 1316 outOfDate = Make_Run(&targs); 1317 } 1318 Lst_Destroy(&targs, NOFREE); 1319 1320 } else { 1321 Var_Print(&variables, expandVars); 1322 } 1323 1324 Lst_Destroy(&variables, free); 1325 Lst_Destroy(&makefiles, free); 1326 Lst_Destroy(&source_makefiles, free); 1327 Lst_Destroy(&create, free); 1328 1329 /* print the graph now it's been processed if the user requested it */ 1330 if (DEBUG(GRAPH2)) 1331 Targ_PrintGraph(2); 1332 1333 if (queryFlag) 1334 return (outOfDate); 1335 1336 if (makeErrors != 0) 1337 Finish(makeErrors); 1338 1339 return (0); 1340} 1341