Browse Source

Fixed compiling projects with project references.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/dotnet4@4243 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 17 years ago
parent
commit
8e1bb69fbb
  1. 1
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  2. 1
      src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/AbstractBuildOptions.cs
  3. 1
      src/Main/Base/Project/Src/Internal/Templates/Project/ProjectDescriptor.cs
  4. 2
      src/Main/Base/Project/Src/Internal/Templates/Project/ProjectTemplate.cs
  5. 2
      src/Main/Base/Project/Src/Project/BuildEngine.cs
  6. 1
      src/Main/Base/Project/Src/Project/CompilableProject.cs
  7. 1
      src/Main/Base/Project/Src/Project/Converter/LanguageConverter.cs
  8. 1
      src/Main/Base/Project/Src/Project/Items/ProjectItem.cs
  9. 91
      src/Main/Base/Project/Src/Project/MSBuildEngine/ParallelMSBuildManager.cs
  10. 213
      src/Main/Base/Project/Src/Project/MSBuildInternals.cs
  11. 1
      src/Main/Base/Project/Src/Project/Solution/Solution.cs
  12. 1
      src/Main/Base/Project/Src/Project/WebReferenceUrl.cs

1
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -55,7 +55,6 @@
<Reference Include="System.Windows.Forms" /> <Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
<Reference Include="Microsoft.Build.Framework" /> <Reference Include="Microsoft.Build.Framework" />
<Reference Include="Microsoft.Build.Engine" />
<Reference Include="Microsoft.Build" /> <Reference Include="Microsoft.Build" />
<Reference Include="WindowsBase"> <Reference Include="WindowsBase">
<RequiredTargetFramework>3.0</RequiredTargetFramework> <RequiredTargetFramework>3.0</RequiredTargetFramework>

1
src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/AbstractBuildOptions.cs

@ -14,7 +14,6 @@ using System.Windows.Forms;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Project; using ICSharpCode.SharpDevelop.Project;
using StringPair = System.Collections.Generic.KeyValuePair<System.String, System.String>; using StringPair = System.Collections.Generic.KeyValuePair<System.String, System.String>;
using MSBuild = Microsoft.Build.BuildEngine;
namespace ICSharpCode.SharpDevelop.Gui.OptionPanels namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
{ {

1
src/Main/Base/Project/Src/Internal/Templates/Project/ProjectDescriptor.cs

@ -15,7 +15,6 @@ using System.Xml;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Project; using ICSharpCode.SharpDevelop.Project;
using Import = System.Collections.Generic.KeyValuePair<System.String, System.String>; using Import = System.Collections.Generic.KeyValuePair<System.String, System.String>;
using MSBuild = Microsoft.Build.BuildEngine;
namespace ICSharpCode.SharpDevelop.Internal.Templates namespace ICSharpCode.SharpDevelop.Internal.Templates
{ {

2
src/Main/Base/Project/Src/Internal/Templates/Project/ProjectTemplate.cs

@ -379,6 +379,8 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates
projectCreateInformation.Solution.Save(); projectCreateInformation.Solution.Save();
ProjectService.OnSolutionCreated(new SolutionEventArgs(projectCreateInformation.Solution)); ProjectService.OnSolutionCreated(new SolutionEventArgs(projectCreateInformation.Solution));
projectCreateInformation.Solution.Dispose(); projectCreateInformation.Solution.Dispose();
} else {
project.Dispose();
} }
return solutionLocation; return solutionLocation;
} else { } else {

2
src/Main/Base/Project/Src/Project/BuildEngine.cs

@ -482,7 +482,7 @@ namespace ICSharpCode.SharpDevelop.Project
void OnBuildFinished(BuildNode node, bool success) void OnBuildFinished(BuildNode node, bool success)
{ {
ICSharpCode.Core.LoggingService.Info("Finished building " + node.project.Name); ICSharpCode.Core.LoggingService.Info("Finished building " + node.project.Name +", success=" + success);
lock (this) { lock (this) {
if (node.buildFinished) { if (node.buildFinished) {
throw new InvalidOperationException("This node already finished building, do not call IBuildFeedbackSink.Done() multiple times!"); throw new InvalidOperationException("This node already finished building, do not call IBuildFeedbackSink.Done() multiple times!");

1
src/Main/Base/Project/Src/Project/CompilableProject.cs

@ -14,7 +14,6 @@ using System.IO;
using System.Linq; using System.Linq;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Debugging; using ICSharpCode.SharpDevelop.Debugging;
using MSBuild = Microsoft.Build.BuildEngine;
namespace ICSharpCode.SharpDevelop.Project namespace ICSharpCode.SharpDevelop.Project
{ {

1
src/Main/Base/Project/Src/Project/Converter/LanguageConverter.cs

@ -18,7 +18,6 @@ using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Ast; using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.PrettyPrinter; using ICSharpCode.NRefactory.PrettyPrinter;
using ICSharpCode.SharpDevelop.Project.Commands; using ICSharpCode.SharpDevelop.Project.Commands;
using MSBuild = Microsoft.Build.BuildEngine;
using ICSharpCode.SharpDevelop.Internal.Templates; using ICSharpCode.SharpDevelop.Internal.Templates;
namespace ICSharpCode.SharpDevelop.Project.Converter namespace ICSharpCode.SharpDevelop.Project.Converter

1
src/Main/Base/Project/Src/Project/Items/ProjectItem.cs

@ -13,7 +13,6 @@ using System.Linq;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
using Microsoft.Build.BuildEngine;
namespace ICSharpCode.SharpDevelop.Project namespace ICSharpCode.SharpDevelop.Project
{ {

91
src/Main/Base/Project/Src/Project/MSBuildEngine/ParallelMSBuildManager.cs

@ -5,9 +5,10 @@
// <version>$Revision$</version> // <version>$Revision$</version>
// </file> // </file>
using ICSharpCode.Core; using Microsoft.Build.Logging;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using ICSharpCode.Core;
using Microsoft.Build.Execution; using Microsoft.Build.Execution;
using Microsoft.Build.Framework; using Microsoft.Build.Framework;
@ -18,7 +19,14 @@ namespace ICSharpCode.SharpDevelop.Project
/// ///
/// MSBuild only allows a single BuildManager to build at one time, and loggers /// MSBuild only allows a single BuildManager to build at one time, and loggers
/// are specified globally for that BuildManager. /// are specified globally for that BuildManager.
/// This class allows ///
/// This class allows to run multiple indepent builds concurrently. Logging events
/// will be forwarded to the appropriate logger.
///
/// Note: due to MSBuild limitations, all projects being built must be from the same ProjectCollection.
/// SharpDevelop simply uses the predefined ProjectCollection.GlobalProjectCollection.
/// Code accessing that collection (even if indirectly through MSBuild) should lock on
/// MSBuildInternals.GlobalProjectCollectionLock.
/// </summary> /// </summary>
public static class ParallelMSBuildManager public static class ParallelMSBuildManager
{ {
@ -31,8 +39,13 @@ namespace ICSharpCode.SharpDevelop.Project
lock (enableDisableLock) { lock (enableDisableLock) {
if (enableCount == 0) { if (enableCount == 0) {
BuildParameters parameters = new BuildParameters(); BuildParameters parameters = new BuildParameters();
parameters.Loggers = new ILogger[] { new CentralLogger() }; parameters.Loggers = new ILogger[] {
BuildManager.DefaultBuildManager.BeginBuild(parameters); new CentralLogger(),
#if DEBUG
new ConsoleLogger(LoggerVerbosity.Normal),
#endif
};
BuildManager.DefaultBuildManager.BeginBuild(parameters);
} }
enableCount++; enableCount++;
} }
@ -70,8 +83,8 @@ namespace ICSharpCode.SharpDevelop.Project
lock (submissionEventSourceMapping) { lock (submissionEventSourceMapping) {
submissionEventSourceMapping.Add(submission.SubmissionId, eventSource); submissionEventSourceMapping.Add(submission.SubmissionId, eventSource);
} }
// TODO: when will the logger be shut down? RunningBuild build = new RunningBuild(eventSource, logger, callback);
submission.ExecuteAsync(OnComplete, callback); submission.ExecuteAsync(build.OnComplete, null);
return submission; return submission;
} catch (Exception ex) { } catch (Exception ex) {
LoggingService.Warn("Got exception starting build (exception will be rethrown)", ex); LoggingService.Warn("Got exception starting build (exception will be rethrown)", ex);
@ -80,20 +93,39 @@ namespace ICSharpCode.SharpDevelop.Project
} }
} }
static void OnComplete(BuildSubmission submission) sealed class RunningBuild
{ {
DisableBuildEngine(); ILogger logger;
BuildSubmissionCompleteCallback callback;
EventSource eventSource;
lock (submissionEventSourceMapping) { public RunningBuild(EventSource eventSource, ILogger logger, BuildSubmissionCompleteCallback callback)
submissionEventSourceMapping.Remove(submission.SubmissionId); {
this.eventSource = eventSource;
this.logger = logger;
this.callback = callback;
}
internal void OnComplete(BuildSubmission submission)
{
DisableBuildEngine();
lock (submissionEventSourceMapping) {
submissionEventSourceMapping.Remove(submission.SubmissionId);
}
if (submission.BuildResult.Exception != null) {
LoggingService.Error(submission.BuildResult.Exception);
eventSource.ForwardEvent(new BuildErrorEventArgs(null, null, null, 0, 0, 0, 0, submission.BuildResult.Exception.ToString(), null, null));
}
if (logger != null)
logger.Shutdown();
if (callback != null)
callback(submission);
} }
BuildSubmissionCompleteCallback callback = submission.AsyncContext as BuildSubmissionCompleteCallback;
if (callback != null)
callback(submission);
} }
sealed class CentralLogger : INodeLogger, IEventRedirector sealed class CentralLogger : INodeLogger, IEventRedirector
{ {
public void Initialize(IEventSource eventSource, int nodeCount) public void Initialize(IEventSource eventSource, int nodeCount)
{ {
Initialize(eventSource); Initialize(eventSource);
@ -113,20 +145,27 @@ namespace ICSharpCode.SharpDevelop.Project
public void ForwardEvent(Microsoft.Build.Framework.BuildEventArgs e) public void ForwardEvent(Microsoft.Build.Framework.BuildEventArgs e)
{ {
if (e.BuildEventContext == null) { try {
if (e is BuildStartedEventArgs || e is BuildFinishedEventArgs) { if (e.BuildEventContext == null) {
// these two don't have context set, so we cannot forward them if (e is BuildStartedEventArgs || e is BuildFinishedEventArgs) {
// this isn't a problem because we know ourselves when we start/stop a build // these two don't have context set, so we cannot forward them
return; // this isn't a problem because we know ourselves when we start/stop a build
} else { return;
throw new InvalidOperationException("BuildEventContext is null on " + e.ToString()); } else {
throw new InvalidOperationException("BuildEventContext is null on " + e.ToString());
}
} }
EventSource redirector;
lock (submissionEventSourceMapping) {
if (!submissionEventSourceMapping.TryGetValue(e.BuildEventContext.SubmissionId, out redirector)) {
LoggingService.Warn("Could not deliver build event: " + e + ":\n" + e.Message);
}
}
if (redirector != null)
redirector.ForwardEvent(e);
} catch (Exception ex) {
MessageService.ShowError(ex, "Error in build logger");
} }
IEventRedirector redirector;
lock (submissionEventSourceMapping) {
redirector = submissionEventSourceMapping[e.BuildEventContext.SubmissionId];
}
redirector.ForwardEvent(e);
} }
} }
} }

213
src/Main/Base/Project/Src/Project/MSBuildInternals.cs

@ -31,8 +31,10 @@ namespace ICSharpCode.SharpDevelop.Project
public static class MSBuildInternals public static class MSBuildInternals
{ {
/// <summary> /// <summary>
/// MSBuild does not support multi-threading, so every invocation of MSBuild that /// Note: due to MSBuild limitations, all projects being built must be from the same ProjectCollection.
/// runs inside the SharpDevelop process must lock on this object to prevent conflicts. /// SharpDevelop simply uses the predefined ProjectCollection.GlobalProjectCollection.
/// Code accessing that collection (even if indirectly through MSBuild) should lock on
/// MSBuildInternals.GlobalProjectCollectionLock.
/// </summary> /// </summary>
public readonly static object GlobalProjectCollectionLock = new object(); public readonly static object GlobalProjectCollectionLock = new object();
@ -83,60 +85,6 @@ namespace ICSharpCode.SharpDevelop.Project
} }
#endregion #endregion
/*
internal static void EnsureCorrectTempProject(MSBuild.Project baseProject,
string configuration, string platform,
ref MSBuild.Project tempProject)
{
if (configuration == null && platform == null) {
// unload temp project
if (tempProject != null && tempProject != baseProject) {
tempProject.ParentEngine.UnloadAllProjects();
}
tempProject = null;
return;
}
if (configuration == null)
configuration = baseProject.GetEvaluatedProperty("Configuration");
if (platform == null)
platform = baseProject.GetEvaluatedProperty("Platform");
if (tempProject != null
&& tempProject.GetEvaluatedProperty("Configuration") == configuration
&& tempProject.GetEvaluatedProperty("Platform") == platform)
{
// already correct
return;
}
if (baseProject.GetEvaluatedProperty("Configuration") == configuration
&& baseProject.GetEvaluatedProperty("Platform") == platform)
{
tempProject = baseProject;
return;
}
// create new project
// unload old temp project
if (tempProject != null && tempProject != baseProject) {
tempProject.ParentEngine.UnloadAllProjects();
}
try {
MSBuild.Engine engine = CreateEngine();
tempProject = engine.CreateNewProject();
// tell MSBuild the path so that projects containing <Import Project="relativePath" />
// can be loaded
tempProject.FullFileName = baseProject.FullFileName;
MSBuildBasedProject.InitializeMSBuildProject(tempProject);
tempProject.LoadXml(baseProject.Xml);
tempProject.SetProperty("Configuration", configuration);
tempProject.SetProperty("Platform", platform);
} catch (Exception ex) {
ICSharpCode.Core.MessageService.ShowWarning(ex.ToString());
tempProject = baseProject;
}
}
*/
internal static PropertyStorageLocations GetLocationFromCondition(MSBuild.Construction.ProjectElement element) internal static PropertyStorageLocations GetLocationFromCondition(MSBuild.Construction.ProjectElement element)
{ {
while (element != null) { while (element != null) {
@ -190,120 +138,6 @@ namespace ICSharpCode.SharpDevelop.Project
} }
} }
/*
/// <summary>
/// Evaluates the specified condition in the project and specified configuration/platform.
/// WARNING: EvaluateCondition might add a temporary property group and remove it again,
/// which invalidates enumerators over the list of property groups!
/// </summary>
internal static bool EvaluateCondition(MSBuild.Project project,
string configuration, string platform,
string condition,
ref MSBuild.Project tempProject)
{
if (string.IsNullOrEmpty(condition)) {
return true;
}
EnsureCorrectTempProject(project, configuration, platform, ref tempProject);
return EvaluateCondition(tempProject, condition);
}
/// <summary>
/// Evaluates the specified condition in the project.
/// WARNING: EvaluateCondition might add a temporary property group and remove it again,
/// which invalidates enumerators over the list of property groups!
/// </summary>
internal static bool EvaluateCondition(MSBuild.Project project,
string condition)
{
const string propertyName = "MSBuildInternalsEvaluateConditionDummyPropertyName";
MSBuild.BuildPropertyGroup pGroup = project.AddNewPropertyGroup(true);
pGroup.AddNewProperty(propertyName, "ConditionFalse");
pGroup.AddNewProperty(propertyName, "ConditionTrue").Condition = condition;
bool result = project.GetEvaluatedProperty(propertyName) == "ConditionTrue";
project.RemovePropertyGroup(pGroup);
return result;
}
public static MSBuild.BuildProperty GetProperty(MSBuild.BuildPropertyGroup pg, string name)
{
return pg.Cast<MSBuild.BuildProperty>().FirstOrDefault(p => p.Name == name);
}
public static MSBuild.Engine CreateEngine()
{
return new MSBuild.Engine(MSBuild.ToolsetDefinitionLocations.Registry
| MSBuild.ToolsetDefinitionLocations.ConfigurationFile);
}
*/
/*
/// <summary>
/// Removes all &lt;Import&gt; nodes from a project.
/// </summary>
public static void ClearImports(MSBuild.Project project)
{
if (project == null)
throw new ArgumentNullException("project");
XmlElement xmlProject = BeginXmlManipulation(project);
List<XmlNode> nodesToRemove = new List<XmlNode>();
foreach (XmlNode node in xmlProject.ChildNodes) {
if (node.NodeType == XmlNodeType.Element && node.Name == "Import") {
nodesToRemove.Add(node);
}
}
foreach (XmlNode node in nodesToRemove) {
xmlProject.RemoveChild(node);
}
EndXmlManipulation(project);
}
*/
/*
/// <summary>
/// Changes the value of the ProjectPath property on an existing import.
/// Note: this methods causes the project to recreate all imports, so existing import
/// instances might not be affected.
/// </summary>
public static void SetImportProjectPath(MSBuildBasedProject project, MSBuild.Import import,
string newRawPath)
{
if (project == null)
throw new ArgumentNullException("project");
if (import == null)
throw new ArgumentNullException("import");
if (newRawPath == null)
throw new ArgumentNullException("newRawPath");
lock (project.SyncRoot) {
XmlAttribute a = (XmlAttribute)typeof(MSBuild.Import).InvokeMember(
"ProjectPathAttribute",
BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic,
null, import, null
);
a.Value = newRawPath;
EndXmlManipulation(project.MSBuildProject);
}
project.CreateItemsListFromMSBuild();
}
/// <summary>
/// Gets all custom metadata names defined directly on the item, ignoring defaulted metadata entries.
/// </summary>
public static IList<string> GetCustomMetadataNames(MSBuild.BuildItem item)
{
PropertyInfo prop = typeof(MSBuild.BuildItem).GetProperty("ItemDefinitionLibrary", BindingFlags.Instance | BindingFlags.NonPublic);
object oldValue = prop.GetValue(item, null);
prop.SetValue(item, null, null);
IList<string> result = (IList<string>)item.CustomMetadataNames;
prop.SetValue(item, oldValue, null);
return result;
}
*/
internal static void ResolveAssemblyReferences(MSBuildBasedProject baseProject, ReferenceProjectItem[] referenceReplacements) internal static void ResolveAssemblyReferences(MSBuildBasedProject baseProject, ReferenceProjectItem[] referenceReplacements)
{ {
ProjectInstance project = baseProject.CreateProjectInstance(); ProjectInstance project = baseProject.CreateProjectInstance();
@ -368,45 +202,6 @@ namespace ICSharpCode.SharpDevelop.Project
LoggingService.Warn("Unknown item " + originalInclude); LoggingService.Warn("Unknown item " + originalInclude);
} }
} }
/*
var referenceDict = new Dictionary<string, ReferenceProjectItem>();
foreach (ReferenceProjectItem item in references) {
// references could be duplicate, so we cannot use referenceDict.Add or reference.ToDictionary
referenceDict[item.Include] = item;
}
#if DEBUG
//engine.RegisterLogger(new MSBuild.ConsoleLogger(Microsoft.Build.Framework.LoggerVerbosity.Detailed));
#endif
//Environment.CurrentDirectory = Path.GetDirectoryName(tempProject.FullFileName);
lock (MSBuildInternals.InProcessMSBuildLock) {
if (!tempProject.Build("ResolveAssemblyReferences")) {
LoggingService.Warn("ResolveAssemblyReferences exited with error");
return;
}
}
foreach (MSBuild.BuildItem item in tempProject.GetEvaluatedItemsByName("_ResolveAssemblyReferenceResolvedFiles")) {
string originalInclude = item.GetEvaluatedMetadata("OriginalItemSpec");
ReferenceProjectItem reference;
if (referenceDict.TryGetValue(originalInclude, out reference)) {
reference.AssemblyName = new Dom.DomAssemblyName(item.GetEvaluatedMetadata("FusionName"));
//string fullPath = item.GetEvaluatedMetadata("FullPath"); is incorrect for relative paths
string fullPath = FileUtility.GetAbsolutePath(baseProject.Directory, item.GetEvaluatedMetadata("Identity"));
reference.FileName = fullPath;
reference.Redist = item.GetEvaluatedMetadata("Redist");
//LoggingService.Debug("Got information about " + originalInclude + "; fullpath=" + fullPath);
reference.DefaultCopyLocalValue = bool.Parse(item.GetEvaluatedMetadata("CopyLocal"));
} else {
LoggingService.Warn("Unknown item " + originalInclude);
}
}
tempEngine.UnloadAllProjects(); // unload temp project*/
} }
sealed class SimpleErrorLogger : ILogger sealed class SimpleErrorLogger : ILogger

1
src/Main/Base/Project/Src/Project/Solution/Solution.cs

@ -15,7 +15,6 @@ using System.Text.RegularExpressions;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
using MSBuild = Microsoft.Build.BuildEngine;
namespace ICSharpCode.SharpDevelop.Project namespace ICSharpCode.SharpDevelop.Project
{ {

1
src/Main/Base/Project/Src/Project/WebReferenceUrl.cs

@ -11,7 +11,6 @@ using System.IO;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
using Microsoft.Build.BuildEngine;
namespace ICSharpCode.SharpDevelop.Project namespace ICSharpCode.SharpDevelop.Project
{ {

Loading…
Cancel
Save