internal override void CreateFromStream(BinaryReader reader) { base.CreateFromStream(reader); buildResult = BuildResult.CreateFromStream(reader); }
/// <summary> /// This method adds cached results for each target results for which are contained inside /// the build result. This method is thread safe. /// </summary> internal void AddCacheEntryForBuildResults(BuildResult buildResult) { ErrorUtilities.VerifyThrow(buildResult != null, "Expect a non-null build result"); // Don't cache results if they are marked as uncacheable if (!buildResult.UseResultCache) { return; } cacheScopeReaderWriterLock.AcquireWriterLock(Timeout.Infinite); try { if (!ContainsCacheEntry(Constants.defaultTargetCacheName)) { // If the project file is malformed the build may fail without initializing the initialtargets or // the default targests fields. The retrieval code expects non-null values // so it is necessary to replace null with empty string ErrorUtilities.VerifyThrow(buildResult.EvaluationResult == false || buildResult.InitialTargets != null && buildResult.DefaultTargets != null, "Expect initial targets to be non-null for successful builds"); string defaultTargets = buildResult.DefaultTargets == null ? String.Empty : buildResult.DefaultTargets; PropertyCacheEntry defaultTargetsCacheEntry = new PropertyCacheEntry(Constants.defaultTargetCacheName, defaultTargets); AddCacheEntryInternal(defaultTargetsCacheEntry); string initialTargets = buildResult.InitialTargets == null ? String.Empty : buildResult.InitialTargets; PropertyCacheEntry initialTargetsCacheEntry = new PropertyCacheEntry(Constants.initialTargetCacheName, initialTargets); AddCacheEntryInternal(initialTargetsCacheEntry); } if (!ContainsCacheEntry(Constants.projectIdCacheName)) { PropertyCacheEntry projectIdCacheEntry = new PropertyCacheEntry(Constants.projectIdCacheName, buildResult.ProjectId.ToString(CultureInfo.InvariantCulture)); AddCacheEntryInternal(projectIdCacheEntry); } IDictionary outputsByTargetName = buildResult.OutputsByTarget; //Create single entry for each target in the request foreach (DictionaryEntry entry in buildResult.ResultByTarget) { Target.BuildState buildState = (Target.BuildState)entry.Value; // Only cache successful and failed targets if ((buildState == Target.BuildState.CompletedSuccessfully) || (buildState == Target.BuildState.CompletedUnsuccessfully)) { BuildItem[] targetOutputs = null; // Only cache output items for successful targets if (buildState == Target.BuildState.CompletedSuccessfully) { ErrorUtilities.VerifyThrow(buildResult.OutputsByTarget.Contains(entry.Key), "We must have build results for successful targets"); BuildItem[] outputItems = (BuildItem[])buildResult.OutputsByTarget[entry.Key]; // It's essential that we clear out any pointers to the project from the BuildItem; // otherwise the cache will hold onto the project, and not save any memory. if (outputItems != null) { for (int i = 0; i < outputItems.Length; i++) { outputItems[i] = outputItems[i].VirtualClone(true /* remove references to minimise transitive size */); } } targetOutputs = (BuildItem[])buildResult.OutputsByTarget[entry.Key]; } BuildResultCacheEntry cacheEntry = new BuildResultCacheEntry((string)entry.Key, targetOutputs, (buildState == Target.BuildState.CompletedSuccessfully)); if (Engine.debugMode) { Console.WriteLine("+++Adding cache entry for " + (string)entry.Key + " in " + this.ScopeName + " result: " + (buildState == Target.BuildState.CompletedSuccessfully)); } AddCacheEntryInternal(cacheEntry); } } } finally { cacheScopeReaderWriterLock.ReleaseWriterLock(); } }
internal LocalCallDescriptorForPostBuildResult(BuildResult buildResult) : base(LocalCallType.PostBuildResult) { this.buildResult = buildResult; }