public void MultipleCanonicalCLMissingDependency() { Console.WriteLine("Test: MultipleCanonicalCLMissingDependency"); // 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.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"), }); // Delete one of our dependencies string missing = Path.GetFullPath("TestFiles\\one2.h"); File.Delete(missing); CanonicalTrackedInputFiles d = new CanonicalTrackedInputFiles ( DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.tlog")), DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.cpp")), null, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.obj")), false, /* no minimal rebuild optimization */ false /* shred composite rooting markers */ ); // We're out of date, since a missing dependency indicates out-of-dateness ITaskItem[] outofdate = d.ComputeSourcesNeedingCompilation(); Assert.Equal(1, outofdate.Length); // The dependency has been recorded and retrieved correctly Assert.True(d.DependencyTable[Path.GetFullPath("TestFiles\\one.cpp")].ContainsKey(missing)); // Save out the compacted read log - our missing dependency will be compacted away // The tlog will have to entries compacted, since we're not up to date d.RemoveEntriesForSource(d.SourcesNeedingCompilation); d.SaveTlog(); // read the tlog back in again d = new CanonicalTrackedInputFiles ( DependencyTestHelper.MockTask, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.tlog")), DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.cpp")), null, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.obj")), false, /* no minimal rebuild optimization */ false /* shred composite rooting markers */ ); // We're out of date, since a missing dependency indicates out-of-dateness outofdate = d.ComputeSourcesNeedingCompilation(); Assert.Equal(1, outofdate.Length); // We have a source outstanding for recompilation, it will not appear in // the tracking information as it will be written again Assert.False(d.DependencyTable.ContainsKey(Path.GetFullPath("TestFiles\\one.cpp"))); }
public void SaveCompactedReadTlog() { Console.WriteLine("Test: SaveCompactedReadTlog"); // 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\\two1.h", ""); DependencyTestHelper.WriteAll("TestFiles\\two2.h", ""); DependencyTestHelper.WriteAll("TestFiles\\two3.h", ""); DependencyTestHelper.WriteAll("TestFiles\\two.cpp", ""); DependencyTestHelper.WriteAll("TestFiles\\two.obj", ""); Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register File.WriteAllLines("TestFiles\\one1.tlog", new string[] { "#Command some-command", "^" + Path.GetFullPath("TestFiles\\one.cpp"), Path.GetFullPath("TestFiles\\one1.h"), }); File.WriteAllLines("TestFiles\\one2.tlog", new string[] { "#Command some-command1", "^" + Path.GetFullPath("TestFiles\\one.cpp"), Path.GetFullPath("TestFiles\\one2.h"), Path.GetFullPath("TestFiles\\one3.h"), }); File.WriteAllLines("TestFiles\\two1.tlog", new string[] { "#Command some-command2", "^" + Path.GetFullPath("TestFiles\\two.cpp"), Path.GetFullPath("TestFiles\\two2.h"), Path.GetFullPath("TestFiles\\two3.h"), }); // Touch one Thread.Sleep(sleepTimeMilliseconds); // need to wait since the timestamp check needs some time to register DependencyTestHelper.WriteAll("TestFiles\\one2.h", ""); ITaskItem[] tlogs = { new TaskItem("TestFiles\\one1.tlog"), new TaskItem("TestFiles\\one2.tlog"), new TaskItem("TestFiles\\two1.tlog") }; CanonicalTrackedInputFiles d = new CanonicalTrackedInputFiles ( DependencyTestHelper.MockTask, tlogs, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.cpp")), null, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.obj")), false, /* no minimal rebuild optimization */ false /* shred composite rooting markers */ ); ITaskItem[] outofdate = d.ComputeSourcesNeedingCompilation(); Assert.Equal(1, outofdate.Length); Assert.Equal(outofdate[0].ItemSpec, "TestFiles\\one.cpp"); d.RemoveEntriesForSource(d.SourcesNeedingCompilation); 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)); // There should be no difference in the out of date files after compaction CanonicalTrackedInputFiles d1 = new CanonicalTrackedInputFiles ( DependencyTestHelper.MockTask, tlogs, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.cpp")), null, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\one.obj")), false, /* no minimal rebuild optimization */ false /* shred composite rooting markers */ ); outofdate = d1.ComputeSourcesNeedingCompilation(); Assert.Equal(1, outofdate.Length); Assert.Equal(outofdate[0].ItemSpec, "TestFiles\\one.cpp"); ITaskItem[] tlogs2 = { tlogs[0] }; // All log information should now be in the tlog[0] CanonicalTrackedInputFiles d2 = new CanonicalTrackedInputFiles ( DependencyTestHelper.MockTask, tlogs2, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\two.cpp")), null, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\two.obj")), false, /* no minimal rebuild optimization */ false /* shred composite rooting markers */ ); outofdate = d2.ComputeSourcesNeedingCompilation(); Assert.Equal(0, outofdate.Length); Assert.Equal(1, d2.DependencyTable.Count); Assert.False(d2.DependencyTable.ContainsKey(Path.GetFullPath("TestFiles\\one.cpp"))); // There should be no difference even if we send in all the original tlogs CanonicalTrackedInputFiles d3 = new CanonicalTrackedInputFiles ( DependencyTestHelper.MockTask, tlogs, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\two.cpp")), null, DependencyTestHelper.ItemArray(new TaskItem("TestFiles\\two.obj")), false, /* no minimal rebuild optimization */ false /* shred composite rooting markers */ ); outofdate = d3.ComputeSourcesNeedingCompilation(); Assert.Equal(0, outofdate.Length); Assert.Equal(1, d3.DependencyTable.Count); Assert.False(d3.DependencyTable.ContainsKey(Path.GetFullPath("TestFiles\\one.cpp"))); }
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 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(); }
protected override void OutputReadTLog(ITaskItem[] compiledSources, CanonicalTrackedOutputFiles outputs) { string trackerPath = Path.GetFullPath(TlogDirectory + ReadTLogFilenames[0]); //save tlog for sources not compiled during this execution TaskItem readTrackerItem = new TaskItem(trackerPath); CanonicalTrackedInputFiles files = new CanonicalTrackedInputFiles(new TaskItem[] { readTrackerItem }, Sources, outputs, false, false); files.RemoveEntriesForSource(compiledSources); files.SaveTlog(); //add tlog information for compiled sources using (StreamWriter writer = new StreamWriter(trackerPath, true, Encoding.Unicode)) { foreach (ITaskItem source in compiledSources) { string sourcePath = Path.GetFullPath(source.ItemSpec).ToUpperInvariant(); string objectFilePath = GetObjectFile(source); string depFilePath = Path.ChangeExtension(objectFilePath, ".d"); try { if (File.Exists(depFilePath) == false) { Log.LogMessage(MessageImportance.High, depFilePath + " not found"); } else { writer.WriteLine("^" + sourcePath); DependencyParser parser = new DependencyParser(depFilePath); foreach (string filename in parser.Dependencies) { //source itself not required if (filename == sourcePath) continue; if (File.Exists(filename) == false) { Log.LogMessage(MessageImportance.High, "File " + sourcePath + " is missing dependency " + filename); } string fname = filename.ToUpperInvariant(); fname = Path.GetFullPath(fname); writer.WriteLine(fname); } //remove d file try { File.Delete(depFilePath); } finally { } } } catch (Exception) { Log.LogError("Failed to update " + readTrackerItem + " for " + sourcePath); } } } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// protected override bool Setup () { bool result = base.Setup (); OutOfDateSources = Sources; if (result && !SkippedExecution) { // // Retrieve list of sources considered out-of-date due to either command line changes or tracker flagging. // TODO: Switch use of CanonicalTracked* helpers to TrackedFileManager. // CanonicalTrackedOutputFiles trackedOutputFiles = new CanonicalTrackedOutputFiles (this, TLogWriteFiles); TrackedInputFiles = new CanonicalTrackedInputFiles (this, TLogReadFiles, Sources, ExcludedInputPaths, trackedOutputFiles, true, false);//true); ITaskItem [] outOfDateSourcesFromTracking = TrackedInputFiles.ComputeSourcesNeedingCompilation ();// (true); ITaskItem [] outOfDateSourcesFromCommandLine = GetOutOfDateSourcesFromCmdLineChanges (Sources); #if DEBUG Log.LogMessageFromText (string.Format ("[{0}] --> No. out-of-date sources (from tracking): {1}", ToolName, outOfDateSourcesFromTracking.Length), MessageImportance.Low); Log.LogMessageFromText (string.Format ("[{0}] --> No. out-of-date sources (command line differs): {1}", ToolName, outOfDateSourcesFromCommandLine.Length), MessageImportance.Low); #endif // // Merge out-of-date lists from both sources and assign these for compilation. // HashSet<ITaskItem> mergedOutOfDateSources = new HashSet<ITaskItem> (outOfDateSourcesFromTracking); foreach (ITaskItem item in outOfDateSourcesFromCommandLine) { if (!mergedOutOfDateSources.Contains (item)) { mergedOutOfDateSources.Add (item); } } OutOfDateSources = new ITaskItem [mergedOutOfDateSources.Count]; mergedOutOfDateSources.CopyTo (OutOfDateSources); if ((OutOfDateSources == null) || (OutOfDateSources.Length == 0)) { SkippedExecution = true; } else { // // Remove sources to compile from tracked file list. // TrackedInputFiles.RemoveEntriesForSource (OutOfDateSources); trackedOutputFiles.RemoveEntriesForSource (OutOfDateSources); TrackedInputFiles.SaveTlog (); trackedOutputFiles.SaveTlog (); } } #if DEBUG Log.LogMessageFromText (string.Format ("[{0}] --> Skipped execution: {1}", ToolName, SkippedExecution), MessageImportance.Low); for (int i = 0; i < OutOfDateSources.Length; ++i) { Log.LogMessageFromText (string.Format ("[{0}] --> Out-of-date Sources: [{1}] {2}", ToolName, i, OutOfDateSources [i].ToString ()), MessageImportance.Low); } #endif return result; }
protected int ExecuteTool2(string pathToTool, string responseFileCommands, string commandLineCommands) { int num = 0; try { num = this.TrackerExecuteTool(pathToTool, responseFileCommands, commandLineCommands); } finally { if (this.MinimalRebuildFromTracking || this.TrackFileAccess) { CanonicalTrackedOutputFiles outputs = new CanonicalTrackedOutputFiles(this.TLogWriteFiles); CanonicalTrackedInputFiles compactInputs = new CanonicalTrackedInputFiles(this.TLogReadFiles, this.TrackedInputFiles, this.ExcludedInputPaths, outputs, false, this.MaintainCompositeRootingMarkers); string[] strArray = null; IDictionary<string, string> sourcesToCommandLines = this.MapSourcesToCommandLines(); if (num != 0) { outputs.RemoveEntriesForSource(this.SourcesCompiled); outputs.SaveTlog(); compactInputs.RemoveEntriesForSource(this.SourcesCompiled); compactInputs.SaveTlog(); if (this.MaintainCompositeRootingMarkers) { sourcesToCommandLines.Remove(FileTracker.FormatRootingMarker(this.SourcesCompiled)); } else { foreach (ITaskItem item in this.SourcesCompiled) { sourcesToCommandLines.Remove(FileTracker.FormatRootingMarker(item)); } } this.WriteSourcesToCommandLinesTable(sourcesToCommandLines); } else { this.AddTaskSpecificOutputs(this.SourcesCompiled, outputs); this.RemoveTaskSpecificOutputs(outputs); outputs.RemoveDependenciesFromEntryIfMissing(this.SourcesCompiled); if (this.MaintainCompositeRootingMarkers) { strArray = outputs.RemoveRootsWithSharedOutputs(this.SourcesCompiled); foreach (string str in strArray) { compactInputs.RemoveEntryForSourceRoot(str); } } if ((this.TrackedOutputFilesToIgnore != null) && (this.TrackedOutputFilesToIgnore.Length > 0)) { Dictionary<string, ITaskItem> trackedOutputFilesToRemove = new Dictionary<string, ITaskItem>(StringComparer.OrdinalIgnoreCase); foreach (ITaskItem item2 in this.TrackedOutputFilesToIgnore) { trackedOutputFilesToRemove.Add(item2.GetMetadata("FullPath"), item2); } outputs.SaveTlog(delegate(string fullTrackedPath) { if (trackedOutputFilesToRemove.ContainsKey(fullTrackedPath)) { return false; } return true; }); } else { outputs.SaveTlog(); } this.RemoveTaskSpecificInputs(compactInputs); compactInputs.RemoveDependenciesFromEntryIfMissing(this.SourcesCompiled); if ((this.TrackedInputFilesToIgnore != null) && (this.TrackedInputFilesToIgnore.Length > 0)) { Dictionary<string, ITaskItem> trackedInputFilesToRemove = new Dictionary<string, ITaskItem>(StringComparer.OrdinalIgnoreCase); foreach (ITaskItem item3 in this.TrackedInputFilesToIgnore) { trackedInputFilesToRemove.Add(item3.GetMetadata("FullPath"), item3); } compactInputs.SaveTlog(delegate(string fullTrackedPath) { if (trackedInputFilesToRemove.ContainsKey(fullTrackedPath)) { return false; } return true; }); } else { compactInputs.SaveTlog(); } if (this.MaintainCompositeRootingMarkers) { string str2 = GenerateCommandLine(); sourcesToCommandLines[FileTracker.FormatRootingMarker(this.SourcesCompiled)] = str2; if (strArray != null) { foreach (string str3 in strArray) { sourcesToCommandLines.Remove(str3); } } } else { string str4 = this.SourcesPropertyName ?? "Sources"; string str5 = GenerateCommandLineExceptSwitches(new string[] { str4 }); foreach (ITaskItem item4 in this.SourcesCompiled) { sourcesToCommandLines[FileTracker.FormatRootingMarker(item4)] = str5 + " " + item4.GetMetadata("FullPath").ToUpperInvariant(); } } this.WriteSourcesToCommandLinesTable(sourcesToCommandLines); } } } return num; }
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 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" ); string pchOutputH = Path.GetFullPath( sourceItem.GetMetadata( "PrecompiledHeaderOutputFile" ) ); string pchOutputGCH = pchOutputH + ".gch"; string pchSetting = sourceItem.GetMetadata( "PrecompiledHeader" ).ToLowerInvariant(); try { List<string> dependencies = new List<string>(); dependencies.Add( "^" + sourcePath ); // don't add an entry if the object file wasn't built if (!File.Exists(objectFile)) continue; if (!File.Exists(dotDFile)) { throw new Exception( "File " + sourcePath + " is missing it's .d file: " + dotDFile ); } DepFileParse depFileParse = new DepFileParse(dotDFile); foreach (string dependentFile in depFileParse.DependentFiles) { if (dependentFile != sourcePath) { if (File.Exists(dependentFile) == false) { throw new Exception( "File " + sourcePath + " is missing dependent file: " + dependentFile ); } dependencies.Add( dependentFile ); } } if ( pchSetting == "use" ) { dependencies.Add( pchOutputH.ToUpperInvariant() ); dependencies.Add( pchOutputGCH.ToUpperInvariant() ); } // Done with this .d file. So delete it try { File.Delete(dotDFile); } finally { } // Finally write out the file and its dependencies, must ensure success before doing this foreach( var dep in dependencies ) { writer.WriteLine( dep ); } } catch ( Exception ) { Log.LogError( "Failed processing dependencies in: " + dotDFile ); } } } }
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(); }