public void ExecutionProperties()
        {
            Engine engine = new Engine();
                   engine.BinPath="TestBinPath";

            ArrayList targetsToBuild = new ArrayList();
            targetsToBuild.Add("targetName");
            ProjectBuildState projectContext = new ProjectBuildState(new BuildRequest(-1, null, null, (BuildPropertyGroup)null, null, -1, false, false), targetsToBuild, new BuildEventContext(0, 1, 1, 1));

            TaskExecutionContext context = new TaskExecutionContext(null, null, null, projectContext, 4, EngineCallback.inProcNode, new BuildEventContext(BuildEventContext.InvalidNodeId, BuildEventContext.InvalidTargetId, BuildEventContext.InvalidProjectContextId, BuildEventContext.InvalidTaskId));

            Assert.IsTrue(context.BuildContext.TargetNamesToBuild.Contains("targetName"), "Expected target list to contain targetName");

            Assert.AreEqual(EngineCallback.inProcNode,context.NodeIndex);

            Assert.IsNull(context.ParentTarget,"Expected ParentTarget to be null");

            context.SetTaskOutputs(false, null, 0);

            Assert.IsFalse(context.TaskExecutedSuccessfully );
            Assert.IsNull(context.ThrownException, "Expected ThrownException to be null");

            context.SetTaskOutputs(true, new Exception(), 0);

            Assert.IsTrue(context.TaskExecutedSuccessfully);
            Assert.IsNotNull(context.ThrownException,"Expected ThrownException to not be null");


        }
        public void TaskExecutionContextCreation()
        {

             // Create some items to instantiate a task execution context and check to make sure those values are set properly
            Engine engine = new Engine();
                   engine.BinPath="TestBinPath";
          
            ArrayList targetsToBuild = new ArrayList(); 
            targetsToBuild.Add("targetName");
            ProjectBuildState projectContext = new ProjectBuildState(null, targetsToBuild, new BuildEventContext(0, 1, 1, 1));

            TaskExecutionContext context = new TaskExecutionContext(null, null, null, projectContext, 4, EngineCallback.inProcNode, new BuildEventContext(BuildEventContext.InvalidNodeId, BuildEventContext.InvalidTargetId, BuildEventContext.InvalidProjectContextId, BuildEventContext.InvalidTaskId));
         
            Assert.IsTrue(context.BuildContext.TargetNamesToBuild.Contains("targetName"),"Expected target list to contain targetName");
            Assert.IsNull(context.ParentTarget,"ParentTarget should be null");
            Assert.IsNull(context.ThrownException,"ThrownException should be null");
            Assert.AreEqual(4,context.HandleId,"Node ProxyId should be 4");
        } 
Exemple #3
0
 /// <summary>
 /// This method is called repeatedly to execute the target in multi-threaded mode. In single
 /// threaded mode it is called once and it loops internally until the execution is finished.
 /// </summary>
 /// <param name="buildContext">Context within which the target is being executed</param>
 /// <param name="taskExecutionContext">Result of last execution (multi-threaded only)</param>
 internal void ContinueBuild( ProjectBuildState buildContext, TaskExecutionContext taskExecutionContext)
 {
     executionState.ContinueBuild(buildContext, taskExecutionContext);
 }
Exemple #4
0
        /// <summary>
        /// This method creates a new TaskExecutionContext and return a integer token that maps to it.
        /// This method is not thread safe and must be called only from the engine thread.
        /// </summary>
        internal int CreateTaskContext
        (
            Project parentProject, 
            Target  parentTarget,
            ProjectBuildState buildContext,
            XmlElement taskNode, 
            int nodeIndex,
            BuildEventContext taskContext
        )
        {
            int handleId = nextContextId;
            nextContextId = nextContextId + 1;

            TaskExecutionContext executionContext =
                new TaskExecutionContext(parentProject, parentTarget, taskNode, buildContext, handleId, nodeIndex, taskContext);

            executionContexts.Add(handleId, executionContext);

            return handleId;
        }
Exemple #5
0
        internal void ContinueBuild(ProjectBuildState buildContext, TaskExecutionContext taskExecutionContext)
        {
            if (Engine.debugMode)
            {
                Console.WriteLine("Project continue build :" + buildContext.BuildRequest.ProjectFileName + " Handle " + buildContext.BuildRequest.HandleId + " State " + buildContext.CurrentBuildContextState +
                                   " current target " + buildContext.NameOfTargetInProgress + " blocking target " + buildContext.NameOfBlockingTarget);
            }
            bool exitedDueToError = true;
            try
            {
                if (buildContext.CurrentBuildContextState == ProjectBuildState.BuildContextState.BuildingCurrentTarget)
                {
                    // Execute the next appropriate operation for this target
                    ErrorUtilities.VerifyThrow( taskExecutionContext != null, "Task context should be non-null");
                    taskExecutionContext.ParentTarget.ContinueBuild(taskExecutionContext.BuildContext, taskExecutionContext);
                }
                else if (buildContext.CurrentBuildContextState == ProjectBuildState.BuildContextState.StartingFirstTarget)
                {
                    // Start the first target of the build request
                    buildContext.CurrentBuildContextState = ProjectBuildState.BuildContextState.BuildingCurrentTarget;
                    GetTargetForName(buildContext.NameOfTargetInProgress).Build(buildContext);
                }
                else if (buildContext.CurrentBuildContextState == ProjectBuildState.BuildContextState.CycleDetected)
                {
                    ErrorUtilities.VerifyThrow(
                        taskExecutionContext != null && taskExecutionContext.ParentTarget != null,
                        "Unexpected task context. Should not be null");
                    // Check that the target is in progress
                    ErrorUtilities.VerifyThrow(
                        taskExecutionContext.ParentTarget.TargetBuildState == Target.BuildState.InProgress,
                        "The target forming the cycle should not be complete");
                    // Throw invalid project exeception
                    ProjectErrorUtilities.VerifyThrowInvalidProject
                        (false, taskExecutionContext.ParentTarget.TargetElement,
                         "CircularDependency", taskExecutionContext.ParentTarget.Name);
                }

                CalculateNextActionForProjectContext(buildContext);

                exitedDueToError = false;

                if (Engine.debugMode)
                {
                    Console.WriteLine("Project after continue build :" + buildContext.BuildRequest.ProjectFileName + " Handle " + buildContext.BuildRequest.HandleId + " State " + buildContext.CurrentBuildContextState +
                                      " current target " + buildContext.NameOfTargetInProgress + " blocking target " + buildContext.NameOfBlockingTarget);
                }
            }
            catch (InvalidProjectFileException e)
            {
                // Make sure the Invalid Project error gets logged *before* ProjectFinished.  Otherwise,
                // the log is confusing.
                this.ParentEngine.LoggingServices.LogInvalidProjectFileError(buildContext.ProjectBuildEventContext, e);
            }
            finally
            {
                if ( (exitedDueToError || buildContext.BuildComplete) &&
                     buildContext.CurrentBuildContextState != ProjectBuildState.BuildContextState.RequestFilled)
                {
                    // If the target that threw an exception is being built due to an
                    // dependson or onerror relationship, it is necessary to make sure 
                    // the buildrequests waiting on targets below it get notified of the failure. In single
                    // threaded mode there is only a single outstanding request so this issue is avoided.
                    if (exitedDueToError)
                    {
                        buildContext.RecordBuildException();

                        if (buildContext.NameOfBlockingTarget != null)
                        {
                            while (buildContext.NameOfBlockingTarget != null)
                            {
                                Target blockingTarget = GetTargetForName(buildContext.NameOfBlockingTarget);
                                if (blockingTarget.ExecutionState != null &&
                                    blockingTarget.ExecutionState.BuildingRequiredTargets)
                                {
                                    blockingTarget.ContinueBuild(buildContext, null);
                                }

                                buildContext.RemoveBlockingTarget();
                            }
                            Target inprogressTarget = GetTargetForName(buildContext.NameOfTargetInProgress);
                            if (inprogressTarget.ExecutionState != null &&
                                inprogressTarget.ExecutionState.BuildingRequiredTargets)
                            {
                                inprogressTarget.ContinueBuild(buildContext, null);
                            }
                        }


                        buildContext.CurrentBuildContextState = ProjectBuildState.BuildContextState.BuildComplete;
                    }

                    this.buildingCount--;

                    if (buildContext.BuildRequest.FireProjectStartedFinishedEvents)
                    {
                        ParentEngine.LoggingServices.LogProjectFinished(buildContext.ProjectBuildEventContext, FullFileName, buildContext.BuildResult);
                    }

                    // Notify targets in other projects that are waiting on us via IBuildEngine
                    // interface (via MSBuild and CallTarget tasks).
                    if (buildContext.BuildRequest.IsGeneratedRequest)
                    {
                        if (Engine.debugMode)
                        {
                            Console.WriteLine("Notifying about " + buildContext.BuildRequest.ProjectFileName +
                                              " about " + buildContext.TargetNamesToBuild[0] + " on node " + buildContext.BuildRequest.NodeIndex +
                                              " HandleId " + buildContext.BuildRequest.HandleId + " ReqID " +
                                              buildContext.BuildRequest.RequestId);
                        }
                        ParentEngine.Router.PostDoneNotice(buildContext.BuildRequest);
                    }

                    // Don't try to unload projects loaded by the host
                    if (this.buildingCount == 0 && this.needToUnloadProject && !this.IsLoadedByHost)
                    {
                        parentEngine.UnloadProject(this, false /* unload only this project version */);
                    }

                    buildContext.CurrentBuildContextState = ProjectBuildState.BuildContextState.RequestFilled;
                }
            }
        }
Exemple #6
0
        /// <summary>
        /// This function is called to break the link between two targets that creates a cycle. The link could be 
        /// due to depends/onerror relationship between parent and child. In that case both parent and child are
        /// on the same node and within the same project. Or the link could be formed by an IBuildEngine callback 
        /// (made such by tasks such as MSBuild or CallTarget) in which case there maybe multiple requests forming 
        /// same link between parent and child. Also in that case parent and child maybe on different nodes and/or in 
        /// different projects. In either case the break is forced by finding the correct builds states and causing
        /// them to fail.
        /// </summary>
        internal void BreakCycle(TargetInProgessState child, TargetInProgessState parent)
        {
            ErrorUtilities.VerifyThrow( child.TargetId.nodeId == parentEngine.NodeId,
                                        "Expect the child target to be on the node");

            Project parentProject = projectManager.GetProject(child.TargetId.projectId);

            ErrorUtilities.VerifyThrow(parentProject  != null,
                                        "Expect the parent project to be on the node");

            Target childTarget = parentProject.Targets[child.TargetId.name];

            List<ProjectBuildState> parentStates = FindConnectingContexts(child, parent, childTarget, childTarget.ExecutionState.GetWaitingBuildContexts(),
                                      childTarget.ExecutionState.InitiatingBuildContext);

            ErrorUtilities.VerifyThrow(parentStates.Count > 0, "Must find at least one matching context");

            for (int i = 0; i < parentStates.Count; i++)
            {
                parentStates[i].CurrentBuildContextState = ProjectBuildState.BuildContextState.CycleDetected;
                TaskExecutionContext taskExecutionContext =
                    new TaskExecutionContext(parentProject, childTarget, null, parentStates[i], EngineCallback.invalidEngineHandle, 
                                             EngineCallback.inProcNode, null);

                parentEngine.PostTaskOutputUpdates(taskExecutionContext);
            }
        }
        /// <summary>
        /// Iterate over the contexts waiting for the target - triggering updates for each of them since the target 
        /// is complete
        /// </summary>
        internal void NotifyWaitingTargets(ProjectBuildState errorContext)
        {
            // If there was a failure (either unhandled exception or a cycle) the stack will
            // not unwind properly (i.e. via ContinueBuild call). Therefore the initiating request
            // must be notified the target completed if the error occurred in another context
            if (errorContext != null)
            {
                AddWaitingBuildContext(initiatingBuildContext);
            }

            // Notify the target within the same project that are waiting for current target
            // These targets are in the process of either building dependencies or error targets
            // or part of a sequential build context
            while (waitingTargets != null && waitingTargets.Count != 0)
            {
                //Grab the first context
                ProjectBuildState buildContext = waitingTargets[0];
                waitingTargets.RemoveAt(0);

                //Don't report any messages within the context in which the error occured. That context
                //is addressed as the base of the stack 
                if (buildContext == errorContext ||
                    buildContext.CurrentBuildContextState == ProjectBuildState.BuildContextState.RequestFilled)
                {
                    continue;
                }
                
                parentEngine.Scheduler.NotifyOfUnblockedRequest(buildContext.BuildRequest);

                ErrorUtilities.VerifyThrow(
                    buildContext.CurrentBuildContextState == ProjectBuildState.BuildContextState.WaitingForTarget ||
                    buildContext == initiatingBuildContext,
                    "This context should be waiting for a target to be evaluated");

                if (buildContext.NameOfBlockingTarget == null)
                {
                    ErrorUtilities.VerifyThrow(
                        String.Compare(EscapingUtilities.UnescapeAll(buildContext.NameOfTargetInProgress), targetClass.Name, StringComparison.OrdinalIgnoreCase) == 0,
                        "The name of the target in progress is inconsistent with the target being built");

                    // This target was part of a sequential request so we need to notify the parent project
                    // to start building the next target in the sequence
                    if (Engine.debugMode)
                    {
                        Console.WriteLine("Finished " + buildContext.BuildRequest.ProjectFileName + ":" + targetClass.Name + " for node:" +
                                            buildContext.BuildRequest.NodeIndex + " HandleId " + buildContext.BuildRequest.HandleId);
                    }
                }
                else
                {
                    // The target on the waiting list must be waiting for this target to complete due to
                    // a dependent or onerror relationship between targets
                    ErrorUtilities.VerifyThrow(
                        String.Compare(buildContext.NameOfBlockingTarget, targetClass.Name, StringComparison.OrdinalIgnoreCase) == 0,
                        "This target should only be updated once the dependent target is completed");

                    if (Engine.debugMode)
                    {
                        Console.WriteLine("Finished " + targetClass.Name + " notifying " + EscapingUtilities.UnescapeAll(buildContext.NameOfTargetInProgress));
                    }
                }

                // Post a dummy context to the queue to cause the target to run in this context
                TaskExecutionContext taskExecutionContext = 
                    new TaskExecutionContext(parentProject, null, null, buildContext, 
                                             EngineCallback.invalidEngineHandle, EngineCallback.inProcNode, null);
                parentEngine.PostTaskOutputUpdates(taskExecutionContext);
            }
        }
        private void ProcessTaskOutputs(TaskExecutionContext executionContext)
        {
            // Get the success or failure
            if (targetBuildSuccessful)
            {
                if (!executionContext.TaskExecutedSuccessfully)
                {
                    targetBuildSuccessful = false;
                    // Check if the task threw an unhandled exception during its execution
                    if (executionContext.ThrownException != null)
                    {
                        // The stack trace for remote task InvalidProjectFileException can be ignored
                        // since it is not recorded and the exception will be caught inside the project
                        // class
                        if (executionContext.ThrownException is InvalidProjectFileException)
                        {
                            throw executionContext.ThrownException;
                        }
                        else
                        {
                            // The error occured outside of the user code (it may still be caused
                            // by bad user input), the build should be terminated. The exception
                            // will be logged as a fatal build error in engine. The exceptions caused
                            // by user code are converted into LogFatalTaskError messages by the TaskEngine
                            RemoteErrorException.Throw(executionContext.ThrownException, 
                                                       targetBuildEventContext, 
                                                       "RemoteErrorDuringTaskExecution",
                                                       parentProject.FullFileName, 
                                                       targetClass.Name);
                        }
                    }
                    // We need to disable the execution of the task if it was previously enabled,
                    // and if were only doing execution we can stop processing at the point the
                    // error occurred. If the task fails (which implies that ContinueOnError != 'true'), then do 
                    // not execute the remaining tasks because they may depend on the completion 
                    // of this task.
                    ErrorUtilities.VerifyThrow(howToBuild == DependencyAnalysisResult.FullBuild ||
                                                howToBuild == DependencyAnalysisResult.IncrementalBuild,
                                                "We can only see a failure for an execution stage");
                    if (howToBuild != DependencyAnalysisResult.FullBuild)
                        howToBuild = DependencyAnalysisResult.SkipUpToDate;
                    else
                        exitBatchDueToError = true;
                }
            }

            currentTask++;
        }
        private void ContinueRunningTasks
        (
            ProjectBuildState buildContext, TaskExecutionContext taskExecutionContext,
            bool startingFirstTask
        )
        {
            bool exitDueToError = true;
            try
            {
                // If this is the first task - initialize for running it 
                if (startingFirstTask)
                {
                    InitializeForRunningTargetBatches();
                }

                // If run a task then process its outputs
                if (currentTask != targetElement.ChildNodes.Count && !startingFirstTask)
                {
                    ProcessTaskOutputs(taskExecutionContext);
                }

                // Check if we processed the last node in a batch or terminated the batch due to error
                if (currentTask == targetElement.ChildNodes.Count || exitBatchDueToError)
                {
                    FinishRunningSingleTargetBatch();

                    // On failure transition into unsuccessful state
                    if (!targetBuildSuccessful)
                    {
                        overallSuccess = false;
                        FinishRunningTargetBatches(buildContext);
                        // Transition the state machine into building the error clause state
                        InitializeOnErrorClauseExecution();
                        inProgressBuildState = InProgressBuildState.BuildingErrorClause;
                        ExecuteErrorTarget(buildContext);
                        exitDueToError = false;
                        return;
                    }

                    //Check if this was the last bucket 
                    if (currentBucket == buckets.Count)
                    {
                        FinishRunningTargetBatches(buildContext);
                        inProgressBuildState = InProgressBuildState.NotInProgress;
                        // Notify targets that are waiting for the results
                        NotifyBuildCompletion(Target.BuildState.CompletedSuccessfully, null);
                        exitDueToError = false;
                        return;
                    }

                    // Prepare the next bucket
                    InitializeForRunningSingleTargetBatch();
                }

                // Execute the current task
                ExecuteCurrentTask(buildContext);

                exitDueToError = false;
            }
            catch (InvalidProjectFileException e)
            {
                // Make sure the Invalid Project error gets logged *before* TargetFinished.  Otherwise,
                // the log is confusing.
                this.parentEngine.LoggingServices.LogInvalidProjectFileError(targetBuildEventContext, e);
                throw;
            }
            finally
            {
                if (exitDueToError && loggedTargetStart)
                {
                    // Log that the target has failed
                    parentEngine.LoggingServices.LogTargetFinished(
                        targetBuildEventContext,
                        targetClass.Name,
                        this.parentProject.FullFileName,
                        targetClass.ProjectFileOfTargetElement,
                        false);
                }
            }
        }
        internal void ContinueBuild
        (
            ProjectBuildState buildContext, TaskExecutionContext taskExecutionContext
        )
        {
            // Verify that the target is in progress
            ErrorUtilities.VerifyThrow(inProgressBuildState != InProgressBuildState.NotInProgress, "Not in progress");

            bool exitedDueToError = true;

            try
            {
                // In the single threaded mode we want to avoid looping all the way back to the 
                // engine because there is no need for to be interruptable to address
                // other build requests. Instead we loop inside this function untill the target is 
                // fully built.
                do
                {
                    // Transition the state machine appropriatly
                    if (inProgressBuildState == InProgressBuildState.RunningTasks)
                    {
                        ContinueRunningTasks(buildContext, taskExecutionContext, false);
                    }
                    else if (inProgressBuildState == InProgressBuildState.BuildingDependencies)
                    {
                        ContinueBuildingDependencies(buildContext);
                    }
                    else if (inProgressBuildState == InProgressBuildState.StartingBuild)
                    {
                        initiatingBuildContext = buildContext;
                        inProgressBuildState = InProgressBuildState.BuildingDependencies;
                        currentDependentTarget = 0;
                        ExecuteDependentTarget(buildContext);
                    }
                    else if (inProgressBuildState == InProgressBuildState.BuildingErrorClause)
                    {
                        ContinueBuildingErrorClause(buildContext);
                    }

                    // In the single threaded mode we need to pull up the outputs of the previous 
                    // step
                    if (parentEngine.Router.SingleThreadedMode &&
                        inProgressBuildState == InProgressBuildState.RunningTasks)
                    {
                        taskExecutionContext = parentEngine.GetTaskOutputUpdates();
                    }
                } while (parentEngine.Router.SingleThreadedMode && inProgressBuildState == InProgressBuildState.RunningTasks);

                // Indicate that we exited successfully
                exitedDueToError = false;
            }
            finally
            {
                if (exitedDueToError)
                {
                    inProgressBuildState = InProgressBuildState.NotInProgress;
                    NotifyBuildCompletion(Target.BuildState.CompletedUnsuccessfully, buildContext);
                }
            }
        }
Exemple #11
0
 internal void PostTaskOutputUpdates(TaskExecutionContext executionContext)
 {
     taskOutputUpdates.Enqueue(executionContext);
 }
Exemple #12
0
        /// <summary>
        /// This method will continue a project build which is in progress
        /// </summary>
        private void BuildProjectInternalContinue(BuildRequest buildRequest, ProjectBuildState buildContext, TaskExecutionContext taskExecutionContext, Project project)
        {
            if (buildRequest != null && ProfileBuild )
            {
                buildRequest.ProcessingStartTime = DateTime.Now.Ticks;
            }

            project.ContinueBuild(buildContext, taskExecutionContext);
        }
Exemple #13
0
        /// <summary>
        /// Builds the specific targets in an MSBuild project. Since projects can build other projects, this method may get called
        /// back recursively. It keeps track of the projects being built, so that it knows when we've popped back out to the root
        /// of the callstack again, so we can reset the state of all the projects.  Otherwise, you wouldn't be able to do more
        /// than one build using the same Engine object, because the 2nd, 3rd, etc. builds would just say "hmm, looks like this
        /// project has already been built, so I'm not going to build it again".
        /// </summary>
        private void BuildProjectInternal
        (
            BuildRequest buildRequest, 
            ProjectBuildState buildContext,
            TaskExecutionContext taskExecutionContext,
            bool initialCall
        )
        {
            Project project = buildRequest.ProjectToBuild;

            bool exitedDueToError = true;

            try
            {
                SetBuildItemCurrentDirectory(project);
                if (initialCall)
                {
#if (!STANDALONEBUILD)
                    CodeMarkers.Instance.CodeMarker(CodeMarkerEvent.perfMSBuildEngineBuildProjectBegin);
#endif
#if MSBUILDENABLEVSPROFILING 
                    string beginProjectBuild = String.Format(CultureInfo.CurrentCulture, "Build Project {0} Using Old OM - Start", project.FullFileName);
                    DataCollection.CommentMarkProfile(8802, beginProjectBuild);
#endif 

                    // Make sure we were passed in a project object.
                    error.VerifyThrowArgument(project != null, "MissingProject", "Project");

                    // Make sure this project object is associated with this engine object.
                    error.VerifyThrowInvalidOperation(project.ParentEngine == this, "IncorrectObjectAssociation", "Project", "Engine");
                }

                try
                { 
                    if (initialCall)
                    {
                        BuildProjectInternalInitial(buildRequest, project);
                    }
                    else
                    {
                        BuildProjectInternalContinue(buildRequest, buildContext, taskExecutionContext, project);
                    }

                    exitedDueToError = false;
                }
                /**********************************************************************************************************************
                * WARNING: Do NOT add any more catch blocks below! Exceptions should be caught as close to their point of origin as
                * possible, and converted into one of the known exceptions. The code that causes an exception best understands the
                * reason for the exception, and only that code can provide the proper error message. We do NOT want to display
                * messages from unknown exceptions, because those messages are most likely neither localized, nor composed in the
                * canonical form with the correct prefix.
                *********************************************************************************************************************/
                // Handle errors in the project file.
                catch (InvalidProjectFileException e)
                {
                    primaryLoggingServices.LogInvalidProjectFileError(buildRequest.ParentBuildEventContext, e);
                }
                // Handle logger failures -- abort immediately
                catch (LoggerException)
                {
                    // Polite logger failure
                    throw;
                }
                catch (InternalLoggerException)
                {
                    // Logger threw arbitrary exception
                    throw;
                }
                // Handle all other errors.  These errors are completely unexpected, so
                // make sure to give the callstack as well.
                catch (Exception)
                {
                    fatalErrorContext = buildRequest.ParentBuildEventContext;
                    fatalErrorProjectName = project.FullFileName;

                    // Rethrow so that the host can catch it and possibly rethrow it again
                    // so that Watson can give the user the option to send us an error report.
                    throw;
                }

                /**********************************************************************************************************************
                * WARNING: Do NOT add any more catch blocks above!
                *********************************************************************************************************************/
                finally
                {
                    FinishBuildProjectInProgress(buildRequest, buildContext, exitedDueToError);
                }
            }
            finally
            {
                // Flush out all the logging messages, which may have been posted outside target execution
                primaryLoggingServices.ProcessPostedLoggingEvents();

                if (buildRequest != null && buildRequest.BuildCompleted || exitedDueToError)
                {
#if (!STANDALONEBUILD)
                    CodeMarkers.Instance.CodeMarker(CodeMarkerEvent.perfMSBuildEngineBuildProjectEnd);
#endif
#if MSBUILDENABLEVSPROFILING 
                    string endProjectBuild = String.Format(CultureInfo.CurrentCulture, "Build Project {0} Using Old OM - End", project.FullFileName);
                    DataCollection.CommentMarkProfile(8803, endProjectBuild);
#endif 
                }
            }
        }
Exemple #14
0
 /// <summary>
 /// This method is called repeatedly to execute the target in multi-threaded mode. In single
 /// threaded mode it is called once and it loops internally until the execution is finished.
 /// </summary>
 /// <param name="buildContext">Context within which the target is being executed</param>
 /// <param name="taskExecutionContext">Result of last execution (multi-threaded only)</param>
 internal void ContinueBuild(ProjectBuildState buildContext, TaskExecutionContext taskExecutionContext)
 {
     executionState.ContinueBuild(buildContext, taskExecutionContext);
 }