public void OutputCLMinimalRebuildOptimizationComputed() { Console.WriteLine("Test: OutputCLMinimalRebuildOptimizationComputed"); // Prepare read tlog DependencyTestHelper.WriteAll("TestFiles\\one1.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one2.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one3.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one.cpp", ""); DependencyTestHelper.WriteAll("TestFiles\\two.cpp", ""); DependencyTestHelper.WriteAll("TestFiles\\three.cpp", ""); Thread.Sleep(sleepTimeMilliseconds); DependencyTestHelper.WriteAll("TestFiles\\one.obj", ""); DependencyTestHelper.WriteAll("TestFiles\\two.obj", ""); DependencyTestHelper.WriteAll("TestFiles\\three.obj", ""); Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register File.WriteAllLines("TestFiles\\one.read.tlog", new string[] { "#Command some-command", "^" + Path.GetFullPath("TestFiles\\one.cpp"), Path.GetFullPath("TestFiles\\one1.h"), Path.GetFullPath("TestFiles\\one2.h"), Path.GetFullPath("TestFiles\\one3.h"), "^" + Path.GetFullPath("TestFiles\\two.cpp"), Path.GetFullPath("TestFiles\\one1.h"), Path.GetFullPath("TestFiles\\one2.h"), Path.GetFullPath("TestFiles\\one3.h"), "^" + Path.GetFullPath("TestFiles\\three.cpp"), Path.GetFullPath("TestFiles\\one1.h"), Path.GetFullPath("TestFiles\\one2.h"), Path.GetFullPath("TestFiles\\one3.h"), }); // Our source files ITaskItem[] sources = { new TaskItem("TestFiles\\one.cpp"), new TaskItem("TestFiles\\two.cpp"), new TaskItem("TestFiles\\three.cpp"), }; // Prepare write tlog File.WriteAllLines("TestFiles\\one.write.tlog", new string[] { "#Command some-command", "^" + FileTracker.FormatRootingMarker(sources), Path.GetFullPath("TestFiles\\one.obj"), Path.GetFullPath("TestFiles\\two.obj"), Path.GetFullPath("TestFiles\\three.obj"), }); // Represent our tracked and computed outputs CanonicalTrackedOutputFiles outputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog"))); // "Compute" the additional output information for this compilation, rather than them being tracked outputs.AddComputedOutputForSourceRoot(Path.GetFullPath("TestFiles\\one.cpp"), Path.GetFullPath("TestFiles\\one.obj")); outputs.AddComputedOutputForSourceRoot(Path.GetFullPath("TestFiles\\two.cpp"), Path.GetFullPath("TestFiles\\two.obj")); outputs.AddComputedOutputForSourceRoot(Path.GetFullPath("TestFiles\\three.cpp"), Path.GetFullPath("TestFiles\\three.obj")); // Represent our tracked and provided inputs CanonicalTrackedInputFiles d = new CanonicalTrackedInputFiles ( DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")), sources, null, outputs, false, /* no minimal rebuild optimization */ false /* shred composite rooting markers */ ); // First of all, all things should be up to date ITaskItem[] outofdate = d.ComputeSourcesNeedingCompilation(); Assert.Equal(0, outofdate.Length); // Delete one of the outputs in the group File.Delete(Path.GetFullPath("TestFiles\\two.obj")); // With optimization off, all sources in the group will need compilation d.SourcesNeedingCompilation = null; outofdate = d.ComputeSourcesNeedingCompilation(); Assert.Equal(3, outofdate.Length); // With optimization on, only the source that matches the output will need compilation d = new CanonicalTrackedInputFiles ( DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")), sources, null, outputs, true, /* enable minimal rebuild optimization */ false /* shred composite rooting markers */ ); outofdate = d.ComputeSourcesNeedingCompilation(); Assert.Equal(1, outofdate.Length); // And the source is.. two.cpp! Assert.Equal(outofdate[0].ItemSpec, "TestFiles\\two.cpp"); }
public void ReplaceOutputForSource() { Console.WriteLine("Test: ReplaceOutputForSource"); if (File.Exists(Path.GetFullPath("TestFiles\\three.i"))) { File.Delete(Path.GetFullPath("TestFiles\\three.i")); } // Prepare read tlog DependencyTestHelper.WriteAll("TestFiles\\one1.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one2.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one3.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one.cpp", ""); DependencyTestHelper.WriteAll("TestFiles\\two.cpp", ""); DependencyTestHelper.WriteAll("TestFiles\\three.cpp", ""); Thread.Sleep(sleepTimeMilliseconds); DependencyTestHelper.WriteAll("TestFiles\\one.obj", ""); DependencyTestHelper.WriteAll("TestFiles\\two.obj", ""); DependencyTestHelper.WriteAll("TestFiles\\three.obj", ""); Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register File.WriteAllLines("TestFiles\\one.read.tlog", new string[] { "#Command some-command", "^" + Path.GetFullPath("TestFiles\\one.cpp"), Path.GetFullPath("TestFiles\\one1.h").ToUpperInvariant(), Path.GetFullPath("TestFiles\\one2.h"), Path.GetFullPath("TestFiles\\one3.h"), "^" + Path.GetFullPath("TestFiles\\two.cpp"), Path.GetFullPath("TestFiles\\one1.h"), Path.GetFullPath("TestFiles\\one2.h"), Path.GetFullPath("TestFiles\\one3.h"), "^" + Path.GetFullPath("TestFiles\\three.cpp"), Path.GetFullPath("TestFiles\\one1.h"), Path.GetFullPath("TestFiles\\one2.h"), Path.GetFullPath("TestFiles\\one3.h"), }); // Our source files ITaskItem[] sources = { new TaskItem("TestFiles\\one.cpp"), new TaskItem("TestFiles\\two.cpp"), new TaskItem("TestFiles\\three.cpp"), }; // Prepare write tlog File.WriteAllLines("TestFiles\\one.write.tlog", new string[] { "#Command some-command", "^" + Path.GetFullPath("TestFiles\\one.cpp"), Path.GetFullPath("TestFiles\\one.obj"), "^" + Path.GetFullPath("TestFiles\\two.cpp"), Path.GetFullPath("TestFiles\\two.obj"), "^" + Path.GetFullPath("TestFiles\\three.cpp"), Path.GetFullPath("TestFiles\\three.obj"), }); // Represent our tracked and computed outputs CanonicalTrackedOutputFiles outputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog"))); // Change the output (note that this doesn't affect the timestamp) File.Move(Path.GetFullPath("TestFiles\\three.obj"), Path.GetFullPath("TestFiles\\three.i")); string threeRootingMarker = FileTracker.FormatRootingMarker(new TaskItem("TestFiles\\three.cpp")); // Remove the fact that three.obj was the tracked output bool removed = outputs.RemoveOutputForSourceRoot(threeRootingMarker, Path.GetFullPath("TestFiles\\three.obj")); Assert.True(removed); // "Compute" the replacement output information for this compilation, rather than the one originally tracked outputs.AddComputedOutputForSourceRoot(threeRootingMarker, Path.GetFullPath("TestFiles\\three.i")); // Represent our tracked and provided inputs CanonicalTrackedInputFiles d = new CanonicalTrackedInputFiles ( DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")), sources, null, outputs, true, /* minimal rebuild optimization */ false /* shred composite rooting markers */ ); // We should have one output for three.cpp Assert.Equal(1, outputs.DependencyTable[threeRootingMarker].Count); Assert.Equal(false, outputs.DependencyTable[threeRootingMarker].ContainsKey(Path.GetFullPath("TestFiles\\three.obj"))); // All things should be up to date ITaskItem[] outofdate = d.ComputeSourcesNeedingCompilation(); Assert.Equal(0, outofdate.Length); // Delete the new output File.Delete(Path.GetFullPath("TestFiles\\three.i")); // This means a recompile would be required for the roots d.SourcesNeedingCompilation = null; outofdate = d.ComputeSourcesNeedingCompilation(); Assert.Equal(1, outofdate.Length); }
protected virtual CanonicalTrackedOutputFiles OutputWriteTLog(ITaskItem[] inputs) { string path = Path.Combine(TlogDirectory, WriteTLogFilename); TaskItem item = new TaskItem(path); CanonicalTrackedOutputFiles trackedFiles = new CanonicalTrackedOutputFiles(new TaskItem[] { item }); foreach (ITaskItem sourceItem in Sources) { //remove this entry associated with compiled source which is about to be recomputed trackedFiles.RemoveEntriesForSource(sourceItem); //add entry with updated information string upper = Path.GetFullPath(sourceItem.ItemSpec).ToUpperInvariant(); trackedFiles.AddComputedOutputForSourceRoot(upper, OutputFile); } //output tlog trackedFiles.SaveTlog(); return trackedFiles; }
private CanonicalTrackedOutputFiles ConstructWriteTLog( ITaskItem[] upToDateSources ) { // Remove any files we're about to compile from the log TaskItem item = new TaskItem( Path.Combine( TrackerIntermediateDirectory, WriteTLogNames[0] ) ); CanonicalTrackedOutputFiles files = new CanonicalTrackedOutputFiles( new TaskItem[] { item } ); files.RemoveEntriesForSource( Sources ); // Add in the files we're compiling right now. Essentially just updating their output object filenames. foreach ( ITaskItem sourceItem in upToDateSources ) { string sourcePath = Path.GetFullPath( sourceItem.ItemSpec ).ToUpperInvariant(); string objectFile = Path.GetFullPath( sourceItem.GetMetadata( "ObjectFileName" ) ).ToUpperInvariant(); files.AddComputedOutputForSourceRoot( sourcePath, objectFile ); } // Save it out files.SaveTlog(); // Pass onto the ReadTLog saving return files; }
protected override int ExecuteTool(string pathToTool, string responseFileCommands, string commandLineCommands) { responseFileCommands = responseFileCommands.Replace("[PackageName]", PackageName); commandLineCommands = commandLineCommands.Replace("[PackageName]", PackageName); string src = ""; foreach (var item in Sources) src += " " + item.ToString(); if (ShowCommandLine) Log.LogMessage(MessageImportance.High, pathToTool + " " + responseFileCommands + " " + commandLineCommands); else Log.LogMessage(MessageImportance.High, "Compiling" + src); /* return base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands); */ int num = 0; try { num = this.TrackerExecuteTool(pathToTool, responseFileCommands, commandLineCommands); return num; } finally { if (this.MinimalRebuildFromTracking || this.TrackFileAccess) { CanonicalTrackedOutputFiles trackedOutputFiles = new CanonicalTrackedOutputFiles(this.TLogWriteFiles); CanonicalTrackedInputFiles trackedInputFiles = new CanonicalTrackedInputFiles(this.TLogReadFiles, this.Sources, this.ExcludedInputPaths, trackedOutputFiles, true, this.MaintainCompositeRootingMarkers); DependencyFilter includeInTLog = new DependencyFilter(this.OutputDependencyFilter); DependencyFilter dependencyFilter = new DependencyFilter(this.InputDependencyFilter); this.trackedInputFilesToRemove = new Dictionary<string, ITaskItem>((IEqualityComparer<string>) StringComparer.OrdinalIgnoreCase); if (this.TrackedInputFilesToIgnore != null) { foreach (ITaskItem taskItem in this.TrackedInputFilesToIgnore) this.trackedInputFilesToRemove.Add(taskItem.GetMetadata("FullPath"), taskItem); } this.trackedOutputFilesToRemove = new Dictionary<string, ITaskItem>((IEqualityComparer<string>) StringComparer.OrdinalIgnoreCase); if (this.TrackedOutputFilesToIgnore != null) { foreach (ITaskItem taskItem in this.TrackedOutputFilesToIgnore) this.trackedOutputFilesToRemove.Add(taskItem.GetMetadata("FullPath"), taskItem); } trackedOutputFiles.RemoveDependenciesFromEntryIfMissing(this.SourcesCompiled); trackedInputFiles.RemoveDependenciesFromEntryIfMissing(this.SourcesCompiled); if (num != 0) { ITaskItem[] source1; ITaskItem[] upToDateSources; if (this.SourcesCompiled.Length > 1) { KeyValuePair<string, bool>[] keyValuePairArray = new KeyValuePair<string, bool>[]{ new KeyValuePair<string, bool>("ObjectFile", true), /* new KeyValuePair<string, bool>("BrowseInformationFile", this.BrowseInformation), new KeyValuePair<string, bool>("XMLDocumentationFileName", this.GenerateXMLDocumentationFiles) */ }; foreach (ITaskItem source2 in this.Sources) { string sourceKey = FileTracker.FormatRootingMarker(source2); foreach (KeyValuePair<string, bool> keyValuePair in keyValuePairArray) { string metadata = source2.GetMetadata(keyValuePair.Key); if (keyValuePair.Value && !string.IsNullOrEmpty(metadata)) trackedOutputFiles.AddComputedOutputForSourceRoot(sourceKey, metadata); } } source1 = trackedInputFiles.ComputeSourcesNeedingCompilation(); List<ITaskItem> taskItemList = new List<ITaskItem>(); int index = 0; foreach (ITaskItem taskItem in this.SourcesCompiled) { if (index >= source1.Length) taskItemList.Add(taskItem); else if (!source1[index].Equals((object) taskItem)) taskItemList.Add(taskItem); else ++index; } upToDateSources = taskItemList.ToArray(); foreach (ITaskItem source2 in this.Sources) { string sourceRoot = FileTracker.FormatRootingMarker(source2); foreach (KeyValuePair<string, bool> keyValuePair in keyValuePairArray) { string metadata = source2.GetMetadata(keyValuePair.Key); if (keyValuePair.Value && !string.IsNullOrEmpty(metadata)) trackedOutputFiles.RemoveOutputForSourceRoot(sourceRoot, metadata); } } } else { source1 = this.SourcesCompiled; upToDateSources = new ITaskItem[0]; } //trackedOutputFiles.RemoveEntriesForSource(source1, this.preprocessOutput); trackedOutputFiles.SaveTlog(includeInTLog); trackedInputFiles.RemoveEntriesForSource(source1); trackedInputFiles.SaveTlog(dependencyFilter); this.ConstructCommandTLog(upToDateSources, dependencyFilter); } else { this.RemoveTaskSpecificInputs(trackedInputFiles); trackedOutputFiles.SaveTlog(includeInTLog); trackedInputFiles.SaveTlog(dependencyFilter); this.ConstructCommandTLog(this.SourcesCompiled, dependencyFilter); } TrackedVCToolTask.DeleteEmptyFile(this.TLogWriteFiles); TrackedVCToolTask.DeleteEmptyFile(this.TLogReadFiles); } } }
private void GetResourcesToProcess(out List<ITaskItem> inputsToProcess, out List<ITaskItem> outputsToProcess) { CanonicalTrackedInputFiles files2; inputsToProcess = new List<ITaskItem>(); outputsToProcess = new List<ITaskItem>(); for (int i = 0; i < this.Sources.Length; i++) { this.Sources[i].CopyMetadataTo(this.OutputResources[i]); this.Sources[i].SetMetadata("OutputResource", this.OutputResources[i].ItemSpec); } if (!this.MinimalRebuildFromTracking) { for (int j = 0; j < this.Sources.Length; j++) { inputsToProcess.Add(this.Sources[j]); outputsToProcess.Add(this.OutputResources[j]); } return; } ITaskItem[] readTLogs = TrackedDependencies.ExpandWildcards(this.TLogReadFiles); ITaskItem[] writeTLogs = TrackedDependencies.ExpandWildcards(this.TLogWriteFiles); if (((this.AdditionalInputs != null) && (this.AdditionalInputs.Length > 0)) && this.AnyAdditionalInputOutOfDate(readTLogs, writeTLogs)) { for (int k = 0; k < this.Sources.Length; k++) { inputsToProcess.Add(this.Sources[k]); outputsToProcess.Add(this.OutputResources[k]); } return; } CanonicalTrackedOutputFiles outputs = new CanonicalTrackedOutputFiles(this, writeTLogs, false); foreach (ITaskItem item in this.Sources) { string sourceKey = FileTracker.FormatRootingMarker(item); outputs.AddComputedOutputForSourceRoot(sourceKey, item.GetMetadata(outputFileMetadataName)); } if (this.StronglyTypedLanguage != null) { try { if (this.StronglyTypedFileName == null) { CodeDomProvider provider = null; if (ProcessResourceFiles.TryCreateCodeDomProvider(base.Log, this.StronglyTypedLanguage, out provider)) { this.StronglyTypedFileName = ProcessResourceFiles.GenerateDefaultStronglyTypedFilename(provider, this.OutputResources[0].ItemSpec); } } if (this.StronglyTypedFileName != null) { string str2 = FileTracker.FormatRootingMarker(this.Sources[0]); outputs.AddComputedOutputForSourceRoot(str2, this.StronglyTypedFileName); goto Label_01F8; } this.unsuccessfullyCreatedOutFiles.Add(this.OutputResources[0].ItemSpec); } catch (Exception exception) { if (Microsoft.Build.Shared.ExceptionHandling.NotExpectedException(exception)) { throw; } base.Log.LogErrorWithCodeFromResources("GenerateResource.CannotWriteSTRFile", new object[] { this.StronglyTypedFileName, exception.Message }); this.unsuccessfullyCreatedOutFiles.Add(this.OutputResources[0].ItemSpec); } return; } Label_01F8: files2 = new CanonicalTrackedInputFiles(this, readTLogs, this.Sources, this.ExcludedInputPaths, outputs, true, false); ITaskItem[] source = files2.ComputeSourcesNeedingCompilation(); if (source.Length == 0) { if (!string.IsNullOrEmpty(this.StronglyTypedLanguage)) { this.stronglyTypedResourceSuccessfullyCreated = true; } } else { foreach (ITaskItem item2 in source) { inputsToProcess.Add(item2); ITaskItem2 item3 = item2 as ITaskItem2; if (item3 != null) { outputsToProcess.Add(new TaskItem(item3.GetMetadataValueEscaped("OutputResource"))); } else { outputsToProcess.Add(new TaskItem(Microsoft.Build.Shared.EscapingUtilities.Escape(item2.GetMetadata("OutputResource")))); } } try { files2.RemoveEntriesForSource(source); files2.SaveTlog(); outputs = new CanonicalTrackedOutputFiles(this, this.TLogWriteFiles); outputs.RemoveEntriesForSource(source); outputs.SaveTlog(); } catch (Exception exception2) { if (Microsoft.Build.Shared.ExceptionHandling.NotExpectedException(exception2) && !(exception2 is UnauthorizedAccessException)) { throw; } base.Log.LogErrorFromException(exception2); } } }
private void CompactTrackingLogs(bool taskSucceeded) { CanonicalTrackedOutputFiles outputs = new CanonicalTrackedOutputFiles(this.TLogWriteFiles); CanonicalTrackedInputFiles files2 = new CanonicalTrackedInputFiles(this.TLogReadFiles, this.Sources, this.ExcludedInputPaths, outputs, true, false); outputs.RemoveDependenciesFromEntryIfMissing(this.Sources); files2.RemoveDependenciesFromEntryIfMissing(this.Sources); if (!taskSucceeded) { foreach (ITaskItem item in this.Sources) { string sourceKey = FileTracker.FormatRootingMarker(item); outputs.AddComputedOutputForSourceRoot(sourceKey, item.GetMetadata(outputFileMetadataName)); } ITaskItem[] source = files2.ComputeSourcesNeedingCompilation(); foreach (ITaskItem item2 in this.Sources) { string sourceRoot = FileTracker.FormatRootingMarker(item2); outputs.RemoveOutputForSourceRoot(sourceRoot, item2.GetMetadata(outputFileMetadataName)); } outputs.RemoveEntriesForSource(source); files2.RemoveEntriesForSource(source); } if (!string.IsNullOrEmpty(this.StronglyTypedFileName) && this.stronglyTypedResourceSuccessfullyCreated) { string stronglyTypedFileName = this.StronglyTypedFileName; foreach (ITaskItem item3 in this.Sources) { string str4 = FileTracker.FormatRootingMarker(item3); outputs.AddComputedOutputForSourceRoot(str4, stronglyTypedFileName); } } files2.SaveTlog(); outputs.SaveTlog(); }