Bug 579138 - Project dependencies are not built in the correct order

Fixing the issue where circular dependencies cause stack overflow.

Change-Id: I4ca87eb4e8ccb82b25f85d1cea04fc0d4ddd60c0
Signed-off-by: Umair Sair <umair_sair@hotmail.com>
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/CommonBuilder.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/CommonBuilder.java
index da7db25..2d6c149 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/CommonBuilder.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/CommonBuilder.java
@@ -23,6 +23,7 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.net.URI;
+import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -104,6 +105,7 @@
 
 	private boolean fBuildErrOccured;
 	private Set<String> builtRefConfigIds = new HashSet<>();
+	private Set<String> scheduledConfigIds = new HashSet<>();
 
 	public CommonBuilder() {
 	}
@@ -438,6 +440,7 @@
 
 		fBuildSet.start(this);
 		builtRefConfigIds.clear();
+		scheduledConfigIds.clear();
 
 		IProject project = getProject();
 
@@ -488,6 +491,7 @@
 			if (status.getSeverity() != IStatus.OK)
 				throw new CoreException(status);
 
+			scheduledConfigIds.add(activeCfg.getId());
 			IConfiguration rcfgs[] = getReferencedConfigs(builders);
 
 			monitor.beginTask("", num + rcfgs.length); //$NON-NLS-1$
@@ -520,6 +524,8 @@
 					build(kind, new CfgBuildInfo(builders[i], isForeground), new SubProgressMonitor(monitor, 1));
 				}
 			}
+
+			scheduledConfigIds.remove(activeCfg.getId());
 		}
 
 		if (isForeground)
@@ -582,6 +588,13 @@
 			IProject project = cfg.getOwner().getProject();
 			fBuildSet.getCfgIdSet(project, true).add(cfg.getId());
 
+			if (scheduledConfigIds.contains(cfg.getId())) {
+				ManagedBuilderCorePlugin.log(new Status(IStatus.WARNING, ManagedBuilderCorePlugin.getUniqueIdentifier(),
+						MessageFormat.format(ManagedMakeMessages.getString("CommonBuilder.circular_dependency"), //$NON-NLS-1$
+								project.getName(), cfg.getName())));
+				continue;
+			}
+
 			if (!builtRefConfigIds.contains(cfg.getId())) {
 				if (VERBOSE) {
 					outputTrace(cfg.getOwner().getProject().getName(),
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties
index f56b381..92cd9a7 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties
@@ -164,6 +164,7 @@
 CommonBuilder.22=Building referenced configurations..
 CommonBuilder.23=Buildfile generation error occurred..
 CommonBuilder.24=Build stopped..
+CommonBuilder.circular_dependency=Circular dependency detected in "Project Properties -> C/C++ General -> Path and Symbols -> References tab" for project {0} <{1}>. Build of dependency aborted to prevent infinite cyclic build.
 ParallelBuilder.missingOutDir=Failed to create output directory {0}
 
 MakeBuilder.buildError=