var toolset = parameters.GetToolset (toolsVersion);
if (toolset == null)
throw new InvalidOperationException (string.Format ("Toolset version '{0}' was not resolved to valid toolset", toolsVersion));
- event_source.FireMessageRaised (this, new BuildMessageEventArgs (string.Format ("Using Toolset version {0}.", toolsVersion), null, null, MessageImportance.Low));
+ LogMessageEvent (new BuildMessageEventArgs (string.Format ("Using Toolset version {0}.", toolsVersion), null, null, MessageImportance.Low));
var buildTaskFactory = new BuildTaskFactory (BuildTaskDatabase.GetDefaultTaskDatabase (toolset), submission.BuildRequest.ProjectInstance.TaskDatabase);
BuildProject (new InternalBuildArguments () { CheckCancel = checkCancel, Result = result, Project = project, TargetNames = targetNames, GlobalProperties = globalProperties, TargetOutputs = targetOutputs, ToolsVersion = toolsVersion, BuildTaskFactory = buildTaskFactory });
}
try {
var initialPropertiesFormatted = "Initial Properties:\n" + string.Join (Environment.NewLine, project.Properties.OrderBy (p => p.Name).Select (p => string.Format ("{0} = {1}", p.Name, p.EvaluatedValue)).ToArray ());
- event_source.FireMessageRaised (this, new BuildMessageEventArgs (initialPropertiesFormatted, null, null, MessageImportance.Low));
+ LogMessageEvent (new BuildMessageEventArgs (initialPropertiesFormatted, null, null, MessageImportance.Low));
// null targets -> success. empty targets -> success(!)
if (request.TargetNames == null)
BuildTargetByName (targetName, args);
// FIXME: check .NET behavior, whether cancellation always results in failure.
- args.Result.OverallResult = args.CheckCancel () ? BuildResultCode.Failure : args.Result.ResultsByTarget.Select (p => p.Value).Any (r => r.ResultCode == TargetResultCode.Failure) ? BuildResultCode.Failure : BuildResultCode.Success;
+ args.Result.OverallResult = args.CheckCancel () ? BuildResultCode.Failure : args.Result.ResultsByTarget.Any (p => p.Value.ResultCode == TargetResultCode.Failure) ? BuildResultCode.Failure : BuildResultCode.Success;
}
} catch (Exception ex) {
- event_source.FireErrorRaised (this, new BuildErrorEventArgs (null, null, project.FullPath, 0, 0, 0, 0, "Unhandled exception occured during a build", null, null));
- event_source.FireMessageRaised (this, new BuildMessageEventArgs ("Exception details: " + ex, null, null, MessageImportance.Low));
- args.Result.OverallResult = BuildResultCode.Failure;
+ LogErrorEvent (new BuildErrorEventArgs (null, null, project.FullPath, 0, 0, 0, 0, "Unhandled exception occured during a build", null, null));
+ LogMessageEvent (new BuildMessageEventArgs ("Exception details: " + ex, null, null, MessageImportance.Low));
+ throw; // BuildSubmission re-catches this.
} finally {
event_source.FireBuildFinished (this, new BuildFinishedEventArgs ("Build Finished.", null, args.Result.OverallResult == BuildResultCode.Success, DateTime.Now));
}
if (!request.ProjectInstance.Targets.TryGetValue (targetName, out target))
throw new InvalidOperationException (string.Format ("target '{0}' was not found in project '{1}'", targetName, project.FullPath));
else if (!args.Project.EvaluateCondition (target.Condition)) {
- event_source.FireMessageRaised (this, new BuildMessageEventArgs (string.Format ("Target '{0}' was skipped because condition '{1}' wasn't met.", target.Name, target.Condition), null, null, MessageImportance.Low));
+ LogMessageEvent (new BuildMessageEventArgs (string.Format ("Target '{0}' was skipped because condition '{1}' wasn't met.", target.Name, target.Condition), null, null, MessageImportance.Low));
targetResult.Skip ();
} else {
// process DependsOnTargets first.
var inputs = args.Project.GetAllItems (target.Inputs, string.Empty, creator, creator, s => true, (t, s) => {
});
if (!inputs.Any ()) {
- event_source.FireMessageRaised (this, new BuildMessageEventArgs (string.Format ("Target '{0}' was skipped because there is no input.", target.Name), null, null, MessageImportance.Low));
+ LogMessageEvent (new BuildMessageEventArgs (string.Format ("Target '{0}' was skipped because there is no input.", target.Name), null, null, MessageImportance.Low));
skip = true;
} else {
var outputs = args.Project.GetAllItems (target.Outputs, string.Empty, creator, creator, s => true, (t, s) => {
});
var needsUpdates = GetOlderOutputsThanInputs (inputs, outputs).FirstOrDefault ();
if (needsUpdates != null)
- event_source.FireMessageRaised (this, new BuildMessageEventArgs (string.Format ("Target '{0}' needs to be built because new output {1} is needed.", target.Name, needsUpdates.ItemSpec), null, null, MessageImportance.Low));
+ LogMessageEvent (new BuildMessageEventArgs (string.Format ("Target '{0}' needs to be built because new output {1} is needed.", target.Name, needsUpdates.ItemSpec), null, null, MessageImportance.Low));
else {
- event_source.FireMessageRaised (this, new BuildMessageEventArgs (string.Format ("Target '{0}' was skipped because all the outputs are newer than all the inputs.", target.Name), null, null, MessageImportance.Low));
+ LogMessageEvent (new BuildMessageEventArgs (string.Format ("Target '{0}' was skipped because all the outputs are newer than all the inputs.", target.Name), null, null, MessageImportance.Low));
skip = true;
}
}
foreach (var ti in target.Children.OfType<ProjectTaskInstance> ()) {
current_task = ti;
if (!args.Project.EvaluateCondition (ti.Condition)) {
- event_source.FireMessageRaised (this, new BuildMessageEventArgs (string.Format ("Task '{0}' was skipped because condition '{1}' wasn't met.", ti.Name, ti.Condition), null, null, MessageImportance.Low));
+ LogMessageEvent (new BuildMessageEventArgs (string.Format ("Task '{0}' was skipped because condition '{1}' wasn't met.", ti.Name, ti.Condition), null, null, MessageImportance.Low));
continue;
}
if (!RunBuildTask (target, ti, targetResult, args))
factoryIdentityParameters ["MSBuildArchitecture"] = taskInstance.MSBuildArchitecture;
#endif
var task = args.BuildTaskFactory.CreateTask (taskInstance.Name, factoryIdentityParameters, this);
- event_source.FireMessageRaised (this, new BuildMessageEventArgs (string.Format ("Using task {0} from {1}", taskInstance.Name, task.GetType ().AssemblyQualifiedName), null, null, MessageImportance.Low));
+ LogMessageEvent (new BuildMessageEventArgs (string.Format ("Using task {0} from {1}", taskInstance.Name, task.GetType ().AssemblyQualifiedName), null, null, MessageImportance.Low));
task.HostObject = host;
task.BuildEngine = this;
BuildManager = buildManager;
new Thread (RunLoop).Start ();
}
+
+ ~BuildNodeManager ()
+ {
+ run_loop = false;
+ queue_wait_handle.Set ();
+ }
public BuildManager BuildManager { get; private set; }
{
while (run_loop) {
try {
- if (queued_builds.Count == 0) {
+ if (queued_builds.Count == 0)
queue_wait_handle.WaitOne ();
- }
if (!run_loop)
break;
BuildSubmission build;
continue;
StartOneBuild (build);
} catch (Exception ex) {
+ // FIXME: I guess INodeLogger should be used instead.
Console.Error.WriteLine ("Uncaught build node exception occured");
Console.Error.WriteLine (ex);
}
void StartOneBuild (BuildSubmission build)
{
var node = TakeNode (build);
- // FIXME: Task here causes NotImplementedException in somewhere in Interlocked. It does not make sense.
- //ongoing_builds [build] = task_factory.StartNew (node.ExecuteBuild);
- new Thread (() => { node.ExecuteBuild (); }).Start ();
+ // FIXME: Task (non-generic) here causes NotImplementedException in somewhere in Interlocked. It does not make sense.
+ ongoing_builds [build] = task_factory.StartNew (node.ExecuteBuild);
+ //new Thread (() => { node.ExecuteBuild (); }).Start ();
+ }
+
+ void EndOneBuild (BuildNode node)
+ {
+ var task = ongoing_builds [node.Build];
+ ongoing_builds [node.Build] = null;
+ node.Release ();
}
// FIXME: take max nodes into account here, and get throttling working.
Build = build;
}
+ public void Release ()
+ {
+ Build = null;
+ IsAvailable = true;
+ }
+
public BuildResult ExecuteBuild ()
{
- // FIXME: depending on NodeAffinity, build it through another MSBuild process.
- if (Affinity == NodeAffinity.OutOfProc)
- throw new NotImplementedException ();
- return Build.Execute ();
+ BuildResult result;
+ try {
+ // FIXME: depending on NodeAffinity, build it through another MSBuild process.
+ if (Affinity == NodeAffinity.OutOfProc)
+ throw new NotImplementedException ();
+ result = Build.InternalExecute ();
+ } catch (Exception ex) {
+ // FIXME: I guess INodeLogger should be used instead.
+ Console.Error.WriteLine ("Uncaught build node exception occured");
+ Console.Error.WriteLine (ex);
+ result = null;
+ } finally {
+ Manager.EndOneBuild (this);
+ }
+ return result;
}
}
}
var root = ProjectRootElement.Create (xml);
var proj = new ProjectInstance (root);
var bm = new BuildManager ();
- bm.BeginBuild (new BuildParameters () { Loggers = new ILogger [] { new ConsoleLogger () } });
+ bm.BeginBuild (new BuildParameters ());
DateTime waitDone = DateTime.MinValue;
DateTime beforeExec = DateTime.Now;
var l = new List<BuildSubmission> ();
Assert.IsTrue (endBuildDone - beforeExec >= TimeSpan.FromSeconds (1), "#2");
Assert.IsTrue (endBuildDone > waitDone, "#3");
}
+
+ [Test]
+ public void BuildCommonResolveAssemblyReferences ()
+ {
+ string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+ <Import Project='$(MSBuildToolsPath)\Microsoft.Common.targets' />
+ <ItemGroup>
+ <Reference Include='System.Core' />
+ <Reference Include='System.Xml' />
+ </ItemGroup>
+</Project>";
+ var xml = XmlReader.Create (new StringReader (project_xml));
+ var root = ProjectRootElement.Create (xml);
+ root.FullPath = "BuildManagerTest.BuildCommonResolveAssemblyReferences.proj";
+ var proj = new ProjectInstance (root);
+ var manager = new BuildManager ();
+ var parameters = new BuildParameters () { Loggers = new ILogger [] {new ConsoleLogger (LoggerVerbosity.Diagnostic)} };
+ var request = new BuildRequestData (proj, new string [] {"ResolveAssemblyReferences"});
+ var result = manager.Build (parameters, request);
+ var items = result.ResultsByTarget ["ResolveAssemblyReferences"].Items;
+ Assert.AreEqual (2, items.Count (), "#0");
+ Assert.IsTrue (items.Any (i => Path.GetFileName (i.ItemSpec) == "System.Core.dll"), "#1");
+ Assert.IsTrue (items.Any (i => Path.GetFileName (i.ItemSpec) == "System.Xml.dll"), "#2");
+ Assert.IsTrue (File.Exists (items.First (i => Path.GetFileName (i.ItemSpec) == "System.Core.dll").ItemSpec), "#3");
+ Assert.IsTrue (File.Exists (items.First (i => Path.GetFileName (i.ItemSpec) == "System.Xml.dll").ItemSpec), "#4");
+ Assert.AreEqual (BuildResultCode.Success, result.OverallResult, "#5");
+ }
}
}