bool isValidated;
BuildItemGroupCollection itemGroups;
ImportCollection imports;
- string[] initialTargets;
+ List<string> initialTargets;
Dictionary <string, BuildItemGroup> last_item_group_containing;
bool needToReevaluate;
Engine parentEngine;
current_settings = BuildSettings.None;
builtTargetKeys = new List<string> ();
+ initialTargets = new List<string> ();
+ defaultTargets = new string [0];
globalProperties = new BuildPropertyGroup (null, this, null, false);
foreach (BuildProperty bp in parentEngine.GlobalProperties)
return false;
}
- if (!initialTargetsBuilt && initialTargets != null && initialTargets.Length > 0) {
+ if (!initialTargetsBuilt) {
foreach (string target in initialTargets) {
if (!BuildTarget (target.Trim (), targetOutputs))
return false;
if (ParentEngine.DefaultTasksRegistered)
taskDatabase.CopyTasks (ParentEngine.DefaultTasks);
- if (xmlDocument.DocumentElement.GetAttributeNode ("DefaultTargets") != null)
- defaultTargets = xmlDocument.DocumentElement.GetAttribute ("DefaultTargets").Split (';');
- else
- defaultTargets = new string [0];
-
- ProcessProjectAttributes (xmlDocument.DocumentElement.Attributes);
+ initialTargets = new List<string> ();
+ defaultTargets = new string [0];
ProcessElements (xmlDocument.DocumentElement, null);
isDirty = false;
foreach (XmlAttribute attr in attributes) {
switch (attr.Name) {
case "InitialTargets":
- initialTargets = attr.Value.Split (new char [] {';'},
- StringSplitOptions.RemoveEmptyEntries);
+ initialTargets.AddRange (attr.Value.Split (
+ new char [] {';', ' '},
+ StringSplitOptions.RemoveEmptyEntries));
break;
case "DefaultTargets":
- defaultTargets = attr.Value.Split (new char [] {';'},
+ // first non-empty DefaultTargets found is used
+ if (defaultTargets == null || defaultTargets.Length == 0)
+ defaultTargets = attr.Value.Split (new char [] {';', ' '},
StringSplitOptions.RemoveEmptyEntries);
break;
}
internal void ProcessElements (XmlElement rootElement, ImportedProject ip)
{
+ ProcessProjectAttributes (rootElement.Attributes);
foreach (XmlNode xn in rootElement.ChildNodes) {
if (xn is XmlElement) {
XmlElement xe = (XmlElement) xn;
public string DefaultTargets {
get {
- return xmlDocument.DocumentElement.GetAttribute ("DefaultTargets");
+ return String.Join ("; ", defaultTargets);
}
set {
xmlDocument.DocumentElement.SetAttribute ("DefaultTargets", value);
- defaultTargets = value.Split (new char [] {';'}, StringSplitOptions.RemoveEmptyEntries);
+ if (value != null)
+ defaultTargets = value.Split (new char [] {';', ' '},
+ StringSplitOptions.RemoveEmptyEntries);
}
}
public string InitialTargets {
get {
- return xmlDocument.DocumentElement.GetAttribute ("InitialTargets");
+ return String.Join ("; ", initialTargets.ToArray ());
}
set {
+ initialTargets.Clear ();
xmlDocument.DocumentElement.SetAttribute ("InitialTargets", value);
- initialTargets = value.Split (new char [] {';'}, StringSplitOptions.RemoveEmptyEntries);
+ if (value != null)
+ initialTargets.AddRange (value.Split (
+ new char [] {';', ' '}, StringSplitOptions.RemoveEmptyEntries));
}
}
try {
Assert.IsTrue (project.Build (), "Build failed");
- Assert.AreEqual (0, logger.CheckHead ("Executing pre target", MessageImportance.Normal), "A1");
- Assert.AreEqual (0, logger.CheckHead ("Executing boo target", MessageImportance.Normal), "A2");
- Assert.AreEqual (0, logger.Count, "A3");
+ logger.CheckLoggedMessageHead ("Executing pre target", "A1");
+ logger.CheckLoggedMessageHead ("Executing boo target", "A2");
+
+ Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
+ } catch {
+ logger.DumpMessages ();
+ throw;
+ }
+ }
+
+ [Test]
+ public void TestInitialTargetsWithImports () {
+ Engine engine = new Engine (Consts.BinPath);
+ Project project = engine.CreateNewProject ();
+
+ string second = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" InitialTargets=""One "">
+ <Target Name=""One"">
+ <Message Text='Executing Second::One target'/>
+ </Target>
+ <Import Project='third.proj'/>
+ </Project>
+";
+ using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "second.proj")))) {
+ sw.Write (second);
+ }
+
+ string third = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" InitialTargets=""Two"">
+ <Target Name=""Two"">
+ <Message Text='Executing Third::Two target'/>
+ </Target>
+ </Project>
+";
+ using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "third.proj")))) {
+ sw.Write (third);
+ }
+
+
+ project.LoadXml (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" InitialTargets=""pre"">
+ <Target Name=""boo"">
+ <Message Text=""Executing boo target""/>
+ </Target>
+ <Target Name=""pre"">
+ <Message Text=""Executing pre target""/>
+ </Target>
+ <Import Project='Test/resources/second.proj'/>
+ </Project>");
+
+ MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+ new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+ engine.RegisterLogger (logger);
+
+ try {
+ Assert.IsTrue (project.Build (), "Build failed");
+
+ logger.CheckLoggedMessageHead ("Executing pre target", "A1");
+ logger.CheckLoggedMessageHead ("Executing Second::One target", "A2");
+ logger.CheckLoggedMessageHead ("Executing Third::Two target", "A3");
+ logger.CheckLoggedMessageHead ("Executing boo target", "A4");
+ Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
+
+ Assert.AreEqual ("pre; One; Two", project.InitialTargets, "List of initial targets");
+ } catch {
+ logger.DumpMessages ();
+ throw;
+ }
+ }
+
+ [Test]
+ public void TestDefaultTargets () {
+ Engine engine = new Engine (Consts.BinPath);
+ Project project = engine.CreateNewProject ();
+
+ project.LoadXml (@"<Project DefaultTargets='pre' xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" >
+ <Target Name=""boo"">
+ <Message Text=""Executing boo target""/>
+ </Target>
+ <Target Name=""pre"">
+ <Message Text=""Executing pre target""/>
+ </Target>
+ </Project>");
+
+ MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+ new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+ engine.RegisterLogger (logger);
+
+ try {
+ Assert.IsTrue (project.Build (), "Build failed");
+
+ logger.CheckLoggedMessageHead ("Executing pre target", "A1");
+ Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
+
+ Assert.AreEqual ("pre", project.DefaultTargets, "Default targets");
+ } catch {
+ logger.DumpMessages ();
+ throw;
+ }
+ }
+
+
+ [Test]
+ public void TestDefaultTargetsWithImports () {
+ Engine engine = new Engine (Consts.BinPath);
+ Project project = engine.CreateNewProject ();
+
+ string second = @"<Project DefaultTargets='One' xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <Target Name=""One"">
+ <Message Text='Executing Second::One target'/>
+ </Target>
+ </Project>";
+ using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "second.proj")))) {
+ sw.Write (second);
+ }
+
+ project.LoadXml (@"<Project DefaultTargets='pre' xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" >
+ <Target Name=""boo"">
+ <Message Text=""Executing boo target""/>
+ </Target>
+ <Target Name=""pre"">
+ <Message Text=""Executing pre target""/>
+ </Target>
+ <Import Project='Test/resources/second.proj'/>
+ </Project>");
+
+ MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+ new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+ engine.RegisterLogger (logger);
+
+ try {
+ Assert.IsTrue (project.Build (), "Build failed");
+
+ logger.CheckLoggedMessageHead ("Executing pre target", "A1");
+ Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
+
+ Assert.AreEqual ("pre", project.DefaultTargets, "Default targets");
+ } catch {
+ logger.DumpMessages ();
+ throw;
+ }
+ }
+
+ [Test]
+ public void TestNoDefaultTargetsWithImports () {
+ Engine engine = new Engine (Consts.BinPath);
+ Project project = engine.CreateNewProject ();
+
+
+ string second = @"<Project DefaultTargets='; One ; Two' xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <Target Name=""One"">
+ <Message Text='Executing Second::One target'/>
+ </Target>
+ <Target Name=""Two"">
+ <Message Text='Executing Second::Two target'/>
+ </Target>
+
+ </Project>";
+ using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "second.proj")))) {
+ sw.Write (second);
+ }
+
+ project.LoadXml (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" >
+ <Target Name=""boo"">
+ <Message Text=""Executing boo target""/>
+ </Target>
+ <Target Name=""pre"">
+ <Message Text=""Executing pre target""/>
+ </Target>
+ <Import Project='Test/resources/second.proj'/>
+ </Project>");
+
+ MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+ new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+ engine.RegisterLogger (logger);
+
+ try {
+ Assert.IsTrue (project.Build (), "Build failed");
+
+ logger.CheckLoggedMessageHead ("Executing Second::One target", "A1");
+ logger.CheckLoggedMessageHead ("Executing Second::Two target", "A2");
+ Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
+
+ Assert.AreEqual ("One; Two", project.DefaultTargets, "Default targets");
+ } catch {
+ logger.DumpMessages ();
+ throw;
+ }
+ }
+
+ [Test]
+ public void TestNoDefaultTargets () {
+ Engine engine = new Engine (Consts.BinPath);
+ Project project = engine.CreateNewProject ();
+
+ project.LoadXml (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" >
+ <Target Name=""boo"">
+ <Message Text=""Executing boo target""/>
+ </Target>
+ <Target Name=""pre"">
+ <Message Text=""Executing pre target""/>
+ </Target>
+ </Project>");
+
+ MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+ new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+ engine.RegisterLogger (logger);
+
+ try {
+ Assert.IsTrue (project.Build (), "Build failed");
+
+ logger.CheckLoggedMessageHead ("Executing boo target", "A1");
+ Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
+
+ Assert.AreEqual ("", project.DefaultTargets, "Default targets");
} catch {
logger.DumpMessages ();
throw;