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

Annotation of src/usr.bin/make/make.c, Revision 1.36

1.25      espie       1: /*     $OpenPackages$ */
1.36    ! espie       2: /*     $OpenBSD: make.c,v 1.35 2004/04/07 13:11:36 espie Exp $ */
1.6       millert     3: /*     $NetBSD: make.c,v 1.10 1996/11/06 17:59:15 christos Exp $       */
1.1       deraadt     4:
                      5: /*
1.4       millert     6:  * Copyright (c) 1988, 1989, 1990, 1993
                      7:  *     The Regents of the University of California.  All rights reserved.
1.1       deraadt     8:  * Copyright (c) 1989 by Berkeley Softworks
                      9:  * All rights reserved.
                     10:  *
                     11:  * This code is derived from software contributed to Berkeley by
                     12:  * Adam de Boor.
                     13:  *
                     14:  * Redistribution and use in source and binary forms, with or without
                     15:  * modification, are permitted provided that the following conditions
                     16:  * are met:
                     17:  * 1. Redistributions of source code must retain the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer.
                     19:  * 2. Redistributions in binary form must reproduce the above copyright
                     20:  *    notice, this list of conditions and the following disclaimer in the
                     21:  *    documentation and/or other materials provided with the distribution.
1.33      millert    22:  * 3. Neither the name of the University nor the names of its contributors
1.1       deraadt    23:  *    may be used to endorse or promote products derived from this software
                     24:  *    without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     27:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     28:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     29:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     30:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     31:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     32:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     33:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     34:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     35:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     36:  * SUCH DAMAGE.
                     37:  */
                     38:
                     39: /*-
                     40:  * make.c --
                     41:  *     The functions which perform the examination of targets and
                     42:  *     their suitability for creation
                     43:  *
                     44:  * Interface:
1.25      espie      45:  *     Make_Run                Initialize things for the module and recreate
1.26      espie      46:  *                             whatever needs recreating. Returns true if
                     47:  *                             work was (or would have been) done and
                     48:  *                             false
1.25      espie      49:  *                             otherwise.
                     50:  *
                     51:  *     Make_Update             Update all parents of a given child. Performs
                     52:  *                             various bookkeeping chores like the updating
                     53:  *                             of the cmtime field of the parent, filling
                     54:  *                             of the IMPSRC context variable, etc. It will
                     55:  *                             place the parent on the toBeMade queue if it
                     56:  *                             should be.
                     57:  *
                     58:  *     Make_TimeStamp          Function to set the parent's cmtime field
                     59:  *                             based on a child's modification time.
                     60:  *
                     61:  *     Make_DoAllVar           Set up the various local variables for a
                     62:  *                             target, including the .ALLSRC variable, making
                     63:  *                             sure that any variable that needs to exist
                     64:  *                             at the very least has the empty value.
1.1       deraadt    65:  *
1.25      espie      66:  *     Make_OODate             Determine if a target is out-of-date.
1.1       deraadt    67:  *
1.5       millert    68:  *     Make_HandleUse          See if a child is a .USE node for a parent
1.1       deraadt    69:  *                             and perform the .USE actions if so.
                     70:  */
                     71:
1.27      espie      72: #include <limits.h>
1.26      espie      73: #include <stdio.h>
                     74: #include "config.h"
                     75: #include "defines.h"
                     76: #include "dir.h"
                     77: #include "job.h"
                     78: #include "arch.h"
                     79: #include "suff.h"
                     80: #include "var.h"
                     81: #include "targ.h"
                     82: #include "error.h"
                     83: #include "make.h"
                     84: #include "gnode.h"
                     85: #include "extern.h"
                     86: #include "timestamp.h"
                     87: #include "lst.h"
1.25      espie      88:
                     89: static LIST    toBeMade;       /* The current fringe of the graph. These
1.1       deraadt    90:                                 * are nodes which await examination by
                     91:                                 * MakeOODate. It is added to by
                     92:                                 * Make_Update and subtracted from by
                     93:                                 * MakeStartJobs */
1.25      espie      94: static int     numNodes;       /* Number of nodes to be processed. If this
1.1       deraadt    95:                                 * is non-zero when Job_Empty() returns
1.26      espie      96:                                 * true, there's a cycle in the graph */
1.1       deraadt    97:
1.25      espie      98: static void MakeAddChild(void *, void *);
                     99: static void MakeAddAllSrc(void *, void *);
                    100: static void MakeTimeStamp(void *, void *);
                    101: static void MakeHandleUse(void *, void *);
1.26      espie     102: static bool MakeStartJobs(void);
1.25      espie     103: static void MakePrintStatus(void *, void *);
1.1       deraadt   104: /*-
                    105:  *-----------------------------------------------------------------------
                    106:  * Make_TimeStamp --
                    107:  *     Set the cmtime field of a parent node based on the mtime stamp in its
1.25      espie     108:  *     child.
1.1       deraadt   109:  *
                    110:  * Side Effects:
                    111:  *     The cmtime of the parent node will be changed if the mtime
                    112:  *     field of the child is greater than it.
                    113:  *-----------------------------------------------------------------------
                    114:  */
1.15      espie     115: void
1.35      espie     116: Make_TimeStamp(
                    117:     GNode *pgn, /* the current parent */
                    118:     GNode *cgn) /* the child we've just examined */
1.1       deraadt   119: {
1.26      espie     120:     if (is_strictly_before(pgn->cmtime, cgn->mtime))
1.1       deraadt   121:        pgn->cmtime = cgn->mtime;
                    122: }
                    123:
1.25      espie     124: /* Wrapper to call Make_TimeStamp from a forEach loop. */
1.15      espie     125: static void
1.35      espie     126: MakeTimeStamp(
                    127:     void *pgn, /* the current parent */
                    128:     void *cgn) /* the child we've just examined */
1.1       deraadt   129: {
1.15      espie     130:     Make_TimeStamp((GNode *)pgn, (GNode *)cgn);
1.1       deraadt   131: }
1.25      espie     132:
1.1       deraadt   133: /*-
                    134:  *-----------------------------------------------------------------------
                    135:  * Make_OODate --
                    136:  *     See if a given node is out of date with respect to its sources.
                    137:  *     Used by Make_Run when deciding which nodes to place on the
                    138:  *     toBeMade queue initially and by Make_Update to screen out USE and
                    139:  *     EXEC nodes. In the latter case, however, any other sort of node
                    140:  *     must be considered out-of-date since at least one of its children
                    141:  *     will have been recreated.
                    142:  *
                    143:  * Results:
1.26      espie     144:  *     true if the node is out of date. false otherwise.
1.1       deraadt   145:  *
                    146:  * Side Effects:
                    147:  *     The mtime field of the node and the cmtime field of its parents
                    148:  *     will/may be changed.
                    149:  *-----------------------------------------------------------------------
                    150:  */
1.26      espie     151: bool
1.35      espie     152: Make_OODate(GNode *gn) /* the node to check */
1.1       deraadt   153: {
1.26      espie     154:     bool           oodate;
1.1       deraadt   155:
                    156:     /*
                    157:      * Certain types of targets needn't even be sought as their datedness
                    158:      * doesn't depend on their modification time...
                    159:      */
                    160:     if ((gn->type & (OP_JOIN|OP_USE|OP_EXEC)) == 0) {
1.23      espie     161:        (void)Dir_MTime(gn);
1.1       deraadt   162:        if (DEBUG(MAKE)) {
1.23      espie     163:            if (!is_out_of_date(gn->mtime)) {
1.25      espie     164:                printf("modified %s...", Targ_FmtTime(gn->mtime));
1.1       deraadt   165:            } else {
1.25      espie     166:                printf("non-existent...");
1.1       deraadt   167:            }
                    168:        }
                    169:     }
                    170:
                    171:     /*
                    172:      * A target is remade in one of the following circumstances:
                    173:      * its modification time is smaller than that of its youngest child
                    174:      *     and it would actually be run (has commands or type OP_NOP)
                    175:      * it's the object of a force operator
                    176:      * it has no children, was on the lhs of an operator and doesn't exist
                    177:      *     already.
                    178:      *
                    179:      * Libraries are only considered out-of-date if the archive module says
                    180:      * they are.
                    181:      *
1.34      jmc       182:      * These weird rules are brought to you by Backward-Compatibility and
1.1       deraadt   183:      * the strange people who wrote 'Make'.
                    184:      */
                    185:     if (gn->type & OP_USE) {
                    186:        /*
                    187:         * If the node is a USE node it is *never* out of date
                    188:         * no matter *what*.
                    189:         */
                    190:        if (DEBUG(MAKE)) {
                    191:            printf(".USE node...");
                    192:        }
1.26      espie     193:        oodate = false;
1.4       millert   194:     } else if ((gn->type & OP_LIB) && Arch_IsLib(gn)) {
1.1       deraadt   195:        if (DEBUG(MAKE)) {
                    196:            printf("library...");
                    197:        }
                    198:
                    199:        /*
                    200:         * always out of date if no children and :: target
                    201:         */
                    202:
1.25      espie     203:        oodate = Arch_LibOODate(gn) ||
1.24      espie     204:            (is_out_of_date(gn->cmtime) && (gn->type & OP_DOUBLEDEP));
1.1       deraadt   205:     } else if (gn->type & OP_JOIN) {
                    206:        /*
                    207:         * A target with the .JOIN attribute is only considered
                    208:         * out-of-date if any of its children was out-of-date.
                    209:         */
                    210:        if (DEBUG(MAKE)) {
                    211:            printf(".JOIN node...");
                    212:        }
                    213:        oodate = gn->childMade;
1.2       niklas    214:     } else if (gn->type & (OP_FORCE|OP_EXEC|OP_PHONY)) {
1.1       deraadt   215:        /*
                    216:         * A node which is the object of the force (!) operator or which has
                    217:         * the .EXEC attribute is always considered out-of-date.
                    218:         */
                    219:        if (DEBUG(MAKE)) {
                    220:            if (gn->type & OP_FORCE) {
                    221:                printf("! operator...");
1.2       niklas    222:            } else if (gn->type & OP_PHONY) {
                    223:                printf(".PHONY node...");
1.1       deraadt   224:            } else {
                    225:                printf(".EXEC node...");
                    226:            }
                    227:        }
1.26      espie     228:        oodate = true;
                    229:     } else if (is_strictly_before(gn->mtime, gn->cmtime) ||
1.24      espie     230:               (is_out_of_date(gn->cmtime) &&
                    231:                (is_out_of_date(gn->mtime) || (gn->type & OP_DOUBLEDEP))))
1.1       deraadt   232:     {
                    233:        /*
                    234:         * A node whose modification time is less than that of its
1.13      espie     235:         * youngest child or that has no children (cmtime == OUT_OF_DATE) and
                    236:         * either doesn't exist (mtime == OUT_OF_DATE) or was the object of a
1.1       deraadt   237:         * :: operator is out-of-date. Why? Because that's the way Make does
                    238:         * it.
                    239:         */
                    240:        if (DEBUG(MAKE)) {
1.26      espie     241:            if (is_strictly_before(gn->mtime, gn->cmtime)) {
1.1       deraadt   242:                printf("modified before source...");
1.24      espie     243:            } else if (is_out_of_date(gn->mtime)) {
1.1       deraadt   244:                printf("non-existent and no sources...");
                    245:            } else {
                    246:                printf(":: operator and no sources...");
                    247:            }
                    248:        }
1.26      espie     249:        oodate = true;
1.1       deraadt   250:     } else {
                    251: #if 0
                    252:        /* WHY? */
                    253:        if (DEBUG(MAKE)) {
                    254:            printf("source %smade...", gn->childMade ? "" : "not ");
                    255:        }
                    256:        oodate = gn->childMade;
                    257: #else
1.26      espie     258:        oodate = false;
1.1       deraadt   259: #endif /* 0 */
                    260:     }
                    261:
                    262:     /*
                    263:      * If the target isn't out-of-date, the parents need to know its
                    264:      * modification time. Note that targets that appear to be out-of-date
                    265:      * but aren't, because they have no commands and aren't of type OP_NOP,
                    266:      * have their mtime stay below their children's mtime to keep parents from
                    267:      * thinking they're out-of-date.
                    268:      */
1.15      espie     269:     if (!oodate)
1.17      espie     270:        Lst_ForEach(&gn->parents, MakeTimeStamp, gn);
1.1       deraadt   271:
1.25      espie     272:     return oodate;
1.1       deraadt   273: }
1.25      espie     274:
1.1       deraadt   275: /*-
                    276:  *-----------------------------------------------------------------------
                    277:  * MakeAddChild  --
                    278:  *     Function used by Make_Run to add a child to the list l.
1.26      espie     279:  *     It will only add the child if its make field is false.
1.1       deraadt   280:  *
                    281:  * Side Effects:
                    282:  *     The given list is extended
                    283:  *-----------------------------------------------------------------------
                    284:  */
1.15      espie     285: static void
1.35      espie     286: MakeAddChild(
                    287:     void *gnp,         /* the node to add */
                    288:     void *lp)          /* the list to which to add it */
1.1       deraadt   289: {
1.25      espie     290:     GNode         *gn = (GNode *)gnp;
                    291:     Lst           l = (Lst)lp;
1.5       millert   292:
1.15      espie     293:     if (!gn->make && !(gn->type & OP_USE))
1.14      espie     294:        Lst_EnQueue(l, gn);
1.1       deraadt   295: }
1.25      espie     296:
1.5       millert   297: /*-
                    298:  *-----------------------------------------------------------------------
1.1       deraadt   299:  * Make_HandleUse --
                    300:  *     Function called by Make_Run and SuffApplyTransform on the downward
                    301:  *     pass to handle .USE and transformation nodes. A callback function
                    302:  *     for Lst_ForEach, it implements the .USE and transformation
                    303:  *     functionality by copying the node's commands, type flags
                    304:  *     and children to the parent node. Should be called before the
                    305:  *     children are enqueued to be looked at by MakeAddChild.
                    306:  *
                    307:  *     A .USE node is much like an explicit transformation rule, except
                    308:  *     its commands are always added to the target node, even if the
                    309:  *     target already has commands.
                    310:  *
                    311:  * Side Effects:
                    312:  *     Children and commands may be added to the parent and the parent's
                    313:  *     type may be changed.
                    314:  *
                    315:  *-----------------------------------------------------------------------
                    316:  */
1.15      espie     317: void
1.35      espie     318: Make_HandleUse(
                    319:     GNode      *cgn,   /* The .USE node */
                    320:     GNode      *pgn)   /* The target of the .USE node */
1.1       deraadt   321: {
1.25      espie     322:     GNode      *gn;    /* A child of the .USE node */
                    323:     LstNode    ln;     /* An element in the children list */
1.1       deraadt   324:
                    325:     if (cgn->type & (OP_USE|OP_TRANSFORM)) {
1.17      espie     326:        if ((cgn->type & OP_USE) || Lst_IsEmpty(&pgn->commands)) {
1.25      espie     327:            /* .USE or transformation and target has no commands -- append
                    328:             * the child's commands to the parent.  */
1.18      espie     329:            Lst_Concat(&pgn->commands, &cgn->commands);
1.1       deraadt   330:        }
1.4       millert   331:
1.25      espie     332:        for (ln = Lst_First(&cgn->children); ln != NULL; ln = Lst_Adv(ln)) {
1.19      espie     333:            gn = (GNode *)Lst_Datum(ln);
                    334:
1.26      espie     335:            if (Lst_AddNew(&pgn->children, gn)) {
1.19      espie     336:                Lst_AtEnd(&gn->parents, pgn);
                    337:                pgn->unmade += 1;
1.1       deraadt   338:            }
                    339:        }
1.4       millert   340:
1.1       deraadt   341:        pgn->type |= cgn->type & ~(OP_OPMASK|OP_USE|OP_TRANSFORM);
                    342:
                    343:        /*
                    344:         * This child node is now "made", so we decrement the count of
                    345:         * unmade children in the parent... We also remove the child
                    346:         * from the parent's list to accurately reflect the number of decent
                    347:         * children the parent has. This is used by Make_Run to decide
                    348:         * whether to queue the parent or examine its children...
                    349:         */
1.6       millert   350:        if (cgn->type & OP_USE) {
1.5       millert   351:            pgn->unmade--;
1.1       deraadt   352:        }
                    353:     }
                    354: }
1.15      espie     355: static void
1.35      espie     356: MakeHandleUse(
                    357:     void *pgn, /* the current parent */
                    358:     void *cgn) /* the child we've just examined */
1.1       deraadt   359: {
1.15      espie     360:     Make_HandleUse((GNode *)pgn, (GNode *)cgn);
1.1       deraadt   361: }
1.25      espie     362:
1.1       deraadt   363: /*-
                    364:  *-----------------------------------------------------------------------
1.25      espie     365:  * Make_Update --
1.1       deraadt   366:  *     Perform update on the parents of a node. Used by JobFinish once
                    367:  *     a node has been dealt with and by MakeStartJobs if it finds an
1.4       millert   368:  *     up-to-date node.
1.1       deraadt   369:  *
                    370:  * Results:
                    371:  *     Always returns 0
                    372:  *
                    373:  * Side Effects:
                    374:  *     The unmade field of pgn is decremented and pgn may be placed on
                    375:  *     the toBeMade queue if this field becomes 0.
                    376:  *
1.25      espie     377:  *     If the child was made, the parent's childMade field will be set true
1.1       deraadt   378:  *     and its cmtime set to now.
                    379:  *
                    380:  *     If the child wasn't made, the cmtime field of the parent will be
                    381:  *     altered if the child's mtime is big enough.
                    382:  *
                    383:  *     Finally, if the child is the implied source for the parent, the
                    384:  *     parent's IMPSRC variable is set appropriately.
                    385:  *
                    386:  *-----------------------------------------------------------------------
                    387:  */
                    388: void
1.35      espie     389: Make_Update(GNode *cgn)        /* the child node */
1.1       deraadt   390: {
1.25      espie     391:     GNode      *pgn;   /* the parent node */
                    392:     char       *cname; /* the child's name */
                    393:     LstNode    ln;     /* Element in parents and iParents lists */
1.1       deraadt   394:
1.20      espie     395:     cname = Varq_Value(TARGET_INDEX, cgn);
1.1       deraadt   396:
                    397:     /*
                    398:      * If the child was actually made, see what its modification time is
                    399:      * now -- some rules won't actually update the file. If the file still
                    400:      * doesn't exist, make its mtime now.
                    401:      */
                    402:     if (cgn->made != UPTODATE) {
                    403:        /*
                    404:         * This is what Make does and it's actually a good thing, as it
                    405:         * allows rules like
                    406:         *
                    407:         *      cmp -s y.tab.h parse.h || cp y.tab.h parse.h
                    408:         *
                    409:         * to function as intended. Unfortunately, thanks to the stateless
                    410:         * nature of NFS (by which I mean the loose coupling of two clients
                    411:         * using the same file from a common server), there are times
                    412:         * when the modification time of a file created on a remote
                    413:         * machine will not be modified before the local stat() implied by
                    414:         * the Dir_MTime occurs, thus leading us to believe that the file
                    415:         * is unchanged, wreaking havoc with files that depend on this one.
                    416:         *
                    417:         * I have decided it is better to make too much than to make too
                    418:         * little, so this stuff is commented out unless you're sure it's ok.
                    419:         * -- ardeb 1/12/88
                    420:         */
                    421:        /*
1.25      espie     422:         * Christos, 4/9/92: If we are  saving commands pretend that
1.1       deraadt   423:         * the target is made now. Otherwise archives with ... rules
                    424:         * don't work!
                    425:         */
1.25      espie     426:        if (noExecute || (cgn->type & OP_SAVE_CMDS) ||
1.23      espie     427:            is_out_of_date(Dir_MTime(cgn))) {
1.1       deraadt   428:            cgn->mtime = now;
                    429:        }
                    430:        if (DEBUG(MAKE)) {
                    431:            printf("update time: %s\n", Targ_FmtTime(cgn->mtime));
                    432:        }
                    433:     }
1.4       millert   434:
1.25      espie     435:     for (ln = Lst_First(&cgn->parents); ln != NULL; ln = Lst_Adv(ln)) {
1.19      espie     436:        pgn = (GNode *)Lst_Datum(ln);
                    437:        if (pgn->make) {
                    438:            pgn->unmade -= 1;
                    439:
                    440:            if ( ! (cgn->type & (OP_EXEC|OP_USE))) {
                    441:                if (cgn->made == MADE) {
1.26      espie     442:                    pgn->childMade = true;
                    443:                    if (is_strictly_before(pgn->cmtime, cgn->mtime))
1.19      espie     444:                        pgn->cmtime = cgn->mtime;
                    445:                } else {
1.24      espie     446:                    (void)Make_TimeStamp(pgn, cgn);
1.1       deraadt   447:                }
1.19      espie     448:            }
                    449:            if (pgn->unmade == 0) {
                    450:                /*
                    451:                 * Queue the node up -- any unmade predecessors will
                    452:                 * be dealt with in MakeStartJobs.
                    453:                 */
                    454:                Lst_EnQueue(&toBeMade, pgn);
                    455:            } else if (pgn->unmade < 0) {
1.25      espie     456:                Error("Graph cycles through %s", pgn->name);
1.1       deraadt   457:            }
                    458:        }
                    459:     }
1.25      espie     460:     /* Deal with successor nodes. If any is marked for making and has an unmade
1.1       deraadt   461:      * count of 0, has not been made and isn't in the examination queue,
                    462:      * it means we need to place it in the queue as it restrained itself
1.25      espie     463:      * before. */
1.19      espie     464:     for (ln = Lst_First(&cgn->successors); ln != NULL; ln = Lst_Adv(ln)) {
1.1       deraadt   465:        GNode   *succ = (GNode *)Lst_Datum(ln);
                    466:
1.25      espie     467:        if (succ->make && succ->unmade == 0 && succ->made == UNMADE)
                    468:            (void)Lst_QueueNew(&toBeMade, succ);
1.1       deraadt   469:     }
1.4       millert   470:
1.25      espie     471:     /* Set the .PREFIX and .IMPSRC variables for all the implied parents
                    472:      * of this node.  */
1.19      espie     473:     {
1.20      espie     474:     char       *cpref = Varq_Value(PREFIX_INDEX, cgn);
1.1       deraadt   475:
1.25      espie     476:     for (ln = Lst_First(&cgn->iParents); ln != NULL; ln = Lst_Adv(ln)) {
                    477:        pgn = (GNode *)Lst_Datum(ln);
                    478:        if (pgn->make) {
1.32      deraadt   479:            Varq_Set(IMPSRC_INDEX, cname, pgn);
1.25      espie     480:            Varq_Set(PREFIX_INDEX, cpref, pgn);
1.1       deraadt   481:        }
1.25      espie     482:     }
1.1       deraadt   483:     }
                    484: }
1.25      espie     485:
1.1       deraadt   486: /*-
                    487:  *-----------------------------------------------------------------------
                    488:  * MakeAddAllSrc --
                    489:  *     Add a child's name to the ALLSRC and OODATE variables of the given
                    490:  *     node. Called from Make_DoAllVar via Lst_ForEach. A child is added only
                    491:  *     if it has not been given the .EXEC, .USE or .INVISIBLE attributes.
                    492:  *     .EXEC and .USE children are very rarely going to be files, so...
                    493:  *     A child is added to the OODATE variable if its modification time is
                    494:  *     later than that of its parent, as defined by Make, except if the
                    495:  *     parent is a .JOIN node. In that case, it is only added to the OODATE
                    496:  *     variable if it was actually made (since .JOIN nodes don't have
                    497:  *     modification times, the comparison is rather unfair...)..
                    498:  *
                    499:  * Side Effects:
                    500:  *     The ALLSRC variable for the given node is extended.
                    501:  *-----------------------------------------------------------------------
                    502:  */
1.15      espie     503: static void
1.35      espie     504: MakeAddAllSrc(
                    505:     void *cgnp, /* The child to add */
                    506:     void *pgnp) /* The parent to whose ALLSRC variable it should be */
1.1       deraadt   507:                        /* added */
                    508: {
1.25      espie     509:     GNode      *cgn = (GNode *)cgnp;
                    510:     GNode      *pgn = (GNode *)pgnp;
1.1       deraadt   511:     if ((cgn->type & (OP_EXEC|OP_USE|OP_INVISIBLE)) == 0) {
1.25      espie     512:        const char *child;
1.1       deraadt   513:
1.5       millert   514:        if (OP_NOP(cgn->type) ||
1.20      espie     515:            (child = Varq_Value(TARGET_INDEX, cgn)) == NULL) {
1.3       briggs    516:            /*
                    517:             * this node is only source; use the specific pathname for it
                    518:             */
1.25      espie     519:            child = cgn->path != NULL ? cgn->path : cgn->name;
1.3       briggs    520:        }
1.5       millert   521:
1.20      espie     522:        Varq_Append(ALLSRC_INDEX, child, pgn);
1.1       deraadt   523:        if (pgn->type & OP_JOIN) {
1.25      espie     524:            if (cgn->made == MADE) {
1.20      espie     525:                Varq_Append(OODATE_INDEX, child, pgn);
1.25      espie     526:            }
1.26      espie     527:        } else if (is_strictly_before(pgn->mtime, cgn->mtime) ||
                    528:                   (!is_strictly_before(cgn->mtime, now) && cgn->made == MADE))
1.1       deraadt   529:        {
                    530:            /*
                    531:             * It goes in the OODATE variable if the parent is younger than the
                    532:             * child or if the child has been modified more recently than
                    533:             * the start of the make. This is to keep pmake from getting
                    534:             * confused if something else updates the parent after the
                    535:             * make starts (shouldn't happen, I know, but sometimes it
                    536:             * does). In such a case, if we've updated the kid, the parent
                    537:             * is likely to have a modification time later than that of
                    538:             * the kid and anything that relies on the OODATE variable will
                    539:             * be hosed.
                    540:             *
                    541:             */
1.20      espie     542:            Varq_Append(OODATE_INDEX, child, pgn);
1.1       deraadt   543:        }
                    544:     }
                    545: }
1.25      espie     546:
1.1       deraadt   547: /*-
                    548:  *-----------------------------------------------------------------------
                    549:  * Make_DoAllVar --
                    550:  *     Set up the ALLSRC and OODATE variables. Sad to say, it must be
                    551:  *     done separately, rather than while traversing the graph. This is
                    552:  *     because Make defined OODATE to contain all sources whose modification
                    553:  *     times were later than that of the target, *not* those sources that
                    554:  *     were out-of-date. Since in both compatibility and native modes,
                    555:  *     the modification time of the parent isn't found until the child
                    556:  *     has been dealt with, we have to wait until now to fill in the
                    557:  *     variable. As for ALLSRC, the ordering is important and not
                    558:  *     guaranteed when in native mode, so it must be set here, too.
                    559:  *
                    560:  * Side Effects:
                    561:  *     The ALLSRC and OODATE variables of the given node is filled in.
                    562:  *     If the node is a .JOIN node, its TARGET variable will be set to
1.25      espie     563:  *     match its ALLSRC variable.
1.1       deraadt   564:  *-----------------------------------------------------------------------
                    565:  */
                    566: void
1.35      espie     567: Make_DoAllVar(GNode *gn)
1.1       deraadt   568: {
1.17      espie     569:     Lst_ForEach(&gn->children, MakeAddAllSrc, gn);
1.1       deraadt   570:
1.25      espie     571:     if (Varq_Value(OODATE_INDEX, gn) == NULL)
1.20      espie     572:        Varq_Set(OODATE_INDEX, "", gn);
1.25      espie     573:     if (Varq_Value(ALLSRC_INDEX, gn) == NULL)
1.20      espie     574:        Varq_Set(ALLSRC_INDEX, "", gn);
1.1       deraadt   575:
1.8       espie     576:     if (gn->type & OP_JOIN)
1.20      espie     577:        Varq_Set(TARGET_INDEX, Varq_Value(ALLSRC_INDEX, gn), gn);
1.1       deraadt   578: }
1.25      espie     579:
1.1       deraadt   580: /*-
                    581:  *-----------------------------------------------------------------------
                    582:  * MakeStartJobs --
                    583:  *     Start as many jobs as possible.
                    584:  *
                    585:  * Results:
                    586:  *     If the query flag was given to pmake, no job will be started,
                    587:  *     but as soon as an out-of-date target is found, this function
1.26      espie     588:  *     returns true. At all other times, this function returns false.
1.1       deraadt   589:  *
                    590:  * Side Effects:
                    591:  *     Nodes are removed from the toBeMade queue and job table slots
                    592:  *     are filled.
                    593:  *-----------------------------------------------------------------------
                    594:  */
1.26      espie     595: static bool
1.35      espie     596: MakeStartJobs(void)
1.1       deraadt   597: {
1.25      espie     598:     GNode      *gn;
1.4       millert   599:
1.17      espie     600:     while (!Job_Full() && (gn = (GNode *)Lst_DeQueue(&toBeMade)) != NULL) {
1.1       deraadt   601:        if (DEBUG(MAKE)) {
1.25      espie     602:            printf("Examining %s...", gn->name);
1.1       deraadt   603:        }
                    604:        /*
                    605:         * Make sure any and all predecessors that are going to be made,
                    606:         * have been.
                    607:         */
1.17      espie     608:        if (!Lst_IsEmpty(&gn->preds)) {
1.1       deraadt   609:            LstNode ln;
                    610:
1.19      espie     611:            for (ln = Lst_First(&gn->preds); ln != NULL; ln = Lst_Adv(ln)){
1.1       deraadt   612:                GNode   *pgn = (GNode *)Lst_Datum(ln);
                    613:
                    614:                if (pgn->make && pgn->made == UNMADE) {
                    615:                    if (DEBUG(MAKE)) {
                    616:                        printf("predecessor %s not made yet.\n", pgn->name);
                    617:                    }
                    618:                    break;
                    619:                }
                    620:            }
                    621:            /*
1.25      espie     622:             * If ln isn't NULL, there's a predecessor as yet unmade, so we
1.1       deraadt   623:             * just drop this node on the floor. When the node in question
                    624:             * has been made, it will notice this node as being ready to
                    625:             * make but as yet unmade and will place the node on the queue.
                    626:             */
1.10      espie     627:            if (ln != NULL) {
1.1       deraadt   628:                continue;
                    629:            }
                    630:        }
1.4       millert   631:
1.1       deraadt   632:        numNodes--;
1.25      espie     633:        if (Make_OODate(gn)) {
1.1       deraadt   634:            if (DEBUG(MAKE)) {
1.25      espie     635:                printf("out-of-date\n");
1.1       deraadt   636:            }
                    637:            if (queryFlag) {
1.26      espie     638:                return true;
1.1       deraadt   639:            }
1.25      espie     640:            Make_DoAllVar(gn);
                    641:            Job_Make(gn);
1.1       deraadt   642:        } else {
                    643:            if (DEBUG(MAKE)) {
1.25      espie     644:                printf("up-to-date\n");
1.1       deraadt   645:            }
                    646:            gn->made = UPTODATE;
                    647:            if (gn->type & OP_JOIN) {
                    648:                /*
                    649:                 * Even for an up-to-date .JOIN node, we need it to have its
                    650:                 * context variables so references to it get the correct
                    651:                 * value for .TARGET when building up the context variables
                    652:                 * of its parent(s)...
                    653:                 */
1.25      espie     654:                Make_DoAllVar(gn);
1.1       deraadt   655:            }
1.4       millert   656:
1.25      espie     657:            Make_Update(gn);
1.1       deraadt   658:        }
                    659:     }
1.26      espie     660:     return false;
1.1       deraadt   661: }
1.25      espie     662:
1.1       deraadt   663: /*-
                    664:  *-----------------------------------------------------------------------
                    665:  * MakePrintStatus --
                    666:  *     Print the status of a top-level node, viz. it being up-to-date
                    667:  *     already or not created due to an error in a lower level.
                    668:  *     Callback function for Make_Run via Lst_ForEach.
1.25      espie     669:  *
                    670:  * Side Effects:
                    671:  *     A message may be printed.
1.1       deraadt   672:  *-----------------------------------------------------------------------
                    673:  */
1.15      espie     674: static void
1.35      espie     675: MakePrintStatus(
                    676:     void *gnp,             /* Node to examine */
                    677:     void *cyclep)          /* True if gn->unmade being non-zero implies
1.1       deraadt   678:                             * a cycle in the graph, not an error in an
                    679:                             * inferior */
                    680: {
1.25      espie     681:     GNode      *gn = (GNode *)gnp;
1.26      espie     682:     bool       cycle = *(bool *)cyclep;
1.1       deraadt   683:     if (gn->made == UPTODATE) {
1.25      espie     684:        printf("`%s' is up to date.\n", gn->name);
1.1       deraadt   685:     } else if (gn->unmade != 0) {
                    686:        if (cycle) {
1.26      espie     687:            bool t = true;
1.1       deraadt   688:            /*
                    689:             * If printing cycles and came to one that has unmade children,
                    690:             * print out the cycle by recursing on its children. Note a
                    691:             * cycle like:
                    692:             *  a : b
                    693:             *  b : c
                    694:             *  c : b
                    695:             * will cause this to erroneously complain about a being in
                    696:             * the cycle, but this is a good approximation.
                    697:             */
                    698:            if (gn->made == CYCLE) {
                    699:                Error("Graph cycles through `%s'", gn->name);
                    700:                gn->made = ENDCYCLE;
1.17      espie     701:                Lst_ForEach(&gn->children, MakePrintStatus, &t);
1.1       deraadt   702:                gn->made = UNMADE;
                    703:            } else if (gn->made != ENDCYCLE) {
                    704:                gn->made = CYCLE;
1.17      espie     705:                Lst_ForEach(&gn->children, MakePrintStatus, &t);
1.1       deraadt   706:            }
                    707:        } else {
1.25      espie     708:            printf("`%s' not remade because of errors.\n", gn->name);
1.1       deraadt   709:        }
                    710:     }
                    711: }
1.25      espie     712:
1.5       millert   713:
1.1       deraadt   714: /*-
                    715:  *-----------------------------------------------------------------------
1.6       millert   716:  * Make_Run --
                    717:  *     Initialize the nodes to remake and the list of nodes which are
                    718:  *     ready to be made by doing a breadth-first traversal of the graph
                    719:  *     starting from the nodes in the given list. Once this traversal
                    720:  *     is finished, all the 'leaves' of the graph are in the toBeMade
                    721:  *     queue.
                    722:  *     Using this queue and the Job module, work back up the graph,
                    723:  *     calling on MakeStartJobs to keep the job table as full as
                    724:  *     possible.
                    725:  *
1.1       deraadt   726:  * Results:
1.26      espie     727:  *     true if work was done. false otherwise.
1.1       deraadt   728:  *
                    729:  * Side Effects:
1.6       millert   730:  *     The make field of all nodes involved in the creation of the given
                    731:  *     targets is set to 1. The toBeMade list is set to contain all the
                    732:  *     'leaves' of these subgraphs.
1.1       deraadt   733:  *-----------------------------------------------------------------------
                    734:  */
1.26      espie     735: bool
1.35      espie     736: Make_Run(Lst targs)            /* the initial list of targets */
1.1       deraadt   737: {
1.25      espie     738:     GNode          *gn;        /* a temporary pointer */
                    739:     LIST           examine;    /* List of targets to examine */
                    740:     int            errors;     /* Number of errors the Job module reports */
1.1       deraadt   741:
1.30      espie     742:     Static_Lst_Init(&toBeMade);
1.1       deraadt   743:
1.18      espie     744:     Lst_Clone(&examine, targs, NOCOPY);
1.1       deraadt   745:     numNodes = 0;
1.4       millert   746:
1.1       deraadt   747:     /*
                    748:      * Make an initial downward pass over the graph, marking nodes to be made
                    749:      * as we go down. We call Suff_FindDeps to find where a node is and
                    750:      * to get some children for it if it has none and also has no commands.
                    751:      * If the node is a leaf, we stick it on the toBeMade queue to
                    752:      * be looked at in a minute, otherwise we add its children to our queue
1.4       millert   753:      * and go on about our business.
1.1       deraadt   754:      */
1.18      espie     755:     while ((gn = (GNode *)Lst_DeQueue(&examine)) != NULL) {
1.1       deraadt   756:        if (!gn->make) {
1.26      espie     757:            gn->make = true;
1.1       deraadt   758:            numNodes++;
1.4       millert   759:
1.1       deraadt   760:            /*
                    761:             * Apply any .USE rules before looking for implicit dependencies
                    762:             * to make sure everything has commands that should...
                    763:             */
1.17      espie     764:            Lst_ForEach(&gn->children, MakeHandleUse, gn);
1.25      espie     765:            Suff_FindDeps(gn);
1.1       deraadt   766:
1.6       millert   767:            if (gn->unmade != 0) {
1.18      espie     768:                Lst_ForEach(&gn->children, MakeAddChild, &examine);
1.1       deraadt   769:            } else {
1.17      espie     770:                Lst_EnQueue(&toBeMade, gn);
1.1       deraadt   771:            }
                    772:        }
                    773:     }
1.4       millert   774:
1.1       deraadt   775:     if (queryFlag) {
                    776:        /*
                    777:         * We wouldn't do any work unless we could start some jobs in the
                    778:         * next loop... (we won't actually start any, of course, this is just
                    779:         * to see if any of the targets was out of date)
                    780:         */
1.25      espie     781:        return MakeStartJobs();
1.1       deraadt   782:     } else {
                    783:        /*
                    784:         * Initialization. At the moment, no jobs are running and until some
                    785:         * get started, nothing will happen since the remaining upward
                    786:         * traversal of the graph is performed by the routines in job.c upon
                    787:         * the finishing of a job. So we fill the Job table as much as we can
1.4       millert   788:         * before going into our loop.
1.1       deraadt   789:         */
1.25      espie     790:        (void)MakeStartJobs();
1.1       deraadt   791:     }
                    792:
                    793:     /*
                    794:      * Main Loop: The idea here is that the ending of jobs will take
                    795:      * care of the maintenance of data structures and the waiting for output
                    796:      * will cause us to be idle most of the time while our children run as
                    797:      * much as possible. Because the job table is kept as full as possible,
                    798:      * the only time when it will be empty is when all the jobs which need
                    799:      * running have been run, so that is the end condition of this loop.
                    800:      * Note that the Job module will exit if there were any errors unless the
                    801:      * keepgoing flag was given.
                    802:      */
1.25      espie     803:     while (!Job_Empty()) {
                    804:        Job_CatchOutput();
                    805:        Job_CatchChildren(!usePipes);
1.1       deraadt   806:        (void)MakeStartJobs();
                    807:     }
                    808:
1.7       espie     809:     errors = Job_Finish();
1.1       deraadt   810:
                    811:     /*
                    812:      * Print the final status of each target. E.g. if it wasn't made
                    813:      * because some inferior reported an error.
                    814:      */
1.25      espie     815:     errors = errors == 0 && numNodes != 0;
1.14      espie     816:     Lst_ForEach(targs, MakePrintStatus, &errors);
1.4       millert   817:
1.26      espie     818:     return true;
1.1       deraadt   819: }