try {
buildState = BuildState.Started;
- result = BuildDependencies (GetDependencies (), out executeOnErrors);
- if (!result && executeOnErrors)
- ExecuteOnErrors ();
-
- if (result)
- // deps built fine, do main build
- result = DoBuild (out executeOnErrors);
+#if NET_4_0
+ result = BuildDependencies (out executeOnErrors) &&
+ BuildBeforeThisTargets (out executeOnErrors) &&
+ DoBuild (out executeOnErrors) && // deps & Before targets built fine, do main build
+ BuildAfterThisTargets (out executeOnErrors);
+#else
+ result = BuildDependencies (out executeOnErrors) && DoBuild (out executeOnErrors);
+#endif
buildState = BuildState.Finished;
} catch (Exception e) {
return result;
}
- List <Target> GetDependencies ()
+ bool BuildDependencies (out bool executeOnErrors)
{
- List <Target> list = new List <Target> ();
- Target t;
- string [] targetNames;
- Expression deps;
-
- if (DependsOnTargets != String.Empty) {
- deps = new Expression ();
- deps.Parse (DependsOnTargets, ParseOptions.AllowItemsNoMetadataAndSplit);
- targetNames = (string []) deps.ConvertTo (Project, typeof (string []));
- foreach (string dep_name in targetNames) {
- t = project.Targets [dep_name.Trim ()];
- if (t == null)
- throw new InvalidProjectFileException (String.Format (
- "Target '{0}', a dependency of target '{1}', not found.",
- dep_name.Trim (), Name));
- list.Add (t);
- }
- }
- return list;
+ executeOnErrors = false;
+
+ if (String.IsNullOrEmpty (DependsOnTargets))
+ return true;
+
+ var expr = new Expression ();
+ expr.Parse (DependsOnTargets, ParseOptions.AllowItemsNoMetadataAndSplit);
+ string [] targetNames = (string []) expr.ConvertTo (Project, typeof (string []));
+
+ bool result = BuildOtherTargets (targetNames,
+ tname => engine.LogError ("Target '{0}', a dependency of target '{1}', not found.",
+ tname, Name),
+ out executeOnErrors);
+ if (!result && executeOnErrors)
+ ExecuteOnErrors ();
+
+ return result;
+ }
+
+#if NET_4_0
+ bool BuildBeforeThisTargets (out bool executeOnErrors)
+ {
+ executeOnErrors = false;
+ bool result = BuildOtherTargets (BeforeThisTargets, null, out executeOnErrors);
+ if (!result && executeOnErrors)
+ ExecuteOnErrors ();
+
+ return result;
}
- bool BuildDependencies (List <Target> deps, out bool executeOnErrors)
+ bool BuildAfterThisTargets (out bool executeOnErrors)
{
executeOnErrors = false;
- foreach (Target t in deps) {
+ //missing_target handler not required as these are picked from actual target's
+ //"Before/AfterTargets attributes!
+ bool result = BuildOtherTargets (AfterThisTargets, null, out executeOnErrors);
+ if (!result && executeOnErrors)
+ ExecuteOnErrors ();
+
+ return result;
+ }
+#endif
+
+ bool BuildOtherTargets (IEnumerable<string> targetNames, Action<string> missing_target, out bool executeOnErrors)
+ {
+ executeOnErrors = false;
+ if (targetNames == null)
+ // nothing to build
+ return true;
+
+ foreach (string target_name in targetNames) {
+ var t = project.Targets [target_name.Trim ()];
+ if (t == null) {
+ if (missing_target != null)
+ missing_target (target_name);
+ return false;
+ }
+
if (t.BuildState == BuildState.NotStarted)
if (!t.Build (null, out executeOnErrors))
return false;
+
if (t.BuildState == BuildState.Started)
throw new InvalidProjectFileException ("Cycle in target dependencies detected");
}
}
}
+#if NET_4_0
+ internal string BeforeTargets {
+ get { return targetElement.GetAttribute ("BeforeTargets"); }
+ }
+
+ internal string AfterTargets {
+ get { return targetElement.GetAttribute ("AfterTargets"); }
+ }
+
+ internal List<string> BeforeThisTargets { get; set; }
+ internal List<string> AfterThisTargets { get; set; }
+#endif
+
internal List<BuildTask> BuildTasks {
get { return buildTasks; }
}