Esempio n. 1
0
/*-
 *-----------------------------------------------------------------------
 * 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);
}
Esempio n. 2
0
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;
}