Beispiel #1
0
bool
Job_CheckCommands(GNode *gn)
{
    /* Alter our type to tell if errors should be ignored or things
     * should not be printed so setup_and_run_command knows what to do.
     */
    if (Targ_Ignore(gn))
        gn->type |= OP_IGNORE;
    if (Targ_Silent(gn))
        gn->type |= OP_SILENT;

    if (OP_NOP(gn->type) && Lst_IsEmpty(&gn->commands) &&
            (gn->type & OP_LIB) == 0) {
        /*
         * No commands. Look for .DEFAULT rule from which we might infer
         * commands
         */
        if ((gn->type & OP_NODEFAULT) == 0 &&
                (DEFAULT->type & OP_DUMMY) == 0 &&
                !Lst_IsEmpty(&DEFAULT->commands)) {
            /*
             * Make only looks for a .DEFAULT if the node was never
             * the target of an operator, so that's what we do too.
             * If a .DEFAULT was given, we substitute its commands
             * for gn's commands and set the IMPSRC variable to be
             * the target's name The DEFAULT node acts like a
             * transformation rule, in that gn also inherits any
             * attributes or sources attached to .DEFAULT itself.
             */
            Make_HandleUse(DEFAULT, gn);
            Var(IMPSRC_INDEX, gn) = Var(TARGET_INDEX, gn);
        } else if (is_out_of_date(Dir_MTime(gn))) {
            /*
             * The node wasn't the target of an operator we have no
             * .DEFAULT rule to go on and the target doesn't
             * already exist. There's nothing more we can do for
             * this branch.
             */
            return false;
        }
    }
    return true;
}
Beispiel #2
0
/*-
 *-----------------------------------------------------------------------
 * Compat_Make --
 *	Make a target.
 *
 * Input:
 *	gnp		The node to make
 *	pgnp		Parent to abort if necessary
 *
 * Results:
 *	0
 *
 * Side Effects:
 *	If an error is detected and not being ignored, the process exits.
 *
 *-----------------------------------------------------------------------
 */
int
Compat_Make(void *gnp, void *pgnp)
{
    GNode *gn = (GNode *)gnp;
    GNode *pgn = (GNode *)pgnp;

    if (!meta[0])		/* we came here from jobs */
	Compat_Init();
    if (gn->made == UNMADE && (gn == pgn || (pgn->type & OP_MADE) == 0)) {
	/*
	 * First mark ourselves to be made, then apply whatever transformations
	 * the suffix module thinks are necessary. Once that's done, we can
	 * descend and make all our children. If any of them has an error
	 * but the -k flag was given, our 'make' field will be set FALSE again.
	 * This is our signal to not attempt to do anything but abort our
	 * parent as well.
	 */
	gn->flags |= REMAKE;
	gn->made = BEINGMADE;
	if ((gn->type & OP_MADE) == 0)
	    Suff_FindDeps(gn);
	Lst_ForEach(gn->children, Compat_Make, gn);
	if ((gn->flags & REMAKE) == 0) {
	    gn->made = ABORTED;
	    pgn->flags &= ~REMAKE;
	    goto cohorts;
	}

	if (Lst_Member(gn->iParents, pgn) != NULL) {
	    char *p1;
	    Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn, 0);
	    if (p1)
		free(p1);
	}

	/*
	 * All the children were made ok. Now cmgn->mtime contains the
	 * modification time of the newest child, we need to find out if we
	 * exist and when we were modified last. The criteria for datedness
	 * are defined by the Make_OODate function.
	 */
	if (DEBUG(MAKE)) {
	    fprintf(debug_file, "Examining %s...", gn->name);
	}
	if (! Make_OODate(gn)) {
	    gn->made = UPTODATE;
	    if (DEBUG(MAKE)) {
		fprintf(debug_file, "up-to-date.\n");
	    }
	    goto cohorts;
	} else if (DEBUG(MAKE)) {
	    fprintf(debug_file, "out-of-date.\n");
	}

	/*
	 * If the user is just seeing if something is out-of-date, exit now
	 * to tell him/her "yes".
	 */
	if (queryFlag) {
	    exit(1);
	}

	/*
	 * We need to be re-made. We also have to make sure we've got a $?
	 * variable. To be nice, we also define the $> variable using
	 * Make_DoAllVar().
	 */
	Make_DoAllVar(gn);

	/*
	 * Alter our type to tell if errors should be ignored or things
	 * should not be printed so CompatRunCommand knows what to do.
	 */
	if (Targ_Ignore(gn)) {
	    gn->type |= OP_IGNORE;
	}
	if (Targ_Silent(gn)) {
	    gn->type |= OP_SILENT;
	}

	if (Job_CheckCommands(gn, Fatal)) {
	    /*
	     * Our commands are ok, but we still have to worry about the -t
	     * flag...
	     */
	    if (!touchFlag || (gn->type & OP_MAKE)) {
		curTarg = gn;
#ifdef USE_META
		if (useMeta && !NoExecute(gn)) {
		    meta_job_start(NULL, gn);
		}
#endif
		Lst_ForEach(gn->commands, CompatRunCommand, gn);
		curTarg = NULL;
	    } else {
		Job_Touch(gn, gn->type & OP_SILENT);
	    }
	} else {
	    gn->made = ERROR;
	}
#ifdef USE_META
	if (useMeta && !NoExecute(gn)) {
	    meta_job_finish(NULL);
	}
#endif

	if (gn->made != ERROR) {
	    /*
	     * If the node was made successfully, mark it so, update
	     * its modification time and timestamp all its parents. Note
	     * that for .ZEROTIME targets, the timestamping isn't done.
	     * This is to keep its state from affecting that of its parent.
	     */
	    gn->made = MADE;
	    pgn->flags |= Make_Recheck(gn) == 0 ? FORCE : 0;
	    if (!(gn->type & OP_EXEC)) {
		pgn->flags |= CHILDMADE;
		Make_TimeStamp(pgn, gn);
	    }
	} else if (keepgoing) {
	    pgn->flags &= ~REMAKE;
	} else {
	    PrintOnError(gn, "\n\nStop.");
	    exit(1);
	}
    } else if (gn->made == ERROR) {
	/*
	 * Already had an error when making this beastie. Tell the parent
	 * to abort.
	 */
	pgn->flags &= ~REMAKE;
    } else {
	if (Lst_Member(gn->iParents, pgn) != NULL) {
	    char *p1;
	    Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn, 0);
	    if (p1)
		free(p1);
	}
	switch(gn->made) {
	    case BEINGMADE:
		Error("Graph cycles through %s", gn->name);
		gn->made = ERROR;
		pgn->flags &= ~REMAKE;
		break;
	    case MADE:
		if ((gn->type & OP_EXEC) == 0) {
		    pgn->flags |= CHILDMADE;
		    Make_TimeStamp(pgn, gn);
		}
		break;
	    case UPTODATE:
		if ((gn->type & OP_EXEC) == 0) {
		    Make_TimeStamp(pgn, gn);
		}
		break;
	    default:
		break;
	}
    }

cohorts:
    Lst_ForEach(gn->cohorts, Compat_Make, pgnp);
    return (0);
}