Esempio n. 1
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);
}
Esempio n. 2
0
File: job.c Progetto: UNGLinux/Obase
static Job *
prepare_job(GNode *gn, int flags)
{
	bool cmdsOK;     	/* true if the nodes commands were all right */
	bool noExec;     	/* Set true if we decide not to run the job */

	/*
	 * Check the commands now so any attributes from .DEFAULT have a chance
	 * to migrate to the node
	 */
	cmdsOK = Job_CheckCommands(gn);
	expand_commands(gn);

	if ((gn->type & OP_MAKE) || (!noExecute && !touchFlag)) {
		/*
		 * We're serious here, but if the commands were bogus, we're
		 * also dead...
		 */
		if (!cmdsOK)
			job_failure(gn, Punt);

		if (Lst_IsEmpty(&gn->commands))
			noExec = true;
		else
			noExec = false;

	} else if (noExecute) {
		if (!cmdsOK || Lst_IsEmpty(&gn->commands))
			noExec = true;
		else
			noExec = false;
	} else {
		/*
		 * Just touch the target and note that no shell should be
		 * executed.  Check
		 * the commands, too, but don't die if they're no good -- it
		 * does no harm to keep working up the graph.
		 */
		Job_Touch(gn);
		noExec = true;
	}

	/*
	 * If we're not supposed to execute a shell, don't.
	 */
	if (noExec) {
		/*
		 * We only want to work our way up the graph if we aren't here
		 * because the commands for the job were no good.
		 */
		if (cmdsOK && !aborting) {
			gn->built_status = MADE;
			Make_Update(gn);
		}
		return NULL;
	} else {
		Job *job;       	/* new job descriptor */
		job = emalloc(sizeof(Job));
		if (job == NULL)
			Punt("JobStart out of memory");

		job->node = gn;

		/*
		 * Set the initial value of the flags for this job based on the
		 * global ones and the node's attributes... Any flags supplied
		 * by the caller are also added to the field.
		 */
		job->flags = flags;

		if (gn->type & OP_CHEAP)
			return job;
		if ((gn->type & OP_EXPENSIVE) || 
		    expensive_commands(&gn->expanded))
			job->flags |= JOB_IS_EXPENSIVE;

		return job;
	}
}