public CanonicalTrackedInputFiles(ITask ownerTask, ITaskItem[] tlogFiles, ITaskItem[] sourceFiles, ITaskItem[] excludedInputPaths, CanonicalTrackedOutputFiles outputs, bool useMinimalRebuildOptimization, bool maintainCompositeRootingMarkers) { this.outputNewestTime = DateTime.MinValue; this.outputNewest = ""; this.excludedInputPaths = new HashSet<string>(StringComparer.Ordinal); this.lastWriteTimeCache = new ConcurrentDictionary<string, DateTime>(StringComparer.Ordinal); this.InternalConstruct(ownerTask, tlogFiles, sourceFiles, null, excludedInputPaths, outputs, useMinimalRebuildOptimization, maintainCompositeRootingMarkers); }
protected override bool ComputeOutOfDateSources() { // Same as base class, other than the things commented out. // We're not using CustomTrackedVCToolTask's File Tracker, we're using our own. Hence these changes. if (this.TrackerIntermediateDirectory != null) { string trackerIntermediateDirectory = this.TrackerIntermediateDirectory; } if (this.MinimalRebuildFromTracking || this.TrackFileAccess) { this.AssignDefaultTLogPaths(); } if (this.MinimalRebuildFromTracking && !this.ForcedRebuildRequired()) { CanonicalTrackedOutputFiles outputs = new CanonicalTrackedOutputFiles(this, this.TLogWriteFiles); this.SourceDependencies = new CanonicalTrackedInputFiles(this, this.TLogReadFiles, this.Sources /*TrackedInputFiles*/, this.ExcludedInputPaths, outputs, /*this.UseMinimalRebuildOptimization*/ true, /*this.MaintainCompositeRootingMarkers*/ false); ITaskItem[] sourcesOutOfDateThroughTracking = this.SourceDependencies.ComputeSourcesNeedingCompilation(/*false*/); List<ITaskItem> sourcesWithChangedCommandLines = this.GenerateSourcesOutOfDateDueToCommandLine(); this.SourcesCompiled = this.MergeOutOfDateSourceLists(sourcesOutOfDateThroughTracking, sourcesWithChangedCommandLines); if (this.SourcesCompiled.Length == 0) { this.SkippedExecution = true; return this.SkippedExecution; } this.SourcesCompiled = this.AssignOutOfDateSources(this.SourcesCompiled); this.SourceDependencies.RemoveEntriesForSource(this.SourcesCompiled); this.SourceDependencies.SaveTlog(); outputs.RemoveEntriesForSource(this.SourcesCompiled); outputs.SaveTlog(); } else { this.SourcesCompiled = this.TrackedInputFiles; if ((this.SourcesCompiled == null) || (this.SourcesCompiled.Length == 0)) { this.SkippedExecution = true; return this.SkippedExecution; } } // if (this.TrackFileAccess) // { // this.RootSource = FileTracker.FormatRootingMarker(this.SourcesCompiled); // } this.SkippedExecution = false; return this.SkippedExecution; }
public void WriteTLogWithInitialEmptyLine() { Console.WriteLine("Test: WriteTLogWithInitialEmptyLine"); // Prepare files File.WriteAllLines("TestFiles\\one.write.tlog", new string[] { "", "^FOO" }); MockTask task = DependencyTestHelper.MockTask; CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles ( task, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")) ); Assert.Equal(1, ((task as ITask).BuildEngine as MockEngine).Warnings); // "Should have a warning." Assert.Equal(0, d.DependencyTable.Count); // "DependencyTable should be empty." }
public void RootContainsSubRoots() { Console.WriteLine("Test: RootContainsSubRoots"); CanonicalTrackedOutputFiles output = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, null); Assert.True(output.RootContainsAllSubRootComponents("a|b|c|d|e|f|g", "a|b|C|d|e|F|g")); Assert.True(output.RootContainsAllSubRootComponents("a|b|c|d|e|f|g", "a")); Assert.True(output.RootContainsAllSubRootComponents("a|b|c|d|e|f|g", "g")); Assert.True(output.RootContainsAllSubRootComponents("a|b|c|d|e|f|g", "d")); Assert.True(output.RootContainsAllSubRootComponents("a|b|c|d|e|f|g", "a|b")); Assert.True(output.RootContainsAllSubRootComponents("a|b|c|d|e|f|g", "f|g")); Assert.True(output.RootContainsAllSubRootComponents("a|b|c|d|e|f|g", "b|a")); Assert.True(output.RootContainsAllSubRootComponents("a|b|c|d|e|f|g", "g|f")); Assert.True(output.RootContainsAllSubRootComponents("a|b|c|d|e|f|g", "b|e")); }
public void RemoveRootsWithSharedOutputs_CurrentRootNotInTable() { Console.WriteLine("Test: RemoveRootsWithSharedOutputs"); DependencyTestHelper.WriteAll("TestFiles\\one1.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one2.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one3.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one.cpp", ""); DependencyTestHelper.WriteAll("TestFiles\\one.obj", ""); DependencyTestHelper.WriteAll("TestFiles\\one.tlh", ""); DependencyTestHelper.WriteAll("TestFiles\\one.tli", ""); Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register string rootingMarker1 = Path.GetFullPath("TestFiles\\one.cpp") + "|" + Path.GetFullPath("TestFiles\\three.cpp") + "|" + Path.GetFullPath("TestFiles\\two.cpp"); string rootingMarker2 = Path.GetFullPath("TestFiles\\one.cpp") + "|" + Path.GetFullPath("TestFiles\\three.cpp"); string rootingMarker3 = Path.GetFullPath("TestFiles\\one.cpp"); File.WriteAllLines("TestFiles\\one.write.tlog", new string[] { "#Command some-command", "^" + rootingMarker1.ToUpperInvariant(), Path.GetFullPath("TestFiles\\one1.h"), Path.GetFullPath("TestFiles\\one2.h"), Path.GetFullPath("TestFiles\\one3.h"), "^" + rootingMarker2.ToUpperInvariant(), Path.GetFullPath("TestFiles\\one3.obj"), Path.GetFullPath("TestFiles\\one3.tlh"), Path.GetFullPath("TestFiles\\one3.tli"), "^" + rootingMarker3.ToUpperInvariant(), Path.GetFullPath("TestFiles\\one1.h"), Path.GetFullPath("TestFiles\\one2.obj"), }); CanonicalTrackedOutputFiles outputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog"))); Assert.True(outputs.DependencyTable.ContainsKey(rootingMarker1)); Assert.True(outputs.DependencyTable.ContainsKey(rootingMarker2)); Assert.True(outputs.DependencyTable.ContainsKey(rootingMarker3)); outputs.RemoveRootsWithSharedOutputs(new ITaskItem[] { new TaskItem("TestFiles\\four.cpp"), new TaskItem("TestFiles\\one.cpp"), new TaskItem("TestFiles\\three.cpp"), new TaskItem("TestFiles\\two.cpp") }); Assert.True(outputs.DependencyTable.ContainsKey(rootingMarker1)); Assert.True(outputs.DependencyTable.ContainsKey(rootingMarker2)); Assert.True(outputs.DependencyTable.ContainsKey(rootingMarker3)); }
public void OutputSingleCanonicalCLAcrossTlogs() { Console.WriteLine("Test: OutputSingleCanonicalCLAcrossTlogs"); // Prepare files Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register File.WriteAllLines("TestFiles\\one.tlog", new string[] { "#Command some-command", "^" + Path.GetFullPath("TestFiles\\one.cpp"), Path.GetFullPath("TestFiles\\oNe.obj"), }); File.WriteAllLines("TestFiles\\two.tlog", new string[] { "#Command some-command", "^" + Path.GetFullPath("TestFiles\\one.cpp"), Path.GetFullPath("TestFiles\\one.pch"), }); ITaskItem[] tlogs = { new TaskItem("TestFiles\\one.tlog"), new TaskItem("TestFiles\\two.tlog") }; CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, tlogs); ITaskItem[] outputs = d.OutputsForSource(new TaskItem(Path.GetFullPath("TestFiles\\one.cpp"))); Assert.Equal(2, outputs.Length); Assert.Equal(outputs[0].ItemSpec, Path.GetFullPath("TestFiles\\oNe.obj")); Assert.Equal(outputs[1].ItemSpec, Path.GetFullPath("TestFiles\\one.pch")); }
public void OutputMultipleUnrecognisedRootCanonicalCL() { Console.WriteLine("Test: OutputMultipleUnrecognisedRootCanonicalCL"); // Prepare files Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register File.WriteAllLines("TestFiles\\one.tlog", new string[] { "#Command some-command", "^" + Path.GetFullPath("TestFiles\\one.cpp") + "|" + Path.GetFullPath("TestFiles\\two.cpp") + "|" + Path.GetFullPath("TestFiles\\three.cpp"), Path.GetFullPath("TestFiles\\oNe.obj"), Path.GetFullPath("TestFiles\\two.obj"), Path.GetFullPath("TestFiles\\three.obj"), }); CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.tlog"))); ITaskItem[] outputs = d.OutputsForSource(new TaskItem(Path.GetFullPath("TestFiles\\four.cpp"))); Assert.Equal(0, outputs.Length); }
public void OutputMultipleCanonicalCLLongTempPath() { Console.WriteLine("Test: OutputMultipleCanonicalCLLongTempPath"); ITaskItem[] sources = new TaskItem[] { new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\two.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\three.cpp"))}; string oldTempPath = Environment.GetEnvironmentVariable("TEMP"); string oldTmpPath = Environment.GetEnvironmentVariable("TMP"); string newTempPath = Path.GetFullPath("TestFiles\\ThisIsAReallyVeryLongTemporaryPlace\\ThatIsLongerThanTheSourcePaths"); Directory.CreateDirectory(newTempPath); Environment.SetEnvironmentVariable("TEMP", newTempPath); Environment.SetEnvironmentVariable("TMP", newTempPath); Console.WriteLine("Test: OutputMultipleCanonicalCL"); // Prepare files Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register File.WriteAllLines("TestFiles\\one.tlog", new string[] { "#Command some-command", "^" + FileTracker.FormatRootingMarker(sources), Path.GetFullPath("TestFiles\\oNe.obj"), Path.GetFullPath("TestFiles\\two.obj"), Path.GetFullPath("TestFiles\\three.obj"), }); CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.tlog"))); ITaskItem[] outputs = d.OutputsForSource(sources); Environment.SetEnvironmentVariable("TEMP", oldTempPath); Environment.SetEnvironmentVariable("TMP", oldTmpPath); Assert.Equal(3, outputs.Length); Assert.Equal(outputs[0].ItemSpec, Path.GetFullPath("TestFiles\\oNe.obj")); Assert.Equal(outputs[1].ItemSpec, Path.GetFullPath("TestFiles\\two.obj")); Assert.Equal(outputs[2].ItemSpec, Path.GetFullPath("TestFiles\\three.obj")); }
public void MultipleCanonicalCLMissingOutputDependencyRemoved() { Console.WriteLine("Test: MultipleCanonicalCLMissingOutputDependencyRemoved"); // Prepare files 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", ""); Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register DependencyTestHelper.WriteAll("TestFiles\\one.obj", ""); DependencyTestHelper.WriteAll("TestFiles\\two.obj", ""); 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"), }); 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\\sometempfile2.obj") }); string missing = Path.GetFullPath("TestFiles\\sometempfile2.obj"); CanonicalTrackedOutputFiles compactOutputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog"))); // Save out the compacted read log - our missing dependency will be compacted away // Use an anonymous method to encapsulate the contains check for the tlogs compactOutputs.SaveTlog(delegate (string fullTrackedPath) { // We need to answer the question "should fullTrackedPath be included in the TLog?" return (String.Compare(fullTrackedPath, missing, StringComparison.OrdinalIgnoreCase) != 0); }); // Read the Tlogs back in.. compactOutputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog"))); // Compact the read tlog CanonicalTrackedInputFiles compactInputs = new CanonicalTrackedInputFiles ( DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")), new TaskItem[] { new TaskItem("TestFiles\\one.cpp"), new TaskItem("TestFiles\\two.cpp") }, null, compactOutputs, false, /* no minimal rebuild optimization */ false /* shred composite rooting markers */ ); compactInputs.SaveTlog(); ITaskItem[] outofDate = compactInputs.ComputeSourcesNeedingCompilation(); Assert.Equal(0, outofDate.Length); }
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; }
private void ConstructReadTLog( ITaskItem[] upToDateSources, CanonicalTrackedOutputFiles outputs ) { string readTrackerPath = Path.GetFullPath( TrackerIntermediateDirectory + "\\" + ReadTLogNames[0] ); // Rewrite out read log, with the sources we're *not* compiling right now. TaskItem readTrackerItem = new TaskItem( readTrackerPath ); CanonicalTrackedInputFiles files = new CanonicalTrackedInputFiles(new TaskItem[] { readTrackerItem }, Sources, outputs, false, false); files.RemoveEntriesForSource(Sources); files.SaveTlog(); // Now append onto the read log the sources we're compiling. It'll parse the .d files for each compiled file, so we know the // dependency header files associated with it, these will be recorded in the logfile. using ( StreamWriter writer = new StreamWriter( readTrackerPath, true, Encoding.Unicode ) ) { foreach ( ITaskItem sourceItem in upToDateSources ) { string itemSpec = sourceItem.ItemSpec; string sourcePath = Path.GetFullPath( sourceItem.ItemSpec ).ToUpperInvariant(); string objectFile = Path.GetFullPath( sourceItem.GetMetadata( "ObjectFileName" ) ); string dotDFile = Path.GetFullPath( Path.GetDirectoryName( objectFile ) + "\\" + Path.GetFileNameWithoutExtension( objectFile ) + ".d" ); try { writer.WriteLine("^" + sourcePath); if (File.Exists(dotDFile)) { DepFileParse depFileParse = new DepFileParse(dotDFile); foreach (string dependentFile in depFileParse.DependentFiles) { if (dependentFile != sourcePath) { if (File.Exists(dependentFile) == false) { Log.LogMessage(MessageImportance.High, "File " + sourcePath + " is missing dependent file: " + dependentFile); } writer.WriteLine(dependentFile); } } // Done with this .d file. So delete it try { File.Delete(dotDFile); } finally { } } else if (File.Exists(objectFile)) { Log.LogMessage(MessageImportance.High, "File " + sourcePath + " is missing it's .d file: " + dotDFile); } } catch ( Exception ) { Log.LogError( "Failed processing dependencies in: " + dotDFile ); } } } }
protected virtual void RemoveTaskSpecificOutputs(CanonicalTrackedOutputFiles compactOutputs) { }
// private void BeginUnicodeOutput() // { // this.unicodePipeReadHandle = null; // this.unicodePipeWriteHandle = null; // this.unicodeOutputEnded = null; // if (this.UseUnicodeOutput) // { // NativeMethodsShared.SecurityAttributes lpPipeAttributes = new NativeMethodsShared.SecurityAttributes { // lpSecurityDescriptor = NativeMethodsShared.NullIntPtr, // bInheritHandle = true // }; // if (NativeMethodsShared.CreatePipe(out this.unicodePipeReadHandle, out this.unicodePipeWriteHandle, lpPipeAttributes, 0)) // { // List<string> list = new List<string>(); // if (base.EnvironmentVariables != null) // { // list.AddRange(base.EnvironmentVariables); // } // list.Add("VS_UNICODE_OUTPUT=" + this.unicodePipeWriteHandle.DangerousGetHandle()); // base.EnvironmentVariables = list.ToArray(); // this.unicodeOutputEnded = new AutoResetEvent(false); // ThreadPool.QueueUserWorkItem(new WaitCallback(this.ReadUnicodeOutput)); // } // else // { // base.Log.LogWarningWithCodeFromResources("TrackedVCToolTask.CreateUnicodeOutputPipeFailed", new object[] { this.ToolName }); // } // } // } /*internal*/ protected virtual bool ComputeOutOfDateSources() { if (this.TrackerIntermediateDirectory != null) { string trackerIntermediateDirectory = this.TrackerIntermediateDirectory; } if (this.MinimalRebuildFromTracking || this.TrackFileAccess) { this.AssignDefaultTLogPaths(); } if (this.MinimalRebuildFromTracking && !this.ForcedRebuildRequired()) { CanonicalTrackedOutputFiles outputs = new CanonicalTrackedOutputFiles(this, this.TLogWriteFiles); this.sourceDependencies = new CanonicalTrackedInputFiles(this, this.TLogReadFiles, this.TrackedInputFiles, this.ExcludedInputPaths, outputs, this.UseMinimalRebuildOptimization, this.MaintainCompositeRootingMarkers); ITaskItem[] sourcesOutOfDateThroughTracking = this.SourceDependencies.ComputeSourcesNeedingCompilation(false); List<ITaskItem> sourcesWithChangedCommandLines = this.GenerateSourcesOutOfDateDueToCommandLine(); this.SourcesCompiled = this.MergeOutOfDateSourceLists(sourcesOutOfDateThroughTracking, sourcesWithChangedCommandLines); if (this.SourcesCompiled.Length == 0) { this.SkippedExecution = true; return this.SkippedExecution; } this.SourcesCompiled = this.AssignOutOfDateSources(this.SourcesCompiled); this.SourceDependencies.RemoveEntriesForSource(this.SourcesCompiled); this.SourceDependencies.SaveTlog(); outputs.RemoveEntriesForSource(this.SourcesCompiled); outputs.SaveTlog(); } else { this.SourcesCompiled = this.TrackedInputFiles; if ((this.SourcesCompiled == null) || (this.SourcesCompiled.Length == 0)) { this.SkippedExecution = true; return this.SkippedExecution; } } if (this.TrackFileAccess) { this.RootSource = FileTracker.FormatRootingMarker(this.SourcesCompiled); } this.SkippedExecution = false; return this.SkippedExecution; }
protected virtual void AddTaskSpecificOutputs(ITaskItem[] sources, CanonicalTrackedOutputFiles compactOutputs) { }
public CanonicalTrackedInputFiles(ITask ownerTask, ITaskItem[] tlogFiles, ITaskItem sourceFile, ITaskItem[] excludedInputPaths, CanonicalTrackedOutputFiles outputs, bool useMinimalRebuildOptimization, bool maintainCompositeRootingMarkers) { this.outputNewestTime = DateTime.MinValue; this.outputNewest = ""; this.excludedInputPaths = new HashSet <string>(StringComparer.Ordinal); this.lastWriteTimeCache = new ConcurrentDictionary <string, DateTime>(StringComparer.Ordinal); ITaskItem[] sourceFiles = new ITaskItem[] { sourceFile }; this.InternalConstruct(ownerTask, tlogFiles, sourceFiles, null, excludedInputPaths, outputs, useMinimalRebuildOptimization, maintainCompositeRootingMarkers); }
private void InternalConstruct(ITask ownerTask, ITaskItem[] tlogFiles, ITaskItem[] sourceFiles, ITaskItem[] outputFiles, ITaskItem[] excludedInputPaths, CanonicalTrackedOutputFiles outputs, bool useMinimalRebuildOptimization, bool maintainCompositeRootingMarkers) { if (ownerTask != null) { this.Log = new TaskLoggingHelper(ownerTask); this.Log.TaskResources = AssemblyResources.PrimaryResources; this.Log.HelpKeywordPrefix = "MSBuild."; } this.tlogFiles = TrackedDependencies.ExpandWildcards(tlogFiles); this.tlogAvailable = TrackedDependencies.ItemsExist(this.tlogFiles); this.sourceFiles = sourceFiles; this.outputs = outputs; this.outputFiles = outputFiles; this.useMinimalRebuildOptimization = useMinimalRebuildOptimization; this.maintainCompositeRootingMarkers = maintainCompositeRootingMarkers; if (excludedInputPaths != null) { foreach (ITaskItem item in excludedInputPaths) { string str = FileUtilities.EnsureNoTrailingSlash(FileUtilities.NormalizePath(item.ItemSpec)).ToUpperInvariant(); this.excludedInputPaths.Add(str); } } this.dependencyTable = new Dictionary <string, Dictionary <string, string> >(StringComparer.OrdinalIgnoreCase); if (this.tlogFiles != null) { this.ConstructDependencyTable(); } }
public void ExcludeSpecificDirectory() { Console.WriteLine("Test: ExcludeSpecificDirectory"); DependencyTestHelper.WriteAll("TestFiles\\one1.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); Directory.CreateDirectory("TestFiles\\Foo"); DependencyTestHelper.WriteAll("TestFiles\\Foo\\one2.h", ""); 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").ToUpperInvariant(), Path.GetFullPath("TestFiles\\one1.h").ToUpperInvariant(), Path.GetFullPath("TestFiles\\Foo\\one2.h").ToUpperInvariant(), Path.GetFullPath("TestFiles\\one3.h").ToUpperInvariant(), "^" + Path.GetFullPath("TestFiles\\two.cpp").ToUpperInvariant(), Path.GetFullPath("TestFiles\\one1.h").ToUpperInvariant(), Path.GetFullPath("TestFiles\\Foo\\one2.h").ToUpperInvariant(), Path.GetFullPath("TestFiles\\one3.h").ToUpperInvariant(), "^" + Path.GetFullPath("TestFiles\\three.cpp").ToUpperInvariant(), Path.GetFullPath("TestFiles\\one1.h").ToUpperInvariant(), Path.GetFullPath("TestFiles\\Foo\\one2.h").ToUpperInvariant(), Path.GetFullPath("TestFiles\\one3.h").ToUpperInvariant(), }); // 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").ToUpperInvariant(), Path.GetFullPath("TestFiles\\one.obj").ToUpperInvariant(), "^" + Path.GetFullPath("TestFiles\\two.cpp").ToUpperInvariant(), Path.GetFullPath("TestFiles\\two.obj").ToUpperInvariant(), "^" + Path.GetFullPath("TestFiles\\three.cpp").ToUpperInvariant(), Path.GetFullPath("TestFiles\\three.obj").ToUpperInvariant(), }); // Represent our tracked and computed outputs CanonicalTrackedOutputFiles outputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog"))); // Represent our tracked and provided inputs CanonicalTrackedInputFiles d = new CanonicalTrackedInputFiles ( DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")), sources, new TaskItem[] { new TaskItem(Path.GetFullPath("TeSTfiles\\Foo")) }, outputs, true, /* minimal rebuild optimization */ false /* shred composite rooting markers */ ); // All things should be up to date ITaskItem[] outofdate = d.ComputeSourcesNeedingCompilation(); Assert.Equal(0, 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; }
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"); }
protected virtual void OutputReadTLog(ITaskItem[] compiledSources, CanonicalTrackedOutputFiles outputs) { string trackerPath = Path.GetFullPath(TlogDirectory + ReadTLogFilenames[0]); using (var writer = new StreamWriter(trackerPath, false, Encoding.Unicode)) { string sourcePath = ""; foreach (ITaskItem source in Sources) { if (sourcePath != "") sourcePath += "|"; sourcePath += Path.GetFullPath(source.ItemSpec).ToUpperInvariant(); } writer.WriteLine("^" + sourcePath); foreach (ITaskItem source in Sources) { writer.WriteLine(Path.GetFullPath(source.ItemSpec).ToUpperInvariant()); } writer.WriteLine(Path.GetFullPath(OutputFile).ToUpperInvariant()); } }
public void OutputMultipleCanonicalCLSubrootMisMatch() { Console.WriteLine("Test: OutputMultipleCanonicalCLSubrootMisMatch"); // sources is NOT a subset of source ITaskItem[] sources = new TaskItem[] { new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\two.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\three.cpp"))}; ITaskItem[] sources2 = new TaskItem[] { new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\two.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\four.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\five.cpp"))}; ITaskItem[] sources2Match = new TaskItem[] { new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\four.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\two.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\five.cpp"))}; ITaskItem[] sourcesPlusOne = new TaskItem[] { new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\two.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\eight.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\three.cpp"))}; // Do note sources2Match and source2 is missing three.cpp. It is to test if the RootContainsAllSubRootComponents can handle the case. // Prepare files Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register File.WriteAllLines("TestFiles\\one.tlog", new string[] { "#Command some-command", "^" + FileTracker.FormatRootingMarker(sources), Path.GetFullPath("TestFiles\\oNe.obj"), Path.GetFullPath("TestFiles\\two.obj"), Path.GetFullPath("TestFiles\\three.obj"), "^" + FileTracker.FormatRootingMarker(sources2), Path.GetFullPath("TestFiles\\fOUr.obj"), Path.GetFullPath("TestFiles\\fIve.obj"), Path.GetFullPath("TestFiles\\sIx.obj"), Path.GetFullPath("TestFiles\\sEvEn.obj"), Path.GetFullPath("TestFiles\\EIght.obj"), }); CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.tlog"))); ITaskItem[] outputs = d.OutputsForSource(sources2Match, /*searchForSubRootsInCompositeRootingMarkers*/ false); Assert.Equal(5, outputs.Length); Assert.Equal(outputs[0].ItemSpec, Path.GetFullPath("TestFiles\\fOUr.obj")); Assert.Equal(outputs[1].ItemSpec, Path.GetFullPath("TestFiles\\fIve.obj")); Assert.Equal(outputs[2].ItemSpec, Path.GetFullPath("TestFiles\\sIx.obj")); Assert.Equal(outputs[3].ItemSpec, Path.GetFullPath("TestFiles\\sEvEn.obj")); Assert.Equal(outputs[4].ItemSpec, Path.GetFullPath("TestFiles\\EIght.obj")); ITaskItem[] outputs2 = d.OutputsForSource(sources2Match, /*searchForSubRootsInCompositeRootingMarkers*/ true); Assert.Equal(5, outputs2.Length); Assert.Equal(outputs2[0].ItemSpec, Path.GetFullPath("TestFiles\\fOUr.obj")); Assert.Equal(outputs2[1].ItemSpec, Path.GetFullPath("TestFiles\\fIve.obj")); Assert.Equal(outputs2[2].ItemSpec, Path.GetFullPath("TestFiles\\sIx.obj")); Assert.Equal(outputs2[3].ItemSpec, Path.GetFullPath("TestFiles\\sEvEn.obj")); Assert.Equal(outputs2[4].ItemSpec, Path.GetFullPath("TestFiles\\EIght.obj")); ITaskItem[] outputs3 = d.OutputsForSource(sourcesPlusOne, /*searchForSubRootsInCompositeRootingMarkers*/ true); Assert.Equal(3, outputs3.Length); Assert.Equal(outputs3[0].ItemSpec, Path.GetFullPath("TestFiles\\oNe.obj")); Assert.Equal(outputs3[1].ItemSpec, Path.GetFullPath("TestFiles\\two.obj")); Assert.Equal(outputs3[2].ItemSpec, Path.GetFullPath("TestFiles\\three.obj")); ITaskItem[] outputs4 = d.OutputsForSource(sourcesPlusOne, /*searchForSubRootsInCompositeRootingMarkers*/ false); Assert.Equal(0, outputs4.Length); }
protected void CalcSourcesToBuild() { //check if full recompile is required otherwise perform incremental if (ForcedRebuildRequired() || MinimalRebuildFromTracking == false) { CompileSourceList = Sources; return; } //retrieve list of sources out of date due to command line changes List<ITaskItem> outOfDateSourcesFromCommandLine = GetOutOfDateSourcesFromCmdLineChanges(); //retrieve sources out of date due to tracking CanonicalTrackedOutputFiles outputs = new CanonicalTrackedOutputFiles(this, TLogWriteFiles); TrackedInputFiles = new CanonicalTrackedInputFiles(this, TLogReadFiles, Sources, ExcludedInputPaths, outputs, true, false); ITaskItem[] outOfDateSourcesFromTracking = TrackedInputFiles.ComputeSourcesNeedingCompilation(); //merge out of date lists CompileSourceList = MergeOutOfDateSources(outOfDateSourcesFromTracking, outOfDateSourcesFromCommandLine); if (CompileSourceList.Length == 0) { SkippedExecution = true; return; } //remove sources to compile from tracked file list TrackedInputFiles.RemoveEntriesForSource(CompileSourceList); outputs.RemoveEntriesForSource(CompileSourceList); TrackedInputFiles.SaveTlog(); outputs.SaveTlog(); }
public void OutputNonExistentTlog() { Console.WriteLine("Test: NonExistentTlog"); // Just to be sure, delete the test tlog. File.Delete("TestFiles\\one.tlog"); CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.tlog"))); ITaskItem[] outputs = d.OutputsForSource(new TaskItem(Path.GetFullPath("TestFiles\\one.cpp"))); Assert.Null(outputs); }
public void OutputMultipleCanonicalCLSubrootMatch() { Console.WriteLine("Test: OutputMultipleCanonicalCLSubrootMatch"); // sources is a subset of source2 ITaskItem[] sources = new TaskItem[] { new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\two.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\three.cpp"))}; ITaskItem[] sources2 = new TaskItem[] { new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\two.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\three.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\four.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\five.cpp"))}; // Prepare files Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register File.WriteAllLines("TestFiles\\one.tlog", new string[] { "#Command some-command", "^" + FileTracker.FormatRootingMarker(sources), Path.GetFullPath("TestFiles\\oNe.obj"), Path.GetFullPath("TestFiles\\two.obj"), Path.GetFullPath("TestFiles\\three.obj"), "^" + FileTracker.FormatRootingMarker(sources2), Path.GetFullPath("TestFiles\\fOUr.obj"), Path.GetFullPath("TestFiles\\fIve.obj"), Path.GetFullPath("TestFiles\\sIx.obj"), Path.GetFullPath("TestFiles\\sEvEn.obj"), Path.GetFullPath("TestFiles\\EIght.obj"), }); CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.tlog"))); ITaskItem[] outputs = d.OutputsForSource(sources2, /*searchForSubRootsInCompositeRootingMarkers*/ false); Assert.IsTrue(outputs.Length == 5); Assert.IsTrue(outputs[0].ItemSpec == Path.GetFullPath("TestFiles\\fOUr.obj")); Assert.IsTrue(outputs[1].ItemSpec == Path.GetFullPath("TestFiles\\fIve.obj")); Assert.IsTrue(outputs[2].ItemSpec == Path.GetFullPath("TestFiles\\sIx.obj")); Assert.IsTrue(outputs[3].ItemSpec == Path.GetFullPath("TestFiles\\sEvEn.obj")); Assert.IsTrue(outputs[4].ItemSpec == Path.GetFullPath("TestFiles\\EIght.obj")); ITaskItem[] outputs2 = d.OutputsForSource(sources2, /*searchForSubRootsInCompositeRootingMarkers*/ true); Assert.IsTrue(outputs2.Length == 8); Assert.IsTrue(outputs2[0].ItemSpec == Path.GetFullPath("TestFiles\\oNe.obj")); Assert.IsTrue(outputs2[1].ItemSpec == Path.GetFullPath("TestFiles\\two.obj")); Assert.IsTrue(outputs2[2].ItemSpec == Path.GetFullPath("TestFiles\\three.obj")); Assert.IsTrue(outputs2[3].ItemSpec == Path.GetFullPath("TestFiles\\fOUr.obj")); Assert.IsTrue(outputs2[4].ItemSpec == Path.GetFullPath("TestFiles\\fIve.obj")); Assert.IsTrue(outputs2[5].ItemSpec == Path.GetFullPath("TestFiles\\sIx.obj")); Assert.IsTrue(outputs2[6].ItemSpec == Path.GetFullPath("TestFiles\\sEvEn.obj")); Assert.IsTrue(outputs2[7].ItemSpec == Path.GetFullPath("TestFiles\\EIght.obj")); // Test if sources can find the superset. ITaskItem[] outputs3 = d.OutputsForSource(sources, /*searchForSubRootsInCompositeRootingMarkers*/ true); Assert.IsTrue(outputs3.Length == 8); Assert.IsTrue(outputs3[0].ItemSpec == Path.GetFullPath("TestFiles\\oNe.obj")); Assert.IsTrue(outputs3[1].ItemSpec == Path.GetFullPath("TestFiles\\two.obj")); Assert.IsTrue(outputs3[2].ItemSpec == Path.GetFullPath("TestFiles\\three.obj")); Assert.IsTrue(outputs3[3].ItemSpec == Path.GetFullPath("TestFiles\\fOUr.obj")); Assert.IsTrue(outputs3[4].ItemSpec == Path.GetFullPath("TestFiles\\fIve.obj")); Assert.IsTrue(outputs3[5].ItemSpec == Path.GetFullPath("TestFiles\\sIx.obj")); Assert.IsTrue(outputs3[6].ItemSpec == Path.GetFullPath("TestFiles\\sEvEn.obj")); Assert.IsTrue(outputs3[7].ItemSpec == Path.GetFullPath("TestFiles\\EIght.obj")); ITaskItem[] outputs4 = d.OutputsForSource(sources, /*searchForSubRootsInCompositeRootingMarkers*/ false); Assert.IsTrue(outputs4.Length == 3); Assert.IsTrue(outputs4[0].ItemSpec == Path.GetFullPath("TestFiles\\oNe.obj")); Assert.IsTrue(outputs4[1].ItemSpec == Path.GetFullPath("TestFiles\\two.obj")); Assert.IsTrue(outputs4[2].ItemSpec == Path.GetFullPath("TestFiles\\three.obj")); }
public void RemoveDependencyFromEntry() { Console.WriteLine("Test: RemoveDependencyFromEntry"); // Prepare files DependencyTestHelper.WriteAll("TestFiles\\one1.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one2.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one3.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one.cpp", ""); DependencyTestHelper.WriteAll("TestFiles\\one.obj", ""); DependencyTestHelper.WriteAll("TestFiles\\one.tlh", ""); DependencyTestHelper.WriteAll("TestFiles\\one.tli", ""); 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\\one3.obj"), Path.GetFullPath("TestFiles\\one3.tlh"), Path.GetFullPath("TestFiles\\one3.tli"), }); File.WriteAllLines("TestFiles\\one.write.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\\one3.obj"), Path.GetFullPath("TestFiles\\one3.tlh"), Path.GetFullPath("TestFiles\\one3.tli"), }); CanonicalTrackedOutputFiles compactOutputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog"))); compactOutputs.RemoveDependencyFromEntry(new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\one3.obj"))); compactOutputs.SaveTlog(); CanonicalTrackedOutputFiles writtenOutputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog"))); Assert.False(writtenOutputs.DependencyTable[Path.GetFullPath("TestFiles\\one.cpp")].ContainsKey(Path.GetFullPath("TestFiles\\one3.obj"))); CanonicalTrackedInputFiles compactInputs = new CanonicalTrackedInputFiles ( DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")), DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.cpp")), null, compactOutputs, false, /* no minimal rebuild optimization */ false /* shred composite rooting markers */ ); compactInputs.RemoveDependencyFromEntry(new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\one3.obj"))); compactInputs.SaveTlog(); CanonicalTrackedInputFiles writtenInputs = new CanonicalTrackedInputFiles ( DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")), DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.cpp")), null, writtenOutputs, false, /* no minimal rebuild optimization */ false /* shred composite rooting markers */ ); Assert.False(writtenInputs.DependencyTable[Path.GetFullPath("TestFiles\\one.cpp")].ContainsKey(Path.GetFullPath("TestFiles\\one3.obj"))); }
public void OutputMultipleSingleSubRootCanonicalCL() { Console.WriteLine("Test: OutputMultipleSingleSubRootCanonicalCL"); ITaskItem[] sources = new TaskItem[] { new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\two.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\three.cpp"))}; // Prepare files Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register File.WriteAllLines("TestFiles\\one.tlog", new string[] { "#Command some-command", "^" + FileTracker.FormatRootingMarker(sources), Path.GetFullPath("TestFiles\\oNe.obj"), Path.GetFullPath("TestFiles\\two.obj"), Path.GetFullPath("TestFiles\\three.obj"), }); CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.tlog"))); ITaskItem[] outputs = d.OutputsForSource(new TaskItem(Path.GetFullPath("TestFiles\\two.cpp"))); Assert.IsTrue(outputs.Length == 3); Assert.IsTrue(outputs[0].ItemSpec == Path.GetFullPath("TestFiles\\oNe.obj")); Assert.IsTrue(outputs[1].ItemSpec == Path.GetFullPath("TestFiles\\two.obj")); Assert.IsTrue(outputs[2].ItemSpec == Path.GetFullPath("TestFiles\\three.obj")); }
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); }
public void WriteTLogWithEmptyLineBetweenRoots() { Console.WriteLine("Test: WriteTLogWithEmptyLineImmediatelyAfterRoot"); // Prepare files File.WriteAllLines("TestFiles\\one.write.tlog", new string[] { "^FOO", "FOO", "", "^BAR", "BAR" }); MockTask task = DependencyTestHelper.MockTask; CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles ( task, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog")) ); Assert.AreEqual(1, ((task as ITask).BuildEngine as MockEngine).Warnings, "Should have a warning."); Assert.AreEqual(0, d.DependencyTable.Count, "DependencyTable should be empty."); }
public void SaveCompactedWriteTlog() { Console.WriteLine("Test: SaveCompactedWriteTlog"); TaskItem fooItem = new TaskItem("foo"); ITaskItem[] sources = new TaskItem[] { new TaskItem(Path.GetFullPath("TestFiles\\one.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\two.cpp")), new TaskItem(Path.GetFullPath("TestFiles\\three.cpp"))}; string rootMarker = FileTracker.FormatRootingMarker(sources); // Prepare files Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register File.WriteAllLines("TestFiles\\one.tlog", new string[] { "#Command some-command", "^" + rootMarker, Path.GetFullPath("TestFiles\\oNe.obj"), "^" + fooItem.GetMetadata("Fullpath"), Path.GetFullPath("TestFiles\\foo1.bar"), Path.GetFullPath("TestFiles\\bar1.baz"), }); File.WriteAllLines("TestFiles\\two.tlog", new string[] { "#Command some-command", "^" + rootMarker, Path.GetFullPath("TestFiles\\two.obj"), Path.GetFullPath("TestFiles\\three.obj"), "^" + fooItem.GetMetadata("Fullpath"), Path.GetFullPath("TestFiles\\foo2.bar"), Path.GetFullPath("TestFiles\\bar2.baz"), }); ITaskItem[] tlogs = { new TaskItem("TestFiles\\one.tlog"), new TaskItem("TestFiles\\two.tlog") }; Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, tlogs); ITaskItem[] outputs = d.OutputsForSource(sources); Assert.Equal(3, outputs.Length); Assert.Equal(outputs[0].ItemSpec, Path.GetFullPath("TestFiles\\oNe.obj")); Assert.Equal(outputs[1].ItemSpec, Path.GetFullPath("TestFiles\\two.obj")); Assert.Equal(outputs[2].ItemSpec, Path.GetFullPath("TestFiles\\three.obj")); outputs = d.OutputsForSource(fooItem); Assert.Equal(4, outputs.Length); Assert.Equal(outputs[0].ItemSpec, Path.GetFullPath("TestFiles\\foo1.bar")); Assert.Equal(outputs[1].ItemSpec, Path.GetFullPath("TestFiles\\bar1.baz")); Assert.Equal(outputs[2].ItemSpec, Path.GetFullPath("TestFiles\\foo2.bar")); Assert.Equal(outputs[3].ItemSpec, Path.GetFullPath("TestFiles\\bar2.baz")); // Compact the tlog removing all entries for "foo" leaving the other entries intact d.RemoveEntriesForSource(fooItem); d.SaveTlog(); // All the tlogs need to still be there even after compaction // It's OK for them to be empty, but their absence might mean a partial clean // A missing tlog would mean a clean build Assert.True(Microsoft.Build.Utilities.TrackedDependencies.ItemsExist(tlogs)); // All log information should now be in the tlog[0] ITaskItem[] tlogs2 = { tlogs[0] }; CanonicalTrackedOutputFiles d2 = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, tlogs2); outputs = d2.OutputsForSource(fooItem); Assert.Equal(0, outputs.Length); outputs = d2.OutputsForSource(sources); Assert.Equal(3, outputs.Length); Assert.Equal(outputs[0].ItemSpec, Path.GetFullPath("TestFiles\\oNe.obj")); Assert.Equal(outputs[1].ItemSpec, Path.GetFullPath("TestFiles\\two.obj")); Assert.Equal(outputs[2].ItemSpec, Path.GetFullPath("TestFiles\\three.obj")); // There should be no difference even if we send in all the original tlogs CanonicalTrackedOutputFiles d3 = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, tlogs); outputs = d3.OutputsForSource(fooItem); Assert.Equal(0, outputs.Length); outputs = d3.OutputsForSource(sources); Assert.Equal(3, outputs.Length); Assert.Equal(outputs[0].ItemSpec, Path.GetFullPath("TestFiles\\oNe.obj")); Assert.Equal(outputs[1].ItemSpec, Path.GetFullPath("TestFiles\\two.obj")); Assert.Equal(outputs[2].ItemSpec, Path.GetFullPath("TestFiles\\three.obj")); }
public void MultipleCanonicalCLCompactMissingOnSuccess() { Console.WriteLine("Test: MultipleCanonicalCLCompactMissingOnSuccess"); // Prepare files DependencyTestHelper.WriteAll("TestFiles\\one1.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one2.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one3.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one.cpp", ""); DependencyTestHelper.WriteAll("TestFiles\\one.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"), }); File.WriteAllLines("TestFiles\\one.write.tlog", new string[] { "#Command some-command", "^" + Path.GetFullPath("TestFiles\\one.cpp"), Path.GetFullPath("TestFiles\\one.obj"), Path.GetFullPath("TestFiles\\sometempfile.obj") }); CanonicalTrackedOutputFiles compactOutputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog"))); compactOutputs.RemoveDependenciesFromEntryIfMissing(new TaskItem(Path.GetFullPath("TestFiles\\one.cpp"))); compactOutputs.SaveTlog(); // Compact the read tlog CanonicalTrackedInputFiles compactInputs = new CanonicalTrackedInputFiles ( DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")), DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.cpp")), null, compactOutputs, false, /* no minimal rebuild optimization */ false /* shred composite rooting markers */ ); compactInputs.RemoveDependenciesFromEntryIfMissing(new TaskItem(Path.GetFullPath("TestFiles\\one.cpp"))); compactInputs.SaveTlog(); CanonicalTrackedOutputFiles outputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog"))); CanonicalTrackedInputFiles d = new CanonicalTrackedInputFiles ( DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")), DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.cpp")), null, outputs, false, /* no minimal rebuild optimization */ false /* shred composite rooting markers */ ); ITaskItem[] outofdate = d.ComputeSourcesNeedingCompilation(); Assert.Equal(0, outofdate.Length); }
public void InvalidWriteTLogName() { Console.WriteLine("Test: InvalidWriteTLogName"); MockTask task = DependencyTestHelper.MockTask; CanonicalTrackedOutputFiles d = new CanonicalTrackedOutputFiles ( task, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\|one|.write.tlog")) ); Assert.Equal(1, ((task as ITask).BuildEngine as MockEngine).Warnings); // "Should have an error." Assert.Equal(0, d.DependencyTable.Count); // "DependencyTable should be empty." }
public void MultipleCanonicalCLCompactMissingOnSuccessMultiEntry() { Console.WriteLine("Test: MultipleCanonicalCLCompactMissingOnSuccessMultiEntry"); // Prepare files DependencyTestHelper.WriteAll("TestFiles\\one1.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one2.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one3.h", ""); DependencyTestHelper.WriteAll("TestFiles\\one.cpp", ""); DependencyTestHelper.WriteAll("TestFiles\\one.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\\two1.h"), Path.GetFullPath("TestFiles\\two2.h"), }); File.WriteAllLines("TestFiles\\one.write.tlog", new string[] { "#Command some-command", "^" + Path.GetFullPath("TestFiles\\one.cpp"), Path.GetFullPath("TestFiles\\one.obj"), Path.GetFullPath("TestFiles\\sometempfile.obj"), "^" + Path.GetFullPath("TestFiles\\two.cpp"), Path.GetFullPath("TestFiles\\two.obj"), Path.GetFullPath("TestFiles\\sometempfile2.obj") }); CanonicalTrackedOutputFiles compactOutputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog"))); compactOutputs.RemoveDependenciesFromEntryIfMissing(new TaskItem(Path.GetFullPath("TestFiles\\one.cpp"))); compactOutputs.SaveTlog(); // Compact the read tlog CanonicalTrackedInputFiles compactInputs = new CanonicalTrackedInputFiles ( DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")), DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.cpp")), null, compactOutputs, false, /* no minimal rebuild optimization */ false /* shred composite rooting markers */ ); compactInputs.RemoveDependenciesFromEntryIfMissing(new TaskItem(Path.GetFullPath("TestFiles\\one.cpp"))); compactInputs.SaveTlog(); CanonicalTrackedOutputFiles writtenOutputs = new CanonicalTrackedOutputFiles(DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.write.tlog"))); CanonicalTrackedInputFiles writtenInputs = new CanonicalTrackedInputFiles ( DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.read.tlog")), DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.cpp")), null, writtenOutputs, false, /* no minimal rebuild optimization */ false /* shred composite rooting markers */ ); Assert.Equal(1, writtenOutputs.DependencyTable[Path.GetFullPath("TestFiles\\one.cpp")].Count); Assert.Equal(4, writtenInputs.DependencyTable[Path.GetFullPath("TestFiles\\one.cpp")].Count); // Everything to do with two.cpp should be left intact Assert.Equal(2, writtenOutputs.DependencyTable[Path.GetFullPath("TestFiles\\two.cpp")].Count); Assert.Equal(3, writtenInputs.DependencyTable[Path.GetFullPath("TestFiles\\two.cpp")].Count); }