private GraphReuseResult(PipGraph pipGraph, EngineSchedule engineSchedule, InputTracker.InputChanges inputChanges) { m_pipGraph = pipGraph; m_engineSchedule = engineSchedule; InputChanges = inputChanges; // Calling invariant method explicitely because this is the only way to check it at least once. Invariant(); }
/// <nodoc /> public XlgDebuggerState(DebugLogsAnalyzer analyzer) : base(XlgThreadId) { Analyzer = analyzer; var logFile = Path.Combine(Path.GetDirectoryName(Analyzer.Input.ExecutionLogPath), "BuildXL.status.csv"); StackTrace = new[] { new DisplayStackTraceEntry(file: logFile, line: 1, position: 1, functionName: "<main>", entry: null) }; PipsByType = Enum .GetValues(typeof(PipType)) .Cast <PipType>() .Except(new[] { PipType.Max }) .Aggregate(new ObjectInfoBuilder(), (obi, pipType) => obi.Prop(pipType.ToString(), () => PipGraph.RetrievePipReferencesOfType(pipType).ToArray())) .Build(); PipsByStatus = Enum .GetValues(typeof(PipExecutionLevel)) .Cast <PipExecutionLevel>() .Select(level => level.ToString()) .Concat(new[] { ExeLevelNotCompleted }) .Aggregate(new ObjectInfoBuilder(), (obi, levelStr) => obi.Prop(levelStr, () => GetPipsForExecutionLevel(levelStr))) .Build(); RootObject = new ObjectInfoBuilder() .Preview("Root") .Prop("Pips", () => PipGraph.RetrieveAllPips()) .Prop("ProcessPips", () => PipGraph.RetrievePipReferencesOfType(PipType.Process)) .Prop("Files", () => PipGraph.AllFiles) .Prop("Directories", () => PipGraph.AllSealDirectories) .Prop("DirMembership", () => Analyzer.GetDirMembershipData()) //.Prop("CriticalPath", () => new AnalyzeCriticalPath()) .Prop("GroupedBy", new ObjectInfoBuilder() .Prop("Pips", new PipsScope()) .Prop("Files", () => GroupFiles(PipGraph.AllFiles)) .Prop("Directories", () => GroupDirs(PipGraph.AllSealDirectories)) .Build()) .Build(); RootEnv = new Env( parent: null, resolver: (obj) => { return(Renderer.GetObjectInfo(context: this, obj).SetValidator(obj => !Renderer.IsInvalid(obj))); }, vars: LibraryFunctions.All.ToDictionary(f => '$' + f.Name, f => Result.Scalar(f)), current: RootObject); Evaluator = new Evaluator( new Env(parent: RootEnv, resolver: RootEnv.Resolver, current: RootEnv.Current), Analyzer.EnableEvalCaching, Analyzer.EnsureOrdering); }
// Check whether a pip (which produced secondPipOutput) is reachable from another pip (which has to produce firstPipOutput) private void AssertReachability(List <Pip> processPips, PipGraph pipGraph, string firstPipOutput, string secondPipOutput) { var firstPip = processPips.Find(p => p.PipId == FindPipIdThatProducedFile(pipGraph, firstPipOutput)); var secondPip = processPips.Find(p => p.PipId == FindPipIdThatProducedFile(pipGraph, secondPipOutput)); Assert.NotNull(firstPip); Assert.NotNull(secondPip); Assert.True(pipGraph.DataflowGraph.IsReachableFrom(firstPip.PipId.ToNodeId(), secondPip.PipId.ToNodeId(), true)); }
protected override void AssertPipGraphContent(PipGraph pipGraph, SimpleGraph file2file, StringTable stringTable) { AssertPipGraphCounts(pipGraph, new Dictionary <PipType, int> { [PipType.Process] = file2file.NodeCount, }); var processPips = pipGraph.RetrievePipsOfType(PipType.Process).ToList(); AssertEdges(pipGraph, file2file, processPips, stringTable); }
/// <summary> /// Same behavior as <see cref="LoadOrReuse"/>, but the file envelopeId is ignored /// </summary> /// <remarks> /// Only available when the factory is constructed with analysis mode on /// </remarks> public IIncrementalSchedulingState LoadOrReuseIgnoringFileEnvelope( PipGraph pipGraph, IConfiguration configuration, ContentHash preserveOutputSalt, string incrementalSchedulingStatePath, SchedulerState schedulerState) { Contract.Assert(m_analysisMode); return(LoadOrReuseInternal(FileEnvelopeId.Invalid, pipGraph, configuration, preserveOutputSalt, incrementalSchedulingStatePath, schedulerState)); }
/// <nodoc /> public XlgDebuggerState(DebugLogsAnalyzer analyzer) : base(XlgThreadId) { Analyzer = analyzer; var logFile = Path.Combine(Path.GetDirectoryName(Analyzer.Input.ExecutionLogPath), "BuildXL.log"); StackTrace = new[] { new DisplayStackTraceEntry(file: logFile, line: 1, position: 1, functionName: "<main>", entry: null) }; PipsByType = new ObjectInfo(Enum .GetValues(typeof(PipType)) .Cast <PipType>() .Except(new[] { PipType.Max }) .Select(pipType => new Property(pipType.ToString(), () => PipGraph.RetrievePipReferencesOfType(pipType).ToArray()))); PipsByStatus = new ObjectInfo(Enum .GetValues(typeof(PipExecutionLevel)) .Cast <PipExecutionLevel>() .Select(level => level.ToString()) .Concat(new[] { ExeLevelNotCompleted }) .Select(levelStr => new Property(levelStr, () => GetPipsForExecutionLevel(levelStr)))); RootObject = new ObjectInfo(preview: "Root", properties: new[] { new Property("Pips", () => PipGraph.RetrieveAllPips()), new Property("Files", () => PipGraph.AllFiles), new Property("Directories", () => PipGraph.AllSealDirectories), //new Property("CriticalPath", new AnalyzeCricialPath()), new Property("GroupedBy", new ObjectInfo(new[] { new Property("Pips", new PipsScope()), new Property("Files", () => GroupFiles(PipGraph.AllFiles)), new Property("Directories", () => GroupDirs(PipGraph.AllSealDirectories)) })) }); RootEnv = new Env( parent: null, resolver: (obj) => { var result = Renderer.GetObjectInfo(context: this, obj); return(new ObjectInfo( result.Preview, properties: result.Properties .Select(p => new Property(p.Name, value: Renderer.IsInvalid(p.Value) ? new object[0] : p.Value)) .ToArray())); }, vars: LibraryFunctions.All.ToDictionary(f => '$' + f.Name, f => Result.Scalar(f)), current: RootObject); Evaluator = new Evaluator(new Env(parent: RootEnv, resolver: RootEnv.Resolver, current: RootEnv.Current)); }
public Context( PipExecutionContext pipContext, PipGraph pipGraph, IReadonlyDirectedGraph scheduledGraph, AbsolutePath configFilePath, IIdeConfiguration ideConfig) { Contract.Requires(pipGraph != null); Contract.Requires(scheduledGraph != null); Contract.Requires(configFilePath.IsValid); Contract.Requires(ideConfig.SolutionRoot.IsValid); Contract.Requires(ideConfig.SolutionName.IsValid); Contract.Requires(ideConfig.IsEnabled); Contract.Requires(ideConfig.IsNewEnabled); PipGraph = pipGraph; ScheduledGraph = scheduledGraph; StringTable = pipContext.StringTable; PathTable = pipContext.PathTable; SymbolTable = pipContext.SymbolTable; QualifierTable = pipContext.QualifierTable; IdeConfig = ideConfig; DotSettingsPathStr = ideConfig.DotSettingsFile.IsValid ? ideConfig.DotSettingsFile.ToString(PathTable) : null; ConfigFilePathStr = configFilePath.ToString(PathTable); EnlistmentRoot = configFilePath.GetParent(PathTable); EnlistmentRootStr = EnlistmentRoot.ToString(PathTable); SolutionRoot = ideConfig.SolutionRoot; SolutionRootStr = SolutionRoot.ToString(PathTable); SolutionFilePathStr = IdeGenerator.GetSolutionPath(ideConfig, PathTable).ToString(PathTable); CanWriteToSrc = ideConfig.CanWriteToSrc ?? false; ProjectsRoot = CanWriteToSrc ? EnlistmentRoot : SolutionRoot.Combine(PathTable, PathAtom.Create(PathTable.StringTable, "Projects")); ResxExtensionName = PathAtom.Create(StringTable, ".resx"); CscExeName = PathAtom.Create(StringTable, "csc.exe"); CscDllName = PathAtom.Create(StringTable, "csc.dll"); XunitConsoleDllName = PathAtom.Create(StringTable, "xunit.console.dll"); DotnetName = PathAtom.Create(StringTable, "dotnet"); ResgenExeName = PathAtom.Create(StringTable, "ResGen.exe"); ResourcesExtensionName = PathAtom.Create(StringTable, ".resources"); CsExtensionName = PathAtom.Create(StringTable, ".cs"); DllExtensionName = PathAtom.Create(StringTable, ".dll"); ClExeName = PathAtom.Create(StringTable, "cl.exe"); LinkExeName = PathAtom.Create(StringTable, "Link.exe"); VsTestExeName = PathAtom.Create(StringTable, "vstest.console.exe"); AssemblyDeploymentTag = StringId.Create(StringTable, "assemblyDeployment"); TestDeploymentTag = StringId.Create(StringTable, "testDeployment"); }
/// <summary> /// Factory method for the case when pip graph can be reused for graph patching. /// A non-null pip graph must be provided; input changes may optionally be provided too. /// </summary> internal static GraphReuseResult CreateForPartialReuse(PipGraph pipGraph, InputTracker.InputChanges inputChanges) { Contract.Requires(pipGraph != null); Contract.Requires(inputChanges != null); Contract.Requires(inputChanges.ChangedPaths.Any()); return(new GraphReuseResult( pipGraph: pipGraph, engineSchedule: null, inputChanges: inputChanges)); }
/// <summary> /// Adds a process finished by <see cref="TryFinishProcessApplyingOSDefaults(ProcessBuilder, out ProcessOutputs, out Process)"/> to /// the pip graph and updates its process outputs with the pip id that the graph assigns to the added process it /// </summary> public bool TryAddFinishedProcessToGraph(Process pip, ProcessOutputs processOutputs) { if (PipGraph != null) { var success = PipGraph.AddProcess(pip, GetValuePipId()); processOutputs.ProcessPipId = pip.PipId; return(success); } return(true); }
/// <nodoc /> public DirectoryArtifact ReserveSharedOpaqueDirectory(AbsolutePath directoryArtifactRoot) { if (PipGraph != null) { return(PipGraph.ReserveSharedOpaqueDirectory(directoryArtifactRoot)); } // If the pip graph is not available (e.g. /phase:evaluate was passed) // then a directory artifact with seal id zero should suffice return(DirectoryArtifact.CreateWithZeroPartialSealId(directoryArtifactRoot)); }
/// <summary> /// Runs the scheduler using the instance member PipGraph and Configuration objects. This will also carry over /// any state from any previous run such as the cache /// </summary> public ScheduleRunResult RunScheduler(SchedulerTestHooks testHooks = null, SchedulerState schedulerState = null, RootFilter filter = null, TempCleaner tempCleaner = null) { if (m_graphWasModified || m_lastGraph == null) { m_lastGraph = PipGraphBuilder.Build(); XAssert.IsNotNull(m_lastGraph, "Failed to build pip graph"); } m_graphWasModified = false; return(RunSchedulerSpecific(m_lastGraph, testHooks, schedulerState, filter, tempCleaner)); }
/// <summary> /// Loads an existing instance of <see cref="IIncrementalSchedulingState"/> from a given file or reuse it from a given <see cref="SchedulerState"/>. /// </summary> public IIncrementalSchedulingState LoadOrReuse( FileEnvelopeId atomicSaveToken, PipGraph pipGraph, IConfiguration configuration, ContentHash preserveOutputSalt, string incrementalSchedulingStatePath, SchedulerState schedulerState) { Contract.Requires(atomicSaveToken.IsValid); return(LoadOrReuseInternal(atomicSaveToken, pipGraph, configuration, preserveOutputSalt, incrementalSchedulingStatePath, schedulerState)); }
/// <summary> /// Verifies that the file/directory output by a fragment exists in the resulting graph. /// </summary> /// <param name="graph">Resulting graph.</param> /// <param name="fragmentOrigin">Graph fragment where the output originates.</param> /// <param name="outputPath">Path to output file/directory.</param> private void VerifyProducerExists(PipGraph graph, TestPipGraphFragment fragmentOrigin, AbsolutePath outputPath) { AbsolutePath remappedOutputPath = RemapFragmentPath(fragmentOrigin, outputPath); var pipId = graph.TryGetProducer(FileArtifact.CreateOutputFile(remappedOutputPath)); if (!pipId.IsValid) { pipId = graph.TryGetProducer(DirectoryArtifact.CreateWithZeroPartialSealId(remappedOutputPath)); } XAssert.IsTrue(pipId.IsValid, $"Producer of '{outputPath.ToString(fragmentOrigin.Context.PathTable)}' from fragment '{fragmentOrigin.ModuleName}' could not be found in the resulting graph"); }
// A convoluted way of finding a PipId knowing some output from the pip and assuming the outputs' filenames are unique private PipId FindPipIdThatProducedFile(PipGraph pipGraph, string filename) { foreach (var kvp in pipGraph.AllFilesAndProducers) { if (kvp.Key.Path.ToString(PathTable).Contains(filename)) { return(kvp.Value); } } return(PipId.Invalid); }
protected override void AssertPipGraphContent(PipGraph pipGraph, SimpleGraph file2file, StringTable stringTable) { AssertPipGraphCounts(pipGraph, new Dictionary <PipType, int> { [PipType.Process] = file2file.NodeCount * 3, // service pip, service shutdown pip, and service finalize pip in each file [PipType.Ipc] = file2file.NodeCount, // one IPC pip per file }); var ipcPips = pipGraph.RetrievePipsOfType(PipType.Ipc).ToList(); AssertEdges(pipGraph, file2file, ipcPips, stringTable); AssertMonikerConsistencyForIpcPip(ipcPips.Cast <IpcPip>(), pipGraph); }
public TestScheduler( PipGraph graph, TestPipQueue pipQueue, PipExecutionContext context, FileContentTable fileContentTable, EngineCache cache, IConfiguration configuration, FileAccessWhitelist fileAccessWhitelist, DirectoryMembershipFingerprinterRuleSet directoryMembershipFingerprinterRules = null, ITempCleaner tempCleaner = null, PipRuntimeTimeTable runningTimeTable = null, JournalState journalState = null, PerformanceCollector performanceCollector = null, string fingerprintSalt = null, PreserveOutputsInfo?previousInputsSalt = null, IEnumerable <Pip> successfulPips = null, IEnumerable <Pip> failedPips = null, LoggingContext loggingContext = null, IIpcProvider ipcProvider = null, DirectoryTranslator directoryTranslator = null, VmInitializer vmInitializer = null, SchedulerTestHooks testHooks = null) : base(graph, pipQueue, context, fileContentTable, cache, configuration, fileAccessWhitelist, loggingContext, null, directoryMembershipFingerprinterRules, tempCleaner, AsyncLazy <PipRuntimeTimeTable> .FromResult(runningTimeTable), performanceCollector, fingerprintSalt, previousInputsSalt, ipcProvider: ipcProvider, directoryTranslator: directoryTranslator, journalState: journalState, vmInitializer: vmInitializer, testHooks: testHooks) { m_testPipQueue = pipQueue; if (successfulPips != null) { foreach (var pip in successfulPips) { Contract.Assume(pip.PipId.IsValid, "Override results must be added after the pip has been added to the scheduler"); m_overridePipResults.Add(pip.PipId, PipResultStatus.Succeeded); } } if (failedPips != null) { foreach (var pip in failedPips) { Contract.Assume(pip.PipId.IsValid, "Override results must be added after the pip has been added to the scheduler"); m_overridePipResults.Add(pip.PipId, PipResultStatus.Failed); } } m_loggingContext = loggingContext; }
/// <nodoc/> public bool TryAssertOutputExistenceInOpaqueDirectory(DirectoryArtifact outputDirectoryArtifact, AbsolutePath outputInOpaque, out FileArtifact fileArtifact) { Contract.Requires(outputDirectoryArtifact.IsValid); Contract.Requires(outputInOpaque.IsValid); if (PipGraph is null) { fileArtifact = FileArtifact.Invalid; return(false); } return(PipGraph.TryAssertOutputExistenceInOpaqueDirectory(outputDirectoryArtifact, outputInOpaque, out fileArtifact)); }
public ChooseWorkerCpu( LoggingContext loggingContext, IConfiguration config, IReadOnlyList <Worker> workers, IPipQueue pipQueue, PipGraph pipGraph, FileContentManager fileContentManager) : base(loggingContext, config, workers, pipQueue, DispatcherKind.ChooseWorkerCpu, config.Schedule.MaxChooseWorkerCpu) { m_pipTable = pipGraph.PipTable; m_executedProcessOutputs = new ContentTrackingSet(pipGraph); m_fileContentManager = fileContentManager; m_pipSetupCostPool = new ObjectPool <PipSetupCosts>(() => new PipSetupCosts(this), costs => costs, size: config.Schedule.MaxChooseWorkerCpu); }
/// <summary> /// Class constructor /// </summary> public CachedGraph(PipGraph pipGraph, DirectedGraph dataflowGraph, PipExecutionContext context, MountPathExpander mountPathExpander) { Contract.Requires(pipGraph != null); Contract.Requires(dataflowGraph != null); Contract.Requires(context != null); Contract.Requires(mountPathExpander != null); DataflowGraph = dataflowGraph; PipTable = pipGraph.PipTable; MountPathExpander = mountPathExpander; Context = context; PipGraph = pipGraph; }
public ChooseWorkerCpu( LoggingContext loggingContext, int maxParallelDegree, IReadOnlyList <Worker> workers, IPipQueue pipQueue, PipGraph pipGraph, FileContentManager fileContentManager) : base(loggingContext, workers, pipQueue, DispatcherKind.ChooseWorkerCpu, maxParallelDegree) { m_pipTable = pipGraph.PipTable; m_executedProcessOutputs = new ContentTrackingSet(pipGraph); m_fileContentManager = fileContentManager; m_pipSetupCostPool = new ObjectPool <PipSetupCosts>(() => new PipSetupCosts(this), costs => costs, size: maxParallelDegree); }
internal static void AssertPipGraphCounts(PipGraph pipGraph, Dictionary <PipType, int> pipTypeCounts) { var pips = pipGraph.RetrieveScheduledPips().Where(p => NotMetaPip(p) && p.PipType != PipType.HashSourceFile).ToArray(); XAssert.All( pipTypeCounts, pipTypeAndCount => { AssertPipTypeCount(pips, pipTypeAndCount.Key, pipTypeAndCount.Value); }); var expectedTotalNonMetaPips = pipTypeCounts.Sum(t => t.Value); XAssert.AreEqual(expectedTotalNonMetaPips, pips.Count(), "Expected total number non-meta pips didn't match"); }
public override void Prepare() { m_writer = new StreamWriter(OutputFilePath); SpecPath = AbsolutePath.Create(PathTable, @"d:\dbs\el\o8\Build\ProductBuild\liblet_officewebserviceapi_droidx86_ship\build.dsc"); DirectoryPath = AbsolutePath.Create(PathTable, @"d:\dbs\cx\o8\androidsdk.24.0.4"); foreach (var producer in PipGraph.GetProducingPips(SpecPath)) { m_writer.WriteLine(GetDescription(producer)); m_writer.WriteLine(); } // GetPathProducers(path); }
private void GetPathProducers(AbsolutePath path) { Dictionary <AbsolutePath, DirectoryArtifact> directories = new Dictionary <AbsolutePath, DirectoryArtifact>(); foreach (var directory in PipGraph.AllSealDirectories) { directories[directory.Path] = directory; } var latest = PipGraph.TryGetLatestFileArtifactForPath(path); if (!latest.IsValid) { m_writer.WriteLine("No declared file producers"); } else { for (int i = 0; i <= latest.RewriteCount; i++) { var producerId = PipGraph.TryGetProducer(new FileArtifact(path, i)); if (producerId.IsValid) { m_writer.WriteLine("File Producer: ({0})", i); m_producers.Add(producerId); m_writer.WriteLine(GetDescription(GetPip(producerId))); m_writer.WriteLine(); } } } while (path.IsValid) { DirectoryArtifact containingDirectory; if (directories.TryGetValue(path, out containingDirectory)) { var directoryNode = PipGraph.GetSealedDirectoryNode(containingDirectory); var sealDirectory = (SealDirectory)GetPip(directoryNode); if (sealDirectory.Kind == SealDirectoryKind.Opaque) { m_writer.WriteLine("Directory Producer:"); m_producers.Add(PipGraph.GetProducer(containingDirectory)); m_writer.WriteLine(GetDescription(GetPip(PipGraph.GetProducer(containingDirectory)))); m_writer.WriteLine("Directory: " + GetDescription(sealDirectory)); m_writer.WriteLine(); } } path = path.GetParent(PathTable); } }
/// <summary> /// Class constructor /// </summary> public CachedGraph(PipGraph pipGraph, IReadonlyDirectedGraph directedGraph, PipExecutionContext context, MountPathExpander mountPathExpander, EngineSerializer serializer = null) { Contract.Requires(pipGraph != null); Contract.Requires(directedGraph != null); Contract.Requires(context != null); Contract.Requires(mountPathExpander != null); DirectedGraph = directedGraph; PipTable = pipGraph.PipTable; MountPathExpander = mountPathExpander; Context = context; PipGraph = pipGraph; Serializer = serializer; }
/// <summary> /// Creates an instance of <see cref="TestPipGraphFragment"/>. /// </summary> public TestPipGraphFragment(LoggingContext loggingContext, string sourceRoot, string objectRoot, string redirectedRoot, string moduleName, bool useTopSort = false) { Contract.Requires(loggingContext != null); Contract.Requires(!string.IsNullOrEmpty(sourceRoot)); Contract.Requires(!string.IsNullOrEmpty(objectRoot)); Contract.Requires(!string.IsNullOrEmpty(moduleName)); Context = BuildXLContext.CreateInstanceForTesting(); m_loggingContext = loggingContext; m_sourceRoot = AbsolutePath.Create(Context.PathTable, sourceRoot); m_objectRoot = AbsolutePath.Create(Context.PathTable, objectRoot); m_expander = new MountPathExpander(Context.PathTable); var configuration = new ConfigurationImpl() { Schedule = { UseFixedApiServerMoniker = true, ComputePipStaticFingerprints = true, } }; m_useTopSort = useTopSort; PipGraph = m_useTopSort ? new PipGraphFragmentBuilderTopSort(Context, configuration, m_expander) : new PipGraphFragmentBuilder(Context, configuration, m_expander); ModuleName = moduleName; var specFileName = moduleName + ".dsc"; m_specPath = m_sourceRoot.Combine(Context.PathTable, specFileName); m_moduleId = ModuleId.Create(StringId.Create(Context.StringTable, moduleName)); var modulePip = ModulePip.CreateForTesting( Context.StringTable, m_specPath, m_moduleId); PipGraph.AddModule(modulePip); PipGraph.AddSpecFile(new SpecFilePip(new FileArtifact(m_specPath), new LocationData(m_specPath, 0, 0), modulePip.Module)); m_defaultConstructionHelper = PipConstructionHelper.CreateForTesting( Context, objectRoot: m_objectRoot, redirectedRoot: AbsolutePath.Create(Context.PathTable, redirectedRoot), pipGraph: PipGraph, moduleName: moduleName, specRelativePath: Path.Combine(m_sourceRoot.GetName(Context.PathTable).ToString(Context.StringTable), specFileName), specPath: m_specPath, symbol: moduleName + "_defaultValue"); }
private bool ProcessFilter(string filterText, FileStream stream, StreamWriter writer) { var parser = new FilterParser(CachedGraph.Context, CachedGraph.MountPathExpander.TryGetRootByMountName, filterText, canonicalize: true); if (!parser.TryParse(out var rootFilter, out var error)) { Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Error at position {1} of command line pip filter {0}. {3} {2}", filterText, error.Position, error.FormatFilterPointingToPosition(filterText), error.Message)); return(false); } var outputs = PipGraph.FilterOutputs(rootFilter); var pips = new List <PipId>(); if (PipGraph.FilterNodesToBuild(Events.StaticContext, rootFilter, out var nodes)) { foreach (var node in nodes) { pips.Add(node.ToPipId()); } } writer.WriteLine(I($"Filter: {filterText}")); writer.WriteLine(I($"Pips: {pips.Count}")); Console.WriteLine(I($"Pips: {pips.Count}")); foreach (var pip in pips) { writer.WriteLine(GetDescription(GetPip(pip))); } writer.WriteLine(); Console.WriteLine(I($"Outputs: {outputs.Count}")); writer.WriteLine(I($"Outputs: {outputs.Count}")); foreach (var output in outputs) { var kind = output.IsDirectory ? "D" : "F"; writer.WriteLine(I($"{kind}: {output.Path.ToString(PathTable)} ({GetDescription(GetPip(PipGraph.GetProducer(output)))})")); } writer.WriteLine(); writer.WriteLine(); writer.Flush(); stream.Flush(); return(true); }
private PipId GetValuePipId() { if (PipGraph != null) { if (!m_valuePip.PipId.IsValid) { PipGraph.AddOutputValue(m_valuePip); } Contract.Assert(m_valuePip.PipId.IsValid); } return(m_valuePip.PipId); }
private void TopSortInternal(List <Pip> pips, List <List <Pip> > sortedPipGroups) { var childrenLeftToVisit = new Dictionary <Pip, int>(); sortedPipGroups.Add(new List <Pip>()); int totalAdded = 0; foreach (var pip in pips) { childrenLeftToVisit[pip] = 0; } foreach (var pip in pips) { foreach (var dependent in (PipGraph.RetrievePipImmediateDependents(pip) ?? Enumerable.Empty <Pip>())) { childrenLeftToVisit[dependent]++; } } foreach (var pip in pips) { if (childrenLeftToVisit[pip] == 0) { totalAdded++; sortedPipGroups[sortedPipGroups.Count - 1].Add(pip); } } int currentLevel = sortedPipGroups.Count - 1; while (totalAdded < pips.Count) { sortedPipGroups.Add(new List <Pip>()); foreach (var pip in sortedPipGroups[currentLevel]) { foreach (var dependent in PipGraph.RetrievePipImmediateDependents(pip) ?? Enumerable.Empty <Pip>()) { if (--childrenLeftToVisit[dependent] == 0) { totalAdded++; sortedPipGroups[currentLevel + 1].Add(dependent); } } } currentLevel++; } }
/// <nodoc/> public bool TryAssertOutputExistenceInOpaqueDirectory(DirectoryArtifact outputDirectoryArtifact, AbsolutePath outputInOpaque, out FileArtifact fileArtifact) { Contract.Requires(outputDirectoryArtifact.IsValid); Contract.Requires(outputInOpaque.IsValid); // A null pip graph is the case of, for example, /phase:evaluate. Since there is no real execution going on, let's pretend the asserted file exists if (PipGraph is null) { // Outputs in opaques always have rewrite count 1 fileArtifact = FileArtifact.CreateOutputFile(outputInOpaque); return(true); } return(PipGraph.TryAssertOutputExistenceInOpaqueDirectory(outputDirectoryArtifact, outputInOpaque, out fileArtifact)); }
protected static void AssertEdges(PipGraph pipGraph, SimpleGraph file2file, List <Pip> pips, StringTable stringTable) { XAssert.All( file2file.Edges, edge => { var srcPip = FindPipByTag(pips, GetProcTag(edge.Src), stringTable); var destPip = FindPipByTag(pips, GetProcTag(edge.Dest), stringTable); var deps = pipGraph.RetrievePipImmediateDependencies(srcPip).ToList(); if (!deps.Contains(destPip)) { XAssert.Fail($"Edge ({edge.Src})->({edge.Dest}) not found: expected an edge between {srcPip} <-- {destPip}; dependencies of Pip {srcPip} are: {XAssert.SetToString(deps)}"); } }); }