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$"); 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> 66127880Sdes#include <sys/time.h> 67144020Sharti#include <sys/queue.h> 68127899Sru#include <sys/resource.h> 69153115Sru#include <sys/utsname.h> 7018730Ssteve#include <sys/wait.h> 7127644Scharnier#include <err.h> 721590Srgrimes#include <errno.h> 73127880Sdes#include <stdlib.h> 74141104Sharti#include <string.h> 7563955Simp#include <unistd.h> 76127880Sdes 77141104Sharti#include "arch.h" 78141133Sharti#include "buf.h" 79141104Sharti#include "config.h" 801590Srgrimes#include "dir.h" 81141104Sharti#include "globals.h" 82167330Sfjoe#include "GNode.h" 831590Srgrimes#include "job.h" 84141104Sharti#include "make.h" 85141104Sharti#include "parse.h" 861590Srgrimes#include "pathnames.h" 87146572Sharti#include "shell.h" 88141104Sharti#include "str.h" 89141104Sharti#include "suff.h" 90141104Sharti#include "targ.h" 91141104Sharti#include "util.h" 92141104Sharti#include "var.h" 931590Srgrimes 94146146Shartiextern char **environ; /* XXX what header declares this variable? */ 95146146Sharti 96160442Sobrien#define WANT_ENV_MKLVL 1 97138071Sjmallett#define MKLVL_MAXVAL 500 98138071Sjmallett#define MKLVL_ENVVAR "__MKLVL__" 99104395Sjmallett 100138916Sharti/* ordered list of makefiles to read */ 101138916Shartistatic Lst makefiles = Lst_Initializer(makefiles); 102138916Sharti 103167330Sfjoe/* ordered list of source makefiles */ 104167330Sfjoestatic Lst source_makefiles = Lst_Initializer(source_makefiles); 105167330Sfjoe 106138916Sharti/* list of variables to print */ 107138916Shartistatic Lst variables = Lst_Initializer(variables); 108138916Sharti 109146146Shartistatic Boolean expandVars; /* fully expand printed variables */ 110146146Shartistatic Boolean noBuiltins; /* -r flag */ 111160442Sobrienstatic Boolean forceJobs; /* -j argument given */ 112146146Shartistatic char *curdir; /* startup directory */ 113146146Shartistatic char *objdir; /* where we chdir'ed to */ 114167330Sfjoestatic char **save_argv; /* saved argv */ 115167330Sfjoestatic char *save_makeflags;/* saved MAKEFLAGS */ 116146146Sharti 117146146Sharti/* (-E) vars to override from env */ 118146146ShartiLst envFirstVars = Lst_Initializer(envFirstVars); 119146146Sharti 120146146Sharti/* Targets to be made */ 121146146ShartiLst create = Lst_Initializer(create); 122146146Sharti 123146146ShartiBoolean allPrecious; /* .PRECIOUS given on line by itself */ 124167330SfjoeBoolean is_posix; /* .POSIX target seen */ 125177101SobrienBoolean mfAutoDeps; /* .MAKEFILEDEPS target seen */ 126190821SfjoeBoolean remakingMakefiles; /* True if remaking makefiles is in progress */ 127146146ShartiBoolean beSilent; /* -s flag */ 128146146ShartiBoolean beVerbose; /* -v flag */ 129187132SobrienBoolean beQuiet; /* -Q flag */ 130144475ShartiBoolean compatMake; /* -B argument */ 131149844Shartiint debug; /* -d flag */ 132146146ShartiBoolean ignoreErrors; /* -i flag */ 133146146Shartiint jobLimit; /* -j argument */ 134186279Sfjoeint makeErrors; /* Number of targets not remade due to errors */ 135146146ShartiBoolean jobsRunning; /* TRUE if the jobs might be running */ 136146146ShartiBoolean keepgoing; /* -k flag */ 137144475ShartiBoolean noExecute; /* -n flag */ 138181021SedBoolean printGraphOnly; /* -p flag */ 139144475ShartiBoolean queryFlag; /* -q flag */ 140144475ShartiBoolean touchFlag; /* -t flag */ 141144475ShartiBoolean usePipes; /* !-P flag */ 142146146Shartiuint32_t warn_cmd; /* command line warning flags */ 143146146Shartiuint32_t warn_flags; /* actual warning flags */ 144146146Shartiuint32_t warn_nocmd; /* command line no-warning flags */ 145138916Sharti 146146146Shartitime_t now; /* Time at start of make */ 147146146Shartistruct GNode *DEFAULT; /* .DEFAULT node */ 148138916Sharti 149230392Srmhstatic struct { 150230392Srmh const char *foreign_name; 151230392Srmh const char *freebsd_name; 152230392Srmh} arch_aliases[] = { 153230392Srmh { "x86_64", "amd64" }, 154230392Srmh { "mipsel", "mips" }, 155230392Srmh}; 156230392Srmh 157144475Sharti/** 158146143Sharti * Exit with usage message. 159146143Sharti */ 160146143Shartistatic void 161146143Shartiusage(void) 162146143Sharti{ 163146143Sharti fprintf(stderr, 164181021Sed "usage: make [-BPSXeiknpqrstv] [-C directory] [-D variable]\n" 165146143Sharti "\t[-d flags] [-E variable] [-f makefile] [-I directory]\n" 166146143Sharti "\t[-j max_jobs] [-m directory] [-V variable]\n" 167146143Sharti "\t[variable=value] [target ...]\n"); 168146143Sharti exit(2); 169146143Sharti} 170146143Sharti 171146143Sharti/** 172144475Sharti * MFLAGS_append 173144475Sharti * Append a flag with an optional argument to MAKEFLAGS and MFLAGS 174133085Sharti */ 175133085Shartistatic void 176141252ShartiMFLAGS_append(const char *flag, char *arg) 177133085Sharti{ 178140870Sharti char *str; 179138232Sharti 180146146Sharti Var_Append(".MAKEFLAGS", flag, VAR_GLOBAL); 181140870Sharti if (arg != NULL) { 182140870Sharti str = MAKEFLAGS_quote(arg); 183146146Sharti Var_Append(".MAKEFLAGS", str, VAR_GLOBAL); 184140870Sharti free(str); 185140870Sharti } 186133085Sharti 187133085Sharti Var_Append("MFLAGS", flag, VAR_GLOBAL); 188140870Sharti if (arg != NULL) { 189140870Sharti str = MAKEFLAGS_quote(arg); 190140870Sharti Var_Append("MFLAGS", str, VAR_GLOBAL); 191140870Sharti free(str); 192140870Sharti } 193133085Sharti} 194133085Sharti 195144475Sharti/** 196145679Sharti * Main_ParseWarn 197145679Sharti * 198145679Sharti * Handle argument to warning option. 199145679Sharti */ 200145679Shartiint 201145679ShartiMain_ParseWarn(const char *arg, int iscmd) 202145679Sharti{ 203145679Sharti int i, neg; 204145679Sharti 205145679Sharti static const struct { 206145679Sharti const char *option; 207145679Sharti uint32_t flag; 208145679Sharti } options[] = { 209145679Sharti { "dirsyntax", WARN_DIRSYNTAX }, 210145679Sharti { NULL, 0 } 211145679Sharti }; 212145679Sharti 213145679Sharti neg = 0; 214145679Sharti if (arg[0] == 'n' && arg[1] == 'o') { 215145679Sharti neg = 1; 216145679Sharti arg += 2; 217145679Sharti } 218145679Sharti 219145679Sharti for (i = 0; options[i].option != NULL; i++) 220145679Sharti if (strcmp(arg, options[i].option) == 0) 221145679Sharti break; 222145679Sharti 223145679Sharti if (options[i].option == NULL) 224145679Sharti /* unknown option */ 225145679Sharti return (-1); 226145679Sharti 227145679Sharti if (iscmd) { 228145679Sharti if (!neg) { 229145679Sharti warn_cmd |= options[i].flag; 230145679Sharti warn_nocmd &= ~options[i].flag; 231145679Sharti warn_flags |= options[i].flag; 232145679Sharti } else { 233145679Sharti warn_nocmd |= options[i].flag; 234145679Sharti warn_cmd &= ~options[i].flag; 235145679Sharti warn_flags &= ~options[i].flag; 236145679Sharti } 237145679Sharti } else { 238145679Sharti if (!neg) { 239145679Sharti warn_flags |= (options[i].flag & ~warn_nocmd); 240145679Sharti } else { 241145679Sharti warn_flags &= ~(options[i].flag | warn_cmd); 242145679Sharti } 243145679Sharti } 244145679Sharti return (0); 245145679Sharti} 246145679Sharti 247145679Sharti/** 248146143Sharti * Open and parse the given makefile. 249146143Sharti * 250146143Sharti * Results: 251146143Sharti * TRUE if ok. FALSE if couldn't open file. 252146143Sharti */ 253146143Shartistatic Boolean 254146143ShartiReadMakefile(const char p[]) 255146143Sharti{ 256152982Sdavidxu char *fname, *fnamesave; /* makefile to read */ 257146143Sharti FILE *stream; 258146143Sharti char *name, path[MAXPATHLEN]; 259146143Sharti char *MAKEFILE; 260146143Sharti int setMAKEFILE; 261146143Sharti 262146143Sharti /* XXX - remove this once constification is done */ 263152982Sdavidxu fnamesave = fname = estrdup(p); 264146143Sharti 265146143Sharti if (!strcmp(fname, "-")) { 266146143Sharti Parse_File("(stdin)", stdin); 267146145Sharti Var_SetGlobal("MAKEFILE", ""); 268146143Sharti } else { 269146143Sharti setMAKEFILE = strcmp(fname, ".depend"); 270146143Sharti 271146143Sharti /* if we've chdir'd, rebuild the path name */ 272146143Sharti if (curdir != objdir && *fname != '/') { 273146143Sharti snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname); 274146143Sharti /* 275146143Sharti * XXX The realpath stuff breaks relative includes 276146143Sharti * XXX in some cases. The problem likely is in 277146143Sharti * XXX parse.c where it does special things in 278228992Suqs * XXX ParseDoInclude if the file is relative 279146143Sharti * XXX or absolute and not a system file. There 280146143Sharti * XXX it assumes that if the current file that's 281146143Sharti * XXX being included is absolute, that any files 282146143Sharti * XXX that it includes shouldn't do the -I path 283228992Suqs * XXX stuff, which is inconsistent with historical 284228992Suqs * XXX behavior. However, I can't penetrate the mists 285146143Sharti * XXX further, so I'm putting this workaround in 286146143Sharti * XXX here until such time as the underlying bug 287146143Sharti * XXX can be fixed. 288146143Sharti */ 289146143Sharti#if THIS_BREAKS_THINGS 290146143Sharti if (realpath(path, path) != NULL && 291146143Sharti (stream = fopen(path, "r")) != NULL) { 292146143Sharti MAKEFILE = fname; 293146143Sharti fname = path; 294146143Sharti goto found; 295146143Sharti } 296146143Sharti } else if (realpath(fname, path) != NULL) { 297146143Sharti MAKEFILE = fname; 298146143Sharti fname = path; 299146143Sharti if ((stream = fopen(fname, "r")) != NULL) 300146143Sharti goto found; 301146143Sharti } 302146143Sharti#else 303146143Sharti if ((stream = fopen(path, "r")) != NULL) { 304146143Sharti MAKEFILE = fname; 305146143Sharti fname = path; 306146143Sharti goto found; 307146143Sharti } 308146143Sharti } else { 309146143Sharti MAKEFILE = fname; 310146143Sharti if ((stream = fopen(fname, "r")) != NULL) 311146143Sharti goto found; 312146143Sharti } 313146143Sharti#endif 314146143Sharti /* look in -I and system include directories. */ 315146143Sharti name = Path_FindFile(fname, &parseIncPath); 316146143Sharti if (!name) 317146143Sharti name = Path_FindFile(fname, &sysIncPath); 318152969Sfjoe if (!name || !(stream = fopen(name, "r"))) { 319152982Sdavidxu free(fnamesave); 320146143Sharti return (FALSE); 321152969Sfjoe } 322146143Sharti MAKEFILE = fname = name; 323146143Sharti /* 324146143Sharti * set the MAKEFILE variable desired by System V fans -- the 325146143Sharti * placement of the setting here means it gets set to the last 326146143Sharti * makefile specified, as it is set by SysV make. 327146143Sharti */ 328146143Shartifound: 329146143Sharti if (setMAKEFILE) 330146145Sharti Var_SetGlobal("MAKEFILE", MAKEFILE); 331146143Sharti Parse_File(fname, stream); 332146143Sharti } 333152982Sdavidxu free(fnamesave); 334146143Sharti return (TRUE); 335146143Sharti} 336146143Sharti 337146143Sharti/** 338167330Sfjoe * Open and parse the given makefile. 339167330Sfjoe * If open is successful add it to the list of makefiles. 340167330Sfjoe * 341167330Sfjoe * Results: 342167330Sfjoe * TRUE if ok. FALSE if couldn't open file. 343167330Sfjoe */ 344167330Sfjoestatic Boolean 345167330SfjoeTryReadMakefile(const char p[]) 346167330Sfjoe{ 347167330Sfjoe char *data; 348167330Sfjoe LstNode *last = Lst_Last(&source_makefiles); 349167330Sfjoe 350167330Sfjoe if (!ReadMakefile(p)) 351167330Sfjoe return (FALSE); 352167330Sfjoe 353167330Sfjoe data = estrdup(p); 354167330Sfjoe if (last == NULL) { 355167330Sfjoe LstNode *first = Lst_First(&source_makefiles); 356167330Sfjoe Lst_Insert(&source_makefiles, first, data); 357167330Sfjoe } else 358167330Sfjoe Lst_Append(&source_makefiles, last, estrdup(p)); 359167330Sfjoe return (TRUE); 360167330Sfjoe} 361167330Sfjoe 362167330Sfjoe/** 363144475Sharti * MainParseArgs 3641590Srgrimes * Parse a given argument vector. Called from main() and from 3651590Srgrimes * Main_ParseArgLine() when the .MAKEFLAGS target is used. 3661590Srgrimes * 3671590Srgrimes * XXX: Deal with command line overriding .MAKEFLAGS in makefile 3681590Srgrimes * 3691590Srgrimes * Side Effects: 3701590Srgrimes * Various global and local flags will be set depending on the flags 3711590Srgrimes * given 3721590Srgrimes */ 3731590Srgrimesstatic void 374104696SjmallettMainParseArgs(int argc, char **argv) 3751590Srgrimes{ 3765814Sjkh int c; 377146038Sharti Boolean found_dd = FALSE; 378201526Sobrien char found_dir[MAXPATHLEN + 1]; /* for searching for sys.mk */ 3791590Srgrimes 380144896Shartirearg: 3811590Srgrimes optind = 1; /* since we're called more than once */ 382144896Sharti optreset = 1; 383187995Simp#define OPTFLAGS "ABC:D:d:E:ef:I:ij:km:nPpQqrSstV:vXx:" 384146038Sharti for (;;) { 385146038Sharti if ((optind < argc) && strcmp(argv[optind], "--") == 0) { 386146038Sharti found_dd = TRUE; 387146038Sharti } 388146038Sharti if ((c = getopt(argc, argv, OPTFLAGS)) == -1) { 389146038Sharti break; 390146038Sharti } 3911590Srgrimes switch(c) { 392144387Sharti 393144387Sharti case 'A': 394144387Sharti arch_fatal = FALSE; 395144387Sharti MFLAGS_append("-A", NULL); 396144387Sharti break; 397187995Simp case 'B': 398187995Simp compatMake = TRUE; 399187995Simp MFLAGS_append("-B", NULL); 400187995Simp unsetenv("MAKE_JOBS_FIFO"); 401187995Simp break; 402102393Sjmallett case 'C': 403107964Sseanc if (chdir(optarg) == -1) 404107964Sseanc err(1, "chdir %s", optarg); 405201526Sobrien if (getcwd(curdir, MAXPATHLEN) == NULL) 406201526Sobrien err(2, NULL); 407102393Sjmallett break; 4081590Srgrimes case 'D': 409146145Sharti Var_SetGlobal(optarg, "1"); 410133085Sharti MFLAGS_append("-D", optarg); 4111590Srgrimes break; 4121590Srgrimes case 'd': { 4131590Srgrimes char *modules = optarg; 4141590Srgrimes 4151590Srgrimes for (; *modules; ++modules) 4161590Srgrimes switch (*modules) { 4171590Srgrimes case 'A': 4181590Srgrimes debug = ~0; 4191590Srgrimes break; 4201590Srgrimes case 'a': 4211590Srgrimes debug |= DEBUG_ARCH; 4221590Srgrimes break; 4231590Srgrimes case 'c': 4241590Srgrimes debug |= DEBUG_COND; 4251590Srgrimes break; 4261590Srgrimes case 'd': 4271590Srgrimes debug |= DEBUG_DIR; 4281590Srgrimes break; 4291590Srgrimes case 'f': 4301590Srgrimes debug |= DEBUG_FOR; 4311590Srgrimes break; 4321590Srgrimes case 'g': 4331590Srgrimes if (modules[1] == '1') { 4341590Srgrimes debug |= DEBUG_GRAPH1; 4351590Srgrimes ++modules; 4361590Srgrimes } 4371590Srgrimes else if (modules[1] == '2') { 4381590Srgrimes debug |= DEBUG_GRAPH2; 4391590Srgrimes ++modules; 4401590Srgrimes } 4411590Srgrimes break; 4421590Srgrimes case 'j': 4431590Srgrimes debug |= DEBUG_JOB; 4441590Srgrimes break; 44560569Swill case 'l': 44660569Swill debug |= DEBUG_LOUD; 44760569Swill break; 4481590Srgrimes case 'm': 4491590Srgrimes debug |= DEBUG_MAKE; 4501590Srgrimes break; 4511590Srgrimes case 's': 4521590Srgrimes debug |= DEBUG_SUFF; 4531590Srgrimes break; 4541590Srgrimes case 't': 4551590Srgrimes debug |= DEBUG_TARG; 4561590Srgrimes break; 4571590Srgrimes case 'v': 4581590Srgrimes debug |= DEBUG_VAR; 4591590Srgrimes break; 4601590Srgrimes default: 461144475Sharti warnx("illegal argument to d option " 462144475Sharti "-- %c", *modules); 4631590Srgrimes usage(); 4641590Srgrimes } 465133085Sharti MFLAGS_append("-d", optarg); 4661590Srgrimes break; 4671590Srgrimes } 46849332Shoek case 'E': 469138920Sru Lst_AtEnd(&envFirstVars, estrdup(optarg)); 470133085Sharti MFLAGS_append("-E", optarg); 47149332Shoek break; 4721590Srgrimes case 'e': 4731590Srgrimes checkEnvFirst = TRUE; 474133085Sharti MFLAGS_append("-e", NULL); 4751590Srgrimes break; 4761590Srgrimes case 'f': 477138920Sru Lst_AtEnd(&makefiles, estrdup(optarg)); 4781590Srgrimes break; 479187995Simp case 'I': 480187995Simp Parse_AddIncludeDir(optarg); 481187995Simp MFLAGS_append("-I", optarg); 482187995Simp break; 4831590Srgrimes case 'i': 4841590Srgrimes ignoreErrors = TRUE; 485133085Sharti MFLAGS_append("-i", NULL); 4861590Srgrimes break; 48749331Shoek case 'j': { 48849331Shoek char *endptr; 48949331Shoek 49018730Ssteve forceJobs = TRUE; 491146140Sharti jobLimit = strtol(optarg, &endptr, 10); 492146140Sharti if (jobLimit <= 0 || *endptr != '\0') { 49349938Shoek warnx("illegal number, -j argument -- %s", 49449938Shoek optarg); 49549938Shoek usage(); 49649331Shoek } 497133085Sharti MFLAGS_append("-j", optarg); 4981590Srgrimes break; 49949331Shoek } 5001590Srgrimes case 'k': 5011590Srgrimes keepgoing = TRUE; 502133085Sharti MFLAGS_append("-k", NULL); 5031590Srgrimes break; 50418730Ssteve case 'm': 505201526Sobrien /* look for magic parent directory search string */ 506201526Sobrien if (strncmp(".../", optarg, 4) == 0) { 507201526Sobrien if (!Dir_FindHereOrAbove(curdir, optarg + 4, 508201526Sobrien found_dir, sizeof(found_dir))) 509201526Sobrien break; /* nothing doing */ 510201526Sobrien Path_AddDir(&sysIncPath, found_dir); 511201526Sobrien } else { 512201526Sobrien Path_AddDir(&sysIncPath, optarg); 513201526Sobrien } 514133085Sharti MFLAGS_append("-m", optarg); 51518730Ssteve break; 5161590Srgrimes case 'n': 5171590Srgrimes noExecute = TRUE; 518133085Sharti MFLAGS_append("-n", NULL); 5191590Srgrimes break; 520187995Simp case 'P': 521187995Simp usePipes = FALSE; 522187995Simp MFLAGS_append("-P", NULL); 523187995Simp break; 524181021Sed case 'p': 525181021Sed printGraphOnly = TRUE; 526181021Sed debug |= DEBUG_GRAPH1; 527181021Sed break; 528186713Sobrien case 'Q': 529186713Sobrien beQuiet = TRUE; 530187132Sobrien beVerbose = FALSE; 531186713Sobrien MFLAGS_append("-Q", NULL); 532186713Sobrien break; 5331590Srgrimes case 'q': 5341590Srgrimes queryFlag = TRUE; 5351590Srgrimes /* Kind of nonsensical, wot? */ 536133085Sharti MFLAGS_append("-q", NULL); 5371590Srgrimes break; 5381590Srgrimes case 'r': 5391590Srgrimes noBuiltins = TRUE; 540133085Sharti MFLAGS_append("-r", NULL); 5411590Srgrimes break; 542187995Simp case 'S': 543187995Simp keepgoing = FALSE; 544187995Simp MFLAGS_append("-S", NULL); 545187995Simp break; 5461590Srgrimes case 's': 5471590Srgrimes beSilent = TRUE; 548133085Sharti MFLAGS_append("-s", NULL); 5491590Srgrimes break; 5501590Srgrimes case 't': 5511590Srgrimes touchFlag = TRUE; 552133085Sharti MFLAGS_append("-t", NULL); 5531590Srgrimes break; 554187995Simp case 'V': 555187995Simp Lst_AtEnd(&variables, estrdup(optarg)); 556187995Simp MFLAGS_append("-V", optarg); 557187995Simp break; 55841151Sdg case 'v': 55941151Sdg beVerbose = TRUE; 560186713Sobrien beQuiet = FALSE; 561133085Sharti MFLAGS_append("-v", NULL); 56241151Sdg break; 563187995Simp case 'X': 564187995Simp expandVars = FALSE; 565187995Simp break; 566145627Sharti case 'x': 567145679Sharti if (Main_ParseWarn(optarg, 1) != -1) 568145627Sharti MFLAGS_append("-x", optarg); 569145627Sharti break; 570167330Sfjoe 5711590Srgrimes default: 5721590Srgrimes case '?': 5731590Srgrimes usage(); 5741590Srgrimes } 5751590Srgrimes } 576144896Sharti argv += optind; 577144896Sharti argc -= optind; 5781590Srgrimes 5791590Srgrimes oldVars = TRUE; 5801590Srgrimes 5811590Srgrimes /* 582144896Sharti * Parse the rest of the arguments. 583144896Sharti * o Check for variable assignments and perform them if so. 584144896Sharti * o Check for more flags and restart getopt if so. 585160442Sobrien * o Anything else is taken to be a target and added 586144896Sharti * to the end of the "create" list. 5871590Srgrimes */ 588144896Sharti for (; *argv != NULL; ++argv, --argc) { 589133562Sharti if (Parse_IsVar(*argv)) { 590140870Sharti char *ptr = MAKEFLAGS_quote(*argv); 591167330Sfjoe char *v = estrdup(*argv); 592133562Sharti 593146146Sharti Var_Append(".MAKEFLAGS", ptr, VAR_GLOBAL); 594167330Sfjoe Parse_DoVar(v, VAR_CMD); 595133562Sharti free(ptr); 596167330Sfjoe free(v); 597133562Sharti 598144896Sharti } else if ((*argv)[0] == '-') { 599144896Sharti if ((*argv)[1] == '\0') { 600144896Sharti /* 601144896Sharti * (*argv) is a single dash, so we 602144896Sharti * just ignore it. 603144896Sharti */ 604146038Sharti } else if (found_dd) { 605146038Sharti /* 606146038Sharti * Double dash has been found, ignore 607146038Sharti * any more options. But what do we do 608146038Sharti * with it? For now treat it like a target. 609146038Sharti */ 610146038Sharti Lst_AtEnd(&create, estrdup(*argv)); 611144896Sharti } else { 612144896Sharti /* 613146038Sharti * (*argv) is a -flag, so backup argv and 614146038Sharti * argc. getopt() expects options to start 615146038Sharti * in the 2nd position. 616144896Sharti */ 617144896Sharti argc++; 618144896Sharti argv--; 6191590Srgrimes goto rearg; 6201590Srgrimes } 621144896Sharti 622144896Sharti } else if ((*argv)[0] == '\0') { 623144896Sharti Punt("illegal (null) argument."); 624144896Sharti 625144896Sharti } else { 626138916Sharti Lst_AtEnd(&create, estrdup(*argv)); 6271590Srgrimes } 628144896Sharti } 6291590Srgrimes} 6301590Srgrimes 631144475Sharti/** 632144475Sharti * Main_ParseArgLine 633160442Sobrien * Used by the parse module when a .MFLAGS or .MAKEFLAGS target 6341590Srgrimes * is encountered and by main() when reading the .MAKEFLAGS envariable. 6351590Srgrimes * Takes a line of arguments and breaks it into its 636160442Sobrien * component words and passes those words and the number of them to the 6371590Srgrimes * MainParseArgs function. 6381590Srgrimes * The line should have all its leading whitespace removed. 6391590Srgrimes * 6401590Srgrimes * Side Effects: 6411590Srgrimes * Only those that come from the various arguments. 6421590Srgrimes */ 6431590Srgrimesvoid 644140870ShartiMain_ParseArgLine(char *line, int mflags) 6451590Srgrimes{ 646146345Sharti ArgArray aa; 6471590Srgrimes 6481590Srgrimes if (line == NULL) 6491590Srgrimes return; 6501590Srgrimes for (; *line == ' '; ++line) 6511590Srgrimes continue; 6521590Srgrimes if (!*line) 6531590Srgrimes return; 6541590Srgrimes 655140870Sharti if (mflags) 656146345Sharti MAKEFLAGS_break(&aa, line); 657140870Sharti else 658146345Sharti brk_string(&aa, line, TRUE); 659140870Sharti 660146345Sharti MainParseArgs(aa.argc, aa.argv); 661146345Sharti ArgArray_Done(&aa); 6621590Srgrimes} 6631590Srgrimes 664146146Shartistatic char * 665141252Shartichdir_verify_path(const char *path, char *obpath) 66618339Sswallace{ 66718339Sswallace struct stat sb; 66818339Sswallace 66918339Sswallace if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { 67075973Sru if (chdir(path) == -1 || getcwd(obpath, MAXPATHLEN) == NULL) { 67127644Scharnier warn("warning: %s", path); 672141252Sharti return (NULL); 67318339Sswallace } 674138232Sharti return (obpath); 67518339Sswallace } 67618339Sswallace 677141252Sharti return (NULL); 67818339Sswallace} 67918339Sswallace 680146144Sharti/** 681146144Sharti * In lieu of a good way to prevent every possible looping in make(1), stop 682146144Sharti * there from being more than MKLVL_MAXVAL processes forked by make(1), to 683146144Sharti * prevent a forkbomb from happening, in a dumb and mechanical way. 684146144Sharti * 685146144Sharti * Side Effects: 686228992Suqs * Creates or modifies environment variable MKLVL_ENVVAR via setenv(). 687138071Sjmallett */ 688138071Sjmallettstatic void 689138071Sjmallettcheck_make_level(void) 690138071Sjmallett{ 691138071Sjmallett#ifdef WANT_ENV_MKLVL 692138071Sjmallett char *value = getenv(MKLVL_ENVVAR); 693138071Sjmallett int level = (value == NULL) ? 0 : atoi(value); 694138071Sjmallett 695138071Sjmallett if (level < 0) { 696213493Simp errx(2, "Invalid value for recursion level (%d).", level); 697138071Sjmallett } else if (level > MKLVL_MAXVAL) { 698213493Simp errx(2, "Max recursion level (%d) exceeded.", MKLVL_MAXVAL); 699138071Sjmallett } else { 700138071Sjmallett char new_value[32]; 701138071Sjmallett sprintf(new_value, "%d", level + 1); 702138071Sjmallett setenv(MKLVL_ENVVAR, new_value, 1); 703138071Sjmallett } 704138071Sjmallett#endif /* WANT_ENV_MKLVL */ 705138071Sjmallett} 706138071Sjmallett 707144475Sharti/** 708167330Sfjoe * Main_AddSourceMakefile 709167330Sfjoe * Add a file to the list of source makefiles 710167330Sfjoe */ 711167330Sfjoevoid 712167330SfjoeMain_AddSourceMakefile(const char *name) 713167330Sfjoe{ 714167330Sfjoe 715167330Sfjoe Lst_AtEnd(&source_makefiles, estrdup(name)); 716167330Sfjoe} 717167330Sfjoe 718167330Sfjoe/** 719167330Sfjoe * Remake_Makefiles 720167330Sfjoe * Remake all the makefiles 721167330Sfjoe */ 722167330Sfjoestatic void 723167330SfjoeRemake_Makefiles(void) 724167330Sfjoe{ 725198199Sfjoe Lst cleanup; 726167330Sfjoe LstNode *ln; 727167330Sfjoe int error_cnt = 0; 728167330Sfjoe int remade_cnt = 0; 729167330Sfjoe 730167330Sfjoe Compat_InstallSignalHandlers(); 731170179Sfjoe if (curdir != objdir) { 732170179Sfjoe if (chdir(curdir) < 0) 733170179Sfjoe Fatal("Failed to change directory to %s.", curdir); 734170179Sfjoe } 735167330Sfjoe 736198199Sfjoe Lst_Init(&cleanup); 737167330Sfjoe LST_FOREACH(ln, &source_makefiles) { 738167330Sfjoe LstNode *ln2; 739167330Sfjoe struct GNode *gn; 740167330Sfjoe const char *name = Lst_Datum(ln); 741167330Sfjoe Boolean saveTouchFlag = touchFlag; 742167330Sfjoe Boolean saveQueryFlag = queryFlag; 743167330Sfjoe Boolean saveNoExecute = noExecute; 744168892Sfjoe int mtime; 745167330Sfjoe 746167330Sfjoe /* 747167330Sfjoe * Create node 748167330Sfjoe */ 749167330Sfjoe gn = Targ_FindNode(name, TARG_CREATE); 750167330Sfjoe DEBUGF(MAKE, ("Checking %s...", gn->name)); 751167330Sfjoe Suff_FindDeps(gn); 752167330Sfjoe 753167330Sfjoe /* 754167330Sfjoe * -t, -q and -n has no effect unless the makefile is 755167330Sfjoe * specified as one of the targets explicitly in the 756167330Sfjoe * command line 757167330Sfjoe */ 758167330Sfjoe LST_FOREACH(ln2, &create) { 759167330Sfjoe if (!strcmp(gn->name, Lst_Datum(ln2))) { 760167330Sfjoe /* found as a target */ 761167330Sfjoe break; 762167330Sfjoe } 763167330Sfjoe } 764167330Sfjoe if (ln2 == NULL) { 765167330Sfjoe touchFlag = FALSE; 766167330Sfjoe queryFlag = FALSE; 767167330Sfjoe noExecute = FALSE; 768167330Sfjoe } 769167330Sfjoe 770167330Sfjoe /* 771167330Sfjoe * Check and remake the makefile 772167330Sfjoe */ 773168892Sfjoe mtime = Dir_MTime(gn); 774190821Sfjoe remakingMakefiles = TRUE; 775167330Sfjoe Compat_Make(gn, gn); 776190821Sfjoe remakingMakefiles = FALSE; 777167330Sfjoe 778167330Sfjoe /* 779167330Sfjoe * Restore -t, -q and -n behaviour 780167330Sfjoe */ 781167330Sfjoe touchFlag = saveTouchFlag; 782167330Sfjoe queryFlag = saveQueryFlag; 783167330Sfjoe noExecute = saveNoExecute; 784167330Sfjoe 785167330Sfjoe /* 786167330Sfjoe * Compat_Make will leave the 'made' field of gn 787167330Sfjoe * in one of the following states: 788167330Sfjoe * UPTODATE gn was already up-to-date 789167330Sfjoe * MADE gn was recreated successfully 790167330Sfjoe * ERROR An error occurred while gn was being created 791167330Sfjoe * ABORTED gn was not remade because one of its inferiors 792167330Sfjoe * could not be made due to errors. 793167330Sfjoe */ 794168892Sfjoe if (gn->made == MADE) { 795168892Sfjoe if (mtime != Dir_MTime(gn)) { 796168892Sfjoe DEBUGF(MAKE, 797168892Sfjoe ("%s updated (%d -> %d).\n", 798168892Sfjoe gn->name, mtime, gn->mtime)); 799168892Sfjoe remade_cnt++; 800168892Sfjoe } else { 801168892Sfjoe DEBUGF(MAKE, 802168892Sfjoe ("%s not updated: skipping restart.\n", 803168892Sfjoe gn->name)); 804168892Sfjoe } 805168892Sfjoe } else if (gn->made == ERROR) 806167330Sfjoe error_cnt++; 807167330Sfjoe else if (gn->made == ABORTED) { 808167330Sfjoe printf("`%s' not remade because of errors.\n", 809167330Sfjoe gn->name); 810167330Sfjoe error_cnt++; 811173919Sfjoe } else if (gn->made == UPTODATE) { 812198199Sfjoe Lst_EnQueue(&cleanup, gn); 813167330Sfjoe } 814167330Sfjoe } 815167330Sfjoe 816167330Sfjoe if (error_cnt > 0) 817167330Sfjoe Fatal("Failed to remake Makefiles."); 818167330Sfjoe if (remade_cnt > 0) { 819167330Sfjoe DEBUGF(MAKE, ("Restarting `%s'.\n", save_argv[0])); 820167330Sfjoe 821167330Sfjoe /* 822167330Sfjoe * Some of makefiles were remade -- restart from clean state 823167330Sfjoe */ 824167330Sfjoe if (save_makeflags != NULL) 825167330Sfjoe setenv("MAKEFLAGS", save_makeflags, 1); 826167330Sfjoe else 827167330Sfjoe unsetenv("MAKEFLAGS"); 828167330Sfjoe if (execvp(save_argv[0], save_argv) < 0) { 829167330Sfjoe Fatal("Can't restart `%s': %s.", 830167330Sfjoe save_argv[0], strerror(errno)); 831167330Sfjoe } 832167330Sfjoe } 833170179Sfjoe 834198199Sfjoe while (!Lst_IsEmpty(&cleanup)) { 835198199Sfjoe GNode *gn = Lst_DeQueue(&cleanup); 836198199Sfjoe 837198199Sfjoe gn->unmade = 0; 838198199Sfjoe gn->make = FALSE; 839198199Sfjoe gn->made = UNMADE; 840198199Sfjoe gn->childMade = FALSE; 841198199Sfjoe gn->mtime = gn->cmtime = 0; 842198199Sfjoe gn->cmtime_gn = NULL; 843198199Sfjoe 844198199Sfjoe LST_FOREACH(ln, &gn->children) { 845198199Sfjoe GNode *cgn = Lst_Datum(ln); 846198199Sfjoe 847198199Sfjoe gn->unmade++; 848198199Sfjoe Lst_EnQueue(&cleanup, cgn); 849198199Sfjoe } 850198199Sfjoe } 851198199Sfjoe 852170179Sfjoe if (curdir != objdir) { 853170179Sfjoe if (chdir(objdir) < 0) 854170179Sfjoe Fatal("Failed to change directory to %s.", objdir); 855170179Sfjoe } 856167330Sfjoe} 857167330Sfjoe 858167330Sfjoe/** 859144475Sharti * main 8601590Srgrimes * The main function, for obvious reasons. Initializes variables 8611590Srgrimes * and a few modules, then parses the arguments give it in the 8621590Srgrimes * environment and on the command line. Reads the system makefile 8631590Srgrimes * followed by either Makefile, makefile or the file given by the 8641590Srgrimes * -f argument. Sets the .MAKEFLAGS PMake variable based on all the 8651590Srgrimes * flags it has received by then uses either the Make or the Compat 8661590Srgrimes * module to create the initial list of targets. 8671590Srgrimes * 8681590Srgrimes * Results: 8691590Srgrimes * If -q was given, exits -1 if anything was out-of-date. Else it exits 8701590Srgrimes * 0. 8711590Srgrimes * 8721590Srgrimes * Side Effects: 8731590Srgrimes * The program exits when done. Targets are created. etc. etc. etc. 8741590Srgrimes */ 8751590Srgrimesint 876104696Sjmallettmain(int argc, char **argv) 8771590Srgrimes{ 878160442Sobrien const char *machine; 879146144Sharti const char *machine_arch; 880146144Sharti const char *machine_cpu; 881160442Sobrien Boolean outOfDate = TRUE; /* FALSE if all targets up to date */ 882146581Sharti const char *p; 883146157Sharti const char *pathp; 884146157Sharti const char *path; 88573262Simp char mdpath[MAXPATHLEN]; 88673262Simp char obpath[MAXPATHLEN]; 88773262Simp char cdpath[MAXPATHLEN]; 888201526Sobrien char found_dir[MAXPATHLEN + 1]; /* for searching for sys.mk */ 88918730Ssteve char *cp = NULL, *start; 890141252Sharti 891167330Sfjoe save_argv = argv; 892167330Sfjoe save_makeflags = getenv("MAKEFLAGS"); 893167330Sfjoe if (save_makeflags != NULL) 894167330Sfjoe save_makeflags = estrdup(save_makeflags); 895167330Sfjoe 896146146Sharti /* 897146146Sharti * Initialize file global variables. 898146146Sharti */ 899146146Sharti expandVars = TRUE; 900146146Sharti noBuiltins = FALSE; /* Read the built-in rules */ 901160442Sobrien forceJobs = FALSE; /* No -j flag */ 902146146Sharti curdir = cdpath; 903146146Sharti 904146146Sharti /* 905146146Sharti * Initialize program global variables. 906146146Sharti */ 907146146Sharti beSilent = FALSE; /* Print commands as executed */ 908146146Sharti ignoreErrors = FALSE; /* Pay attention to non-zero returns */ 909146146Sharti noExecute = FALSE; /* Execute all commands */ 910181021Sed printGraphOnly = FALSE; /* Don't stop after printing graph */ 911146146Sharti keepgoing = FALSE; /* Stop on error */ 912146146Sharti allPrecious = FALSE; /* Remove targets when interrupted */ 913146146Sharti queryFlag = FALSE; /* This is not just a check-run */ 914146146Sharti touchFlag = FALSE; /* Actually update targets */ 915146146Sharti usePipes = TRUE; /* Catch child output in pipes */ 916146146Sharti debug = 0; /* No debug verbosity, please. */ 917146146Sharti jobsRunning = FALSE; 918146146Sharti 919146146Sharti jobLimit = DEFMAXJOBS; 920146146Sharti compatMake = FALSE; /* No compat mode */ 921146146Sharti 922138071Sjmallett check_make_level(); 923104395Sjmallett 92418730Ssteve#ifdef RLIMIT_NOFILE 9251590Srgrimes /* 92618730Ssteve * get rid of resource limit on file descriptors 92718730Ssteve */ 92818730Ssteve { 92918730Ssteve struct rlimit rl; 930146144Sharti if (getrlimit(RLIMIT_NOFILE, &rl) == -1) { 931146144Sharti err(2, "getrlimit"); 93218730Ssteve } 933146144Sharti rl.rlim_cur = rl.rlim_max; 934146144Sharti if (setrlimit(RLIMIT_NOFILE, &rl) == -1) { 935146144Sharti err(2, "setrlimit"); 936146144Sharti } 93718730Ssteve } 93818730Ssteve#endif 9391590Srgrimes 9405814Sjkh /* 9415814Sjkh * Get the name of this type of MACHINE from utsname 9425814Sjkh * so we can share an executable for similar machines. 9435814Sjkh * (i.e. m68k: amiga hp300, mac68k, sun3, ...) 9445814Sjkh * 945153115Sru * Note that both MACHINE and MACHINE_ARCH are decided at 946153115Sru * run-time. 9475814Sjkh */ 948213494Simp if ((machine = getenv("MACHINE")) == NULL) { 949144475Sharti static struct utsname utsname; 950230392Srmh unsigned int i; 95118730Ssteve 952144475Sharti if (uname(&utsname) == -1) 953144475Sharti err(2, "uname"); 954144475Sharti machine = utsname.machine; 955230392Srmh 956230392Srmh /* Canonicalize non-FreeBSD naming conventions */ 957230392Srmh for (i = 0; i < sizeof(arch_aliases) 958230392Srmh / sizeof(arch_aliases[0]); i++) 959230392Srmh if (!strcmp(machine, arch_aliases[i].foreign_name)) { 960230392Srmh machine = arch_aliases[i].freebsd_name; 961230392Srmh break; 962230392Srmh } 9635814Sjkh } 9641590Srgrimes 965146144Sharti if ((machine_arch = getenv("MACHINE_ARCH")) == NULL) { 966146144Sharti#ifdef MACHINE_ARCH 967146144Sharti machine_arch = MACHINE_ARCH; 968146144Sharti#else 96944362Simp machine_arch = "unknown"; 97044362Simp#endif 97144362Simp } 97244362Simp 9731590Srgrimes /* 974228992Suqs * Set machine_cpu to the minimum supported CPU revision based 97572679Skris * on the target architecture, if not already set. 97672679Skris */ 977146144Sharti if ((machine_cpu = getenv("MACHINE_CPU")) == NULL) { 97872679Skris if (!strcmp(machine_arch, "i386")) 979243831Sjkim machine_cpu = "i486"; 98072679Skris else 98172679Skris machine_cpu = "unknown"; 98272679Skris } 9831590Srgrimes 9841590Srgrimes /* 9851590Srgrimes * Initialize the parsing, directory and variable modules to prepare 9861590Srgrimes * for the reading of inclusion paths and variable settings on the 9871590Srgrimes * command line 9881590Srgrimes */ 989146144Sharti Proc_Init(); 990146144Sharti 9911590Srgrimes Dir_Init(); /* Initialize directory structures so -I flags 9921590Srgrimes * can be processed correctly */ 993145971Sharti Var_Init(environ); /* As well as the lists of variables for 9941590Srgrimes * parsing arguments */ 995146560Sharti 9961590Srgrimes /* 997146560Sharti * Initialize the Shell so that we have a shell for != assignments 998146560Sharti * on the command line. 999146560Sharti */ 1000146560Sharti Shell_Init(); 1001146560Sharti 1002146560Sharti /* 10031590Srgrimes * Initialize various variables. 10041590Srgrimes * MAKE also gets this name, for compatibility 10051590Srgrimes * .MAKEFLAGS gets set to the empty string just in case. 10061590Srgrimes * MFLAGS also gets initialized empty, for compatibility. 10071590Srgrimes */ 1008146145Sharti Var_SetGlobal("MAKE", argv[0]); 1009146146Sharti Var_SetGlobal(".MAKEFLAGS", ""); 1010146145Sharti Var_SetGlobal("MFLAGS", ""); 1011146145Sharti Var_SetGlobal("MACHINE", machine); 1012146145Sharti Var_SetGlobal("MACHINE_ARCH", machine_arch); 1013146145Sharti Var_SetGlobal("MACHINE_CPU", machine_cpu); 101497121Sru#ifdef MAKE_VERSION 1015146145Sharti Var_SetGlobal("MAKE_VERSION", MAKE_VERSION); 101697121Sru#endif 1017186559Sobrien Var_SetGlobal(".newline", "\n"); /* handy for :@ loops */ 1018186559Sobrien { 1019186559Sobrien char tmp[64]; 10201590Srgrimes 1021186559Sobrien snprintf(tmp, sizeof(tmp), "%u", getpid()); 1022186559Sobrien Var_SetGlobal(".MAKE.PID", tmp); 1023186559Sobrien snprintf(tmp, sizeof(tmp), "%u", getppid()); 1024186559Sobrien Var_SetGlobal(".MAKE.PPID", tmp); 1025186559Sobrien } 1026186559Sobrien Job_SetPrefix(); 1027186559Sobrien 10281590Srgrimes /* 1029201526Sobrien * Find where we are... 1030201526Sobrien */ 1031201526Sobrien if (getcwd(curdir, MAXPATHLEN) == NULL) 1032201526Sobrien err(2, NULL); 1033201526Sobrien 1034201526Sobrien /* 1035144896Sharti * First snag things out of the MAKEFLAGS environment 1036144896Sharti * variable. Then parse the command line arguments. 10371590Srgrimes */ 1038140870Sharti Main_ParseArgLine(getenv("MAKEFLAGS"), 1); 10398874Srgrimes 10401590Srgrimes MainParseArgs(argc, argv); 10411590Srgrimes 10421590Srgrimes /* 1043201526Sobrien * Verify that cwd is sane (after -C may have changed it). 1044120053Sru */ 1045141252Sharti { 1046141252Sharti struct stat sa; 1047141252Sharti 1048120053Sru if (stat(curdir, &sa) == -1) 1049120053Sru err(2, "%s", curdir); 1050141252Sharti } 1051120053Sru 1052120053Sru /* 1053120053Sru * The object directory location is determined using the 1054120053Sru * following order of preference: 1055120053Sru * 1056120053Sru * 1. MAKEOBJDIRPREFIX`cwd` 1057120053Sru * 2. MAKEOBJDIR 1058143412Sharti * 3. PATH_OBJDIR.${MACHINE} 1059143412Sharti * 4. PATH_OBJDIR 1060143412Sharti * 5. PATH_OBJDIRPREFIX`cwd` 1061120053Sru * 1062120053Sru * If one of the first two fails, use the current directory. 1063120053Sru * If the remaining three all fail, use the current directory. 1064120053Sru * 1065120053Sru * Once things are initted, 1066120053Sru * have to add the original directory to the search path, 1067228992Suqs * and modify the paths for the Makefiles appropriately. The 1068120053Sru * current directory is also placed as a variable for make scripts. 1069120053Sru */ 1070120053Sru if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) { 1071120053Sru if (!(path = getenv("MAKEOBJDIR"))) { 1072143412Sharti path = PATH_OBJDIR; 1073143412Sharti pathp = PATH_OBJDIRPREFIX; 1074146145Sharti snprintf(mdpath, MAXPATHLEN, "%s.%s", path, machine); 1075120053Sru if (!(objdir = chdir_verify_path(mdpath, obpath))) 1076120053Sru if (!(objdir=chdir_verify_path(path, obpath))) { 1077138232Sharti snprintf(mdpath, MAXPATHLEN, 1078120053Sru "%s%s", pathp, curdir); 1079120053Sru if (!(objdir=chdir_verify_path(mdpath, 1080120053Sru obpath))) 1081120053Sru objdir = curdir; 1082120053Sru } 1083120053Sru } 1084120053Sru else if (!(objdir = chdir_verify_path(path, obpath))) 1085120053Sru objdir = curdir; 1086120053Sru } 1087120053Sru else { 1088138232Sharti snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir); 1089120053Sru if (!(objdir = chdir_verify_path(mdpath, obpath))) 1090120053Sru objdir = curdir; 1091120053Sru } 1092120053Sru Dir_InitDot(); /* Initialize the "." directory */ 1093120053Sru if (objdir != curdir) 1094144020Sharti Path_AddDir(&dirSearchPath, curdir); 1095146145Sharti Var_SetGlobal(".ST_EXPORTVAR", "YES"); 1096146145Sharti Var_SetGlobal(".CURDIR", curdir); 1097146145Sharti Var_SetGlobal(".OBJDIR", objdir); 1098120053Sru 1099137606Sphk if (getenv("MAKE_JOBS_FIFO") != NULL) 1100137606Sphk forceJobs = TRUE; 1101120053Sru /* 110228228Sfsmp * Be compatible if user did not specify -j and did not explicitly 110328228Sfsmp * turned compatibility on 110428228Sfsmp */ 110528228Sfsmp if (!compatMake && !forceJobs) 110628228Sfsmp compatMake = TRUE; 110728228Sfsmp 110828228Sfsmp /* 1109144387Sharti * Initialize target and suffix modules in preparation for 11101590Srgrimes * parsing the makefile(s) 11111590Srgrimes */ 11121590Srgrimes Targ_Init(); 11131590Srgrimes Suff_Init(); 11141590Srgrimes 111569527Swill DEFAULT = NULL; 1116138232Sharti time(&now); 11171590Srgrimes 11181590Srgrimes /* 11191590Srgrimes * Set up the .TARGETS variable to contain the list of targets to be 11201590Srgrimes * created. If none specified, make the variable empty -- the parser 11211590Srgrimes * will fill the thing in with the default or .MAIN target. 11221590Srgrimes */ 1123146145Sharti if (Lst_IsEmpty(&create)) { 1124146145Sharti Var_SetGlobal(".TARGETS", ""); 1125146145Sharti } else { 1126138512Sharti LstNode *ln; 11271590Srgrimes 1128138916Sharti for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) { 1129138264Sharti char *name = Lst_Datum(ln); 11301590Srgrimes 11311590Srgrimes Var_Append(".TARGETS", name, VAR_GLOBAL); 11321590Srgrimes } 1133146145Sharti } 11341590Srgrimes 113518730Ssteve 11361590Srgrimes /* 113718730Ssteve * If no user-supplied system path was given (through the -m option) 113818730Ssteve * add the directories from the DEFSYSPATH (more than one may be given 113918730Ssteve * as dir1:...:dirn) to the system include path. 11401590Srgrimes */ 1141144020Sharti if (TAILQ_EMPTY(&sysIncPath)) { 1142201526Sobrien char defsyspath[] = PATH_DEFSYSPATH; 1143201526Sobrien char *syspath = getenv("MAKESYSPATH"); 1144146144Sharti 1145201526Sobrien /* 1146201526Sobrien * If no user-supplied system path was given (thru -m option) 1147201526Sobrien * add the directories from the DEFSYSPATH (more than one may 1148201526Sobrien * be given as dir1:...:dirn) to the system include path. 1149201526Sobrien */ 1150201526Sobrien if (syspath == NULL || *syspath == '\0') 1151201526Sobrien syspath = defsyspath; 1152201526Sobrien else 1153201526Sobrien syspath = estrdup(syspath); 1154201526Sobrien 115518730Ssteve for (start = syspath; *start != '\0'; start = cp) { 115618730Ssteve for (cp = start; *cp != '\0' && *cp != ':'; cp++) 115718730Ssteve continue; 1158201526Sobrien if (*cp == ':') { 1159201526Sobrien *cp++ = '\0'; 1160201526Sobrien } 1161201526Sobrien /* look for magic parent directory search string */ 1162201526Sobrien if (strncmp(".../", start, 4) == 0) { 1163201526Sobrien if (Dir_FindHereOrAbove(curdir, start + 4, 1164201526Sobrien found_dir, sizeof(found_dir))) { 1165201526Sobrien Path_AddDir(&sysIncPath, found_dir); 1166201526Sobrien } 116718730Ssteve } else { 1168144020Sharti Path_AddDir(&sysIncPath, start); 116918730Ssteve } 117018730Ssteve } 1171201526Sobrien if (syspath != defsyspath) 1172201526Sobrien free(syspath); 117318730Ssteve } 11741590Srgrimes 117518730Ssteve /* 117618730Ssteve * Read in the built-in rules first, followed by the specified 117718730Ssteve * makefile, if it was (makefile != (char *) NULL), or the default 117818730Ssteve * Makefile and makefile, in that order, if it wasn't. 117918730Ssteve */ 118018730Ssteve if (!noBuiltins) { 1181138916Sharti /* Path of sys.mk */ 1182138916Sharti Lst sysMkPath = Lst_Initializer(sysMkPath); 1183138512Sharti LstNode *ln; 1184146064Sharti char defsysmk[] = PATH_DEFSYSMK; 118518730Ssteve 1186146064Sharti Path_Expand(defsysmk, &sysIncPath, &sysMkPath); 1187138916Sharti if (Lst_IsEmpty(&sysMkPath)) 1188143412Sharti Fatal("make: no system rules (%s).", PATH_DEFSYSMK); 1189143808Sharti LST_FOREACH(ln, &sysMkPath) { 1190143808Sharti if (!ReadMakefile(Lst_Datum(ln))) 1191143808Sharti break; 1192143808Sharti } 119369527Swill if (ln != NULL) 119418730Ssteve Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 1195138916Sharti Lst_Destroy(&sysMkPath, free); 119618730Ssteve } 119718730Ssteve 1198138916Sharti if (!Lst_IsEmpty(&makefiles)) { 1199138512Sharti LstNode *ln; 12001590Srgrimes 1201143808Sharti LST_FOREACH(ln, &makefiles) { 1202167330Sfjoe if (!TryReadMakefile(Lst_Datum(ln))) 1203143808Sharti break; 1204143808Sharti } 120569527Swill if (ln != NULL) 12061590Srgrimes Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 1207167330Sfjoe } else if (!TryReadMakefile("BSDmakefile")) 1208167330Sfjoe if (!TryReadMakefile("makefile")) 1209167330Sfjoe TryReadMakefile("Makefile"); 12101590Srgrimes 1211143808Sharti ReadMakefile(".depend"); 12121590Srgrimes 1213176842Syar /* Install all the flags into the MAKEFLAGS envariable. */ 1214146580Sharti if (((p = Var_Value(".MAKEFLAGS", VAR_GLOBAL)) != NULL) && *p) 12151590Srgrimes setenv("MAKEFLAGS", p, 1); 1216176839Syar else 1217176839Syar setenv("MAKEFLAGS", "", 1); 12181590Srgrimes 12191590Srgrimes /* 12201590Srgrimes * For compatibility, look at the directories in the VPATH variable 12211590Srgrimes * and add them to the search path, if the variable is defined. The 12221590Srgrimes * variable's value is in the same format as the PATH envariable, i.e. 12231590Srgrimes * <directory>:<directory>:<directory>... 12241590Srgrimes */ 12251590Srgrimes if (Var_Exists("VPATH", VAR_CMD)) { 12261590Srgrimes /* 12271590Srgrimes * GCC stores string constants in read-only memory, but 12281590Srgrimes * Var_Subst will want to write this thing, so store it 12291590Srgrimes * in an array 12301590Srgrimes */ 12311590Srgrimes static char VPATH[] = "${VPATH}"; 1232142457Sharti Buffer *buf; 1233142457Sharti char *vpath; 1234142457Sharti char *ptr; 1235142457Sharti char savec; 12361590Srgrimes 1237146027Sharti buf = Var_Subst(VPATH, VAR_CMD, FALSE); 1238142457Sharti 1239143959Sharti vpath = Buf_Data(buf); 12401590Srgrimes do { 12411590Srgrimes /* skip to end of directory */ 1242142457Sharti for (ptr = vpath; *ptr != ':' && *ptr != '\0'; ptr++) 1243141969Sharti ; 1244141969Sharti 12451590Srgrimes /* Save terminator character so know when to stop */ 1246141969Sharti savec = *ptr; 1247141969Sharti *ptr = '\0'; 1248141969Sharti 12491590Srgrimes /* Add directory to search path */ 1250144020Sharti Path_AddDir(&dirSearchPath, vpath); 1251141969Sharti 1252142457Sharti vpath = ptr + 1; 1253141969Sharti } while (savec != '\0'); 1254142457Sharti 1255142457Sharti Buf_Destroy(buf, TRUE); 12561590Srgrimes } 12571590Srgrimes 12581590Srgrimes /* 12591590Srgrimes * Now that all search paths have been read for suffixes et al, it's 12601590Srgrimes * time to add the default search path to their lists... 12611590Srgrimes */ 12621590Srgrimes Suff_DoPaths(); 12631590Srgrimes 12641590Srgrimes /* print the initial graph, if the user requested it */ 12651590Srgrimes if (DEBUG(GRAPH1)) 12661590Srgrimes Targ_PrintGraph(1); 12671590Srgrimes 126817193Sbde /* print the values of any variables requested by the user */ 1269181021Sed if (Lst_IsEmpty(&variables) && !printGraphOnly) { 12701590Srgrimes /* 1271141974Sharti * Since the user has not requested that any variables 1272142008Sharti * be printed, we can build targets. 1273141974Sharti * 1274142008Sharti * Have read the entire graph and need to make a list of targets 1275141974Sharti * to create. If none was given on the command line, we consult 1276141974Sharti * the parsing module to find the main target(s) to create. 12771590Srgrimes */ 1278138916Sharti Lst targs = Lst_Initializer(targs); 1279138916Sharti 1280177101Sobrien if (!is_posix && mfAutoDeps) { 1281167330Sfjoe /* 1282167330Sfjoe * Check if any of the makefiles are out-of-date. 1283167330Sfjoe */ 1284167330Sfjoe Remake_Makefiles(); 1285167330Sfjoe } 1286167330Sfjoe 1287138916Sharti if (Lst_IsEmpty(&create)) 1288138916Sharti Parse_MainName(&targs); 1289101460Sru else 1290138916Sharti Targ_FindList(&targs, &create, TARG_CREATE); 1291101460Sru 1292141974Sharti if (compatMake) { 1293101460Sru /* 1294141974Sharti * Compat_Init will take care of creating 1295141974Sharti * all the targets as well as initializing 1296141974Sharti * the module. 1297101460Sru */ 1298141974Sharti Compat_Run(&targs); 1299141974Sharti outOfDate = 0; 1300141974Sharti } else { 1301141974Sharti /* 1302141974Sharti * Initialize job module before traversing 1303141974Sharti * the graph, now that any .BEGIN and .END 1304141974Sharti * targets have been read. This is done 1305141974Sharti * only if the -q flag wasn't given (to 1306141974Sharti * prevent the .BEGIN from being executed 1307141974Sharti * should it exist). 1308141974Sharti */ 1309101460Sru if (!queryFlag) { 1310146140Sharti Job_Init(jobLimit); 1311101460Sru jobsRunning = TRUE; 1312101460Sru } 1313101460Sru 1314101460Sru /* Traverse the graph, checking on all the targets */ 1315138916Sharti outOfDate = Make_Run(&targs); 13161590Srgrimes } 1317138916Sharti Lst_Destroy(&targs, NOFREE); 1318141974Sharti 1319141974Sharti } else { 1320146141Sharti Var_Print(&variables, expandVars); 132117193Sbde } 13228874Srgrimes 1323138920Sru Lst_Destroy(&variables, free); 1324138920Sru Lst_Destroy(&makefiles, free); 1325167330Sfjoe Lst_Destroy(&source_makefiles, free); 1326138916Sharti Lst_Destroy(&create, free); 13275814Sjkh 13281590Srgrimes /* print the graph now it's been processed if the user requested it */ 13291590Srgrimes if (DEBUG(GRAPH2)) 13301590Srgrimes Targ_PrintGraph(2); 13311590Srgrimes 1332186279Sfjoe if (queryFlag) 1333186279Sfjoe return (outOfDate); 1334186279Sfjoe 1335186279Sfjoe if (makeErrors != 0) 1336186279Sfjoe Finish(makeErrors); 1337186279Sfjoe 1338186279Sfjoe return (0); 13391590Srgrimes} 1340