[BACK]Return to main.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / usr.bin / make

Annotation of src/usr.bin/make/main.c, Revision 1.504

1.504   ! rillig      1: /*     $NetBSD: main.c,v 1.503 2020/12/26 03:54:48 sjg Exp $   */
1.19      christos    2:
1.1       cgd         3: /*
1.31      christos    4:  * Copyright (c) 1988, 1989, 1990, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
1.91      agc         6:  *
                      7:  * This code is derived from software contributed to Berkeley by
                      8:  * Adam de Boor.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. Neither the name of the University nor the names of its contributors
                     19:  *    may be used to endorse or promote products derived from this software
                     20:  *    without specific prior written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     25:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     28:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     32:  * SUCH DAMAGE.
                     33:  */
                     34:
                     35: /*
1.1       cgd        36:  * Copyright (c) 1989 by Berkeley Softworks
                     37:  * All rights reserved.
                     38:  *
                     39:  * This code is derived from software contributed to Berkeley by
                     40:  * Adam de Boor.
                     41:  *
                     42:  * Redistribution and use in source and binary forms, with or without
                     43:  * modification, are permitted provided that the following conditions
                     44:  * are met:
                     45:  * 1. Redistributions of source code must retain the above copyright
                     46:  *    notice, this list of conditions and the following disclaimer.
                     47:  * 2. Redistributions in binary form must reproduce the above copyright
                     48:  *    notice, this list of conditions and the following disclaimer in the
                     49:  *    documentation and/or other materials provided with the distribution.
                     50:  * 3. All advertising materials mentioning features or use of this software
                     51:  *    must display the following acknowledgement:
                     52:  *     This product includes software developed by the University of
                     53:  *     California, Berkeley and its contributors.
                     54:  * 4. Neither the name of the University nor the names of its contributors
                     55:  *    may be used to endorse or promote products derived from this software
                     56:  *    without specific prior written permission.
                     57:  *
                     58:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     59:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     60:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     61:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     62:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     63:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     64:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     65:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     66:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     67:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     68:  * SUCH DAMAGE.
                     69:  */
                     70:
1.438     rillig     71: /* The main file for this entire program. Exit routines etc. reside here.
1.1       cgd        72:  *
                     73:  * Utility functions defined in this file:
                     74:  *
1.438     rillig     75:  *     Main_ParseArgLine       Parse and process command line arguments from
                     76:  *                             a single string.  Used to implement the
                     77:  *                             special targets .MFLAGS and .MAKEFLAGS.
                     78:  *
                     79:  *     Error                   Print a tagged error message.
                     80:  *
                     81:  *     Fatal                   Print an error message and exit.
1.1       cgd        82:  *
1.438     rillig     83:  *     Punt                    Abort all jobs and exit with a message.
1.1       cgd        84:  *
                     85:  *     Finish                  Finish things up by printing the number of
1.438     rillig     86:  *                             errors which occurred, and exit.
1.1       cgd        87:  */
                     88:
1.13      cgd        89: #include <sys/types.h>
                     90: #include <sys/time.h>
1.1       cgd        91: #include <sys/param.h>
1.13      cgd        92: #include <sys/resource.h>
1.1       cgd        93: #include <sys/stat.h>
1.225     matt       94: #ifdef MAKE_NATIVE
                     95: #include <sys/sysctl.h>
                     96: #endif
1.17      gwr        97: #include <sys/utsname.h>
1.29      christos   98: #include <sys/wait.h>
1.85      wiz        99:
1.1       cgd       100: #include <errno.h>
1.215     christos  101: #include <signal.h>
1.85      wiz       102: #include <stdarg.h>
1.42      kleink    103: #include <time.h>
1.85      wiz       104:
1.1       cgd       105: #include "make.h"
1.13      cgd       106: #include "dir.h"
                    107: #include "job.h"
1.1       cgd       108: #include "pathnames.h"
1.58      sommerfe  109: #include "trace.h"
1.1       cgd       110:
1.337     rillig    111: /*     "@(#)main.c     8.3 (Berkeley) 3/19/94" */
1.504   ! rillig    112: MAKE_RCSID("$NetBSD: main.c,v 1.503 2020/12/26 03:54:48 sjg Exp $");
1.337     rillig    113: #if defined(MAKE_NATIVE) && !defined(lint)
1.369     rillig    114: __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 "
                    115:            "The Regents of the University of California.  "
                    116:            "All rights reserved.");
1.337     rillig    117: #endif
                    118:
1.391     rillig    119: CmdOpts opts;
1.453     rillig    120: time_t now;                    /* Time at start of make */
1.459     rillig    121: GNode *defaultNode;            /* .DEFAULT node */
1.453     rillig    122: Boolean allPrecious;           /* .PRECIOUS given on line by itself */
                    123: Boolean deleteOnError;         /* .DELETE_ON_ERROR: set */
1.1       cgd       124:
1.453     rillig    125: static int maxJobTokens;       /* -j argument */
                    126: Boolean enterFlagObj;          /* -w and objdir != srcdir */
1.391     rillig    127:
1.423     rillig    128: Boolean preserveUndefined;
1.453     rillig    129: static int jp_0 = -1, jp_1 = -1; /* ends of parent job pipe */
                    130: Boolean doing_depend;          /* Set while reading .depend */
                    131: static Boolean jobsRunning;    /* TRUE if the jobs might be running */
                    132: static const char *tracefile;
                    133: static int ReadMakefile(const char *);
1.469     rillig    134: static void purge_relative_cached_realpaths(void);
1.453     rillig    135:
                    136: static Boolean ignorePWD;      /* if we use -C, PWD is meaningless */
                    137: static char objdir[MAXPATHLEN + 1]; /* where we chdir'ed to */
                    138: char curdir[MAXPATHLEN + 1];   /* Startup directory */
1.497     rillig    139: const char *progname;
1.176     sjg       140: char *makeDependfile;
1.183     sjg       141: pid_t myPid;
1.220     christos  142: int makelevel;
1.1       cgd       143:
1.58      sommerfe  144: Boolean forceJobs = FALSE;
1.481     rillig    145: static int main_errors = 0;
1.469     rillig    146: static HashTable cached_realpaths;
1.58      sommerfe  147:
1.220     christos  148: /*
                    149:  * For compatibility with the POSIX version of MAKEFLAGS that includes
1.439     rillig    150:  * all the options without '-', convert 'flags' to '-f -l -a -g -s'.
1.220     christos  151:  */
                    152: static char *
                    153: explode(const char *flags)
                    154: {
1.453     rillig    155:        size_t len;
                    156:        char *nf, *st;
                    157:        const char *f;
                    158:
                    159:        if (flags == NULL)
                    160:                return NULL;
                    161:
                    162:        for (f = flags; *f; f++)
                    163:                if (!ch_isalpha(*f))
                    164:                        break;
                    165:
1.477     rillig    166:        if (*f != '\0')
1.453     rillig    167:                return bmake_strdup(flags);
                    168:
                    169:        len = strlen(flags);
                    170:        st = nf = bmake_malloc(len * 3 + 1);
1.477     rillig    171:        while (*flags != '\0') {
1.453     rillig    172:                *nf++ = '-';
                    173:                *nf++ = *flags++;
                    174:                *nf++ = ' ';
                    175:        }
                    176:        *nf = '\0';
                    177:        return st;
1.220     christos  178: }
1.279     rillig    179:
1.450     rillig    180: /*
                    181:  * usage --
                    182:  *     exit with usage message
                    183:  */
                    184: MAKE_ATTR_DEAD static void
                    185: usage(void)
                    186: {
1.466     rillig    187:        size_t prognameLen = strcspn(progname, "[");
1.450     rillig    188:
                    189:        (void)fprintf(stderr,
1.468     rillig    190: "usage: %.*s [-BeikNnqrSstWwX]\n"
1.450     rillig    191: "            [-C directory] [-D variable] [-d flags] [-f makefile]\n"
                    192: "            [-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]\n"
                    193: "            [-V variable] [-v variable] [variable=value] [target ...]\n",
1.466     rillig    194:            (int)prognameLen, progname);
1.450     rillig    195:        exit(2);
                    196: }
                    197:
1.133     dsl       198: static void
1.344     rillig    199: parse_debug_option_F(const char *modules)
                    200: {
1.453     rillig    201:        const char *mode;
                    202:        size_t len;
                    203:        char *fname;
                    204:
                    205:        if (opts.debug_file != stdout && opts.debug_file != stderr)
                    206:                fclose(opts.debug_file);
                    207:
                    208:        if (*modules == '+') {
                    209:                modules++;
                    210:                mode = "a";
                    211:        } else
                    212:                mode = "w";
1.344     rillig    213:
1.453     rillig    214:        if (strcmp(modules, "stdout") == 0) {
                    215:                opts.debug_file = stdout;
                    216:                return;
                    217:        }
                    218:        if (strcmp(modules, "stderr") == 0) {
                    219:                opts.debug_file = stderr;
                    220:                return;
                    221:        }
1.344     rillig    222:
1.453     rillig    223:        len = strlen(modules);
                    224:        fname = bmake_malloc(len + 20);
                    225:        memcpy(fname, modules, len + 1);
                    226:
                    227:        /* Let the filename be modified by the pid */
                    228:        if (strcmp(fname + len - 3, ".%d") == 0)
                    229:                snprintf(fname + len - 2, 20, "%d", getpid());
                    230:
                    231:        opts.debug_file = fopen(fname, mode);
                    232:        if (opts.debug_file == NULL) {
                    233:                fprintf(stderr, "Cannot open debug file %s\n",
                    234:                    fname);
                    235:                usage();
                    236:        }
                    237:        free(fname);
1.344     rillig    238: }
                    239:
                    240: static void
1.133     dsl       241: parse_debug_options(const char *argvalue)
                    242: {
                    243:        const char *modules;
1.470     rillig    244:        DebugFlags debug = opts.debug;
1.133     dsl       245:
                    246:        for (modules = argvalue; *modules; ++modules) {
                    247:                switch (*modules) {
1.369     rillig    248:                case '0':       /* undocumented, only intended for tests */
1.470     rillig    249:                        debug = DEBUG_NONE;
1.369     rillig    250:                        break;
1.133     dsl       251:                case 'A':
1.470     rillig    252:                        debug = DEBUG_ALL;
1.133     dsl       253:                        break;
                    254:                case 'a':
1.470     rillig    255:                        debug |= DEBUG_ARCH;
1.133     dsl       256:                        break;
1.155     christos  257:                case 'C':
1.470     rillig    258:                        debug |= DEBUG_CWD;
1.155     christos  259:                        break;
1.133     dsl       260:                case 'c':
1.470     rillig    261:                        debug |= DEBUG_COND;
1.133     dsl       262:                        break;
                    263:                case 'd':
1.470     rillig    264:                        debug |= DEBUG_DIR;
1.133     dsl       265:                        break;
                    266:                case 'e':
1.470     rillig    267:                        debug |= DEBUG_ERROR;
1.133     dsl       268:                        break;
                    269:                case 'f':
1.470     rillig    270:                        debug |= DEBUG_FOR;
1.133     dsl       271:                        break;
                    272:                case 'g':
                    273:                        if (modules[1] == '1') {
1.470     rillig    274:                                debug |= DEBUG_GRAPH1;
1.475     rillig    275:                                modules++;
1.444     rillig    276:                        } else if (modules[1] == '2') {
1.470     rillig    277:                                debug |= DEBUG_GRAPH2;
1.475     rillig    278:                                modules++;
1.444     rillig    279:                        } else if (modules[1] == '3') {
1.470     rillig    280:                                debug |= DEBUG_GRAPH3;
1.475     rillig    281:                                modules++;
1.133     dsl       282:                        }
                    283:                        break;
1.280     sjg       284:                case 'h':
1.470     rillig    285:                        debug |= DEBUG_HASH;
1.280     sjg       286:                        break;
1.133     dsl       287:                case 'j':
1.470     rillig    288:                        debug |= DEBUG_JOB;
1.133     dsl       289:                        break;
1.285     sjg       290:                case 'L':
1.501     rillig    291:                        opts.strict = TRUE;
1.285     sjg       292:                        break;
1.146     sjg       293:                case 'l':
1.470     rillig    294:                        debug |= DEBUG_LOUD;
1.146     sjg       295:                        break;
1.190     sjg       296:                case 'M':
1.470     rillig    297:                        debug |= DEBUG_META;
1.190     sjg       298:                        break;
1.133     dsl       299:                case 'm':
1.470     rillig    300:                        debug |= DEBUG_MAKE;
1.133     dsl       301:                        break;
                    302:                case 'n':
1.470     rillig    303:                        debug |= DEBUG_SCRIPT;
1.133     dsl       304:                        break;
                    305:                case 'p':
1.470     rillig    306:                        debug |= DEBUG_PARSE;
1.133     dsl       307:                        break;
                    308:                case 's':
1.470     rillig    309:                        debug |= DEBUG_SUFF;
1.133     dsl       310:                        break;
                    311:                case 't':
1.470     rillig    312:                        debug |= DEBUG_TARG;
1.133     dsl       313:                        break;
1.201     sjg       314:                case 'V':
1.394     rillig    315:                        opts.debugVflag = TRUE;
1.201     sjg       316:                        break;
1.133     dsl       317:                case 'v':
1.470     rillig    318:                        debug |= DEBUG_VAR;
1.133     dsl       319:                        break;
                    320:                case 'x':
1.470     rillig    321:                        debug |= DEBUG_SHELL;
1.133     dsl       322:                        break;
                    323:                case 'F':
1.344     rillig    324:                        parse_debug_option_F(modules + 1);
1.153     apb       325:                        goto debug_setbuf;
1.133     dsl       326:                default:
                    327:                        (void)fprintf(stderr,
                    328:                            "%s: illegal argument to d option -- %c\n",
                    329:                            progname, *modules);
                    330:                        usage();
                    331:                }
                    332:        }
1.471     rillig    333:
                    334: debug_setbuf:
1.470     rillig    335:        opts.debug = debug;
1.453     rillig    336:
1.153     apb       337:        /*
                    338:         * Make the debug_file unbuffered, and make
                    339:         * stdout line buffered (unless debugfile == stdout).
                    340:         */
1.391     rillig    341:        setvbuf(opts.debug_file, NULL, _IONBF, 0);
                    342:        if (opts.debug_file != stdout) {
1.153     apb       343:                setvbuf(stdout, NULL, _IOLBF, 0);
                    344:        }
1.133     dsl       345: }
                    346:
1.264     sjg       347: /*
                    348:  * does path contain any relative components
                    349:  */
1.286     rillig    350: static Boolean
1.264     sjg       351: is_relpath(const char *path)
                    352: {
                    353:        const char *cp;
                    354:
                    355:        if (path[0] != '/')
                    356:                return TRUE;
                    357:        cp = path;
1.286     rillig    358:        while ((cp = strstr(cp, "/.")) != NULL) {
1.264     sjg       359:                cp += 2;
1.439     rillig    360:                if (*cp == '.')
1.453     rillig    361:                        cp++;
1.264     sjg       362:                if (cp[0] == '/' || cp[0] == '\0')
                    363:                        return TRUE;
1.286     rillig    364:        }
1.264     sjg       365:        return FALSE;
                    366: }
                    367:
1.355     rillig    368: static void
                    369: MainParseArgChdir(const char *argvalue)
                    370: {
                    371:        struct stat sa, sb;
                    372:
                    373:        if (chdir(argvalue) == -1) {
                    374:                (void)fprintf(stderr, "%s: chdir %s: %s\n",
                    375:                    progname, argvalue, strerror(errno));
                    376:                exit(1);
                    377:        }
                    378:        if (getcwd(curdir, MAXPATHLEN) == NULL) {
                    379:                (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
                    380:                exit(2);
                    381:        }
                    382:        if (!is_relpath(argvalue) &&
                    383:            stat(argvalue, &sa) != -1 &&
                    384:            stat(curdir, &sb) != -1 &&
                    385:            sa.st_ino == sb.st_ino &&
                    386:            sa.st_dev == sb.st_dev)
                    387:                strncpy(curdir, argvalue, MAXPATHLEN);
                    388:        ignorePWD = TRUE;
                    389: }
                    390:
1.356     rillig    391: static void
                    392: MainParseArgJobsInternal(const char *argvalue)
                    393: {
1.440     rillig    394:        char end;
                    395:        if (sscanf(argvalue, "%d,%d%c", &jp_0, &jp_1, &end) != 2) {
1.356     rillig    396:                (void)fprintf(stderr,
1.453     rillig    397:                    "%s: internal error -- J option malformed (%s)\n",
                    398:                    progname, argvalue);
1.356     rillig    399:                usage();
                    400:        }
                    401:        if ((fcntl(jp_0, F_GETFD, 0) < 0) ||
                    402:            (fcntl(jp_1, F_GETFD, 0) < 0)) {
                    403: #if 0
                    404:                (void)fprintf(stderr,
                    405:                    "%s: ###### warning -- J descriptors were closed!\n",
                    406:                    progname);
                    407:                exit(2);
                    408: #endif
                    409:                jp_0 = -1;
                    410:                jp_1 = -1;
1.391     rillig    411:                opts.compatMake = TRUE;
1.356     rillig    412:        } else {
                    413:                Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
                    414:                Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
                    415:        }
                    416: }
                    417:
                    418: static void
                    419: MainParseArgJobs(const char *argvalue)
                    420: {
                    421:        char *p;
                    422:
                    423:        forceJobs = TRUE;
1.391     rillig    424:        opts.maxJobs = (int)strtol(argvalue, &p, 0);
                    425:        if (*p != '\0' || opts.maxJobs < 1) {
1.356     rillig    426:                (void)fprintf(stderr,
                    427:                    "%s: illegal argument to -j -- must be positive integer!\n",
                    428:                    progname);
                    429:                exit(1);        /* XXX: why not 2? */
                    430:        }
                    431:        Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
                    432:        Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
                    433:        Var_Set(".MAKE.JOBS", argvalue, VAR_GLOBAL);
1.391     rillig    434:        maxJobTokens = opts.maxJobs;
1.356     rillig    435: }
                    436:
1.357     rillig    437: static void
                    438: MainParseArgSysInc(const char *argvalue)
                    439: {
                    440:        /* look for magic parent directory search string */
                    441:        if (strncmp(".../", argvalue, 4) == 0) {
1.371     rillig    442:                char *found_path = Dir_FindHereOrAbove(curdir, argvalue + 4);
                    443:                if (found_path == NULL)
1.357     rillig    444:                        return;
                    445:                (void)Dir_AddDir(sysIncPath, found_path);
1.371     rillig    446:                free(found_path);
1.357     rillig    447:        } else {
                    448:                (void)Dir_AddDir(sysIncPath, argvalue);
                    449:        }
                    450:        Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
                    451:        Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
                    452: }
                    453:
1.354     rillig    454: static Boolean
1.360     rillig    455: MainParseArg(char c, const char *argvalue)
1.354     rillig    456: {
                    457:        switch (c) {
                    458:        case '\0':
                    459:                break;
                    460:        case 'B':
1.391     rillig    461:                opts.compatMake = TRUE;
1.354     rillig    462:                Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL);
                    463:                Var_Set(MAKE_MODE, "compat", VAR_GLOBAL);
                    464:                break;
                    465:        case 'C':
1.355     rillig    466:                MainParseArgChdir(argvalue);
1.354     rillig    467:                break;
                    468:        case 'D':
1.359     rillig    469:                if (argvalue[0] == '\0') return FALSE;
1.354     rillig    470:                Var_Set(argvalue, "1", VAR_GLOBAL);
                    471:                Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
                    472:                Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
                    473:                break;
                    474:        case 'I':
                    475:                Parse_AddIncludeDir(argvalue);
                    476:                Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
                    477:                Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
                    478:                break;
                    479:        case 'J':
1.356     rillig    480:                MainParseArgJobsInternal(argvalue);
1.354     rillig    481:                break;
                    482:        case 'N':
1.391     rillig    483:                opts.noExecute = TRUE;
                    484:                opts.noRecursiveExecute = TRUE;
1.354     rillig    485:                Var_Append(MAKEFLAGS, "-N", VAR_GLOBAL);
                    486:                break;
                    487:        case 'S':
1.391     rillig    488:                opts.keepgoing = FALSE;
1.354     rillig    489:                Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
                    490:                break;
                    491:        case 'T':
                    492:                tracefile = bmake_strdup(argvalue);
                    493:                Var_Append(MAKEFLAGS, "-T", VAR_GLOBAL);
                    494:                Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
                    495:                break;
                    496:        case 'V':
                    497:        case 'v':
1.437     rillig    498:                opts.printVars = c == 'v' ? PVM_EXPANDED : PVM_UNEXPANDED;
1.485     rillig    499:                Lst_Append(&opts.variables, bmake_strdup(argvalue));
1.391     rillig    500:                /* XXX: Why always -V? */
1.354     rillig    501:                Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
                    502:                Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
                    503:                break;
                    504:        case 'W':
1.391     rillig    505:                opts.parseWarnFatal = TRUE;
1.441     rillig    506:                /* XXX: why no Var_Append? */
1.354     rillig    507:                break;
                    508:        case 'X':
1.391     rillig    509:                opts.varNoExportEnv = TRUE;
1.354     rillig    510:                Var_Append(MAKEFLAGS, "-X", VAR_GLOBAL);
                    511:                break;
                    512:        case 'd':
                    513:                /* If '-d-opts' don't pass to children */
                    514:                if (argvalue[0] == '-')
                    515:                        argvalue++;
                    516:                else {
                    517:                        Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
                    518:                        Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
                    519:                }
                    520:                parse_debug_options(argvalue);
                    521:                break;
                    522:        case 'e':
1.391     rillig    523:                opts.checkEnvFirst = TRUE;
1.354     rillig    524:                Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
                    525:                break;
                    526:        case 'f':
1.484     rillig    527:                Lst_Append(&opts.makefiles, bmake_strdup(argvalue));
1.354     rillig    528:                break;
                    529:        case 'i':
1.391     rillig    530:                opts.ignoreErrors = TRUE;
1.354     rillig    531:                Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
                    532:                break;
                    533:        case 'j':
1.356     rillig    534:                MainParseArgJobs(argvalue);
1.354     rillig    535:                break;
                    536:        case 'k':
1.391     rillig    537:                opts.keepgoing = TRUE;
1.354     rillig    538:                Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
                    539:                break;
                    540:        case 'm':
1.357     rillig    541:                MainParseArgSysInc(argvalue);
1.441     rillig    542:                /* XXX: why no Var_Append? */
1.354     rillig    543:                break;
                    544:        case 'n':
1.391     rillig    545:                opts.noExecute = TRUE;
1.354     rillig    546:                Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
                    547:                break;
                    548:        case 'q':
1.391     rillig    549:                opts.queryFlag = TRUE;
1.354     rillig    550:                /* Kind of nonsensical, wot? */
                    551:                Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
                    552:                break;
                    553:        case 'r':
1.391     rillig    554:                opts.noBuiltins = TRUE;
1.354     rillig    555:                Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
                    556:                break;
                    557:        case 's':
1.391     rillig    558:                opts.beSilent = TRUE;
1.354     rillig    559:                Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
                    560:                break;
                    561:        case 't':
1.391     rillig    562:                opts.touchFlag = TRUE;
1.354     rillig    563:                Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
                    564:                break;
                    565:        case 'w':
1.391     rillig    566:                opts.enterFlag = TRUE;
1.354     rillig    567:                Var_Append(MAKEFLAGS, "-w", VAR_GLOBAL);
                    568:                break;
                    569:        default:
                    570:        case '?':
                    571:                usage();
                    572:        }
                    573:        return TRUE;
                    574: }
                    575:
1.345     rillig    576: /* Parse the given arguments.  Called from main() and from
                    577:  * Main_ParseArgLine() when the .MAKEFLAGS target is used.
1.1       cgd       578:  *
1.345     rillig    579:  * The arguments must be treated as read-only and will be freed after the
                    580:  * call.
1.1       cgd       581:  *
1.345     rillig    582:  * XXX: Deal with command line overriding .MAKEFLAGS in makefile */
1.1       cgd       583: static void
1.149     christos  584: MainParseArgs(int argc, char **argv)
1.1       cgd       585: {
1.360     rillig    586:        char c;
1.98      ross      587:        int arginc;
1.133     dsl       588:        char *argvalue;
1.98      ross      589:        char *optscan;
1.101     ross      590:        Boolean inOption, dashDash = FALSE;
1.1       cgd       591:
1.359     rillig    592:        const char *optspecs = "BC:D:I:J:NST:V:WXd:ef:ij:km:nqrstv:w";
1.98      ross      593: /* Can't actually use getopt(3) because rescanning is not portable */
                    594:
1.279     rillig    595: rearg:
1.98      ross      596:        inOption = FALSE;
1.108     lukem     597:        optscan = NULL;
1.358     rillig    598:        while (argc > 1) {
1.359     rillig    599:                const char *optspec;
1.358     rillig    600:                if (!inOption)
1.98      ross      601:                        optscan = argv[1];
                    602:                c = *optscan++;
                    603:                arginc = 0;
1.358     rillig    604:                if (inOption) {
                    605:                        if (c == '\0') {
1.475     rillig    606:                                argv++;
                    607:                                argc--;
1.98      ross      608:                                inOption = FALSE;
                    609:                                continue;
                    610:                        }
                    611:                } else {
1.101     ross      612:                        if (c != '-' || dashDash)
1.98      ross      613:                                break;
                    614:                        inOption = TRUE;
                    615:                        c = *optscan++;
                    616:                }
                    617:                /* '-' found at some earlier point */
1.359     rillig    618:                optspec = strchr(optspecs, c);
                    619:                if (c != '\0' && optspec != NULL && optspec[1] == ':') {
1.98      ross      620:                        /* -<something> found, and <something> should have an arg */
                    621:                        inOption = FALSE;
                    622:                        arginc = 1;
                    623:                        argvalue = optscan;
1.358     rillig    624:                        if (*argvalue == '\0') {
1.122     christos  625:                                if (argc < 3)
                    626:                                        goto noarg;
1.98      ross      627:                                argvalue = argv[2];
                    628:                                arginc = 2;
                    629:                        }
1.108     lukem     630:                } else {
1.279     rillig    631:                        argvalue = NULL;
1.98      ross      632:                }
1.354     rillig    633:                switch (c) {
1.98      ross      634:                case '\0':
1.358     rillig    635:                        arginc = 1;
                    636:                        inOption = FALSE;
                    637:                        break;
1.101     ross      638:                case '-':
1.358     rillig    639:                        dashDash = TRUE;
                    640:                        break;
1.1       cgd       641:                default:
1.358     rillig    642:                        if (!MainParseArg(c, argvalue))
                    643:                                goto noarg;
1.1       cgd       644:                }
1.98      ross      645:                argv += arginc;
                    646:                argc -= arginc;
1.1       cgd       647:        }
                    648:
                    649:        /*
                    650:         * See if the rest of the arguments are variable assignments and
                    651:         * perform them if so. Else take them to be targets and stuff them
                    652:         * on the end of the "create" list.
                    653:         */
1.369     rillig    654:        for (; argc > 1; ++argv, --argc) {
                    655:                VarAssign var;
                    656:                if (Parse_IsVar(argv[1], &var)) {
1.410     rillig    657:                        Parse_DoVar(&var, VAR_CMDLINE);
1.67      sjg       658:                } else {
1.460     rillig    659:                        if (argv[1][0] == '\0')
1.1       cgd       660:                                Punt("illegal (null) argument.");
1.460     rillig    661:                        if (argv[1][0] == '-' && !dashDash)
1.1       cgd       662:                                goto rearg;
1.486     rillig    663:                        Lst_Append(&opts.create, bmake_strdup(argv[1]));
1.1       cgd       664:                }
1.369     rillig    665:        }
1.122     christos  666:
                    667:        return;
                    668: noarg:
                    669:        (void)fprintf(stderr, "%s: option requires an argument -- %c\n",
                    670:            progname, c);
                    671:        usage();
1.1       cgd       672: }
                    673:
1.361     rillig    674: /* Break a line of arguments into words and parse them.
1.85      wiz       675:  *
1.361     rillig    676:  * Used when a .MFLAGS or .MAKEFLAGS target is encountered during parsing and
                    677:  * by main() when reading the MAKEFLAGS environment variable. */
1.1       cgd       678: void
1.161     dsl       679: Main_ParseArgLine(const char *line)
1.1       cgd       680: {
1.331     rillig    681:        Words words;
1.296     rillig    682:        char *buf;
1.1       cgd       683:
                    684:        if (line == NULL)
                    685:                return;
1.496     rillig    686:        /* XXX: don't use line as an iterator variable */
1.13      cgd       687:        for (; *line == ' '; ++line)
                    688:                continue;
1.442     rillig    689:        if (line[0] == '\0')
1.1       cgd       690:                return;
                    691:
1.442     rillig    692:        {
1.499     rillig    693:                FStr argv0 = Var_Value(".MAKE", VAR_GLOBAL);
                    694:                buf = str_concat3(argv0.str, " ", line);
                    695:                FStr_Done(&argv0);
1.442     rillig    696:        }
1.40      christos  697:
1.331     rillig    698:        words = Str_Words(buf, TRUE);
                    699:        if (words.words == NULL) {
1.159     christos  700:                Error("Unterminated quoted string [%s]", buf);
                    701:                free(buf);
                    702:                return;
                    703:        }
1.45      itohy     704:        free(buf);
1.331     rillig    705:        MainParseArgs((int)words.len, words.words);
1.40      christos  706:
1.331     rillig    707:        Words_Free(words);
1.1       cgd       708: }
                    709:
1.74      tv        710: Boolean
1.456     sjg       711: Main_SetObjdir(Boolean writable, const char *fmt, ...)
1.31      christos  712: {
                    713:        struct stat sb;
1.260     christos  714:        char *path;
                    715:        char buf[MAXPATHLEN + 1];
1.265     sjg       716:        char buf2[MAXPATHLEN + 1];
1.76      tv        717:        Boolean rc = FALSE;
1.252     christos  718:        va_list ap;
                    719:
                    720:        va_start(ap, fmt);
1.260     christos  721:        vsnprintf(path = buf, MAXPATHLEN, fmt, ap);
1.252     christos  722:        va_end(ap);
1.31      christos  723:
1.74      tv        724:        if (path[0] != '/') {
1.263     sjg       725:                snprintf(buf2, MAXPATHLEN, "%s/%s", curdir, path);
                    726:                path = buf2;
1.74      tv        727:        }
                    728:
                    729:        /* look for the directory and try to chdir there */
1.31      christos  730:        if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
1.456     sjg       731:                if ((writable && access(path, W_OK) != 0) ||
1.433     rillig    732:                    (chdir(path) != 0)) {
1.463     rillig    733:                        (void)fprintf(stderr, "%s warning: %s: %s.\n",
                    734:                            progname, path, strerror(errno));
1.74      tv        735:                } else {
1.295     rillig    736:                        snprintf(objdir, sizeof objdir, "%s", path);
1.277     rillig    737:                        Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
1.74      tv        738:                        setenv("PWD", objdir, 1);
1.79      tv        739:                        Dir_InitDot();
1.469     rillig    740:                        purge_relative_cached_realpaths();
1.74      tv        741:                        rc = TRUE;
1.391     rillig    742:                        if (opts.enterFlag && strcmp(objdir, curdir) != 0)
1.233     sjg       743:                                enterFlagObj = TRUE;
1.31      christos  744:                }
                    745:        }
                    746:
1.74      tv        747:        return rc;
1.31      christos  748: }
                    749:
1.252     christos  750: static Boolean
1.461     rillig    751: SetVarObjdir(Boolean writable, const char *var, const char *suffix)
1.252     christos  752: {
1.499     rillig    753:        FStr path = Var_Value(var, VAR_CMDLINE);
                    754:        FStr xpath;
1.296     rillig    755:
1.499     rillig    756:        if (path.str == NULL || path.str[0] == '\0') {
                    757:                FStr_Done(&path);
1.252     christos  758:                return FALSE;
1.288     rillig    759:        }
1.252     christos  760:
1.260     christos  761:        /* expand variable substitutions */
1.499     rillig    762:        xpath = FStr_InitRefer(path.str);
                    763:        if (strchr(path.str, '$') != 0) {
                    764:                char *expanded;
                    765:                (void)Var_Subst(path.str, VAR_GLOBAL, VARE_WANTRES, &expanded);
1.341     rillig    766:                /* TODO: handle errors */
1.499     rillig    767:                xpath = FStr_InitOwn(expanded);
1.341     rillig    768:        }
1.260     christos  769:
1.499     rillig    770:        (void)Main_SetObjdir(writable, "%s%s", xpath.str, suffix);
1.260     christos  771:
1.499     rillig    772:        FStr_Done(&xpath);
                    773:        FStr_Done(&path);
1.252     christos  774:        return TRUE;
                    775: }
                    776:
1.462     rillig    777: /* Splits str into words, adding them to the list.
                    778:  * The string must be kept alive as long as the list. */
1.197     sjg       779: int
1.462     rillig    780: str2Lst_Append(StringList *lp, char *str)
1.176     sjg       781: {
1.453     rillig    782:        char *cp;
                    783:        int n;
1.176     sjg       784:
1.462     rillig    785:        const char *sep = " \t";
1.176     sjg       786:
1.453     rillig    787:        for (n = 0, cp = strtok(str, sep); cp; cp = strtok(NULL, sep)) {
                    788:                Lst_Append(lp, cp);
                    789:                n++;
                    790:        }
                    791:        return n;
1.176     sjg       792: }
                    793:
1.167     christos  794: #ifdef SIGINFO
                    795: /*ARGSUSED*/
                    796: static void
1.200     joerg     797: siginfo(int signo MAKE_ATTR_UNUSED)
1.167     christos  798: {
                    799:        char dir[MAXPATHLEN];
                    800:        char str[2 * MAXPATHLEN];
                    801:        int len;
1.426     rillig    802:        if (getcwd(dir, sizeof dir) == NULL)
1.167     christos  803:                return;
1.426     rillig    804:        len = snprintf(str, sizeof str, "%s: Working in: %s\n", progname, dir);
1.167     christos  805:        if (len > 0)
                    806:                (void)write(STDERR_FILENO, str, (size_t)len);
                    807: }
                    808: #endif
                    809:
1.500     rillig    810: /* Allow makefiles some control over the mode we run in. */
                    811: static void
                    812: MakeMode(void)
1.176     sjg       813: {
1.500     rillig    814:        FStr mode = FStr_InitRefer(NULL);
1.176     sjg       815:
1.500     rillig    816:        if (mode.str == NULL) {
                    817:                char *expanded;
1.453     rillig    818:                (void)Var_Subst("${" MAKE_MODE ":tl}",
1.500     rillig    819:                    VAR_GLOBAL, VARE_WANTRES, &expanded);
1.453     rillig    820:                /* TODO: handle errors */
1.500     rillig    821:                mode = FStr_InitOwn(expanded);
1.453     rillig    822:        }
1.176     sjg       823:
1.500     rillig    824:        if (mode.str[0] != '\0') {
                    825:                if (strstr(mode.str, "compat")) {
1.453     rillig    826:                        opts.compatMake = TRUE;
                    827:                        forceJobs = FALSE;
                    828:                }
1.190     sjg       829: #if USE_META
1.500     rillig    830:                if (strstr(mode.str, "meta"))
                    831:                        meta_mode_init(mode.str);
1.190     sjg       832: #endif
1.453     rillig    833:        }
1.238     christos  834:
1.500     rillig    835:        FStr_Done(&mode);
1.176     sjg       836: }
                    837:
1.266     christos  838: static void
1.383     rillig    839: PrintVar(const char *varname, Boolean expandVars)
                    840: {
                    841:        if (strchr(varname, '$')) {
1.384     rillig    842:                char *evalue;
                    843:                (void)Var_Subst(varname, VAR_GLOBAL, VARE_WANTRES, &evalue);
1.383     rillig    844:                /* TODO: handle errors */
1.384     rillig    845:                printf("%s\n", evalue);
                    846:                bmake_free(evalue);
                    847:
1.383     rillig    848:        } else if (expandVars) {
                    849:                char *expr = str_concat3("${", varname, "}");
1.384     rillig    850:                char *evalue;
                    851:                (void)Var_Subst(expr, VAR_GLOBAL, VARE_WANTRES, &evalue);
1.383     rillig    852:                /* TODO: handle errors */
                    853:                free(expr);
1.384     rillig    854:                printf("%s\n", evalue);
                    855:                bmake_free(evalue);
                    856:
1.383     rillig    857:        } else {
1.499     rillig    858:                FStr value = Var_Value(varname, VAR_GLOBAL);
                    859:                printf("%s\n", value.str != NULL ? value.str : "");
                    860:                FStr_Done(&value);
1.383     rillig    861:        }
                    862: }
                    863:
1.432     rillig    864: /*
                    865:  * Return a Boolean based on a variable.
                    866:  *
                    867:  * If the knob is not set, return the fallback.
                    868:  * If set, anything that looks or smells like "No", "False", "Off", "0", etc.
                    869:  * is FALSE, otherwise TRUE.
                    870:  */
                    871: static Boolean
                    872: GetBooleanVar(const char *varname, Boolean fallback)
                    873: {
1.453     rillig    874:        char *expr = str_concat3("${", varname, ":U}");
                    875:        char *value;
                    876:        Boolean res;
                    877:
                    878:        (void)Var_Subst(expr, VAR_GLOBAL, VARE_WANTRES, &value);
                    879:        /* TODO: handle errors */
                    880:        res = ParseBoolean(value, fallback);
                    881:        free(value);
                    882:        free(expr);
                    883:        return res;
1.432     rillig    884: }
                    885:
1.383     rillig    886: static void
1.266     christos  887: doPrintVars(void)
                    888: {
1.338     rillig    889:        StringListNode *ln;
1.266     christos  890:        Boolean expandVars;
                    891:
1.437     rillig    892:        if (opts.printVars == PVM_EXPANDED)
1.272     christos  893:                expandVars = TRUE;
1.394     rillig    894:        else if (opts.debugVflag)
1.266     christos  895:                expandVars = FALSE;
                    896:        else
1.432     rillig    897:                expandVars = GetBooleanVar(".MAKE.EXPAND_VARIABLES", FALSE);
1.266     christos  898:
1.485     rillig    899:        for (ln = opts.variables.first; ln != NULL; ln = ln->next) {
1.383     rillig    900:                const char *varname = ln->datum;
                    901:                PrintVar(varname, expandVars);
1.266     christos  902:        }
                    903: }
                    904:
                    905: static Boolean
                    906: runTargets(void)
                    907: {
1.488     rillig    908:        GNodeList targs = LST_INIT;     /* target nodes to create */
1.351     rillig    909:        Boolean outOfDate;      /* FALSE if all targets up to date */
1.266     christos  910:
                    911:        /*
                    912:         * Have now read the entire graph and need to make a list of
                    913:         * targets to create. If none was given on the command line,
                    914:         * we consult the parsing module to find the main target(s)
                    915:         * to create.
                    916:         */
1.486     rillig    917:        if (Lst_IsEmpty(&opts.create))
1.488     rillig    918:                Parse_MainName(&targs);
1.266     christos  919:        else
1.488     rillig    920:                Targ_FindList(&targs, &opts.create);
1.266     christos  921:
1.391     rillig    922:        if (!opts.compatMake) {
1.266     christos  923:                /*
                    924:                 * Initialize job module before traversing the graph
                    925:                 * now that any .BEGIN and .END targets have been read.
                    926:                 * This is done only if the -q flag wasn't given
                    927:                 * (to prevent the .BEGIN from being executed should
                    928:                 * it exist).
                    929:                 */
1.391     rillig    930:                if (!opts.queryFlag) {
1.266     christos  931:                        Job_Init();
                    932:                        jobsRunning = TRUE;
                    933:                }
                    934:
                    935:                /* Traverse the graph, checking on all the targets */
1.488     rillig    936:                outOfDate = Make_Run(&targs);
1.266     christos  937:        } else {
                    938:                /*
                    939:                 * Compat_Init will take care of creating all the
                    940:                 * targets as well as initializing the module.
                    941:                 */
1.488     rillig    942:                Compat_Run(&targs);
1.266     christos  943:                outOfDate = FALSE;
                    944:        }
1.488     rillig    945:        Lst_Done(&targs);       /* Don't free the nodes. */
1.266     christos  946:        return outOfDate;
                    947: }
                    948:
1.343     rillig    949: /*
                    950:  * Set up the .TARGETS variable to contain the list of targets to be
                    951:  * created. If none specified, make the variable empty -- the parser
                    952:  * will fill the thing in with the default or .MAIN target.
                    953:  */
                    954: static void
                    955: InitVarTargets(void)
                    956: {
                    957:        StringListNode *ln;
                    958:
1.486     rillig    959:        if (Lst_IsEmpty(&opts.create)) {
1.343     rillig    960:                Var_Set(".TARGETS", "", VAR_GLOBAL);
                    961:                return;
                    962:        }
                    963:
1.486     rillig    964:        for (ln = opts.create.first; ln != NULL; ln = ln->next) {
1.343     rillig    965:                char *name = ln->datum;
                    966:                Var_Append(".TARGETS", name, VAR_GLOBAL);
                    967:        }
                    968: }
                    969:
1.404     rillig    970: static void
                    971: InitRandom(void)
                    972: {
                    973:        struct timeval tv;
                    974:
                    975:        gettimeofday(&tv, NULL);
                    976:        srandom((unsigned int)(tv.tv_sec + tv.tv_usec));
                    977: }
                    978:
1.369     rillig    979: static const char *
1.451     rillig    980: InitVarMachine(const struct utsname *utsname)
1.369     rillig    981: {
                    982:        const char *machine = getenv("MACHINE");
                    983:        if (machine != NULL)
                    984:                return machine;
                    985:
1.458     rillig    986: #if defined(MAKE_NATIVE)
1.369     rillig    987:        return utsname->machine;
1.458     rillig    988: #elif defined(MAKE_MACHINE)
1.369     rillig    989:        return MAKE_MACHINE;
                    990: #else
                    991:        return "unknown";
                    992: #endif
                    993: }
                    994:
                    995: static const char *
1.451     rillig    996: InitVarMachineArch(void)
1.369     rillig    997: {
                    998:        const char *env = getenv("MACHINE_ARCH");
                    999:        if (env != NULL)
                   1000:                return env;
                   1001:
                   1002: #ifdef MAKE_NATIVE
                   1003:        {
                   1004:                struct utsname utsname;
1.426     rillig   1005:                static char machine_arch_buf[sizeof utsname.machine];
1.369     rillig   1006:                const int mib[2] = { CTL_HW, HW_MACHINE_ARCH };
1.426     rillig   1007:                size_t len = sizeof machine_arch_buf;
1.369     rillig   1008:
                   1009:                if (sysctl(mib, __arraycount(mib), machine_arch_buf,
                   1010:                        &len, NULL, 0) < 0) {
                   1011:                    (void)fprintf(stderr, "%s: sysctl failed (%s).\n", progname,
                   1012:                        strerror(errno));
                   1013:                    exit(2);
                   1014:                }
                   1015:
                   1016:                return machine_arch_buf;
                   1017:        }
1.457     rillig   1018: #elif defined(MACHINE_ARCH)
                   1019:        return MACHINE_ARCH;
                   1020: #elif defined(MAKE_MACHINE_ARCH)
1.369     rillig   1021:        return MAKE_MACHINE_ARCH;
                   1022: #else
                   1023:        return "unknown";
                   1024: #endif
                   1025: }
                   1026:
1.381     rillig   1027: #ifndef NO_PWD_OVERRIDE
                   1028: /*
                   1029:  * All this code is so that we know where we are when we start up
                   1030:  * on a different machine with pmake.
1.382     rillig   1031:  *
1.381     rillig   1032:  * Overriding getcwd() with $PWD totally breaks MAKEOBJDIRPREFIX
                   1033:  * since the value of curdir can vary depending on how we got
                   1034:  * here.  Ie sitting at a shell prompt (shell that provides $PWD)
                   1035:  * or via subdir.mk in which case its likely a shell which does
                   1036:  * not provide it.
1.382     rillig   1037:  *
1.381     rillig   1038:  * So, to stop it breaking this case only, we ignore PWD if
1.382     rillig   1039:  * MAKEOBJDIRPREFIX is set or MAKEOBJDIR contains a variable expression.
1.381     rillig   1040:  */
                   1041: static void
1.382     rillig   1042: HandlePWD(const struct stat *curdir_st)
1.381     rillig   1043: {
1.382     rillig   1044:        char *pwd;
1.499     rillig   1045:        FStr prefix, makeobjdir;
1.382     rillig   1046:        struct stat pwd_st;
1.381     rillig   1047:
                   1048:        if (ignorePWD || (pwd = getenv("PWD")) == NULL)
                   1049:                return;
                   1050:
1.499     rillig   1051:        prefix = Var_Value("MAKEOBJDIRPREFIX", VAR_CMDLINE);
                   1052:        if (prefix.str != NULL) {
                   1053:                FStr_Done(&prefix);
1.382     rillig   1054:                return;
1.381     rillig   1055:        }
1.382     rillig   1056:
1.499     rillig   1057:        makeobjdir = Var_Value("MAKEOBJDIR", VAR_CMDLINE);
                   1058:        if (makeobjdir.str != NULL && strchr(makeobjdir.str, '$') != NULL)
1.382     rillig   1059:                goto ignore_pwd;
                   1060:
                   1061:        if (stat(pwd, &pwd_st) == 0 &&
                   1062:            curdir_st->st_ino == pwd_st.st_ino &&
                   1063:            curdir_st->st_dev == pwd_st.st_dev)
                   1064:                (void)strncpy(curdir, pwd, MAXPATHLEN);
                   1065:
                   1066: ignore_pwd:
1.499     rillig   1067:        FStr_Done(&makeobjdir);
1.381     rillig   1068: }
                   1069: #endif
                   1070:
1.407     rillig   1071: /*
                   1072:  * Find the .OBJDIR.  If MAKEOBJDIRPREFIX, or failing that,
                   1073:  * MAKEOBJDIR is set in the environment, try only that value
                   1074:  * and fall back to .CURDIR if it does not exist.
                   1075:  *
                   1076:  * Otherwise, try _PATH_OBJDIR.MACHINE-MACHINE_ARCH, _PATH_OBJDIR.MACHINE,
                   1077:  * and * finally _PATH_OBJDIRPREFIX`pwd`, in that order.  If none
                   1078:  * of these paths exist, just use .CURDIR.
                   1079:  */
                   1080: static void
                   1081: InitObjdir(const char *machine, const char *machine_arch)
                   1082: {
1.456     sjg      1083:        Boolean writable;
                   1084:
1.491     rillig   1085:        Dir_InitCur(curdir);
1.456     sjg      1086:        writable = GetBooleanVar("MAKE_OBJDIR_CHECK_WRITABLE", TRUE);
                   1087:        (void)Main_SetObjdir(FALSE, "%s", curdir);
1.407     rillig   1088:
1.461     rillig   1089:        if (!SetVarObjdir(writable, "MAKEOBJDIRPREFIX", curdir) &&
                   1090:            !SetVarObjdir(writable, "MAKEOBJDIR", "") &&
1.456     sjg      1091:            !Main_SetObjdir(writable, "%s.%s-%s", _PATH_OBJDIR, machine, machine_arch) &&
                   1092:            !Main_SetObjdir(writable, "%s.%s", _PATH_OBJDIR, machine) &&
                   1093:            !Main_SetObjdir(writable, "%s", _PATH_OBJDIR))
                   1094:                (void)Main_SetObjdir(writable, "%s%s", _PATH_OBJDIRPREFIX, curdir);
1.407     rillig   1095: }
                   1096:
1.393     rillig   1097: /* get rid of resource limit on file descriptors */
                   1098: static void
                   1099: UnlimitFiles(void)
                   1100: {
                   1101: #if defined(MAKE_NATIVE) || (defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE))
                   1102:        struct rlimit rl;
                   1103:        if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
                   1104:            rl.rlim_cur != rl.rlim_max) {
                   1105:                rl.rlim_cur = rl.rlim_max;
                   1106:                (void)setrlimit(RLIMIT_NOFILE, &rl);
                   1107:        }
                   1108: #endif
                   1109: }
                   1110:
1.395     rillig   1111: static void
                   1112: CmdOpts_Init(void)
                   1113: {
1.494     rillig   1114:        opts.compatMake = FALSE;
                   1115:        opts.debug = DEBUG_NONE;
1.395     rillig   1116:        /* opts.debug_file has been initialized earlier */
1.501     rillig   1117:        opts.strict = FALSE;
1.395     rillig   1118:        opts.debugVflag = FALSE;
1.396     rillig   1119:        opts.checkEnvFirst = FALSE;
1.484     rillig   1120:        Lst_Init(&opts.makefiles);
1.395     rillig   1121:        opts.ignoreErrors = FALSE;      /* Pay attention to non-zero returns */
1.493     rillig   1122:        opts.maxJobs = 1;
1.395     rillig   1123:        opts.keepgoing = FALSE;         /* Stop on error */
                   1124:        opts.noRecursiveExecute = FALSE; /* Execute all .MAKE targets */
                   1125:        opts.noExecute = FALSE;         /* Execute all commands */
1.494     rillig   1126:        opts.queryFlag = FALSE;
1.395     rillig   1127:        opts.noBuiltins = FALSE;        /* Read the built-in rules */
                   1128:        opts.beSilent = FALSE;          /* Print commands as executed */
1.494     rillig   1129:        opts.touchFlag = FALSE;
1.437     rillig   1130:        opts.printVars = PVM_NONE;
1.485     rillig   1131:        Lst_Init(&opts.variables);
1.396     rillig   1132:        opts.parseWarnFatal = FALSE;
                   1133:        opts.enterFlag = FALSE;
                   1134:        opts.varNoExportEnv = FALSE;
1.486     rillig   1135:        Lst_Init(&opts.create);
1.395     rillig   1136: }
                   1137:
1.406     rillig   1138: /* Initialize MAKE and .MAKE to the path of the executable, so that it can be
                   1139:  * found by execvp(3) and the shells, even after a chdir.
                   1140:  *
                   1141:  * If it's a relative path and contains a '/', resolve it to an absolute path.
                   1142:  * Otherwise keep it as is, assuming it will be found in the PATH. */
1.397     rillig   1143: static void
1.406     rillig   1144: InitVarMake(const char *argv0)
1.405     rillig   1145: {
1.406     rillig   1146:        const char *make = argv0;
1.405     rillig   1147:
1.406     rillig   1148:        if (argv0[0] != '/' && strchr(argv0, '/') != NULL) {
                   1149:                char pathbuf[MAXPATHLEN];
1.502     rillig   1150:                const char *abspath = cached_realpath(argv0, pathbuf);
1.406     rillig   1151:                struct stat st;
1.502     rillig   1152:                if (abspath != NULL && abspath[0] == '/' &&
                   1153:                    stat(make, &st) == 0)
                   1154:                        make = abspath;
1.405     rillig   1155:        }
1.406     rillig   1156:
                   1157:        Var_Set("MAKE", make, VAR_GLOBAL);
                   1158:        Var_Set(".MAKE", make, VAR_GLOBAL);
1.405     rillig   1159: }
                   1160:
1.434     rillig   1161: /* Add the directories from the colon-separated syspath to defSysIncPath.
                   1162:  * After returning, the contents of syspath is unspecified. */
1.405     rillig   1163: static void
1.409     rillig   1164: InitDefSysIncPath(char *syspath)
1.397     rillig   1165: {
                   1166:        static char defsyspath[] = _PATH_DEFSYSPATH;
                   1167:        char *start, *cp;
                   1168:
                   1169:        /*
                   1170:         * If no user-supplied system path was given (through the -m option)
                   1171:         * add the directories from the DEFSYSPATH (more than one may be given
                   1172:         * as dir1:...:dirn) to the system include path.
                   1173:         */
                   1174:        if (syspath == NULL || syspath[0] == '\0')
                   1175:                syspath = defsyspath;
                   1176:        else
                   1177:                syspath = bmake_strdup(syspath);
                   1178:
                   1179:        for (start = syspath; *start != '\0'; start = cp) {
                   1180:                for (cp = start; *cp != '\0' && *cp != ':'; cp++)
                   1181:                        continue;
1.433     rillig   1182:                if (*cp == ':')
1.397     rillig   1183:                        *cp++ = '\0';
1.433     rillig   1184:
1.397     rillig   1185:                /* look for magic parent directory search string */
1.464     rillig   1186:                if (strncmp(start, ".../", 4) == 0) {
1.397     rillig   1187:                        char *dir = Dir_FindHereOrAbove(curdir, start + 4);
                   1188:                        if (dir != NULL) {
1.409     rillig   1189:                                (void)Dir_AddDir(defSysIncPath, dir);
1.397     rillig   1190:                                free(dir);
                   1191:                        }
1.464     rillig   1192:                } else {
                   1193:                        (void)Dir_AddDir(defSysIncPath, start);
1.397     rillig   1194:                }
                   1195:        }
                   1196:
                   1197:        if (syspath != defsyspath)
                   1198:                free(syspath);
                   1199: }
                   1200:
1.398     rillig   1201: static void
                   1202: ReadBuiltinRules(void)
                   1203: {
1.445     rillig   1204:        StringListNode *ln;
1.487     rillig   1205:        StringList sysMkPath = LST_INIT;
1.445     rillig   1206:
1.398     rillig   1207:        Dir_Expand(_PATH_DEFSYSMK,
1.453     rillig   1208:            Lst_IsEmpty(sysIncPath) ? defSysIncPath : sysIncPath,
1.487     rillig   1209:            &sysMkPath);
                   1210:        if (Lst_IsEmpty(&sysMkPath))
1.398     rillig   1211:                Fatal("%s: no system rules (%s).", progname, _PATH_DEFSYSMK);
1.445     rillig   1212:
1.487     rillig   1213:        for (ln = sysMkPath.first; ln != NULL; ln = ln->next)
1.445     rillig   1214:                if (ReadMakefile(ln->datum) == 0)
                   1215:                        break;
                   1216:
                   1217:        if (ln == NULL)
                   1218:                Fatal("%s: cannot open %s.",
1.487     rillig   1219:                    progname, (const char *)sysMkPath.first->datum);
1.445     rillig   1220:
                   1221:        /* Free the list but not the actual filenames since these may still
                   1222:         * be used in GNodes. */
1.487     rillig   1223:        Lst_Done(&sysMkPath);
1.398     rillig   1224: }
                   1225:
1.408     rillig   1226: static void
                   1227: InitMaxJobs(void)
                   1228: {
                   1229:        char *value;
                   1230:        int n;
                   1231:
                   1232:        if (forceJobs || opts.compatMake ||
                   1233:            !Var_Exists(".MAKE.JOBS", VAR_GLOBAL))
                   1234:                return;
                   1235:
                   1236:        (void)Var_Subst("${.MAKE.JOBS}", VAR_GLOBAL, VARE_WANTRES, &value);
                   1237:        /* TODO: handle errors */
                   1238:        n = (int)strtol(value, NULL, 0);
                   1239:        if (n < 1) {
                   1240:                (void)fprintf(stderr,
1.453     rillig   1241:                    "%s: illegal value for .MAKE.JOBS "
                   1242:                    "-- must be positive integer!\n",
                   1243:                    progname);
1.408     rillig   1244:                exit(1);
                   1245:        }
                   1246:
                   1247:        if (n != opts.maxJobs) {
                   1248:                Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
                   1249:                Var_Append(MAKEFLAGS, value, VAR_GLOBAL);
                   1250:        }
                   1251:
                   1252:        opts.maxJobs = n;
                   1253:        maxJobTokens = opts.maxJobs;
                   1254:        forceJobs = TRUE;
                   1255:        free(value);
                   1256: }
                   1257:
1.400     rillig   1258: /*
                   1259:  * For compatibility, look at the directories in the VPATH variable
                   1260:  * and add them to the search path, if the variable is defined. The
                   1261:  * variable's value is in the same format as the PATH environment
                   1262:  * variable, i.e. <directory>:<directory>:<directory>...
                   1263:  */
                   1264: static void
                   1265: InitVpath(void)
                   1266: {
                   1267:        char *vpath, savec, *path;
1.410     rillig   1268:        if (!Var_Exists("VPATH", VAR_CMDLINE))
1.400     rillig   1269:                return;
                   1270:
1.410     rillig   1271:        (void)Var_Subst("${VPATH}", VAR_CMDLINE, VARE_WANTRES, &vpath);
1.400     rillig   1272:        /* TODO: handle errors */
                   1273:        path = vpath;
                   1274:        do {
                   1275:                char *cp;
                   1276:                /* skip to end of directory */
                   1277:                for (cp = path; *cp != ':' && *cp != '\0'; cp++)
                   1278:                        continue;
                   1279:                /* Save terminator character so know when to stop */
                   1280:                savec = *cp;
                   1281:                *cp = '\0';
                   1282:                /* Add directory to search path */
1.490     rillig   1283:                (void)Dir_AddDir(&dirSearchPath, path);
1.400     rillig   1284:                *cp = savec;
                   1285:                path = cp + 1;
                   1286:        } while (savec == ':');
                   1287:        free(vpath);
                   1288: }
                   1289:
1.402     rillig   1290: static void
1.443     rillig   1291: ReadAllMakefiles(StringList *makefiles)
1.403     rillig   1292: {
1.443     rillig   1293:        StringListNode *ln;
1.403     rillig   1294:
1.443     rillig   1295:        for (ln = makefiles->first; ln != NULL; ln = ln->next) {
                   1296:                const char *fname = ln->datum;
                   1297:                if (ReadMakefile(fname) != 0)
                   1298:                        Fatal("%s: cannot open %s.", progname, fname);
1.403     rillig   1299:        }
                   1300: }
                   1301:
                   1302: static void
1.443     rillig   1303: ReadFirstDefaultMakefile(void)
                   1304: {
1.446     rillig   1305:        StringListNode *ln;
1.443     rillig   1306:        char *prefs;
1.446     rillig   1307:
1.443     rillig   1308:        (void)Var_Subst("${" MAKE_MAKEFILE_PREFERENCE "}",
1.453     rillig   1309:            VAR_CMDLINE, VARE_WANTRES, &prefs);
1.443     rillig   1310:        /* TODO: handle errors */
                   1311:
                   1312:        /* XXX: This should use a local list instead of opts.makefiles
                   1313:         * since these makefiles do not come from the command line.  They
                   1314:         * also have different semantics in that only the first file that
                   1315:         * is found is processed.  See ReadAllMakefiles. */
1.484     rillig   1316:        (void)str2Lst_Append(&opts.makefiles, prefs);
1.446     rillig   1317:
1.484     rillig   1318:        for (ln = opts.makefiles.first; ln != NULL; ln = ln->next)
1.446     rillig   1319:                if (ReadMakefile(ln->datum) == 0)
                   1320:                        break;
                   1321:
1.443     rillig   1322:        free(prefs);
                   1323: }
                   1324:
1.449     rillig   1325: /* Initialize variables such as MAKE, MACHINE, .MAKEFLAGS.
                   1326:  * Initialize a few modules.
                   1327:  * Parse the arguments from MAKEFLAGS and the command line. */
1.443     rillig   1328: static void
1.448     rillig   1329: main_Init(int argc, char **argv)
1.402     rillig   1330: {
1.381     rillig   1331:        struct stat sa;
1.369     rillig   1332:        const char *machine;
                   1333:        const char *machine_arch;
1.55      sjg      1334:        char *syspath = getenv("MAKESYSPATH");
1.119     tsutsui  1335:        struct utsname utsname;
1.107     sjg      1336:
1.154     apb      1337:        /* default to writing debug to stderr */
1.391     rillig   1338:        opts.debug_file = stderr;
1.133     dsl      1339:
1.469     rillig   1340:        HashTable_Init(&cached_realpaths);
                   1341:
1.167     christos 1342: #ifdef SIGINFO
1.188     sjg      1343:        (void)bmake_signal(SIGINFO, siginfo);
1.167     christos 1344: #endif
1.404     rillig   1345:
                   1346:        InitRandom();
1.277     rillig   1347:
1.498     rillig   1348:        progname = str_basename(argv[0]);
1.393     rillig   1349:
                   1350:        UnlimitFiles();
1.13      cgd      1351:
1.206     christos 1352:        if (uname(&utsname) == -1) {
1.447     rillig   1353:                (void)fprintf(stderr, "%s: uname failed (%s).\n", progname,
1.453     rillig   1354:                    strerror(errno));
1.447     rillig   1355:                exit(2);
1.206     christos 1356:        }
                   1357:
1.17      gwr      1358:        /*
                   1359:         * Get the name of this type of MACHINE from utsname
                   1360:         * so we can share an executable for similar machines.
                   1361:         * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
                   1362:         *
1.33      christos 1363:         * Note that both MACHINE and MACHINE_ARCH are decided at
                   1364:         * run-time.
1.17      gwr      1365:         */
1.451     rillig   1366:        machine = InitVarMachine(&utsname);
                   1367:        machine_arch = InitVarMachineArch();
1.33      christos 1368:
1.447     rillig   1369:        myPid = getpid();       /* remember this for vFork() */
1.183     sjg      1370:
1.1       cgd      1371:        /*
1.51      sjg      1372:         * Just in case MAKEOBJDIR wants us to do something tricky.
                   1373:         */
1.476     rillig   1374:        Targ_Init();
                   1375:        Var_Init();
1.277     rillig   1376:        Var_Set(".MAKE.OS", utsname.sysname, VAR_GLOBAL);
                   1377:        Var_Set("MACHINE", machine, VAR_GLOBAL);
                   1378:        Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL);
1.170     perry    1379: #ifdef MAKE_VERSION
1.277     rillig   1380:        Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL);
1.170     perry    1381: #endif
1.277     rillig   1382:        Var_Set(".newline", "\n", VAR_GLOBAL); /* handy for :@ loops */
1.176     sjg      1383:        /*
                   1384:         * This is the traditional preference for makefiles.
                   1385:         */
                   1386: #ifndef MAKEFILE_PREFERENCE_LIST
                   1387: # define MAKEFILE_PREFERENCE_LIST "makefile Makefile"
                   1388: #endif
1.453     rillig   1389:        Var_Set(MAKE_MAKEFILE_PREFERENCE, MAKEFILE_PREFERENCE_LIST, VAR_GLOBAL);
1.277     rillig   1390:        Var_Set(MAKE_DEPENDFILE, ".depend", VAR_GLOBAL);
1.51      sjg      1391:
1.395     rillig   1392:        CmdOpts_Init();
1.447     rillig   1393:        allPrecious = FALSE;    /* Remove targets when interrupted */
                   1394:        deleteOnError = FALSE;  /* Historical default behavior */
1.1       cgd      1395:        jobsRunning = FALSE;
                   1396:
1.391     rillig   1397:        maxJobTokens = opts.maxJobs;
1.174     sjg      1398:        ignorePWD = FALSE;
1.13      cgd      1399:
1.1       cgd      1400:        /*
                   1401:         * Initialize the parsing, directory and variable modules to prepare
                   1402:         * for the reading of inclusion paths and variable settings on the
                   1403:         * command line
                   1404:         */
1.36      gwr      1405:
                   1406:        /*
1.1       cgd      1407:         * Initialize various variables.
                   1408:         *      MAKE also gets this name, for compatibility
                   1409:         *      .MAKEFLAGS gets set to the empty string just in case.
                   1410:         *      MFLAGS also gets initialized empty, for compatibility.
                   1411:         */
1.79      tv       1412:        Parse_Init();
1.406     rillig   1413:        InitVarMake(argv[0]);
1.277     rillig   1414:        Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
                   1415:        Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL);
                   1416:        Var_Set("MFLAGS", "", VAR_GLOBAL);
                   1417:        Var_Set(".ALLTARGETS", "", VAR_GLOBAL);
1.217     sjg      1418:        /* some makefiles need to know this */
1.410     rillig   1419:        Var_Set(MAKE_LEVEL ".ENV", MAKE_LEVEL_ENV, VAR_CMDLINE);
1.1       cgd      1420:
1.447     rillig   1421:        /* Set some other useful variables. */
1.142     sjg      1422:        {
1.447     rillig   1423:                char tmp[64], *ep = getenv(MAKE_LEVEL_ENV);
1.142     sjg      1424:
1.447     rillig   1425:                makelevel = ep != NULL && ep[0] != '\0' ? atoi(ep) : 0;
                   1426:                if (makelevel < 0)
                   1427:                        makelevel = 0;
                   1428:                snprintf(tmp, sizeof tmp, "%d", makelevel);
                   1429:                Var_Set(MAKE_LEVEL, tmp, VAR_GLOBAL);
                   1430:                snprintf(tmp, sizeof tmp, "%u", myPid);
                   1431:                Var_Set(".MAKE.PID", tmp, VAR_GLOBAL);
                   1432:                snprintf(tmp, sizeof tmp, "%u", getppid());
                   1433:                Var_Set(".MAKE.PPID", tmp, VAR_GLOBAL);
1.480     sjg      1434:                snprintf(tmp, sizeof tmp, "%u", getuid());
                   1435:                Var_Set(".MAKE.UID", tmp, VAR_GLOBAL);
                   1436:                snprintf(tmp, sizeof tmp, "%u", getgid());
                   1437:                Var_Set(".MAKE.GID", tmp, VAR_GLOBAL);
1.142     sjg      1438:        }
1.220     christos 1439:        if (makelevel > 0) {
                   1440:                char pn[1024];
1.426     rillig   1441:                snprintf(pn, sizeof pn, "%s[%d]", progname, makelevel);
1.221     christos 1442:                progname = bmake_strdup(pn);
1.220     christos 1443:        }
1.142     sjg      1444:
1.210     sjg      1445: #ifdef USE_META
                   1446:        meta_init();
                   1447: #endif
1.306     rillig   1448:        Dir_Init();
1.255     sjg      1449:
1.142     sjg      1450:        /*
1.1       cgd      1451:         * First snag any flags out of the MAKE environment variable.
                   1452:         * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
                   1453:         * in a different format).
                   1454:         */
                   1455: #ifdef POSIX
1.412     rillig   1456:        {
1.447     rillig   1457:                char *p1 = explode(getenv("MAKEFLAGS"));
                   1458:                Main_ParseArgLine(p1);
                   1459:                free(p1);
1.412     rillig   1460:        }
1.1       cgd      1461: #else
                   1462:        Main_ParseArgLine(getenv("MAKE"));
                   1463: #endif
1.31      christos 1464:
1.1       cgd      1465:        /*
1.175     sjg      1466:         * Find where we are (now).
                   1467:         * We take care of PWD for the automounter below...
1.174     sjg      1468:         */
                   1469:        if (getcwd(curdir, MAXPATHLEN) == NULL) {
1.194     dholland 1470:                (void)fprintf(stderr, "%s: getcwd: %s.\n",
1.453     rillig   1471:                    progname, strerror(errno));
1.174     sjg      1472:                exit(2);
                   1473:        }
                   1474:
1.175     sjg      1475:        MainParseArgs(argc, argv);
                   1476:
1.391     rillig   1477:        if (opts.enterFlag)
1.220     christos 1478:                printf("%s: Entering directory `%s'\n", progname, curdir);
                   1479:
1.175     sjg      1480:        /*
                   1481:         * Verify that cwd is sane.
                   1482:         */
1.174     sjg      1483:        if (stat(curdir, &sa) == -1) {
1.447     rillig   1484:                (void)fprintf(stderr, "%s: %s: %s.\n",
1.453     rillig   1485:                    progname, curdir, strerror(errno));
1.447     rillig   1486:                exit(2);
1.174     sjg      1487:        }
                   1488:
1.222     sjg      1489: #ifndef NO_PWD_OVERRIDE
1.381     rillig   1490:        HandlePWD(&sa);
1.222     sjg      1491: #endif
1.277     rillig   1492:        Var_Set(".CURDIR", curdir, VAR_GLOBAL);
1.174     sjg      1493:
1.407     rillig   1494:        InitObjdir(machine, machine_arch);
1.174     sjg      1495:
                   1496:        /*
1.1       cgd      1497:         * Initialize archive, target and suffix modules in preparation for
                   1498:         * parsing the makefile(s)
                   1499:         */
                   1500:        Arch_Init();
                   1501:        Suff_Init();
1.58      sommerfe 1502:        Trace_Init(tracefile);
1.1       cgd      1503:
1.459     rillig   1504:        defaultNode = NULL;
1.1       cgd      1505:        (void)time(&now);
                   1506:
1.58      sommerfe 1507:        Trace_Log(MAKESTART, NULL);
1.279     rillig   1508:
1.343     rillig   1509:        InitVarTargets();
1.25      christos 1510:
1.409     rillig   1511:        InitDefSysIncPath(syspath);
1.448     rillig   1512: }
1.25      christos 1513:
1.449     rillig   1514: /* Read the system makefile followed by either makefile, Makefile or the
                   1515:  * files given by the -f option. Exit on parse errors. */
1.448     rillig   1516: static void
                   1517: main_ReadFiles(void)
                   1518: {
1.452     rillig   1519:
1.398     rillig   1520:        if (!opts.noBuiltins)
                   1521:                ReadBuiltinRules();
1.452     rillig   1522:
1.484     rillig   1523:        if (!Lst_IsEmpty(&opts.makefiles))
                   1524:                ReadAllMakefiles(&opts.makefiles);
1.443     rillig   1525:        else
                   1526:                ReadFirstDefaultMakefile();
1.448     rillig   1527: }
1.436     rillig   1528:
1.449     rillig   1529: /* Compute the dependency graph. */
1.448     rillig   1530: static void
                   1531: main_PrepareMaking(void)
                   1532: {
1.138     dsl      1533:        /* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */
1.437     rillig   1534:        if (!opts.noBuiltins || opts.printVars == PVM_NONE) {
1.503     sjg      1535:                (void)Var_Subst("${.MAKE.DEPENDFILE}",
1.453     rillig   1536:                    VAR_CMDLINE, VARE_WANTRES, &makeDependfile);
1.447     rillig   1537:                if (makeDependfile[0] != '\0') {
                   1538:                        /* TODO: handle errors */
                   1539:                        doing_depend = TRUE;
                   1540:                        (void)ReadMakefile(makeDependfile);
                   1541:                        doing_depend = FALSE;
                   1542:                }
1.145     dsl      1543:        }
1.1       cgd      1544:
1.233     sjg      1545:        if (enterFlagObj)
                   1546:                printf("%s: Entering directory `%s'\n", progname, objdir);
1.279     rillig   1547:
1.500     rillig   1548:        MakeMode();
1.176     sjg      1549:
1.412     rillig   1550:        {
1.499     rillig   1551:                FStr makeflags = Var_Value(MAKEFLAGS, VAR_GLOBAL);
                   1552:                Var_Append("MFLAGS", makeflags.str, VAR_GLOBAL);
                   1553:                FStr_Done(&makeflags);
1.412     rillig   1554:        }
1.1       cgd      1555:
1.408     rillig   1556:        InitMaxJobs();
1.243     matthias 1557:
                   1558:        /*
1.447     rillig   1559:         * Be compatible if the user did not specify -j and did not explicitly
                   1560:         * turn compatibility on.
1.243     matthias 1561:         */
1.447     rillig   1562:        if (!opts.compatMake && !forceJobs)
                   1563:                opts.compatMake = TRUE;
1.243     matthias 1564:
1.391     rillig   1565:        if (!opts.compatMake)
1.447     rillig   1566:                Job_ServerStart(maxJobTokens, jp_0, jp_1);
1.352     rillig   1567:        DEBUG5(JOB, "job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n",
1.453     rillig   1568:            jp_0, jp_1, opts.maxJobs, maxJobTokens, opts.compatMake ? 1 : 0);
1.58      sommerfe 1569:
1.437     rillig   1570:        if (opts.printVars == PVM_NONE)
1.447     rillig   1571:                Main_ExportMAKEFLAGS(TRUE);     /* initial export */
1.279     rillig   1572:
1.400     rillig   1573:        InitVpath();
1.1       cgd      1574:
                   1575:        /*
                   1576:         * Now that all search paths have been read for suffixes et al, it's
                   1577:         * time to add the default search path to their lists...
                   1578:         */
                   1579:        Suff_DoPaths();
1.50      mycroft  1580:
                   1581:        /*
                   1582:         * Propagate attributes through :: dependency lists.
                   1583:         */
                   1584:        Targ_Propagate();
1.1       cgd      1585:
                   1586:        /* print the initial graph, if the user requested it */
                   1587:        if (DEBUG(GRAPH1))
                   1588:                Targ_PrintGraph(1);
1.448     rillig   1589: }
1.1       cgd      1590:
1.449     rillig   1591: /* Make the targets.
                   1592:  * If the -v or -V options are given, print variables instead.
1.465     rillig   1593:  * Return whether any of the targets is out-of-date. */
1.448     rillig   1594: static Boolean
                   1595: main_Run(void)
                   1596: {
1.437     rillig   1597:        if (opts.printVars != PVM_NONE) {
1.465     rillig   1598:                /* print the values of any variables requested by the user */
1.266     christos 1599:                doPrintVars();
1.448     rillig   1600:                return FALSE;
1.138     dsl      1601:        } else {
1.448     rillig   1602:                return runTargets();
1.31      christos 1603:        }
1.448     rillig   1604: }
                   1605:
1.449     rillig   1606: /* Clean up after making the targets. */
1.448     rillig   1607: static void
                   1608: main_CleanUp(void)
                   1609: {
                   1610: #ifdef CLEANUP
1.485     rillig   1611:        Lst_DoneCall(&opts.variables, free);
1.484     rillig   1612:        /*
                   1613:         * Don't free the actual strings from opts.makefiles, they may be
                   1614:         * used in GNodes.
                   1615:         */
                   1616:        Lst_Done(&opts.makefiles);
1.489     rillig   1617:        Lst_DoneCall(&opts.create, free);
1.448     rillig   1618: #endif
                   1619:
                   1620:        /* print the graph now it's been processed if the user requested it */
                   1621:        if (DEBUG(GRAPH2))
                   1622:                Targ_PrintGraph(2);
1.31      christos 1623:
1.448     rillig   1624:        Trace_Log(MAKEEND, NULL);
                   1625:
                   1626:        if (enterFlagObj)
                   1627:                printf("%s: Leaving directory `%s'\n", progname, objdir);
                   1628:        if (opts.enterFlag)
                   1629:                printf("%s: Leaving directory `%s'\n", progname, curdir);
1.14      jtc      1630:
1.448     rillig   1631: #ifdef USE_META
                   1632:        meta_finish();
                   1633: #endif
                   1634:        Suff_End();
                   1635:        Targ_End();
                   1636:        Arch_End();
                   1637:        Var_End();
                   1638:        Parse_End();
                   1639:        Dir_End();
                   1640:        Job_End();
                   1641:        Trace_End();
                   1642: }
                   1643:
1.449     rillig   1644: /* Determine the exit code. */
1.448     rillig   1645: static int
                   1646: main_Exit(Boolean outOfDate)
                   1647: {
1.501     rillig   1648:        if (opts.strict && (main_errors > 0 || Parse_GetFatals() > 0))
1.447     rillig   1649:                return 2;       /* Not 1 so -q can distinguish error */
1.137     dsl      1650:        return outOfDate ? 1 : 0;
1.1       cgd      1651: }
                   1652:
1.448     rillig   1653: int
                   1654: main(int argc, char **argv)
                   1655: {
                   1656:        Boolean outOfDate;
                   1657:
                   1658:        main_Init(argc, argv);
                   1659:        main_ReadFiles();
                   1660:        main_PrepareMaking();
                   1661:        outOfDate = main_Run();
                   1662:        main_CleanUp();
                   1663:        return main_Exit(outOfDate);
                   1664: }
                   1665:
1.321     rillig   1666: /* Open and parse the given makefile, with all its side effects.
1.1       cgd      1667:  *
                   1668:  * Results:
1.124     sjg      1669:  *     0 if ok. -1 if couldn't open file.
1.1       cgd      1670:  */
1.124     sjg      1671: static int
1.325     rillig   1672: ReadMakefile(const char *fname)
1.1       cgd      1673: {
1.140     dsl      1674:        int fd;
1.304     rillig   1675:        char *name, *path = NULL;
1.1       cgd      1676:
1.454     rillig   1677:        if (strcmp(fname, "-") == 0) {
1.193     dholland 1678:                Parse_File(NULL /*stdin*/, -1);
1.277     rillig   1679:                Var_Set("MAKEFILE", "", VAR_INTERNAL);
1.1       cgd      1680:        } else {
                   1681:                /* if we've chdir'd, rebuild the path name */
1.454     rillig   1682:                if (strcmp(curdir, objdir) != 0 && *fname != '/') {
1.304     rillig   1683:                        path = str_concat3(curdir, "/", fname);
1.140     dsl      1684:                        fd = open(path, O_RDONLY);
                   1685:                        if (fd != -1) {
1.1       cgd      1686:                                fname = path;
                   1687:                                goto found;
                   1688:                        }
1.309     rillig   1689:                        free(path);
1.279     rillig   1690:
1.95      jmc      1691:                        /* If curdir failed, try objdir (ala .depend) */
1.304     rillig   1692:                        path = str_concat3(objdir, "/", fname);
1.140     dsl      1693:                        fd = open(path, O_RDONLY);
                   1694:                        if (fd != -1) {
1.95      jmc      1695:                                fname = path;
                   1696:                                goto found;
                   1697:                        }
1.140     dsl      1698:                } else {
                   1699:                        fd = open(fname, O_RDONLY);
                   1700:                        if (fd != -1)
                   1701:                                goto found;
                   1702:                }
1.1       cgd      1703:                /* look in -I and system include directories. */
                   1704:                name = Dir_FindFile(fname, parseIncPath);
1.454     rillig   1705:                if (name == NULL) {
1.409     rillig   1706:                        SearchPath *sysInc = Lst_IsEmpty(sysIncPath)
                   1707:                                             ? defSysIncPath : sysIncPath;
                   1708:                        name = Dir_FindFile(fname, sysInc);
                   1709:                }
1.454     rillig   1710:                if (name == NULL || (fd = open(name, O_RDONLY)) == -1) {
1.238     christos 1711:                        free(name);
1.48      christos 1712:                        free(path);
1.278     rillig   1713:                        return -1;
1.48      christos 1714:                }
1.1       cgd      1715:                fname = name;
                   1716:                /*
                   1717:                 * set the MAKEFILE variable desired by System V fans -- the
                   1718:                 * placement of the setting here means it gets set to the last
                   1719:                 * makefile specified, as it is set by SysV make.
                   1720:                 */
1.67      sjg      1721: found:
1.176     sjg      1722:                if (!doing_depend)
1.277     rillig   1723:                        Var_Set("MAKEFILE", fname, VAR_INTERNAL);
1.140     dsl      1724:                Parse_File(fname, fd);
1.1       cgd      1725:        }
1.48      christos 1726:        free(path);
1.278     rillig   1727:        return 0;
1.54      sjg      1728: }
                   1729:
1.29      christos 1730: /*-
                   1731:  * Cmd_Exec --
                   1732:  *     Execute the command in cmd, and return the output of that command
1.302     rillig   1733:  *     in a string.  In the output, newlines are replaced with spaces.
1.29      christos 1734:  *
                   1735:  * Results:
1.293     rillig   1736:  *     A string containing the output of the command, or the empty string.
                   1737:  *     *errfmt returns a format string describing the command failure,
                   1738:  *     if any, using a single %s conversion specification.
1.29      christos 1739:  *
                   1740:  * Side Effects:
                   1741:  *     The string must be freed by the caller.
                   1742:  */
                   1743: char *
1.293     rillig   1744: Cmd_Exec(const char *cmd, const char **errfmt)
1.29      christos 1745: {
1.453     rillig   1746:        const char *args[4];    /* Args for invoking the shell */
1.482     rillig   1747:        int pipefds[2];
1.453     rillig   1748:        int cpid;               /* Child PID */
                   1749:        int pid;                /* PID from wait() */
                   1750:        int status;             /* command exit status */
                   1751:        Buffer buf;             /* buffer to store the result */
                   1752:        ssize_t bytes_read;
                   1753:        char *res;              /* result */
                   1754:        size_t res_len;
                   1755:        char *cp;
                   1756:        int savederr;           /* saved errno */
                   1757:
                   1758:        *errfmt = NULL;
                   1759:
                   1760:        if (!shellName)
                   1761:                Shell_Init();
                   1762:        /*
                   1763:         * Set up arguments for shell
1.29      christos 1764:         */
1.453     rillig   1765:        args[0] = shellName;
                   1766:        args[1] = "-c";
                   1767:        args[2] = cmd;
                   1768:        args[3] = NULL;
1.31      christos 1769:
1.453     rillig   1770:        /*
                   1771:         * Open a pipe for fetching its output
                   1772:         */
1.482     rillig   1773:        if (pipe(pipefds) == -1) {
1.453     rillig   1774:                *errfmt = "Couldn't create pipe for \"%s\"";
                   1775:                goto bad;
                   1776:        }
                   1777:
1.504   ! rillig   1778:        Var_ReexportVars();
        !          1779:
1.453     rillig   1780:        /*
                   1781:         * Fork
                   1782:         */
                   1783:        switch (cpid = vFork()) {
                   1784:        case 0:
1.482     rillig   1785:                (void)close(pipefds[0]); /* Close input side of pipe */
1.453     rillig   1786:
                   1787:                /*
                   1788:                 * Duplicate the output stream to the shell's output, then
                   1789:                 * shut the extra thing down. Note we don't fetch the error
                   1790:                 * stream...why not? Why?
                   1791:                 */
1.482     rillig   1792:                (void)dup2(pipefds[1], 1);
                   1793:                (void)close(pipefds[1]);
1.143     sjg      1794:
1.453     rillig   1795:                (void)execv(shellPath, UNCONST(args));
                   1796:                _exit(1);
                   1797:                /*NOTREACHED*/
                   1798:
                   1799:        case -1:
                   1800:                *errfmt = "Couldn't exec \"%s\"";
                   1801:                goto bad;
1.29      christos 1802:
1.453     rillig   1803:        default:
1.482     rillig   1804:                (void)close(pipefds[1]); /* No need for the writing half */
1.31      christos 1805:
1.453     rillig   1806:                savederr = 0;
                   1807:                Buf_Init(&buf);
1.29      christos 1808:
1.453     rillig   1809:                do {
                   1810:                        char result[BUFSIZ];
1.482     rillig   1811:                        bytes_read = read(pipefds[0], result, sizeof result);
1.453     rillig   1812:                        if (bytes_read > 0)
                   1813:                                Buf_AddBytes(&buf, result, (size_t)bytes_read);
                   1814:                } while (bytes_read > 0 ||
                   1815:                         (bytes_read == -1 && errno == EINTR));
                   1816:                if (bytes_read == -1)
                   1817:                        savederr = errno;
                   1818:
1.482     rillig   1819:                (void)close(pipefds[0]); /* Close the input side of the pipe. */
1.453     rillig   1820:
                   1821:                /* Wait for the process to exit. */
                   1822:                while ((pid = waitpid(cpid, &status, 0)) != cpid && pid >= 0)
                   1823:                        JobReapChild(pid, status, FALSE);
                   1824:
                   1825:                res_len = Buf_Len(&buf);
                   1826:                res = Buf_Destroy(&buf, FALSE);
                   1827:
                   1828:                if (savederr != 0)
                   1829:                        *errfmt = "Couldn't read shell's output for \"%s\"";
                   1830:
                   1831:                if (WIFSIGNALED(status))
                   1832:                        *errfmt = "\"%s\" exited on a signal";
                   1833:                else if (WEXITSTATUS(status) != 0)
                   1834:                        *errfmt = "\"%s\" returned non-zero status";
                   1835:
                   1836:                /* Convert newlines to spaces.  A final newline is just stripped */
                   1837:                if (res_len > 0 && res[res_len - 1] == '\n')
                   1838:                        res[res_len - 1] = '\0';
                   1839:                for (cp = res; *cp != '\0'; cp++)
                   1840:                        if (*cp == '\n')
                   1841:                                *cp = ' ';
                   1842:                break;
                   1843:        }
                   1844:        return res;
1.29      christos 1845: bad:
1.453     rillig   1846:        return bmake_strdup("");
1.1       cgd      1847: }
                   1848:
1.369     rillig   1849: /* Print a printf-style error message.
1.1       cgd      1850:  *
1.431     rillig   1851:  * In default mode, this error message has no consequences, in particular it
                   1852:  * does not affect the exit status.  Only in lint mode (-dL) it does. */
1.1       cgd      1853: void
1.89      christos 1854: Error(const char *fmt, ...)
1.1       cgd      1855: {
                   1856:        va_list ap;
1.162     dsl      1857:        FILE *err_file;
1.85      wiz      1858:
1.391     rillig   1859:        err_file = opts.debug_file;
1.162     dsl      1860:        if (err_file == stdout)
                   1861:                err_file = stderr;
1.184     sjg      1862:        (void)fflush(stdout);
1.162     dsl      1863:        for (;;) {
                   1864:                va_start(ap, fmt);
                   1865:                fprintf(err_file, "%s: ", progname);
                   1866:                (void)vfprintf(err_file, fmt, ap);
                   1867:                va_end(ap);
                   1868:                (void)fprintf(err_file, "\n");
                   1869:                (void)fflush(err_file);
                   1870:                if (err_file == stderr)
                   1871:                        break;
                   1872:                err_file = stderr;
                   1873:        }
1.481     rillig   1874:        main_errors++;
1.1       cgd      1875: }
                   1876:
1.465     rillig   1877: /* Wait for any running jobs to finish, then produce an error message,
                   1878:  * finally exit immediately.
1.1       cgd      1879:  *
1.465     rillig   1880:  * Exiting immediately differs from Parse_Error, which exits only after the
                   1881:  * current top-level makefile has been parsed completely. */
1.1       cgd      1882: void
1.89      christos 1883: Fatal(const char *fmt, ...)
1.1       cgd      1884: {
                   1885:        va_list ap;
1.85      wiz      1886:
1.1       cgd      1887:        if (jobsRunning)
                   1888:                Job_Wait();
                   1889:
1.184     sjg      1890:        (void)fflush(stdout);
1.465     rillig   1891:        va_start(ap, fmt);
1.1       cgd      1892:        (void)vfprintf(stderr, fmt, ap);
                   1893:        va_end(ap);
                   1894:        (void)fprintf(stderr, "\n");
                   1895:        (void)fflush(stderr);
                   1896:
1.176     sjg      1897:        PrintOnError(NULL, NULL);
1.67      sjg      1898:
1.94      dsl      1899:        if (DEBUG(GRAPH2) || DEBUG(GRAPH3))
1.1       cgd      1900:                Targ_PrintGraph(2);
1.433     rillig   1901:        Trace_Log(MAKEERROR, NULL);
1.1       cgd      1902:        exit(2);                /* Not 1 so -q can distinguish error */
                   1903: }
                   1904:
1.392     rillig   1905: /* Major exception once jobs are being created.
                   1906:  * Kills all jobs, prints a message and exits. */
1.1       cgd      1907: void
1.89      christos 1908: Punt(const char *fmt, ...)
1.1       cgd      1909: {
                   1910:        va_list ap;
1.85      wiz      1911:
1.13      cgd      1912:        va_start(ap, fmt);
1.184     sjg      1913:        (void)fflush(stdout);
1.63      christos 1914:        (void)fprintf(stderr, "%s: ", progname);
1.1       cgd      1915:        (void)vfprintf(stderr, fmt, ap);
                   1916:        va_end(ap);
                   1917:        (void)fprintf(stderr, "\n");
                   1918:        (void)fflush(stderr);
                   1919:
1.176     sjg      1920:        PrintOnError(NULL, NULL);
1.67      sjg      1921:
1.1       cgd      1922:        DieHorribly();
                   1923: }
                   1924:
1.392     rillig   1925: /* Exit without giving a message. */
1.1       cgd      1926: void
1.85      wiz      1927: DieHorribly(void)
1.1       cgd      1928: {
                   1929:        if (jobsRunning)
                   1930:                Job_AbortAll();
                   1931:        if (DEBUG(GRAPH2))
                   1932:                Targ_PrintGraph(2);
1.433     rillig   1933:        Trace_Log(MAKEERROR, NULL);
1.1       cgd      1934:        exit(2);                /* Not 1, so -q can distinguish error */
                   1935: }
                   1936:
1.392     rillig   1937: /* Called when aborting due to errors in child shell to signal abnormal exit.
                   1938:  * The program exits.
                   1939:  * Errors is the number of errors encountered in Make_Make. */
1.1       cgd      1940: void
1.421     rillig   1941: Finish(int errs)
1.1       cgd      1942: {
1.429     rillig   1943:        if (shouldDieQuietly(NULL, -1))
1.275     sjg      1944:                exit(2);
1.421     rillig   1945:        Fatal("%d error%s", errs, errs == 1 ? "" : "s");
1.1       cgd      1946: }
                   1947:
1.21      christos 1948: /*
1.208     dholland 1949:  * eunlink --
1.21      christos 1950:  *     Remove a file carefully, avoiding directories.
                   1951:  */
                   1952: int
1.85      wiz      1953: eunlink(const char *file)
1.21      christos 1954: {
                   1955:        struct stat st;
                   1956:
                   1957:        if (lstat(file, &st) == -1)
                   1958:                return -1;
                   1959:
                   1960:        if (S_ISDIR(st.st_mode)) {
                   1961:                errno = EISDIR;
                   1962:                return -1;
                   1963:        }
                   1964:        return unlink(file);
1.1       cgd      1965: }
                   1966:
1.373     rillig   1967: static void
                   1968: write_all(int fd, const void *data, size_t n)
                   1969: {
                   1970:        const char *mem = data;
                   1971:
                   1972:        while (n > 0) {
                   1973:                ssize_t written = write(fd, mem, n);
                   1974:                if (written == -1 && errno == EAGAIN)
                   1975:                        continue;
                   1976:                if (written == -1)
                   1977:                        break;
                   1978:                mem += written;
1.375     rillig   1979:                n -= (size_t)written;
1.373     rillig   1980:        }
                   1981: }
                   1982:
1.1       cgd      1983: /*
1.372     rillig   1984:  * execDie --
1.66      christos 1985:  *     Print why exec failed, avoiding stdio.
                   1986:  */
1.372     rillig   1987: void MAKE_ATTR_DEAD
                   1988: execDie(const char *af, const char *av)
1.66      christos 1989: {
1.373     rillig   1990:        Buffer buf;
                   1991:
1.435     rillig   1992:        Buf_Init(&buf);
1.373     rillig   1993:        Buf_AddStr(&buf, progname);
                   1994:        Buf_AddStr(&buf, ": ");
                   1995:        Buf_AddStr(&buf, af);
                   1996:        Buf_AddStr(&buf, "(");
                   1997:        Buf_AddStr(&buf, av);
                   1998:        Buf_AddStr(&buf, ") failed (");
                   1999:        Buf_AddStr(&buf, strerror(errno));
                   2000:        Buf_AddStr(&buf, ")\n");
1.66      christos 2001:
1.373     rillig   2002:        write_all(STDERR_FILENO, Buf_GetAll(&buf, NULL), Buf_Len(&buf));
1.66      christos 2003:
1.373     rillig   2004:        Buf_Destroy(&buf, TRUE);
1.372     rillig   2005:        _exit(1);
1.66      christos 2006: }
                   2007:
1.262     riastrad 2008: /* purge any relative paths */
                   2009: static void
1.469     rillig   2010: purge_relative_cached_realpaths(void)
1.262     riastrad 2011: {
1.453     rillig   2012:        HashEntry *he, *nhe;
                   2013:        HashIter hi;
                   2014:
1.469     rillig   2015:        HashIter_Init(&hi, &cached_realpaths);
1.453     rillig   2016:        he = HashIter_Next(&hi);
                   2017:        while (he != NULL) {
                   2018:                nhe = HashIter_Next(&hi);
                   2019:                if (he->key[0] != '/') {
1.469     rillig   2020:                        DEBUG1(DIR, "cached_realpath: purging %s\n", he->key);
                   2021:                        HashTable_DeleteEntry(&cached_realpaths, he);
                   2022:                        /* XXX: What about the allocated he->value? Either
                   2023:                         * free them or document why they cannot be freed. */
1.453     rillig   2024:                }
                   2025:                he = nhe;
1.262     riastrad 2026:        }
                   2027: }
                   2028:
1.245     sjg      2029: char *
                   2030: cached_realpath(const char *pathname, char *resolved)
                   2031: {
1.453     rillig   2032:        const char *rp;
                   2033:
                   2034:        if (pathname == NULL || pathname[0] == '\0')
                   2035:                return NULL;
                   2036:
1.469     rillig   2037:        rp = HashTable_FindValue(&cached_realpaths, pathname);
                   2038:        if (rp != NULL) {
1.453     rillig   2039:                /* a hit */
                   2040:                strncpy(resolved, rp, MAXPATHLEN);
                   2041:                resolved[MAXPATHLEN - 1] = '\0';
1.469     rillig   2042:                return resolved;
                   2043:        }
                   2044:
                   2045:        rp = realpath(pathname, resolved);
                   2046:        if (rp != NULL) {
                   2047:                HashTable_Set(&cached_realpaths, pathname, bmake_strdup(rp));
                   2048:                DEBUG2(DIR, "cached_realpath: %s -> %s\n", pathname, rp);
                   2049:                return resolved;
                   2050:        }
1.248     christos 2051:
1.469     rillig   2052:        /* should we negative-cache? */
                   2053:        return NULL;
1.245     sjg      2054: }
                   2055:
1.275     sjg      2056: /*
                   2057:  * Return true if we should die without noise.
1.429     rillig   2058:  * For example our failing child was a sub-make or failure happened elsewhere.
1.275     sjg      2059:  */
1.429     rillig   2060: Boolean
                   2061: shouldDieQuietly(GNode *gn, int bf)
1.275     sjg      2062: {
1.453     rillig   2063:        static int quietly = -1;
1.275     sjg      2064:
1.453     rillig   2065:        if (quietly < 0) {
                   2066:                if (DEBUG(JOB) || !GetBooleanVar(".MAKE.DIE_QUIETLY", TRUE))
                   2067:                        quietly = 0;
                   2068:                else if (bf >= 0)
                   2069:                        quietly = bf;
                   2070:                else
                   2071:                        quietly = gn != NULL && (gn->type & OP_MAKE);
                   2072:        }
                   2073:        return quietly;
1.275     sjg      2074: }
                   2075:
1.385     rillig   2076: static void
                   2077: SetErrorVars(GNode *gn)
                   2078: {
1.453     rillig   2079:        StringListNode *ln;
1.385     rillig   2080:
1.453     rillig   2081:        /*
                   2082:         * We can print this even if there is no .ERROR target.
                   2083:         */
                   2084:        Var_Set(".ERROR_TARGET", gn->name, VAR_GLOBAL);
                   2085:        Var_Delete(".ERROR_CMD", VAR_GLOBAL);
                   2086:
1.483     rillig   2087:        for (ln = gn->commands.first; ln != NULL; ln = ln->next) {
1.453     rillig   2088:                const char *cmd = ln->datum;
                   2089:
                   2090:                if (cmd == NULL)
                   2091:                        break;
                   2092:                Var_Append(".ERROR_CMD", cmd, VAR_GLOBAL);
                   2093:        }
1.385     rillig   2094: }
                   2095:
1.472     rillig   2096: /* Print some helpful information in case of an error.
                   2097:  * The caller should exit soon after calling this function. */
1.67      sjg      2098: void
1.472     rillig   2099: PrintOnError(GNode *gn, const char *msg)
1.67      sjg      2100: {
1.472     rillig   2101:        static GNode *errorNode = NULL;
1.283     sjg      2102:
1.453     rillig   2103:        if (DEBUG(HASH)) {
                   2104:                Targ_Stats();
                   2105:                Var_Stats();
                   2106:        }
                   2107:
                   2108:        /* we generally want to keep quiet if a sub-make died */
                   2109:        if (shouldDieQuietly(gn, -1))
                   2110:                return;
                   2111:
1.472     rillig   2112:        if (msg != NULL)
                   2113:                printf("%s", msg);
1.453     rillig   2114:        printf("\n%s: stopped in %s\n", progname, curdir);
1.279     rillig   2115:
1.472     rillig   2116:        if (errorNode != NULL)
1.453     rillig   2117:                return;         /* we've been here! */
1.472     rillig   2118:
                   2119:        if (gn != NULL)
1.453     rillig   2120:                SetErrorVars(gn);
1.472     rillig   2121:
                   2122:        {
                   2123:                char *errorVarsValues;
                   2124:                (void)Var_Subst("${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}",
                   2125:                                VAR_GLOBAL, VARE_WANTRES, &errorVarsValues);
                   2126:                /* TODO: handle errors */
                   2127:                printf("%s", errorVarsValues);
                   2128:                free(errorVarsValues);
                   2129:        }
                   2130:
1.453     rillig   2131:        fflush(stdout);
1.176     sjg      2132:
1.453     rillig   2133:        /*
                   2134:         * Finally, see if there is a .ERROR target, and run it if so.
                   2135:         */
1.472     rillig   2136:        errorNode = Targ_FindNode(".ERROR");
                   2137:        if (errorNode != NULL) {
                   2138:                errorNode->type |= OP_SPECIAL;
                   2139:                Compat_Make(errorNode, errorNode);
1.453     rillig   2140:        }
1.68      sjg      2141: }
                   2142:
                   2143: void
1.85      wiz      2144: Main_ExportMAKEFLAGS(Boolean first)
1.68      sjg      2145: {
1.453     rillig   2146:        static Boolean once = TRUE;
                   2147:        const char *expr;
                   2148:        char *s;
1.68      sjg      2149:
1.453     rillig   2150:        if (once != first)
                   2151:                return;
                   2152:        once = FALSE;
1.279     rillig   2153:
1.453     rillig   2154:        expr = "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}";
                   2155:        (void)Var_Subst(expr, VAR_CMDLINE, VARE_WANTRES, &s);
                   2156:        /* TODO: handle errors */
                   2157:        if (s[0] != '\0') {
1.68      sjg      2158: #ifdef POSIX
1.453     rillig   2159:                setenv("MAKEFLAGS", s, 1);
1.68      sjg      2160: #else
1.453     rillig   2161:                setenv("MAKE", s, 1);
1.68      sjg      2162: #endif
1.453     rillig   2163:        }
1.1       cgd      2164: }
1.180     sjg      2165:
1.191     sjg      2166: char *
                   2167: getTmpdir(void)
1.180     sjg      2168: {
1.453     rillig   2169:        static char *tmpdir = NULL;
1.473     rillig   2170:        struct stat st;
                   2171:
                   2172:        if (tmpdir != NULL)
                   2173:                return tmpdir;
1.180     sjg      2174:
1.473     rillig   2175:        /* Honor $TMPDIR but only if it is valid. Ensure it ends with '/'. */
                   2176:        (void)Var_Subst("${TMPDIR:tA:U" _PATH_TMP "}/",
                   2177:            VAR_GLOBAL, VARE_WANTRES, &tmpdir);
                   2178:        /* TODO: handle errors */
1.180     sjg      2179:
1.473     rillig   2180:        if (stat(tmpdir, &st) < 0 || !S_ISDIR(st.st_mode)) {
                   2181:                free(tmpdir);
                   2182:                tmpdir = bmake_strdup(_PATH_TMP);
1.180     sjg      2183:        }
1.453     rillig   2184:        return tmpdir;
1.191     sjg      2185: }
                   2186:
                   2187: /*
                   2188:  * Create and open a temp file using "pattern".
1.414     rillig   2189:  * If out_fname is provided, set it to a copy of the filename created.
1.191     sjg      2190:  * Otherwise unlink the file once open.
                   2191:  */
                   2192: int
1.414     rillig   2193: mkTempFile(const char *pattern, char **out_fname)
1.191     sjg      2194: {
1.453     rillig   2195:        static char *tmpdir = NULL;
                   2196:        char tfile[MAXPATHLEN];
                   2197:        int fd;
                   2198:
                   2199:        if (pattern == NULL)
                   2200:                pattern = TMPPAT;
                   2201:        if (tmpdir == NULL)
                   2202:                tmpdir = getTmpdir();
                   2203:        if (pattern[0] == '/') {
                   2204:                snprintf(tfile, sizeof tfile, "%s", pattern);
                   2205:        } else {
                   2206:                snprintf(tfile, sizeof tfile, "%s%s", tmpdir, pattern);
                   2207:        }
                   2208:        if ((fd = mkstemp(tfile)) < 0)
                   2209:                Punt("Could not create temporary file %s: %s", tfile,
                   2210:                    strerror(errno));
1.478     rillig   2211:        if (out_fname != NULL) {
1.453     rillig   2212:                *out_fname = bmake_strdup(tfile);
                   2213:        } else {
1.479     rillig   2214:                unlink(tfile);  /* we just want the descriptor */
1.453     rillig   2215:        }
                   2216:        return fd;
1.180     sjg      2217: }
1.201     sjg      2218:
1.240     sjg      2219: /*
1.474     rillig   2220:  * Convert a string representation of a boolean into a boolean value.
                   2221:  * Anything that looks like "No", "False", "Off", "0" etc. is FALSE,
                   2222:  * the empty string is the fallback, everything else is TRUE.
1.240     sjg      2223:  */
                   2224: Boolean
1.474     rillig   2225: ParseBoolean(const char *s, Boolean fallback)
1.240     sjg      2226: {
1.474     rillig   2227:        char ch = ch_tolower(s[0]);
                   2228:        if (ch == '\0')
                   2229:                return fallback;
                   2230:        if (ch == '0' || ch == 'f' || ch == 'n')
1.453     rillig   2231:                return FALSE;
1.474     rillig   2232:        if (ch == 'o')
                   2233:                return ch_tolower(s[1]) != 'f';
                   2234:        return TRUE;
1.240     sjg      2235: }

CVSweb <webmaster@jp.NetBSD.org>