private void InitializeForRunningSingleTargetBatch() { // Verify that the target is in the right state ErrorUtilities.VerifyThrow(inProgressBuildState == InProgressBuildState.RunningTasks, "Wrong state"); // Check if the current task number is valid ErrorUtilities.VerifyThrow(currentBucket < buckets.Count, "No buckets left"); Hashtable changedTargetInputs = null; Hashtable upToDateTargetInputs = null; howToBuild = DependencyAnalysisResult.FullBuild; ItemBucket bucket = (ItemBucket)buckets[currentBucket]; // For the first batch of a target use the targets original targetID. for each batch after the first one use a uniqueId to identity the target in the batch if (currentBucket != 0) { targetBuildEventContext = new BuildEventContext(targetBuildEventContext.NodeId, parentEngine.GetNextTargetId(), targetBuildEventContext.ProjectContextId, targetBuildEventContext.TaskId); } // Flag the start of the target. parentEngine.LoggingServices.LogTargetStarted( targetBuildEventContext, targetClass.Name, this.parentProject.FullFileName, targetClass.ProjectFileOfTargetElement); loggedTargetStart = true; // Figure out how we should build the target TargetDependencyAnalyzer dependencyAnalyzer = new TargetDependencyAnalyzer(parentProject.ProjectDirectory, targetClass, parentEngine.LoggingServices, targetBuildEventContext); howToBuild = dependencyAnalyzer.PerformDependencyAnalysis(bucket, out changedTargetInputs, out upToDateTargetInputs); targetBuildSuccessful = true; exitBatchDueToError = false; // If we need to build the target - initialize the data structure for // running the tasks if ((howToBuild != DependencyAnalysisResult.SkipNoInputs) && (howToBuild != DependencyAnalysisResult.SkipNoOutputs)) { // Within each target batch items are divided into lookup and execution; they must be // kept separate: enforce this by cloning and entering scope lookupForInference = bucket.Lookup; lookupForExecution = bucket.Lookup.Clone(); lookupForInference.EnterScope(); lookupForExecution.EnterScope(); // if we're doing an incremental build, we need to effectively run the task twice -- once // to infer the outputs for up-to-date input items, and once to actually execute the task; // as a result we need separate sets of item and property collections to track changes if (howToBuild == DependencyAnalysisResult.IncrementalBuild) { // subset the relevant items to those that are up-to-date foreach (DictionaryEntry upToDateTargetInputsEntry in upToDateTargetInputs) { lookupForInference.PopulateWithItems((string)upToDateTargetInputsEntry.Key, (BuildItemGroup)upToDateTargetInputsEntry.Value); } // subset the relevant items to those that have changed foreach (DictionaryEntry changedTargetInputsEntry in changedTargetInputs) { lookupForExecution.PopulateWithItems((string)changedTargetInputsEntry.Key, (BuildItemGroup)changedTargetInputsEntry.Value); } } projectFileOfTaskNode = XmlUtilities.GetXmlNodeFile(targetElement, parentProject.FullFileName); // count the tasks in the target currentTask = 0; skippedNodeCount = 0; } else { currentTask = targetElement.ChildNodes.Count; } }
private DependencyAnalysisResult PerformDependencyAnalysisTestHelper ( FileWriteInfo [] filesToAnalyze, Hashtable itemsByName, string inputs, string outputs, out Hashtable changedTargetInputs, out Hashtable upToDateTargetInputs ) { List<string> filesToDelete = new List<string>(); try { // first set the disk up for (int i = 0; i < filesToAnalyze.Length; ++i) { string path = ObjectModelHelpers.CreateFileInTempProjectDirectory(filesToAnalyze[i].Path, ""); File.SetLastWriteTime(path, filesToAnalyze[i].LastWriteTime); filesToDelete.Add(path); } // now create the project string unformattedProjectXml = @" <Project ToolsVersion=`3.5` xmlns=`msbuildnamespace`> <Target Name=`Build` Inputs=`{0}` Outputs=`{1}`> </Target> </Project> "; Project p = ObjectModelHelpers.CreateInMemoryProject(String.Format(unformattedProjectXml, inputs, outputs)); // now do the dependency analysis ItemBucket itemBucket = new ItemBucket(null, null, LookupHelpers.CreateLookup(itemsByName), 0); TargetDependencyAnalyzer analyzer = new TargetDependencyAnalyzer(ObjectModelHelpers.TempProjectDir, p.Targets["Build"], p.ParentEngine.LoggingServices, (BuildEventContext)null); return analyzer.PerformDependencyAnalysis(itemBucket, out changedTargetInputs, out upToDateTargetInputs); } finally { // finally clean up foreach (string path in filesToDelete) { if (File.Exists(path)) File.Delete(path); } } }