main.c revision 145971
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 145971 2005-05-06 18:30:06Z harti $"); 501590Srgrimes 51144475Sharti/* 52144475Sharti * main.c 531590Srgrimes * The main file for this entire program. Exit routines etc 541590Srgrimes * reside here. 551590Srgrimes * 561590Srgrimes * Utility functions defined in this file: 57144475Sharti * Main_ParseArgLine 58144475Sharti * Takes a line of arguments, breaks them and 59144475Sharti * treats them as if they were given when first 60144475Sharti * invoked. Used by the parse module to implement 61144475Sharti * the .MFLAGS target. 621590Srgrimes */ 631590Srgrimes 64141104Sharti#ifndef MACHINE 65141104Sharti#include <sys/utsname.h> 66141104Sharti#endif 671590Srgrimes#include <sys/param.h> 681590Srgrimes#include <sys/stat.h> 6939006Skato#include <sys/sysctl.h> 70127880Sdes#include <sys/time.h> 71144020Sharti#include <sys/queue.h> 72127899Sru#include <sys/resource.h> 7318730Ssteve#include <sys/wait.h> 7427644Scharnier#include <err.h> 751590Srgrimes#include <errno.h> 76127880Sdes#include <signal.h> 77127880Sdes#include <stdlib.h> 78141104Sharti#include <string.h> 7963955Simp#include <unistd.h> 80127880Sdes 81141104Sharti#include "arch.h" 82141133Sharti#include "buf.h" 83141104Sharti#include "compat.h" 84141104Sharti#include "config.h" 851590Srgrimes#include "dir.h" 86141104Sharti#include "globals.h" 871590Srgrimes#include "job.h" 88141104Sharti#include "make.h" 89141104Sharti#include "nonints.h" 90141104Sharti#include "parse.h" 911590Srgrimes#include "pathnames.h" 92141104Sharti#include "str.h" 93141104Sharti#include "suff.h" 94141104Sharti#include "targ.h" 95141104Sharti#include "util.h" 96141104Sharti#include "var.h" 971590Srgrimes 98104395Sjmallett#define WANT_ENV_MKLVL 1 99138071Sjmallett#define MKLVL_MAXVAL 500 100138071Sjmallett#define MKLVL_ENVVAR "__MKLVL__" 101104395Sjmallett 1021590Srgrimes#define MAKEFLAGS ".MAKEFLAGS" 1031590Srgrimes 104145971Shartiextern char **environ; /* XXX what header declares this variable? */ 105145971Sharti 106138916Sharti/* Targets to be made */ 107138916ShartiLst create = Lst_Initializer(create); 108138916Sharti 109144475Shartitime_t now; /* Time at start of make */ 110144475Shartistruct GNode *DEFAULT; /* .DEFAULT node */ 111144475ShartiBoolean allPrecious; /* .PRECIOUS given on line by itself */ 112145679Shartiuint32_t warn_flags; /* actual warning flags */ 113145679Shartiuint32_t warn_cmd; /* command line warning flags */ 114145679Shartiuint32_t warn_nocmd; /* command line no-warning flags */ 1151590Srgrimes 116144475Shartistatic Boolean noBuiltins; /* -r flag */ 117138916Sharti 118138916Sharti/* ordered list of makefiles to read */ 119138916Shartistatic Lst makefiles = Lst_Initializer(makefiles); 120138916Sharti 121144475Shartistatic Boolean expandVars; /* fully expand printed variables */ 122138916Sharti 123138916Sharti/* list of variables to print */ 124138916Shartistatic Lst variables = Lst_Initializer(variables); 125138916Sharti 126144475Shartiint maxJobs; /* -j argument */ 127144475Shartistatic Boolean forceJobs; /* -j argument given */ 128144475ShartiBoolean compatMake; /* -B argument */ 129144475ShartiBoolean debug; /* -d flag */ 130144475ShartiBoolean noExecute; /* -n flag */ 131144475ShartiBoolean keepgoing; /* -k flag */ 132144475ShartiBoolean queryFlag; /* -q flag */ 133144475ShartiBoolean touchFlag; /* -t flag */ 134144475ShartiBoolean usePipes; /* !-P flag */ 135144475ShartiBoolean ignoreErrors; /* -i flag */ 136144475ShartiBoolean beSilent; /* -s flag */ 137144475ShartiBoolean beVerbose; /* -v flag */ 138144475ShartiBoolean oldVars; /* variable substitution style */ 139144475ShartiBoolean checkEnvFirst; /* -e flag */ 140138916Sharti 141138916Sharti/* (-E) vars to override from env */ 142138916ShartiLst envFirstVars = Lst_Initializer(envFirstVars); 143138916Sharti 144144475ShartiBoolean jobsRunning; /* TRUE if the jobs might be running */ 1451590Srgrimes 146144475Shartichar *chdir_verify_path(const char *, char *); 147144475Shartistatic int ReadMakefile(const char *); 148144475Shartistatic void usage(void); 1491590Srgrimes 150144475Shartistatic char *curdir; /* startup directory */ 151144475Shartistatic char *objdir; /* where we chdir'ed to */ 1521590Srgrimes 153144475Sharti/** 154144475Sharti * MFLAGS_append 155144475Sharti * Append a flag with an optional argument to MAKEFLAGS and MFLAGS 156133085Sharti */ 157133085Shartistatic void 158141252ShartiMFLAGS_append(const char *flag, char *arg) 159133085Sharti{ 160140870Sharti char *str; 161138232Sharti 162133085Sharti Var_Append(MAKEFLAGS, flag, VAR_GLOBAL); 163140870Sharti if (arg != NULL) { 164140870Sharti str = MAKEFLAGS_quote(arg); 165140870Sharti Var_Append(MAKEFLAGS, str, VAR_GLOBAL); 166140870Sharti free(str); 167140870Sharti } 168133085Sharti 169133085Sharti Var_Append("MFLAGS", flag, VAR_GLOBAL); 170140870Sharti if (arg != NULL) { 171140870Sharti str = MAKEFLAGS_quote(arg); 172140870Sharti Var_Append("MFLAGS", str, VAR_GLOBAL); 173140870Sharti free(str); 174140870Sharti } 175133085Sharti} 176133085Sharti 177144475Sharti/** 178145679Sharti * Main_ParseWarn 179145679Sharti * 180145679Sharti * Handle argument to warning option. 181145679Sharti */ 182145679Shartiint 183145679ShartiMain_ParseWarn(const char *arg, int iscmd) 184145679Sharti{ 185145679Sharti int i, neg; 186145679Sharti 187145679Sharti static const struct { 188145679Sharti const char *option; 189145679Sharti uint32_t flag; 190145679Sharti } options[] = { 191145679Sharti { "dirsyntax", WARN_DIRSYNTAX }, 192145679Sharti { NULL, 0 } 193145679Sharti }; 194145679Sharti 195145679Sharti neg = 0; 196145679Sharti if (arg[0] == 'n' && arg[1] == 'o') { 197145679Sharti neg = 1; 198145679Sharti arg += 2; 199145679Sharti } 200145679Sharti 201145679Sharti for (i = 0; options[i].option != NULL; i++) 202145679Sharti if (strcmp(arg, options[i].option) == 0) 203145679Sharti break; 204145679Sharti 205145679Sharti if (options[i].option == NULL) 206145679Sharti /* unknown option */ 207145679Sharti return (-1); 208145679Sharti 209145679Sharti if (iscmd) { 210145679Sharti if (!neg) { 211145679Sharti warn_cmd |= options[i].flag; 212145679Sharti warn_nocmd &= ~options[i].flag; 213145679Sharti warn_flags |= options[i].flag; 214145679Sharti } else { 215145679Sharti warn_nocmd |= options[i].flag; 216145679Sharti warn_cmd &= ~options[i].flag; 217145679Sharti warn_flags &= ~options[i].flag; 218145679Sharti } 219145679Sharti } else { 220145679Sharti if (!neg) { 221145679Sharti warn_flags |= (options[i].flag & ~warn_nocmd); 222145679Sharti } else { 223145679Sharti warn_flags &= ~(options[i].flag | warn_cmd); 224145679Sharti } 225145679Sharti } 226145679Sharti return (0); 227145679Sharti} 228145679Sharti 229145679Sharti/** 230144475Sharti * MainParseArgs 2311590Srgrimes * Parse a given argument vector. Called from main() and from 2321590Srgrimes * Main_ParseArgLine() when the .MAKEFLAGS target is used. 2331590Srgrimes * 2341590Srgrimes * XXX: Deal with command line overriding .MAKEFLAGS in makefile 2351590Srgrimes * 2361590Srgrimes * Side Effects: 2371590Srgrimes * Various global and local flags will be set depending on the flags 2381590Srgrimes * given 2391590Srgrimes */ 2401590Srgrimesstatic void 241104696SjmallettMainParseArgs(int argc, char **argv) 2421590Srgrimes{ 2435814Sjkh int c; 2441590Srgrimes 245144896Shartirearg: 2461590Srgrimes optind = 1; /* since we're called more than once */ 247144896Sharti optreset = 1; 248145627Sharti#define OPTFLAGS "ABC:D:E:I:PSV:Xd:ef:ij:km:nqrstvx:" 249144896Sharti while((c = getopt(argc, argv, OPTFLAGS)) != -1) { 2501590Srgrimes switch(c) { 251144387Sharti 252144387Sharti case 'A': 253144387Sharti arch_fatal = FALSE; 254144387Sharti MFLAGS_append("-A", NULL); 255144387Sharti break; 256102393Sjmallett case 'C': 257107964Sseanc if (chdir(optarg) == -1) 258107964Sseanc err(1, "chdir %s", optarg); 259102393Sjmallett break; 2601590Srgrimes case 'D': 2611590Srgrimes Var_Set(optarg, "1", VAR_GLOBAL); 262133085Sharti MFLAGS_append("-D", optarg); 2631590Srgrimes break; 2641590Srgrimes case 'I': 2651590Srgrimes Parse_AddIncludeDir(optarg); 266133085Sharti MFLAGS_append("-I", optarg); 2671590Srgrimes break; 26817193Sbde case 'V': 269138920Sru Lst_AtEnd(&variables, estrdup(optarg)); 270133085Sharti MFLAGS_append("-V", optarg); 27117193Sbde break; 27266365Speter case 'X': 27366365Speter expandVars = FALSE; 27466365Speter break; 2751590Srgrimes case 'B': 2761590Srgrimes compatMake = TRUE; 277133085Sharti MFLAGS_append("-B", NULL); 278137626Sphk unsetenv("MAKE_JOBS_FIFO"); 2791590Srgrimes break; 2801590Srgrimes case 'P': 2811590Srgrimes usePipes = FALSE; 282133085Sharti MFLAGS_append("-P", NULL); 2831590Srgrimes break; 2841590Srgrimes case 'S': 2851590Srgrimes keepgoing = FALSE; 286133085Sharti MFLAGS_append("-S", NULL); 2871590Srgrimes break; 2881590Srgrimes case 'd': { 2891590Srgrimes char *modules = optarg; 2901590Srgrimes 2911590Srgrimes for (; *modules; ++modules) 2921590Srgrimes switch (*modules) { 2931590Srgrimes case 'A': 2941590Srgrimes debug = ~0; 2951590Srgrimes break; 2961590Srgrimes case 'a': 2971590Srgrimes debug |= DEBUG_ARCH; 2981590Srgrimes break; 2991590Srgrimes case 'c': 3001590Srgrimes debug |= DEBUG_COND; 3011590Srgrimes break; 3021590Srgrimes case 'd': 3031590Srgrimes debug |= DEBUG_DIR; 3041590Srgrimes break; 3051590Srgrimes case 'f': 3061590Srgrimes debug |= DEBUG_FOR; 3071590Srgrimes break; 3081590Srgrimes case 'g': 3091590Srgrimes if (modules[1] == '1') { 3101590Srgrimes debug |= DEBUG_GRAPH1; 3111590Srgrimes ++modules; 3121590Srgrimes } 3131590Srgrimes else if (modules[1] == '2') { 3141590Srgrimes debug |= DEBUG_GRAPH2; 3151590Srgrimes ++modules; 3161590Srgrimes } 3171590Srgrimes break; 3181590Srgrimes case 'j': 3191590Srgrimes debug |= DEBUG_JOB; 3201590Srgrimes break; 32160569Swill case 'l': 32260569Swill debug |= DEBUG_LOUD; 32360569Swill break; 3241590Srgrimes case 'm': 3251590Srgrimes debug |= DEBUG_MAKE; 3261590Srgrimes break; 3271590Srgrimes case 's': 3281590Srgrimes debug |= DEBUG_SUFF; 3291590Srgrimes break; 3301590Srgrimes case 't': 3311590Srgrimes debug |= DEBUG_TARG; 3321590Srgrimes break; 3331590Srgrimes case 'v': 3341590Srgrimes debug |= DEBUG_VAR; 3351590Srgrimes break; 3361590Srgrimes default: 337144475Sharti warnx("illegal argument to d option " 338144475Sharti "-- %c", *modules); 3391590Srgrimes usage(); 3401590Srgrimes } 341133085Sharti MFLAGS_append("-d", optarg); 3421590Srgrimes break; 3431590Srgrimes } 34449332Shoek case 'E': 345138920Sru Lst_AtEnd(&envFirstVars, estrdup(optarg)); 346133085Sharti MFLAGS_append("-E", optarg); 34749332Shoek break; 3481590Srgrimes case 'e': 3491590Srgrimes checkEnvFirst = TRUE; 350133085Sharti MFLAGS_append("-e", NULL); 3511590Srgrimes break; 3521590Srgrimes case 'f': 353138920Sru Lst_AtEnd(&makefiles, estrdup(optarg)); 3541590Srgrimes break; 3551590Srgrimes case 'i': 3561590Srgrimes ignoreErrors = TRUE; 357133085Sharti MFLAGS_append("-i", NULL); 3581590Srgrimes break; 35949331Shoek case 'j': { 36049331Shoek char *endptr; 36149331Shoek 36218730Ssteve forceJobs = TRUE; 36349331Shoek maxJobs = strtol(optarg, &endptr, 10); 36449331Shoek if (maxJobs <= 0 || *endptr != '\0') { 36549938Shoek warnx("illegal number, -j argument -- %s", 36649938Shoek optarg); 36749938Shoek usage(); 36849331Shoek } 369133085Sharti MFLAGS_append("-j", optarg); 3701590Srgrimes break; 37149331Shoek } 3721590Srgrimes case 'k': 3731590Srgrimes keepgoing = TRUE; 374133085Sharti MFLAGS_append("-k", NULL); 3751590Srgrimes break; 37618730Ssteve case 'm': 377144020Sharti Path_AddDir(&sysIncPath, optarg); 378133085Sharti MFLAGS_append("-m", optarg); 37918730Ssteve break; 3801590Srgrimes case 'n': 3811590Srgrimes noExecute = TRUE; 382133085Sharti MFLAGS_append("-n", NULL); 3831590Srgrimes break; 3841590Srgrimes case 'q': 3851590Srgrimes queryFlag = TRUE; 3861590Srgrimes /* Kind of nonsensical, wot? */ 387133085Sharti MFLAGS_append("-q", NULL); 3881590Srgrimes break; 3891590Srgrimes case 'r': 3901590Srgrimes noBuiltins = TRUE; 391133085Sharti MFLAGS_append("-r", NULL); 3921590Srgrimes break; 3931590Srgrimes case 's': 3941590Srgrimes beSilent = TRUE; 395133085Sharti MFLAGS_append("-s", NULL); 3961590Srgrimes break; 3971590Srgrimes case 't': 3981590Srgrimes touchFlag = TRUE; 399133085Sharti MFLAGS_append("-t", NULL); 4001590Srgrimes break; 40141151Sdg case 'v': 40241151Sdg beVerbose = TRUE; 403133085Sharti MFLAGS_append("-v", NULL); 40441151Sdg break; 405145627Sharti case 'x': 406145679Sharti if (Main_ParseWarn(optarg, 1) != -1) 407145627Sharti MFLAGS_append("-x", optarg); 408145627Sharti break; 409145627Sharti 4101590Srgrimes default: 4111590Srgrimes case '?': 4121590Srgrimes usage(); 4131590Srgrimes } 4141590Srgrimes } 415144896Sharti argv += optind; 416144896Sharti argc -= optind; 4171590Srgrimes 4181590Srgrimes oldVars = TRUE; 4191590Srgrimes 4201590Srgrimes /* 421144896Sharti * Parse the rest of the arguments. 422144896Sharti * o Check for variable assignments and perform them if so. 423144896Sharti * o Check for more flags and restart getopt if so. 424144896Sharti * o Anything else is taken to be a target and added 425144896Sharti * to the end of the "create" list. 4261590Srgrimes */ 427144896Sharti for (; *argv != NULL; ++argv, --argc) { 428133562Sharti if (Parse_IsVar(*argv)) { 429140870Sharti char *ptr = MAKEFLAGS_quote(*argv); 430133562Sharti 431133562Sharti Var_Append(MAKEFLAGS, ptr, VAR_GLOBAL); 432144896Sharti Parse_DoVar(*argv, VAR_CMD); 433133562Sharti free(ptr); 434133562Sharti 435144896Sharti } else if ((*argv)[0] == '-') { 436144896Sharti if ((*argv)[1] == '\0') { 437144896Sharti /* 438144896Sharti * (*argv) is a single dash, so we 439144896Sharti * just ignore it. 440144896Sharti */ 441144896Sharti } else { 442144896Sharti /* 443144896Sharti * (*argv) is a -flag, so backup argv 444144896Sharti * and argc, since getopt() expects 445144896Sharti * options to start in the 2nd position. 446144896Sharti */ 447144896Sharti argc++; 448144896Sharti argv--; 4491590Srgrimes goto rearg; 4501590Srgrimes } 451144896Sharti 452144896Sharti } else if ((*argv)[0] == '\0') { 453144896Sharti Punt("illegal (null) argument."); 454144896Sharti 455144896Sharti } else { 456138916Sharti Lst_AtEnd(&create, estrdup(*argv)); 4571590Srgrimes } 458144896Sharti } 4591590Srgrimes} 4601590Srgrimes 461144475Sharti/** 462144475Sharti * Main_ParseArgLine 4631590Srgrimes * Used by the parse module when a .MFLAGS or .MAKEFLAGS target 4641590Srgrimes * is encountered and by main() when reading the .MAKEFLAGS envariable. 4651590Srgrimes * Takes a line of arguments and breaks it into its 4661590Srgrimes * component words and passes those words and the number of them to the 4671590Srgrimes * MainParseArgs function. 4681590Srgrimes * The line should have all its leading whitespace removed. 4691590Srgrimes * 4701590Srgrimes * Side Effects: 4711590Srgrimes * Only those that come from the various arguments. 4721590Srgrimes */ 4731590Srgrimesvoid 474140870ShartiMain_ParseArgLine(char *line, int mflags) 4751590Srgrimes{ 4761590Srgrimes char **argv; /* Manufactured argument vector */ 4771590Srgrimes int argc; /* Number of arguments in argv */ 4781590Srgrimes 4791590Srgrimes if (line == NULL) 4801590Srgrimes return; 4811590Srgrimes for (; *line == ' '; ++line) 4821590Srgrimes continue; 4831590Srgrimes if (!*line) 4841590Srgrimes return; 4851590Srgrimes 486140870Sharti if (mflags) 487140870Sharti argv = MAKEFLAGS_break(line, &argc); 488140870Sharti else 489140870Sharti argv = brk_string(line, &argc, TRUE); 490140870Sharti 4911590Srgrimes MainParseArgs(argc, argv); 4921590Srgrimes} 4931590Srgrimes 49418339Sswallacechar * 495141252Shartichdir_verify_path(const char *path, char *obpath) 49618339Sswallace{ 49718339Sswallace struct stat sb; 49818339Sswallace 49918339Sswallace if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { 50075973Sru if (chdir(path) == -1 || getcwd(obpath, MAXPATHLEN) == NULL) { 50127644Scharnier warn("warning: %s", path); 502141252Sharti return (NULL); 50318339Sswallace } 504138232Sharti return (obpath); 50518339Sswallace } 50618339Sswallace 507141252Sharti return (NULL); 50818339Sswallace} 50918339Sswallace 510133082Shartistatic void 511133082Sharticatch_child(int sig __unused) 512123513Sdes{ 513123513Sdes} 51418339Sswallace 515138071Sjmallett/* 516138071Sjmallett * In lieu of a good way to prevent every possible looping in 517138071Sjmallett * make(1), stop there from being more than MKLVL_MAXVAL processes forked 518138071Sjmallett * by make(1), to prevent a forkbomb from happening, in a dumb and 519138071Sjmallett * mechanical way. 520138071Sjmallett */ 521138071Sjmallettstatic void 522138071Sjmallettcheck_make_level(void) 523138071Sjmallett{ 524138071Sjmallett#ifdef WANT_ENV_MKLVL 525138071Sjmallett char *value = getenv(MKLVL_ENVVAR); 526138071Sjmallett int level = (value == NULL) ? 0 : atoi(value); 527138071Sjmallett 528138071Sjmallett if (level < 0) { 529144475Sharti errc(2, EAGAIN, "Invalid value for recursion level (%d).", 530144475Sharti level); 531138071Sjmallett } else if (level > MKLVL_MAXVAL) { 532144475Sharti errc(2, EAGAIN, "Max recursion level (%d) exceeded.", 533144475Sharti MKLVL_MAXVAL); 534138071Sjmallett } else { 535138071Sjmallett char new_value[32]; 536138071Sjmallett sprintf(new_value, "%d", level + 1); 537138071Sjmallett setenv(MKLVL_ENVVAR, new_value, 1); 538138071Sjmallett } 539138071Sjmallett#endif /* WANT_ENV_MKLVL */ 540138071Sjmallett} 541138071Sjmallett 542144475Sharti/** 543144475Sharti * main 5441590Srgrimes * The main function, for obvious reasons. Initializes variables 5451590Srgrimes * and a few modules, then parses the arguments give it in the 5461590Srgrimes * environment and on the command line. Reads the system makefile 5471590Srgrimes * followed by either Makefile, makefile or the file given by the 5481590Srgrimes * -f argument. Sets the .MAKEFLAGS PMake variable based on all the 5491590Srgrimes * flags it has received by then uses either the Make or the Compat 5501590Srgrimes * module to create the initial list of targets. 5511590Srgrimes * 5521590Srgrimes * Results: 5531590Srgrimes * If -q was given, exits -1 if anything was out-of-date. Else it exits 5541590Srgrimes * 0. 5551590Srgrimes * 5561590Srgrimes * Side Effects: 5571590Srgrimes * The program exits when done. Targets are created. etc. etc. etc. 5581590Srgrimes */ 5591590Srgrimesint 560104696Sjmallettmain(int argc, char **argv) 5611590Srgrimes{ 5621590Srgrimes Boolean outOfDate = TRUE; /* FALSE if all targets up to date */ 563141252Sharti char *p, *p1, *pathp; 564141252Sharti char *path; 56573262Simp char mdpath[MAXPATHLEN]; 56673262Simp char obpath[MAXPATHLEN]; 56773262Simp char cdpath[MAXPATHLEN]; 568141252Sharti const char *machine = getenv("MACHINE"); 569141252Sharti const char *machine_arch = getenv("MACHINE_ARCH"); 570141252Sharti const char *machine_cpu = getenv("MACHINE_CPU"); 57118730Ssteve char *cp = NULL, *start; 572141252Sharti 573144475Sharti /* avoid faults on read-only strings */ 574143412Sharti static char syspath[] = PATH_DEFSYSPATH; 5751590Srgrimes 576123513Sdes { 577123513Sdes /* 578123513Sdes * Catch SIGCHLD so that we get kicked out of select() when we 579123513Sdes * need to look at a child. This is only known to matter for the 580123513Sdes * -j case (perhaps without -P). 581123513Sdes * 582123513Sdes * XXX this is intentionally misplaced. 583123513Sdes */ 584123513Sdes struct sigaction sa; 585123513Sdes 586123513Sdes sigemptyset(&sa.sa_mask); 587123513Sdes sa.sa_flags = SA_RESTART | SA_NOCLDSTOP; 588123513Sdes sa.sa_handler = catch_child; 589123513Sdes sigaction(SIGCHLD, &sa, NULL); 590123513Sdes } 591123513Sdes 592138071Sjmallett check_make_level(); 593104395Sjmallett 59464739Sgreen#if DEFSHELL == 2 59564739Sgreen /* 59664739Sgreen * Turn off ENV to make ksh happier. 59764739Sgreen */ 59864739Sgreen unsetenv("ENV"); 59964739Sgreen#endif 60064739Sgreen 60118730Ssteve#ifdef RLIMIT_NOFILE 6021590Srgrimes /* 60318730Ssteve * get rid of resource limit on file descriptors 60418730Ssteve */ 60518730Ssteve { 60618730Ssteve struct rlimit rl; 60718730Ssteve if (getrlimit(RLIMIT_NOFILE, &rl) != -1 && 60818730Ssteve rl.rlim_cur != rl.rlim_max) { 60918730Ssteve rl.rlim_cur = rl.rlim_max; 610138232Sharti setrlimit(RLIMIT_NOFILE, &rl); 61118730Ssteve } 61218730Ssteve } 61318730Ssteve#endif 6141590Srgrimes 6155814Sjkh /* 61639006Skato * PC-98 kernel sets the `i386' string to the utsname.machine and 61739006Skato * it cannot be distinguished from IBM-PC by uname(3). Therefore, 61839006Skato * we check machine.ispc98 and adjust the machine variable before 61939006Skato * using usname(3) below. 62053631Smarcel * NOTE: machdep.ispc98 was defined on 1998/8/31. At that time, 62153631Smarcel * __FreeBSD_version was defined as 300003. So, this check can 62253631Smarcel * safely be done with any kernel with version > 300003. 62339006Skato */ 62439006Skato if (!machine) { 62539006Skato int ispc98; 62639006Skato size_t len; 62739006Skato 62839006Skato len = sizeof(ispc98); 62939006Skato if (!sysctlbyname("machdep.ispc98", &ispc98, &len, NULL, 0)) { 63039006Skato if (ispc98) 63139006Skato machine = "pc98"; 63239006Skato } 63339006Skato } 63439006Skato 63539006Skato /* 6365814Sjkh * Get the name of this type of MACHINE from utsname 6375814Sjkh * so we can share an executable for similar machines. 6385814Sjkh * (i.e. m68k: amiga hp300, mac68k, sun3, ...) 6395814Sjkh * 6405814Sjkh * Note that while MACHINE is decided at run-time, 6415814Sjkh * MACHINE_ARCH is always known at compile time. 6425814Sjkh */ 64318864Ssteve if (!machine) { 64418339Sswallace#ifndef MACHINE 645144475Sharti static struct utsname utsname; 64618730Ssteve 647144475Sharti if (uname(&utsname) == -1) 648144475Sharti err(2, "uname"); 649144475Sharti machine = utsname.machine; 65018339Sswallace#else 651144475Sharti machine = MACHINE; 65218339Sswallace#endif 6535814Sjkh } 6541590Srgrimes 65544362Simp if (!machine_arch) { 65644362Simp#ifndef MACHINE_ARCH 65744362Simp machine_arch = "unknown"; 65844362Simp#else 65944362Simp machine_arch = MACHINE_ARCH; 66044362Simp#endif 66144362Simp } 66244362Simp 6631590Srgrimes /* 66472679Skris * Set machine_cpu to the minumum supported CPU revision based 66572679Skris * on the target architecture, if not already set. 66672679Skris */ 66772679Skris if (!machine_cpu) { 66872679Skris if (!strcmp(machine_arch, "i386")) 66972679Skris machine_cpu = "i386"; 67072679Skris else if (!strcmp(machine_arch, "alpha")) 67172679Skris machine_cpu = "ev4"; 67272679Skris else 67372679Skris machine_cpu = "unknown"; 67472679Skris } 6751590Srgrimes 67666365Speter expandVars = TRUE; 6771590Srgrimes beSilent = FALSE; /* Print commands as executed */ 6781590Srgrimes ignoreErrors = FALSE; /* Pay attention to non-zero returns */ 6791590Srgrimes noExecute = FALSE; /* Execute all commands */ 6801590Srgrimes keepgoing = FALSE; /* Stop on error */ 6811590Srgrimes allPrecious = FALSE; /* Remove targets when interrupted */ 6821590Srgrimes queryFlag = FALSE; /* This is not just a check-run */ 6831590Srgrimes noBuiltins = FALSE; /* Read the built-in rules */ 6841590Srgrimes touchFlag = FALSE; /* Actually update targets */ 6851590Srgrimes usePipes = TRUE; /* Catch child output in pipes */ 6861590Srgrimes debug = 0; /* No debug verbosity, please. */ 6871590Srgrimes jobsRunning = FALSE; 6881590Srgrimes 689137571Sphk maxJobs = DEFMAXJOBS; 69028228Sfsmp forceJobs = FALSE; /* No -j flag */ 69118730Ssteve compatMake = FALSE; /* No compat mode */ 6921590Srgrimes 6931590Srgrimes /* 6941590Srgrimes * Initialize the parsing, directory and variable modules to prepare 6951590Srgrimes * for the reading of inclusion paths and variable settings on the 6961590Srgrimes * command line 6971590Srgrimes */ 6981590Srgrimes Dir_Init(); /* Initialize directory structures so -I flags 6991590Srgrimes * can be processed correctly */ 700145971Sharti Var_Init(environ); /* As well as the lists of variables for 7011590Srgrimes * parsing arguments */ 7025814Sjkh str_init(); 7031590Srgrimes 7041590Srgrimes /* 7051590Srgrimes * Initialize various variables. 7061590Srgrimes * MAKE also gets this name, for compatibility 7071590Srgrimes * .MAKEFLAGS gets set to the empty string just in case. 7081590Srgrimes * MFLAGS also gets initialized empty, for compatibility. 7091590Srgrimes */ 7101590Srgrimes Var_Set("MAKE", argv[0], VAR_GLOBAL); 7111590Srgrimes Var_Set(MAKEFLAGS, "", VAR_GLOBAL); 7121590Srgrimes Var_Set("MFLAGS", "", VAR_GLOBAL); 7135814Sjkh Var_Set("MACHINE", machine, VAR_GLOBAL); 71444362Simp Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL); 71572679Skris Var_Set("MACHINE_CPU", machine_cpu, VAR_GLOBAL); 71697121Sru#ifdef MAKE_VERSION 71797121Sru Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL); 71897121Sru#endif 7191590Srgrimes 7201590Srgrimes /* 721144896Sharti * First snag things out of the MAKEFLAGS environment 722144896Sharti * variable. Then parse the command line arguments. 7231590Srgrimes */ 724140870Sharti Main_ParseArgLine(getenv("MAKEFLAGS"), 1); 7258874Srgrimes 7261590Srgrimes MainParseArgs(argc, argv); 7271590Srgrimes 7281590Srgrimes /* 729120053Sru * Find where we are... 730120053Sru */ 731120053Sru curdir = cdpath; 732120053Sru if (getcwd(curdir, MAXPATHLEN) == NULL) 733120053Sru err(2, NULL); 734120053Sru 735141252Sharti { 736141252Sharti struct stat sa; 737141252Sharti 738120053Sru if (stat(curdir, &sa) == -1) 739120053Sru err(2, "%s", curdir); 740141252Sharti } 741120053Sru 742120053Sru /* 743120053Sru * The object directory location is determined using the 744120053Sru * following order of preference: 745120053Sru * 746120053Sru * 1. MAKEOBJDIRPREFIX`cwd` 747120053Sru * 2. MAKEOBJDIR 748143412Sharti * 3. PATH_OBJDIR.${MACHINE} 749143412Sharti * 4. PATH_OBJDIR 750143412Sharti * 5. PATH_OBJDIRPREFIX`cwd` 751120053Sru * 752120053Sru * If one of the first two fails, use the current directory. 753120053Sru * If the remaining three all fail, use the current directory. 754120053Sru * 755120053Sru * Once things are initted, 756120053Sru * have to add the original directory to the search path, 757120053Sru * and modify the paths for the Makefiles apropriately. The 758120053Sru * current directory is also placed as a variable for make scripts. 759120053Sru */ 760120053Sru if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) { 761120053Sru if (!(path = getenv("MAKEOBJDIR"))) { 762143412Sharti path = PATH_OBJDIR; 763143412Sharti pathp = PATH_OBJDIRPREFIX; 764138232Sharti snprintf(mdpath, MAXPATHLEN, "%s.%s", 765120053Sru path, machine); 766120053Sru if (!(objdir = chdir_verify_path(mdpath, obpath))) 767120053Sru if (!(objdir=chdir_verify_path(path, obpath))) { 768138232Sharti snprintf(mdpath, MAXPATHLEN, 769120053Sru "%s%s", pathp, curdir); 770120053Sru if (!(objdir=chdir_verify_path(mdpath, 771120053Sru obpath))) 772120053Sru objdir = curdir; 773120053Sru } 774120053Sru } 775120053Sru else if (!(objdir = chdir_verify_path(path, obpath))) 776120053Sru objdir = curdir; 777120053Sru } 778120053Sru else { 779138232Sharti snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir); 780120053Sru if (!(objdir = chdir_verify_path(mdpath, obpath))) 781120053Sru objdir = curdir; 782120053Sru } 783120053Sru Dir_InitDot(); /* Initialize the "." directory */ 784120053Sru if (objdir != curdir) 785144020Sharti Path_AddDir(&dirSearchPath, curdir); 786145971Sharti Var_Set(".ST_EXPORTVAR", "YES", VAR_GLOBAL); 787120053Sru Var_Set(".CURDIR", curdir, VAR_GLOBAL); 788120053Sru Var_Set(".OBJDIR", objdir, VAR_GLOBAL); 789120053Sru 790137606Sphk if (getenv("MAKE_JOBS_FIFO") != NULL) 791137606Sphk forceJobs = TRUE; 792120053Sru /* 79328228Sfsmp * Be compatible if user did not specify -j and did not explicitly 79428228Sfsmp * turned compatibility on 79528228Sfsmp */ 79628228Sfsmp if (!compatMake && !forceJobs) 79728228Sfsmp compatMake = TRUE; 79828228Sfsmp 79928228Sfsmp /* 800144387Sharti * Initialize target and suffix modules in preparation for 8011590Srgrimes * parsing the makefile(s) 8021590Srgrimes */ 8031590Srgrimes Targ_Init(); 8041590Srgrimes Suff_Init(); 8051590Srgrimes 80669527Swill DEFAULT = NULL; 807138232Sharti time(&now); 8081590Srgrimes 8091590Srgrimes /* 8101590Srgrimes * Set up the .TARGETS variable to contain the list of targets to be 8111590Srgrimes * created. If none specified, make the variable empty -- the parser 8121590Srgrimes * will fill the thing in with the default or .MAIN target. 8131590Srgrimes */ 814138916Sharti if (!Lst_IsEmpty(&create)) { 815138512Sharti LstNode *ln; 8161590Srgrimes 817138916Sharti for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) { 818138264Sharti char *name = Lst_Datum(ln); 8191590Srgrimes 8201590Srgrimes Var_Append(".TARGETS", name, VAR_GLOBAL); 8211590Srgrimes } 8221590Srgrimes } else 8231590Srgrimes Var_Set(".TARGETS", "", VAR_GLOBAL); 8241590Srgrimes 82518730Ssteve 8261590Srgrimes /* 82718730Ssteve * If no user-supplied system path was given (through the -m option) 82818730Ssteve * add the directories from the DEFSYSPATH (more than one may be given 82918730Ssteve * as dir1:...:dirn) to the system include path. 8301590Srgrimes */ 831144020Sharti if (TAILQ_EMPTY(&sysIncPath)) { 83218730Ssteve for (start = syspath; *start != '\0'; start = cp) { 83318730Ssteve for (cp = start; *cp != '\0' && *cp != ':'; cp++) 83418730Ssteve continue; 83518730Ssteve if (*cp == '\0') { 836144020Sharti Path_AddDir(&sysIncPath, start); 83718730Ssteve } else { 83818730Ssteve *cp++ = '\0'; 839144020Sharti Path_AddDir(&sysIncPath, start); 84018730Ssteve } 84118730Ssteve } 84218730Ssteve } 8431590Srgrimes 84418730Ssteve /* 84518730Ssteve * Read in the built-in rules first, followed by the specified 84618730Ssteve * makefile, if it was (makefile != (char *) NULL), or the default 84718730Ssteve * Makefile and makefile, in that order, if it wasn't. 84818730Ssteve */ 84918730Ssteve if (!noBuiltins) { 850138916Sharti /* Path of sys.mk */ 851138916Sharti Lst sysMkPath = Lst_Initializer(sysMkPath); 852138512Sharti LstNode *ln; 85318730Ssteve 854144020Sharti Path_Expand(PATH_DEFSYSMK, &sysIncPath, &sysMkPath); 855138916Sharti if (Lst_IsEmpty(&sysMkPath)) 856143412Sharti Fatal("make: no system rules (%s).", PATH_DEFSYSMK); 857143808Sharti LST_FOREACH(ln, &sysMkPath) { 858143808Sharti if (!ReadMakefile(Lst_Datum(ln))) 859143808Sharti break; 860143808Sharti } 86169527Swill if (ln != NULL) 86218730Ssteve Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 863138916Sharti Lst_Destroy(&sysMkPath, free); 86418730Ssteve } 86518730Ssteve 866138916Sharti if (!Lst_IsEmpty(&makefiles)) { 867138512Sharti LstNode *ln; 8681590Srgrimes 869143808Sharti LST_FOREACH(ln, &makefiles) { 870143808Sharti if (!ReadMakefile(Lst_Datum(ln))) 871143808Sharti break; 872143808Sharti } 87369527Swill if (ln != NULL) 8741590Srgrimes Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 875143808Sharti } else if (!ReadMakefile("BSDmakefile")) 876143808Sharti if (!ReadMakefile("makefile")) 877143808Sharti ReadMakefile("Makefile"); 8781590Srgrimes 879143808Sharti ReadMakefile(".depend"); 8801590Srgrimes 8811590Srgrimes /* Install all the flags into the MAKE envariable. */ 8825814Sjkh if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1)) != NULL) && *p) 8831590Srgrimes setenv("MAKEFLAGS", p, 1); 884105826Sjmallett free(p1); 8851590Srgrimes 8861590Srgrimes /* 8871590Srgrimes * For compatibility, look at the directories in the VPATH variable 8881590Srgrimes * and add them to the search path, if the variable is defined. The 8891590Srgrimes * variable's value is in the same format as the PATH envariable, i.e. 8901590Srgrimes * <directory>:<directory>:<directory>... 8911590Srgrimes */ 8921590Srgrimes if (Var_Exists("VPATH", VAR_CMD)) { 8931590Srgrimes /* 8941590Srgrimes * GCC stores string constants in read-only memory, but 8951590Srgrimes * Var_Subst will want to write this thing, so store it 8961590Srgrimes * in an array 8971590Srgrimes */ 8981590Srgrimes static char VPATH[] = "${VPATH}"; 899142457Sharti Buffer *buf; 900142457Sharti char *vpath; 901142457Sharti char *ptr; 902142457Sharti char savec; 9031590Srgrimes 904142457Sharti buf = Var_Subst(NULL, VPATH, VAR_CMD, FALSE); 905142457Sharti 906143959Sharti vpath = Buf_Data(buf); 9071590Srgrimes do { 9081590Srgrimes /* skip to end of directory */ 909142457Sharti for (ptr = vpath; *ptr != ':' && *ptr != '\0'; ptr++) 910141969Sharti ; 911141969Sharti 9121590Srgrimes /* Save terminator character so know when to stop */ 913141969Sharti savec = *ptr; 914141969Sharti *ptr = '\0'; 915141969Sharti 9161590Srgrimes /* Add directory to search path */ 917144020Sharti Path_AddDir(&dirSearchPath, vpath); 918141969Sharti 919142457Sharti vpath = ptr + 1; 920141969Sharti } while (savec != '\0'); 921142457Sharti 922142457Sharti Buf_Destroy(buf, TRUE); 9231590Srgrimes } 9241590Srgrimes 9251590Srgrimes /* 9261590Srgrimes * Now that all search paths have been read for suffixes et al, it's 9271590Srgrimes * time to add the default search path to their lists... 9281590Srgrimes */ 9291590Srgrimes Suff_DoPaths(); 9301590Srgrimes 9311590Srgrimes /* print the initial graph, if the user requested it */ 9321590Srgrimes if (DEBUG(GRAPH1)) 9331590Srgrimes Targ_PrintGraph(1); 9341590Srgrimes 93517193Sbde /* print the values of any variables requested by the user */ 936141974Sharti if (Lst_IsEmpty(&variables)) { 9371590Srgrimes /* 938141974Sharti * Since the user has not requested that any variables 939142008Sharti * be printed, we can build targets. 940141974Sharti * 941142008Sharti * Have read the entire graph and need to make a list of targets 942141974Sharti * to create. If none was given on the command line, we consult 943141974Sharti * the parsing module to find the main target(s) to create. 9441590Srgrimes */ 945138916Sharti Lst targs = Lst_Initializer(targs); 946138916Sharti 947138916Sharti if (Lst_IsEmpty(&create)) 948138916Sharti Parse_MainName(&targs); 949101460Sru else 950138916Sharti Targ_FindList(&targs, &create, TARG_CREATE); 951101460Sru 952141974Sharti if (compatMake) { 953101460Sru /* 954141974Sharti * Compat_Init will take care of creating 955141974Sharti * all the targets as well as initializing 956141974Sharti * the module. 957101460Sru */ 958141974Sharti Compat_Run(&targs); 959141974Sharti outOfDate = 0; 960141974Sharti } else { 961141974Sharti /* 962141974Sharti * Initialize job module before traversing 963141974Sharti * the graph, now that any .BEGIN and .END 964141974Sharti * targets have been read. This is done 965141974Sharti * only if the -q flag wasn't given (to 966141974Sharti * prevent the .BEGIN from being executed 967141974Sharti * should it exist). 968141974Sharti */ 969101460Sru if (!queryFlag) { 970137572Sphk Job_Init(maxJobs); 971101460Sru jobsRunning = TRUE; 972101460Sru } 973101460Sru 974101460Sru /* Traverse the graph, checking on all the targets */ 975138916Sharti outOfDate = Make_Run(&targs); 9761590Srgrimes } 977138916Sharti Lst_Destroy(&targs, NOFREE); 978141974Sharti 979141974Sharti } else { 980141974Sharti /* 981141974Sharti * Print the values of any variables requested by 982141974Sharti * the user. 983141974Sharti */ 984142457Sharti LstNode *n; 985142457Sharti const char *name; 986142457Sharti char *v; 987142457Sharti char *value; 988141974Sharti 989142457Sharti LST_FOREACH(n, &variables) { 990142457Sharti name = Lst_Datum(n); 991141974Sharti if (expandVars) { 992141974Sharti v = emalloc(strlen(name) + 1 + 3); 993141974Sharti sprintf(v, "${%s}", name); 994141974Sharti 995143292Sharti value = Buf_Peel(Var_Subst(NULL, v, 996143292Sharti VAR_GLOBAL, FALSE)); 997142457Sharti printf("%s\n", value); 998142457Sharti 999142457Sharti free(v); 1000143292Sharti free(value); 1001141974Sharti } else { 1002141974Sharti value = Var_Value(name, VAR_GLOBAL, &v); 1003142457Sharti printf("%s\n", value != NULL ? value : ""); 1004142457Sharti if (v != NULL) 1005142457Sharti free(v); 1006141974Sharti } 1007141974Sharti } 100817193Sbde } 10098874Srgrimes 1010138920Sru Lst_Destroy(&variables, free); 1011138920Sru Lst_Destroy(&makefiles, free); 1012138916Sharti Lst_Destroy(&create, free); 10135814Sjkh 10141590Srgrimes /* print the graph now it's been processed if the user requested it */ 10151590Srgrimes if (DEBUG(GRAPH2)) 10161590Srgrimes Targ_PrintGraph(2); 10171590Srgrimes 10181590Srgrimes if (queryFlag && outOfDate) 1019138232Sharti return (1); 10201590Srgrimes else 1021138232Sharti return (0); 10221590Srgrimes} 10231590Srgrimes 1024144475Sharti/** 1025144475Sharti * ReadMakefile 10261590Srgrimes * Open and parse the given makefile. 10271590Srgrimes * 10281590Srgrimes * Results: 10291590Srgrimes * TRUE if ok. FALSE if couldn't open file. 10301590Srgrimes * 10311590Srgrimes * Side Effects: 10321590Srgrimes * lots 10331590Srgrimes */ 10341590Srgrimesstatic Boolean 1035143808ShartiReadMakefile(const char *p) 10361590Srgrimes{ 1037104696Sjmallett char *fname; /* makefile to read */ 10381590Srgrimes FILE *stream; 103973262Simp char *name, path[MAXPATHLEN]; 104097163Sjmallett char *MAKEFILE; 104194990Sru int setMAKEFILE; 10421590Srgrimes 1043138561Sharti /* XXX - remove this once constification is done */ 1044138561Sharti fname = estrdup(p); 1045104696Sjmallett 10461590Srgrimes if (!strcmp(fname, "-")) { 10471590Srgrimes Parse_File("(stdin)", stdin); 10481590Srgrimes Var_Set("MAKEFILE", "", VAR_GLOBAL); 10491590Srgrimes } else { 105094990Sru setMAKEFILE = strcmp(fname, ".depend"); 105194990Sru 10521590Srgrimes /* if we've chdir'd, rebuild the path name */ 10531590Srgrimes if (curdir != objdir && *fname != '/') { 1054138232Sharti snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname); 1055100733Simp /* 1056100733Simp * XXX The realpath stuff breaks relative includes 1057100733Simp * XXX in some cases. The problem likely is in 1058100733Simp * XXX parse.c where it does special things in 1059100733Simp * XXX ParseDoInclude if the file is relateive 1060100733Simp * XXX or absolute and not a system file. There 1061100733Simp * XXX it assumes that if the current file that's 1062100733Simp * XXX being included is absolute, that any files 1063100733Simp * XXX that it includes shouldn't do the -I path 1064100733Simp * XXX stuff, which is inconsistant with historical 1065100733Simp * XXX behavior. However, I can't pentrate the mists 1066100733Simp * XXX further, so I'm putting this workaround in 1067100733Simp * XXX here until such time as the underlying bug 1068100733Simp * XXX can be fixed. 1069100733Simp */ 1070100733Simp#if THIS_BREAKS_THINGS 107197077Sjmallett if (realpath(path, path) != NULL && 107297077Sjmallett (stream = fopen(path, "r")) != NULL) { 107397163Sjmallett MAKEFILE = fname; 10741590Srgrimes fname = path; 10751590Srgrimes goto found; 10761590Srgrimes } 107797077Sjmallett } else if (realpath(fname, path) != NULL) { 107897163Sjmallett MAKEFILE = fname; 107997077Sjmallett fname = path; 108097077Sjmallett if ((stream = fopen(fname, "r")) != NULL) 108197077Sjmallett goto found; 108297077Sjmallett } 1083100733Simp#else 1084100733Simp if ((stream = fopen(path, "r")) != NULL) { 1085100733Simp MAKEFILE = fname; 1086100733Simp fname = path; 1087100733Simp goto found; 1088100733Simp } 1089100733Simp } else { 1090100733Simp MAKEFILE = fname; 1091100733Simp if ((stream = fopen(fname, "r")) != NULL) 1092100733Simp goto found; 1093100733Simp } 1094100733Simp#endif 10951590Srgrimes /* look in -I and system include directories. */ 1096144020Sharti name = Path_FindFile(fname, &parseIncPath); 10971590Srgrimes if (!name) 1098144020Sharti name = Path_FindFile(fname, &sysIncPath); 10991590Srgrimes if (!name || !(stream = fopen(name, "r"))) 1100138232Sharti return (FALSE); 110197163Sjmallett MAKEFILE = fname = name; 11021590Srgrimes /* 11031590Srgrimes * set the MAKEFILE variable desired by System V fans -- the 11041590Srgrimes * placement of the setting here means it gets set to the last 11051590Srgrimes * makefile specified, as it is set by SysV make. 11061590Srgrimes */ 110794990Srufound: 110894990Sru if (setMAKEFILE) 110997163Sjmallett Var_Set("MAKEFILE", MAKEFILE, VAR_GLOBAL); 11101590Srgrimes Parse_File(fname, stream); 1111138232Sharti fclose(stream); 11121590Srgrimes } 1113138232Sharti return (TRUE); 11141590Srgrimes} 11151590Srgrimes 1116144475Sharti/** 1117144475Sharti * Cmd_Exec 111818730Ssteve * Execute the command in cmd, and return the output of that command 111918730Ssteve * in a string. 112018730Ssteve * 112118730Ssteve * Results: 112218730Ssteve * A string containing the output of the command, or the empty string 1123104121Sjmallett * If error is not NULL, it contains the reason for the command failure 112418730Ssteve * 112518730Ssteve * Side Effects: 112618730Ssteve * The string must be freed by the caller. 112718730Ssteve */ 1128141454ShartiBuffer * 1129141252ShartiCmd_Exec(char *cmd, const char **error) 113018730Ssteve{ 1131144475Sharti int fds[2]; /* Pipe streams */ 1132144475Sharti int cpid; /* Child PID */ 1133144475Sharti int pid; /* PID from wait() */ 1134144475Sharti int status; /* command exit status */ 1135144475Sharti Buffer *buf; /* buffer to store the result */ 1136144475Sharti ssize_t rcnt; 113718730Ssteve 1138144475Sharti *error = NULL; 1139144475Sharti buf = Buf_Init(0); 114018730Ssteve 1141144475Sharti if (shellPath == NULL) 1142144475Sharti Shell_Init(); 114318730Ssteve /* 1144144475Sharti * Open a pipe for fetching its output 114518730Ssteve */ 1146144475Sharti if (pipe(fds) == -1) { 1147144475Sharti *error = "Couldn't create pipe for \"%s\""; 1148144475Sharti return (buf); 1149144475Sharti } 115018730Ssteve 115118730Ssteve /* 1152144475Sharti * Fork 115318730Ssteve */ 1154144475Sharti switch (cpid = vfork()) { 1155144475Sharti case 0: 1156144475Sharti /* 1157144475Sharti * Close input side of pipe 1158144475Sharti */ 1159144475Sharti close(fds[0]); 116018730Ssteve 1161144475Sharti /* 1162144475Sharti * Duplicate the output stream to the shell's output, then 1163144475Sharti * shut the extra thing down. Note we don't fetch the error 1164144475Sharti * stream...why not? Why? 1165144475Sharti */ 1166144475Sharti dup2(fds[1], 1); 1167144475Sharti close(fds[1]); 116818730Ssteve 1169144475Sharti { 1170144475Sharti char *args[4]; 1171141454Sharti 1172144475Sharti /* Set up arguments for shell */ 1173144475Sharti args[0] = shellName; 1174144475Sharti args[1] = "-c"; 1175144475Sharti args[2] = cmd; 1176144475Sharti args[3] = NULL; 1177141454Sharti 1178144475Sharti execv(shellPath, args); 1179144475Sharti _exit(1); 1180144475Sharti /*NOTREACHED*/ 1181144475Sharti } 118218730Ssteve 1183144475Sharti case -1: 1184144475Sharti *error = "Couldn't exec \"%s\""; 1185144475Sharti return (buf); 118618730Ssteve 1187144475Sharti default: 1188144475Sharti /* 1189144475Sharti * No need for the writing half 1190144475Sharti */ 1191144475Sharti close(fds[1]); 1192141454Sharti 1193144475Sharti do { 1194144475Sharti char result[BUFSIZ]; 1195141454Sharti 1196144475Sharti rcnt = read(fds[0], result, sizeof(result)); 1197144475Sharti if (rcnt != -1) 1198144475Sharti Buf_AddBytes(buf, (size_t)rcnt, (Byte *)result); 1199144475Sharti } while (rcnt > 0 || (rcnt == -1 && errno == EINTR)); 120018730Ssteve 1201144475Sharti if (rcnt == -1) 1202144475Sharti *error = "Error reading shell's output for \"%s\""; 120318730Ssteve 1204144475Sharti /* 1205144475Sharti * Close the input side of the pipe. 1206144475Sharti */ 1207144475Sharti close(fds[0]); 120818730Ssteve 1209144475Sharti /* 1210144475Sharti * Wait for the process to exit. 1211144475Sharti */ 1212144475Sharti while (((pid = wait(&status)) != cpid) && (pid >= 0)) 1213144475Sharti continue; 121418730Ssteve 1215144475Sharti if (status) 1216144475Sharti *error = "\"%s\" returned non-zero status"; 1217144475Sharti 1218144475Sharti Buf_StripNewlines(buf); 1219144475Sharti 1220144475Sharti break; 1221144475Sharti } 1222144475Sharti return (buf); 122318730Ssteve} 122418730Ssteve 12251590Srgrimes/* 12261590Srgrimes * usage -- 12271590Srgrimes * exit with usage message 12281590Srgrimes */ 12291590Srgrimesstatic void 1230104696Sjmallettusage(void) 12311590Srgrimes{ 1232145627Sharti fprintf(stderr, "%s\n%s\n%s\n%s\n", 1233145627Sharti"usage: make [-ABPSXeiknqrstv] [-C directory] [-D variable] [-d flags]", 1234113512Sru" [-E variable] [-f makefile] [-I directory] [-j max_jobs]", 1235145627Sharti" [-m directory] [-V variable] [variable=value] [-x warn_flag]", 1236145627Sharti" [target ...]"); 12371590Srgrimes exit(2); 12381590Srgrimes} 1239