main.c revision 146146
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 146146 2005-05-12 15:04:14Z 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 <stdlib.h> 77141104Sharti#include <string.h> 7863955Simp#include <unistd.h> 79127880Sdes 80141104Sharti#include "arch.h" 81141133Sharti#include "buf.h" 82141104Sharti#include "config.h" 831590Srgrimes#include "dir.h" 84141104Sharti#include "globals.h" 851590Srgrimes#include "job.h" 86141104Sharti#include "make.h" 87141104Sharti#include "parse.h" 881590Srgrimes#include "pathnames.h" 89141104Sharti#include "str.h" 90141104Sharti#include "suff.h" 91141104Sharti#include "targ.h" 92141104Sharti#include "util.h" 93141104Sharti#include "var.h" 941590Srgrimes 95146146Shartiextern char **environ; /* XXX what header declares this variable? */ 96146146Sharti 97104395Sjmallett#define WANT_ENV_MKLVL 1 98138071Sjmallett#define MKLVL_MAXVAL 500 99138071Sjmallett#define MKLVL_ENVVAR "__MKLVL__" 100104395Sjmallett 101138916Sharti/* ordered list of makefiles to read */ 102138916Shartistatic Lst makefiles = Lst_Initializer(makefiles); 103138916Sharti 104138916Sharti/* list of variables to print */ 105138916Shartistatic Lst variables = Lst_Initializer(variables); 106138916Sharti 107146146Shartistatic Boolean expandVars; /* fully expand printed variables */ 108146146Shartistatic Boolean noBuiltins; /* -r flag */ 109144475Shartistatic Boolean forceJobs; /* -j argument given */ 110146146Shartistatic char *curdir; /* startup directory */ 111146146Shartistatic char *objdir; /* where we chdir'ed to */ 112146146Sharti 113146146Sharti/* (-E) vars to override from env */ 114146146ShartiLst envFirstVars = Lst_Initializer(envFirstVars); 115146146Sharti 116146146Sharti/* Targets to be made */ 117146146ShartiLst create = Lst_Initializer(create); 118146146Sharti 119146146ShartiBoolean allPrecious; /* .PRECIOUS given on line by itself */ 120146146ShartiBoolean beSilent; /* -s flag */ 121146146ShartiBoolean beVerbose; /* -v flag */ 122144475ShartiBoolean compatMake; /* -B argument */ 123144475ShartiBoolean debug; /* -d flag */ 124146146ShartiBoolean ignoreErrors; /* -i flag */ 125146146Shartiint jobLimit; /* -j argument */ 126146146ShartiBoolean jobsRunning; /* TRUE if the jobs might be running */ 127146146ShartiBoolean keepgoing; /* -k flag */ 128144475ShartiBoolean noExecute; /* -n flag */ 129144475ShartiBoolean queryFlag; /* -q flag */ 130144475ShartiBoolean touchFlag; /* -t flag */ 131144475ShartiBoolean usePipes; /* !-P flag */ 132146146Shartiuint32_t warn_cmd; /* command line warning flags */ 133146146Shartiuint32_t warn_flags; /* actual warning flags */ 134146146Shartiuint32_t warn_nocmd; /* command line no-warning flags */ 135138916Sharti 136146146Shartitime_t now; /* Time at start of make */ 137146146Shartistruct GNode *DEFAULT; /* .DEFAULT node */ 138138916Sharti 139144475Sharti/** 140146143Sharti * Exit with usage message. 141146143Sharti */ 142146143Shartistatic void 143146143Shartiusage(void) 144146143Sharti{ 145146143Sharti fprintf(stderr, 146146143Sharti "usage: make [-BPSXeiknqrstv] [-C directory] [-D variable]\n" 147146143Sharti "\t[-d flags] [-E variable] [-f makefile] [-I directory]\n" 148146143Sharti "\t[-j max_jobs] [-m directory] [-V variable]\n" 149146143Sharti "\t[variable=value] [target ...]\n"); 150146143Sharti exit(2); 151146143Sharti} 152146143Sharti 153146143Sharti/** 154144475Sharti * MFLAGS_append 155144475Sharti * Append a flag with an optional argument to MAKEFLAGS and MFLAGS 156133085Sharti */ 157133085Shartistatic void 158141252ShartiMFLAGS_append(const char *flag, char *arg) 159133085Sharti{ 160140870Sharti char *str; 161138232Sharti 162146146Sharti Var_Append(".MAKEFLAGS", flag, VAR_GLOBAL); 163140870Sharti if (arg != NULL) { 164140870Sharti str = MAKEFLAGS_quote(arg); 165146146Sharti Var_Append(".MAKEFLAGS", str, VAR_GLOBAL); 166140870Sharti free(str); 167140870Sharti } 168133085Sharti 169133085Sharti Var_Append("MFLAGS", flag, VAR_GLOBAL); 170140870Sharti if (arg != NULL) { 171140870Sharti str = MAKEFLAGS_quote(arg); 172140870Sharti Var_Append("MFLAGS", str, VAR_GLOBAL); 173140870Sharti free(str); 174140870Sharti } 175133085Sharti} 176133085Sharti 177144475Sharti/** 178145679Sharti * Main_ParseWarn 179145679Sharti * 180145679Sharti * Handle argument to warning option. 181145679Sharti */ 182145679Shartiint 183145679ShartiMain_ParseWarn(const char *arg, int iscmd) 184145679Sharti{ 185145679Sharti int i, neg; 186145679Sharti 187145679Sharti static const struct { 188145679Sharti const char *option; 189145679Sharti uint32_t flag; 190145679Sharti } options[] = { 191145679Sharti { "dirsyntax", WARN_DIRSYNTAX }, 192145679Sharti { NULL, 0 } 193145679Sharti }; 194145679Sharti 195145679Sharti neg = 0; 196145679Sharti if (arg[0] == 'n' && arg[1] == 'o') { 197145679Sharti neg = 1; 198145679Sharti arg += 2; 199145679Sharti } 200145679Sharti 201145679Sharti for (i = 0; options[i].option != NULL; i++) 202145679Sharti if (strcmp(arg, options[i].option) == 0) 203145679Sharti break; 204145679Sharti 205145679Sharti if (options[i].option == NULL) 206145679Sharti /* unknown option */ 207145679Sharti return (-1); 208145679Sharti 209145679Sharti if (iscmd) { 210145679Sharti if (!neg) { 211145679Sharti warn_cmd |= options[i].flag; 212145679Sharti warn_nocmd &= ~options[i].flag; 213145679Sharti warn_flags |= options[i].flag; 214145679Sharti } else { 215145679Sharti warn_nocmd |= options[i].flag; 216145679Sharti warn_cmd &= ~options[i].flag; 217145679Sharti warn_flags &= ~options[i].flag; 218145679Sharti } 219145679Sharti } else { 220145679Sharti if (!neg) { 221145679Sharti warn_flags |= (options[i].flag & ~warn_nocmd); 222145679Sharti } else { 223145679Sharti warn_flags &= ~(options[i].flag | warn_cmd); 224145679Sharti } 225145679Sharti } 226145679Sharti return (0); 227145679Sharti} 228145679Sharti 229145679Sharti/** 230146143Sharti * Open and parse the given makefile. 231146143Sharti * 232146143Sharti * Results: 233146143Sharti * TRUE if ok. FALSE if couldn't open file. 234146143Sharti */ 235146143Shartistatic Boolean 236146143ShartiReadMakefile(const char p[]) 237146143Sharti{ 238146143Sharti char *fname; /* makefile to read */ 239146143Sharti FILE *stream; 240146143Sharti char *name, path[MAXPATHLEN]; 241146143Sharti char *MAKEFILE; 242146143Sharti int setMAKEFILE; 243146143Sharti 244146143Sharti /* XXX - remove this once constification is done */ 245146143Sharti fname = estrdup(p); 246146143Sharti 247146143Sharti if (!strcmp(fname, "-")) { 248146143Sharti Parse_File("(stdin)", stdin); 249146145Sharti Var_SetGlobal("MAKEFILE", ""); 250146143Sharti } else { 251146143Sharti setMAKEFILE = strcmp(fname, ".depend"); 252146143Sharti 253146143Sharti /* if we've chdir'd, rebuild the path name */ 254146143Sharti if (curdir != objdir && *fname != '/') { 255146143Sharti snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname); 256146143Sharti /* 257146143Sharti * XXX The realpath stuff breaks relative includes 258146143Sharti * XXX in some cases. The problem likely is in 259146143Sharti * XXX parse.c where it does special things in 260146143Sharti * XXX ParseDoInclude if the file is relateive 261146143Sharti * XXX or absolute and not a system file. There 262146143Sharti * XXX it assumes that if the current file that's 263146143Sharti * XXX being included is absolute, that any files 264146143Sharti * XXX that it includes shouldn't do the -I path 265146143Sharti * XXX stuff, which is inconsistant with historical 266146143Sharti * XXX behavior. However, I can't pentrate the mists 267146143Sharti * XXX further, so I'm putting this workaround in 268146143Sharti * XXX here until such time as the underlying bug 269146143Sharti * XXX can be fixed. 270146143Sharti */ 271146143Sharti#if THIS_BREAKS_THINGS 272146143Sharti if (realpath(path, path) != NULL && 273146143Sharti (stream = fopen(path, "r")) != NULL) { 274146143Sharti MAKEFILE = fname; 275146143Sharti fname = path; 276146143Sharti goto found; 277146143Sharti } 278146143Sharti } else if (realpath(fname, path) != NULL) { 279146143Sharti MAKEFILE = fname; 280146143Sharti fname = path; 281146143Sharti if ((stream = fopen(fname, "r")) != NULL) 282146143Sharti goto found; 283146143Sharti } 284146143Sharti#else 285146143Sharti if ((stream = fopen(path, "r")) != NULL) { 286146143Sharti MAKEFILE = fname; 287146143Sharti fname = path; 288146143Sharti goto found; 289146143Sharti } 290146143Sharti } else { 291146143Sharti MAKEFILE = fname; 292146143Sharti if ((stream = fopen(fname, "r")) != NULL) 293146143Sharti goto found; 294146143Sharti } 295146143Sharti#endif 296146143Sharti /* look in -I and system include directories. */ 297146143Sharti name = Path_FindFile(fname, &parseIncPath); 298146143Sharti if (!name) 299146143Sharti name = Path_FindFile(fname, &sysIncPath); 300146143Sharti if (!name || !(stream = fopen(name, "r"))) 301146143Sharti return (FALSE); 302146143Sharti MAKEFILE = fname = name; 303146143Sharti /* 304146143Sharti * set the MAKEFILE variable desired by System V fans -- the 305146143Sharti * placement of the setting here means it gets set to the last 306146143Sharti * makefile specified, as it is set by SysV make. 307146143Sharti */ 308146143Shartifound: 309146143Sharti if (setMAKEFILE) 310146145Sharti Var_SetGlobal("MAKEFILE", MAKEFILE); 311146143Sharti Parse_File(fname, stream); 312146143Sharti fclose(stream); 313146143Sharti } 314146143Sharti return (TRUE); 315146143Sharti} 316146143Sharti 317146143Sharti/** 318144475Sharti * MainParseArgs 3191590Srgrimes * Parse a given argument vector. Called from main() and from 3201590Srgrimes * Main_ParseArgLine() when the .MAKEFLAGS target is used. 3211590Srgrimes * 3221590Srgrimes * XXX: Deal with command line overriding .MAKEFLAGS in makefile 3231590Srgrimes * 3241590Srgrimes * Side Effects: 3251590Srgrimes * Various global and local flags will be set depending on the flags 3261590Srgrimes * given 3271590Srgrimes */ 3281590Srgrimesstatic void 329104696SjmallettMainParseArgs(int argc, char **argv) 3301590Srgrimes{ 3315814Sjkh int c; 332146038Sharti Boolean found_dd = FALSE; 3331590Srgrimes 334144896Shartirearg: 3351590Srgrimes optind = 1; /* since we're called more than once */ 336144896Sharti optreset = 1; 337145627Sharti#define OPTFLAGS "ABC:D:E:I:PSV:Xd:ef:ij:km:nqrstvx:" 338146038Sharti for (;;) { 339146038Sharti if ((optind < argc) && strcmp(argv[optind], "--") == 0) { 340146038Sharti found_dd = TRUE; 341146038Sharti } 342146038Sharti if ((c = getopt(argc, argv, OPTFLAGS)) == -1) { 343146038Sharti break; 344146038Sharti } 3451590Srgrimes switch(c) { 346144387Sharti 347144387Sharti case 'A': 348144387Sharti arch_fatal = FALSE; 349144387Sharti MFLAGS_append("-A", NULL); 350144387Sharti break; 351102393Sjmallett case 'C': 352107964Sseanc if (chdir(optarg) == -1) 353107964Sseanc err(1, "chdir %s", optarg); 354102393Sjmallett break; 3551590Srgrimes case 'D': 356146145Sharti Var_SetGlobal(optarg, "1"); 357133085Sharti MFLAGS_append("-D", optarg); 3581590Srgrimes break; 3591590Srgrimes case 'I': 3601590Srgrimes Parse_AddIncludeDir(optarg); 361133085Sharti MFLAGS_append("-I", optarg); 3621590Srgrimes break; 36317193Sbde case 'V': 364138920Sru Lst_AtEnd(&variables, estrdup(optarg)); 365133085Sharti MFLAGS_append("-V", optarg); 36617193Sbde break; 36766365Speter case 'X': 36866365Speter expandVars = FALSE; 36966365Speter break; 3701590Srgrimes case 'B': 3711590Srgrimes compatMake = TRUE; 372133085Sharti MFLAGS_append("-B", NULL); 373137626Sphk unsetenv("MAKE_JOBS_FIFO"); 3741590Srgrimes break; 3751590Srgrimes case 'P': 3761590Srgrimes usePipes = FALSE; 377133085Sharti MFLAGS_append("-P", NULL); 3781590Srgrimes break; 3791590Srgrimes case 'S': 3801590Srgrimes keepgoing = FALSE; 381133085Sharti MFLAGS_append("-S", NULL); 3821590Srgrimes break; 3831590Srgrimes case 'd': { 3841590Srgrimes char *modules = optarg; 3851590Srgrimes 3861590Srgrimes for (; *modules; ++modules) 3871590Srgrimes switch (*modules) { 3881590Srgrimes case 'A': 3891590Srgrimes debug = ~0; 3901590Srgrimes break; 3911590Srgrimes case 'a': 3921590Srgrimes debug |= DEBUG_ARCH; 3931590Srgrimes break; 3941590Srgrimes case 'c': 3951590Srgrimes debug |= DEBUG_COND; 3961590Srgrimes break; 3971590Srgrimes case 'd': 3981590Srgrimes debug |= DEBUG_DIR; 3991590Srgrimes break; 4001590Srgrimes case 'f': 4011590Srgrimes debug |= DEBUG_FOR; 4021590Srgrimes break; 4031590Srgrimes case 'g': 4041590Srgrimes if (modules[1] == '1') { 4051590Srgrimes debug |= DEBUG_GRAPH1; 4061590Srgrimes ++modules; 4071590Srgrimes } 4081590Srgrimes else if (modules[1] == '2') { 4091590Srgrimes debug |= DEBUG_GRAPH2; 4101590Srgrimes ++modules; 4111590Srgrimes } 4121590Srgrimes break; 4131590Srgrimes case 'j': 4141590Srgrimes debug |= DEBUG_JOB; 4151590Srgrimes break; 41660569Swill case 'l': 41760569Swill debug |= DEBUG_LOUD; 41860569Swill break; 4191590Srgrimes case 'm': 4201590Srgrimes debug |= DEBUG_MAKE; 4211590Srgrimes break; 4221590Srgrimes case 's': 4231590Srgrimes debug |= DEBUG_SUFF; 4241590Srgrimes break; 4251590Srgrimes case 't': 4261590Srgrimes debug |= DEBUG_TARG; 4271590Srgrimes break; 4281590Srgrimes case 'v': 4291590Srgrimes debug |= DEBUG_VAR; 4301590Srgrimes break; 4311590Srgrimes default: 432144475Sharti warnx("illegal argument to d option " 433144475Sharti "-- %c", *modules); 4341590Srgrimes usage(); 4351590Srgrimes } 436133085Sharti MFLAGS_append("-d", optarg); 4371590Srgrimes break; 4381590Srgrimes } 43949332Shoek case 'E': 440138920Sru Lst_AtEnd(&envFirstVars, estrdup(optarg)); 441133085Sharti MFLAGS_append("-E", optarg); 44249332Shoek break; 4431590Srgrimes case 'e': 4441590Srgrimes checkEnvFirst = TRUE; 445133085Sharti MFLAGS_append("-e", NULL); 4461590Srgrimes break; 4471590Srgrimes case 'f': 448138920Sru Lst_AtEnd(&makefiles, estrdup(optarg)); 4491590Srgrimes break; 4501590Srgrimes case 'i': 4511590Srgrimes ignoreErrors = TRUE; 452133085Sharti MFLAGS_append("-i", NULL); 4531590Srgrimes break; 45449331Shoek case 'j': { 45549331Shoek char *endptr; 45649331Shoek 45718730Ssteve forceJobs = TRUE; 458146140Sharti jobLimit = strtol(optarg, &endptr, 10); 459146140Sharti if (jobLimit <= 0 || *endptr != '\0') { 46049938Shoek warnx("illegal number, -j argument -- %s", 46149938Shoek optarg); 46249938Shoek usage(); 46349331Shoek } 464133085Sharti MFLAGS_append("-j", optarg); 4651590Srgrimes break; 46649331Shoek } 4671590Srgrimes case 'k': 4681590Srgrimes keepgoing = TRUE; 469133085Sharti MFLAGS_append("-k", NULL); 4701590Srgrimes break; 47118730Ssteve case 'm': 472144020Sharti Path_AddDir(&sysIncPath, optarg); 473133085Sharti MFLAGS_append("-m", optarg); 47418730Ssteve break; 4751590Srgrimes case 'n': 4761590Srgrimes noExecute = TRUE; 477133085Sharti MFLAGS_append("-n", NULL); 4781590Srgrimes break; 4791590Srgrimes case 'q': 4801590Srgrimes queryFlag = TRUE; 4811590Srgrimes /* Kind of nonsensical, wot? */ 482133085Sharti MFLAGS_append("-q", NULL); 4831590Srgrimes break; 4841590Srgrimes case 'r': 4851590Srgrimes noBuiltins = TRUE; 486133085Sharti MFLAGS_append("-r", NULL); 4871590Srgrimes break; 4881590Srgrimes case 's': 4891590Srgrimes beSilent = TRUE; 490133085Sharti MFLAGS_append("-s", NULL); 4911590Srgrimes break; 4921590Srgrimes case 't': 4931590Srgrimes touchFlag = TRUE; 494133085Sharti MFLAGS_append("-t", NULL); 4951590Srgrimes break; 49641151Sdg case 'v': 49741151Sdg beVerbose = TRUE; 498133085Sharti MFLAGS_append("-v", NULL); 49941151Sdg break; 500145627Sharti case 'x': 501145679Sharti if (Main_ParseWarn(optarg, 1) != -1) 502145627Sharti MFLAGS_append("-x", optarg); 503145627Sharti break; 504145627Sharti 5051590Srgrimes default: 5061590Srgrimes case '?': 5071590Srgrimes usage(); 5081590Srgrimes } 5091590Srgrimes } 510144896Sharti argv += optind; 511144896Sharti argc -= optind; 5121590Srgrimes 5131590Srgrimes oldVars = TRUE; 5141590Srgrimes 5151590Srgrimes /* 516144896Sharti * Parse the rest of the arguments. 517144896Sharti * o Check for variable assignments and perform them if so. 518144896Sharti * o Check for more flags and restart getopt if so. 519144896Sharti * o Anything else is taken to be a target and added 520144896Sharti * to the end of the "create" list. 5211590Srgrimes */ 522144896Sharti for (; *argv != NULL; ++argv, --argc) { 523133562Sharti if (Parse_IsVar(*argv)) { 524140870Sharti char *ptr = MAKEFLAGS_quote(*argv); 525133562Sharti 526146146Sharti Var_Append(".MAKEFLAGS", ptr, VAR_GLOBAL); 527144896Sharti Parse_DoVar(*argv, VAR_CMD); 528133562Sharti free(ptr); 529133562Sharti 530144896Sharti } else if ((*argv)[0] == '-') { 531144896Sharti if ((*argv)[1] == '\0') { 532144896Sharti /* 533144896Sharti * (*argv) is a single dash, so we 534144896Sharti * just ignore it. 535144896Sharti */ 536146038Sharti } else if (found_dd) { 537146038Sharti /* 538146038Sharti * Double dash has been found, ignore 539146038Sharti * any more options. But what do we do 540146038Sharti * with it? For now treat it like a target. 541146038Sharti */ 542146038Sharti Lst_AtEnd(&create, estrdup(*argv)); 543144896Sharti } else { 544144896Sharti /* 545146038Sharti * (*argv) is a -flag, so backup argv and 546146038Sharti * argc. getopt() expects options to start 547146038Sharti * in the 2nd position. 548144896Sharti */ 549144896Sharti argc++; 550144896Sharti argv--; 5511590Srgrimes goto rearg; 5521590Srgrimes } 553144896Sharti 554144896Sharti } else if ((*argv)[0] == '\0') { 555144896Sharti Punt("illegal (null) argument."); 556144896Sharti 557144896Sharti } else { 558138916Sharti Lst_AtEnd(&create, estrdup(*argv)); 5591590Srgrimes } 560144896Sharti } 5611590Srgrimes} 5621590Srgrimes 563144475Sharti/** 564144475Sharti * Main_ParseArgLine 5651590Srgrimes * Used by the parse module when a .MFLAGS or .MAKEFLAGS target 5661590Srgrimes * is encountered and by main() when reading the .MAKEFLAGS envariable. 5671590Srgrimes * Takes a line of arguments and breaks it into its 5681590Srgrimes * component words and passes those words and the number of them to the 5691590Srgrimes * MainParseArgs function. 5701590Srgrimes * The line should have all its leading whitespace removed. 5711590Srgrimes * 5721590Srgrimes * Side Effects: 5731590Srgrimes * Only those that come from the various arguments. 5741590Srgrimes */ 5751590Srgrimesvoid 576140870ShartiMain_ParseArgLine(char *line, int mflags) 5771590Srgrimes{ 5781590Srgrimes char **argv; /* Manufactured argument vector */ 5791590Srgrimes int argc; /* Number of arguments in argv */ 5801590Srgrimes 5811590Srgrimes if (line == NULL) 5821590Srgrimes return; 5831590Srgrimes for (; *line == ' '; ++line) 5841590Srgrimes continue; 5851590Srgrimes if (!*line) 5861590Srgrimes return; 5871590Srgrimes 588140870Sharti if (mflags) 589140870Sharti argv = MAKEFLAGS_break(line, &argc); 590140870Sharti else 591140870Sharti argv = brk_string(line, &argc, TRUE); 592140870Sharti 5931590Srgrimes MainParseArgs(argc, argv); 5941590Srgrimes} 5951590Srgrimes 596146146Shartistatic char * 597141252Shartichdir_verify_path(const char *path, char *obpath) 59818339Sswallace{ 59918339Sswallace struct stat sb; 60018339Sswallace 60118339Sswallace if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { 60275973Sru if (chdir(path) == -1 || getcwd(obpath, MAXPATHLEN) == NULL) { 60327644Scharnier warn("warning: %s", path); 604141252Sharti return (NULL); 60518339Sswallace } 606138232Sharti return (obpath); 60718339Sswallace } 60818339Sswallace 609141252Sharti return (NULL); 61018339Sswallace} 61118339Sswallace 612146144Sharti/** 613146144Sharti * In lieu of a good way to prevent every possible looping in make(1), stop 614146144Sharti * there from being more than MKLVL_MAXVAL processes forked by make(1), to 615146144Sharti * prevent a forkbomb from happening, in a dumb and mechanical way. 616146144Sharti * 617146144Sharti * Side Effects: 618146144Sharti * Creates or modifies enviornment variable MKLVL_ENVVAR via setenv(). 619138071Sjmallett */ 620138071Sjmallettstatic void 621138071Sjmallettcheck_make_level(void) 622138071Sjmallett{ 623138071Sjmallett#ifdef WANT_ENV_MKLVL 624138071Sjmallett char *value = getenv(MKLVL_ENVVAR); 625138071Sjmallett int level = (value == NULL) ? 0 : atoi(value); 626138071Sjmallett 627138071Sjmallett if (level < 0) { 628144475Sharti errc(2, EAGAIN, "Invalid value for recursion level (%d).", 629144475Sharti level); 630138071Sjmallett } else if (level > MKLVL_MAXVAL) { 631144475Sharti errc(2, EAGAIN, "Max recursion level (%d) exceeded.", 632144475Sharti MKLVL_MAXVAL); 633138071Sjmallett } else { 634138071Sjmallett char new_value[32]; 635138071Sjmallett sprintf(new_value, "%d", level + 1); 636138071Sjmallett setenv(MKLVL_ENVVAR, new_value, 1); 637138071Sjmallett } 638138071Sjmallett#endif /* WANT_ENV_MKLVL */ 639138071Sjmallett} 640138071Sjmallett 641144475Sharti/** 642144475Sharti * main 6431590Srgrimes * The main function, for obvious reasons. Initializes variables 6441590Srgrimes * and a few modules, then parses the arguments give it in the 6451590Srgrimes * environment and on the command line. Reads the system makefile 6461590Srgrimes * followed by either Makefile, makefile or the file given by the 6471590Srgrimes * -f argument. Sets the .MAKEFLAGS PMake variable based on all the 6481590Srgrimes * flags it has received by then uses either the Make or the Compat 6491590Srgrimes * module to create the initial list of targets. 6501590Srgrimes * 6511590Srgrimes * Results: 6521590Srgrimes * If -q was given, exits -1 if anything was out-of-date. Else it exits 6531590Srgrimes * 0. 6541590Srgrimes * 6551590Srgrimes * Side Effects: 6561590Srgrimes * The program exits when done. Targets are created. etc. etc. etc. 6571590Srgrimes */ 6581590Srgrimesint 659104696Sjmallettmain(int argc, char **argv) 6601590Srgrimes{ 661146144Sharti const char *machine; 662146144Sharti const char *machine_arch; 663146144Sharti const char *machine_cpu; 6641590Srgrimes Boolean outOfDate = TRUE; /* FALSE if all targets up to date */ 665141252Sharti char *p, *p1, *pathp; 666141252Sharti char *path; 66773262Simp char mdpath[MAXPATHLEN]; 66873262Simp char obpath[MAXPATHLEN]; 66973262Simp char cdpath[MAXPATHLEN]; 67018730Ssteve char *cp = NULL, *start; 671141252Sharti 672146146Sharti /* 673146146Sharti * Initialize file global variables. 674146146Sharti */ 675146146Sharti expandVars = TRUE; 676146146Sharti noBuiltins = FALSE; /* Read the built-in rules */ 677146146Sharti forceJobs = FALSE; /* No -j flag */ 678146146Sharti curdir = cdpath; 679146146Sharti 680146146Sharti /* 681146146Sharti * Initialize program global variables. 682146146Sharti */ 683146146Sharti beSilent = FALSE; /* Print commands as executed */ 684146146Sharti ignoreErrors = FALSE; /* Pay attention to non-zero returns */ 685146146Sharti noExecute = FALSE; /* Execute all commands */ 686146146Sharti keepgoing = FALSE; /* Stop on error */ 687146146Sharti allPrecious = FALSE; /* Remove targets when interrupted */ 688146146Sharti queryFlag = FALSE; /* This is not just a check-run */ 689146146Sharti touchFlag = FALSE; /* Actually update targets */ 690146146Sharti usePipes = TRUE; /* Catch child output in pipes */ 691146146Sharti debug = 0; /* No debug verbosity, please. */ 692146146Sharti jobsRunning = FALSE; 693146146Sharti 694146146Sharti jobLimit = DEFMAXJOBS; 695146146Sharti compatMake = FALSE; /* No compat mode */ 696146146Sharti 697138071Sjmallett check_make_level(); 698104395Sjmallett 69918730Ssteve#ifdef RLIMIT_NOFILE 7001590Srgrimes /* 70118730Ssteve * get rid of resource limit on file descriptors 70218730Ssteve */ 70318730Ssteve { 70418730Ssteve struct rlimit rl; 705146144Sharti if (getrlimit(RLIMIT_NOFILE, &rl) == -1) { 706146144Sharti err(2, "getrlimit"); 70718730Ssteve } 708146144Sharti rl.rlim_cur = rl.rlim_max; 709146144Sharti if (setrlimit(RLIMIT_NOFILE, &rl) == -1) { 710146144Sharti err(2, "setrlimit"); 711146144Sharti } 71218730Ssteve } 71318730Ssteve#endif 7141590Srgrimes 7155814Sjkh /* 71639006Skato * PC-98 kernel sets the `i386' string to the utsname.machine and 71739006Skato * it cannot be distinguished from IBM-PC by uname(3). Therefore, 71839006Skato * we check machine.ispc98 and adjust the machine variable before 71939006Skato * using usname(3) below. 72053631Smarcel * NOTE: machdep.ispc98 was defined on 1998/8/31. At that time, 72153631Smarcel * __FreeBSD_version was defined as 300003. So, this check can 72253631Smarcel * safely be done with any kernel with version > 300003. 72339006Skato */ 72439006Skato if (!machine) { 72539006Skato int ispc98; 72639006Skato size_t len; 72739006Skato 72839006Skato len = sizeof(ispc98); 72939006Skato if (!sysctlbyname("machdep.ispc98", &ispc98, &len, NULL, 0)) { 73039006Skato if (ispc98) 73139006Skato machine = "pc98"; 73239006Skato } 73339006Skato } 73439006Skato 73539006Skato /* 7365814Sjkh * Get the name of this type of MACHINE from utsname 7375814Sjkh * so we can share an executable for similar machines. 7385814Sjkh * (i.e. m68k: amiga hp300, mac68k, sun3, ...) 7395814Sjkh * 7405814Sjkh * Note that while MACHINE is decided at run-time, 7415814Sjkh * MACHINE_ARCH is always known at compile time. 7425814Sjkh */ 743146144Sharti if ((machine = getenv("MACHINE")) == NULL) { 744146144Sharti#ifdef MACHINE 745146144Sharti machine = MACHINE; 746146144Sharti#else 747144475Sharti static struct utsname utsname; 74818730Ssteve 749144475Sharti if (uname(&utsname) == -1) 750144475Sharti err(2, "uname"); 751144475Sharti machine = utsname.machine; 75218339Sswallace#endif 7535814Sjkh } 7541590Srgrimes 755146144Sharti if ((machine_arch = getenv("MACHINE_ARCH")) == NULL) { 756146144Sharti#ifdef MACHINE_ARCH 757146144Sharti machine_arch = MACHINE_ARCH; 758146144Sharti#else 75944362Simp machine_arch = "unknown"; 76044362Simp#endif 76144362Simp } 76244362Simp 7631590Srgrimes /* 76472679Skris * Set machine_cpu to the minumum supported CPU revision based 76572679Skris * on the target architecture, if not already set. 76672679Skris */ 767146144Sharti if ((machine_cpu = getenv("MACHINE_CPU")) == NULL) { 76872679Skris if (!strcmp(machine_arch, "i386")) 76972679Skris machine_cpu = "i386"; 77072679Skris else if (!strcmp(machine_arch, "alpha")) 77172679Skris machine_cpu = "ev4"; 77272679Skris else 77372679Skris machine_cpu = "unknown"; 77472679Skris } 7751590Srgrimes 7761590Srgrimes /* 7771590Srgrimes * Initialize the parsing, directory and variable modules to prepare 7781590Srgrimes * for the reading of inclusion paths and variable settings on the 7791590Srgrimes * command line 7801590Srgrimes */ 781146144Sharti Proc_Init(); 782146144Sharti 7831590Srgrimes Dir_Init(); /* Initialize directory structures so -I flags 7841590Srgrimes * can be processed correctly */ 785145971Sharti Var_Init(environ); /* As well as the lists of variables for 7861590Srgrimes * parsing arguments */ 7875814Sjkh str_init(); 7881590Srgrimes 7891590Srgrimes /* 7901590Srgrimes * Initialize various variables. 7911590Srgrimes * MAKE also gets this name, for compatibility 7921590Srgrimes * .MAKEFLAGS gets set to the empty string just in case. 7931590Srgrimes * MFLAGS also gets initialized empty, for compatibility. 7941590Srgrimes */ 795146145Sharti Var_SetGlobal("MAKE", argv[0]); 796146146Sharti Var_SetGlobal(".MAKEFLAGS", ""); 797146145Sharti Var_SetGlobal("MFLAGS", ""); 798146145Sharti Var_SetGlobal("MACHINE", machine); 799146145Sharti Var_SetGlobal("MACHINE_ARCH", machine_arch); 800146145Sharti Var_SetGlobal("MACHINE_CPU", machine_cpu); 80197121Sru#ifdef MAKE_VERSION 802146145Sharti Var_SetGlobal("MAKE_VERSION", MAKE_VERSION); 80397121Sru#endif 8041590Srgrimes 8051590Srgrimes /* 806144896Sharti * First snag things out of the MAKEFLAGS environment 807144896Sharti * variable. Then parse the command line arguments. 8081590Srgrimes */ 809140870Sharti Main_ParseArgLine(getenv("MAKEFLAGS"), 1); 8108874Srgrimes 8111590Srgrimes MainParseArgs(argc, argv); 8121590Srgrimes 8131590Srgrimes /* 814120053Sru * Find where we are... 815120053Sru */ 816120053Sru if (getcwd(curdir, MAXPATHLEN) == NULL) 817120053Sru err(2, NULL); 818120053Sru 819141252Sharti { 820141252Sharti struct stat sa; 821141252Sharti 822120053Sru if (stat(curdir, &sa) == -1) 823120053Sru err(2, "%s", curdir); 824141252Sharti } 825120053Sru 826120053Sru /* 827120053Sru * The object directory location is determined using the 828120053Sru * following order of preference: 829120053Sru * 830120053Sru * 1. MAKEOBJDIRPREFIX`cwd` 831120053Sru * 2. MAKEOBJDIR 832143412Sharti * 3. PATH_OBJDIR.${MACHINE} 833143412Sharti * 4. PATH_OBJDIR 834143412Sharti * 5. PATH_OBJDIRPREFIX`cwd` 835120053Sru * 836120053Sru * If one of the first two fails, use the current directory. 837120053Sru * If the remaining three all fail, use the current directory. 838120053Sru * 839120053Sru * Once things are initted, 840120053Sru * have to add the original directory to the search path, 841120053Sru * and modify the paths for the Makefiles apropriately. The 842120053Sru * current directory is also placed as a variable for make scripts. 843120053Sru */ 844120053Sru if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) { 845120053Sru if (!(path = getenv("MAKEOBJDIR"))) { 846143412Sharti path = PATH_OBJDIR; 847143412Sharti pathp = PATH_OBJDIRPREFIX; 848146145Sharti snprintf(mdpath, MAXPATHLEN, "%s.%s", path, machine); 849120053Sru if (!(objdir = chdir_verify_path(mdpath, obpath))) 850120053Sru if (!(objdir=chdir_verify_path(path, obpath))) { 851138232Sharti snprintf(mdpath, MAXPATHLEN, 852120053Sru "%s%s", pathp, curdir); 853120053Sru if (!(objdir=chdir_verify_path(mdpath, 854120053Sru obpath))) 855120053Sru objdir = curdir; 856120053Sru } 857120053Sru } 858120053Sru else if (!(objdir = chdir_verify_path(path, obpath))) 859120053Sru objdir = curdir; 860120053Sru } 861120053Sru else { 862138232Sharti snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir); 863120053Sru if (!(objdir = chdir_verify_path(mdpath, obpath))) 864120053Sru objdir = curdir; 865120053Sru } 866120053Sru Dir_InitDot(); /* Initialize the "." directory */ 867120053Sru if (objdir != curdir) 868144020Sharti Path_AddDir(&dirSearchPath, curdir); 869146145Sharti Var_SetGlobal(".ST_EXPORTVAR", "YES"); 870146145Sharti Var_SetGlobal(".CURDIR", curdir); 871146145Sharti Var_SetGlobal(".OBJDIR", objdir); 872120053Sru 873137606Sphk if (getenv("MAKE_JOBS_FIFO") != NULL) 874137606Sphk forceJobs = TRUE; 875120053Sru /* 87628228Sfsmp * Be compatible if user did not specify -j and did not explicitly 87728228Sfsmp * turned compatibility on 87828228Sfsmp */ 87928228Sfsmp if (!compatMake && !forceJobs) 88028228Sfsmp compatMake = TRUE; 88128228Sfsmp 88228228Sfsmp /* 883144387Sharti * Initialize target and suffix modules in preparation for 8841590Srgrimes * parsing the makefile(s) 8851590Srgrimes */ 8861590Srgrimes Targ_Init(); 8871590Srgrimes Suff_Init(); 8881590Srgrimes 88969527Swill DEFAULT = NULL; 890138232Sharti time(&now); 8911590Srgrimes 8921590Srgrimes /* 8931590Srgrimes * Set up the .TARGETS variable to contain the list of targets to be 8941590Srgrimes * created. If none specified, make the variable empty -- the parser 8951590Srgrimes * will fill the thing in with the default or .MAIN target. 8961590Srgrimes */ 897146145Sharti if (Lst_IsEmpty(&create)) { 898146145Sharti Var_SetGlobal(".TARGETS", ""); 899146145Sharti } else { 900138512Sharti LstNode *ln; 9011590Srgrimes 902138916Sharti for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) { 903138264Sharti char *name = Lst_Datum(ln); 9041590Srgrimes 9051590Srgrimes Var_Append(".TARGETS", name, VAR_GLOBAL); 9061590Srgrimes } 907146145Sharti } 9081590Srgrimes 90918730Ssteve 9101590Srgrimes /* 91118730Ssteve * If no user-supplied system path was given (through the -m option) 91218730Ssteve * add the directories from the DEFSYSPATH (more than one may be given 91318730Ssteve * as dir1:...:dirn) to the system include path. 9141590Srgrimes */ 915144020Sharti if (TAILQ_EMPTY(&sysIncPath)) { 916146144Sharti char syspath[] = PATH_DEFSYSPATH; 917146144Sharti 91818730Ssteve for (start = syspath; *start != '\0'; start = cp) { 91918730Ssteve for (cp = start; *cp != '\0' && *cp != ':'; cp++) 92018730Ssteve continue; 92118730Ssteve if (*cp == '\0') { 922144020Sharti Path_AddDir(&sysIncPath, start); 92318730Ssteve } else { 92418730Ssteve *cp++ = '\0'; 925144020Sharti Path_AddDir(&sysIncPath, start); 92618730Ssteve } 92718730Ssteve } 92818730Ssteve } 9291590Srgrimes 93018730Ssteve /* 93118730Ssteve * Read in the built-in rules first, followed by the specified 93218730Ssteve * makefile, if it was (makefile != (char *) NULL), or the default 93318730Ssteve * Makefile and makefile, in that order, if it wasn't. 93418730Ssteve */ 93518730Ssteve if (!noBuiltins) { 936138916Sharti /* Path of sys.mk */ 937138916Sharti Lst sysMkPath = Lst_Initializer(sysMkPath); 938138512Sharti LstNode *ln; 939146064Sharti char defsysmk[] = PATH_DEFSYSMK; 94018730Ssteve 941146064Sharti Path_Expand(defsysmk, &sysIncPath, &sysMkPath); 942138916Sharti if (Lst_IsEmpty(&sysMkPath)) 943143412Sharti Fatal("make: no system rules (%s).", PATH_DEFSYSMK); 944143808Sharti LST_FOREACH(ln, &sysMkPath) { 945143808Sharti if (!ReadMakefile(Lst_Datum(ln))) 946143808Sharti break; 947143808Sharti } 94869527Swill if (ln != NULL) 94918730Ssteve Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 950138916Sharti Lst_Destroy(&sysMkPath, free); 95118730Ssteve } 95218730Ssteve 953138916Sharti if (!Lst_IsEmpty(&makefiles)) { 954138512Sharti LstNode *ln; 9551590Srgrimes 956143808Sharti LST_FOREACH(ln, &makefiles) { 957143808Sharti if (!ReadMakefile(Lst_Datum(ln))) 958143808Sharti break; 959143808Sharti } 96069527Swill if (ln != NULL) 9611590Srgrimes Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 962143808Sharti } else if (!ReadMakefile("BSDmakefile")) 963143808Sharti if (!ReadMakefile("makefile")) 964143808Sharti ReadMakefile("Makefile"); 9651590Srgrimes 966143808Sharti ReadMakefile(".depend"); 9671590Srgrimes 9681590Srgrimes /* Install all the flags into the MAKE envariable. */ 969146146Sharti if (((p = Var_Value(".MAKEFLAGS", VAR_GLOBAL, &p1)) != NULL) && *p) 9701590Srgrimes setenv("MAKEFLAGS", p, 1); 971105826Sjmallett free(p1); 9721590Srgrimes 9731590Srgrimes /* 9741590Srgrimes * For compatibility, look at the directories in the VPATH variable 9751590Srgrimes * and add them to the search path, if the variable is defined. The 9761590Srgrimes * variable's value is in the same format as the PATH envariable, i.e. 9771590Srgrimes * <directory>:<directory>:<directory>... 9781590Srgrimes */ 9791590Srgrimes if (Var_Exists("VPATH", VAR_CMD)) { 9801590Srgrimes /* 9811590Srgrimes * GCC stores string constants in read-only memory, but 9821590Srgrimes * Var_Subst will want to write this thing, so store it 9831590Srgrimes * in an array 9841590Srgrimes */ 9851590Srgrimes static char VPATH[] = "${VPATH}"; 986142457Sharti Buffer *buf; 987142457Sharti char *vpath; 988142457Sharti char *ptr; 989142457Sharti char savec; 9901590Srgrimes 991146027Sharti buf = Var_Subst(VPATH, VAR_CMD, FALSE); 992142457Sharti 993143959Sharti vpath = Buf_Data(buf); 9941590Srgrimes do { 9951590Srgrimes /* skip to end of directory */ 996142457Sharti for (ptr = vpath; *ptr != ':' && *ptr != '\0'; ptr++) 997141969Sharti ; 998141969Sharti 9991590Srgrimes /* Save terminator character so know when to stop */ 1000141969Sharti savec = *ptr; 1001141969Sharti *ptr = '\0'; 1002141969Sharti 10031590Srgrimes /* Add directory to search path */ 1004144020Sharti Path_AddDir(&dirSearchPath, vpath); 1005141969Sharti 1006142457Sharti vpath = ptr + 1; 1007141969Sharti } while (savec != '\0'); 1008142457Sharti 1009142457Sharti Buf_Destroy(buf, TRUE); 10101590Srgrimes } 10111590Srgrimes 10121590Srgrimes /* 10131590Srgrimes * Now that all search paths have been read for suffixes et al, it's 10141590Srgrimes * time to add the default search path to their lists... 10151590Srgrimes */ 10161590Srgrimes Suff_DoPaths(); 10171590Srgrimes 10181590Srgrimes /* print the initial graph, if the user requested it */ 10191590Srgrimes if (DEBUG(GRAPH1)) 10201590Srgrimes Targ_PrintGraph(1); 10211590Srgrimes 102217193Sbde /* print the values of any variables requested by the user */ 1023141974Sharti if (Lst_IsEmpty(&variables)) { 10241590Srgrimes /* 1025141974Sharti * Since the user has not requested that any variables 1026142008Sharti * be printed, we can build targets. 1027141974Sharti * 1028142008Sharti * Have read the entire graph and need to make a list of targets 1029141974Sharti * to create. If none was given on the command line, we consult 1030141974Sharti * the parsing module to find the main target(s) to create. 10311590Srgrimes */ 1032138916Sharti Lst targs = Lst_Initializer(targs); 1033138916Sharti 1034138916Sharti if (Lst_IsEmpty(&create)) 1035138916Sharti Parse_MainName(&targs); 1036101460Sru else 1037138916Sharti Targ_FindList(&targs, &create, TARG_CREATE); 1038101460Sru 1039141974Sharti if (compatMake) { 1040101460Sru /* 1041141974Sharti * Compat_Init will take care of creating 1042141974Sharti * all the targets as well as initializing 1043141974Sharti * the module. 1044101460Sru */ 1045141974Sharti Compat_Run(&targs); 1046141974Sharti outOfDate = 0; 1047141974Sharti } else { 1048141974Sharti /* 1049141974Sharti * Initialize job module before traversing 1050141974Sharti * the graph, now that any .BEGIN and .END 1051141974Sharti * targets have been read. This is done 1052141974Sharti * only if the -q flag wasn't given (to 1053141974Sharti * prevent the .BEGIN from being executed 1054141974Sharti * should it exist). 1055141974Sharti */ 1056101460Sru if (!queryFlag) { 1057146140Sharti Job_Init(jobLimit); 1058101460Sru jobsRunning = TRUE; 1059101460Sru } 1060101460Sru 1061101460Sru /* Traverse the graph, checking on all the targets */ 1062138916Sharti outOfDate = Make_Run(&targs); 10631590Srgrimes } 1064138916Sharti Lst_Destroy(&targs, NOFREE); 1065141974Sharti 1066141974Sharti } else { 1067146141Sharti Var_Print(&variables, expandVars); 106817193Sbde } 10698874Srgrimes 1070138920Sru Lst_Destroy(&variables, free); 1071138920Sru Lst_Destroy(&makefiles, free); 1072138916Sharti Lst_Destroy(&create, free); 10735814Sjkh 10741590Srgrimes /* print the graph now it's been processed if the user requested it */ 10751590Srgrimes if (DEBUG(GRAPH2)) 10761590Srgrimes Targ_PrintGraph(2); 10771590Srgrimes 10781590Srgrimes if (queryFlag && outOfDate) 1079138232Sharti return (1); 10801590Srgrimes else 1081138232Sharti return (0); 10821590Srgrimes} 10831590Srgrimes 1084