main.c revision 201526
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 201526 2010-01-04 18:57:22Z obrien $"); 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 641590Srgrimes#include <sys/param.h> 651590Srgrimes#include <sys/stat.h> 6639006Skato#include <sys/sysctl.h> 67127880Sdes#include <sys/time.h> 68144020Sharti#include <sys/queue.h> 69127899Sru#include <sys/resource.h> 70153115Sru#include <sys/utsname.h> 7118730Ssteve#include <sys/wait.h> 7227644Scharnier#include <err.h> 731590Srgrimes#include <errno.h> 74127880Sdes#include <stdlib.h> 75141104Sharti#include <string.h> 7663955Simp#include <unistd.h> 77127880Sdes 78141104Sharti#include "arch.h" 79141133Sharti#include "buf.h" 80141104Sharti#include "config.h" 811590Srgrimes#include "dir.h" 82141104Sharti#include "globals.h" 83167330Sfjoe#include "GNode.h" 841590Srgrimes#include "job.h" 85141104Sharti#include "make.h" 86141104Sharti#include "parse.h" 871590Srgrimes#include "pathnames.h" 88146572Sharti#include "shell.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 97160442Sobrien#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 104167330Sfjoe/* ordered list of source makefiles */ 105167330Sfjoestatic Lst source_makefiles = Lst_Initializer(source_makefiles); 106167330Sfjoe 107138916Sharti/* list of variables to print */ 108138916Shartistatic Lst variables = Lst_Initializer(variables); 109138916Sharti 110146146Shartistatic Boolean expandVars; /* fully expand printed variables */ 111146146Shartistatic Boolean noBuiltins; /* -r flag */ 112160442Sobrienstatic Boolean forceJobs; /* -j argument given */ 113146146Shartistatic char *curdir; /* startup directory */ 114146146Shartistatic char *objdir; /* where we chdir'ed to */ 115167330Sfjoestatic char **save_argv; /* saved argv */ 116167330Sfjoestatic char *save_makeflags;/* saved MAKEFLAGS */ 117146146Sharti 118146146Sharti/* (-E) vars to override from env */ 119146146ShartiLst envFirstVars = Lst_Initializer(envFirstVars); 120146146Sharti 121146146Sharti/* Targets to be made */ 122146146ShartiLst create = Lst_Initializer(create); 123146146Sharti 124146146ShartiBoolean allPrecious; /* .PRECIOUS given on line by itself */ 125167330SfjoeBoolean is_posix; /* .POSIX target seen */ 126177101SobrienBoolean mfAutoDeps; /* .MAKEFILEDEPS target seen */ 127190821SfjoeBoolean remakingMakefiles; /* True if remaking makefiles is in progress */ 128146146ShartiBoolean beSilent; /* -s flag */ 129146146ShartiBoolean beVerbose; /* -v flag */ 130187132SobrienBoolean beQuiet; /* -Q flag */ 131144475ShartiBoolean compatMake; /* -B argument */ 132149844Shartiint debug; /* -d flag */ 133146146ShartiBoolean ignoreErrors; /* -i flag */ 134146146Shartiint jobLimit; /* -j argument */ 135186279Sfjoeint makeErrors; /* Number of targets not remade due to errors */ 136146146ShartiBoolean jobsRunning; /* TRUE if the jobs might be running */ 137146146ShartiBoolean keepgoing; /* -k flag */ 138144475ShartiBoolean noExecute; /* -n flag */ 139181021SedBoolean printGraphOnly; /* -p flag */ 140144475ShartiBoolean queryFlag; /* -q flag */ 141144475ShartiBoolean touchFlag; /* -t flag */ 142144475ShartiBoolean usePipes; /* !-P flag */ 143146146Shartiuint32_t warn_cmd; /* command line warning flags */ 144146146Shartiuint32_t warn_flags; /* actual warning flags */ 145146146Shartiuint32_t warn_nocmd; /* command line no-warning flags */ 146138916Sharti 147146146Shartitime_t now; /* Time at start of make */ 148146146Shartistruct GNode *DEFAULT; /* .DEFAULT node */ 149138916Sharti 150144475Sharti/** 151146143Sharti * Exit with usage message. 152146143Sharti */ 153146143Shartistatic void 154146143Shartiusage(void) 155146143Sharti{ 156146143Sharti fprintf(stderr, 157181021Sed "usage: make [-BPSXeiknpqrstv] [-C directory] [-D variable]\n" 158146143Sharti "\t[-d flags] [-E variable] [-f makefile] [-I directory]\n" 159146143Sharti "\t[-j max_jobs] [-m directory] [-V variable]\n" 160146143Sharti "\t[variable=value] [target ...]\n"); 161146143Sharti exit(2); 162146143Sharti} 163146143Sharti 164146143Sharti/** 165144475Sharti * MFLAGS_append 166144475Sharti * Append a flag with an optional argument to MAKEFLAGS and MFLAGS 167133085Sharti */ 168133085Shartistatic void 169141252ShartiMFLAGS_append(const char *flag, char *arg) 170133085Sharti{ 171140870Sharti char *str; 172138232Sharti 173146146Sharti Var_Append(".MAKEFLAGS", flag, VAR_GLOBAL); 174140870Sharti if (arg != NULL) { 175140870Sharti str = MAKEFLAGS_quote(arg); 176146146Sharti Var_Append(".MAKEFLAGS", str, VAR_GLOBAL); 177140870Sharti free(str); 178140870Sharti } 179133085Sharti 180133085Sharti Var_Append("MFLAGS", flag, VAR_GLOBAL); 181140870Sharti if (arg != NULL) { 182140870Sharti str = MAKEFLAGS_quote(arg); 183140870Sharti Var_Append("MFLAGS", str, VAR_GLOBAL); 184140870Sharti free(str); 185140870Sharti } 186133085Sharti} 187133085Sharti 188144475Sharti/** 189145679Sharti * Main_ParseWarn 190145679Sharti * 191145679Sharti * Handle argument to warning option. 192145679Sharti */ 193145679Shartiint 194145679ShartiMain_ParseWarn(const char *arg, int iscmd) 195145679Sharti{ 196145679Sharti int i, neg; 197145679Sharti 198145679Sharti static const struct { 199145679Sharti const char *option; 200145679Sharti uint32_t flag; 201145679Sharti } options[] = { 202145679Sharti { "dirsyntax", WARN_DIRSYNTAX }, 203145679Sharti { NULL, 0 } 204145679Sharti }; 205145679Sharti 206145679Sharti neg = 0; 207145679Sharti if (arg[0] == 'n' && arg[1] == 'o') { 208145679Sharti neg = 1; 209145679Sharti arg += 2; 210145679Sharti } 211145679Sharti 212145679Sharti for (i = 0; options[i].option != NULL; i++) 213145679Sharti if (strcmp(arg, options[i].option) == 0) 214145679Sharti break; 215145679Sharti 216145679Sharti if (options[i].option == NULL) 217145679Sharti /* unknown option */ 218145679Sharti return (-1); 219145679Sharti 220145679Sharti if (iscmd) { 221145679Sharti if (!neg) { 222145679Sharti warn_cmd |= options[i].flag; 223145679Sharti warn_nocmd &= ~options[i].flag; 224145679Sharti warn_flags |= options[i].flag; 225145679Sharti } else { 226145679Sharti warn_nocmd |= options[i].flag; 227145679Sharti warn_cmd &= ~options[i].flag; 228145679Sharti warn_flags &= ~options[i].flag; 229145679Sharti } 230145679Sharti } else { 231145679Sharti if (!neg) { 232145679Sharti warn_flags |= (options[i].flag & ~warn_nocmd); 233145679Sharti } else { 234145679Sharti warn_flags &= ~(options[i].flag | warn_cmd); 235145679Sharti } 236145679Sharti } 237145679Sharti return (0); 238145679Sharti} 239145679Sharti 240145679Sharti/** 241146143Sharti * Open and parse the given makefile. 242146143Sharti * 243146143Sharti * Results: 244146143Sharti * TRUE if ok. FALSE if couldn't open file. 245146143Sharti */ 246146143Shartistatic Boolean 247146143ShartiReadMakefile(const char p[]) 248146143Sharti{ 249152982Sdavidxu char *fname, *fnamesave; /* makefile to read */ 250146143Sharti FILE *stream; 251146143Sharti char *name, path[MAXPATHLEN]; 252146143Sharti char *MAKEFILE; 253146143Sharti int setMAKEFILE; 254146143Sharti 255146143Sharti /* XXX - remove this once constification is done */ 256152982Sdavidxu fnamesave = fname = estrdup(p); 257146143Sharti 258146143Sharti if (!strcmp(fname, "-")) { 259146143Sharti Parse_File("(stdin)", stdin); 260146145Sharti Var_SetGlobal("MAKEFILE", ""); 261146143Sharti } else { 262146143Sharti setMAKEFILE = strcmp(fname, ".depend"); 263146143Sharti 264146143Sharti /* if we've chdir'd, rebuild the path name */ 265146143Sharti if (curdir != objdir && *fname != '/') { 266146143Sharti snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname); 267146143Sharti /* 268146143Sharti * XXX The realpath stuff breaks relative includes 269146143Sharti * XXX in some cases. The problem likely is in 270146143Sharti * XXX parse.c where it does special things in 271146143Sharti * XXX ParseDoInclude if the file is relateive 272146143Sharti * XXX or absolute and not a system file. There 273146143Sharti * XXX it assumes that if the current file that's 274146143Sharti * XXX being included is absolute, that any files 275146143Sharti * XXX that it includes shouldn't do the -I path 276146143Sharti * XXX stuff, which is inconsistant with historical 277146143Sharti * XXX behavior. However, I can't pentrate the mists 278146143Sharti * XXX further, so I'm putting this workaround in 279146143Sharti * XXX here until such time as the underlying bug 280146143Sharti * XXX can be fixed. 281146143Sharti */ 282146143Sharti#if THIS_BREAKS_THINGS 283146143Sharti if (realpath(path, path) != NULL && 284146143Sharti (stream = fopen(path, "r")) != NULL) { 285146143Sharti MAKEFILE = fname; 286146143Sharti fname = path; 287146143Sharti goto found; 288146143Sharti } 289146143Sharti } else if (realpath(fname, path) != NULL) { 290146143Sharti MAKEFILE = fname; 291146143Sharti fname = path; 292146143Sharti if ((stream = fopen(fname, "r")) != NULL) 293146143Sharti goto found; 294146143Sharti } 295146143Sharti#else 296146143Sharti if ((stream = fopen(path, "r")) != NULL) { 297146143Sharti MAKEFILE = fname; 298146143Sharti fname = path; 299146143Sharti goto found; 300146143Sharti } 301146143Sharti } else { 302146143Sharti MAKEFILE = fname; 303146143Sharti if ((stream = fopen(fname, "r")) != NULL) 304146143Sharti goto found; 305146143Sharti } 306146143Sharti#endif 307146143Sharti /* look in -I and system include directories. */ 308146143Sharti name = Path_FindFile(fname, &parseIncPath); 309146143Sharti if (!name) 310146143Sharti name = Path_FindFile(fname, &sysIncPath); 311152969Sfjoe if (!name || !(stream = fopen(name, "r"))) { 312152982Sdavidxu free(fnamesave); 313146143Sharti return (FALSE); 314152969Sfjoe } 315146143Sharti MAKEFILE = fname = name; 316146143Sharti /* 317146143Sharti * set the MAKEFILE variable desired by System V fans -- the 318146143Sharti * placement of the setting here means it gets set to the last 319146143Sharti * makefile specified, as it is set by SysV make. 320146143Sharti */ 321146143Shartifound: 322146143Sharti if (setMAKEFILE) 323146145Sharti Var_SetGlobal("MAKEFILE", MAKEFILE); 324146143Sharti Parse_File(fname, stream); 325146143Sharti } 326152982Sdavidxu free(fnamesave); 327146143Sharti return (TRUE); 328146143Sharti} 329146143Sharti 330146143Sharti/** 331167330Sfjoe * Open and parse the given makefile. 332167330Sfjoe * If open is successful add it to the list of makefiles. 333167330Sfjoe * 334167330Sfjoe * Results: 335167330Sfjoe * TRUE if ok. FALSE if couldn't open file. 336167330Sfjoe */ 337167330Sfjoestatic Boolean 338167330SfjoeTryReadMakefile(const char p[]) 339167330Sfjoe{ 340167330Sfjoe char *data; 341167330Sfjoe LstNode *last = Lst_Last(&source_makefiles); 342167330Sfjoe 343167330Sfjoe if (!ReadMakefile(p)) 344167330Sfjoe return (FALSE); 345167330Sfjoe 346167330Sfjoe data = estrdup(p); 347167330Sfjoe if (last == NULL) { 348167330Sfjoe LstNode *first = Lst_First(&source_makefiles); 349167330Sfjoe Lst_Insert(&source_makefiles, first, data); 350167330Sfjoe } else 351167330Sfjoe Lst_Append(&source_makefiles, last, estrdup(p)); 352167330Sfjoe return (TRUE); 353167330Sfjoe} 354167330Sfjoe 355167330Sfjoe/** 356144475Sharti * MainParseArgs 3571590Srgrimes * Parse a given argument vector. Called from main() and from 3581590Srgrimes * Main_ParseArgLine() when the .MAKEFLAGS target is used. 3591590Srgrimes * 3601590Srgrimes * XXX: Deal with command line overriding .MAKEFLAGS in makefile 3611590Srgrimes * 3621590Srgrimes * Side Effects: 3631590Srgrimes * Various global and local flags will be set depending on the flags 3641590Srgrimes * given 3651590Srgrimes */ 3661590Srgrimesstatic void 367104696SjmallettMainParseArgs(int argc, char **argv) 3681590Srgrimes{ 3695814Sjkh int c; 370146038Sharti Boolean found_dd = FALSE; 371201526Sobrien char found_dir[MAXPATHLEN + 1]; /* for searching for sys.mk */ 3721590Srgrimes 373144896Shartirearg: 3741590Srgrimes optind = 1; /* since we're called more than once */ 375144896Sharti optreset = 1; 376187995Simp#define OPTFLAGS "ABC:D:d:E:ef:I:ij:km:nPpQqrSstV:vXx:" 377146038Sharti for (;;) { 378146038Sharti if ((optind < argc) && strcmp(argv[optind], "--") == 0) { 379146038Sharti found_dd = TRUE; 380146038Sharti } 381146038Sharti if ((c = getopt(argc, argv, OPTFLAGS)) == -1) { 382146038Sharti break; 383146038Sharti } 3841590Srgrimes switch(c) { 385144387Sharti 386144387Sharti case 'A': 387144387Sharti arch_fatal = FALSE; 388144387Sharti MFLAGS_append("-A", NULL); 389144387Sharti break; 390187995Simp case 'B': 391187995Simp compatMake = TRUE; 392187995Simp MFLAGS_append("-B", NULL); 393187995Simp unsetenv("MAKE_JOBS_FIFO"); 394187995Simp break; 395102393Sjmallett case 'C': 396107964Sseanc if (chdir(optarg) == -1) 397107964Sseanc err(1, "chdir %s", optarg); 398201526Sobrien if (getcwd(curdir, MAXPATHLEN) == NULL) 399201526Sobrien err(2, NULL); 400102393Sjmallett break; 4011590Srgrimes case 'D': 402146145Sharti Var_SetGlobal(optarg, "1"); 403133085Sharti MFLAGS_append("-D", optarg); 4041590Srgrimes break; 4051590Srgrimes case 'd': { 4061590Srgrimes char *modules = optarg; 4071590Srgrimes 4081590Srgrimes for (; *modules; ++modules) 4091590Srgrimes switch (*modules) { 4101590Srgrimes case 'A': 4111590Srgrimes debug = ~0; 4121590Srgrimes break; 4131590Srgrimes case 'a': 4141590Srgrimes debug |= DEBUG_ARCH; 4151590Srgrimes break; 4161590Srgrimes case 'c': 4171590Srgrimes debug |= DEBUG_COND; 4181590Srgrimes break; 4191590Srgrimes case 'd': 4201590Srgrimes debug |= DEBUG_DIR; 4211590Srgrimes break; 4221590Srgrimes case 'f': 4231590Srgrimes debug |= DEBUG_FOR; 4241590Srgrimes break; 4251590Srgrimes case 'g': 4261590Srgrimes if (modules[1] == '1') { 4271590Srgrimes debug |= DEBUG_GRAPH1; 4281590Srgrimes ++modules; 4291590Srgrimes } 4301590Srgrimes else if (modules[1] == '2') { 4311590Srgrimes debug |= DEBUG_GRAPH2; 4321590Srgrimes ++modules; 4331590Srgrimes } 4341590Srgrimes break; 4351590Srgrimes case 'j': 4361590Srgrimes debug |= DEBUG_JOB; 4371590Srgrimes break; 43860569Swill case 'l': 43960569Swill debug |= DEBUG_LOUD; 44060569Swill break; 4411590Srgrimes case 'm': 4421590Srgrimes debug |= DEBUG_MAKE; 4431590Srgrimes break; 4441590Srgrimes case 's': 4451590Srgrimes debug |= DEBUG_SUFF; 4461590Srgrimes break; 4471590Srgrimes case 't': 4481590Srgrimes debug |= DEBUG_TARG; 4491590Srgrimes break; 4501590Srgrimes case 'v': 4511590Srgrimes debug |= DEBUG_VAR; 4521590Srgrimes break; 4531590Srgrimes default: 454144475Sharti warnx("illegal argument to d option " 455144475Sharti "-- %c", *modules); 4561590Srgrimes usage(); 4571590Srgrimes } 458133085Sharti MFLAGS_append("-d", optarg); 4591590Srgrimes break; 4601590Srgrimes } 46149332Shoek case 'E': 462138920Sru Lst_AtEnd(&envFirstVars, estrdup(optarg)); 463133085Sharti MFLAGS_append("-E", optarg); 46449332Shoek break; 4651590Srgrimes case 'e': 4661590Srgrimes checkEnvFirst = TRUE; 467133085Sharti MFLAGS_append("-e", NULL); 4681590Srgrimes break; 4691590Srgrimes case 'f': 470138920Sru Lst_AtEnd(&makefiles, estrdup(optarg)); 4711590Srgrimes break; 472187995Simp case 'I': 473187995Simp Parse_AddIncludeDir(optarg); 474187995Simp MFLAGS_append("-I", optarg); 475187995Simp break; 4761590Srgrimes case 'i': 4771590Srgrimes ignoreErrors = TRUE; 478133085Sharti MFLAGS_append("-i", NULL); 4791590Srgrimes break; 48049331Shoek case 'j': { 48149331Shoek char *endptr; 48249331Shoek 48318730Ssteve forceJobs = TRUE; 484146140Sharti jobLimit = strtol(optarg, &endptr, 10); 485146140Sharti if (jobLimit <= 0 || *endptr != '\0') { 48649938Shoek warnx("illegal number, -j argument -- %s", 48749938Shoek optarg); 48849938Shoek usage(); 48949331Shoek } 490133085Sharti MFLAGS_append("-j", optarg); 4911590Srgrimes break; 49249331Shoek } 4931590Srgrimes case 'k': 4941590Srgrimes keepgoing = TRUE; 495133085Sharti MFLAGS_append("-k", NULL); 4961590Srgrimes break; 49718730Ssteve case 'm': 498201526Sobrien /* look for magic parent directory search string */ 499201526Sobrien if (strncmp(".../", optarg, 4) == 0) { 500201526Sobrien if (!Dir_FindHereOrAbove(curdir, optarg + 4, 501201526Sobrien found_dir, sizeof(found_dir))) 502201526Sobrien break; /* nothing doing */ 503201526Sobrien Path_AddDir(&sysIncPath, found_dir); 504201526Sobrien } else { 505201526Sobrien Path_AddDir(&sysIncPath, optarg); 506201526Sobrien } 507133085Sharti MFLAGS_append("-m", optarg); 50818730Ssteve break; 5091590Srgrimes case 'n': 5101590Srgrimes noExecute = TRUE; 511133085Sharti MFLAGS_append("-n", NULL); 5121590Srgrimes break; 513187995Simp case 'P': 514187995Simp usePipes = FALSE; 515187995Simp MFLAGS_append("-P", NULL); 516187995Simp break; 517181021Sed case 'p': 518181021Sed printGraphOnly = TRUE; 519181021Sed debug |= DEBUG_GRAPH1; 520181021Sed break; 521186713Sobrien case 'Q': 522186713Sobrien beQuiet = TRUE; 523187132Sobrien beVerbose = FALSE; 524186713Sobrien MFLAGS_append("-Q", NULL); 525186713Sobrien break; 5261590Srgrimes case 'q': 5271590Srgrimes queryFlag = TRUE; 5281590Srgrimes /* Kind of nonsensical, wot? */ 529133085Sharti MFLAGS_append("-q", NULL); 5301590Srgrimes break; 5311590Srgrimes case 'r': 5321590Srgrimes noBuiltins = TRUE; 533133085Sharti MFLAGS_append("-r", NULL); 5341590Srgrimes break; 535187995Simp case 'S': 536187995Simp keepgoing = FALSE; 537187995Simp MFLAGS_append("-S", NULL); 538187995Simp break; 5391590Srgrimes case 's': 5401590Srgrimes beSilent = TRUE; 541133085Sharti MFLAGS_append("-s", NULL); 5421590Srgrimes break; 5431590Srgrimes case 't': 5441590Srgrimes touchFlag = TRUE; 545133085Sharti MFLAGS_append("-t", NULL); 5461590Srgrimes break; 547187995Simp case 'V': 548187995Simp Lst_AtEnd(&variables, estrdup(optarg)); 549187995Simp MFLAGS_append("-V", optarg); 550187995Simp break; 55141151Sdg case 'v': 55241151Sdg beVerbose = TRUE; 553186713Sobrien beQuiet = FALSE; 554133085Sharti MFLAGS_append("-v", NULL); 55541151Sdg break; 556187995Simp case 'X': 557187995Simp expandVars = FALSE; 558187995Simp break; 559145627Sharti case 'x': 560145679Sharti if (Main_ParseWarn(optarg, 1) != -1) 561145627Sharti MFLAGS_append("-x", optarg); 562145627Sharti break; 563167330Sfjoe 5641590Srgrimes default: 5651590Srgrimes case '?': 5661590Srgrimes usage(); 5671590Srgrimes } 5681590Srgrimes } 569144896Sharti argv += optind; 570144896Sharti argc -= optind; 5711590Srgrimes 5721590Srgrimes oldVars = TRUE; 5731590Srgrimes 5741590Srgrimes /* 575144896Sharti * Parse the rest of the arguments. 576144896Sharti * o Check for variable assignments and perform them if so. 577144896Sharti * o Check for more flags and restart getopt if so. 578160442Sobrien * o Anything else is taken to be a target and added 579144896Sharti * to the end of the "create" list. 5801590Srgrimes */ 581144896Sharti for (; *argv != NULL; ++argv, --argc) { 582133562Sharti if (Parse_IsVar(*argv)) { 583140870Sharti char *ptr = MAKEFLAGS_quote(*argv); 584167330Sfjoe char *v = estrdup(*argv); 585133562Sharti 586146146Sharti Var_Append(".MAKEFLAGS", ptr, VAR_GLOBAL); 587167330Sfjoe Parse_DoVar(v, VAR_CMD); 588133562Sharti free(ptr); 589167330Sfjoe free(v); 590133562Sharti 591144896Sharti } else if ((*argv)[0] == '-') { 592144896Sharti if ((*argv)[1] == '\0') { 593144896Sharti /* 594144896Sharti * (*argv) is a single dash, so we 595144896Sharti * just ignore it. 596144896Sharti */ 597146038Sharti } else if (found_dd) { 598146038Sharti /* 599146038Sharti * Double dash has been found, ignore 600146038Sharti * any more options. But what do we do 601146038Sharti * with it? For now treat it like a target. 602146038Sharti */ 603146038Sharti Lst_AtEnd(&create, estrdup(*argv)); 604144896Sharti } else { 605144896Sharti /* 606146038Sharti * (*argv) is a -flag, so backup argv and 607146038Sharti * argc. getopt() expects options to start 608146038Sharti * in the 2nd position. 609144896Sharti */ 610144896Sharti argc++; 611144896Sharti argv--; 6121590Srgrimes goto rearg; 6131590Srgrimes } 614144896Sharti 615144896Sharti } else if ((*argv)[0] == '\0') { 616144896Sharti Punt("illegal (null) argument."); 617144896Sharti 618144896Sharti } else { 619138916Sharti Lst_AtEnd(&create, estrdup(*argv)); 6201590Srgrimes } 621144896Sharti } 6221590Srgrimes} 6231590Srgrimes 624144475Sharti/** 625144475Sharti * Main_ParseArgLine 626160442Sobrien * Used by the parse module when a .MFLAGS or .MAKEFLAGS target 6271590Srgrimes * is encountered and by main() when reading the .MAKEFLAGS envariable. 6281590Srgrimes * Takes a line of arguments and breaks it into its 629160442Sobrien * component words and passes those words and the number of them to the 6301590Srgrimes * MainParseArgs function. 6311590Srgrimes * The line should have all its leading whitespace removed. 6321590Srgrimes * 6331590Srgrimes * Side Effects: 6341590Srgrimes * Only those that come from the various arguments. 6351590Srgrimes */ 6361590Srgrimesvoid 637140870ShartiMain_ParseArgLine(char *line, int mflags) 6381590Srgrimes{ 639146345Sharti ArgArray aa; 6401590Srgrimes 6411590Srgrimes if (line == NULL) 6421590Srgrimes return; 6431590Srgrimes for (; *line == ' '; ++line) 6441590Srgrimes continue; 6451590Srgrimes if (!*line) 6461590Srgrimes return; 6471590Srgrimes 648140870Sharti if (mflags) 649146345Sharti MAKEFLAGS_break(&aa, line); 650140870Sharti else 651146345Sharti brk_string(&aa, line, TRUE); 652140870Sharti 653146345Sharti MainParseArgs(aa.argc, aa.argv); 654146345Sharti ArgArray_Done(&aa); 6551590Srgrimes} 6561590Srgrimes 657146146Shartistatic char * 658141252Shartichdir_verify_path(const char *path, char *obpath) 65918339Sswallace{ 66018339Sswallace struct stat sb; 66118339Sswallace 66218339Sswallace if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { 66375973Sru if (chdir(path) == -1 || getcwd(obpath, MAXPATHLEN) == NULL) { 66427644Scharnier warn("warning: %s", path); 665141252Sharti return (NULL); 66618339Sswallace } 667138232Sharti return (obpath); 66818339Sswallace } 66918339Sswallace 670141252Sharti return (NULL); 67118339Sswallace} 67218339Sswallace 673146144Sharti/** 674146144Sharti * In lieu of a good way to prevent every possible looping in make(1), stop 675146144Sharti * there from being more than MKLVL_MAXVAL processes forked by make(1), to 676146144Sharti * prevent a forkbomb from happening, in a dumb and mechanical way. 677146144Sharti * 678146144Sharti * Side Effects: 679146144Sharti * Creates or modifies enviornment variable MKLVL_ENVVAR via setenv(). 680138071Sjmallett */ 681138071Sjmallettstatic void 682138071Sjmallettcheck_make_level(void) 683138071Sjmallett{ 684138071Sjmallett#ifdef WANT_ENV_MKLVL 685138071Sjmallett char *value = getenv(MKLVL_ENVVAR); 686138071Sjmallett int level = (value == NULL) ? 0 : atoi(value); 687138071Sjmallett 688138071Sjmallett if (level < 0) { 689144475Sharti errc(2, EAGAIN, "Invalid value for recursion level (%d).", 690144475Sharti level); 691138071Sjmallett } else if (level > MKLVL_MAXVAL) { 692144475Sharti errc(2, EAGAIN, "Max recursion level (%d) exceeded.", 693144475Sharti MKLVL_MAXVAL); 694138071Sjmallett } else { 695138071Sjmallett char new_value[32]; 696138071Sjmallett sprintf(new_value, "%d", level + 1); 697138071Sjmallett setenv(MKLVL_ENVVAR, new_value, 1); 698138071Sjmallett } 699138071Sjmallett#endif /* WANT_ENV_MKLVL */ 700138071Sjmallett} 701138071Sjmallett 702144475Sharti/** 703167330Sfjoe * Main_AddSourceMakefile 704167330Sfjoe * Add a file to the list of source makefiles 705167330Sfjoe */ 706167330Sfjoevoid 707167330SfjoeMain_AddSourceMakefile(const char *name) 708167330Sfjoe{ 709167330Sfjoe 710167330Sfjoe Lst_AtEnd(&source_makefiles, estrdup(name)); 711167330Sfjoe} 712167330Sfjoe 713167330Sfjoe/** 714167330Sfjoe * Remake_Makefiles 715167330Sfjoe * Remake all the makefiles 716167330Sfjoe */ 717167330Sfjoestatic void 718167330SfjoeRemake_Makefiles(void) 719167330Sfjoe{ 720198199Sfjoe Lst cleanup; 721167330Sfjoe LstNode *ln; 722167330Sfjoe int error_cnt = 0; 723167330Sfjoe int remade_cnt = 0; 724167330Sfjoe 725167330Sfjoe Compat_InstallSignalHandlers(); 726170179Sfjoe if (curdir != objdir) { 727170179Sfjoe if (chdir(curdir) < 0) 728170179Sfjoe Fatal("Failed to change directory to %s.", curdir); 729170179Sfjoe } 730167330Sfjoe 731198199Sfjoe Lst_Init(&cleanup); 732167330Sfjoe LST_FOREACH(ln, &source_makefiles) { 733167330Sfjoe LstNode *ln2; 734167330Sfjoe struct GNode *gn; 735167330Sfjoe const char *name = Lst_Datum(ln); 736167330Sfjoe Boolean saveTouchFlag = touchFlag; 737167330Sfjoe Boolean saveQueryFlag = queryFlag; 738167330Sfjoe Boolean saveNoExecute = noExecute; 739168892Sfjoe int mtime; 740167330Sfjoe 741167330Sfjoe /* 742167330Sfjoe * Create node 743167330Sfjoe */ 744167330Sfjoe gn = Targ_FindNode(name, TARG_CREATE); 745167330Sfjoe DEBUGF(MAKE, ("Checking %s...", gn->name)); 746167330Sfjoe Suff_FindDeps(gn); 747167330Sfjoe 748167330Sfjoe /* 749167330Sfjoe * -t, -q and -n has no effect unless the makefile is 750167330Sfjoe * specified as one of the targets explicitly in the 751167330Sfjoe * command line 752167330Sfjoe */ 753167330Sfjoe LST_FOREACH(ln2, &create) { 754167330Sfjoe if (!strcmp(gn->name, Lst_Datum(ln2))) { 755167330Sfjoe /* found as a target */ 756167330Sfjoe break; 757167330Sfjoe } 758167330Sfjoe } 759167330Sfjoe if (ln2 == NULL) { 760167330Sfjoe touchFlag = FALSE; 761167330Sfjoe queryFlag = FALSE; 762167330Sfjoe noExecute = FALSE; 763167330Sfjoe } 764167330Sfjoe 765167330Sfjoe /* 766167330Sfjoe * Check and remake the makefile 767167330Sfjoe */ 768168892Sfjoe mtime = Dir_MTime(gn); 769190821Sfjoe remakingMakefiles = TRUE; 770167330Sfjoe Compat_Make(gn, gn); 771190821Sfjoe remakingMakefiles = FALSE; 772167330Sfjoe 773167330Sfjoe /* 774167330Sfjoe * Restore -t, -q and -n behaviour 775167330Sfjoe */ 776167330Sfjoe touchFlag = saveTouchFlag; 777167330Sfjoe queryFlag = saveQueryFlag; 778167330Sfjoe noExecute = saveNoExecute; 779167330Sfjoe 780167330Sfjoe /* 781167330Sfjoe * Compat_Make will leave the 'made' field of gn 782167330Sfjoe * in one of the following states: 783167330Sfjoe * UPTODATE gn was already up-to-date 784167330Sfjoe * MADE gn was recreated successfully 785167330Sfjoe * ERROR An error occurred while gn was being created 786167330Sfjoe * ABORTED gn was not remade because one of its inferiors 787167330Sfjoe * could not be made due to errors. 788167330Sfjoe */ 789168892Sfjoe if (gn->made == MADE) { 790168892Sfjoe if (mtime != Dir_MTime(gn)) { 791168892Sfjoe DEBUGF(MAKE, 792168892Sfjoe ("%s updated (%d -> %d).\n", 793168892Sfjoe gn->name, mtime, gn->mtime)); 794168892Sfjoe remade_cnt++; 795168892Sfjoe } else { 796168892Sfjoe DEBUGF(MAKE, 797168892Sfjoe ("%s not updated: skipping restart.\n", 798168892Sfjoe gn->name)); 799168892Sfjoe } 800168892Sfjoe } else if (gn->made == ERROR) 801167330Sfjoe error_cnt++; 802167330Sfjoe else if (gn->made == ABORTED) { 803167330Sfjoe printf("`%s' not remade because of errors.\n", 804167330Sfjoe gn->name); 805167330Sfjoe error_cnt++; 806173919Sfjoe } else if (gn->made == UPTODATE) { 807198199Sfjoe Lst_EnQueue(&cleanup, gn); 808167330Sfjoe } 809167330Sfjoe } 810167330Sfjoe 811167330Sfjoe if (error_cnt > 0) 812167330Sfjoe Fatal("Failed to remake Makefiles."); 813167330Sfjoe if (remade_cnt > 0) { 814167330Sfjoe DEBUGF(MAKE, ("Restarting `%s'.\n", save_argv[0])); 815167330Sfjoe 816167330Sfjoe /* 817167330Sfjoe * Some of makefiles were remade -- restart from clean state 818167330Sfjoe */ 819167330Sfjoe if (save_makeflags != NULL) 820167330Sfjoe setenv("MAKEFLAGS", save_makeflags, 1); 821167330Sfjoe else 822167330Sfjoe unsetenv("MAKEFLAGS"); 823167330Sfjoe if (execvp(save_argv[0], save_argv) < 0) { 824167330Sfjoe Fatal("Can't restart `%s': %s.", 825167330Sfjoe save_argv[0], strerror(errno)); 826167330Sfjoe } 827167330Sfjoe } 828170179Sfjoe 829198199Sfjoe while (!Lst_IsEmpty(&cleanup)) { 830198199Sfjoe GNode *gn = Lst_DeQueue(&cleanup); 831198199Sfjoe 832198199Sfjoe gn->unmade = 0; 833198199Sfjoe gn->make = FALSE; 834198199Sfjoe gn->made = UNMADE; 835198199Sfjoe gn->childMade = FALSE; 836198199Sfjoe gn->mtime = gn->cmtime = 0; 837198199Sfjoe gn->cmtime_gn = NULL; 838198199Sfjoe 839198199Sfjoe LST_FOREACH(ln, &gn->children) { 840198199Sfjoe GNode *cgn = Lst_Datum(ln); 841198199Sfjoe 842198199Sfjoe gn->unmade++; 843198199Sfjoe Lst_EnQueue(&cleanup, cgn); 844198199Sfjoe } 845198199Sfjoe } 846198199Sfjoe 847170179Sfjoe if (curdir != objdir) { 848170179Sfjoe if (chdir(objdir) < 0) 849170179Sfjoe Fatal("Failed to change directory to %s.", objdir); 850170179Sfjoe } 851167330Sfjoe} 852167330Sfjoe 853167330Sfjoe/** 854144475Sharti * main 8551590Srgrimes * The main function, for obvious reasons. Initializes variables 8561590Srgrimes * and a few modules, then parses the arguments give it in the 8571590Srgrimes * environment and on the command line. Reads the system makefile 8581590Srgrimes * followed by either Makefile, makefile or the file given by the 8591590Srgrimes * -f argument. Sets the .MAKEFLAGS PMake variable based on all the 8601590Srgrimes * flags it has received by then uses either the Make or the Compat 8611590Srgrimes * module to create the initial list of targets. 8621590Srgrimes * 8631590Srgrimes * Results: 8641590Srgrimes * If -q was given, exits -1 if anything was out-of-date. Else it exits 8651590Srgrimes * 0. 8661590Srgrimes * 8671590Srgrimes * Side Effects: 8681590Srgrimes * The program exits when done. Targets are created. etc. etc. etc. 8691590Srgrimes */ 8701590Srgrimesint 871104696Sjmallettmain(int argc, char **argv) 8721590Srgrimes{ 873160442Sobrien const char *machine; 874146144Sharti const char *machine_arch; 875146144Sharti const char *machine_cpu; 876160442Sobrien Boolean outOfDate = TRUE; /* FALSE if all targets up to date */ 877146581Sharti const char *p; 878146157Sharti const char *pathp; 879146157Sharti const char *path; 88073262Simp char mdpath[MAXPATHLEN]; 88173262Simp char obpath[MAXPATHLEN]; 88273262Simp char cdpath[MAXPATHLEN]; 883201526Sobrien char found_dir[MAXPATHLEN + 1]; /* for searching for sys.mk */ 88418730Ssteve char *cp = NULL, *start; 885141252Sharti 886167330Sfjoe save_argv = argv; 887167330Sfjoe save_makeflags = getenv("MAKEFLAGS"); 888167330Sfjoe if (save_makeflags != NULL) 889167330Sfjoe save_makeflags = estrdup(save_makeflags); 890167330Sfjoe 891146146Sharti /* 892146146Sharti * Initialize file global variables. 893146146Sharti */ 894146146Sharti expandVars = TRUE; 895146146Sharti noBuiltins = FALSE; /* Read the built-in rules */ 896160442Sobrien forceJobs = FALSE; /* No -j flag */ 897146146Sharti curdir = cdpath; 898146146Sharti 899146146Sharti /* 900146146Sharti * Initialize program global variables. 901146146Sharti */ 902146146Sharti beSilent = FALSE; /* Print commands as executed */ 903146146Sharti ignoreErrors = FALSE; /* Pay attention to non-zero returns */ 904146146Sharti noExecute = FALSE; /* Execute all commands */ 905181021Sed printGraphOnly = FALSE; /* Don't stop after printing graph */ 906146146Sharti keepgoing = FALSE; /* Stop on error */ 907146146Sharti allPrecious = FALSE; /* Remove targets when interrupted */ 908146146Sharti queryFlag = FALSE; /* This is not just a check-run */ 909146146Sharti touchFlag = FALSE; /* Actually update targets */ 910146146Sharti usePipes = TRUE; /* Catch child output in pipes */ 911146146Sharti debug = 0; /* No debug verbosity, please. */ 912146146Sharti jobsRunning = FALSE; 913146146Sharti 914146146Sharti jobLimit = DEFMAXJOBS; 915146146Sharti compatMake = FALSE; /* No compat mode */ 916146146Sharti 917138071Sjmallett check_make_level(); 918104395Sjmallett 91918730Ssteve#ifdef RLIMIT_NOFILE 9201590Srgrimes /* 92118730Ssteve * get rid of resource limit on file descriptors 92218730Ssteve */ 92318730Ssteve { 92418730Ssteve struct rlimit rl; 925146144Sharti if (getrlimit(RLIMIT_NOFILE, &rl) == -1) { 926146144Sharti err(2, "getrlimit"); 92718730Ssteve } 928146144Sharti rl.rlim_cur = rl.rlim_max; 929146144Sharti if (setrlimit(RLIMIT_NOFILE, &rl) == -1) { 930146144Sharti err(2, "setrlimit"); 931146144Sharti } 93218730Ssteve } 93318730Ssteve#endif 9341590Srgrimes 9355814Sjkh /* 936176786Simp * Prior to 7.0, FreeBSD/pc98 kernel used to set the 937176786Simp * utsname.machine to "i386", and MACHINE was defined as 938176786Simp * "i386", so it could not be distinguished from FreeBSD/i386. 939176786Simp * Therefore, we had to check machine.ispc98 and adjust the 940176786Simp * MACHINE variable. NOTE: The code is still here to be able 941176786Simp * to compile new make binary on old FreeBSD/pc98 systems, and 942176786Simp * have the MACHINE variable set properly. 94339006Skato */ 944146157Sharti if ((machine = getenv("MACHINE")) == NULL) { 94539006Skato int ispc98; 94639006Skato size_t len; 94739006Skato 94839006Skato len = sizeof(ispc98); 94939006Skato if (!sysctlbyname("machdep.ispc98", &ispc98, &len, NULL, 0)) { 95039006Skato if (ispc98) 95139006Skato machine = "pc98"; 95239006Skato } 95339006Skato } 95439006Skato 95539006Skato /* 9565814Sjkh * Get the name of this type of MACHINE from utsname 9575814Sjkh * so we can share an executable for similar machines. 9585814Sjkh * (i.e. m68k: amiga hp300, mac68k, sun3, ...) 9595814Sjkh * 960153115Sru * Note that both MACHINE and MACHINE_ARCH are decided at 961153115Sru * run-time. 9625814Sjkh */ 963146157Sharti if (machine == NULL) { 964144475Sharti static struct utsname utsname; 96518730Ssteve 966144475Sharti if (uname(&utsname) == -1) 967144475Sharti err(2, "uname"); 968144475Sharti machine = utsname.machine; 9695814Sjkh } 9701590Srgrimes 971146144Sharti if ((machine_arch = getenv("MACHINE_ARCH")) == NULL) { 972146144Sharti#ifdef MACHINE_ARCH 973146144Sharti machine_arch = MACHINE_ARCH; 974146144Sharti#else 97544362Simp machine_arch = "unknown"; 97644362Simp#endif 97744362Simp } 97844362Simp 9791590Srgrimes /* 98072679Skris * Set machine_cpu to the minumum supported CPU revision based 98172679Skris * on the target architecture, if not already set. 98272679Skris */ 983146144Sharti if ((machine_cpu = getenv("MACHINE_CPU")) == NULL) { 98472679Skris if (!strcmp(machine_arch, "i386")) 98572679Skris machine_cpu = "i386"; 98672679Skris else if (!strcmp(machine_arch, "alpha")) 98772679Skris machine_cpu = "ev4"; 98872679Skris else 98972679Skris machine_cpu = "unknown"; 99072679Skris } 9911590Srgrimes 9921590Srgrimes /* 9931590Srgrimes * Initialize the parsing, directory and variable modules to prepare 9941590Srgrimes * for the reading of inclusion paths and variable settings on the 9951590Srgrimes * command line 9961590Srgrimes */ 997146144Sharti Proc_Init(); 998146144Sharti 9991590Srgrimes Dir_Init(); /* Initialize directory structures so -I flags 10001590Srgrimes * can be processed correctly */ 1001145971Sharti Var_Init(environ); /* As well as the lists of variables for 10021590Srgrimes * parsing arguments */ 1003146560Sharti 10041590Srgrimes /* 1005146560Sharti * Initialize the Shell so that we have a shell for != assignments 1006146560Sharti * on the command line. 1007146560Sharti */ 1008146560Sharti Shell_Init(); 1009146560Sharti 1010146560Sharti /* 10111590Srgrimes * Initialize various variables. 10121590Srgrimes * MAKE also gets this name, for compatibility 10131590Srgrimes * .MAKEFLAGS gets set to the empty string just in case. 10141590Srgrimes * MFLAGS also gets initialized empty, for compatibility. 10151590Srgrimes */ 1016146145Sharti Var_SetGlobal("MAKE", argv[0]); 1017146146Sharti Var_SetGlobal(".MAKEFLAGS", ""); 1018146145Sharti Var_SetGlobal("MFLAGS", ""); 1019146145Sharti Var_SetGlobal("MACHINE", machine); 1020146145Sharti Var_SetGlobal("MACHINE_ARCH", machine_arch); 1021146145Sharti Var_SetGlobal("MACHINE_CPU", machine_cpu); 102297121Sru#ifdef MAKE_VERSION 1023146145Sharti Var_SetGlobal("MAKE_VERSION", MAKE_VERSION); 102497121Sru#endif 1025186559Sobrien Var_SetGlobal(".newline", "\n"); /* handy for :@ loops */ 1026186559Sobrien { 1027186559Sobrien char tmp[64]; 10281590Srgrimes 1029186559Sobrien snprintf(tmp, sizeof(tmp), "%u", getpid()); 1030186559Sobrien Var_SetGlobal(".MAKE.PID", tmp); 1031186559Sobrien snprintf(tmp, sizeof(tmp), "%u", getppid()); 1032186559Sobrien Var_SetGlobal(".MAKE.PPID", tmp); 1033186559Sobrien } 1034186559Sobrien Job_SetPrefix(); 1035186559Sobrien 10361590Srgrimes /* 1037201526Sobrien * Find where we are... 1038201526Sobrien */ 1039201526Sobrien if (getcwd(curdir, MAXPATHLEN) == NULL) 1040201526Sobrien err(2, NULL); 1041201526Sobrien 1042201526Sobrien /* 1043144896Sharti * First snag things out of the MAKEFLAGS environment 1044144896Sharti * variable. Then parse the command line arguments. 10451590Srgrimes */ 1046140870Sharti Main_ParseArgLine(getenv("MAKEFLAGS"), 1); 10478874Srgrimes 10481590Srgrimes MainParseArgs(argc, argv); 10491590Srgrimes 10501590Srgrimes /* 1051201526Sobrien * Verify that cwd is sane (after -C may have changed it). 1052120053Sru */ 1053141252Sharti { 1054141252Sharti struct stat sa; 1055141252Sharti 1056120053Sru if (stat(curdir, &sa) == -1) 1057120053Sru err(2, "%s", curdir); 1058141252Sharti } 1059120053Sru 1060120053Sru /* 1061120053Sru * The object directory location is determined using the 1062120053Sru * following order of preference: 1063120053Sru * 1064120053Sru * 1. MAKEOBJDIRPREFIX`cwd` 1065120053Sru * 2. MAKEOBJDIR 1066143412Sharti * 3. PATH_OBJDIR.${MACHINE} 1067143412Sharti * 4. PATH_OBJDIR 1068143412Sharti * 5. PATH_OBJDIRPREFIX`cwd` 1069120053Sru * 1070120053Sru * If one of the first two fails, use the current directory. 1071120053Sru * If the remaining three all fail, use the current directory. 1072120053Sru * 1073120053Sru * Once things are initted, 1074120053Sru * have to add the original directory to the search path, 1075120053Sru * and modify the paths for the Makefiles apropriately. The 1076120053Sru * current directory is also placed as a variable for make scripts. 1077120053Sru */ 1078120053Sru if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) { 1079120053Sru if (!(path = getenv("MAKEOBJDIR"))) { 1080143412Sharti path = PATH_OBJDIR; 1081143412Sharti pathp = PATH_OBJDIRPREFIX; 1082146145Sharti snprintf(mdpath, MAXPATHLEN, "%s.%s", path, machine); 1083120053Sru if (!(objdir = chdir_verify_path(mdpath, obpath))) 1084120053Sru if (!(objdir=chdir_verify_path(path, obpath))) { 1085138232Sharti snprintf(mdpath, MAXPATHLEN, 1086120053Sru "%s%s", pathp, curdir); 1087120053Sru if (!(objdir=chdir_verify_path(mdpath, 1088120053Sru obpath))) 1089120053Sru objdir = curdir; 1090120053Sru } 1091120053Sru } 1092120053Sru else if (!(objdir = chdir_verify_path(path, obpath))) 1093120053Sru objdir = curdir; 1094120053Sru } 1095120053Sru else { 1096138232Sharti snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir); 1097120053Sru if (!(objdir = chdir_verify_path(mdpath, obpath))) 1098120053Sru objdir = curdir; 1099120053Sru } 1100120053Sru Dir_InitDot(); /* Initialize the "." directory */ 1101120053Sru if (objdir != curdir) 1102144020Sharti Path_AddDir(&dirSearchPath, curdir); 1103146145Sharti Var_SetGlobal(".ST_EXPORTVAR", "YES"); 1104146145Sharti Var_SetGlobal(".CURDIR", curdir); 1105146145Sharti Var_SetGlobal(".OBJDIR", objdir); 1106120053Sru 1107137606Sphk if (getenv("MAKE_JOBS_FIFO") != NULL) 1108137606Sphk forceJobs = TRUE; 1109120053Sru /* 111028228Sfsmp * Be compatible if user did not specify -j and did not explicitly 111128228Sfsmp * turned compatibility on 111228228Sfsmp */ 111328228Sfsmp if (!compatMake && !forceJobs) 111428228Sfsmp compatMake = TRUE; 111528228Sfsmp 111628228Sfsmp /* 1117144387Sharti * Initialize target and suffix modules in preparation for 11181590Srgrimes * parsing the makefile(s) 11191590Srgrimes */ 11201590Srgrimes Targ_Init(); 11211590Srgrimes Suff_Init(); 11221590Srgrimes 112369527Swill DEFAULT = NULL; 1124138232Sharti time(&now); 11251590Srgrimes 11261590Srgrimes /* 11271590Srgrimes * Set up the .TARGETS variable to contain the list of targets to be 11281590Srgrimes * created. If none specified, make the variable empty -- the parser 11291590Srgrimes * will fill the thing in with the default or .MAIN target. 11301590Srgrimes */ 1131146145Sharti if (Lst_IsEmpty(&create)) { 1132146145Sharti Var_SetGlobal(".TARGETS", ""); 1133146145Sharti } else { 1134138512Sharti LstNode *ln; 11351590Srgrimes 1136138916Sharti for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) { 1137138264Sharti char *name = Lst_Datum(ln); 11381590Srgrimes 11391590Srgrimes Var_Append(".TARGETS", name, VAR_GLOBAL); 11401590Srgrimes } 1141146145Sharti } 11421590Srgrimes 114318730Ssteve 11441590Srgrimes /* 114518730Ssteve * If no user-supplied system path was given (through the -m option) 114618730Ssteve * add the directories from the DEFSYSPATH (more than one may be given 114718730Ssteve * as dir1:...:dirn) to the system include path. 11481590Srgrimes */ 1149144020Sharti if (TAILQ_EMPTY(&sysIncPath)) { 1150201526Sobrien char defsyspath[] = PATH_DEFSYSPATH; 1151201526Sobrien char *syspath = getenv("MAKESYSPATH"); 1152146144Sharti 1153201526Sobrien /* 1154201526Sobrien * If no user-supplied system path was given (thru -m option) 1155201526Sobrien * add the directories from the DEFSYSPATH (more than one may 1156201526Sobrien * be given as dir1:...:dirn) to the system include path. 1157201526Sobrien */ 1158201526Sobrien if (syspath == NULL || *syspath == '\0') 1159201526Sobrien syspath = defsyspath; 1160201526Sobrien else 1161201526Sobrien syspath = estrdup(syspath); 1162201526Sobrien 116318730Ssteve for (start = syspath; *start != '\0'; start = cp) { 116418730Ssteve for (cp = start; *cp != '\0' && *cp != ':'; cp++) 116518730Ssteve continue; 1166201526Sobrien if (*cp == ':') { 1167201526Sobrien *cp++ = '\0'; 1168201526Sobrien } 1169201526Sobrien /* look for magic parent directory search string */ 1170201526Sobrien if (strncmp(".../", start, 4) == 0) { 1171201526Sobrien if (Dir_FindHereOrAbove(curdir, start + 4, 1172201526Sobrien found_dir, sizeof(found_dir))) { 1173201526Sobrien Path_AddDir(&sysIncPath, found_dir); 1174201526Sobrien } 117518730Ssteve } else { 1176144020Sharti Path_AddDir(&sysIncPath, start); 117718730Ssteve } 117818730Ssteve } 1179201526Sobrien if (syspath != defsyspath) 1180201526Sobrien free(syspath); 118118730Ssteve } 11821590Srgrimes 118318730Ssteve /* 118418730Ssteve * Read in the built-in rules first, followed by the specified 118518730Ssteve * makefile, if it was (makefile != (char *) NULL), or the default 118618730Ssteve * Makefile and makefile, in that order, if it wasn't. 118718730Ssteve */ 118818730Ssteve if (!noBuiltins) { 1189138916Sharti /* Path of sys.mk */ 1190138916Sharti Lst sysMkPath = Lst_Initializer(sysMkPath); 1191138512Sharti LstNode *ln; 1192146064Sharti char defsysmk[] = PATH_DEFSYSMK; 119318730Ssteve 1194146064Sharti Path_Expand(defsysmk, &sysIncPath, &sysMkPath); 1195138916Sharti if (Lst_IsEmpty(&sysMkPath)) 1196143412Sharti Fatal("make: no system rules (%s).", PATH_DEFSYSMK); 1197143808Sharti LST_FOREACH(ln, &sysMkPath) { 1198143808Sharti if (!ReadMakefile(Lst_Datum(ln))) 1199143808Sharti break; 1200143808Sharti } 120169527Swill if (ln != NULL) 120218730Ssteve Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 1203138916Sharti Lst_Destroy(&sysMkPath, free); 120418730Ssteve } 120518730Ssteve 1206138916Sharti if (!Lst_IsEmpty(&makefiles)) { 1207138512Sharti LstNode *ln; 12081590Srgrimes 1209143808Sharti LST_FOREACH(ln, &makefiles) { 1210167330Sfjoe if (!TryReadMakefile(Lst_Datum(ln))) 1211143808Sharti break; 1212143808Sharti } 121369527Swill if (ln != NULL) 12141590Srgrimes Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 1215167330Sfjoe } else if (!TryReadMakefile("BSDmakefile")) 1216167330Sfjoe if (!TryReadMakefile("makefile")) 1217167330Sfjoe TryReadMakefile("Makefile"); 12181590Srgrimes 1219143808Sharti ReadMakefile(".depend"); 12201590Srgrimes 1221176842Syar /* Install all the flags into the MAKEFLAGS envariable. */ 1222146580Sharti if (((p = Var_Value(".MAKEFLAGS", VAR_GLOBAL)) != NULL) && *p) 12231590Srgrimes setenv("MAKEFLAGS", p, 1); 1224176839Syar else 1225176839Syar setenv("MAKEFLAGS", "", 1); 12261590Srgrimes 12271590Srgrimes /* 12281590Srgrimes * For compatibility, look at the directories in the VPATH variable 12291590Srgrimes * and add them to the search path, if the variable is defined. The 12301590Srgrimes * variable's value is in the same format as the PATH envariable, i.e. 12311590Srgrimes * <directory>:<directory>:<directory>... 12321590Srgrimes */ 12331590Srgrimes if (Var_Exists("VPATH", VAR_CMD)) { 12341590Srgrimes /* 12351590Srgrimes * GCC stores string constants in read-only memory, but 12361590Srgrimes * Var_Subst will want to write this thing, so store it 12371590Srgrimes * in an array 12381590Srgrimes */ 12391590Srgrimes static char VPATH[] = "${VPATH}"; 1240142457Sharti Buffer *buf; 1241142457Sharti char *vpath; 1242142457Sharti char *ptr; 1243142457Sharti char savec; 12441590Srgrimes 1245146027Sharti buf = Var_Subst(VPATH, VAR_CMD, FALSE); 1246142457Sharti 1247143959Sharti vpath = Buf_Data(buf); 12481590Srgrimes do { 12491590Srgrimes /* skip to end of directory */ 1250142457Sharti for (ptr = vpath; *ptr != ':' && *ptr != '\0'; ptr++) 1251141969Sharti ; 1252141969Sharti 12531590Srgrimes /* Save terminator character so know when to stop */ 1254141969Sharti savec = *ptr; 1255141969Sharti *ptr = '\0'; 1256141969Sharti 12571590Srgrimes /* Add directory to search path */ 1258144020Sharti Path_AddDir(&dirSearchPath, vpath); 1259141969Sharti 1260142457Sharti vpath = ptr + 1; 1261141969Sharti } while (savec != '\0'); 1262142457Sharti 1263142457Sharti Buf_Destroy(buf, TRUE); 12641590Srgrimes } 12651590Srgrimes 12661590Srgrimes /* 12671590Srgrimes * Now that all search paths have been read for suffixes et al, it's 12681590Srgrimes * time to add the default search path to their lists... 12691590Srgrimes */ 12701590Srgrimes Suff_DoPaths(); 12711590Srgrimes 12721590Srgrimes /* print the initial graph, if the user requested it */ 12731590Srgrimes if (DEBUG(GRAPH1)) 12741590Srgrimes Targ_PrintGraph(1); 12751590Srgrimes 127617193Sbde /* print the values of any variables requested by the user */ 1277181021Sed if (Lst_IsEmpty(&variables) && !printGraphOnly) { 12781590Srgrimes /* 1279141974Sharti * Since the user has not requested that any variables 1280142008Sharti * be printed, we can build targets. 1281141974Sharti * 1282142008Sharti * Have read the entire graph and need to make a list of targets 1283141974Sharti * to create. If none was given on the command line, we consult 1284141974Sharti * the parsing module to find the main target(s) to create. 12851590Srgrimes */ 1286138916Sharti Lst targs = Lst_Initializer(targs); 1287138916Sharti 1288177101Sobrien if (!is_posix && mfAutoDeps) { 1289167330Sfjoe /* 1290167330Sfjoe * Check if any of the makefiles are out-of-date. 1291167330Sfjoe */ 1292167330Sfjoe Remake_Makefiles(); 1293167330Sfjoe } 1294167330Sfjoe 1295138916Sharti if (Lst_IsEmpty(&create)) 1296138916Sharti Parse_MainName(&targs); 1297101460Sru else 1298138916Sharti Targ_FindList(&targs, &create, TARG_CREATE); 1299101460Sru 1300141974Sharti if (compatMake) { 1301101460Sru /* 1302141974Sharti * Compat_Init will take care of creating 1303141974Sharti * all the targets as well as initializing 1304141974Sharti * the module. 1305101460Sru */ 1306141974Sharti Compat_Run(&targs); 1307141974Sharti outOfDate = 0; 1308141974Sharti } else { 1309141974Sharti /* 1310141974Sharti * Initialize job module before traversing 1311141974Sharti * the graph, now that any .BEGIN and .END 1312141974Sharti * targets have been read. This is done 1313141974Sharti * only if the -q flag wasn't given (to 1314141974Sharti * prevent the .BEGIN from being executed 1315141974Sharti * should it exist). 1316141974Sharti */ 1317101460Sru if (!queryFlag) { 1318146140Sharti Job_Init(jobLimit); 1319101460Sru jobsRunning = TRUE; 1320101460Sru } 1321101460Sru 1322101460Sru /* Traverse the graph, checking on all the targets */ 1323138916Sharti outOfDate = Make_Run(&targs); 13241590Srgrimes } 1325138916Sharti Lst_Destroy(&targs, NOFREE); 1326141974Sharti 1327141974Sharti } else { 1328146141Sharti Var_Print(&variables, expandVars); 132917193Sbde } 13308874Srgrimes 1331138920Sru Lst_Destroy(&variables, free); 1332138920Sru Lst_Destroy(&makefiles, free); 1333167330Sfjoe Lst_Destroy(&source_makefiles, free); 1334138916Sharti Lst_Destroy(&create, free); 13355814Sjkh 13361590Srgrimes /* print the graph now it's been processed if the user requested it */ 13371590Srgrimes if (DEBUG(GRAPH2)) 13381590Srgrimes Targ_PrintGraph(2); 13391590Srgrimes 1340186279Sfjoe if (queryFlag) 1341186279Sfjoe return (outOfDate); 1342186279Sfjoe 1343186279Sfjoe if (makeErrors != 0) 1344186279Sfjoe Finish(makeErrors); 1345186279Sfjoe 1346186279Sfjoe return (0); 13471590Srgrimes} 1348