Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Evoy2004-05-24 19:23:36 -0400
committerSean Evoy2004-05-24 19:23:36 -0400
commitd03b0f48a0f0fcb86fb3f7a25f2f8f8ac67cbe54 (patch)
treeae0f59b59d0472bcae7f49de0123d613a619cb68 /build/org.eclipse.cdt.managedbuilder.core
parent5b7521640179743e3fe1bb59d0b75bab2689d70a (diff)
downloadorg.eclipse.cdt-d03b0f48a0f0fcb86fb3f7a25f2f8f8ac67cbe54.tar.gz
org.eclipse.cdt-d03b0f48a0f0fcb86fb3f7a25f2f8f8ac67cbe54.tar.xz
org.eclipse.cdt-d03b0f48a0f0fcb86fb3f7a25f2f8f8ac67cbe54.zip
Large commit. Two components. The first is to switch all the managed build components over to the new plugin loading scheme. The second is to remove the dependency between the indexer and the build system for dependency calculation. Currently, to make this work, there is a flag that is only available on the 3.x GCC compilers, but I will be addressing that shortly.
Diffstat (limited to 'build/org.eclipse.cdt.managedbuilder.core')
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/plugin.xml2
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/schema/ManagedBuildTools.exsd24
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ITool.java10
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java92
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuilderCorePlugin.java114
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedCProjectNature.java7
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/GeneratedMakefileBuilder.java102
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MakefileGenerator.java1100
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java263
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedMakeMessages.java58
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java19
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionReference.java23
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties20
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Target.java7
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java7
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java11
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/scannerconfig/ManagedBuildCPathEntryContainer.java11
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedBuilderDependencyCalculator.java28
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedBuilderMakefileGenerator.java72
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator.java43
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultIndexerDependencyCalculator.java86
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java1302
22 files changed, 1925 insertions, 1476 deletions
diff --git a/build/org.eclipse.cdt.managedbuilder.core/plugin.xml b/build/org.eclipse.cdt.managedbuilder.core/plugin.xml
index 9b8054bc0af..a2685df62b7 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/plugin.xml
+++ b/build/org.eclipse.cdt.managedbuilder.core/plugin.xml
@@ -15,7 +15,7 @@
<requires>
<import plugin="org.eclipse.cdt.core"/>
<import plugin="org.eclipse.core.resources"/>
- <import plugin="org.eclipse.core.runtime.compatibility"/>
+ <import plugin="org.eclipse.core.runtime"/>
<import plugin="org.eclipse.cdt.make.core"/>
</requires>
diff --git a/build/org.eclipse.cdt.managedbuilder.core/schema/ManagedBuildTools.exsd b/build/org.eclipse.cdt.managedbuilder.core/schema/ManagedBuildTools.exsd
index bd6dfd96a96..03fc3ca5540 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/schema/ManagedBuildTools.exsd
+++ b/build/org.eclipse.cdt.managedbuilder.core/schema/ManagedBuildTools.exsd
@@ -109,7 +109,7 @@
This is an optional field that specifies the class that provides the dependency calculation for a given tool. This field is unused in CDT 1.2.
</documentation>
<appInfo>
- <meta.attribute kind="java" basedOn="org.eclipse.cdt.internal.core.sourcedependency.ISourceDependency"/>
+ <meta.attribute kind="java" basedOn="org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator"/>
</appInfo>
</annotation>
</attribute>
@@ -239,6 +239,16 @@ Additional special types exist to flag options of special relevance to the build
</restriction>
</simpleType>
</attribute>
+ <attribute name="helpSupplier" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java"/>
+ </appInfo>
+ </annotation>
+ </attribute>
</complexType>
</element>
@@ -393,7 +403,7 @@ Additional special types exist to flag options of special relevance to the build
<element name="target">
<annotation>
<documentation>
- Represents a type of resource that is the target of the build process, for example, a Linux Library. A target contains a sequence of tool definitions and configurations. Targets are arranged in an inheritance hierarchy where a target inherits the list of tools from it&apos;s parent and can add to or override tools in this list.
+ Represents a type of resource that is the target of the build process, for example, a Linux static library. A target contains a sequence of tool definitions and configurations. Targets are arranged in an inheritance hierarchy where a target inherits the list of tools from it&apos;s parent and can add to or override tools in this list.
</documentation>
</annotation>
<complexType>
@@ -510,6 +520,16 @@ Additional special types exist to flag options of special relevance to the build
</appInfo>
</annotation>
</attribute>
+ <attribute name="makefileGenerator" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator"/>
+ </appInfo>
+ </annotation>
+ </attribute>
</complexType>
</element>
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ITool.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ITool.java
index c6be9280f37..74764229969 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ITool.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ITool.java
@@ -10,6 +10,8 @@
**********************************************************************/
package org.eclipse.cdt.managedbuilder.core;
+import java.util.List;
+
/**
*
*/
@@ -42,6 +44,14 @@ public interface ITool extends IBuildObject {
public boolean buildsFileType(String extension);
/**
+ * Answers the list of valid source extensions the receiver know how to build.
+ * The list may be empty but will never be <code>null</code>.
+ *
+ * @return List
+ */
+ public List getInputExtensions();
+
+ /**
* Answers a constant corresponding to the project nature the tool should be used
* for. Possible answers are:
*
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java
index cea801d2756..0d0ac6ab330 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java
@@ -41,8 +41,11 @@ import org.eclipse.cdt.core.parser.IScannerInfoProvider;
import org.eclipse.cdt.managedbuilder.internal.core.Configuration;
import org.eclipse.cdt.managedbuilder.internal.core.DefaultManagedConfigElement;
import org.eclipse.cdt.managedbuilder.internal.core.ManagedBuildInfo;
+import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages;
import org.eclipse.cdt.managedbuilder.internal.core.Target;
import org.eclipse.cdt.managedbuilder.internal.core.Tool;
+import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator;
+import org.eclipse.cdt.managedbuilder.scannerconfig.IManagedScannerInfoCollector;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
@@ -50,7 +53,8 @@ import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
-import org.eclipse.core.runtime.IPluginDescriptor;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.PluginVersionIdentifier;
import org.eclipse.core.runtime.QualifiedName;
import org.w3c.dom.Document;
@@ -69,8 +73,8 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
private static final String ROOT_NODE_NAME = "ManagedProjectBuildInfo"; //$NON-NLS-1$
public static final String SETTINGS_FILE_NAME = ".cdtbuild"; //$NON-NLS-1$
private static final ITarget[] emptyTargets = new ITarget[0];
- public static final String INTERFACE_IDENTITY = ManagedBuilderCorePlugin.getUniqueIdentifier() + "." + "ManagedBuildManager"; //$NON-NLS-1$ //$NON-NLS-2$
- public static final String EXTENSION_POINT_ID = "ManagedBuildInfo"; //$NON-NLS-1$
+ public static final String INTERFACE_IDENTITY = ManagedBuilderCorePlugin.getUniqueIdentifier() + ".ManagedBuildManager"; //$NON-NLS-1$
+ public static final String EXTENSION_POINT_ID = ManagedBuilderCorePlugin.getUniqueIdentifier() + ".ManagedBuildInfo"; //$NON-NLS-1$
private static final String REVISION_ELEMENT_NAME = "managedBuildRevision"; //$NON-NLS-1$
private static final String VERSION_ELEMENT_NAME = "fileVersion"; //$NON-NLS-1$
private static final String MANIFEST_VERSION_ERROR ="ManagedBuildManager.error.manifest.version.error"; //$NON-NLS-1$
@@ -236,7 +240,73 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
info.setSelectedTarget(target);
}
}
-
+
+ public static IManagedBuilderMakefileGenerator getMakefileGenerator(String targetId) {
+ try {
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IExtensionPoint extension = registry.getExtensionPoint(EXTENSION_POINT_ID);
+ if (extension != null) {
+ // There could be many of these
+ IExtension[] extensions = extension.getExtensions();
+ for (int i = 0; i < extensions.length; i++) {
+ IConfigurationElement[] configElements = extensions[i].getConfigurationElements();
+ for (int j = 0; j < configElements.length; j++) {
+ IConfigurationElement element = configElements[j];
+ if (element.getName().equals(ITarget.TARGET_ELEMENT_NAME)) {
+ if (element.getAttribute(ITarget.ID).equals(targetId)) {
+ if (element.getAttribute(ManagedBuilderCorePlugin.MAKEGEN_ID) != null) {
+ return (IManagedBuilderMakefileGenerator) element.createExecutableExtension(ManagedBuilderCorePlugin.MAKEGEN_ID);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (CoreException e) {
+ // Probably not defined
+ ManagedBuilderCorePlugin.log(e);
+ }
+ return null;
+ }
+
+ /**
+ * Targets may have a scanner collector defined that knows how to discover
+ * built-in compiler defines and includes search paths. Find the scanner
+ * collector implentation for the target specified.
+ *
+ * @param string the unique id of the target to search for
+ * @return an implementation of <code>IManagedScannerInfoCollector</code>
+ */
+ public static IManagedScannerInfoCollector getScannerInfoCollector(String targetId) {
+ try {
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IExtensionPoint extension = registry.getExtensionPoint(EXTENSION_POINT_ID);
+ if (extension != null) {
+ // There could be many of these
+ IExtension[] extensions = extension.getExtensions();
+ for (int i = 0; i < extensions.length; i++) {
+ IConfigurationElement[] configElements = extensions[i].getConfigurationElements();
+ for (int j = 0; j < configElements.length; j++) {
+ IConfigurationElement element = configElements[j];
+ if (element.getName().equals(ITarget.TARGET_ELEMENT_NAME)) {
+ if (element.getAttribute(ITarget.ID).equals(targetId)) {
+ if (element.getAttribute(ManagedBuilderCorePlugin.SCANNER_INFO_ID) != null) {
+ return (IManagedScannerInfoCollector) element.createExecutableExtension(ManagedBuilderCorePlugin.SCANNER_INFO_ID);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (CoreException e) {
+ // Probably not defined
+ ManagedBuilderCorePlugin.log(e);
+ }
+ return null;
+ }
+
/**
* Gets the currently selected target. This is used while the project
* property pages are displayed
@@ -352,6 +422,7 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
}
}
+
/**
* Saves the build information associated with a project and all resources
* in the project to the build info file.
@@ -501,13 +572,13 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
if (resource instanceof IProject) {
// Must be an extension target (why?)
if (owner != null)
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("ManagedBuildManager.error.owner_not_null")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("ManagedBuildManager.error.owner_not_null")); //$NON-NLS-1$
} else {
// Owner must be owned by the project containing this resource
if (owner == null)
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("ManagedBuildManager.error.null_owner")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("ManagedBuildManager.error.null_owner")); //$NON-NLS-1$
if (!owner.equals(resource.getProject()))
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("ManagedBuildManager.error.owner_not_project")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("ManagedBuildManager.error.owner_not_project")); //$NON-NLS-1$
}
// Passed validation so create the target.
@@ -566,7 +637,7 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
fileVersion = rootElement.getNodeValue();
PluginVersionIdentifier version = new PluginVersionIdentifier(fileVersion);
if (!buildInfoVersion.isCompatibleWith(version)) {
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString(PROJECT_VERSION_ERROR));
+ throw new BuildException(ManagedMakeMessages.getResourceString(PROJECT_VERSION_ERROR));
}
if (buildInfoVersion.isGreaterThan(version)) {
// TODO Upgrade the project
@@ -599,8 +670,7 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
return;
// Get those extensions
- IPluginDescriptor descriptor = ManagedBuilderCorePlugin.getDefault().getDescriptor();
- IExtensionPoint extensionPoint = descriptor.getExtensionPoint(EXTENSION_POINT_ID);
+ IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(EXTENSION_POINT_ID);
IExtension[] extensions = extensionPoint.getExtensions();
// First call the constructors
@@ -609,7 +679,7 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
// Can we read this manifest
if (!isVersionCompatible(extension)) {
//The version of the Plug-in is greater than what the manager thinks it understands
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString(MANIFEST_VERSION_ERROR));
+ throw new BuildException(ManagedMakeMessages.getResourceString(MANIFEST_VERSION_ERROR));
}
IConfigurationElement[] elements = extension.getConfigurationElements();
loadConfigElements(DefaultManagedConfigElement.convertArray(elements));
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuilderCorePlugin.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuilderCorePlugin.java
index 5b2330314de..66fda3f3885 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuilderCorePlugin.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuilderCorePlugin.java
@@ -11,108 +11,64 @@ package org.eclipse.cdt.managedbuilder.core;
* IBM Rational Software - Initial API and implementation
* **********************************************************************/
-import java.text.MessageFormat;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
+import java.lang.reflect.InvocationTargetException;
-import org.eclipse.cdt.managedbuilder.scannerconfig.IManagedScannerInfoCollector;
+import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.IExtension;
-import org.eclipse.core.runtime.IExtensionPoint;
-import org.eclipse.core.runtime.IPluginDescriptor;
+import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
public class ManagedBuilderCorePlugin extends Plugin {
+ private static final String PLUGIN_ID = "org.eclipse.cdt.managedbuilder.core"; //$NON-NLS-1$
+ // The attribute name for the dependency calculator
+ public static final String DEP_CALC_ID ="dependencyCalculator"; //$NON-NLS-1$
//The shared instance.
private static ManagedBuilderCorePlugin plugin;
- //Resource bundle.
- private static ResourceBundle resourceBundle;
-
+ // The attribute name for the scanner info collector
+ public static final String SCANNER_INFO_ID = "scannerInfoCollector"; //$NON-NLS-1$
+ // The attribute name for the makefile generator
+ public static final String MAKEGEN_ID ="makefileGenerator"; //$NON-NLS-1$
+
/**
* @param descriptor
*/
- public ManagedBuilderCorePlugin(IPluginDescriptor descriptor) {
- super(descriptor);
+ public ManagedBuilderCorePlugin() {
+ super();
plugin = this;
- try {
- resourceBundle = ResourceBundle.getBundle("org.eclipse.cdt.managedbuilder.internal.core.PluginResources"); //$NON-NLS-1$
- } catch (MissingResourceException x) {
- resourceBundle = null;
- }
- }
-
- /**
- * Returns the shared instance.
- */
- public static ManagedBuilderCorePlugin getDefault() {
- return plugin;
- }
-
-
- public static String getResourceString(String key) {
- try {
- return resourceBundle.getString(key);
- } catch (MissingResourceException e) {
- return "!" + key + "!"; //$NON-NLS-1$ //$NON-NLS-2$
- } catch (NullPointerException e) {
- return "#" + key + "#"; //$NON-NLS-1$ //$NON-NLS-2$
- }
- }
-
- public static String getFormattedString(String key, String arg) {
- return MessageFormat.format(getResourceString(key), new String[] { arg });
- }
-
- public static String getFormattedString(String key, String[] args) {
- return MessageFormat.format(getResourceString(key), args);
}
- /**
- * Convenience method which returns the unique identifier of this plugin.
- */
public static String getUniqueIdentifier() {
if (getDefault() == null) {
// If the default instance is not yet initialized,
// return a static identifier. This identifier must
// match the plugin id defined in plugin.xml
- return "org.eclipse.cdt.managedbuilder.core"; //$NON-NLS-1$
+ return PLUGIN_ID;
}
- return getDefault().getDescriptor().getUniqueIdentifier();
+ return getDefault().getBundle().getSymbolicName();
}
-
+
/**
- * Targets may have a scanner collector defined that knows how to discover
- * built-in compiler defines and includes search paths. Find the scanner
- * collector implentation for the target specified.
- *
- * @param string the unique id of the target to search for
- * @return an implementation of <code>IManagedScannerInfoCollector</code>
+ * Returns the shared instance.
*/
- public IManagedScannerInfoCollector getScannerInfoCollector(String targetId) {
- try {
- IExtensionPoint extension = getDescriptor().getExtensionPoint(ManagedBuildManager.EXTENSION_POINT_ID);
- if (extension != null) {
- // There could be many of these
- IExtension[] extensions = extension.getExtensions();
- for (int i = 0; i < extensions.length; i++) {
- IConfigurationElement[] configElements = extensions[i].getConfigurationElements();
- for (int j = 0; j < configElements.length; j++) {
- IConfigurationElement element = configElements[j];
- if (element.getName().equals("target")) { //$NON-NLS-1$
- if (element.getAttribute(ITarget.ID).equals(targetId)) {
- return (IManagedScannerInfoCollector) element.createExecutableExtension("scannerInfoCollector"); //$NON-NLS-1$
- }
- }
- }
- }
- }
- }
- catch (CoreException e) {
- // Probably not defined
- }
- return null;
+ public static ManagedBuilderCorePlugin getDefault() {
+ return plugin;
+ }
+
+ public static void log(Throwable e) {
+ if (e instanceof InvocationTargetException)
+ e = ((InvocationTargetException) e).getTargetException();
+ IStatus status = null;
+ if (e instanceof CoreException)
+ status = ((CoreException) e).getStatus();
+ else
+ status = new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.OK, e.getMessage(), e);
+ log(status);
+ }
+
+ public static void log(IStatus status) {
+ ResourcesPlugin.getPlugin().getLog().log(status);
}
}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedCProjectNature.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedCProjectNature.java
index 4d04c6c8352..44d18723ca8 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedCProjectNature.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedCProjectNature.java
@@ -21,8 +21,8 @@ import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IProjectNature;
import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPluginDescriptor;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
public class ManagedCProjectNature implements IProjectNature {
@@ -110,9 +110,8 @@ public class ManagedCProjectNature implements IProjectNature {
*/
public static String getBuilderID() {
Plugin plugin = (Plugin)ManagedBuilderCorePlugin.getDefault();
- IPluginDescriptor descriptor = plugin.getDescriptor();
- if (descriptor.getExtension(BUILDER_NAME) != null) {
- return descriptor.getUniqueIdentifier() + "." + BUILDER_NAME; //$NON-NLS-1$
+ if (Platform.getExtensionRegistry().getExtension(BUILDER_NAME) != null) {
+ return ManagedBuilderCorePlugin.getUniqueIdentifier() + "." + BUILDER_NAME; //$NON-NLS-1$
}
return BUILDER_ID;
}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/GeneratedMakefileBuilder.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/GeneratedMakefileBuilder.java
index be83f61b6db..2174ef0fee6 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/GeneratedMakefileBuilder.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/GeneratedMakefileBuilder.java
@@ -28,8 +28,11 @@ import org.eclipse.cdt.core.model.ICModelMarker;
import org.eclipse.cdt.core.resources.ACBuilder;
import org.eclipse.cdt.core.resources.IConsole;
import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
+import org.eclipse.cdt.managedbuilder.core.ITool;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
+import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator;
+import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
@@ -39,11 +42,15 @@ import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubProgressMonitor;
public class GeneratedMakefileBuilder extends ACBuilder {
@@ -65,7 +72,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
// Local variables
protected List resourcesToBuild;
protected List ruleList;
-
+ protected IManagedBuilderMakefileGenerator generator;
public class ResourceDeltaVisitor implements IResourceDeltaVisitor {
private boolean buildNeeded = false;
@@ -96,7 +103,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
* @see org.eclipse.core.internal.events.InternalBuilder#build(int, java.util.Map, org.eclipse.core.runtime.IProgressMonitor)
*/
protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException {
- String statusMsg = ManagedBuilderCorePlugin.getFormattedString(START, getProject().getName());
+ String statusMsg = ManagedMakeMessages.getFormattedString(START, getProject().getName());
IProject[] deps = getProject().getReferencedProjects();
if (statusMsg != null) {
monitor.subTask(statusMsg);
@@ -171,7 +178,9 @@ public class GeneratedMakefileBuilder extends ACBuilder {
IProject depProject = deps[i];
if (ManagedBuildManager.manages(depProject)) {
IManagedBuildInfo depInfo = ManagedBuildManager.getBuildInfo(depProject);
- MakefileGenerator generator = new MakefileGenerator(depProject, depInfo, monitor);
+ String targetID = depInfo.getDefaultTarget().getParent().getId();
+ IManagedBuilderMakefileGenerator generator = ManagedBuildManager.getMakefileGenerator(targetID);
+ generator.initialize(depProject, depInfo, monitor);
try {
generator.regenerateMakefiles();
} catch (CoreException e) {
@@ -182,11 +191,13 @@ public class GeneratedMakefileBuilder extends ACBuilder {
}
// Need to report status to the user
- String statusMsg = ManagedBuilderCorePlugin.getFormattedString(REBUILD, getProject().getName());
+ String statusMsg = ManagedMakeMessages.getFormattedString(REBUILD, getProject().getName());
monitor.subTask(statusMsg);
// Regenerate the makefiles for this project
- MakefileGenerator generator = new MakefileGenerator(getProject(), info, monitor);
+ String targetID = info.getDefaultTarget().getParent().getId();
+ generator = ManagedBuildManager.getMakefileGenerator(targetID);
+ generator.initialize(getProject(), info, monitor);
try {
generator.regenerateMakefiles();
} catch (CoreException e) {
@@ -195,14 +206,53 @@ public class GeneratedMakefileBuilder extends ACBuilder {
}
// Now call make
- IPath topBuildDir = generator.getTopBuildDir();
+ IPath topBuildDir = generator.getBuildWorkingDir();
if (topBuildDir != null) {
- invokeMake(true, topBuildDir.removeFirstSegments(1), info, monitor);
+ invokeMake(true, topBuildDir, info, monitor);
} else {
monitor.done();
}
+
+ // Now regenerate the dependencies
+ try {
+ generator.regenerateDependencies(false);
+ } catch (CoreException e) {
+ // Throw the exception back to the builder
+ throw e;
+ }
+
}
+ /**
+ * @param toolId
+ * @return
+ */
+ public IManagedBuilderDependencyCalculator getDependencyCalculator(String toolId) {
+ try {
+ IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(ManagedBuilderCorePlugin.getUniqueIdentifier(), ManagedBuilderCorePlugin.DEP_CALC_ID);
+ if (extension != null) {
+ // There could be many of these
+ IExtension[] extensions = extension.getExtensions();
+ for (int i = 0; i < extensions.length; i++) {
+ IConfigurationElement[] configElements = extensions[i].getConfigurationElements();
+ for (int j = 0; j < configElements.length; j++) {
+ IConfigurationElement element = configElements[j];
+ if (element.getName().equals(ITool.TOOL_ELEMENT_NAME)) {
+ if (element.getAttribute(ITool.ID).equals(toolId)) {
+ if (element.getAttribute(ManagedBuilderCorePlugin.DEP_CALC_ID) != null) {
+ return (IManagedBuilderDependencyCalculator) element.createExecutableExtension(ManagedBuilderCorePlugin.DEP_CALC_ID);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (CoreException e) {
+ // Probably not defined
+ }
+ return null;
+ }
/* (non-javadoc)
* Answers an array of strings with the proper make targets
*
@@ -262,7 +312,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
if (monitor == null) {
monitor = new NullProgressMonitor();
}
- statusMsg = ManagedBuilderCorePlugin.getFormattedString(INCREMENTAL, getProject().getName());
+ statusMsg = ManagedMakeMessages.getFormattedString(INCREMENTAL, getProject().getName());
monitor.subTask(statusMsg);
// Regenerate the makefiles for any managed projects this project depends on
@@ -271,7 +321,9 @@ public class GeneratedMakefileBuilder extends ACBuilder {
IProject depProject = deps[i];
if (ManagedBuildManager.manages(depProject)) {
IManagedBuildInfo depInfo = ManagedBuildManager.getBuildInfo(depProject);
- MakefileGenerator generator = new MakefileGenerator(depProject, depInfo, monitor);
+ String targetID = depInfo.getDefaultTarget().getParent().getId();
+ IManagedBuilderMakefileGenerator generator = ManagedBuildManager.getMakefileGenerator(targetID);
+ generator.initialize(depProject, depInfo, monitor);
try {
generator.regenerateMakefiles();
} catch (CoreException e) {
@@ -282,7 +334,9 @@ public class GeneratedMakefileBuilder extends ACBuilder {
}
// Ask the makefile generator to generate any makefiles needed to build delta
- MakefileGenerator generator = new MakefileGenerator(getProject(), info, monitor);
+ String targetID = info.getDefaultTarget().getParent().getId();
+ generator = ManagedBuildManager.getMakefileGenerator(targetID);
+ generator.initialize(getProject(), info, monitor);
try {
generator.generateMakefiles(delta);
} catch (CoreException e) {
@@ -319,7 +373,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
if (root == null) {
return;
}
- IPath makefile = workingDirectory.addTrailingSeparator().append(MakefileGenerator.MAKEFILE_NAME);
+ IPath makefile = workingDirectory.addTrailingSeparator().append(generator.getMakefileName());
if (root.getFileForLocation(makefile) == null) {
return;
}
@@ -330,7 +384,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
String[] msgs = new String[2];
msgs[0] = makeCommand.toString();
msgs[1] = currentProject.getName();
- monitor.beginTask(ManagedBuilderCorePlugin.getFormattedString(MAKE, msgs), IProgressMonitor.UNKNOWN);
+ monitor.beginTask(ManagedMakeMessages.getFormattedString(MAKE, msgs), IProgressMonitor.UNKNOWN);
// Get a build console for the project
StringBuffer buf = new StringBuffer();
@@ -339,14 +393,14 @@ public class GeneratedMakefileBuilder extends ACBuilder {
ConsoleOutputStream consoleOutStream = console.getOutputStream();
String[] consoleHeader = new String[3];
consoleHeader[0] = fullBuild ?
- ManagedBuilderCorePlugin.getResourceString(TYPE_FULL) :
- ManagedBuilderCorePlugin.getResourceString(TYPE_INC);
+ ManagedMakeMessages.getResourceString(TYPE_FULL) :
+ ManagedMakeMessages.getResourceString(TYPE_INC);
consoleHeader[1] = info.getConfigurationName();
consoleHeader[2] = currentProject.getName();
- buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$
- buf.append(ManagedBuilderCorePlugin.getFormattedString(CONSOLE_HEADER, consoleHeader));
- buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$
- buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$
+ buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$
+ buf.append(ManagedMakeMessages.getFormattedString(CONSOLE_HEADER, consoleHeader));
+ buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$
+ buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$
consoleOutStream.write(buf.toString().getBytes());
consoleOutStream.flush();
@@ -392,7 +446,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
// Hook up an error parser manager
String[] errorParsers = info.getDefaultTarget().getErrorParserList();
- ErrorParserManager epm = new ErrorParserManager(getProject(), this, errorParsers);
+ ErrorParserManager epm = new ErrorParserManager(getProject(), workingDirectory, this, errorParsers);
epm.setOutputStream(consoleOutStream);
OutputStream stdout = epm.getOutputStream();
OutputStream stderr = epm.getOutputStream();
@@ -413,7 +467,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
// Force a resync of the projects without allowing the user to cancel.
// This is probably unkind, but short of this there is no way to insure
// the UI is up-to-date with the build results
- monitor.subTask(ManagedBuilderCorePlugin.getResourceString(REFRESH));
+ monitor.subTask(ManagedMakeMessages.getResourceString(REFRESH));
try {
currentProject.refreshLocal(IResource.DEPTH_INFINITE, null);
for (int j = 0; j < deps.length; ++j) {
@@ -421,7 +475,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
project.refreshLocal(IResource.DEPTH_INFINITE, null);
}
} catch (CoreException e) {
- monitor.subTask(ManagedBuilderCorePlugin.getResourceString(REFRESH_ERROR));
+ monitor.subTask(ManagedMakeMessages.getResourceString(REFRESH_ERROR));
}
} else {
errMsg = launcher.getErrorMessage();
@@ -430,13 +484,13 @@ public class GeneratedMakefileBuilder extends ACBuilder {
// Report either the success or failure of our mission
buf = new StringBuffer();
if (errMsg != null && errMsg.length() > 0) {
- String errorDesc = ManagedBuilderCorePlugin.getResourceString(BUILD_ERROR);
+ String errorDesc = ManagedMakeMessages.getResourceString(BUILD_ERROR);
buf.append(errorDesc);
buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$
buf.append("(").append(errMsg).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
} else {
// Report a successful build
- String successMsg = ManagedBuilderCorePlugin.getFormattedString(BUILD_FINISHED, currentProject.getName());
+ String successMsg = ManagedMakeMessages.getFormattedString(BUILD_FINISHED, currentProject.getName());
buf.append(successMsg);
buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$
}
@@ -447,7 +501,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
stdout.close();
stderr.close();
- monitor.subTask(ManagedBuilderCorePlugin.getResourceString(MARKERS));
+ monitor.subTask(ManagedMakeMessages.getResourceString(MARKERS));
epm.reportProblems();
}
} catch (Exception e) {
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MakefileGenerator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MakefileGenerator.java
deleted file mode 100644
index 072e6346828..00000000000
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MakefileGenerator.java
+++ /dev/null
@@ -1,1100 +0,0 @@
-package org.eclipse.cdt.managedbuilder.internal.core;
-
-/**********************************************************************
- * Copyright (c) 2003,2004 Rational Software Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
- *
- * Contributors:
- * IBM Rational Software - Initial API and implementation
- * **********************************************************************/
-
-import java.io.ByteArrayInputStream;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-
-import org.eclipse.cdt.core.CCorePlugin;
-import org.eclipse.cdt.core.search.ICSearchConstants;
-import org.eclipse.cdt.core.search.ICSearchScope;
-import org.eclipse.cdt.core.search.SearchEngine;
-import org.eclipse.cdt.internal.core.model.Util;
-import org.eclipse.cdt.internal.core.search.PathCollector;
-import org.eclipse.cdt.internal.core.search.PatternSearchJob;
-import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
-import org.eclipse.cdt.internal.core.search.matching.CSearchPattern;
-import org.eclipse.cdt.internal.core.sourcedependency.DependencyQueryJob;
-import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
-import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
-import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.resources.IResourceDeltaVisitor;
-import org.eclipse.core.resources.IResourceProxy;
-import org.eclipse.core.resources.IResourceProxyVisitor;
-import org.eclipse.core.resources.IResourceStatus;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.OperationCanceledException;
-import org.eclipse.core.runtime.Path;
-
-public class MakefileGenerator {
-
- // this is used to draw a "comment line"
- private static final int COLS_PER_LINE = 80;
-
- // String constants for messages
- private static final String MESSAGE = "ManagedMakeBuilder.message"; //$NON-NLS-1$
- private static final String BUILD_ERROR = MESSAGE + ".error"; //$NON-NLS-1$
- private static final String COMMENT = "ManagedMakeBuilder.comment"; //$NON-NLS-1$
- private static final String HEADER = COMMENT + ".header"; //$NON-NLS-1$
- private static final String MOD_LIST = COMMENT + ".module.list"; //$NON-NLS-1$
- private static final String SRC_LISTS = COMMENT + ".source.list"; //$NON-NLS-1$
- private static final String MOD_RULES = COMMENT + ".build.rule"; //$NON-NLS-1$
- private static final String MOD_INCL = COMMENT + ".module.make.includes"; //$NON-NLS-1$
- private static final String DEP_INCL = COMMENT + ".module.dep.includes"; //$NON-NLS-1$
- private static final String AUTO_DEP = COMMENT + ".autodeps"; //$NON-NLS-1$
-
- // String constants for makefile contents
- protected static final String COLON = ":"; //$NON-NLS-1$
- protected static final String DEPFILE_NAME = "subdir.dep"; //$NON-NLS-1$
- protected static final String DOT = "."; //$NON-NLS-1$
- protected static final String MAKEFILE_NAME = "makefile"; //$NON-NLS-1$
- protected static final String MODFILE_NAME = "subdir.mk"; //$NON-NLS-1$
- protected static final String LINEBREAK = "\\"; //$NON-NLS-1$
- protected static final String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$
- protected static final String LOGICAL_AND = "&&"; //$NON-NLS-1$
- protected static final String SEPARATOR = "/"; //$NON-NLS-1$
- protected static final String TAB = "\t"; //$NON-NLS-1$
- protected static final String WHITESPACE = " "; //$NON-NLS-1$
- protected static final String WILDCARD = "%"; //$NON-NLS-1$
- protected static final String COMMENT_SYMBOL = "#"; //$NON-NLS-1$
- protected static final String MAKEFILE_INIT = "makefile.init"; //$NON-NLS-1$
- protected static final String MAKEFILE_DEFS = "makefile.defs"; //$NON-NLS-1$
- protected static final String MAKEFILE_TARGETS = "makefile.targets"; //$NON-NLS-1$
-
- // Local variables needed by generator
- protected IManagedBuildInfo info;
- protected List modifiedList;
- protected IProgressMonitor monitor;
- protected List subdirList;
- protected IProject project;
- protected List ruleList;
- protected IPath topBuildDir;
- private String target;
- private String extension;
-
- /**
- * This class is used to recursively walk the project and determine which
- * modules contribute buildable source files.
- */
- protected class ResourceProxyVisitor implements IResourceProxyVisitor {
- private MakefileGenerator generator;
- private IManagedBuildInfo info;
-
- /**
- * Constructs a new resource proxy visitor to quickly visit project
- * resources.
- */
- public ResourceProxyVisitor(MakefileGenerator generator, IManagedBuildInfo info) {
- this.generator = generator;
- this.info = info;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.core.resources.IResourceProxyVisitor#visit(org.eclipse.core.resources.IResourceProxy)
- */
- public boolean visit(IResourceProxy proxy) throws CoreException {
- // No point in proceeding, is there
- if (generator == null) {
- return false;
- }
-
- // Is this a resource we should even consider
- if (proxy.getType() == IResource.FILE) {
- // Check extension to see if build model should build this file
- IResource resource = proxy.requestResource();
- String ext = resource.getFileExtension();
- if (info.buildsFileType(ext)) {
- if (!generator.isGeneratedResource(resource)) {
- generator.appendBuildSubdirectory(resource);
- }
- }
- return false;
- }
-
- // Recurse into subdirectories
- return true;
- }
-
- }
-
- public class ResourceDeltaVisitor implements IResourceDeltaVisitor {
- private MakefileGenerator generator;
- private IManagedBuildInfo info;
-
- /**
- *
- */
- public ResourceDeltaVisitor(MakefileGenerator generator, IManagedBuildInfo info) {
- this.generator = generator;
- this.info = info;
- }
-
- /* (non-javadoc)
- * Answers a list of resource names in the workspace that depend on the resource
- * specified in the argument.
- *
- * @param resource the root of the dependency tree
- * @return IResource[]
- */
- private IResource[] findDependencies(IResource resource) {
- PathCollector pathCollector = new PathCollector();
- ICSearchScope scope = SearchEngine.createWorkspaceScope();
- CSearchPattern pattern = CSearchPattern.createPattern(resource.getLocation().toOSString(), ICSearchConstants.INCLUDE, ICSearchConstants.REFERENCES, ICSearchConstants.EXACT_MATCH, true);
- IndexManager indexManager = CCorePlugin.getDefault().getCoreModel().getIndexManager();
- indexManager.performConcurrentJob(
- new PatternSearchJob(
- (CSearchPattern) pattern,
- scope,
- pathCollector,
- indexManager),
- ICSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
- null, null);
-
- // We will get back an array of resource names relative to the workspace
- String[] deps = pathCollector.getPaths();
-
- // Convert them to something useful
- List depList = new ArrayList();
- IResource res = null;
- IWorkspaceRoot root = null;
- if (generator.project != null) {
- root = generator.project.getWorkspace().getRoot();
- }
- for (int index = 0; index < deps.length; ++index) {
- res = root.findMember(deps[index]);
- if (res != null) {
- depList.add(res);
- }
- }
-
- return (IResource[]) depList.toArray(new IResource[depList.size()]);
- }
-
- private void handleHeaderDependency(IResource resource, boolean moved) {
- // If this is a move and the resource is external to the project, touch that resource
- if (resource.getProject().equals(generator.project)) {
- generator.appendModifiedSubdirectory(resource);
- } else {
- if (moved) {
- try {
- resource.touch(new NullProgressMonitor());
- } catch (CoreException e) {
- }
- }
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta)
- */
- public boolean visit(IResourceDelta delta) throws CoreException {
- // Should the visitor keep iterating in current directory
- boolean keepLooking = false;
- IResource resource = delta.getResource();
-
- // What kind of resource change has occurred
- if (resource.getType() == IResource.FILE) {
- String ext = resource.getFileExtension();
- boolean moved = false;
- switch (delta.getKind()) {
- case IResourceDelta.ADDED:
- moved = delta.getFlags() == IResourceDelta.MOVED_TO;
- if (!generator.isGeneratedResource(resource)) {
- // This is a source file so just add its container
- if (info.buildsFileType(ext)) {
- generator.appendModifiedSubdirectory(resource);
- } else if (info.isHeaderFile(ext)) {
- // Add the container of the resource and any resources that depend on it
- generator.appendModifiedSubdirectory(resource);
- IResource[] deps = findDependencies(resource);
- for (int i = 0; i < deps.length; ++i){
- handleHeaderDependency(deps[i], moved);
- }
- }
- }
- break;
- case IResourceDelta.REMOVED:
- moved = delta.getFlags() == IResourceDelta.MOVED_FROM;
- if (!generator.isGeneratedResource(resource)) {
- // This is a source file so just add its container
- if (info.buildsFileType(ext)) {
- generator.appendModifiedSubdirectory(resource);
- } else if (info.isHeaderFile(ext)) {
- // Add the container of the resource and any resources that depend on it
- generator.appendModifiedSubdirectory(resource);
- IResource[] deps = findDependencies(resource);
- for (int i = 0; i < deps.length; ++i){
- handleHeaderDependency(deps[i], moved);
- }
- }
- }
- break;
- case IResourceDelta.CHANGED:
- if (!generator.isGeneratedResource(resource)) {
- if (info.buildsFileType(ext)) {
- keepLooking = true;
- } else if (info.isHeaderFile(ext)) {
- // Add the container of the resource and any resources that depend on it
- generator.appendModifiedSubdirectory(resource);
- IResource[] deps= findDependencies(resource);
- for (int i = 0; i < deps.length; ++i){
- handleHeaderDependency(deps[i], moved);
- }
- // That does it for this directory, so don't bother to keep looking
- }
- }
- break;
- default:
- keepLooking = true;
- break;
- }
- } if (resource.getType() == IResource.PROJECT) {
- // If there is a zero-length delta, something the project depends on has changed so just call make
- IResourceDelta[] children = delta.getAffectedChildren();
- if (children != null && children.length > 0) {
- keepLooking = true;
- }
- } else {
- // If the resource is part of the generated directory structure don't recurse
- if (!generator.isGeneratedResource(resource)) {
- keepLooking = true;
- }
- }
-
- return keepLooking;
- }
- }
-
- /**
- * @param project
- * @param info
- * @param monitor
- */
- public MakefileGenerator(IProject project, IManagedBuildInfo info, IProgressMonitor monitor) {
- super();
- // Save the project so we can get path and member information
- this.project = project;
- // Save the monitor reference for reporting back to the user
- this.monitor = monitor;
- // Get the build info for the project
- this.info = info;
- // Get the name of the build target
- target = info.getBuildArtifactName();
- // Get its extension
- extension = info.getBuildArtifactExtension();
- if (extension == null) {
- extension = new String();
- }
- }
-
- /* (non-javadoc)
- * Calculates dependencies for all the source files in the argument. A source
- * file can depend on any number of header files, so the dependencies have to
- * be added to its dependency list.
- *
- * @param module
- * @return
- */
- protected StringBuffer addSourceDependencies(IContainer module) throws CoreException {
- // Calculate the new directory relative to the build output
- IPath moduleRelativePath = module.getProjectRelativePath();
- String relativePath = moduleRelativePath.toString();
- relativePath += relativePath.length() == 0 ? "" : SEPARATOR; //$NON-NLS-1$
-
- // Create the buffer to hold the output for the module and a dep calculator
- StringBuffer buffer = new StringBuffer();
- buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedBuilderCorePlugin.getResourceString(AUTO_DEP) + NEWLINE);
- IndexManager indexManager = CCorePlugin.getDefault().getCoreModel().getIndexManager();
-
- /*
- * Visit each resource in the folder that we have a rule to build.
- * The dependency output for each resource will be in the format
- * <relativePath>/<resourceName>.<outputExtension> : <dep1> ... <depn>
- * with long lines broken.
- */
- IResource[] resources = module.members();
- for (int i = 0; i < resources.length; i++) {
- IResource resource = resources[i];
- if (resource.getType() == IResource.FILE) {
- String inputExt = resource.getFileExtension();
- if (info.buildsFileType(inputExt)) {
- // Get the filename without an extension
- String fileName = resource.getFullPath().removeFileExtension().lastSegment();
- if (fileName == null) continue;
- String outputExt = info.getOutputExtension(inputExt);
- if (outputExt != null) {
- fileName += DOT + outputExt;
- }
- // Ask the dep generator to find all the deps for this resource
- ArrayList dependencies = new ArrayList();
- try {
- indexManager.performConcurrentJob(new DependencyQueryJob(project, (IFile)resource, indexManager, dependencies), ICSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, null, null);
- } catch (Exception e) {
- continue;
- }
- if (dependencies.size() == 0) continue;
- buffer.append(relativePath + fileName + COLON + WHITESPACE);
- Iterator iter = dependencies.listIterator();
- while (iter.hasNext()) {
- buffer.append(LINEBREAK + NEWLINE);
- String rawPath = (String)iter.next();
- // TODO Convert to relative if possible
- String path = escapeWhitespaces(rawPath);
- buffer.append(path);
- if (iter.hasNext()) {
- buffer.append(WHITESPACE);
- }
- }
- buffer.append(NEWLINE);
- }
- }
- }
- return buffer;
- }
-
- /* (non-Javadoc)
- * Answers the argument with all whitespaces replaced with an escape sequence.
- *
- * @param path
- */
- private String escapeWhitespaces(String path) {
- // Escape the spaces in the path/filename if it has any
- String[] segments = path.split("\\s"); //$NON-NLS-1$
- if (segments.length > 1) {
- StringBuffer escapedPath = new StringBuffer();
- for (int index = 0; index < segments.length; ++index) {
- escapedPath.append(segments[index]);
- if (index + 1 < segments.length) {
- escapedPath.append("\\ "); //$NON-NLS-1$
- }
- }
- return escapedPath.toString().trim();
- } else {
- return path;
- }
- }
-
- protected StringBuffer addTopHeader() {
- return addDefaultHeader();
- }
-
- protected StringBuffer addFragmentMakefileHeader() {
- return addDefaultHeader();
- }
-
- protected StringBuffer addFragmentDependenciesHeader() {
- return addDefaultHeader();
- }
-
- protected void outputCommentLine(StringBuffer buffer) {
- for (int i = 0; i < COLS_PER_LINE; i++) {
- buffer.append(COMMENT_SYMBOL);
- }
- buffer.append(NEWLINE);
- }
-
- protected StringBuffer addDefaultHeader() {
- StringBuffer buffer = new StringBuffer();
- outputCommentLine(buffer);
- buffer.append(COMMENT_SYMBOL+WHITESPACE+ManagedBuilderCorePlugin.getResourceString(HEADER)+NEWLINE);
- outputCommentLine(buffer);
- buffer.append(NEWLINE);
- return buffer;
- }
-
- /* (non-javadoc)
- * @param buffer
- * @param info
- */
- protected StringBuffer addMacros() {
- StringBuffer buffer = new StringBuffer();
-
- // Add the ROOT macro
- buffer.append("ROOT := .." + NEWLINE); //$NON-NLS-1$
- buffer.append(NEWLINE);
-
- // include makefile.init supplementary makefile
- buffer.append("-include $(ROOT)" + SEPARATOR + MAKEFILE_INIT + NEWLINE); //$NON-NLS-1$
- buffer.append(NEWLINE);
-
- // Get the clean command from the build model
- buffer.append("RM := "); //$NON-NLS-1$
- buffer.append(info.getCleanCommand() + NEWLINE);
- buffer.append(NEWLINE);
-
- buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedBuilderCorePlugin.getResourceString(SRC_LISTS) + NEWLINE);
- buffer.append("C_SRCS := " + NEWLINE); //$NON-NLS-1$
- buffer.append("CC_SRCS := " + NEWLINE); //$NON-NLS-1$
- buffer.append("CXX_SRCS := " + NEWLINE); //$NON-NLS-1$
- buffer.append("CAPC_SRCS := " + NEWLINE); //$NON-NLS-1$
- buffer.append("CPP_SRCS := " + NEWLINE + NEWLINE); //$NON-NLS-1$
-
- // Add the libraries this project depends on
- buffer.append("LIBS := "); //$NON-NLS-1$
- String[] libs = info.getLibsForTarget(extension);
- for (int i = 0; i < libs.length; i++) {
- String string = libs[i];
- buffer.append(LINEBREAK + NEWLINE + string);
- }
- buffer.append(NEWLINE + NEWLINE);
-
- // Add the extra user-specified objects
- buffer.append("USER_OBJS := "); //$NON-NLS-1$
- String[] userObjs = info.getUserObjectsForTarget(extension);
- for (int j = 0; j < userObjs.length; j++) {
- String string = userObjs[j];
- buffer.append(LINEBREAK + NEWLINE + string);
- }
- buffer.append(NEWLINE + NEWLINE);
-
- buffer.append("OBJS = $(C_SRCS:$(ROOT)/%.c=%.o) $(CC_SRCS:$(ROOT)/%.cc=%.o) $(CXX_SRCS:$(ROOT)/%.cxx=%.o) $(CAPC_SRCS:$(ROOT)/%.C=%.o) $(CPP_SRCS:$(ROOT)/%.cpp=%.o)" + NEWLINE); //$NON-NLS-1$
- return (buffer.append(NEWLINE));
- }
-
- /* (non-javadoc)
- * @return
- */
- protected StringBuffer addSubdirectories() {
- StringBuffer buffer = new StringBuffer();
- // Add the comment
- buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedBuilderCorePlugin.getResourceString(MOD_LIST) + NEWLINE);
- buffer.append("SUBDIRS := " + LINEBREAK + NEWLINE); //$NON-NLS-1$
-
- // Get all the module names
- ListIterator iter = getSubdirList().listIterator();
- while (iter.hasNext()) {
- IContainer container = (IContainer) iter.next();
- // Check the special case where the module is the project root
- if (container.getFullPath() == project.getFullPath()) {
- buffer.append(DOT + WHITESPACE + LINEBREAK + NEWLINE);
- } else {
- IPath path = container.getProjectRelativePath();
- buffer.append(path.toString() + WHITESPACE + LINEBREAK + NEWLINE);
- }
- }
-
- // Now add the makefile instruction to include all the subdirectory makefile fragments
- buffer.append(NEWLINE);
- buffer.append(COMMENT_SYMBOL +WHITESPACE + ManagedBuilderCorePlugin.getResourceString(MOD_INCL) + NEWLINE);
- buffer.append("-include ${patsubst %, %/subdir.mk, $(SUBDIRS)}" + NEWLINE); //$NON-NLS-1$
- buffer.append(NEWLINE);
-
- // Include makefile.defs supplemental makefile
- buffer.append("-include $(ROOT)" + SEPARATOR + MAKEFILE_DEFS + NEWLINE); //$NON-NLS-1$
-
- buffer.append(NEWLINE);
- return buffer;
- }
-
-
- /* (non-javadoc)
- * Answers a <code>StringBuffer</code> containing all of the sources contributed by
- * a container to the build.
- *
- * @param module
- * @return StringBuffer
- */
- protected StringBuffer addSources(IContainer module) throws CoreException {
- // Calculate the new directory relative to the build output
- IPath moduleRelativePath = module.getProjectRelativePath();
- String relativePath = moduleRelativePath.toString();
- relativePath += relativePath.length() == 0 ? "" : SEPARATOR; //$NON-NLS-1$
-
- // String buffers
- StringBuffer buffer = new StringBuffer();
- StringBuffer cBuffer = new StringBuffer("C_SRCS += " + LINEBREAK + NEWLINE); //$NON-NLS-1$
- cBuffer.append("${addprefix $(ROOT)/" + relativePath + "," + LINEBREAK + NEWLINE); //$NON-NLS-1$//$NON-NLS-2$
- StringBuffer ccBuffer = new StringBuffer("CC_SRCS += \\" + NEWLINE); //$NON-NLS-1$
- ccBuffer.append("${addprefix $(ROOT)/" + relativePath + "," + LINEBREAK + NEWLINE); //$NON-NLS-1$//$NON-NLS-2$
- StringBuffer cxxBuffer = new StringBuffer("CXX_SRCS += \\" + NEWLINE); //$NON-NLS-1$
- cxxBuffer.append("${addprefix $(ROOT)/" + relativePath + "," + LINEBREAK + NEWLINE); //$NON-NLS-1$//$NON-NLS-2$
- StringBuffer capcBuffer = new StringBuffer("CAPC_SRCS += \\" + NEWLINE); //$NON-NLS-1$
- capcBuffer.append("${addprefix $(ROOT)/" + relativePath + "," + LINEBREAK + NEWLINE); //$NON-NLS-1$//$NON-NLS-2$
- StringBuffer cppBuffer = new StringBuffer("CPP_SRCS += \\" + NEWLINE); //$NON-NLS-1$
- cppBuffer.append("${addprefix $(ROOT)/" + relativePath + "," + LINEBREAK + NEWLINE); //$NON-NLS-1$//$NON-NLS-2$
- StringBuffer ruleBuffer = new StringBuffer(COMMENT_SYMBOL + WHITESPACE + ManagedBuilderCorePlugin.getResourceString(MOD_RULES) + NEWLINE);
-
- // Put the comment in
- buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedBuilderCorePlugin.getResourceString(SRC_LISTS) + NEWLINE);
-
- // Visit the resources in this folder
- IResource[] resources = module.members();
- for (int i = 0; i < resources.length; i++) {
- IResource resource = resources[i];
- if (resource.getType() == IResource.FILE) {
- String ext = resource.getFileExtension();
- if (info.buildsFileType(ext)) {
- if (new String("c").equals(ext)) { //$NON-NLS-1$
- cBuffer.append(resource.getName() + WHITESPACE + LINEBREAK + NEWLINE);
- } else if (new String("cc").equalsIgnoreCase(ext)) { //$NON-NLS-1$
- ccBuffer.append(resource.getName() + WHITESPACE + LINEBREAK + NEWLINE);
- } else if (new String("cxx").equalsIgnoreCase(ext)) { //$NON-NLS-1$
- cxxBuffer.append(resource.getName() + WHITESPACE + LINEBREAK + NEWLINE);
- } else if (new String("C").equals(ext)) { //$NON-NLS-1$
- capcBuffer.append(resource.getName() + WHITESPACE + LINEBREAK + NEWLINE);
- } else {
- cppBuffer.append(resource.getName() + WHITESPACE + LINEBREAK + NEWLINE);
- }
-
- // Try to add the rule for the file
- addRule(relativePath, ruleBuffer, resource);
- }
- }
- }
-
- // Finish the commands in the buffers
- buffer.append(cBuffer.append("}" + NEWLINE + NEWLINE)); //$NON-NLS-1$
- buffer.append(ccBuffer.append("}" + NEWLINE + NEWLINE)); //$NON-NLS-1$
- buffer.append(cxxBuffer.append("}" + NEWLINE + NEWLINE)); //$NON-NLS-1$
- buffer.append(capcBuffer.append("}" + NEWLINE + NEWLINE)); //$NON-NLS-1$
- buffer.append(cppBuffer.append("}" + NEWLINE + NEWLINE)); //$NON-NLS-1$
-
- return buffer.append(ruleBuffer + NEWLINE);
- }
-
- /* (non-javadoc)
- * Answers a <code>StrinBuffer</code> containing all of the required targets to
- * properly build the project.
- *
- * @return StringBuffer
- */
- protected StringBuffer addTargets(boolean rebuild) {
- StringBuffer buffer = new StringBuffer();
-
- // Assemble the information needed to generate the targets
- String cmd = info.getToolForTarget(extension);
- String flags = info.getFlagsForTarget(extension);
- String outflag = info.getOutputFlag(extension);
- String outputPrefix = info.getOutputPrefix(extension);
- String targets = rebuild ? "clean all" : "all"; //$NON-NLS-1$ //$NON-NLS-2$
-
- // Get all the projects the build target depends on
- IProject[] deps = null;
- try {
- deps = project.getReferencedProjects();
- } catch (CoreException e) {
- // There are 2 exceptions; the project does not exist or it is not open
- // and neither conditions apply if we are building for it ....
- }
-
- // Write out the all target first in case someone just runs make
- // all: targ_<target_name> [deps]
- String defaultTarget = "all:"; //$NON-NLS-1$
- if (deps.length > 0) {
- defaultTarget += WHITESPACE + "deps"; //$NON-NLS-1$
- }
- buffer.append(defaultTarget + WHITESPACE + outputPrefix + target);
- if (extension.length() > 0) {
- buffer.append(DOT + extension);
- }
- buffer.append(NEWLINE + NEWLINE);
-
- /*
- * The build target may depend on other projects in the workspace. These are
- * captured in the deps target:
- * deps:
- * <cd <Proj_Dep_1/build_dir>; $(MAKE) [clean all | all]>
- */
- List managedProjectOutputs = new ArrayList();
- if (deps.length > 0) {
- buffer.append("deps:" + NEWLINE); //$NON-NLS-1$
- if (deps != null) {
- for (int i = 0; i < deps.length; i++) {
- IProject dep = deps[i];
- String buildDir = dep.getLocation().toString();
- String depTargets = targets;
- if (ManagedBuildManager.manages(dep)) {
- // Add the current configuration to the makefile path
- IManagedBuildInfo depInfo = ManagedBuildManager.getBuildInfo(dep);
- buildDir += SEPARATOR + depInfo.getConfigurationName();
-
- // Extract the build artifact to add to the dependency list
- String depTarget = depInfo.getBuildArtifactName();
- String depExt = depInfo.getBuildArtifactExtension();
- String depPrefix = depInfo.getOutputPrefix(depExt);
- if (depInfo.isDirty()) {
- depTargets = "clean all"; //$NON-NLS-1$
- }
- String dependency = buildDir + SEPARATOR + depPrefix + depTarget;
- if (depExt.length() > 0) {
- dependency += DOT + depExt;
- }
- managedProjectOutputs.add(dependency);
- }
- buffer.append(TAB + "-cd" + WHITESPACE + buildDir + WHITESPACE + LOGICAL_AND + WHITESPACE + "$(MAKE) " + depTargets + NEWLINE); //$NON-NLS-1$ //$NON-NLS-2$
- }
- }
- buffer.append(NEWLINE);
- }
-
- /*
- * Write out the target rule as:
- * targ_<prefix><target>.<extension>: $(OBJS) [<dep_proj_1_output> ... <dep_proj_n_output>]
- * $(BUILD_TOOL) $(FLAGS) $(OUTPUT_FLAG) $@ $(OBJS) $(USER_OBJS) $(LIB_DEPS)
- */
- buffer.append(outputPrefix + target);
- if (extension.length() > 0) {
- buffer.append(DOT + extension);
- }
- buffer.append(COLON + WHITESPACE + "$(OBJS)"); //$NON-NLS-1$
- Iterator iter = managedProjectOutputs.listIterator();
- while (iter.hasNext()) {
- buffer.append(WHITESPACE + (String)iter.next());
- }
- buffer.append(NEWLINE);
- buffer.append(TAB + cmd + WHITESPACE + flags + WHITESPACE + outflag + WHITESPACE + "$@" + WHITESPACE + "$(OBJS) $(USER_OBJS) $(LIBS)"); //$NON-NLS-1$ //$NON-NLS-2$
- buffer.append(NEWLINE + NEWLINE);
-
- // Always add a clean target
- buffer.append("clean:" + NEWLINE); //$NON-NLS-1$
- buffer.append(TAB + "-$(RM)" + WHITESPACE + "$(OBJS)" + WHITESPACE + outputPrefix + target); //$NON-NLS-1$ //$NON-NLS-2$
- if (extension.length() > 0) {
- buffer.append(DOT + extension);
- }
- buffer.append(NEWLINE + NEWLINE);
-
- buffer.append(".PHONY: all clean deps" + NEWLINE + NEWLINE); //$NON-NLS-1$
-
- buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedBuilderCorePlugin.getResourceString(DEP_INCL) + NEWLINE);
- buffer.append("-include ${patsubst %, %/subdir.dep, $(SUBDIRS)}" + NEWLINE); //$NON-NLS-1$
- buffer.append(NEWLINE);
-
- // Include makefile.targets supplemental makefile
- buffer.append("-include $(ROOT)" + SEPARATOR + MAKEFILE_TARGETS + NEWLINE); //$NON-NLS-1$
-
- return buffer;
- }
-
- /* (non-javadoc)
- *
- * @param relativePath
- * @param buffer
- * @param resource
- */
- protected void addRule(String relativePath, StringBuffer buffer, IResource resource) {
- String rule = null;
- String cmd = null;
- String buildFlags = null;
- String inputExtension = null;
- String outputExtension = null;
- String outflag = null;
- String outputPrefix = null;
-
- // Is there a special rule for this file
- if (false) {
- }
- else {
- // Get the extension of the resource
- inputExtension = resource.getFileExtension();
- // ASk the build model what it will produce from this
- outputExtension = info.getOutputExtension(inputExtension);
- /*
- * Create the pattern rule in the format
- * <relative_path>/%.o: $(ROOT)/<relative_path>/%.cpp
- * $(CC) $(CFLAGS) $(OUTPUT_FLAG) $@ $<
- *
- * Note that CC CFLAGS and OUTPUT_FLAG all come from the build model
- * and are resolved to a real command before writing to the module
- * makefile, so a real command might look something like
- * source1/%.o: $(ROOT)/source1/%.cpp
- * g++ -g -O2 -c -I/cygdrive/c/eclipse/workspace/Project/headers -o $@ $<
- */
- rule = relativePath + WILDCARD + DOT + outputExtension + COLON + WHITESPACE + "$(ROOT)" + SEPARATOR + relativePath + WILDCARD + DOT + inputExtension; //$NON-NLS-1$
- }
-
- // Check if the rule is listed as something we already generated in the makefile
- if (!getRuleList().contains(rule)) {
- // Add it to the list
- getRuleList().add(rule);
-
- // Add the rule and command to the makefile
- buffer.append(rule + NEWLINE);
- cmd = info.getToolForSource(inputExtension);
- buildFlags = info.getFlagsForSource(inputExtension);
- outflag = info.getOutputFlag(outputExtension);
- outputPrefix = info.getOutputPrefix(outputExtension);
- buffer.append(TAB + cmd + WHITESPACE + buildFlags + WHITESPACE + outflag + WHITESPACE + outputPrefix + "$@" + WHITESPACE + "$<" + NEWLINE + NEWLINE); //$NON-NLS-1$ //$NON-NLS-2$
- }
- }
-
- /**
- * Adds the container of the argument to the list of folders in the project that
- * contribute source files to the build. The resource visitor has already established
- * that the build model knows how to build the files. It has also checked that
- * the resource is not generated as part of the build.
- *
- * @param resource
- */
- public void appendBuildSubdirectory(IResource resource) {
- IContainer container = resource.getParent();
- if (!getSubdirList().contains(container)) {
- getSubdirList().add(container);
- }
-
- }
-
- /**
- * Adds the container of the argument to a list of subdirectories that are part
- * of an incremental rebuild of the project. The makefile fragments for these
- * directories will be regenerated as a result of the build.
- *
- * @param resource
- */
- public void appendModifiedSubdirectory(IResource resource) {
- IContainer container = resource.getParent();
- if (!getModifiedList().contains(container)) {
- getModifiedList().add(container);
- }
- }
-
-
- /* (non-Javadoc)
- * @param message
- */
- protected void cancel(String message) {
- if (monitor != null && !monitor.isCanceled()) {
- throw new OperationCanceledException(message);
- }
- }
-
- /**
- * Check whether the build has been cancelled. Cancellation requests
- * propagated to the caller by throwing <code>OperationCanceledException</code>.
- *
- * @see org.eclipse.core.runtime.OperationCanceledException#OperationCanceledException()
- */
- public void checkCancel() {
- if (monitor != null && monitor.isCanceled()) {
- throw new OperationCanceledException();
- }
- }
-
- /**
- * Clients call this method when an incremental rebuild is required. The argument
- * contains a set of resource deltas that will be used to determine which
- * subdirectories need a new makefile and dependency list (if any).
- *
- * @param delta
- * @throws CoreException
- */
- public void generateMakefiles(IResourceDelta delta) throws CoreException {
- /*
- * Let's do a sanity check right now.
- *
- * 1. This is an incremental build, so if the top-level directory is not
- * there, then a rebuild is needed.
- */
- IFolder folder = project.getFolder(info.getConfigurationName());
- if (!folder.exists()) {
- regenerateMakefiles();
- return;
- }
-
- // Visit the resources in the delta and compile a list of subdirectories to regenerate
- ResourceDeltaVisitor visitor = new ResourceDeltaVisitor(this, info);
- delta.accept(visitor);
-
- // See if the user has cancelled the build
- checkCancel();
-
- // The top-level makefile needs this information
- ResourceProxyVisitor resourceVisitor = new ResourceProxyVisitor(this, info);
- project.accept(resourceVisitor, IResource.NONE);
- checkCancel();
-
- // Regenerate any fragments that are missing for the exisiting directories NOT modified
- Iterator iter = getSubdirList().listIterator();
- while (iter.hasNext()) {
- IContainer subdirectory = (IContainer)iter.next();
- if (!getModifiedList().contains(subdirectory)) {
- // Make sure a fragment makefile and dependency file exist
- IFile makeFragment = project.getFile(subdirectory.getFullPath().addTrailingSeparator().append(MODFILE_NAME));
- IFile depFragment = project.getFile(subdirectory.getFullPath().addTrailingSeparator().append(DEPFILE_NAME));
- if (!makeFragment.exists() || !depFragment.exists()) {
- // If one or both are missing, then add it to the list to be generated
- getModifiedList().add(subdirectory);
- }
- }
- }
-
- // Re-create the top-level makefile
- topBuildDir = createDirectory(info.getConfigurationName());
- IPath makefilePath = topBuildDir.addTrailingSeparator().append(MAKEFILE_NAME);
- IFile makefileHandle = createFile(makefilePath);
- populateTopMakefile(makefileHandle, false);
- checkCancel();
-
- // Regenerate any fragments for modified directories
- iter = getModifiedList().listIterator();
- while (iter.hasNext()) {
- populateFragmentMakefile((IContainer) iter.next());
- checkCancel();
- }
- }
-
- /* (non-javadoc)
- *
- * @return List
- */
- private List getModifiedList() {
- if (modifiedList == null) {
- modifiedList = new ArrayList();
- }
- return modifiedList;
- }
-
- /* (non-javadoc)
- * Answers the list of known build rules. This keeps me from generating duplicate
- * rules for known file extensions.
- *
- * @return List
- */
- private List getRuleList() {
- if (ruleList == null) {
- ruleList = new ArrayList();
- }
- return ruleList;
- }
-
- /* (non-javadoc)
- * Answers the list of subdirectories contributing source code to the build
- *
- * @return List
- */
- private List getSubdirList() {
- if (subdirList == null) {
- subdirList = new ArrayList();
- }
- return subdirList;
- }
-
- /* (non-Javadoc)
- * Return or create the folder needed for the build output. If we are
- * creating the folder, set the derived bit to true so the CM system
- * ignores the contents. If the resource exists, respect the existing
- * derived setting.
- *
- * @param string
- * @return IPath
- */
- private IPath createDirectory(String dirName) throws CoreException {
- // Create or get the handle for the build directory
- IFolder folder = project.getFolder(dirName);
- if (!folder.exists()) {
- // Make sure that parent folders exist
- IPath parentPath = (new Path(dirName)).removeLastSegments(1);
- // Assume that the parent exists if the path is empty
- if (!parentPath.isEmpty()) {
- IFolder parent = project.getFolder(parentPath);
- if (!parent.exists()) {
- createDirectory(parentPath.toString());
- }
- }
-
- // Now make the requested folder
- try {
- folder.create(true, true, null);
- }
- catch (CoreException e) {
- if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED)
- folder.refreshLocal(IResource.DEPTH_ZERO, null);
- else
- throw e;
- }
-
- // Make sure the folder is marked as derived so it is not added to CM
- if (!folder.isDerived()) {
- folder.setDerived(true);
- }
- }
-
- return folder.getFullPath();
- }
-
- /* (non-Javadoc)
- * Return or create the makefile needed for the build. If we are creating
- * the resource, set the derived bit to true so the CM system ignores
- * the contents. If the resource exists, respect the existing derived
- * setting.
- *
- * @param makefilePath
- * @param monitor
- * @return IFile
- */
- private IFile createFile(IPath makefilePath) throws CoreException {
- // Create or get the handle for the makefile
- IWorkspaceRoot root = CCorePlugin.getWorkspace().getRoot();
- IFile newFile = root.getFileForLocation(makefilePath);
- if (newFile == null) {
- newFile = root.getFile(makefilePath);
- }
- // Create the file if it does not exist
- ByteArrayInputStream contents = new ByteArrayInputStream(new byte[0]);
- try {
- newFile.create(contents, false, monitor);
- // Make sure the new file is marked as derived
- if (!newFile.isDerived()) {
- newFile.setDerived(true);
- }
-
- }
- catch (CoreException e) {
- // If the file already existed locally, just refresh to get contents
- if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED)
- newFile.refreshLocal(IResource.DEPTH_ZERO, null);
- else
- throw e;
- }
-
- return newFile;
- }
-
- /**
- * Answers the <code>IPath</code> of the top directory generated for the build
- * output, or <code>null</code> if none has been generated.
- *
- * @return IPath
- */
- public IPath getTopBuildDir() {
- return topBuildDir;
- }
-
- /**
- * Answers <code>true</code> if the argument is found in a generated container
- * @param resource
- * @return boolean
- */
- public boolean isGeneratedResource(IResource resource) {
- // Is this a generated directory ...
- IPath path = resource.getProjectRelativePath();
- String[] configNames = info.getConfigurationNames();
- for (int i = 0; i < configNames.length; i++) {
- String name = configNames[i];
- IPath root = new Path(name);
- // It is if it is a root of the resource pathname
- if (root.isPrefixOf(path)) return true;
- }
-
- return false;
- }
-
- /* (non-javadoc)
- * Create the entire contents of the makefile.
- *
- * @param fileHandle The file to place the contents in.
- * @param rebuild FLag signalling that the user is doing a full rebuild
- * @throws CoreException
- */
- protected void populateTopMakefile(IFile fileHandle, boolean rebuild) throws CoreException {
- StringBuffer buffer = new StringBuffer();
-
- // Add the header
- buffer.append(addTopHeader());
-
- // Add the macro definitions
- buffer.append(addMacros());
-
- // Append the module list
- buffer.append(addSubdirectories());
-
- // Add targets
- buffer.append(addTargets(rebuild));
-
- // Save the file
- Util.save(buffer, fileHandle);
- }
-
- /* (non-javadoc)
- * @param module
- * @throws CoreException
- */
- protected void populateFragmentMakefile(IContainer module) throws CoreException {
- // Calcualte the new directory relative to the build output
- IPath moduleRelativePath = module.getProjectRelativePath();
- IPath buildRoot = getTopBuildDir().removeFirstSegments(1);
- if (buildRoot == null) {
- return;
- }
- IPath moduleOutputPath = buildRoot.append(moduleRelativePath);
-
- // Now create the directory
- IPath moduleOutputDir = createDirectory(moduleOutputPath.toString());
-
- // Create a module makefile
- IFile modMakefile = createFile(moduleOutputDir.addTrailingSeparator().append(MODFILE_NAME));
- StringBuffer makeBuf = new StringBuffer();
- makeBuf.append(addFragmentMakefileHeader());
- makeBuf.append(addSources(module));
-
- // Create a module dep file
- IFile modDepfile = createFile(moduleOutputDir.addTrailingSeparator().append(DEPFILE_NAME));
- StringBuffer depBuf = new StringBuffer();
- depBuf.append(addFragmentDependenciesHeader());
- depBuf.append(addSourceDependencies(module));
-
- // Save the files
- Util.save(makeBuf, modMakefile);
- Util.save(depBuf, modDepfile);
- }
-
-
- /**
- * @throws CoreException
- */
- public void regenerateMakefiles() throws CoreException {
- // Visit the resources in the project
- ResourceProxyVisitor visitor = new ResourceProxyVisitor(this, info);
- project.accept(visitor, IResource.NONE);
-
- // See if the user has cancelled the build
- checkCancel();
-
- // Populate the makefile if any source files have been found in the project
- if (getSubdirList().isEmpty()) {
- return;
- }
-
- // Create the top-level directory for the build output
- topBuildDir = createDirectory(info.getConfigurationName());
-
- // Create the top-level makefile
- IPath makefilePath = topBuildDir.addTrailingSeparator().append(MAKEFILE_NAME);
- IFile makefileHandle = createFile(makefilePath);
-
- populateTopMakefile(makefileHandle, true);
- checkCancel();
-
- // Now populate the module makefiles
- ListIterator iter = getSubdirList().listIterator();
- while (iter.hasNext()) {
- try {
- populateFragmentMakefile((IContainer)iter.next());
- } catch (CoreException e) {
-
- }
- checkCancel();
- }
- }
-}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java
index 497f3189054..0d4fc9b0311 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java
@@ -17,6 +17,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Vector;
import org.eclipse.cdt.core.CCProjectNature;
import org.eclipse.cdt.core.CProjectNature;
@@ -41,9 +42,12 @@ import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.jobs.Job;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
@@ -92,10 +96,26 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
cModelElement = CoreModel.getDefault().create(owner.getProject());
try {
- CoreModel.getDefault().setRawPathEntries(cModelElement, new IPathEntry[]{containerEntry}, new NullProgressMonitor());
- } catch (CModelException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
+ IPathEntry[] entries = cModelElement.getRawPathEntries();
+ if (entries.length > 0 && entries[0].equals(containerEntry)) {
+
+ } else {
+ Job initJob = new Job("Initializing path container") {
+ protected IStatus run(IProgressMonitor monitor) {
+ try {
+ // Set the raw path entries
+ cModelElement.setRawPathEntries(new IPathEntry[]{containerEntry}, new NullProgressMonitor());
+ } catch (CModelException e) {
+ ManagedBuilderCorePlugin.log(e);
+ }
+ return null;
+ }
+
+ };
+ initJob.schedule();
+ }
+ } catch (CModelException e) {
+ ManagedBuilderCorePlugin.log(e);
}
isDirty = false;
@@ -161,27 +181,11 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
// Check to see if there is a rule to build a file with this extension
IConfiguration config = getDefaultConfiguration(getDefaultTarget());
- ITool[] tools = config.getTools();
+ ITool[] tools = config.getFilteredTools(project);
for (int index = 0; index < tools.length; index++) {
ITool tool = tools[index];
- try {
- // Make sure the tool is right for the project
- switch (tool.getNatureFilter()) {
- case ITool.FILTER_C:
- if (project.hasNature(CProjectNature.C_NATURE_ID) && !project.hasNature(CCProjectNature.CC_NATURE_ID)) {
- return tool.buildsFileType(srcExt);
- }
- break;
- case ITool.FILTER_CC:
- if (project.hasNature(CCProjectNature.CC_NATURE_ID)) {
- return tool.buildsFileType(srcExt);
- }
- break;
- case ITool.FILTER_BOTH:
- return tool.buildsFileType(srcExt);
- }
- } catch (CoreException e) {
- continue;
+ if (tool != null && tool.buildsFileType(srcExt)) {
+ return true;
}
}
return false;
@@ -365,31 +369,14 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
// Get all the tools for the current config
IConfiguration config = getDefaultConfiguration(getDefaultTarget());
- ITool[] tools = config.getTools();
+ ITool[] tools = config.getFilteredTools(project);
for (int index = 0; index < tools.length; index++) {
ITool tool = tools[index];
- if (tool.buildsFileType(extension)) {
+ if (tool != null && tool.buildsFileType(extension)) {
try {
- // Make sure the tool is right for the project
- switch (tool.getNatureFilter()) {
- case ITool.FILTER_C:
- if (project.hasNature(CProjectNature.C_NATURE_ID) && !project.hasNature(CCProjectNature.CC_NATURE_ID)) {
- return tool.getToolFlags();
- }
- break;
- case ITool.FILTER_CC:
- if (project.hasNature(CCProjectNature.CC_NATURE_ID)) {
- return tool.getToolFlags();
- }
- break;
- case ITool.FILTER_BOTH:
- return tool.getToolFlags();
- }
- } catch (CoreException e) {
- continue;
+ return tool.getToolFlags();
} catch (BuildException e) {
- // Give it your best shot with the next tool
- continue;
+ return null;
}
}
}
@@ -406,31 +393,14 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
// Get all the tools for the current config
IConfiguration config = getDefaultConfiguration(getDefaultTarget());
- ITool[] tools = config.getTools();
+ ITool[] tools = config.getFilteredTools(project);
for (int index = 0; index < tools.length; index++) {
ITool tool = tools[index];
if (tool.producesFileType(ext)) {
try {
- // Make sure the tool is right for the project
- switch (tool.getNatureFilter()) {
- case ITool.FILTER_C:
- if (project.hasNature(CProjectNature.C_NATURE_ID) && !project.hasNature(CCProjectNature.CC_NATURE_ID)) {
- return tool.getToolFlags();
- }
- break;
- case ITool.FILTER_CC:
- if (project.hasNature(CCProjectNature.CC_NATURE_ID)) {
- return tool.getToolFlags();
- }
- break;
- case ITool.FILTER_BOTH:
- return tool.getToolFlags();
- }
- } catch (CoreException e) {
- continue;
+ return tool.getToolFlags();
} catch (BuildException e) {
- // Give it your best shot with the next tool
- continue;
+ return null;
}
}
}
@@ -534,32 +504,12 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
public String[] getLibsForTarget(String extension) {
IProject project = (IProject)owner;
- ArrayList libs = new ArrayList();
+ Vector libs = new Vector();
// Get all the tools for the current config
IConfiguration config = getDefaultConfiguration(getDefaultTarget());
- ITool[] tools = config.getTools();
+ ITool[] tools = config.getFilteredTools(project);
for (int index = 0; index < tools.length; index++) {
ITool tool = tools[index];
- try {
- // Make sure the tool is right for the project
- switch (tool.getNatureFilter()) {
- case ITool.FILTER_C:
- if (!project.hasNature(CProjectNature.C_NATURE_ID) || project.hasNature(CCProjectNature.CC_NATURE_ID)) {
- continue;
- }
- break;
- case ITool.FILTER_CC:
- if (!project.hasNature(CCProjectNature.CC_NATURE_ID)) {
- continue;
- }
- break;
- case ITool.FILTER_BOTH:
- break;
- }
- } catch (CoreException e) {
- continue;
- }
- // The tool is OK for this project nature
if (tool.producesFileType(extension)) {
IOption[] opts = tool.getOptions();
// Look for the lib option type
@@ -580,7 +530,6 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
}
}
}
- libs.trimToSize();
return (String[])libs.toArray(new String[libs.size()]);
}
@@ -603,29 +552,16 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
*/
public String getOutputExtension(String resourceExtension) {
IProject project = (IProject)owner;
+ String outputExtension = null;
+
// Get all the tools for the current config
IConfiguration config = getDefaultConfiguration(getDefaultTarget());
- ITool[] tools = config.getTools();
+ ITool[] tools = config.getFilteredTools(project);
for (int index = 0; index < tools.length; index++) {
ITool tool = tools[index];
- try {
- // Make sure the tool is right for the project
- switch (tool.getNatureFilter()) {
- case ITool.FILTER_C:
- if (project.hasNature(CProjectNature.C_NATURE_ID) && !project.hasNature(CCProjectNature.CC_NATURE_ID)) {
- return tool.getOutputExtension(resourceExtension);
- }
- break;
- case ITool.FILTER_CC:
- if (project.hasNature(CCProjectNature.CC_NATURE_ID)) {
- return tool.getOutputExtension(resourceExtension);
- }
- break;
- case ITool.FILTER_BOTH:
- return tool.getOutputExtension(resourceExtension);
- }
- } catch (CoreException e) {
- continue;
+ outputExtension = tool.getOutputExtension(resourceExtension);
+ if (outputExtension != null) {
+ return outputExtension;
}
}
return null;
@@ -642,28 +578,9 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
// Get all the tools for the current config
String flags = new String();
IConfiguration config = getDefaultConfiguration(getDefaultTarget());
- ITool[] tools = config.getTools();
+ ITool[] tools = config.getFilteredTools(project);
for (int index = 0; index < tools.length; index++) {
ITool tool = tools[index];
- try {
- // Make sure the tool is right for the project
- switch (tool.getNatureFilter()) {
- case ITool.FILTER_C:
- if (!project.hasNature(CProjectNature.C_NATURE_ID) || project.hasNature(CCProjectNature.CC_NATURE_ID)) {
- continue;
- }
- break;
- case ITool.FILTER_CC:
- if (!project.hasNature(CCProjectNature.CC_NATURE_ID)) {
- continue;
- }
- break;
- case ITool.FILTER_BOTH:
- break;
- }
- } catch (CoreException e) {
- continue;
- }
// It's OK
if (tool.producesFileType(ext)) {
flags = tool.getOutputFlag();
@@ -683,28 +600,9 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
// Get all the tools for the current config
String flags = new String();
IConfiguration config = getDefaultConfiguration(getDefaultTarget());
- ITool[] tools = config.getTools();
+ ITool[] tools = config.getFilteredTools(project);
for (int index = 0; index < tools.length; index++) {
ITool tool = tools[index];
- try {
- // Make sure the tool is right for the project
- switch (tool.getNatureFilter()) {
- case ITool.FILTER_C:
- if (!project.hasNature(CProjectNature.C_NATURE_ID) || project.hasNature(CCProjectNature.CC_NATURE_ID)) {
- continue;
- }
- break;
- case ITool.FILTER_CC:
- if (!project.hasNature(CCProjectNature.CC_NATURE_ID)) {
- continue;
- }
- break;
- case ITool.FILTER_BOTH:
- break;
- }
- } catch (CoreException e) {
- continue;
- }
if (tool.producesFileType(ext)) {
flags = tool.getOutputPrefix();
}
@@ -756,29 +654,11 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
// Get all the tools for the current config
IConfiguration config = getDefaultConfiguration(getDefaultTarget());
- ITool[] tools = config.getTools();
+ ITool[] tools = config.getFilteredTools(project);
for (int index = 0; index < tools.length; index++) {
ITool tool = tools[index];
if (tool.buildsFileType(extension)) {
- try {
- // Make sure the tool is right for the project
- switch (tool.getNatureFilter()) {
- case ITool.FILTER_C:
- if (project.hasNature(CProjectNature.C_NATURE_ID) && !project.hasNature(CCProjectNature.CC_NATURE_ID)) {
- return tool.getToolCommand();
- }
- break;
- case ITool.FILTER_CC:
- if (project.hasNature(CCProjectNature.CC_NATURE_ID)) {
- return tool.getToolCommand();
- }
- break;
- case ITool.FILTER_BOTH:
- return tool.getToolCommand();
- }
- } catch (CoreException e) {
- continue;
- }
+ return tool.getToolCommand();
}
}
return null;
@@ -794,29 +674,11 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
String ext = extension == null ? new String() : extension;
// Get all the tools for the current config
IConfiguration config = getDefaultConfiguration(getDefaultTarget());
- ITool[] tools = config.getTools();
+ ITool[] tools = config.getFilteredTools(project);
for (int index = 0; index < tools.length; index++) {
ITool tool = tools[index];
if (tool.producesFileType(ext)) {
- try {
- // Make sure the tool is right for the project
- switch (tool.getNatureFilter()) {
- case ITool.FILTER_C:
- if (project.hasNature(CProjectNature.C_NATURE_ID) && !project.hasNature(CCProjectNature.CC_NATURE_ID)) {
- return tool.getToolCommand();
- }
- break;
- case ITool.FILTER_CC:
- if (project.hasNature(CCProjectNature.CC_NATURE_ID)) {
- return tool.getToolCommand();
- }
- break;
- case ITool.FILTER_BOTH:
- return tool.getToolCommand();
- }
- } catch (CoreException e) {
- continue;
- }
+ return tool.getToolCommand();
}
}
return null;
@@ -827,31 +689,12 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
*/
public String[] getUserObjectsForTarget(String extension) {
IProject project = (IProject)owner;
- ArrayList objs = new ArrayList();
+ Vector objs = new Vector();
// Get all the tools for the current config
IConfiguration config = getDefaultConfiguration(getDefaultTarget());
- ITool[] tools = config.getTools();
+ ITool[] tools = config.getFilteredTools(project);
for (int index = 0; index < tools.length; index++) {
ITool tool = tools[index];
- try {
- // Make sure the tool is right for the project
- switch (tool.getNatureFilter()) {
- case ITool.FILTER_C:
- if (!project.hasNature(CProjectNature.C_NATURE_ID) || project.hasNature(CCProjectNature.CC_NATURE_ID)) {
- continue;
- }
- break;
- case ITool.FILTER_CC:
- if (!project.hasNature(CCProjectNature.CC_NATURE_ID)) {
- continue;
- }
- break;
- case ITool.FILTER_BOTH:
- break;
- }
- } catch (CoreException e) {
- continue;
- }
// The tool is OK for this project nature
if (tool.producesFileType(extension)) {
IOption[] opts = tool.getOptions();
@@ -868,7 +711,6 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
}
}
}
- objs.trimToSize();
return (String[])objs.toArray(new String[objs.size()]);
}
@@ -985,8 +827,7 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
IPathEntryContainer container = new ManagedBuildCPathEntryContainer(this);
CoreModel.getDefault().setPathEntryContainer(new ICProject[]{cModelElement}, container, new NullProgressMonitor());
} catch (CModelException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ ManagedBuilderCorePlugin.log(e);
}
}
@@ -1122,7 +963,7 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
// And finally update the cModelElement
cModelElement = CoreModel.getDefault().create(owner.getProject());
try {
- CoreModel.getDefault().setRawPathEntries(cModelElement, new IPathEntry[]{containerEntry}, new NullProgressMonitor());
+ CoreModel.setRawPathEntries(cModelElement, new IPathEntry[]{containerEntry}, new NullProgressMonitor());
} catch (CModelException e) {
// TODO Auto-generated catch block
e.printStackTrace();
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedMakeMessages.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedMakeMessages.java
new file mode 100644
index 00000000000..3314aee6ae8
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedMakeMessages.java
@@ -0,0 +1,58 @@
+/**********************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.managedbuilder.internal.core;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * @since 2.0
+ */
+public class ManagedMakeMessages {
+ // Bundle ID
+ private static final String BUNDLE_ID = "org.eclipse.cdt.managedbuilder.internal.core.PluginResources"; //$NON-NLS-1$
+ //Resource bundle.
+ private static ResourceBundle resourceBundle;
+
+ static {
+ try {
+ resourceBundle = ResourceBundle.getBundle(BUNDLE_ID);
+ } catch (MissingResourceException x) {
+ resourceBundle = null;
+ }
+ }
+
+ public static String getResourceString(String key) {
+ try {
+ return resourceBundle.getString(key);
+ } catch (MissingResourceException e) {
+ return "!" + key + "!"; //$NON-NLS-1$ //$NON-NLS-2$
+ } catch (NullPointerException e) {
+ return "#" + key + "#"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ public static String getFormattedString(String key, String arg) {
+ return MessageFormat.format(getResourceString(key), new String[] { arg });
+ }
+
+ public static String getFormattedString(String key, String[] args) {
+ return MessageFormat.format(getResourceString(key), args);
+ }
+
+ /**
+ *
+ */
+ private ManagedMakeMessages() {
+ // No constructor
+ }
+}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java
index 8af8c8b85c5..1c7947f3ae0 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java
@@ -25,7 +25,6 @@ import org.eclipse.cdt.managedbuilder.core.IOption;
import org.eclipse.cdt.managedbuilder.core.IOptionCategory;
import org.eclipse.cdt.managedbuilder.core.ITool;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
-import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
public class Option extends BuildObject implements IOption {
// Static default return values
@@ -230,7 +229,7 @@ public class Option extends BuildObject implements IOption {
*/
public String[] getDefinedSymbols() throws BuildException {
if (valueType != PREPROCESSOR_SYMBOLS) {
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
}
ArrayList v = (ArrayList)value;
if (v == null) {
@@ -315,7 +314,7 @@ public class Option extends BuildObject implements IOption {
*/
public String[] getIncludePaths() throws BuildException {
if (valueType != INCLUDE_PATH) {
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
}
ArrayList v = (ArrayList)value;
if (v == null) {
@@ -331,7 +330,7 @@ public class Option extends BuildObject implements IOption {
*/
public String[] getLibraries() throws BuildException {
if (valueType != LIBRARIES) {
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
}
ArrayList v = (ArrayList)value;
if (v == null) {
@@ -347,7 +346,7 @@ public class Option extends BuildObject implements IOption {
*/
public String getSelectedEnum() throws BuildException {
if (valueType != ENUMERATED) {
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
}
return defaultEnumId == null ? EMPTY_STRING : defaultEnumId;
}
@@ -357,7 +356,7 @@ public class Option extends BuildObject implements IOption {
*/
public String[] getStringListValue() throws BuildException {
if (valueType != STRING_LIST) {
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
}
ArrayList v = (ArrayList)value;
if (v == null) {
@@ -373,7 +372,7 @@ public class Option extends BuildObject implements IOption {
*/
public String getStringValue() throws BuildException {
if (valueType != STRING) {
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
}
return value == null ? EMPTY_STRING : (String)value;
}
@@ -390,7 +389,7 @@ public class Option extends BuildObject implements IOption {
*/
public String[] getUserObjects() throws BuildException {
if (valueType != OBJECTS) {
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
}
// This is the right puppy, so return its list value
ArrayList v = (ArrayList)value;
@@ -424,7 +423,7 @@ public class Option extends BuildObject implements IOption {
{
if (valueType != IOption.STRING
|| valueType != ENUMERATED)
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
if (config == null) {
this.value = value;
@@ -446,7 +445,7 @@ public class Option extends BuildObject implements IOption {
|| valueType != PREPROCESSOR_SYMBOLS
|| valueType != LIBRARIES
|| valueType != OBJECTS)
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
if (config == null) {
this.value = value;
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionReference.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionReference.java
index 4fc0e6e7d03..cb555795c8a 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionReference.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionReference.java
@@ -21,7 +21,6 @@ import org.eclipse.cdt.managedbuilder.core.IOption;
import org.eclipse.cdt.managedbuilder.core.IOptionCategory;
import org.eclipse.cdt.managedbuilder.core.ITool;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
-import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -281,7 +280,7 @@ public class OptionReference implements IOption {
return (String[]) list.toArray(new String[list.size()]);
}
else
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
}
/* (non-Javadoc)
@@ -332,7 +331,7 @@ public class OptionReference implements IOption {
return (String[]) list.toArray(new String[list.size()]);
}
else
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
}
/* (non-Javadoc)
@@ -346,7 +345,7 @@ public class OptionReference implements IOption {
return (String[]) list.toArray(new String[list.size()]);
}
else
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
}
/* (non-Javadoc)
@@ -368,7 +367,7 @@ public class OptionReference implements IOption {
Boolean bool = (Boolean) value;
return bool.booleanValue();
} else {
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
}
}
@@ -430,7 +429,7 @@ public class OptionReference implements IOption {
// This is a valid ID
return (String) value;
} else {
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
}
}
@@ -445,7 +444,7 @@ public class OptionReference implements IOption {
return (String[]) list.toArray(new String[list.size()]);
}
else
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
}
/* (non-Javadoc)
@@ -457,7 +456,7 @@ public class OptionReference implements IOption {
else if (getValueType() == STRING)
return (String)value;
else
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
}
/* (non-Javadoc)
@@ -487,7 +486,7 @@ public class OptionReference implements IOption {
return (String[]) list.toArray(new String[list.size()]);
}
else
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
}
/* (non-Javadoc)
@@ -529,7 +528,7 @@ public class OptionReference implements IOption {
if (getValueType() == BOOLEAN)
this.value = new Boolean(value);
else
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
}
/**
@@ -541,7 +540,7 @@ public class OptionReference implements IOption {
if (getValueType() == STRING || getValueType() == ENUMERATED) {
this.value = value;
} else {
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
}
}
@@ -561,7 +560,7 @@ public class OptionReference implements IOption {
this.value = new ArrayList(Arrays.asList(value));
}
else
- throw new BuildException(ManagedBuilderCorePlugin.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
+ throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$
}
/* (non-Javadoc)
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 6962600bfd7..45e8fedef66 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
@@ -20,13 +20,6 @@ ManagedMakeBuilder.message.console.header = **** {0} of configuration {1} for pr
ManagedMakeBuilder.message.error = Build error
ManagedMakeBuilder.message.error.refresh = Error refreshing project
ManagedMakeBuilder.message.finished = Build complete for project {0}
-ManagedMakeBuilder.comment.module.list = Every subdirectory with source files must be described here
-ManagedMakeBuilder.comment.source.list = Each subdirectory must contribute its source files here
-ManagedMakeBuilder.comment.build.rule = Each subdirectory must supply rules for building sources it contributes
-ManagedMakeBuilder.comment.module.make.includes = Include the makefiles for each source subdirectory
-ManagedMakeBuilder.comment.module.dep.includes = Include automatically-generated dependency list:
-ManagedMakeBuilder.comment.autodeps = Automatically-generated dependency list:
-ManagedMakeBuilder.comment.header = Automatically-generated file. Do not edit!
ManagedMakeBuilder.type.full = Full rebuild
ManagedMakeBuider.type.incremental = Incremental build
@@ -39,3 +32,16 @@ ManagedBuildManager.error.null_owner=addTarget: null owner
ManagedBuildManager.error.owner_not_project=addTarget: owner not project
ManagedBuildManager.error.manifest.version.error=The version of plugin file is higher than version of the build system
ManagedBuildManager.error.project.version.error=The version of the project is higher than the build system
+
+# Makefile Generator Messages
+MakefileGenerator.message.start.file=Building file:
+MakefileGenerator.message.finish.file=Finished building:
+MakefileGenerator.message.start.build=Building target:
+MakefileGenerator.message.finish.build=Finished building target:
+MakefileGenerator.comment.module.list = Every subdirectory with source files must be described here
+MakefileGenerator.comment.source.list = All of the sources participating in the build are defined here
+MakefileGenerator.comment.build.rule = Each subdirectory must supply rules for building sources it contributes
+MakefileGenerator.comment.module.make.includes = Include the makefiles for each source subdirectory
+MakefileGenerator.comment.module.dep.includes = Include automatically-generated dependency list:
+MakefileGenerator.comment.autodeps = Automatically-generated dependency list:
+MakefileGenerator.comment.header = Automatically-generated file. Do not edit!
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Target.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Target.java
index de5f9b5736a..90ebf6fe19e 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Target.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Target.java
@@ -330,7 +330,10 @@ public class Target extends BuildObject implements ITarget {
if (makeCommand != null) {
element.setAttribute(MAKE_COMMAND, makeCommand);
+ } else {
+ // Make sure we use the default
}
+
if (makeArguments != null) {
element.setAttribute(MAKE_ARGS, makeArguments);
}
@@ -420,7 +423,7 @@ public class Target extends BuildObject implements ITarget {
if (parent != null) {
return parent.getMakeCommand();
} else {
- // The user has forgotten to specify a command in the plugin manifets.
+ // The user has forgotten to specify a command in the plugin manifest
return new String("make"); //$NON-NLS-1$
}
} else {
@@ -721,7 +724,7 @@ public class Target extends BuildObject implements ITarget {
return defaultExtension;
}
}
-
+
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.core.ITarget#getBinaryParserId()
*/
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java
index 26e7f3cae71..24859b1113b 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java
@@ -180,12 +180,9 @@ public class Tool extends BuildObject implements ITool, IOptionCategory {
}
/* (non-Javadoc)
- * Safe accessor method to retrieve the list of valid source extensions
- * the receiver know how to build.
- *
- * @return List
+ * @see org.eclipse.cdt.managedbuilder.core.ITool#getInputExtensions()
*/
- private List getInputExtensions() {
+ public List getInputExtensions() {
if (inputExtensions == null) {
inputExtensions = new ArrayList();
}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java
index 1a8c036c008..2838148b298 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java
@@ -273,8 +273,15 @@ public class ToolReference implements IToolReference {
public String getId() {
return parent.getId();
}
-
- /* (non-Javadoc)
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.core.ITool#getInputExtensions()
+ */
+ public List getInputExtensions() {
+ return getTool().getInputExtensions();
+ }
+
+ /* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.core.IBuildObject#getName()
*/
public String getName() {
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/scannerconfig/ManagedBuildCPathEntryContainer.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/scannerconfig/ManagedBuildCPathEntryContainer.java
index 083f1dc9d86..af5d169c64a 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/scannerconfig/ManagedBuildCPathEntryContainer.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/scannerconfig/ManagedBuildCPathEntryContainer.java
@@ -16,7 +16,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.Vector;
import org.eclipse.cdt.core.model.CoreModel;
@@ -32,7 +31,7 @@ import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.IOption;
import org.eclipse.cdt.managedbuilder.core.ITarget;
import org.eclipse.cdt.managedbuilder.core.ITool;
-import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
+import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.internal.core.ManagedBuildInfo;
import org.eclipse.cdt.managedbuilder.scannerconfig.IManagedScannerInfoCollector;
import org.eclipse.core.resources.IProject;
@@ -73,8 +72,7 @@ public class ManagedBuildCPathEntryContainer implements IPathEntryContainer {
protected void addDefinedSymbols(Map definedSymbols) {
// Add a new macro entry for each defined symbol
- Set macros = definedSymbols.keySet();
- Iterator keyIter = macros.iterator();
+ Iterator keyIter = definedSymbols.keySet().iterator();
while (keyIter.hasNext()) {
boolean add = true;
String macro = (String) keyIter.next();
@@ -191,7 +189,7 @@ public class ManagedBuildCPathEntryContainer implements IPathEntryContainer {
/* (non-Javadoc)
* @see org.eclipse.cdt.core.model.IPathEntryContainer#getPathEntries()
*/
- public synchronized IPathEntry[] getPathEntries() {
+ public IPathEntry[] getPathEntries() {
// TODO figure out when I can skip this step
if (entries.isEmpty()) {
// Load the toolchain-spec'd collector
@@ -207,7 +205,7 @@ public class ManagedBuildCPathEntryContainer implements IPathEntryContainer {
}
// See if we can load a dynamic resolver
String baseTargetId = parent.getId();
- IManagedScannerInfoCollector collector = ManagedBuilderCorePlugin.getDefault().getScannerInfoCollector(baseTargetId);
+ IManagedScannerInfoCollector collector = ManagedBuildManager.getScannerInfoCollector(baseTargetId);
if (collector != null) {
collector.setProject(info.getOwner().getProject());
calculateEntriesDynamically((IProject)info.getOwner(), collector);
@@ -239,4 +237,5 @@ public class ManagedBuildCPathEntryContainer implements IPathEntryContainer {
public IPath getPath() {
return new Path("org.eclipse.cdt.managedbuilder.MANAGED_CONTAINER"); //$NON-NLS-1$
}
+
}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedBuilderDependencyCalculator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedBuilderDependencyCalculator.java
new file mode 100644
index 00000000000..b0e6e1026f0
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedBuilderDependencyCalculator.java
@@ -0,0 +1,28 @@
+/**********************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.managedbuilder.makegen;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+
+/**
+ * @since 2.0
+ */
+public interface IManagedBuilderDependencyCalculator {
+ public int TYPE_NODEPS = 0;
+ public int TYPE_COMMAND = 1;
+ public int TYPE_INDEXER = 2;
+ public int TYPE_EXTERNAL = 3;
+
+ public IResource[] findDependencies(IResource resource, IProject project);
+ public int getCalculatorType();
+ public String getDependencyCommand();
+}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedBuilderMakefileGenerator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedBuilderMakefileGenerator.java
new file mode 100644
index 00000000000..7c2b4549fae
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedBuilderMakefileGenerator.java
@@ -0,0 +1,72 @@
+/**********************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.managedbuilder.makegen;
+
+import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * @since 2.0
+ */
+public interface IManagedBuilderMakefileGenerator {
+ /**
+ * @throws CoreException
+ */
+ public void generateDependencies() throws CoreException;
+
+ /**
+ * Clients call this method when an incremental rebuild is required. The argument
+ * contains a set of resource deltas that will be used to determine which
+ * subdirectories need a new makefile and dependency list (if any).
+ *
+ * @param delta
+ * @throws CoreException
+ */
+ public void generateMakefiles(IResourceDelta delta) throws CoreException ;
+
+ /**
+ * Answers the path of the top directory generated for the build
+ * output, or <code>null</code> if none has been generated.
+ *
+ * @return <code>IPath</code> to the working directory of the build
+ */
+ public IPath getBuildWorkingDir();
+
+ /**
+ * Answers the name of the top-level makefile generated by the receiver.
+ *
+ * @return name of the makefile.
+ */
+ public String getMakefileName();
+
+ /**
+ * @param project
+ * @param info
+ * @param monitor
+ */
+ public void initialize(IProject project, IManagedBuildInfo info, IProgressMonitor monitor);
+
+ /**
+ * @param force
+ * @throws CoreException
+ */
+ public void regenerateDependencies(boolean force) throws CoreException;
+
+ /**
+ * @throws CoreException
+ */
+ public void regenerateMakefiles() throws CoreException;
+
+}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator.java
new file mode 100644
index 00000000000..e049897b334
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator.java
@@ -0,0 +1,43 @@
+/**********************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.managedbuilder.makegen.gnu;
+
+import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+
+/**
+ * @since 2.0
+ */
+public class DefaultGCCDependencyCalculator implements IManagedBuilderDependencyCalculator {
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#findDependencies(org.eclipse.core.resources.IResource)
+ */
+ public IResource[] findDependencies(IResource resource, IProject project) {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getCalculatorType()
+ */
+ public int getCalculatorType() {
+ return TYPE_COMMAND;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getDependencyCommand()
+ */
+ public String getDependencyCommand() {
+ // TODO Auto-generated method stub
+ return "$(CC) -M $(CC_FLAGS) $< > makefile.dep"; //$NON-NLS-1$
+ }
+
+}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultIndexerDependencyCalculator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultIndexerDependencyCalculator.java
new file mode 100644
index 00000000000..811b4dfe96c
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultIndexerDependencyCalculator.java
@@ -0,0 +1,86 @@
+/**********************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.managedbuilder.makegen.gnu;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.search.ICSearchConstants;
+import org.eclipse.cdt.core.search.ICSearchScope;
+import org.eclipse.cdt.core.search.SearchEngine;
+import org.eclipse.cdt.internal.core.search.PathCollector;
+import org.eclipse.cdt.internal.core.search.PatternSearchJob;
+import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
+import org.eclipse.cdt.internal.core.search.matching.CSearchPattern;
+import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+
+/**
+ * @since 2.0
+ */
+public class DefaultIndexerDependencyCalculator implements IManagedBuilderDependencyCalculator {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#findDependencies(org.eclipse.core.resources.IResource)
+ */
+ public IResource[] findDependencies(IResource resource, IProject project) {
+ PathCollector pathCollector = new PathCollector();
+ ICSearchScope scope = SearchEngine.createWorkspaceScope();
+ CSearchPattern pattern = CSearchPattern.createPattern(resource.getLocation().toOSString(), ICSearchConstants.INCLUDE, ICSearchConstants.REFERENCES, ICSearchConstants.EXACT_MATCH, true);
+ IndexManager indexManager = CCorePlugin.getDefault().getCoreModel().getIndexManager();
+ indexManager.performConcurrentJob(
+ new PatternSearchJob(
+ (CSearchPattern) pattern,
+ scope,
+ pathCollector,
+ indexManager),
+ ICSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
+ null, null);
+
+ // We will get back an array of resource names relative to the workspace
+ String[] deps = pathCollector.getPaths();
+
+ // Convert them to something useful
+ List depList = new ArrayList();
+ IResource res = null;
+ IWorkspaceRoot root = null;
+ if (project != null) {
+ root = project.getWorkspace().getRoot();
+ }
+ for (int index = 0; index < deps.length; ++index) {
+ res = root.findMember(deps[index]);
+ if (res != null) {
+ depList.add(res);
+ }
+ }
+
+ return (IResource[]) depList.toArray(new IResource[depList.size()]);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getCalculatorType()
+ */
+ public int getCalculatorType() {
+ // Tell the
+ return TYPE_INDEXER;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getDependencyCommand()
+ */
+ public String getDependencyCommand() {
+ // There is no command
+ return null;
+ }
+}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java
new file mode 100644
index 00000000000..337ce478c00
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java
@@ -0,0 +1,1302 @@
+package org.eclipse.cdt.managedbuilder.makegen.gnu;
+
+/**********************************************************************
+ * Copyright (c) 2003,2004 Rational Software Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ *
+ * Contributors:
+ * IBM Rational Software - Initial API and implementation
+ * **********************************************************************/
+
+import java.io.ByteArrayInputStream;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.internal.core.model.Util;
+import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
+import org.eclipse.cdt.managedbuilder.core.ITarget;
+import org.eclipse.cdt.managedbuilder.core.ITool;
+import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
+import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
+import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages;
+import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
+import org.eclipse.core.resources.IResourceStatus;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.SubProgressMonitor;
+
+/**
+ * This is a specialized makefile generator that takes advantage of the
+ * extensions present in Gnu Make.
+ *
+ * @since 1.2
+ */
+public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
+
+ // this is used to draw a "comment line"
+ private static final int COLS_PER_LINE = 80;
+
+ // String constants for messages
+ private static final String MESSAGE = "ManagedMakeBuilder.message"; //$NON-NLS-1$
+ protected static final String MESSAGE_FINISH_BUILD = ManagedMakeMessages.getResourceString("MakefileGenerator.message.finish.build"); //$NON-NLS-1$
+ protected static final String MESSAGE_START_BUILD = ManagedMakeMessages.getResourceString("MakefileGenerator.message.start.build"); //$NON-NLS-1$
+ protected static final String MESSAGE_FINISH_FILE = ManagedMakeMessages.getResourceString("MakefileGenerator.message.finish.file"); //$NON-NLS-1$
+ protected static final String MESSAGE_START_FILE = ManagedMakeMessages.getResourceString("MakefileGenerator.message.start.file"); //$NON-NLS-1$
+ private static final String BUILD_ERROR = MESSAGE + ".error"; //$NON-NLS-1$
+ private static final String COMMENT = "MakefileGenerator.comment"; //$NON-NLS-1$
+ private static final String HEADER = COMMENT + ".header"; //$NON-NLS-1$
+ private static final String MOD_LIST = COMMENT + ".module.list"; //$NON-NLS-1$
+ private static final String SRC_LISTS = COMMENT + ".source.list"; //$NON-NLS-1$
+ private static final String MOD_RULES = COMMENT + ".build.rule"; //$NON-NLS-1$
+ private static final String MOD_INCL = COMMENT + ".module.make.includes"; //$NON-NLS-1$
+ private static final String DEP_INCL = COMMENT + ".module.dep.includes"; //$NON-NLS-1$
+ private static final String AUTO_DEP = COMMENT + ".autodeps"; //$NON-NLS-1$
+
+ // String constants for makefile contents
+ protected static final String AT = "@"; //$NON-NLS-1$
+ protected static final String COLON = ":"; //$NON-NLS-1$
+ protected static final String DEP_EXT = "d"; //$NON-NLS-1$
+ protected static final String DEPFILE_NAME = "subdir.dep"; //$NON-NLS-1$
+ protected static final String DOT = "."; //$NON-NLS-1$
+ protected static final String ECHO = "echo"; //$NON-NLS-1$
+ protected static final String IN_MACRO = "$<"; //$NON-NLS-1$
+ protected static final String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$
+ protected static final String LINEBREAK = "\\" + NEWLINE; //$NON-NLS-1$
+ protected static final String LOGICAL_AND = "&&"; //$NON-NLS-1$
+ protected static final String MAKEFILE_NAME = "makefile"; //$NON-NLS-1$
+ protected static final String MODFILE_NAME = "subdir.mk"; //$NON-NLS-1$
+ protected static final String OUT_MACRO = "$@"; //$NON-NLS-1$
+ protected static final String ROOT = "$(ROOT)"; //$NON-NLS-1$
+ protected static final String SRCSFILE_NAME = "sources.mk"; //$NON-NLS-1$ protected static final String MAKEFILE_TARGETS = "makefile.targets"; //$NON-NLS-1$
+ protected static final String SEPARATOR = "/"; //$NON-NLS-1$
+ protected static final String SINGLE_QUOTE = "'"; //$NON-NLS-1$
+ protected static final String TAB = "\t"; //$NON-NLS-1$
+ protected static final String WHITESPACE = " "; //$NON-NLS-1$
+ protected static final String WILDCARD = "%"; //$NON-NLS-1$
+ protected static final String COMMENT_SYMBOL = "#"; //$NON-NLS-1$
+ protected static final String MAKEFILE_INIT = "makefile.init"; //$NON-NLS-1$
+ protected static final String MAKEFILE_DEFS = "makefile.defs"; //$NON-NLS-1$
+ protected static final String MAKEFILE_TARGETS = "makefile.targets"; //$NON-NLS-1$ protected static final String MAKEFILE_TARGETS = "makefile.targets"; //$NON-NLS-1$
+
+ // Local variables needed by generator
+ private String buildTargetName;
+ private Vector deletedFileList;
+ private String extension;
+ protected IManagedBuildInfo info;
+ protected Vector modifiedList;
+ protected IProgressMonitor monitor;
+ protected IProject project;
+ protected Vector ruleList;
+ protected Vector subdirList;
+ protected IPath topBuildDir;
+
+
+
+ /**
+ * This class is used to recursively walk the project and determine which
+ * modules contribute buildable source files.
+ */
+ protected class ResourceProxyVisitor implements IResourceProxyVisitor {
+ private GnuMakefileGenerator generator;
+ private IManagedBuildInfo info;
+
+ /**
+ * Constructs a new resource proxy visitor to quickly visit project
+ * resources.
+ */
+ public ResourceProxyVisitor(GnuMakefileGenerator generator, IManagedBuildInfo info) {
+ this.generator = generator;
+ this.info = info;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.resources.IResourceProxyVisitor#visit(org.eclipse.core.resources.IResourceProxy)
+ */
+ public boolean visit(IResourceProxy proxy) throws CoreException {
+ // No point in proceeding, is there
+ if (generator == null) {
+ return false;
+ }
+
+ // Is this a resource we should even consider
+ if (proxy.getType() == IResource.FILE) {
+ // Check extension to see if build model should build this file
+ IResource resource = proxy.requestResource();
+ String ext = resource.getFileExtension();
+ if (info.buildsFileType(ext)) {
+ if (!generator.isGeneratedResource(resource)) {
+ generator.appendBuildSubdirectory(resource);
+ }
+ }
+ return false;
+ }
+
+ // Recurse into subdirectories
+ return true;
+ }
+
+ }
+
+ /**
+ * This class walks the delta supplied by the build system to determine
+ * what resources have been changed. The logic is very simple. If a
+ * buildable resource (non-header) has been added or removed, the directories
+ * in which they are located are "dirty" so the makefile fragments for them
+ * have to be regenerated.
+ * <p>
+ * The actual dependencies are recalculated as a result of the build step
+ * itself. We are relying on make to do the right things when confronted
+ * with a dependency on a moved header file. That said, make will treat
+ * the missing header file in a dependency rule as a target it has to build
+ * unless told otherwise. These dummy targets are added to the makefile
+ * to avoid a missing target error.
+ */
+ public class ResourceDeltaVisitor implements IResourceDeltaVisitor {
+ private GnuMakefileGenerator generator;
+ private IManagedBuildInfo info;
+
+ /**
+ * The constructor
+ */
+ public ResourceDeltaVisitor(GnuMakefileGenerator generator, IManagedBuildInfo info) {
+ this.generator = generator;
+ this.info = info;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta)
+ */
+ public boolean visit(IResourceDelta delta) throws CoreException {
+ // Should the visitor keep iterating in current directory
+ boolean keepLooking = false;
+ IResource resource = delta.getResource();
+
+ // What kind of resource change has occurred
+ if (resource.getType() == IResource.FILE) {
+ String ext = resource.getFileExtension();
+ boolean moved = false;
+ switch (delta.getKind()) {
+ case IResourceDelta.ADDED:
+ if (!generator.isGeneratedResource(resource)) {
+ // This is a source file so just add its container
+ if (info.buildsFileType(ext)) {
+ generator.appendModifiedSubdirectory(resource);
+ }
+ }
+ break;
+ case IResourceDelta.REMOVED:
+ // we get this notification if a resource is moved too
+ if (!generator.isGeneratedResource(resource)) {
+ // This is a source file so just add its container
+ if (info.buildsFileType(ext)) {
+ generator.appendModifiedSubdirectory(resource);
+ generator.appendDeletedFile(resource);
+ }
+ }
+ break;
+ default:
+ keepLooking = true;
+ break;
+ }
+ } if (resource.getType() == IResource.PROJECT) {
+ // If there is a zero-length delta, something the project depends on has changed so just call make
+ IResourceDelta[] children = delta.getAffectedChildren();
+ if (children != null && children.length > 0) {
+ keepLooking = true;
+ }
+ } else {
+ // If the resource is part of the generated directory structure don't recurse
+ if (!generator.isGeneratedResource(resource)) {
+ keepLooking = true;
+ }
+ }
+
+ return keepLooking;
+ }
+ }
+
+ public GnuMakefileGenerator() {
+ super();
+ }
+
+ /**
+ * @param project
+ * @param info
+ * @param monitor
+ */
+ public void initialize(IProject project, IManagedBuildInfo info, IProgressMonitor monitor) {
+ // Save the project so we can get path and member information
+ this.project = project;
+ // Save the monitor reference for reporting back to the user
+ this.monitor = monitor;
+ // Get the build info for the project
+ this.info = info;
+ // Get the name of the build target
+ buildTargetName = info.getBuildArtifactName();
+ // Get its extension
+ extension = info.getBuildArtifactExtension();
+ if (extension == null) {
+ extension = new String();
+ }
+ }
+
+ /* (non-Javadoc)
+ * Answers the argument with all whitespaces replaced with an escape sequence.
+ *
+ * @param path
+ */
+ protected String escapeWhitespaces(String path) {
+ // Escape the spaces in the path/filename if it has any
+ String[] segments = path.split("\\s"); //$NON-NLS-1$
+ if (segments.length > 1) {
+ StringBuffer escapedPath = new StringBuffer();
+ for (int index = 0; index < segments.length; ++index) {
+ escapedPath.append(segments[index]);
+ if (index + 1 < segments.length) {
+ escapedPath.append("\\ "); //$NON-NLS-1$
+ }
+ }
+ return escapedPath.toString().trim();
+ } else {
+ return path;
+ }
+ }
+
+ /* (non-Javadoc)
+ * Answers a <code>StringBuffer</code> containing the comment(s)
+ * for the top-level makefile.
+ */
+ protected StringBuffer addTopHeader() {
+ return addDefaultHeader();
+ }
+
+ /* (non-Javadoc)
+ * Answers a <code>StringBuffer</code> containing the comment(s)
+ * for a fragment makefile.
+ */
+ protected StringBuffer addFragmentMakefileHeader() {
+ return addDefaultHeader();
+ }
+
+ /* (non-Javadoc)
+ * Answers a <code>StringBuffer</code> containing the comment(s)
+ * for a dependency makefile.
+ */
+ protected StringBuffer addFragmentDependenciesHeader() {
+ return addDefaultHeader();
+ }
+
+ /* (non-Javadoc)
+ * Put COLS_PER_LINE comment charaters in the argument.
+ */
+ protected void outputCommentLine(StringBuffer buffer) {
+ for (int i = 0; i < COLS_PER_LINE; i++) {
+ buffer.append(COMMENT_SYMBOL);
+ }
+ buffer.append(NEWLINE);
+ }
+
+ /* (non-Javadoc)
+ * Outputs a comment formatted as follows:
+ * ##### ....... #####
+ * # <Comment message>
+ * ##### ....... #####
+ */
+ protected StringBuffer addDefaultHeader() {
+ StringBuffer buffer = new StringBuffer();
+ outputCommentLine(buffer);
+ buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(HEADER) + NEWLINE);
+ outputCommentLine(buffer);
+ buffer.append(NEWLINE);
+ return buffer;
+ }
+
+ /* (non-javadoc)
+ */
+ private StringBuffer addMacros() {
+ StringBuffer buffer = new StringBuffer();
+
+ // Add the ROOT macro
+ buffer.append("ROOT := .." + NEWLINE); //$NON-NLS-1$
+ buffer.append(NEWLINE);
+
+ // include makefile.init supplementary makefile
+ buffer.append("-include $(ROOT)" + SEPARATOR + MAKEFILE_INIT + NEWLINE); //$NON-NLS-1$
+ buffer.append(NEWLINE);
+
+ // Get the clean command from the build model
+ buffer.append("RM := "); //$NON-NLS-1$
+ buffer.append(info.getCleanCommand() + NEWLINE);
+ buffer.append(NEWLINE);
+
+ // Now add the source providers
+ buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(SRC_LISTS) + NEWLINE);
+ buffer.append("-include sources.mk" + NEWLINE); //$NON-NLS-1$
+ buffer.append("-include $(SUBDIRS:%=%/subdir.mk)" + NEWLINE); //$NON-NLS-1$
+ buffer.append("-include objects.mk" + NEWLINE); //$NON-NLS-1$
+ buffer.append("-include $(OBJS:%.o=%.d)" + NEWLINE); //$NON-NLS-1$
+ // Include makefile.defs supplemental makefile
+ buffer.append("-include $(ROOT)" + SEPARATOR + MAKEFILE_DEFS + NEWLINE); //$NON-NLS-1$
+
+
+ return (buffer.append(NEWLINE));
+ }
+
+ /* (non-javadoc)
+ * @return
+ */
+ private StringBuffer addSubdirectories() {
+ StringBuffer buffer = new StringBuffer();
+ // Add the comment
+ buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(MOD_LIST) + NEWLINE);
+
+ buffer.append("SUBDIRS := " + LINEBREAK); //$NON-NLS-1$
+
+ // Get all the module names
+ Iterator iter = getSubdirList().listIterator();
+ while (iter.hasNext()) {
+ IContainer container = (IContainer) iter.next();
+ // Check the special case where the module is the project root
+ if (container.getFullPath() == project.getFullPath()) {
+ buffer.append(DOT + WHITESPACE + LINEBREAK);
+ } else {
+ IPath path = container.getProjectRelativePath();
+ buffer.append(path.toString() + WHITESPACE + LINEBREAK);
+ }
+ }
+
+ buffer.append(NEWLINE);
+ return buffer;
+ }
+
+
+ /* (non-javadoc)
+ * Answers a <code>StringBuffer</code> containing all of the sources contributed by
+ * a container to the build.
+ *
+ * @param module
+ * @return StringBuffer
+ */
+ private StringBuffer addSources(IContainer module) throws CoreException {
+ // Calculate the new directory relative to the build output
+ IPath moduleRelativePath = module.getProjectRelativePath();
+ String relativePath = moduleRelativePath.toString();
+ relativePath += relativePath.length() == 0 ? "" : SEPARATOR; //$NON-NLS-1$
+
+ // get the target for this project
+ ITarget myTarget = info.getDefaultTarget();
+
+ // get the list of tools associated with our target
+ ITool toolArray[] = myTarget.getTools();
+
+ // For each tool for the target, lookup the kinds of sources it can handle and
+ // create a map which will map its extension to a string which holds its list of sources.
+ HashMap extensionToRuleStringMap = new HashMap();
+
+ // get the set of output extensions for all tools
+ Set outputExtensionsSet = getOutputExtentions();
+
+ // put in rules if the file type is not a generated file
+ for(int k = 0; k < toolArray.length; k++) {
+ List extensionsList = toolArray[k].getInputExtensions();
+ // iterate over all extensions that the tool knows how to handle
+ Iterator exListIterator = extensionsList.iterator();
+ while(exListIterator.hasNext()) {
+ // create a macro of the form "EXTENSION_SRCS := "
+ String extensionName = exListIterator.next().toString();
+ if(!extensionToRuleStringMap.containsKey(extensionName) && // do we already have a map entry?
+ !outputExtensionsSet.contains(extensionName)) { // is the file generated?
+
+ // Get the name in the proper macro format
+ StringBuffer macroName = getMacroName(extensionName);
+
+ // there is no entry in the map, so create a buffer for this extension
+ StringBuffer tempBuffer = new StringBuffer();
+ tempBuffer.append(macroName + WHITESPACE + "+=" + WHITESPACE + LINEBREAK); //$NON-NLS$-1
+ tempBuffer.append("${addprefix $(ROOT)/" + relativePath + "," + LINEBREAK); //$NON-NLS$-1 //$NON-NLS$-2
+
+ // have to store the buffer in String form as StringBuffer is not a sublcass of Object
+ extensionToRuleStringMap.put(extensionName, tempBuffer.toString());
+ }
+ }
+ }
+
+ // String buffers
+ StringBuffer buffer = new StringBuffer();
+ StringBuffer ruleBuffer = new StringBuffer(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(MOD_RULES) + NEWLINE);
+
+ // Visit the resources in this folder
+ IResource[] resources = module.members();
+ for (int i = 0; i < resources.length; i++) {
+ IResource resource = resources[i];
+ if (resource.getType() == IResource.FILE) {
+ String ext = resource.getFileExtension();
+ if (info.buildsFileType(ext)) {
+ // look for the extension in the map
+ StringBuffer bufferForExtension = new StringBuffer();
+ bufferForExtension.append(extensionToRuleStringMap.get(ext).toString());
+ if(bufferForExtension != null &&
+ !outputExtensionsSet.contains(bufferForExtension.toString())) {
+
+ bufferForExtension.append(resource.getName() + WHITESPACE + LINEBREAK);
+
+ // re-insert string in the map
+ extensionToRuleStringMap.put(ext, bufferForExtension.toString());
+
+ // Try to add the rule for the file
+ addRule(relativePath, ruleBuffer, resource);
+ }
+ }
+ }
+ }
+
+ // Write out the source info to the buffer
+ Collection bufferCollection = extensionToRuleStringMap.values();
+ Iterator collectionIterator = bufferCollection.iterator();
+ while(collectionIterator.hasNext())
+ {
+ // close off the rule and put two newlines to the buffer
+ StringBuffer currentBuffer = new StringBuffer();
+ currentBuffer.append(collectionIterator.next().toString());
+ currentBuffer.append("}" + NEWLINE + NEWLINE); //$NON-NLS-1$
+
+ // append the contents of the buffer to the master buffer for the whole file
+ buffer.append(currentBuffer);
+ }
+ return buffer.append(ruleBuffer + NEWLINE);
+ }
+
+ /* (non-javadoc)
+ * Answers a <code>StrinBuffer</code> containing all of the required targets to
+ * properly build the project.
+ *
+ * @return StringBuffer
+ */
+ private StringBuffer addTargets(boolean rebuild) {
+ StringBuffer buffer = new StringBuffer();
+
+ // Assemble the information needed to generate the targets
+ String cmd = info.getToolForTarget(extension);
+ String flags = info.getFlagsForTarget(extension);
+ String outflag = info.getOutputFlag(extension);
+ String outputPrefix = info.getOutputPrefix(extension);
+ String targets = rebuild ? "clean all" : "all"; //$NON-NLS-1$ //$NON-NLS-2$
+
+ // Get all the projects the build target depends on
+ IProject[] deps = null;
+ try {
+ deps = project.getReferencedProjects();
+ } catch (CoreException e) {
+ // There are 2 exceptions; the project does not exist or it is not open
+ // and neither conditions apply if we are building for it ....
+ }
+
+ // Write out the all target first in case someone just runs make
+ // all: targ_<target_name> [deps]
+ String defaultTarget = "all:"; //$NON-NLS-1$
+ if (deps.length > 0) {
+ defaultTarget += WHITESPACE + "deps"; //$NON-NLS-1$
+ }
+ buffer.append(defaultTarget + WHITESPACE + outputPrefix + buildTargetName);
+ if (extension.length() > 0) {
+ buffer.append(DOT + extension);
+ }
+ buffer.append(NEWLINE + NEWLINE);
+
+ /*
+ * The build target may depend on other projects in the workspace. These are
+ * captured in the deps target:
+ * deps:
+ * <cd <Proj_Dep_1/build_dir>; $(MAKE) [clean all | all]>
+ */
+ Vector managedProjectOutputs = new Vector();
+ if (deps.length > 0) {
+ buffer.append("deps:" + NEWLINE); //$NON-NLS-1$
+ if (deps != null) {
+ for (int i = 0; i < deps.length; i++) {
+ IProject dep = deps[i];
+ String buildDir = dep.getLocation().toString();
+ String depTargets = targets;
+ if (ManagedBuildManager.manages(dep)) {
+ // Add the current configuration to the makefile path
+ IManagedBuildInfo depInfo = ManagedBuildManager.getBuildInfo(dep);
+ buildDir += SEPARATOR + depInfo.getConfigurationName();
+
+ // Extract the build artifact to add to the dependency list
+ String depTarget = depInfo.getBuildArtifactName();
+ String depExt = depInfo.getBuildArtifactExtension();
+ String depPrefix = depInfo.getOutputPrefix(depExt);
+ if (depInfo.isDirty()) {
+ depTargets = "clean all"; //$NON-NLS-1$
+ }
+ String dependency = buildDir + SEPARATOR + depPrefix + depTarget;
+ if (depExt.length() > 0) {
+ dependency += DOT + depExt;
+ }
+ managedProjectOutputs.add(dependency);
+ }
+ buffer.append(TAB + "-cd" + WHITESPACE + buildDir + WHITESPACE + LOGICAL_AND + WHITESPACE + "$(MAKE) " + depTargets + NEWLINE); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ buffer.append(NEWLINE);
+ }
+
+ /*
+ * Write out the target rule as:
+ * targ_<prefix><target>.<extension>: $(OBJS) [<dep_proj_1_output> ... <dep_proj_n_output>]
+ * @echo 'Building target: $@'
+ * $(BUILD_TOOL) $(FLAGS) $(OUTPUT_FLAG) $@ $(OBJS) $(USER_OBJS) $(LIB_DEPS)
+ * @echo 'Finished building: $@'
+ * @echo
+ */
+ buffer.append(outputPrefix + buildTargetName);
+ if (extension.length() > 0) {
+ buffer.append(DOT + extension);
+ }
+ buffer.append(COLON + WHITESPACE + "$(OBJS)"); //$NON-NLS-1$
+ Iterator iter = managedProjectOutputs.listIterator();
+ while (iter.hasNext()) {
+ buffer.append(WHITESPACE + (String)iter.next());
+ }
+ buffer.append(NEWLINE);
+ buffer.append(TAB + AT + ECHO + WHITESPACE + SINGLE_QUOTE + MESSAGE_START_BUILD + WHITESPACE + OUT_MACRO + SINGLE_QUOTE + NEWLINE);
+ buffer.append(TAB + cmd + WHITESPACE + flags + WHITESPACE + outflag + WHITESPACE + OUT_MACRO + WHITESPACE + "$(OBJS) $(USER_OBJS) $(LIBS)" + NEWLINE); //$NON-NLS-1$
+ buffer.append(TAB + AT + ECHO + WHITESPACE + SINGLE_QUOTE + MESSAGE_FINISH_FILE + WHITESPACE + OUT_MACRO + SINGLE_QUOTE + NEWLINE + TAB + AT + ECHO + NEWLINE + NEWLINE);
+
+ // Always add a clean target
+ buffer.append("clean:" + NEWLINE); //$NON-NLS-1$
+ buffer.append(TAB + "-$(RM)" + WHITESPACE + "$(OBJS)" + WHITESPACE + "$(OBJS:%.o=%.d)" + WHITESPACE + outputPrefix + buildTargetName); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS$-3
+ if (extension.length() > 0) {
+ buffer.append(DOT + extension);
+ }
+ buffer.append(NEWLINE + NEWLINE);
+
+ buffer.append(".PHONY: all clean deps" + NEWLINE + NEWLINE); //$NON-NLS-1$
+
+ // Include makefile.targets supplemental makefile
+ buffer.append("-include $(ROOT)" + SEPARATOR + MAKEFILE_TARGETS + NEWLINE); //$NON-NLS-1$
+
+ return buffer;
+ }
+
+ /* (non-javadoc)
+ * Create the pattern rule in the format:
+ * <relative_path>/<name>.<outputExtension>: $(ROOT)/<relative_path>/<name>.<inputExtension>
+ * @echo 'Building file: $<'
+ * @<tool> <flags> <output_flag> $@ $< && \
+ * echo -n '<relative_path>/<name>.d <relative_path>/' >> <relative_path>/<name>.d && \
+ * <tool> -P -M -MG <flags> $< >> <relative_path>/<name>.d
+ * @echo 'Finished building: $<'
+ * @echo
+ *
+ * Note that the macros all come from the build model and are
+ * resolved to a real command before writing to the module
+ * makefile, so a real command might look something like:
+ * source1/foo.o: $(ROOT)/source1/foo.cpp
+ * @echo 'Building file: $<'
+ * @ g++ -g -O2 -c -I/cygdrive/c/eclipse/workspace/Project/headers -o $@ $< && \
+ * echo -n 'source1/foo.d source1/' >> source1/foo.d && \
+ * g++ -P -M -MG -g -O2 -c -I/cygdrive/c/eclipse/workspace/Project/headers $< >> source1/foo.d
+ * @echo 'Finished building: $<'
+ * @echo
+ *
+ * @param relativePath
+ * @param buffer
+ * @param resource
+ */
+ private void addRule(String relativePath, StringBuffer buffer, IResource resource) {
+ String buildFlags = null;
+ String resourceName = getFileName(resource);
+ String inputExtension = resource.getFileExtension();
+ String cmd = info.getToolForSource(inputExtension);
+ String outputExtension = info.getOutputExtension(inputExtension);
+ String outflag = null;
+ String outputPrefix = null;
+
+ // Add the rule and command to the makefile
+ String buildRule = relativePath + resourceName + DOT + outputExtension + COLON + WHITESPACE + ROOT + SEPARATOR + relativePath + resourceName + DOT + inputExtension;
+ buffer.append(buildRule + NEWLINE);
+ buffer.append(TAB + AT + ECHO + WHITESPACE + SINGLE_QUOTE + MESSAGE_START_FILE + WHITESPACE + IN_MACRO + SINGLE_QUOTE + NEWLINE);
+ buildFlags = info.getFlagsForSource(inputExtension);
+ outflag = info.getOutputFlag(outputExtension);
+ outputPrefix = info.getOutputPrefix(outputExtension);
+
+ // The command to build
+ buffer.append(TAB + AT + ECHO + WHITESPACE + cmd + WHITESPACE + buildFlags + WHITESPACE + outflag + WHITESPACE + outputPrefix + OUT_MACRO + WHITESPACE + IN_MACRO + NEWLINE);
+ buffer.append(TAB + AT + cmd + WHITESPACE + buildFlags + WHITESPACE + outflag + WHITESPACE + outputPrefix + OUT_MACRO + WHITESPACE + IN_MACRO);
+
+ // TODO determine if there are any deps to calculate
+ if (true) {
+ buffer.append(WHITESPACE + LOGICAL_AND + WHITESPACE + LINEBREAK);
+ // TODO get the dep rule out of the tool
+ String depRule = relativePath + resourceName + DOT + DEP_EXT;
+ buffer.append(TAB + ECHO + WHITESPACE + "-n" + WHITESPACE + SINGLE_QUOTE + depRule + WHITESPACE + relativePath + SINGLE_QUOTE + WHITESPACE + ">" + WHITESPACE + depRule + WHITESPACE + LOGICAL_AND + WHITESPACE + LINEBREAK); //$NON-NLS-1$ //$NON-NLS-2$
+ buffer.append(TAB + cmd + WHITESPACE + "-MM -MG -MP -P -w" + WHITESPACE + buildFlags + WHITESPACE + IN_MACRO + WHITESPACE + ">>" + WHITESPACE + depRule); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ // Say goodbye to the nice user
+ buffer.append(NEWLINE);
+ buffer.append(TAB + AT + ECHO + WHITESPACE + SINGLE_QUOTE + MESSAGE_FINISH_FILE + WHITESPACE + IN_MACRO + SINGLE_QUOTE + NEWLINE + TAB + AT + ECHO + NEWLINE + NEWLINE);
+
+ // Make sure we add the resource to the list of objects created during the build
+
+ }
+
+ /**
+ * Adds the container of the argument to the list of folders in the project that
+ * contribute source files to the build. The resource visitor has already established
+ * that the build model knows how to build the files. It has also checked that
+ * the resource is not generated as part of the build.
+ *
+ * @param resource
+ */
+ protected void appendBuildSubdirectory(IResource resource) {
+ IContainer container = resource.getParent();
+ if (!getSubdirList().contains(container)) {
+ getSubdirList().add(container);
+ }
+ }
+
+ /**
+ * Adds the container of the argument to a list of subdirectories that are part
+ * of an incremental rebuild of the project. The makefile fragments for these
+ * directories will be regenerated as a result of the build.
+ *
+ * @param resource
+ */
+ protected void appendModifiedSubdirectory(IResource resource) {
+ IContainer container = resource.getParent();
+ if (!getModifiedList().contains(container)) {
+ getModifiedList().add(container);
+ }
+ }
+
+ /**
+ * If a file is removed from a source folder (either because of a delete
+ * or move action on the part of the user), the makefilegenerator has to
+ * remove the dependency makefile along with the old build goal
+ *
+ * @param resource
+ */
+ protected void appendDeletedFile(IResource resource) {
+ // Cache this for now
+ getDeletedFileList().add(resource);
+ }
+
+
+ /**
+ * @return
+ */
+ private Vector getDeletedFileList() {
+ if (deletedFileList == null) {
+ deletedFileList = new Vector();
+ }
+ return deletedFileList;
+ }
+
+ /* (non-Javadoc)
+ * @param message
+ */
+ protected void cancel(String message) {
+ if (monitor != null && !monitor.isCanceled()) {
+ throw new OperationCanceledException(message);
+ }
+ }
+
+ /**
+ * Check whether the build has been cancelled. Cancellation requests
+ * propagated to the caller by throwing <code>OperationCanceledException</code>.
+ *
+ * @see org.eclipse.core.runtime.OperationCanceledException#OperationCanceledException()
+ */
+ protected void checkCancel() {
+ if (monitor != null && monitor.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator#generateDependencies()
+ */
+ public void generateDependencies() throws CoreException {
+ // A NOP for this generator
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator#generateMakefiles(org.eclipse.core.resources.IResourceDelta)
+ */
+ public void generateMakefiles(IResourceDelta delta) throws CoreException {
+ /*
+ * Let's do a sanity check right now.
+ *
+ * 1. This is an incremental build, so if the top-level directory is not
+ * there, then a rebuild is needed.
+ */
+ IFolder folder = project.getFolder(info.getConfigurationName());
+ if (!folder.exists()) {
+ regenerateMakefiles();
+ return;
+ }
+
+ // Make sure the build directory is available
+ topBuildDir = createDirectory(info.getConfigurationName());
+ checkCancel();
+
+ // Visit the resources in the delta and compile a list of subdirectories to regenerate
+ ResourceDeltaVisitor visitor = new ResourceDeltaVisitor(this, info);
+ delta.accept(visitor);
+ checkCancel();
+
+ // Get all the subdirectories participating in the build
+ ResourceProxyVisitor resourceVisitor = new ResourceProxyVisitor(this, info);
+ project.accept(resourceVisitor, IResource.NONE);
+ IPath srcsFilePath = topBuildDir.addTrailingSeparator().append(SRCSFILE_NAME);
+ IFile srcsFileHandle = createFile(srcsFilePath);
+ populateSourcesMakefile(srcsFileHandle);
+ checkCancel();
+
+ // If any header files have been moved we have to regenerate all the dep files
+
+
+ // Regenerate any fragments that are missing for the exisiting directories NOT modified
+ Iterator iter = getSubdirList().listIterator();
+ while (iter.hasNext()) {
+ IContainer subdirectory = (IContainer)iter.next();
+ if (!getModifiedList().contains(subdirectory)) {
+ // Make sure a fragment makefile exists
+ IPath fragmentPath = getBuildWorkingDir().append(subdirectory.getProjectRelativePath()).addTrailingSeparator().append(MODFILE_NAME);
+ IFile makeFragment = project.getFile(fragmentPath);
+ if (!makeFragment.exists()) {
+ // If one or both are missing, then add it to the list to be generated
+ getModifiedList().add(subdirectory);
+ }
+ }
+ }
+
+ // Delete the old dependency files for any deleted resources
+ iter = getDeletedFileList().listIterator();
+ while (iter.hasNext()) {
+ IResource deletedFile = (IResource)iter.next();
+ deleteDepFile(deletedFile);
+ deleteBuildTarget(deletedFile);
+ }
+
+ // Re-create the top-level makefile
+ IPath makefilePath = topBuildDir.addTrailingSeparator().append(MAKEFILE_NAME);
+ IFile makefileHandle = createFile(makefilePath);
+ populateTopMakefile(makefileHandle, false);
+ checkCancel();
+
+ // Regenerate any fragments for modified directories
+ iter = getModifiedList().listIterator();
+ while (iter.hasNext()) {
+ IContainer subDir = (IContainer) iter.next();
+ populateFragmentMakefile(subDir);
+ checkCancel();
+ }
+ }
+
+ /**
+ * Strips off the file extension from the argument and returns
+ * the name component in a <code>String</code>
+ *
+ * @param file
+ * @return
+ */
+ private String getFileName(IResource file) {
+ String answer = new String();
+ String lastSegment = file.getName();
+ int extensionSeparator = lastSegment.lastIndexOf(DOT);
+ if (extensionSeparator != -1) {
+ answer = lastSegment.substring(0, extensionSeparator);
+ }
+ return answer;
+ }
+
+ protected StringBuffer getMacroName(String extensionName) {
+ StringBuffer macroName = new StringBuffer();
+
+ // We need to handle case sensitivity in file extensions (e.g. .c vs .C), so if the
+ // extension was already upper case, tack on an "UPPER_" to the macro name.
+ // In theory this means there could be a conflict if you had for example,
+ // extensions .c_upper, and .C, but realistically speaking the chances of this are
+ // practically nil so it doesn't seem worth the hassle of generating a truly
+ // unique name.
+ if(extensionName.equals(extensionName.toUpperCase())) {
+ macroName.append(extensionName.toUpperCase() + "_UPPER"); //$NON-NLS$-1
+ } else {
+ // lower case... no need for "UPPER_"
+ macroName.append(extensionName.toUpperCase());
+ }
+ macroName.append("_SRCS"); //$NON-NLS$-1
+ return macroName;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator#getMakefileName()
+ */
+ public String getMakefileName() {
+ return new String(MAKEFILE_NAME);
+ }
+
+ /* (non-javadoc)
+ *
+ * @return List
+ */
+ private Vector getModifiedList() {
+ if (modifiedList == null) {
+ modifiedList = new Vector();
+ }
+ return modifiedList;
+ }
+
+ protected Set getOutputExtentions() {
+ // Get the target for this project
+ ITarget myTarget = info.getDefaultTarget();
+
+ // Get the list of tools associated with our target
+ ITool toolArray[] = myTarget.getTools();
+
+ // The set of output extensions which will be produced by this tool.
+ // It is presumed that this set is not very large (likely < 10) so
+ // a HashSet should provide good performance.
+ HashSet outputExtensionsSet = new HashSet();
+
+ // For each tool for the target, lookup the kinds of sources it outputs
+ // and add that to our list of output extensions.
+ for(int k = 0; k < toolArray.length; k++)
+ {
+ String[] outputs = toolArray[k].getOutputExtensions();
+ outputExtensionsSet.addAll(Arrays.asList(outputs));
+ }
+ return outputExtensionsSet;
+ }
+
+ /* (non-javadoc)
+ * Answers the list of known build rules. This keeps me from generating duplicate
+ * rules for known file extensions.
+ *
+ * @return List
+ */
+ private Vector getRuleList() {
+ if (ruleList == null) {
+ ruleList = new Vector();
+ }
+ return ruleList;
+ }
+
+ /* (non-javadoc)
+ * Answers the list of subdirectories contributing source code to the build
+ *
+ * @return List
+ */
+ private Vector getSubdirList() {
+ if (subdirList == null) {
+ subdirList = new Vector();
+ }
+ return subdirList;
+ }
+
+ /* (non-Javadoc)
+ * Return or create the folder needed for the build output. If we are
+ * creating the folder, set the derived bit to true so the CM system
+ * ignores the contents. If the resource exists, respect the existing
+ * derived setting.
+ *
+ * @param string
+ * @return IPath
+ */
+ private IPath createDirectory(String dirName) throws CoreException {
+ // Create or get the handle for the build directory
+ IFolder folder = project.getFolder(dirName);
+ if (!folder.exists()) {
+ // Make sure that parent folders exist
+ IPath parentPath = (new Path(dirName)).removeLastSegments(1);
+ // Assume that the parent exists if the path is empty
+ if (!parentPath.isEmpty()) {
+ IFolder parent = project.getFolder(parentPath);
+ if (!parent.exists()) {
+ createDirectory(parentPath.toString());
+ }
+ }
+
+ // Now make the requested folder
+ try {
+ folder.create(true, true, null);
+ }
+ catch (CoreException e) {
+ if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED)
+ folder.refreshLocal(IResource.DEPTH_ZERO, null);
+ else
+ throw e;
+ }
+
+ // Make sure the folder is marked as derived so it is not added to CM
+ if (!folder.isDerived()) {
+ folder.setDerived(true);
+ }
+ }
+
+ return folder.getFullPath();
+ }
+
+ /**
+ * @param deletedFile
+ */
+ private void deleteBuildTarget(IResource deletedFile) {
+ // Get the project relative path of the file
+ String fileName = getFileName(deletedFile);
+ String srcExtension = deletedFile.getFileExtension();
+ String targetExtension = info.getOutputExtension(srcExtension);
+ fileName += DOT + targetExtension;
+ IPath projectRelativePath = deletedFile.getProjectRelativePath().removeLastSegments(1);
+ IPath targetFilePath = getBuildWorkingDir().append(projectRelativePath).append(fileName);
+ IResource depFile = project.findMember(targetFilePath);
+ if (depFile != null && depFile.exists()) {
+ try {
+ depFile.delete(true, new SubProgressMonitor(monitor, 1));
+ } catch (CoreException e) {
+ // This had better be allowed during a build
+ ManagedBuilderCorePlugin.log(e);
+ }
+ }
+ }
+
+ /**
+ * @param deletedFile
+ */
+ private void deleteDepFile(IResource deletedFile) {
+ // Get the project relative path of the file
+ String fileName = getFileName(deletedFile);
+ fileName += DOT + DEP_EXT;
+ IPath projectRelativePath = deletedFile.getProjectRelativePath().removeLastSegments(1);
+ IPath depFilePath = getBuildWorkingDir().append(projectRelativePath).append(fileName);
+ IResource depFile = project.findMember(depFilePath);
+ if (depFile != null && depFile.exists()) {
+ try {
+ depFile.delete(true, new SubProgressMonitor(monitor, 1));
+ } catch (CoreException e) {
+ // This had better be allowed during a build
+ ManagedBuilderCorePlugin.log(e);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * Return or create the makefile needed for the build. If we are creating
+ * the resource, set the derived bit to true so the CM system ignores
+ * the contents. If the resource exists, respect the existing derived
+ * setting.
+ *
+ * @param makefilePath
+ * @return IFile
+ */
+ private IFile createFile(IPath makefilePath) throws CoreException {
+ // Create or get the handle for the makefile
+ IWorkspaceRoot root = CCorePlugin.getWorkspace().getRoot();
+ IFile newFile = root.getFileForLocation(makefilePath);
+ if (newFile == null) {
+ newFile = root.getFile(makefilePath);
+ }
+ // Create the file if it does not exist
+ ByteArrayInputStream contents = new ByteArrayInputStream(new byte[0]);
+ try {
+ newFile.create(contents, false, monitor);
+ // Make sure the new file is marked as derived
+ if (!newFile.isDerived()) {
+ newFile.setDerived(true);
+ }
+
+ }
+ catch (CoreException e) {
+ // If the file already existed locally, just refresh to get contents
+ if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED)
+ newFile.refreshLocal(IResource.DEPTH_ZERO, null);
+ else
+ throw e;
+ }
+
+ return newFile;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator#getTopBuildDir()
+ */
+ public IPath getBuildWorkingDir() {
+ return topBuildDir.removeFirstSegments(1);
+ }
+
+ /**
+ * Answers <code>true</code> if the argument is found in a generated container
+ * @param resource
+ * @return boolean
+ */
+ protected boolean isGeneratedResource(IResource resource) {
+ // Is this a generated directory ...
+ IPath path = resource.getProjectRelativePath();
+ String[] configNames = info.getConfigurationNames();
+ for (int i = 0; i < configNames.length; i++) {
+ String name = configNames[i];
+ IPath root = new Path(name);
+ // It is if it is a root of the resource pathname
+ if (root.isPrefixOf(path)) return true;
+ }
+
+ return false;
+ }
+
+ /* (non-javadoc)
+ * Create the entire contents of the makefile.
+ *
+ * @param fileHandle The file to place the contents in.
+ * @param rebuild FLag signalling that the user is doing a full rebuild
+ * @throws CoreException
+ */
+ protected void populateTopMakefile(IFile fileHandle, boolean rebuild) throws CoreException {
+ StringBuffer buffer = new StringBuffer();
+
+ // Add the header
+ buffer.append(addTopHeader());
+
+ // Add the macro definitions
+ buffer.append(addMacros());
+
+ // Add targets
+ buffer.append(addTargets(rebuild));
+
+ // Save the file
+ Util.save(buffer, fileHandle);
+ }
+
+ /* (non-javadoc)
+ * @param module
+ * @throws CoreException
+ */
+ protected void populateFragmentMakefile(IContainer module) throws CoreException {
+ // Calcualte the new directory relative to the build output
+ IPath moduleRelativePath = module.getProjectRelativePath();
+ IPath buildRoot = getBuildWorkingDir();
+ if (buildRoot == null) {
+ return;
+ }
+ IPath moduleOutputPath = buildRoot.append(moduleRelativePath);
+
+ // Now create the directory
+ IPath moduleOutputDir = createDirectory(moduleOutputPath.toString());
+
+ // Create a module makefile
+ IFile modMakefile = createFile(moduleOutputDir.addTrailingSeparator().append(MODFILE_NAME));
+ StringBuffer makeBuf = new StringBuffer();
+ makeBuf.append(addFragmentMakefileHeader());
+ makeBuf.append(addSources(module));
+
+ // Save the files
+ Util.save(makeBuf, modMakefile);
+ }
+
+ /**
+ * The makefile generator "knows" about source files participating in the
+ * the build. It does not keep track of the targets that the build produces.
+ * Instead, it keeps a set of transformation macros that it supplies to the
+ * makefile so that the source names can be transofrmed into the target names
+ * using the built-in string substitution functions of <code>make</code>.
+ *
+ * @param fileHandle The file that should be populated with the output
+ * @throws CoreException
+ */
+ protected void populateObjectsMakefile(IFile fileHandle) throws CoreException {
+ // Master list of "object" dependencies, i.e. dependencies between input files and output files.
+ StringBuffer macroBuffer = new StringBuffer();
+ macroBuffer.append(addDefaultHeader());
+ StringBuffer objectsBuffer = new StringBuffer();
+ objectsBuffer.append("OBJS := " + LINEBREAK); //$NON-NLS-1$
+
+ // Add the libraries this project depends on
+ macroBuffer.append("LIBS := "); //$NON-NLS-1$
+ String[] libs = info.getLibsForTarget(extension);
+ for (int i = 0; i < libs.length; i++) {
+ String string = libs[i];
+ macroBuffer.append(LINEBREAK + string);
+ }
+ macroBuffer.append(NEWLINE);
+
+ // Add the extra user-specified objects
+ macroBuffer.append("USER_OBJS := "); //$NON-NLS-1$
+ String[] userObjs = info.getUserObjectsForTarget(extension);
+ for (int j = 0; j < userObjs.length; j++) {
+ String string = userObjs[j];
+ macroBuffer.append(LINEBREAK + string);
+ }
+ macroBuffer.append(NEWLINE);
+
+ // Dependencies for generated files will not appear here. I.e., if you have a tool which turns
+ // A into B, and then another tool which turns B into C, you will only get dependency info
+ // which says that B depends on A.
+ // TODO Handle dependencies for complex chains of the form A->B->C
+ ITarget myTarget = info.getDefaultTarget();
+
+ // get the list of tools associated with our target
+ ITool toolArray[] = myTarget.getTools();
+
+ // get the set of output extensions for all tools
+ Set outputExtensionsSet = getOutputExtentions();
+
+ // set of input extensions for which rules have been created so far
+ HashSet handledInputExtensionsSet = new HashSet();
+
+ // Look at each input extension and generate an appropriate macro for that extension
+ // based on whether the file is generated or not. We do not want to create rules for
+ // generated files due to the current way the makefile is structured.
+ for(int k = 0; k < toolArray.length; k++) {
+ List extensionsList = toolArray[k].getInputExtensions();
+
+ // iterate over all extensions that the tool knows how to handle
+ Iterator exListIterator = extensionsList.iterator();
+ while(exListIterator.hasNext()) {
+ String extensionName = exListIterator.next().toString();
+
+ // If we are a regular file we get added to the list of object dependencies
+ // if we have not already created a rule for this filetype. It is assumed that
+ // if multiple tools can handle the same input file extension that they will
+ // all map the input extension to the same output extension. This is not explicitly
+ // checked however.
+
+ // Generated files should not appear in the list.
+ if(!outputExtensionsSet.contains(extensionName) && !handledInputExtensionsSet.contains(extensionName)) {
+ handledInputExtensionsSet.add(extensionName);
+ StringBuffer macroName = getMacroName(extensionName);
+
+ // create dependency rule of the form
+ // OBJS = $(macroName1: $(ROOT)/%.input1=%.output1) ... $(macroNameN: $(ROOT)/%.inputN=%.outputN)
+ objectsBuffer.append(WHITESPACE + "$(" + macroName + COLON + "$(ROOT)" + SEPARATOR + WILDCARD
+ + DOT + extensionName + "=" + WILDCARD + DOT +
+ toolArray[k].getOutputExtension(extensionName) + ")" );
+ }
+ }
+ }
+
+ macroBuffer.append(NEWLINE + NEWLINE + objectsBuffer);
+
+ // For now, just save the buffer that was populated when the rules were created
+ Util.save(macroBuffer, fileHandle);
+ }
+
+ /**
+ * @param fileHandle
+ * @throws CoreException
+ */
+ protected void populateSourcesMakefile(IFile fileHandle) throws CoreException {
+ // Add the comment
+ StringBuffer buffer = addDefaultHeader();
+
+ // Add the known macros
+ ITarget myTarget = info.getDefaultTarget();
+ ITool toolArray[] = myTarget.getTools();
+ Set outputExtensionsSet = getOutputExtentions();
+ HashSet handledInputExtensionsSet = new HashSet();
+ for(int k = 0; k < toolArray.length; k++) {
+ List extensionsList = toolArray[k].getInputExtensions();
+ Iterator exListIterator = extensionsList.iterator();
+ while(exListIterator.hasNext()) {
+ // create a macro of the form "EXTENSION_SRCS :="
+ String extensionName = exListIterator.next().toString();
+ if(!outputExtensionsSet.contains(extensionName) && !handledInputExtensionsSet.contains(extensionName)) {
+ handledInputExtensionsSet.add(extensionName);
+ StringBuffer macroName = getMacroName(extensionName);
+ buffer.append(macroName + WHITESPACE + ":=" + WHITESPACE + NEWLINE);
+ }
+ }
+ }
+
+ // Add a list of subdirectories
+ buffer.append(NEWLINE + addSubdirectories());
+
+ // Save the file
+ Util.save(buffer, fileHandle);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator#regenerateDependencies()
+ */
+ public void regenerateDependencies(boolean force) throws CoreException {
+ // A hack for the pre-3.x GCC compilers is to put dummy targets for deps
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator#regenerateMakefiles()
+ */
+ public void regenerateMakefiles() throws CoreException {
+ // Visit the resources in the project
+ ResourceProxyVisitor visitor = new ResourceProxyVisitor(this, info);
+ project.accept(visitor, IResource.NONE);
+
+ // See if the user has cancelled the build
+ checkCancel();
+
+ // Populate the makefile if any source files have been found in the project
+ if (getSubdirList().isEmpty()) {
+ return;
+ }
+
+ // Create the top-level directory for the build output
+ topBuildDir = createDirectory(info.getConfigurationName());
+ checkCancel();
+
+ // Get the list of subdirectories
+ IPath srcsFilePath = topBuildDir.addTrailingSeparator().append(SRCSFILE_NAME);
+ IFile srcsFileHandle = createFile(srcsFilePath);
+ populateSourcesMakefile(srcsFileHandle);
+ checkCancel();
+
+ // Now populate the module makefiles
+ Iterator iter = getSubdirList().listIterator();
+ while (iter.hasNext()) {
+ IContainer subDir = (IContainer)iter.next();
+ try {
+ populateFragmentMakefile(subDir);
+ } catch (CoreException e) {
+ // Probably should ask user if they want to continue
+ checkCancel();
+ continue;
+ }
+ checkCancel();
+ }
+
+ // Create the top-level makefile
+ IPath makefilePath = topBuildDir.addTrailingSeparator().append(MAKEFILE_NAME);
+ IFile makefileHandle = createFile(makefilePath);
+ populateTopMakefile(makefileHandle, true);
+ checkCancel();
+
+ // Now finish up by adding all the object files
+ IPath objFilePath = topBuildDir.addTrailingSeparator().append("objects.mk");
+ IFile objsFileHandle = createFile(objFilePath);
+ populateObjectsMakefile(objsFileHandle);
+ checkCancel();
+ }
+
+}

Back to the top