private Target AddTargetCore( BuildEventArgs args, string targetName, string parentTargetName, string targetFile, TargetBuiltReason targetBuiltReason) { try { lock (syncLock) { var project = GetOrAddProject(args.BuildEventContext.ProjectContextId); var target = project.CreateTarget(targetName, args.BuildEventContext.TargetId); target.NodeId = args.BuildEventContext.NodeId; target.StartTime = args.Timestamp; target.EndTime = target.StartTime; // will properly set later target.ParentTarget = parentTargetName; target.TargetBuiltReason = targetBuiltReason; target.SourceFilePath = targetFile; project.AddChild(target); return(target); } } catch (Exception ex) { HandleException(ex); } return(null); }
public TargetInfo(int id, int nodeId, string name, string sourceFilePath, string parentTarget, TargetBuiltReason reason, DateTime startTime) { Id = id; NodeId = nodeId; Name = name; SourceFilePath = sourceFilePath; ParentTarget = parentTarget; Reason = reason; StartTime = startTime; }
public TargetInfo(string name, string sourceFilePath, string parentTarget, TargetBuiltReason reason, DateTime startTime) { Id = BuildEventContext.InvalidTargetId; NodeId = BuildEventContext.InvalidNodeId; Name = name; SourceFilePath = sourceFilePath; ParentTarget = parentTarget; Reason = reason; StartTime = startTime; EndTime = startTime; Result = Result.Skipped; }
/// <summary> /// Deserializes from a stream through a binary reader /// </summary> /// <param name="reader">Binary reader which is attached to the stream the event will be deserialized from</param> /// <param name="version">The version of the runtime the message packet was created from</param> internal override void CreateFromStream(BinaryReader reader, int version) { base.CreateFromStream(reader, version); #region TargetName if (reader.ReadByte() == 0) { targetName = null; } else { targetName = reader.ReadString(); } #endregion #region ProjectFile if (reader.ReadByte() == 0) { projectFile = null; } else { projectFile = reader.ReadString(); } #endregion #region TargetFile if (reader.ReadByte() == 0) { targetFile = null; } else { targetFile = reader.ReadString(); } #endregion #region ParentTarget if (version > 20) { if (reader.ReadByte() == 0) { parentTarget = null; } else { parentTarget = reader.ReadString(); } } #endregion #region BuildReason if (version > 20) { buildReason = (TargetBuiltReason)reader.ReadInt32(); } #endregion }
public Target(int nodeId, string name, bool isRequestedTarget, string sourceFilePath, string parentTarget, TargetBuiltReason reason, ImmutableList <ItemAction> itemActions, ImmutableList <PropertySet> propertySets, ImmutableList <Item> outputItems, ImmutableList <Task> tasks, DateTime startTime, DateTime endTime, ImmutableList <Message> messages, Result result) : base(messages, startTime, endTime, result) { NodeId = nodeId; Name = name; IsRequestedTarget = isRequestedTarget; SourceFilePath = sourceFilePath; ParentTarget = parentTarget; Reason = reason; ItemActions = itemActions; PropertySets = propertySets; OutputItems = outputItems; Tasks = tasks; }
/// <summary> /// Deserializes from a stream through a binary reader /// </summary> /// <param name="reader">Binary reader which is attached to the stream the event will be deserialized from</param> /// <param name="version">The version of the runtime the message packet was created from</param> internal override void CreateFromStream(BinaryReader reader, int version) { base.CreateFromStream(reader, version); targetName = reader.ReadByte() == 0 ? null : reader.ReadString(); projectFile = reader.ReadByte() == 0 ? null : reader.ReadString(); targetFile = reader.ReadByte() == 0 ? null : reader.ReadString(); if (version > 20) { parentTarget = reader.ReadByte() == 0 ? null : reader.ReadString(); buildReason = (TargetBuiltReason)reader.ReadInt32(); } }
public void TargetStarted(object sender, TargetStartedEventArgs args) { TargetBuiltReason targetBuiltReason = TargetBuiltReason.None; if (args is TargetStartedEventArgs targetStartedArgs) { targetBuiltReason = targetStartedArgs.BuildReason; } AddTargetCore( args, Intern(args.TargetName), Intern(args.ParentTarget), Intern(args.TargetFile), targetBuiltReason); }
public TargetStartedEventArgs2( string message, string helpKeyword, string targetName, string projectFile, string targetFile, string parentTarget, TargetBuiltReason targetBuiltReason, DateTime eventTimestamp) : base( message, helpKeyword, targetName, projectFile, targetFile, parentTarget, eventTimestamp) { TargetBuiltReason = targetBuiltReason; }
/// <summary> /// This constructor allows event data to be initialized. /// </summary> /// <param name="message">text message</param> /// <param name="helpKeyword">help keyword </param> /// <param name="targetName">target name</param> /// <param name="projectFile">project file</param> /// <param name="targetFile">file in which the target is defined</param> /// <param name="parentTarget">The part of the target.</param> /// <param name="buildReason">The reason the parent built this target.</param> /// <param name="eventTimestamp">Timestamp when the event was created</param> public TargetStartedEventArgs ( string message, string helpKeyword, string targetName, string projectFile, string targetFile, string parentTarget, TargetBuiltReason buildReason, DateTime eventTimestamp ) : base(message, helpKeyword, "MSBuild", eventTimestamp) { this.targetName = targetName; this.projectFile = projectFile; this.targetFile = targetFile; this.parentTarget = parentTarget; this.buildReason = buildReason; }
/// <summary> /// The constructor. /// </summary> /// <param name="requestEntry">The build request entry for the target.</param> /// <param name="targetBuilderCallback">The target builder callback.</param> /// <param name="targetSpecification">The specification for the target to build.</param> /// <param name="baseLookup">The lookup to use.</param> /// <param name="parentTarget">The parent of this entry, if any.</param> /// <param name="buildReason">The reason the parent built this target.</param> /// <param name="host">The Build Component Host to use.</param> /// <param name="stopProcessingOnCompletion">True if the target builder should stop processing the current target stack when this target is complete.</param> internal TargetEntry(BuildRequestEntry requestEntry, ITargetBuilderCallback targetBuilderCallback, TargetSpecification targetSpecification, Lookup baseLookup, TargetEntry parentTarget, TargetBuiltReason buildReason, IBuildComponentHost host, bool stopProcessingOnCompletion) { ErrorUtilities.VerifyThrowArgumentNull(requestEntry, nameof(requestEntry)); ErrorUtilities.VerifyThrowArgumentNull(targetBuilderCallback, nameof(targetBuilderCallback)); ErrorUtilities.VerifyThrowArgumentNull(targetSpecification, "targetName"); ErrorUtilities.VerifyThrowArgumentNull(baseLookup, "lookup"); ErrorUtilities.VerifyThrowArgumentNull(host, nameof(host)); _requestEntry = requestEntry; _targetBuilderCallback = targetBuilderCallback; _targetSpecification = targetSpecification; _parentTarget = parentTarget; _buildReason = buildReason; _expander = new Expander <ProjectPropertyInstance, ProjectItemInstance>(baseLookup, baseLookup, FileSystems.Default); _state = TargetEntryState.Dependencies; _baseLookup = baseLookup; _host = host; this.StopProcessingOnCompletion = stopProcessingOnCompletion; }
private Target AddTargetCore( BuildEventArgs args, string targetName, string parentTargetName, string targetFile, TargetBuiltReason targetBuiltReason) { try { lock (syncLock) { var project = GetOrAddProject(args.BuildEventContext.ProjectContextId); var target = project.CreateTarget(targetName, args.BuildEventContext.TargetId); target.NodeId = args.BuildEventContext.NodeId; target.StartTime = args.Timestamp; target.EndTime = target.StartTime; // will properly set later target.ParentTarget = parentTargetName; target.TargetBuiltReason = targetBuiltReason; if (!ParentAllTargetsUnderProject && !string.IsNullOrEmpty(parentTargetName)) { var parentTarget = project.GetOrAddTargetByName(parentTargetName, args.Timestamp); parentTarget.TryAddTarget(target); //project.TryAddTarget(parentTarget); } else { project.TryAddTarget(target); } target.SourceFilePath = targetFile; return(target); } } catch (Exception ex) { HandleException(ex); } return(null); }
private BuildEventArgs ReadTargetStartedEventArgs() { BuildEventArgsFields fields = ReadBuildEventArgsFields(); string targetName = ReadOptionalString(); string projectFile = ReadOptionalString(); string targetFile = ReadOptionalString(); string parentTarget = ReadOptionalString(); // BuildReason was introduced in version 4 TargetBuiltReason buildReason = fileFormatVersion > 3 ? (TargetBuiltReason)ReadInt32() : TargetBuiltReason.None; TargetStartedEventArgs e = new TargetStartedEventArgs( fields.Message, fields.HelpKeyword, targetName, projectFile, targetFile, parentTarget, buildReason, fields.Timestamp); SetCommonFields(e, fields); return(e); }
private BuildEventArgs ReadTargetSkippedEventArgs() { BuildEventArgsFields fields = ReadBuildEventArgsFields(); // Read unused Importance, it defaults to Low ReadInt32(); string targetFile = ReadOptionalString(); string targetName = ReadOptionalString(); string parentTarget = ReadOptionalString(); TargetBuiltReason buildReason = (TargetBuiltReason)ReadInt32(); TargetSkippedEventArgs e = new TargetSkippedEventArgs( fields.Message); SetCommonFields(e, fields); e.ProjectFile = fields.ProjectFile; e.TargetFile = targetFile; e.TargetName = targetName; e.ParentTarget = parentTarget; e.BuildReason = buildReason; return(e); }
/// <summary> /// Log that a target has started /// </summary> internal TargetLoggingContext LogTargetBatchStarted(string projectFullPath, ProjectTargetInstance target, string parentTargetName, TargetBuiltReason buildReason) { ErrorUtilities.VerifyThrow(this.IsValid, "invalid"); return(new TargetLoggingContext(this, projectFullPath, target, parentTargetName, buildReason)); }
/// <summary> /// Logs that a target started /// </summary> /// <param name="projectBuildEventContext">Event context for the project spawning this target</param> /// <param name="targetName">Name of target</param> /// <param name="projectFile">Project file being built</param> /// <param name="projectFileOfTargetElement">Project file which contains the target</param> /// <param name="parentTargetName">The name of the parent target.</param> /// <param name="buildReason">The reason the parent target built the target.</param> /// <returns>The build event context for the target.</returns> /// <exception cref="InternalErrorException">BuildEventContext is null</exception> public BuildEventContext LogTargetStarted(BuildEventContext projectBuildEventContext, string targetName, string projectFile, string projectFileOfTargetElement, string parentTargetName, TargetBuiltReason buildReason) { lock (_lockObject) { ErrorUtilities.VerifyThrow(projectBuildEventContext != null, "projectBuildEventContext is null"); BuildEventContext targetBuildEventContext = new BuildEventContext ( projectBuildEventContext.SubmissionId, projectBuildEventContext.NodeId, projectBuildEventContext.ProjectInstanceId, projectBuildEventContext.ProjectContextId, NextTargetId, BuildEventContext.InvalidTaskId ); string message = String.Empty; if (!OnlyLogCriticalEvents) { if (String.Equals(projectFile, projectFileOfTargetElement, StringComparison.OrdinalIgnoreCase)) { if (!String.IsNullOrEmpty(parentTargetName)) { message = ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword("TargetStartedProjectDepends", targetName, projectFile, parentTargetName); } else { message = ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword("TargetStartedProjectEntry", targetName, projectFile); } } else { if (!String.IsNullOrEmpty(parentTargetName)) { message = ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword("TargetStartedFileProjectDepends", targetName, projectFileOfTargetElement, projectFile, parentTargetName); } else { message = ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword("TargetStartedFileProjectEntry", targetName, projectFileOfTargetElement, projectFile); } } TargetStartedEventArgs buildEvent = new TargetStartedEventArgs ( message, null, // no help keyword targetName, projectFile, projectFileOfTargetElement, parentTargetName, buildReason, DateTime.UtcNow ); buildEvent.BuildEventContext = targetBuildEventContext; ProcessLoggingEvent(buildEvent); } return(targetBuildEventContext); } }
/// <summary> /// Logs that a target started /// </summary> /// <param name="projectBuildEventContext">Event context for the project spawning this target</param> /// <param name="targetName">Name of target</param> /// <param name="projectFile">Project file being built</param> /// <param name="projectFileOfTargetElement">Project file which contains the target</param> /// <param name="parentTargetName">The name of the parent target.</param> /// <param name="buildReason">The reason the parent target built the target.</param> /// <returns>The build event context for the target.</returns> /// <exception cref="InternalErrorException">BuildEventContext is null</exception> public BuildEventContext LogTargetStarted(BuildEventContext projectBuildEventContext, string targetName, string projectFile, string projectFileOfTargetElement, string parentTargetName, TargetBuiltReason buildReason) { lock (_lockObject) { ErrorUtilities.VerifyThrow(projectBuildEventContext != null, "projectBuildEventContext is null"); BuildEventContext targetBuildEventContext = new BuildEventContext ( projectBuildEventContext.SubmissionId, projectBuildEventContext.NodeId, projectBuildEventContext.ProjectInstanceId, projectBuildEventContext.ProjectContextId, NextTargetId, BuildEventContext.InvalidTaskId ); if (!OnlyLogCriticalEvents) { TargetStartedEventArgs buildEvent = new TargetStartedEventArgs ( message: null, helpKeyword: null, targetName, projectFile, projectFileOfTargetElement, parentTargetName, buildReason, DateTime.UtcNow ); buildEvent.BuildEventContext = targetBuildEventContext; ProcessLoggingEvent(buildEvent); } return(targetBuildEventContext); } }
private TargetGraph.Node AddNode(string name, bool wasSkipped, string?parentName, TargetBuiltReason reason, string projectFile) { _targetStack.TryPeek(out var stackParent); if (!wasSkipped) { _targetStack.Push(name); } if (_cluster == null) { throw new Exception($"Cluster is null!"); } var node = _cluster !.GetOrAdd(name); node.Finished = wasSkipped; // was the MSBuild task called on this target directly? bool forced = false; if (parentName == null) { forced = true; parentName = stackParent; } if (parentName != null) { Cluster?parentCluster = null; if (forced) { _projectStack.TryPeek(out parentCluster); } var parent = (parentCluster ?? _cluster).GetOrAdd(parentName); var edge = parent.AddDependency(node, reason); edge.Runtime = true; edge.Forced = forced; } return(node); }
/// <summary> /// Pushes the list of targets specified onto the target stack in reverse order specified, so that /// they will be built in the order specified. /// </summary> /// <param name="targets">List of targets to build.</param> /// <param name="parentTargetEntry">The target which should be considered the parent of these targets.</param> /// <param name="baseLookup">The lookup to be used to build these targets.</param> /// <param name="addAsErrorTarget">True if this should be considered an error target.</param> /// <param name="stopProcessingOnCompletion">True if target stack processing should terminate when the last target in the list is processed.</param> /// <param name="buildReason">The reason the target is being built by the parent.</param> /// <returns>True if we actually pushed any targets, false otherwise.</returns> private async Task <bool> PushTargets(IList <TargetSpecification> targets, TargetEntry parentTargetEntry, Lookup baseLookup, bool addAsErrorTarget, bool stopProcessingOnCompletion, TargetBuiltReason buildReason) { List <TargetEntry> targetsToPush = new List <TargetEntry>(targets.Count); // Iterate the list in reverse order so that the first target in the list is the last pushed, and thus the first to be executed. for (int i = targets.Count - 1; i >= 0; i--) { TargetSpecification targetSpecification = targets[i]; if (buildReason == TargetBuiltReason.BeforeTargets || buildReason == TargetBuiltReason.AfterTargets) { // Don't build any Before or After targets for which we already have results. Unlike other targets, // we don't explicitly log a skipped-with-results message because it is not interesting. if (_buildResult.HasResultsForTarget(targetSpecification.TargetName)) { if (_buildResult[targetSpecification.TargetName].ResultCode != TargetResultCode.Skipped) { continue; } } } ElementLocation targetLocation = targetSpecification.ReferenceLocation; // See if this target is already building under a different build request. If so, we need to wait. int idOfAlreadyBuildingRequest = BuildRequest.InvalidGlobalRequestId; if (_requestEntry.RequestConfiguration.ActivelyBuildingTargets.TryGetValue(targetSpecification.TargetName, out idOfAlreadyBuildingRequest)) { if (idOfAlreadyBuildingRequest != _requestEntry.Request.GlobalRequestId) { // Another request elsewhere is building it. We need to wait. await _requestBuilderCallback.BlockOnTargetInProgress(idOfAlreadyBuildingRequest, targetSpecification.TargetName); // If we come out of here and the target is *still* active, it means the scheduler detected a circular dependency and told us to // continue so we could throw the exception. if (_requestEntry.RequestConfiguration.ActivelyBuildingTargets.ContainsKey(targetSpecification.TargetName)) { ProjectErrorUtilities.ThrowInvalidProject(targetLocation, "CircularDependency", targetSpecification.TargetName); } } else { if (buildReason == TargetBuiltReason.AfterTargets) { // If the target we are pushing is supposed to run after the current target and it is already set to run after us then skip adding it now. continue; } // We are already building this target on this request. That's a circular dependency. ProjectErrorUtilities.ThrowInvalidProject(targetLocation, "CircularDependency", targetSpecification.TargetName); } } else { // Does this target exist in our direct parent chain, if it is a before target (since these can cause circular dependency issues) if (buildReason == TargetBuiltReason.BeforeTargets || buildReason == TargetBuiltReason.DependsOn || buildReason == TargetBuiltReason.None) { TargetEntry currentParent = parentTargetEntry; while (currentParent != null) { if (String.Equals(currentParent.Name, targetSpecification.TargetName, StringComparison.OrdinalIgnoreCase)) { // We are already building this target on this request. That's a circular dependency. ProjectErrorUtilities.ThrowInvalidProject(targetLocation, "CircularDependency", targetSpecification.TargetName); } currentParent = currentParent.ParentEntry; } } else { // For an after target, if it is already ANYWHERE on the stack, we don't need to push it because it is already going to run // after whatever target is causing it to be pushed now. bool alreadyPushed = false; foreach (TargetEntry entry in _targetsToBuild) { if (String.Equals(entry.Name, targetSpecification.TargetName, StringComparison.OrdinalIgnoreCase)) { alreadyPushed = true; break; } } if (alreadyPushed) { continue; } } } // Add to the list of targets to push. We don't actually put it on the stack here because we could run into a circular dependency // during this loop, in which case the target stack would be out of whack. TargetEntry newEntry = new TargetEntry(_requestEntry, this as ITargetBuilderCallback, targetSpecification, baseLookup, parentTargetEntry, buildReason, _componentHost, stopProcessingOnCompletion); newEntry.ErrorTarget = addAsErrorTarget; targetsToPush.Add(newEntry); stopProcessingOnCompletion = false; // The first target on the stack (the last one to be run) always inherits the stopProcessing flag. } // Now push the targets since this operation cannot fail. foreach (TargetEntry targetToPush in targetsToPush) { _targetsToBuild.Push(targetToPush); } bool pushedTargets = (targetsToPush.Count > 0); return(pushedTargets); }
/// <summary> /// Logs a target started event /// </summary> /// <param name="projectBuildEventContext">The build event context of the project</param> /// <param name="targetName">The name of the target</param> /// <param name="projectFile">The project file</param> /// <param name="projectFileOfTargetElement">The project file containing the target element</param> /// <returns>The build event context for the target</returns> public BuildEventContext LogTargetStarted(BuildEventContext projectBuildEventContext, string targetName, string projectFile, string projectFileOfTargetElement, string parentTargetName, TargetBuiltReason buildReason) { return(new BuildEventContext(0, 0, 0, 0)); }
/// <summary> /// Creates a new target logging context from an existing project context and target. /// </summary> internal TargetLoggingContext(ProjectLoggingContext projectLoggingContext, string projectFullPath, ProjectTargetInstance target, string parentTargetName, TargetBuiltReason buildReason) : base(projectLoggingContext) { _projectLoggingContext = projectLoggingContext; _target = target; this.BuildEventContext = LoggingService.LogTargetStarted(projectLoggingContext.BuildEventContext, target.Name, projectFullPath, target.Location.File, parentTargetName, buildReason); this.IsValid = true; }