[BACK]Return to engine.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / make

Annotation of src/usr.bin/make/engine.c, Revision 1.6

1.6     ! espie       1: /*     $OpenBSD: engine.c,v 1.5 2007/09/17 09:28:36 espie Exp $ */
1.1       espie       2: /*
                      3:  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
                      4:  * Copyright (c) 1988, 1989 by Adam de Boor
                      5:  * Copyright (c) 1989 by Berkeley Softworks
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to Berkeley by
                      9:  * Adam de Boor.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. Neither the name of the University nor the names of its contributors
                     20:  *    may be used to endorse or promote products derived from this software
                     21:  *    without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     24:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     25:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     26:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     27:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     28:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     29:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     31:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     32:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     33:  * SUCH DAMAGE.
                     34:  */
                     35:
                     36: #include <limits.h>
                     37: #include <stdio.h>
                     38: #include <errno.h>
                     39: #include <fcntl.h>
                     40: #include <unistd.h>
                     41: #include <string.h>
                     42: #include "config.h"
                     43: #include "defines.h"
                     44: #include "dir.h"
                     45: #include "engine.h"
                     46: #include "arch.h"
                     47: #include "gnode.h"
                     48: #include "targ.h"
                     49: #include "var.h"
                     50: #include "extern.h"
                     51: #include "lst.h"
                     52: #include "timestamp.h"
                     53: #include "make.h"
                     54: #include "main.h"
                     55:
                     56: static void MakeTimeStamp(void *, void *);
                     57: static void MakeAddAllSrc(void *, void *);
1.6     ! espie      58: static int rewrite_time(const char *);
1.1       espie      59:
                     60: /*-
                     61:  *-----------------------------------------------------------------------
                     62:  * Job_CheckCommands --
                     63:  *     Make sure the given node has all the commands it needs.
                     64:  *
                     65:  * Results:
                     66:  *     true if the commands list is/was ok.
                     67:  *
                     68:  * Side Effects:
                     69:  *     The node will have commands from the .DEFAULT rule added to it
                     70:  *     if it needs them.
                     71:  *-----------------------------------------------------------------------
                     72:  */
                     73: bool
1.3       espie      74: Job_CheckCommands(GNode *gn, void (*abortProc)(char *, ...))
1.1       espie      75: {
1.3       espie      76:        if (OP_NOP(gn->type) && Lst_IsEmpty(&gn->commands) &&
                     77:            (gn->type & OP_LIB) == 0) {
                     78:                /*
                     79:                 * No commands. Look for .DEFAULT rule from which we might infer
                     80:                 * commands
                     81:                 */
                     82:                if (DEFAULT != NULL && !Lst_IsEmpty(&DEFAULT->commands)) {
                     83:                        /*
                     84:                         * Make only looks for a .DEFAULT if the node was never
                     85:                         * the target of an operator, so that's what we do too.
                     86:                         * If a .DEFAULT was given, we substitute its commands
                     87:                         * for gn's commands and set the IMPSRC variable to be
                     88:                         * the target's name The DEFAULT node acts like a
                     89:                         * transformation rule, in that gn also inherits any
                     90:                         * attributes or sources attached to .DEFAULT itself.
                     91:                         */
                     92:                        Make_HandleUse(DEFAULT, gn);
                     93:                        Varq_Set(IMPSRC_INDEX, Varq_Value(TARGET_INDEX, gn), gn);
                     94:                } else if (is_out_of_date(Dir_MTime(gn))) {
                     95:                        /*
                     96:                         * The node wasn't the target of an operator we have no
                     97:                         * .DEFAULT rule to go on and the target doesn't
                     98:                         * already exist. There's nothing more we can do for
                     99:                         * this branch. If the -k flag wasn't given, we stop in
                    100:                         * our tracks, otherwise we just don't update this
                    101:                         * node's parents so they never get examined.
                    102:                         */
1.5       espie     103:                        static const char msg[] =
1.3       espie     104:                            "make: don't know how to make";
                    105:
                    106:                        if (gn->type & OP_OPTIONAL) {
1.5       espie     107:                                (void)fprintf(stdout, "%s %s(ignored)\n", msg,
1.3       espie     108:                                    gn->name);
                    109:                                (void)fflush(stdout);
                    110:                        } else if (keepgoing) {
1.5       espie     111:                                (void)fprintf(stdout, "%s %s(continuing)\n",
1.3       espie     112:                                    msg, gn->name);
                    113:                                (void)fflush(stdout);
                    114:                                return false;
                    115:                        } else {
1.5       espie     116:                                (*abortProc)("%s %s. Stop in %s.", msg,
1.3       espie     117:                                    gn->name, Var_Value(".CURDIR"));
                    118:                                return false;
                    119:                        }
                    120:                }
1.1       espie     121:        }
1.3       espie     122:        return true;
1.1       espie     123: }
                    124:
1.6     ! espie     125: /* touch files the hard way, by writing stuff to them */
        !           126: static int
        !           127: rewrite_time(const char *name)
        !           128: {
        !           129:        int fd;
        !           130:        char c;
        !           131:
        !           132:        fd = open(name, O_RDWR | O_CREAT, 0666);
        !           133:        if (fd < 0)
        !           134:                return -1;
        !           135:        /*
        !           136:         * Read and write a byte to the file to change
        !           137:         * the modification time.
        !           138:         */
        !           139:        if (read(fd, &c, 1) == 1) {
        !           140:                (void)lseek(fd, 0, SEEK_SET);
        !           141:                (void)write(fd, &c, 1);
        !           142:        }
        !           143:
        !           144:        (void)close(fd);
        !           145:        return 0;
        !           146: }
        !           147:
1.1       espie     148: /*-
                    149:  *-----------------------------------------------------------------------
                    150:  * Job_Touch --
                    151:  *     Touch the given target. Called by JobStart when the -t flag was
                    152:  *     given
                    153:  *
                    154:  * Side Effects:
                    155:  *     The data modification of the file is changed. In addition, if the
                    156:  *     file did not exist, it is created.
                    157:  *-----------------------------------------------------------------------
                    158:  */
                    159: void
1.3       espie     160: Job_Touch(GNode *gn, bool silent)
1.1       espie     161: {
1.3       espie     162:        if (gn->type & (OP_JOIN|OP_USE|OP_EXEC|OP_OPTIONAL)) {
                    163:                /*
                    164:                 * .JOIN, .USE, .ZEROTIME and .OPTIONAL targets are "virtual"
                    165:                 * targets and, as such, shouldn't really be created.
                    166:                 */
                    167:                return;
                    168:        }
1.1       espie     169:
1.3       espie     170:        if (!silent) {
                    171:                (void)fprintf(stdout, "touch %s\n", gn->name);
                    172:                (void)fflush(stdout);
                    173:        }
1.1       espie     174:
1.3       espie     175:        if (noExecute) {
                    176:                return;
                    177:        }
1.1       espie     178:
1.3       espie     179:        if (gn->type & OP_ARCHV) {
                    180:                Arch_Touch(gn);
                    181:        } else if (gn->type & OP_LIB) {
                    182:                Arch_TouchLib(gn);
                    183:        } else {
                    184:                const char *file = gn->path != NULL ? gn->path : gn->name;
                    185:
                    186:                if (set_times(file) == -1){
1.6     ! espie     187:                        if (rewrite_time(file) == -1) {
1.5       espie     188:                                (void)fprintf(stdout,
                    189:                                    "*** couldn't touch %s: %s", file,
1.3       espie     190:                                    strerror(errno));
                    191:                                (void)fflush(stdout);
                    192:                        }
1.1       espie     193:                }
                    194:        }
                    195: }
                    196:
                    197: /*-
                    198:  *-----------------------------------------------------------------------
                    199:  * Make_TimeStamp --
                    200:  *     Set the cmtime field of a parent node based on the mtime stamp in its
                    201:  *     child.
                    202:  *
                    203:  * Side Effects:
                    204:  *     The cmtime of the parent node will be changed if the mtime
                    205:  *     field of the child is greater than it.
                    206:  *-----------------------------------------------------------------------
                    207:  */
                    208: void
                    209: Make_TimeStamp(
                    210:     GNode *pgn, /* the current parent */
                    211:     GNode *cgn) /* the child we've just examined */
                    212: {
1.3       espie     213:        if (is_strictly_before(pgn->cmtime, cgn->mtime))
                    214:                pgn->cmtime = cgn->mtime;
1.1       espie     215: }
                    216:
                    217: /*-
                    218:  *-----------------------------------------------------------------------
                    219:  * Make_HandleUse --
                    220:  *     Function called by Make_Run and SuffApplyTransform on the downward
                    221:  *     pass to handle .USE and transformation nodes. A callback function
                    222:  *     for Lst_ForEach, it implements the .USE and transformation
                    223:  *     functionality by copying the node's commands, type flags
                    224:  *     and children to the parent node. Should be called before the
                    225:  *     children are enqueued to be looked at by MakeAddChild.
                    226:  *
                    227:  *     A .USE node is much like an explicit transformation rule, except
                    228:  *     its commands are always added to the target node, even if the
                    229:  *     target already has commands.
                    230:  *
                    231:  * Side Effects:
                    232:  *     Children and commands may be added to the parent and the parent's
                    233:  *     type may be changed.
                    234:  *
                    235:  *-----------------------------------------------------------------------
                    236:  */
                    237: void
                    238: Make_HandleUse(
                    239:     GNode      *cgn,   /* The .USE node */
                    240:     GNode      *pgn)   /* The target of the .USE node */
                    241: {
1.3       espie     242:        GNode   *gn;    /* A child of the .USE node */
                    243:        LstNode ln;     /* An element in the children list */
1.1       espie     244:
1.3       espie     245:        if (cgn->type & (OP_USE|OP_TRANSFORM)) {
                    246:                if ((cgn->type & OP_USE) || Lst_IsEmpty(&pgn->commands)) {
                    247:                        /* .USE or transformation and target has no commands --
                    248:                         * append the child's commands to the parent.  */
                    249:                        Lst_Concat(&pgn->commands, &cgn->commands);
                    250:                }
1.1       espie     251:
1.5       espie     252:                for (ln = Lst_First(&cgn->children); ln != NULL;
1.3       espie     253:                    ln = Lst_Adv(ln)) {
                    254:                        gn = (GNode *)Lst_Datum(ln);
                    255:
                    256:                        if (Lst_AddNew(&pgn->children, gn)) {
                    257:                                Lst_AtEnd(&gn->parents, pgn);
1.4       espie     258:                                pgn->unmade++;
1.3       espie     259:                        }
                    260:                }
1.1       espie     261:
1.3       espie     262:                pgn->type |= cgn->type & ~(OP_OPMASK|OP_USE|OP_TRANSFORM);
1.1       espie     263:
1.3       espie     264:                /*
                    265:                 * This child node is now "made", so we decrement the count of
                    266:                 * unmade children in the parent... We also remove the child
                    267:                 * from the parent's list to accurately reflect the number of
                    268:                 * decent children the parent has. This is used by Make_Run to
                    269:                 * decide whether to queue the parent or examine its
                    270:                 * children...
                    271:                 */
                    272:                if (cgn->type & OP_USE) {
                    273:                        pgn->unmade--;
                    274:                }
1.1       espie     275:        }
                    276: }
                    277:
                    278: /*-
                    279:  *-----------------------------------------------------------------------
                    280:  * MakeAddAllSrc --
                    281:  *     Add a child's name to the ALLSRC and OODATE variables of the given
                    282:  *     node. Called from Make_DoAllVar via Lst_ForEach. A child is added only
                    283:  *     if it has not been given the .EXEC, .USE or .INVISIBLE attributes.
                    284:  *     .EXEC and .USE children are very rarely going to be files, so...
                    285:  *     A child is added to the OODATE variable if its modification time is
                    286:  *     later than that of its parent, as defined by Make, except if the
                    287:  *     parent is a .JOIN node. In that case, it is only added to the OODATE
                    288:  *     variable if it was actually made (since .JOIN nodes don't have
                    289:  *     modification times, the comparison is rather unfair...)..
                    290:  *
                    291:  * Side Effects:
                    292:  *     The ALLSRC variable for the given node is extended.
                    293:  *-----------------------------------------------------------------------
                    294:  */
                    295: static void
                    296: MakeAddAllSrc(
                    297:     void *cgnp, /* The child to add */
                    298:     void *pgnp) /* The parent to whose ALLSRC variable it should be */
                    299:                        /* added */
                    300: {
1.3       espie     301:        GNode *cgn = (GNode *)cgnp;
                    302:        GNode *pgn = (GNode *)pgnp;
                    303:        if ((cgn->type & (OP_EXEC|OP_USE|OP_INVISIBLE)) == 0) {
                    304:                const char *child;
                    305:
                    306:                if (OP_NOP(cgn->type) ||
                    307:                    (child = Varq_Value(TARGET_INDEX, cgn)) == NULL) {
                    308:                        /*
                    309:                         * this node is only source; use the specific pathname
                    310:                         * for it
                    311:                         */
                    312:                        child = cgn->path != NULL ? cgn->path : cgn->name;
                    313:                }
1.1       espie     314:
1.3       espie     315:                Varq_Append(ALLSRC_INDEX, child, pgn);
                    316:                if (pgn->type & OP_JOIN) {
                    317:                        if (cgn->made == MADE) {
                    318:                                Varq_Append(OODATE_INDEX, child, pgn);
                    319:                        }
                    320:                } else if (is_strictly_before(pgn->mtime, cgn->mtime) ||
1.5       espie     321:                    (!is_strictly_before(cgn->mtime, now) &&
1.3       espie     322:                    cgn->made == MADE)) {
                    323:                        /*
                    324:                         * It goes in the OODATE variable if the parent is
                    325:                         * younger than the child or if the child has been
                    326:                         * modified more recently than the start of the make.
                    327:                         * This is to keep pmake from getting confused if
                    328:                         * something else updates the parent after the make
                    329:                         * starts (shouldn't happen, I know, but sometimes it
                    330:                         * does). In such a case, if we've updated the kid, the
                    331:                         * parent is likely to have a modification time later
                    332:                         * than that of the kid and anything that relies on the
                    333:                         * OODATE variable will be hosed.
                    334:                         *
                    335:                         */
                    336:                        Varq_Append(OODATE_INDEX, child, pgn);
                    337:                }
1.1       espie     338:        }
                    339: }
                    340:
                    341: /*-
                    342:  *-----------------------------------------------------------------------
                    343:  * Make_DoAllVar --
                    344:  *     Set up the ALLSRC and OODATE variables. Sad to say, it must be
                    345:  *     done separately, rather than while traversing the graph. This is
                    346:  *     because Make defined OODATE to contain all sources whose modification
                    347:  *     times were later than that of the target, *not* those sources that
                    348:  *     were out-of-date. Since in both compatibility and native modes,
                    349:  *     the modification time of the parent isn't found until the child
                    350:  *     has been dealt with, we have to wait until now to fill in the
                    351:  *     variable. As for ALLSRC, the ordering is important and not
                    352:  *     guaranteed when in native mode, so it must be set here, too.
                    353:  *
                    354:  * Side Effects:
                    355:  *     The ALLSRC and OODATE variables of the given node is filled in.
                    356:  *     If the node is a .JOIN node, its TARGET variable will be set to
                    357:  *     match its ALLSRC variable.
                    358:  *-----------------------------------------------------------------------
                    359:  */
                    360: void
                    361: Make_DoAllVar(GNode *gn)
                    362: {
1.3       espie     363:        Lst_ForEach(&gn->children, MakeAddAllSrc, gn);
1.1       espie     364:
1.3       espie     365:        if (Varq_Value(OODATE_INDEX, gn) == NULL)
                    366:                Varq_Set(OODATE_INDEX, "", gn);
                    367:        if (Varq_Value(ALLSRC_INDEX, gn) == NULL)
                    368:                Varq_Set(ALLSRC_INDEX, "", gn);
1.1       espie     369:
1.3       espie     370:        if (gn->type & OP_JOIN)
                    371:                Varq_Set(TARGET_INDEX, Varq_Value(ALLSRC_INDEX, gn), gn);
1.1       espie     372: }
                    373:
                    374: /* Wrapper to call Make_TimeStamp from a forEach loop. */
                    375: static void
                    376: MakeTimeStamp(
                    377:     void *pgn, /* the current parent */
                    378:     void *cgn) /* the child we've just examined */
                    379: {
1.3       espie     380:        Make_TimeStamp((GNode *)pgn, (GNode *)cgn);
1.1       espie     381: }
                    382:
                    383: /*-
                    384:  *-----------------------------------------------------------------------
                    385:  * Make_OODate --
                    386:  *     See if a given node is out of date with respect to its sources.
                    387:  *     Used by Make_Run when deciding which nodes to place on the
                    388:  *     toBeMade queue initially and by Make_Update to screen out USE and
                    389:  *     EXEC nodes. In the latter case, however, any other sort of node
                    390:  *     must be considered out-of-date since at least one of its children
                    391:  *     will have been recreated.
                    392:  *
                    393:  * Results:
                    394:  *     true if the node is out of date. false otherwise.
                    395:  *
                    396:  * Side Effects:
                    397:  *     The mtime field of the node and the cmtime field of its parents
                    398:  *     will/may be changed.
                    399:  *-----------------------------------------------------------------------
                    400:  */
                    401: bool
                    402: Make_OODate(GNode *gn) /* the node to check */
                    403: {
1.3       espie     404:        bool oodate;
1.1       espie     405:
                    406:        /*
1.3       espie     407:         * Certain types of targets needn't even be sought as their datedness
                    408:         * doesn't depend on their modification time...
1.1       espie     409:         */
1.3       espie     410:        if ((gn->type & (OP_JOIN|OP_USE|OP_EXEC)) == 0) {
                    411:                (void)Dir_MTime(gn);
                    412:                if (DEBUG(MAKE)) {
                    413:                        if (!is_out_of_date(gn->mtime)) {
1.5       espie     414:                                printf("modified %s...",
1.3       espie     415:                                    time_to_string(gn->mtime));
                    416:                        } else {
                    417:                                printf("non-existent...");
                    418:                        }
                    419:                }
1.1       espie     420:        }
                    421:
                    422:        /*
1.3       espie     423:         * A target is remade in one of the following circumstances:
                    424:         *      its modification time is smaller than that of its youngest child
                    425:         *          and it would actually be run (has commands or type OP_NOP)
                    426:         *      it's the object of a force operator
                    427:         *      it has no children, was on the lhs of an operator and doesn't
                    428:         *      exist already.
                    429:         *
                    430:         * Libraries are only considered out-of-date if the archive module says
                    431:         * they are.
                    432:         *
                    433:         * These weird rules are brought to you by Backward-Compatibility and
                    434:         * the strange people who wrote 'Make'.
1.1       espie     435:         */
1.3       espie     436:        if (gn->type & OP_USE) {
                    437:                /*
                    438:                 * If the node is a USE node it is *never* out of date
                    439:                 * no matter *what*.
                    440:                 */
                    441:                if (DEBUG(MAKE)) {
                    442:                        printf(".USE node...");
                    443:                }
                    444:                oodate = false;
                    445:        } else if ((gn->type & OP_LIB) && Arch_IsLib(gn)) {
                    446:                if (DEBUG(MAKE)) {
                    447:                        printf("library...");
                    448:                }
1.1       espie     449:
1.3       espie     450:                /*
                    451:                 * always out of date if no children and :: target
                    452:                 */
                    453:
                    454:                oodate = Arch_LibOODate(gn) ||
                    455:                    (is_out_of_date(gn->cmtime) && (gn->type & OP_DOUBLEDEP));
                    456:        } else if (gn->type & OP_JOIN) {
                    457:                /*
                    458:                 * A target with the .JOIN attribute is only considered
                    459:                 * out-of-date if any of its children was out-of-date.
                    460:                 */
                    461:                if (DEBUG(MAKE)) {
                    462:                        printf(".JOIN node...");
                    463:                }
                    464:                oodate = gn->childMade;
                    465:        } else if (gn->type & (OP_FORCE|OP_EXEC|OP_PHONY)) {
                    466:                /*
                    467:                 * A node which is the object of the force (!) operator or
                    468:                 * which has the .EXEC attribute is always considered
                    469:                 * out-of-date.
                    470:                 */
                    471:                if (DEBUG(MAKE)) {
                    472:                        if (gn->type & OP_FORCE) {
                    473:                                printf("! operator...");
                    474:                        } else if (gn->type & OP_PHONY) {
                    475:                                printf(".PHONY node...");
                    476:                        } else {
                    477:                                printf(".EXEC node...");
                    478:                        }
                    479:                }
                    480:                oodate = true;
                    481:        } else if (is_strictly_before(gn->mtime, gn->cmtime) ||
                    482:            (is_out_of_date(gn->cmtime) &&
                    483:            (is_out_of_date(gn->mtime) || (gn->type & OP_DOUBLEDEP)))) {
                    484:                /*
                    485:                 * A node whose modification time is less than that of its
                    486:                 * youngest child or that has no children (cmtime ==
                    487:                 * OUT_OF_DATE) and either doesn't exist (mtime == OUT_OF_DATE)
                    488:                 * or was the object of a :: operator is out-of-date. Why?
                    489:                 * Because that's the way Make does it.
                    490:                 */
                    491:                if (DEBUG(MAKE)) {
                    492:                        if (is_strictly_before(gn->mtime, gn->cmtime)) {
                    493:                                printf("modified before source...");
                    494:                        } else if (is_out_of_date(gn->mtime)) {
                    495:                                printf("non-existent and no sources...");
                    496:                        } else {
                    497:                                printf(":: operator and no sources...");
                    498:                        }
                    499:                }
                    500:                oodate = true;
                    501:        } else {
1.1       espie     502: #if 0
1.3       espie     503:                /* WHY? */
                    504:                if (DEBUG(MAKE)) {
                    505:                        printf("source %smade...", gn->childMade ? "" : "not ");
                    506:                }
                    507:                oodate = gn->childMade;
1.1       espie     508: #else
1.3       espie     509:                oodate = false;
1.1       espie     510: #endif /* 0 */
1.3       espie     511:        }
1.1       espie     512:
1.3       espie     513:        /*
                    514:         * If the target isn't out-of-date, the parents need to know its
                    515:         * modification time. Note that targets that appear to be out-of-date
                    516:         * but aren't, because they have no commands and aren't of type OP_NOP,
                    517:         * have their mtime stay below their children's mtime to keep parents
                    518:         * from thinking they're out-of-date.
                    519:         */
                    520:        if (!oodate)
                    521:                Lst_ForEach(&gn->parents, MakeTimeStamp, gn);
1.1       espie     522:
1.3       espie     523:        return oodate;
1.1       espie     524: }
                    525: