Annotation of 43BSDReno/usr.bin/make/main.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
                      3:  * Copyright (c) 1988, 1989 by Adam de Boor
                      4:  * Copyright (c) 1989 by Berkeley Softworks
                      5:  * All rights reserved.
                      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 are permitted provided
                     11:  * that: (1) source distributions retain this entire copyright notice and
                     12:  * comment, and (2) distributions including binaries display the following
                     13:  * acknowledgement:  ``This product includes software developed by the
                     14:  * University of California, Berkeley and its contributors'' in the
                     15:  * documentation or other materials provided with the distribution and in
                     16:  * all advertising materials mentioning features or use of this software.
                     17:  * Neither the name of the University nor the names of its contributors may
                     18:  * be used to endorse or promote products derived from this software without
                     19:  * specific prior written permission.
                     20:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     21:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     22:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     23:  */
                     24: 
                     25: #ifndef lint
                     26: char copyright[] =
                     27: "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
                     28:  All rights reserved.\n";
                     29: #endif /* not lint */
                     30: 
                     31: #ifndef lint
                     32: static char sccsid[] = "@(#)main.c     5.22 (Berkeley) 6/28/90";
                     33: #endif /* not lint */
                     34: 
                     35: /*-
                     36:  * main.c --
                     37:  *     The main file for this entire program. Exit routines etc
                     38:  *     reside here.
                     39:  *
                     40:  * Utility functions defined in this file:
                     41:  *     Main_ParseArgLine       Takes a line of arguments, breaks them and
                     42:  *                             treats them as if they were given when first
                     43:  *                             invoked. Used by the parse module to implement
                     44:  *                             the .MFLAGS target.
                     45:  *
                     46:  *     Error                   Print a tagged error message. The global
                     47:  *                             MAKE variable must have been defined. This
                     48:  *                             takes a format string and two optional
                     49:  *                             arguments for it.
                     50:  *
                     51:  *     Fatal                   Print an error message and exit. Also takes
                     52:  *                             a format string and two arguments.
                     53:  *
                     54:  *     Punt                    Aborts all jobs and exits with a message. Also
                     55:  *                             takes a format string and two arguments.
                     56:  *
                     57:  *     Finish                  Finish things up by printing the number of
                     58:  *                             errors which occured, as passed to it, and
                     59:  *                             exiting.
                     60:  */
                     61: 
                     62: #include <sys/param.h>
                     63: #include <sys/signal.h>
                     64: #include <sys/stat.h>
                     65: #include <fcntl.h>
                     66: #include <stdio.h>
                     67: #include <varargs.h>
                     68: #include "make.h"
                     69: #include "pathnames.h"
                     70: 
                     71: #ifndef        DEFMAXLOCAL
                     72: #define        DEFMAXLOCAL DEFMAXJOBS
                     73: #endif DEFMAXLOCAL
                     74: 
                     75: #define        MAKEFLAGS       ".MAKEFLAGS"
                     76: 
                     77: Lst                    create;         /* Targets to be made */
                     78: time_t                 now;            /* Time at start of make */
                     79: GNode                  *DEFAULT;       /* .DEFAULT node */
                     80: Boolean                        allPrecious;    /* .PRECIOUS given on line by itself */
                     81: 
                     82: static Boolean         noBuiltins;     /* -r flag */
                     83: static Lst             makefiles;      /* ordered list of makefiles to read */
                     84: int                    maxJobs;        /* -J argument */
                     85: static int             maxLocal;       /* -L argument */
                     86: Boolean                        debug;          /* -d flag */
                     87: Boolean                        noExecute;      /* -n flag */
                     88: Boolean                        keepgoing;      /* -k flag */
                     89: Boolean                        queryFlag;      /* -q flag */
                     90: Boolean                        touchFlag;      /* -t flag */
                     91: Boolean                        usePipes;       /* !-P flag */
                     92: Boolean                        ignoreErrors;   /* -i flag */
                     93: Boolean                        beSilent;       /* -s flag */
                     94: Boolean                        oldVars;        /* variable substitution style */
                     95: Boolean                        checkEnvFirst;  /* -e flag */
                     96: static Boolean         jobsRunning;    /* TRUE if the jobs might be running */
                     97: 
                     98: static Boolean         ReadMakefile();
                     99: 
                    100: static char *curdir;                   /* if chdir'd for an architecture */
                    101: 
                    102: /*-
                    103:  * MainParseArgs --
                    104:  *     Parse a given argument vector. Called from main() and from
                    105:  *     Main_ParseArgLine() when the .MAKEFLAGS target is used.
                    106:  *
                    107:  *     XXX: Deal with command line overriding .MAKEFLAGS in makefile
                    108:  *
                    109:  * Results:
                    110:  *     None
                    111:  *
                    112:  * Side Effects:
                    113:  *     Various global and local flags will be set depending on the flags
                    114:  *     given
                    115:  */
                    116: static void
                    117: MainParseArgs(argc, argv)
                    118:        int argc;
                    119:        char **argv;
                    120: {
                    121:        extern int optind;
                    122:        extern char *optarg;
                    123:        register int i;
                    124:        register char *cp;
                    125:        char c;
                    126: 
                    127:        optind = 1;     /* since we're called more than once */
                    128: rearg: while((c = getopt(argc, argv, "D:I:d:ef:ij:knqrst")) != -1) {
                    129:                switch(c) {
                    130:                case 'D':
                    131:                        Var_Set(optarg, "1", VAR_GLOBAL);
                    132:                        Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
                    133:                        Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
                    134:                        break;
                    135:                case 'I':
                    136:                        Parse_AddIncludeDir(optarg);
                    137:                        Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
                    138:                        Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
                    139:                        break;
                    140: #ifdef notdef
                    141:                case 'L':
                    142:                        maxLocal = atoi(optarg);
                    143:                        Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
                    144:                        Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
                    145:                        break;
                    146:                case 'P':
                    147:                        usePipes = FALSE;
                    148:                        Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
                    149:                        break;
                    150:                case 'S':
                    151:                        keepgoing = FALSE;
                    152:                        Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
                    153:                        break;
                    154: #endif
                    155:                case 'd': {
                    156:                        char *modules = optarg;
                    157: 
                    158:                        for (; *modules; ++modules)
                    159:                                switch (*modules) {
                    160:                                case 'A':
                    161:                                        debug = ~0;
                    162:                                        break;
                    163:                                case 'a':
                    164:                                        debug |= DEBUG_ARCH;
                    165:                                        break;
                    166:                                case 'c':
                    167:                                        debug |= DEBUG_COND;
                    168:                                        break;
                    169:                                case 'd':
                    170:                                        debug |= DEBUG_DIR;
                    171:                                        break;
                    172:                                case 'g':
                    173:                                        if (modules[1] == '1') {
                    174:                                                debug |= DEBUG_GRAPH1;
                    175:                                                ++modules;
                    176:                                        }
                    177:                                        else if (modules[1] == '2') {
                    178:                                                debug |= DEBUG_GRAPH2;
                    179:                                                ++modules;
                    180:                                        }
                    181:                                        break;
                    182:                                case 'j':
                    183:                                        debug |= DEBUG_JOB;
                    184:                                        break;
                    185:                                case 'm':
                    186:                                        debug |= DEBUG_MAKE;
                    187:                                        break;
                    188:                                case 's':
                    189:                                        debug |= DEBUG_SUFF;
                    190:                                        break;
                    191:                                case 't':
                    192:                                        debug |= DEBUG_TARG;
                    193:                                        break;
                    194:                                case 'v':
                    195:                                        debug |= DEBUG_VAR;
                    196:                                        break;
                    197:                                }
                    198:                        Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
                    199:                        Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
                    200:                        break;
                    201:                }
                    202:                case 'e':
                    203:                        checkEnvFirst = TRUE;
                    204:                        Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
                    205:                        break;
                    206:                case 'f':
                    207:                        (void)Lst_AtEnd(makefiles, (ClientData)optarg);
                    208:                        break;
                    209:                case 'i':
                    210:                        ignoreErrors = TRUE;
                    211:                        Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
                    212:                        break;
                    213:                case 'j':
                    214:                        maxJobs = atoi(optarg);
                    215:                        Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
                    216:                        Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
                    217:                        break;
                    218:                case 'k':
                    219:                        keepgoing = TRUE;
                    220:                        Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
                    221:                        break;
                    222:                case 'n':
                    223:                        noExecute = TRUE;
                    224:                        Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
                    225:                        break;
                    226:                case 'q':
                    227:                        queryFlag = TRUE;
                    228:                        /* Kind of nonsensical, wot? */
                    229:                        Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
                    230:                        break;
                    231:                case 'r':
                    232:                        noBuiltins = TRUE;
                    233:                        Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
                    234:                        break;
                    235:                case 's':
                    236:                        beSilent = TRUE;
                    237:                        Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
                    238:                        break;
                    239:                case 't':
                    240:                        touchFlag = TRUE;
                    241:                        Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
                    242:                        break;
                    243:                default:
                    244:                case '?':
                    245:                        usage();
                    246:                }
                    247:        }
                    248: 
                    249:        oldVars = TRUE;
                    250: 
                    251:        /*
                    252:         * See if the rest of the arguments are variable assignments and
                    253:         * perform them if so. Else take them to be targets and stuff them
                    254:         * on the end of the "create" list.
                    255:         */
                    256:        for (argv += optind, argc -= optind; *argv; ++argv, --argc)
                    257:                if (Parse_IsVar(*argv))
                    258:                        Parse_DoVar(*argv, VAR_CMD);
                    259:                else {
                    260:                        if (!**argv)
                    261:                                Punt("illegal (null) argument.");
                    262:                        if (**argv == '-') {
                    263:                                optind = 0;
                    264:                                goto rearg;
                    265:                        }
                    266:                        (void)Lst_AtEnd(create, (ClientData)*argv);
                    267:                }
                    268: }
                    269: 
                    270: /*-
                    271:  * Main_ParseArgLine --
                    272:  *     Used by the parse module when a .MFLAGS or .MAKEFLAGS target
                    273:  *     is encountered and by main() when reading the .MAKEFLAGS envariable.
                    274:  *     Takes a line of arguments and breaks it into its
                    275:  *     component words and passes those words and the number of them to the
                    276:  *     MainParseArgs function.
                    277:  *     The line should have all its leading whitespace removed.
                    278:  *
                    279:  * Results:
                    280:  *     None
                    281:  *
                    282:  * Side Effects:
                    283:  *     Only those that come from the various arguments.
                    284:  */
                    285: void
                    286: Main_ParseArgLine(line)
                    287:        char *line;                     /* Line to fracture */
                    288: {
                    289:        char **argv;                    /* Manufactured argument vector */
                    290:        int argc;                       /* Number of arguments in argv */
                    291: 
                    292:        if (line == NULL)
                    293:                return;
                    294:        for (; *line == ' '; ++line);
                    295:        if (!*line)
                    296:                return;
                    297: 
                    298:        argv = brk_string(line, &argc);
                    299:        MainParseArgs(argc, argv);
                    300: }
                    301: 
                    302: /*-
                    303:  * main --
                    304:  *     The main function, for obvious reasons. Initializes variables
                    305:  *     and a few modules, then parses the arguments give it in the
                    306:  *     environment and on the command line. Reads the system makefile
                    307:  *     followed by either Makefile, makefile or the file given by the
                    308:  *     -f argument. Sets the .MAKEFLAGS PMake variable based on all the
                    309:  *     flags it has received by then uses either the Make or the Compat
                    310:  *     module to create the initial list of targets.
                    311:  *
                    312:  * Results:
                    313:  *     If -q was given, exits -1 if anything was out-of-date. Else it exits
                    314:  *     0.
                    315:  *
                    316:  * Side Effects:
                    317:  *     The program exits when done. Targets are created. etc. etc. etc.
                    318:  */
                    319: main(argc, argv)
                    320:        int argc;
                    321:        char **argv;
                    322: {
                    323:        Lst targs;      /* target nodes to create -- passed to Make_Init */
                    324:        Boolean outOfDate;      /* FALSE if all targets up to date */
                    325:        struct stat sb;
                    326:        char *p, *path, *getenv();
                    327: 
                    328:        /*
                    329:         * if the MAKEOBJDIR (or by default, the _PATH_OBJDIR) directory
                    330:         * exists, change into it and build there.  Once things are
                    331:         * initted, have to add the original directory to the search path,
                    332:         * and modify the paths for the Makefiles apropriately.  The
                    333:         * current directory is also placed as a variable for make scripts.
                    334:         */
                    335:        if (!(path = getenv("MAKEOBJDIR")))
                    336:                path = _PATH_OBJDIR;
                    337:        if (!lstat(path, &sb)) {
                    338:                if (S_ISDIR(sb.st_mode))
                    339:                        curdir = "..";
                    340:                else {
                    341:                        curdir = emalloc((u_int)MAXPATHLEN + 1);
                    342:                        if (!getwd(curdir)) {
                    343:                                (void)fprintf(stderr, "make: %s.\n", curdir);
                    344:                                exit(2);
                    345:                        }
                    346:                }
                    347:                if (chdir(path)) {
                    348:                        extern int errno;
                    349: 
                    350:                        (void)fprintf(stderr, "make: %s: %s.\n",
                    351:                            path, strerror(errno));
                    352:                        exit(2);
                    353:                }
                    354:        }
                    355: 
                    356:        create = Lst_Init(FALSE);
                    357:        makefiles = Lst_Init(FALSE);
                    358:        beSilent = FALSE;               /* Print commands as executed */
                    359:        ignoreErrors = FALSE;           /* Pay attention to non-zero returns */
                    360:        noExecute = FALSE;              /* Execute all commands */
                    361:        keepgoing = FALSE;              /* Stop on error */
                    362:        allPrecious = FALSE;            /* Remove targets when interrupted */
                    363:        queryFlag = FALSE;              /* This is not just a check-run */
                    364:        noBuiltins = FALSE;             /* Read the built-in rules */
                    365:        touchFlag = FALSE;              /* Actually update targets */
                    366:        usePipes = TRUE;                /* Catch child output in pipes */
                    367:        debug = 0;                      /* No debug verbosity, please. */
                    368:        jobsRunning = FALSE;
                    369: 
                    370:        maxJobs = DEFMAXJOBS;           /* Set default max concurrency */
                    371:        maxLocal = DEFMAXLOCAL;         /* Set default local max concurrency */
                    372:     
                    373:        /*
                    374:         * Initialize the parsing, directory and variable modules to prepare
                    375:         * for the reading of inclusion paths and variable settings on the
                    376:         * command line
                    377:         */
                    378:        Dir_Init();             /* Initialize directory structures so -I flags
                    379:                                 * can be processed correctly */
                    380:        Parse_Init();           /* Need to initialize the paths of #include
                    381:                                 * directories */
                    382:        Var_Init();             /* As well as the lists of variables for
                    383:                                 * parsing arguments */
                    384: 
                    385:        if (curdir) {
                    386:                Dir_AddDir(dirSearchPath, curdir);
                    387:                Var_Set(".CURDIR", curdir, VAR_GLOBAL);
                    388:        } else
                    389:                Var_Set(".CURDIR", ".", VAR_GLOBAL);
                    390: 
                    391:        /*
                    392:         * Initialize various variables.
                    393:         *      MAKE also gets this name, for compatibility
                    394:         *      .MAKEFLAGS gets set to the empty string just in case.
                    395:         *      MFLAGS also gets initialized empty, for compatibility.
                    396:         */
                    397:        Var_Set("MAKE", argv[0], VAR_GLOBAL);
                    398:        Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
                    399:        Var_Set("MFLAGS", "", VAR_GLOBAL);
                    400:        Var_Set("MACHINE", MACHINE, VAR_GLOBAL);
                    401: 
                    402:        /*
                    403:         * First snag any flags out of the MAKE environment variable.
                    404:         * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
                    405:         * in a different format).
                    406:         */
                    407: #ifdef POSIX
                    408:        Main_ParseArgLine(getenv("MAKEFLAGS"));
                    409: #else
                    410:        Main_ParseArgLine(getenv("MAKE"));
                    411: #endif
                    412:     
                    413:        MainParseArgs(argc, argv);
                    414: 
                    415:        /*
                    416:         * Initialize archive, target and suffix modules in preparation for
                    417:         * parsing the makefile(s)
                    418:         */
                    419:        Arch_Init();
                    420:        Targ_Init();
                    421:        Suff_Init();
                    422: 
                    423:        DEFAULT = NILGNODE;
                    424:        (void)time(&now);
                    425: 
                    426:        /*
                    427:         * Set up the .TARGETS variable to contain the list of targets to be
                    428:         * created. If none specified, make the variable empty -- the parser
                    429:         * will fill the thing in with the default or .MAIN target.
                    430:         */
                    431:        if (!Lst_IsEmpty(create)) {
                    432:                LstNode ln;
                    433: 
                    434:                for (ln = Lst_First(create); ln != NILLNODE;
                    435:                    ln = Lst_Succ(ln)) {
                    436:                        char *name = (char *)Lst_Datum(ln);
                    437: 
                    438:                        Var_Append(".TARGETS", name, VAR_GLOBAL);
                    439:                }
                    440:        } else
                    441:                Var_Set(".TARGETS", "", VAR_GLOBAL);
                    442: 
                    443:        /*
                    444:         * Read in the built-in rules first, followed by the specified makefile,
                    445:         * if it was (makefile != (char *) NULL), or the default Makefile and
                    446:         * makefile, in that order, if it wasn't.
                    447:         */
                    448:         if (!noBuiltins && !ReadMakefile(_PATH_DEFSYSMK))
                    449:                Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
                    450: 
                    451:        if (!Lst_IsEmpty(makefiles)) {
                    452:                LstNode ln;
                    453: 
                    454:                ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile);
                    455:                if (ln != NILLNODE)
                    456:                        Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
                    457:        } else if (!ReadMakefile("makefile"))
                    458:                (void)ReadMakefile("Makefile");
                    459: 
                    460:        (void)ReadMakefile(".depend");
                    461: 
                    462:        Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL), VAR_GLOBAL);
                    463: 
                    464:        /* Install all the flags into the MAKE envariable. */
                    465:        if ((p = Var_Value(MAKEFLAGS, VAR_GLOBAL)) && *p)
                    466: #ifdef POSIX
                    467:                setenv("MAKEFLAGS", p, 1);
                    468: #else
                    469:                setenv("MAKE", p, 1);
                    470: #endif
                    471: 
                    472:        /*
                    473:         * For compatibility, look at the directories in the VPATH variable
                    474:         * and add them to the search path, if the variable is defined. The
                    475:         * variable's value is in the same format as the PATH envariable, i.e.
                    476:         * <directory>:<directory>:<directory>...
                    477:         */
                    478:        if (Var_Exists("VPATH", VAR_CMD)) {
                    479:                char *vpath, *path, *cp, savec;
                    480:                /*
                    481:                 * GCC stores string constants in read-only memory, but
                    482:                 * Var_Subst will want to write this thing, so store it
                    483:                 * in an array
                    484:                 */
                    485:                static char VPATH[] = "${VPATH}";
                    486: 
                    487:                vpath = Var_Subst(VPATH, VAR_CMD, FALSE);
                    488:                path = vpath;
                    489:                do {
                    490:                        /* skip to end of directory */
                    491:                        for (cp = path; *cp != ':' && *cp != '\0'; cp++);
                    492:                        /* Save terminator character so know when to stop */
                    493:                        savec = *cp;
                    494:                        *cp = '\0';
                    495:                        /* Add directory to search path */
                    496:                        Dir_AddDir(dirSearchPath, path);
                    497:                        *cp = savec;
                    498:                        path = cp + 1;
                    499:                } while (savec == ':');
                    500:                (void)free((Address)vpath);
                    501:        }
                    502: 
                    503:        /*
                    504:         * Now that all search paths have been read for suffixes et al, it's
                    505:         * time to add the default search path to their lists...
                    506:         */
                    507:        Suff_DoPaths();
                    508: 
                    509:        /* print the initial graph, if the user requested it */
                    510:        if (DEBUG(GRAPH1))
                    511:                Targ_PrintGraph(1);
                    512: 
                    513:        /*
                    514:         * Have now read the entire graph and need to make a list of targets
                    515:         * to create. If none was given on the command line, we consult the
                    516:         * parsing module to find the main target(s) to create.
                    517:         */
                    518:        if (Lst_IsEmpty(create))
                    519:                targs = Parse_MainName();
                    520:        else
                    521:                targs = Targ_FindList(create, TARG_CREATE);
                    522: 
                    523: /*
                    524:  * this was original amMake -- want to allow parallelism, so put this
                    525:  * back in, eventually.
                    526:  */
                    527:        if (0) {
                    528:                /*
                    529:                 * Initialize job module before traversing the graph, now that
                    530:                 * any .BEGIN and .END targets have been read.  This is done
                    531:                 * only if the -q flag wasn't given (to prevent the .BEGIN from
                    532:                 * being executed should it exist).
                    533:                 */
                    534:                if (!queryFlag) {
                    535:                        if (maxLocal == -1)
                    536:                                maxLocal = maxJobs;
                    537:                        Job_Init(maxJobs, maxLocal);
                    538:                        jobsRunning = TRUE;
                    539:                }
                    540: 
                    541:                /* Traverse the graph, checking on all the targets */
                    542:                outOfDate = Make_Run(targs);
                    543:        } else
                    544:                /*
                    545:                 * Compat_Init will take care of creating all the targets as
                    546:                 * well as initializing the module.
                    547:                 */
                    548:                Compat_Run(targs);
                    549:     
                    550:        /* print the graph now it's been processed if the user requested it */
                    551:        if (DEBUG(GRAPH2))
                    552:                Targ_PrintGraph(2);
                    553: 
                    554:        if (queryFlag && outOfDate)
                    555:                exit(1);
                    556:        else
                    557:                exit(0);
                    558: }
                    559: 
                    560: /*-
                    561:  * ReadMakefile  --
                    562:  *     Open and parse the given makefile.
                    563:  *
                    564:  * Results:
                    565:  *     TRUE if ok. FALSE if couldn't open file.
                    566:  *
                    567:  * Side Effects:
                    568:  *     lots
                    569:  */
                    570: static Boolean
                    571: ReadMakefile(fname)
                    572:        char *fname;            /* makefile to read */
                    573: {
                    574:        extern Lst parseIncPath, sysIncPath;
                    575:        FILE *stream;
                    576:        char *name, path[MAXPATHLEN + 1];
                    577: 
                    578:        if (!strcmp(fname, "-")) {
                    579:                Parse_File("(stdin)", stdin);
                    580:                Var_Set("MAKEFILE", "", VAR_GLOBAL);
                    581:        } else {
                    582:                if (stream = fopen(fname, "r"))
                    583:                        goto found;
                    584:                /* if we've chdir'd, rebuild the path name */
                    585:                if (curdir && *fname != '/') {
                    586:                        (void)sprintf(path, "%s/%s", curdir, fname);
                    587:                        if (stream = fopen(path, "r")) {
                    588:                                fname = path;
                    589:                                goto found;
                    590:                        }
                    591:                }
                    592:                /* look in -I and system include directories. */
                    593:                name = Dir_FindFile(fname, parseIncPath);
                    594:                if (!name)
                    595:                        name = Dir_FindFile(fname, sysIncPath);
                    596:                if (!name || !(stream = fopen(name, "r")))
                    597:                        return(FALSE);
                    598:                fname = name;
                    599:                /*
                    600:                 * set the MAKEFILE variable desired by System V fans -- the
                    601:                 * placement of the setting here means it gets set to the last
                    602:                 * makefile specified, as it is set by SysV make.
                    603:                 */
                    604: found:         Var_Set("MAKEFILE", fname, VAR_GLOBAL);
                    605:                Parse_File(fname, stream);
                    606:                (void)fclose(stream);
                    607:        }
                    608:        return(TRUE);
                    609: }
                    610: 
                    611: /*-
                    612:  * Error --
                    613:  *     Print an error message given its format.
                    614:  *
                    615:  * Results:
                    616:  *     None.
                    617:  *
                    618:  * Side Effects:
                    619:  *     The message is printed.
                    620:  */
                    621: /* VARARGS */
                    622: void
                    623: Error(va_alist)
                    624:        va_dcl
                    625: {
                    626:        va_list ap;
                    627:        char *fmt;
                    628: 
                    629:        va_start(ap);
                    630:        fmt = va_arg(ap, char *);
                    631:        (void)vfprintf(stderr, fmt, ap);
                    632:        va_end(ap);
                    633:        (void)fprintf(stderr, "\n");
                    634:        (void)fflush(stderr);
                    635: }
                    636: 
                    637: /*-
                    638:  * Fatal --
                    639:  *     Produce a Fatal error message. If jobs are running, waits for them
                    640:  *     to finish.
                    641:  *
                    642:  * Results:
                    643:  *     None
                    644:  *
                    645:  * Side Effects:
                    646:  *     The program exits
                    647:  */
                    648: /* VARARGS */
                    649: void
                    650: Fatal(va_alist)
                    651:        va_dcl
                    652: {
                    653:        va_list ap;
                    654:        char *fmt;
                    655: 
                    656:        if (jobsRunning)
                    657:                Job_Wait();
                    658: 
                    659:        va_start(ap);
                    660:        fmt = va_arg(ap, char *);
                    661:        (void)vfprintf(stderr, fmt, ap);
                    662:        va_end(ap);
                    663:        (void)fprintf(stderr, "\n");
                    664:        (void)fflush(stderr);
                    665: 
                    666:        if (DEBUG(GRAPH2))
                    667:                Targ_PrintGraph(2);
                    668:        exit(2);                /* Not 1 so -q can distinguish error */
                    669: }
                    670: 
                    671: /*
                    672:  * Punt --
                    673:  *     Major exception once jobs are being created. Kills all jobs, prints
                    674:  *     a message and exits.
                    675:  *
                    676:  * Results:
                    677:  *     None 
                    678:  *
                    679:  * Side Effects:
                    680:  *     All children are killed indiscriminately and the program Lib_Exits
                    681:  */
                    682: /* VARARGS */
                    683: void
                    684: Punt(va_alist)
                    685:        va_dcl
                    686: {
                    687:        va_list ap;
                    688:        char *fmt;
                    689: 
                    690:        (void)fprintf(stderr, "make: ");
                    691:        va_start(ap);
                    692:        fmt = va_arg(ap, char *);
                    693:        (void)vfprintf(stderr, fmt, ap);
                    694:        va_end(ap);
                    695:        (void)fprintf(stderr, "\n");
                    696:        (void)fflush(stderr);
                    697: 
                    698:        DieHorribly();
                    699: }
                    700: 
                    701: /*-
                    702:  * DieHorribly --
                    703:  *     Exit without giving a message.
                    704:  *
                    705:  * Results:
                    706:  *     None
                    707:  *
                    708:  * Side Effects:
                    709:  *     A big one...
                    710:  */
                    711: void
                    712: DieHorribly()
                    713: {
                    714:        if (jobsRunning)
                    715:                Job_AbortAll();
                    716:        if (DEBUG(GRAPH2))
                    717:                Targ_PrintGraph(2);
                    718:        exit(2);                /* Not 1, so -q can distinguish error */
                    719: }
                    720: 
                    721: /*
                    722:  * Finish --
                    723:  *     Called when aborting due to errors in child shell to signal
                    724:  *     abnormal exit. 
                    725:  *
                    726:  * Results:
                    727:  *     None 
                    728:  *
                    729:  * Side Effects:
                    730:  *     The program exits
                    731:  */
                    732: void
                    733: Finish(errors)
                    734:        int errors;     /* number of errors encountered in Make_Make */
                    735: {
                    736:        Fatal("%d error%s", errors, errors == 1 ? "" : "s");
                    737: }
                    738: 
                    739: /*
                    740:  * emalloc --
                    741:  *     malloc, but die on error.
                    742:  */
                    743: char *
                    744: emalloc(len)
                    745:        u_int len;
                    746: {
                    747:        extern int errno;
                    748:        char *p, *malloc();
                    749: 
                    750:        if (!(p = malloc(len)))
                    751:                enomem();
                    752:        return(p);
                    753: }
                    754: 
                    755: /*
                    756:  * enomem --
                    757:  *     die when out of memory.
                    758:  */
                    759: enomem()
                    760: {
                    761:        (void)fprintf(stderr, "make: %s.\n", strerror(errno));
                    762:        exit(2);
                    763: }
                    764: 
                    765: /*
                    766:  * usage --
                    767:  *     exit with usage message
                    768:  */
                    769: usage()
                    770: {
                    771:        (void)fprintf(stderr,
                    772: "usage: make [-eiknqrst] [-D variable] [-d flags] [-f makefile ]\n\t\
                    773: [-I directory] [-j max_jobs] [variable=value]\n");
                    774:        exit(2);
                    775: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.