/*- *----------------------------------------------------------------------- * Make_OODate -- * See if a given node is out of date with respect to its sources. * Used by Make_Run when deciding which nodes to place on the * toBeMade queue initially and by Make_Update to screen out USE and * EXEC nodes. In the latter case, however, any other sort of node * must be considered out-of-date since at least one of its children * will have been recreated. * * Input: * gn the node to check * * Results: * TRUE if the node is out of date. FALSE otherwise. * * Side Effects: * The mtime field of the node and the cmgn field of its parents * will/may be changed. *----------------------------------------------------------------------- */ Boolean Make_OODate(GNode *gn) { Boolean oodate; /* * Certain types of targets needn't even be sought as their datedness * doesn't depend on their modification time... */ if ((gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC)) == 0) { (void)Dir_MTime(gn, 1); if (DEBUG(MAKE)) { if (gn->mtime != 0) { fprintf(debug_file, "modified %s...", Targ_FmtTime(gn->mtime)); } else { fprintf(debug_file, "non-existent..."); } } } /* * A target is remade in one of the following circumstances: * its modification time is smaller than that of its youngest child * and it would actually be run (has commands or type OP_NOP) * it's the object of a force operator * it has no children, was on the lhs of an operator and doesn't exist * already. * * Libraries are only considered out-of-date if the archive module says * they are. * * These weird rules are brought to you by Backward-Compatibility and * the strange people who wrote 'Make'. */ if (gn->type & (OP_USE|OP_USEBEFORE)) { /* * If the node is a USE node it is *never* out of date * no matter *what*. */ if (DEBUG(MAKE)) { fprintf(debug_file, ".USE node..."); } oodate = FALSE; } else if ((gn->type & OP_LIB) && ((gn->mtime==0) || Arch_IsLib(gn))) { if (DEBUG(MAKE)) { fprintf(debug_file, "library..."); } /* * always out of date if no children and :: target * or non-existent. */ oodate = (gn->mtime == 0 || Arch_LibOODate(gn) || (gn->cmgn == NULL && (gn->type & OP_DOUBLEDEP))); } else if (gn->type & OP_JOIN) { /* * A target with the .JOIN attribute is only considered * out-of-date if any of its children was out-of-date. */ if (DEBUG(MAKE)) { fprintf(debug_file, ".JOIN node..."); } if (DEBUG(MAKE)) { fprintf(debug_file, "source %smade...", gn->flags & CHILDMADE ? "" : "not "); } oodate = (gn->flags & CHILDMADE) ? TRUE : FALSE; } else if (gn->type & (OP_FORCE|OP_EXEC|OP_PHONY)) { /* * A node which is the object of the force (!) operator or which has * the .EXEC attribute is always considered out-of-date. */ if (DEBUG(MAKE)) { if (gn->type & OP_FORCE) { fprintf(debug_file, "! operator..."); } else if (gn->type & OP_PHONY) { fprintf(debug_file, ".PHONY node..."); } else { fprintf(debug_file, ".EXEC node..."); } } oodate = TRUE; } else if ((gn->cmgn != NULL && gn->mtime < gn->cmgn->mtime) || (gn->cmgn == NULL && ((gn->mtime == 0 && !(gn->type & OP_OPTIONAL)) || gn->type & OP_DOUBLEDEP))) { /* * A node whose modification time is less than that of its * youngest child or that has no children (cmgn == NULL) and * either doesn't exist (mtime == 0) and it isn't optional * or was the object of a * :: operator is out-of-date. * Why? Because that's the way Make does it. */ if (DEBUG(MAKE)) { if (gn->cmgn != NULL && gn->mtime < gn->cmgn->mtime) { fprintf(debug_file, "modified before source %s...", gn->cmgn->path); } else if (gn->mtime == 0) { fprintf(debug_file, "non-existent and no sources..."); } else { fprintf(debug_file, ":: operator and no sources..."); } } oodate = TRUE; } else { /* * When a non-existing child with no sources * (such as a typically used FORCE source) has been made and * the target of the child (usually a directory) has the same * timestamp as the timestamp just given to the non-existing child * after it was considered made. */ if (DEBUG(MAKE)) { if (gn->flags & FORCE) fprintf(debug_file, "non existing child..."); } oodate = (gn->flags & FORCE) ? TRUE : FALSE; } #ifdef USE_META if (useMeta) { oodate = meta_oodate(gn, oodate); } #endif /* * If the target isn't out-of-date, the parents need to know its * modification time. Note that targets that appear to be out-of-date * but aren't, because they have no commands and aren't of type OP_NOP, * have their mtime stay below their children's mtime to keep parents from * thinking they're out-of-date. */ if (!oodate) { Lst_ForEach(gn->parents, MakeTimeStamp, gn); } return (oodate); }
bool Make_OODate(GNode *gn) { bool oodate; /* * Certain types of targets needn't even be sought as their datedness * doesn't depend on their modification time... */ if ((gn->type & (OP_JOIN|OP_USE|OP_EXEC|OP_PHONY)) == 0) { (void)Dir_MTime(gn); if (DEBUG(MAKE)) { if (!is_out_of_date(gn->mtime)) printf("modified %s...", time_to_string(gn->mtime)); else printf("non-existent..."); } } /* * A target is remade in one of the following circumstances: * - its modification time is smaller than that of its youngest child * and it would actually be run (has commands or type OP_NOP) * - it's the object of a force operator * - it has no children, was on the lhs of an operator and doesn't * exist already. * * Libraries are only considered out-of-date if the archive module says * they are. */ if (gn->type & OP_USE) { /* * If the node is a USE node it is *never* out of date * no matter *what*. */ if (DEBUG(MAKE)) printf(".USE node..."); oodate = false; } else if ((gn->type & OP_LIB) && Arch_IsLib(gn)) { if (DEBUG(MAKE)) printf("library..."); /* always out of date if no children and :: target */ oodate = Arch_LibOODate(gn) || (is_out_of_date(gn->cmtime) && (gn->type & OP_DOUBLEDEP)); } else if (gn->type & OP_JOIN) { /* * A target with the .JOIN attribute is only considered * out-of-date if any of its children was out-of-date. */ if (DEBUG(MAKE)) printf(".JOIN node..."); oodate = gn->childMade; } else if (gn->type & (OP_FORCE|OP_EXEC|OP_PHONY)) { /* * A node which is the object of the force (!) operator or which * has the .EXEC attribute is always considered out-of-date. */ if (DEBUG(MAKE)) { if (gn->type & OP_FORCE) printf("! operator..."); else if (gn->type & OP_PHONY) printf(".PHONY node..."); else printf(".EXEC node..."); } oodate = true; } else if (is_strictly_before(gn->mtime, gn->cmtime) || (is_out_of_date(gn->cmtime) && (is_out_of_date(gn->mtime) || (gn->type & OP_DOUBLEDEP)))) { /* * A node whose modification time is less than that of its * youngest child or that has no children (cmtime == * OUT_OF_DATE) and either doesn't exist (mtime == OUT_OF_DATE) * or was the object of a :: operator is out-of-date. */ if (DEBUG(MAKE)) { if (is_strictly_before(gn->mtime, gn->cmtime)) printf("modified before source..."); else if (is_out_of_date(gn->mtime)) printf("non-existent and no sources..."); else printf(":: operator and no sources..."); } oodate = true; } else { oodate = false; } /* * If the target isn't out-of-date, the parents need to know its * modification time. Note that targets that appear to be out-of-date * but aren't, because they have no commands and aren't of type OP_NOP, * have their mtime stay below their children's mtime to keep parents * from thinking they're out-of-date. */ if (!oodate) Lst_ForEach(&gn->parents, MakeTimeStamp, gn); return oodate; }