diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IConfiguration.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IConfiguration.java
index 1b38abfc526..1dfa8052558 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IConfiguration.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IConfiguration.java
@@ -74,6 +74,15 @@ public interface IConfiguration extends IBuildObject {
*/
public boolean isDirty();
+ /**
+ * Answers whether the receiver has been changed and requires the
+ * project to be rebuilt.
+ *
+ * @return true
if the receiver contains a change
+ * that needs the project to be rebuilt
+ */
+ public boolean needsRebuild();
+
/**
* @param isDirty
*/
@@ -119,6 +128,14 @@ public interface IConfiguration extends IBuildObject {
public void setOption(IOption option, String[] value)
throws BuildException;
+ /**
+ * Sets the rebuild state in the receiver.
+ *
+ * @param rebuild true
will force a rebuild the next time the project builds
+ * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setRebuildState(boolean)
+ */
+ void setRebuildState(boolean rebuild);
+
/**
* Overrides the tool command for a tool defined in the receiver.
*
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IManagedBuildInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IManagedBuildInfo.java
index 8c2cd4fffbd..71a8be46fba 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IManagedBuildInfo.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IManagedBuildInfo.java
@@ -208,6 +208,23 @@ public interface IManagedBuildInfo {
*/
public String getVersion();
+
+ /**
+ * Answers whether the receiver has been changed and requires the
+ * project to be rebuilt. When a project is first created, it is
+ * assumed that the user will need it to be fully rebuilt. However
+ * only option and tool command changes will trigger the build
+ * information for an existing project to require a rebuild.
+ *
+ * Clients can reset the state to force or clear the rebuild status
+ * using setRebuildState()
+ * @see ManagedBuildInfo#setRebuildState(boolean)
+ *
+ * @return true
if the resource managed by the
+ * receiver needs to be rebuilt
+ */
+ public boolean needsRebuild();
+
/**
* Answers true if the build model has been changed by the user.
*
@@ -248,6 +265,16 @@ public interface IManagedBuildInfo {
*/
public void setDefaultTarget(ITarget target);
+ /**
+ * Sets the rebuild state in the receiver to the value of the argument.
+ * This is a potentially expensive option, so setting it to true should
+ * only be done if a project resource or setting has been modified in a
+ * way that would invalidate the previous build.
+ *
+ * @param true
will force a rebuild the next time the project builds
+ */
+ public void setRebuildState(boolean rebuild);
+
/**
* Set the currently selected target. This is used while the project
* property pages are displayed
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ITarget.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ITarget.java
index c62e85fa60b..0462f35c9cb 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ITarget.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ITarget.java
@@ -217,6 +217,15 @@ public interface ITarget extends IBuildObject {
*/
public boolean isTestTarget();
+ /**
+ * Answers whether the receiver has been changed and requires the
+ * project to be rebuilt.
+ *
+ * @return true
if the receiver contains a change
+ * that needs the project to be rebuilt
+ */
+ public boolean needsRebuild();
+
/**
* Removes the configuration with the ID specified in the argument.
*
@@ -270,10 +279,19 @@ public interface ITarget extends IBuildObject {
*/
public void setErrorParserIds(String ids);
+ /**
+ * Set the rebuild state of the receiver.
+ *
+ * @param true
will force a rebuild the next time the project builds
+ * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setRebuildState(boolean)
+ */
+ public void setRebuildState(boolean rebuild);
+
/**
* Sets the resource that owns the receiver.
*
* @param resource
*/
public void updateOwner(IResource resource);
+
}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java
index 4cd8e42b5d9..d512be1269e 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java
@@ -37,6 +37,7 @@ import org.w3c.dom.NodeList;
public class Configuration extends BuildObject implements IConfiguration {
private boolean isDirty = false;
private IConfiguration parent;
+ private boolean rebuildNeeded = false;
private boolean resolved = true;
private ITarget target;
private List toolReferences;
@@ -374,6 +375,12 @@ public class Configuration extends BuildObject implements IConfiguration {
return isDirty;
}
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.core.IConfiguration#needsRebuild()
+ */
+ public boolean needsRebuild() {
+ return rebuildNeeded;
+ }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.build.managed.IConfiguration#getParent()
@@ -549,6 +556,7 @@ public class Configuration extends BuildObject implements IConfiguration {
if (option.getBooleanValue() != value) {
createOptionReference(option).setValue(value);
isDirty = true;
+ rebuildNeeded = true;
}
}
@@ -567,6 +575,7 @@ public class Configuration extends BuildObject implements IConfiguration {
if (oldValue != null && !oldValue.equals(value)) {
createOptionReference(option).setValue(value);
isDirty = true;
+ rebuildNeeded = true;
}
}
@@ -599,9 +608,17 @@ public class Configuration extends BuildObject implements IConfiguration {
if(!Arrays.equals(value, oldValue)) {
createOptionReference(option).setValue(value);
isDirty = true;
+ rebuildNeeded = true;
}
}
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.core.IConfiguration#setRebuildState(boolean)
+ */
+ public void setRebuildState(boolean rebuild) {
+ rebuildNeeded = rebuild;
+ }
+
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.core.IConfiguration#setToolCommand(org.eclipse.cdt.managedbuilder.core.ITool, java.lang.String)
*/
@@ -617,6 +634,7 @@ public class Configuration extends BuildObject implements IConfiguration {
// Set the ref's command
if (ref != null) {
isDirty = ref.setToolCommand(command);
+ rebuildNeeded = isDirty;
}
}
}
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 ec850616f3d..daa8d9300e2 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
@@ -40,7 +40,6 @@ import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
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;
@@ -53,6 +52,12 @@ import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubProgressMonitor;
+/**
+ * This is the incremental builder associated with a managed build project. It dynamically
+ * decides the makefile generator it wants to use for a specific target.
+ *
+ * @since 1.2
+ */
public class GeneratedMakefileBuilder extends ACBuilder {
// String constants
private static final String MESSAGE = "ManagedMakeBuilder.message"; //$NON-NLS-1$
@@ -64,6 +69,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
private static final String REFRESH = MESSAGE + ".updating"; //$NON-NLS-1$
private static final String MARKERS = MESSAGE + ".creating.markers"; //$NON-NLS-1$
private static final String CONSOLE_HEADER = MESSAGE + ".console.header"; //$NON-NLS-1$
+ private static final String TYPE_CLEAN = "ManagedMakeBuilder.type.clean"; //$NON-NLS-1$
private static final String TYPE_FULL = "ManagedMakeBuilder.type.full"; //$NON-NLS-1$
private static final String TYPE_INC = "ManagedMakeBuider.type.incremental"; //$NON-NLS-1$
@@ -73,13 +79,66 @@ public class GeneratedMakefileBuilder extends ACBuilder {
protected IManagedBuilderMakefileGenerator generator;
public class ResourceDeltaVisitor implements IResourceDeltaVisitor {
- private boolean buildNeeded = false;
+ private boolean buildNeeded = true;
+ private IManagedBuildInfo buildInfo;
+ private List reservedNames;
+
+ /**
+ *
+ */
+ public ResourceDeltaVisitor(IManagedBuildInfo info) {
+ buildInfo = info;
+ reservedNames = Arrays.asList(new String[]{".cdtbuild", ".cdtproject", ".project"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ /**
+ * @param changedResource
+ * @return
+ */
+ private boolean isGeneratedResource(IResource resource) {
+ // Is this a generated directory ...
+ IPath path = resource.getProjectRelativePath();
+ String[] configNames = buildInfo.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;
+ }
+
+ /**
+ * @param resource
+ * @return
+ */
+ private boolean isProjectFile(IResource resource) {
+ return reservedNames.contains(resource.getName());
+ }
+
public boolean visit(IResourceDelta delta) throws CoreException {
IResource resource = delta.getResource();
// If the project has changed, then a build is needed and we can stop
if (resource != null && resource.getProject() == getProject()) {
- buildNeeded = true;
+ IResourceDelta[] kids = delta.getAffectedChildren();
+ for (int index = kids.length - 1; index >= 0; --index) {
+ IResource changedResource = kids[index].getResource();
+ String ext = changedResource.getFileExtension();
+ // There are some things we don't care about
+ if (resource.isDerived()) {
+ buildNeeded = false;
+ } else if (isGeneratedResource(changedResource)) {
+ buildNeeded = false;
+ } else if (buildInfo.buildsFileType(ext) || buildInfo.isHeaderFile(ext)) {
+ // We do care and there is no point checking anythings else
+ buildNeeded = true;
+ break;
+ } else if (isProjectFile(changedResource)) {
+ buildNeeded = false;
+ } else {
+ buildNeeded = true;
+ }
+ }
return false;
}
@@ -92,7 +151,8 @@ public class GeneratedMakefileBuilder extends ACBuilder {
}
/**
- *
+ * Zero-argument constructor needed to fulfill the contract of an
+ * incremental builder.
*/
public GeneratedMakefileBuilder() {
}
@@ -101,23 +161,28 @@ 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 {
- IProject[] deps = getProject().getReferencedProjects();
+ // We should always tell the build system what projects we reference
+ IProject[] refdProjects = getProject().getReferencedProjects();
// Get the build information
IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(getProject());
if (info == null) {
- return deps;
+ return refdProjects;
}
- if (kind == IncrementalProjectBuilder.FULL_BUILD || info.isDirty()) {
+ // So let's figure out why we got called
+ if (kind == CLEAN_BUILD) {
+ cleanBuild(monitor, info);
+ }
+ else if (kind == FULL_BUILD || info.needsRebuild()) {
fullBuild(monitor, info);
}
- else if (kind == IncrementalProjectBuilder.AUTO_BUILD && info.isDirty()) {
+ else if (kind == AUTO_BUILD && info.needsRebuild()) {
fullBuild(monitor, info);
}
else {
// Create a delta visitor to make sure we should be rebuilding
- ResourceDeltaVisitor visitor = new ResourceDeltaVisitor();
+ ResourceDeltaVisitor visitor = new ResourceDeltaVisitor(info);
IResourceDelta delta = getDelta(getProject());
if (delta == null) {
fullBuild(monitor, info);
@@ -131,20 +196,33 @@ public class GeneratedMakefileBuilder extends ACBuilder {
}
// Scrub the build info of all the projects participating in the build
- info.setDirty(false);
- for (int i = 0; i < deps.length; i++) {
- IProject project = deps[i];
+ info.setRebuildState(false);
+ for (int i = 0; i < refdProjects.length; i++) {
+ IProject project = refdProjects[i];
IManagedBuildInfo depInfo = ManagedBuildManager.getBuildInfo(project);
// May not be a managed project
if (depInfo != null) {
- depInfo.setDirty(false);
+ depInfo.setRebuildState(false);
}
}
// Ask build mechanism to compute deltas for project dependencies next time
- return deps;
+ return refdProjects;
}
+ /**
+ * @param monitor
+ * @param info
+ */
+ protected void cleanBuild(IProgressMonitor monitor, IManagedBuildInfo info) {
+ // Make sure that there is a top level directory and a set of makefiles
+
+
+ // invoke make with the clean argument
+
+ }
+
+
/**
* Check whether the build has been canceled. Cancellation requests
* propagated to the caller by throwing OperationCanceledException
.
@@ -203,7 +281,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
monitor.subTask(statusMsg);
IPath topBuildDir = generator.getBuildWorkingDir();
if (topBuildDir != null) {
- invokeMake(true, topBuildDir, info, monitor);
+ invokeMake(FULL_BUILD, topBuildDir, info, monitor);
} else {
statusMsg = ManagedMakeMessages.getFormattedString(NOTHING_BUILT, getProject().getName()); //$NON-NLS-1$
monitor.subTask(statusMsg);
@@ -263,12 +341,18 @@ public class GeneratedMakefileBuilder extends ACBuilder {
* @param fullBuild
* @return
*/
- protected String[] getMakeTargets(boolean fullBuild) {
+ protected String[] getMakeTargets(int buildType) {
List args = new ArrayList();
- if (fullBuild) {
- args.add("clean"); //$NON-NLS-1$
+ switch (buildType) {
+ case CLEAN_BUILD:
+ args.add("clean"); //$NON-NLS-1$
+ break;
+ case FULL_BUILD:
+ args.add("clean"); //$NON-NLS-1$
+ case INCREMENTAL_BUILD:
+ args.add("all"); //$NON-NLS-1$
+ break;
}
- args.add("all"); //$NON-NLS-1$
return (String[])args.toArray(new String[args.size()]);
}
@@ -349,11 +433,11 @@ public class GeneratedMakefileBuilder extends ACBuilder {
monitor.worked(1);
// Run the build
- statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.starting", getProject().getName());
+ statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.starting", getProject().getName()); //$NON-NLS-1$
monitor.subTask(statusMsg);
IPath buildDir = new Path(info.getConfigurationName());
if (buildDir != null) {
- invokeMake(false, buildDir, info, monitor);
+ invokeMake(INCREMENTAL_BUILD, buildDir, info, monitor);
} else {
statusMsg = ManagedMakeMessages.getFormattedString(NOTHING_BUILT, getProject().getName()); //$NON-NLS-1$
monitor.subTask(statusMsg);
@@ -383,7 +467,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
* @param info
* @param monitor
*/
- protected void invokeMake(boolean fullBuild, IPath buildDir, IManagedBuildInfo info, IProgressMonitor monitor) {
+ protected void invokeMake(int buildType, IPath buildDir, IManagedBuildInfo info, IProgressMonitor monitor) {
// Get the project and make sure there's a monitor to cancel the build
IProject currentProject = getProject();
if (monitor == null) {
@@ -420,9 +504,18 @@ public class GeneratedMakefileBuilder extends ACBuilder {
console.start(currentProject);
ConsoleOutputStream consoleOutStream = console.getOutputStream();
String[] consoleHeader = new String[3];
- consoleHeader[0] = fullBuild ?
- ManagedMakeMessages.getResourceString(TYPE_FULL) :
- ManagedMakeMessages.getResourceString(TYPE_INC);
+ switch (buildType) {
+ case FULL_BUILD:
+ consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_FULL);
+ break;
+ case INCREMENTAL_BUILD:
+ consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_INC);
+ break;
+ case CLEAN_BUILD:
+ consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_CLEAN);
+ break;
+ }
+
consoleHeader[1] = info.getConfigurationName();
consoleHeader[2] = currentProject.getName();
buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$
@@ -449,7 +542,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
makeArgs.add(args[i]);
}
}
- makeArgs.addAll(Arrays.asList(getMakeTargets(fullBuild)));
+ makeArgs.addAll(Arrays.asList(getMakeTargets(buildType)));
String[] makeTargets = (String[]) makeArgs.toArray(new String[makeArgs.size()]);
// Get a launcher for the make command
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 0d4fc9b0311..07b57eddc2b 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
@@ -47,6 +47,7 @@ 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.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -69,6 +70,7 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
private String defaultTargetId;
private ITarget selectedTarget;
private boolean isDirty;
+ private boolean rebuildNeeded;
private IResource owner;
private Map targetMap;
private List targetList;
@@ -100,15 +102,16 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
if (entries.length > 0 && entries[0].equals(containerEntry)) {
} else {
- Job initJob = new Job("Initializing path container") {
+ Job initJob = new Job("Initializing path container") { //$NON-NLS-1$
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 new Status(IStatus.ERROR, ManagedBuilderCorePlugin.getUniqueIdentifier(), -1, e.getLocalizedMessage(), e);
}
- return null;
+ return new Status(IStatus.OK, ManagedBuilderCorePlugin.getUniqueIdentifier(), IStatus.OK, null, null);
+
}
};
@@ -118,7 +121,9 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
ManagedBuilderCorePlugin.log(e);
}
+ // Does not need a save but should be rebuilt
isDirty = false;
+ rebuildNeeded = true;
// The id of the default target from the project persistent settings store
IProject project = (IProject)owner;
@@ -161,6 +166,9 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
}
initializePathEntries();
+
+ // Switch the rebuild off since this is an existing project
+ rebuildNeeded = false;
}
/* (non-Javadoc)
@@ -191,6 +199,17 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
return false;
}
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setRebuildState(boolean)
+ */
+ public void setRebuildState(boolean rebuild) {
+ Iterator iter = getTargets().listIterator();
+ while (iter.hasNext()) {
+ ((ITarget)iter.next()).setRebuildState(rebuild);
+ }
+ rebuildNeeded = rebuild;
+ }
+
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getBuildArtifactExtension()
*/
@@ -775,6 +794,21 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
return false;
}
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#needsRebuild()
+ */
+ public boolean needsRebuild() {
+ if (rebuildNeeded) return true;
+
+ Iterator iter = getTargets().listIterator();
+ while (iter.hasNext()) {
+ if (((ITarget)iter.next()).needsRebuild()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
/* (non-Javadoc)
*
@@ -943,6 +977,14 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
}
}
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ // Just print out the name of the project
+ return "Managed build information for " + owner.getName(); //$NON-NLS-1$
+ }
+
/**
* Sets the owner of the receiver to be the IResource
specified
* in the argument.
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 376545aa42c..0f489178ede 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
@@ -24,6 +24,7 @@ ManagedMakeBuilder.message.no.build = Nothing to build for {0}
ManagedMakeBuilder.message.error = Build error
ManagedMakeBuilder.message.error.refresh = Error refreshing project
ManagedMakeBuilder.message.finished = Build complete for project {0}
+ManagedMakeBuilder.type.clean = Clean-only build
ManagedMakeBuilder.type.full = Full rebuild
ManagedMakeBuider.type.incremental = Incremental build
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 90ebf6fe19e..c9d5d99c44a 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
@@ -853,6 +853,17 @@ public class Target extends BuildObject implements ITarget {
getLocalToolReferences().add(toolRef);
}
+ public boolean needsRebuild(){
+ // Iterate over the configurations and ask them if they need saving
+ Iterator iter = getConfigurationList().listIterator();
+ while (iter.hasNext()) {
+ if (((IConfiguration)iter.next()).needsRebuild()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.core.ITarget#setArtifactExtension(java.lang.String)
*/
@@ -918,6 +929,17 @@ public class Target extends BuildObject implements ITarget {
isDirty = true;
}
}
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.core.ITarget#setRebuildState(boolean)
+ */
+ public void setRebuildState(boolean rebuild) {
+ Iterator iter = getConfigurationList().listIterator();
+ while (iter.hasNext()) {
+ ((IConfiguration)iter.next()).setRebuildState(rebuild);
+ }
+ }
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.core.ITarget#updateOwner(org.eclipse.core.resources.IResource)
@@ -929,5 +951,4 @@ public class Target extends BuildObject implements ITarget {
}
}
-
}
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
index b807627b518..97e54d296ef 100644
--- 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
@@ -59,111 +59,6 @@ import org.eclipse.core.runtime.SubProgressMonitor;
* @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 Vector dependencyMakefiles;
- 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
@@ -243,85 +138,112 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
}
}
- public GnuMakefileGenerator() {
- super();
- }
+
/**
- * @param project
- * @param info
- * @param monitor
+ * This class is used to recursively walk the project and determine which
+ * modules contribute buildable source files.
*/
- 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();
- }
- }
+ protected class ResourceProxyVisitor implements IResourceProxyVisitor {
+ private GnuMakefileGenerator generator;
+ private IManagedBuildInfo info;
- /* (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$
- }
+ /**
+ * 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;
}
- return escapedPath.toString().trim();
- } else {
- return path;
+
+ // 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;
}
+
}
- /* (non-Javadoc)
- * Answers a StringBuffer
containing the comment(s)
- * for the top-level makefile.
- */
- protected StringBuffer addTopHeader() {
- return addDefaultHeader();
- }
+ // String constants for makefile contents and messages
+ protected static final String AT = "@"; //$NON-NLS-1$
+ private static final String COMMENT = "MakefileGenerator.comment"; //$NON-NLS-1$
+ private static final String AUTO_DEP = COMMENT + ".autodeps"; //$NON-NLS-1$
+ private static final String MESSAGE = "ManagedMakeBuilder.message"; //$NON-NLS-1$
+ private static final String BUILD_ERROR = MESSAGE + ".error"; //$NON-NLS-1$
+ protected static final String COLON = ":"; //$NON-NLS-1$
- /* (non-Javadoc)
- * Answers a StringBuffer
containing the comment(s)
- * for a fragment makefile.
- */
- protected StringBuffer addFragmentMakefileHeader() {
- return addDefaultHeader();
- }
+ private static final int COLS_PER_LINE = 80;
+ protected static final String COMMENT_SYMBOL = "#"; //$NON-NLS-1$
+ protected static final String DEP_EXT = "d"; //$NON-NLS-1$
+ private static final String DEP_INCL = COMMENT + ".module.dep.includes"; //$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$
+ private static final String HEADER = COMMENT + ".header"; //$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_DEFS = "makefile.defs"; //$NON-NLS-1$
+ protected static final String MAKEFILE_INIT = "makefile.init"; //$NON-NLS-1$
+ protected static final String MAKEFILE_NAME = "makefile"; //$NON-NLS-1$
+ protected static final String MAKEFILE_TARGETS = "makefile.targets"; //$NON-NLS-1$
+
+ protected static final String MESSAGE_FINISH_BUILD = ManagedMakeMessages.getResourceString("MakefileGenerator.message.finish.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_BUILD = ManagedMakeMessages.getResourceString("MakefileGenerator.message.start.build"); //$NON-NLS-1$
+ protected static final String MESSAGE_START_FILE = ManagedMakeMessages.getResourceString("MakefileGenerator.message.start.file"); //$NON-NLS-1$
+ private static final String MOD_INCL = COMMENT + ".module.make.includes"; //$NON-NLS-1$
+ private static final String MOD_LIST = COMMENT + ".module.list"; //$NON-NLS-1$
+ private static final String MOD_RULES = COMMENT + ".build.rule"; //$NON-NLS-1$
+ protected static final String MODFILE_NAME = "subdir.mk"; //$NON-NLS-1$
+ protected static final String OBJECTS_MAKFILE = "objects.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 SEPARATOR = "/"; //$NON-NLS-1$
+ protected static final String SINGLE_QUOTE = "'"; //$NON-NLS-1$
+ private static final String SRC_LISTS = COMMENT + ".source.list"; //$NON-NLS-1$
+ protected static final String SRCSFILE_NAME = "sources.mk"; //$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$
+
+ // Local variables needed by generator
+ private String buildTargetName;
+ private Vector deletedFileList;
+ private Vector dependencyMakefiles;
+ private String extension;
+ protected IManagedBuildInfo info;
+ protected Vector modifiedList;
+ protected IProgressMonitor monitor;
+ protected IProject project;
+ protected Vector ruleList;
+ protected Vector subdirList;
+ protected IPath topBuildDir;
- /* (non-Javadoc)
- * Answers a StringBuffer
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);
+ public GnuMakefileGenerator() {
+ super();
}
/* (non-Javadoc)
@@ -338,6 +260,22 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
buffer.append(NEWLINE);
return buffer;
}
+
+ /* (non-Javadoc)
+ * Answers a StringBuffer
containing the comment(s)
+ * for a dependency makefile.
+ */
+ protected StringBuffer addFragmentDependenciesHeader() {
+ return addDefaultHeader();
+ }
+
+ /* (non-Javadoc)
+ * Answers a StringBuffer
containing the comment(s)
+ * for a fragment makefile.
+ */
+ protected StringBuffer addFragmentMakefileHeader() {
+ return addDefaultHeader();
+ }
/* (non-javadoc)
*/
@@ -371,30 +309,65 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
}
/* (non-javadoc)
- * @return
+ * Create the pattern rule in the format:
+ * StrinBuffer
containing all of the required targets to
* properly build the project.
@@ -511,20 +511,17 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
String targets = rebuild ? "clean all" : "all"; //$NON-NLS-1$ //$NON-NLS-2$
// Get all the projects the build target depends on
- IProject[] deps = null;
+ IProject[] refdProjects = null;
try {
- deps = project.getReferencedProjects();
+ refdProjects = 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_StringBuffer
containing the comment(s)
+ * for the top-level makefile.
*/
- 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;
- getDependencyMakefiles().add(depRule);
- 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 -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);
+ protected StringBuffer addTopHeader() {
+ return addDefaultHeader();
}
/**
@@ -683,6 +622,18 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
getSubdirList().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);
+ }
/**
* Adds the container of the argument to a list of subdirectories that are part
@@ -697,39 +648,6 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
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;
- }
-
- /**
- * @return
- */
- private Vector getDependencyMakefiles() {
- if (dependencyMakefiles == null) {
- dependencyMakefiles = new Vector();
- }
- return dependencyMakefiles;
- }
/* (non-Javadoc)
* @param message
@@ -752,6 +670,150 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
}
}
+ /* (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
+ * @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, new SubProgressMonitor(monitor, 1));
+ // 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;
+ }
+
+ /**
+ * @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)
+ * 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)
* @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator#generateDependencies()
*/
@@ -858,6 +920,37 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
checkCancel();
}
}
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator#getTopBuildDir()
+ */
+ public IPath getBuildWorkingDir() {
+ if (topBuildDir != null) {
+ return topBuildDir.removeFirstSegments(1);
+ }
+ return null;
+ }
+
+
+ /**
+ * @return
+ */
+ private Vector getDeletedFileList() {
+ if (deletedFileList == null) {
+ deletedFileList = new Vector();
+ }
+ return deletedFileList;
+ }
+
+ /**
+ * @return
+ */
+ private Vector getDependencyMakefiles() {
+ if (dependencyMakefiles == null) {
+ dependencyMakefiles = new Vector();
+ }
+ return dependencyMakefiles;
+ }
/**
* Strips off the file extension from the argument and returns
@@ -886,12 +979,12 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
// 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
+ 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
+ macroName.append("_SRCS"); //$NON-NLS-1$
return macroName;
}
@@ -959,138 +1052,27 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
}
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
+ * @param project
+ * @param info
+ * @param monitor
*/
- 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);
- }
+ 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)
- * 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, new SubProgressMonitor(monitor, 1));
- // 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() {
- if (topBuildDir != null) {
- return topBuildDir.removeFirstSegments(1);
- }
- return null;
- }
/**
* Answers true
if the argument is found in a generated container
@@ -1111,27 +1093,14 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
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
+ /* (non-Javadoc)
+ * Put COLS_PER_LINE comment charaters in the argument.
*/
- 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);
+ protected void outputCommentLine(StringBuffer buffer) {
+ for (int i = 0; i < COLS_PER_LINE; i++) {
+ buffer.append(COMMENT_SYMBOL);
+ }
+ buffer.append(NEWLINE);
}
protected void populateDummyTargets(IFile makefile, boolean force) throws CoreException, IOException {
@@ -1156,7 +1125,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
StringBuffer outBuffer = null;
if (inBuffer != null) {
// Here are the tokens in the file
- String[] dependencies = inBuffer.toString().split("\\s");
+ String[] dependencies = inBuffer.toString().split("\\s"); //$NON-NLS-1$
// If we are doing an incremental build, only update the files that do not have a comment
if (dependencies.length > 0 && !force) {
@@ -1291,9 +1260,9 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
// 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) + ")" );
+ objectsBuffer.append(WHITESPACE + "$(" + macroName + COLON + "$(ROOT)" + SEPARATOR + WILDCARD //$NON-NLS-1$ //$NON-NLS-2$
+ + DOT + extensionName + "=" + WILDCARD + DOT + //$NON-NLS-1$
+ toolArray[k].getOutputExtension(extensionName) + ")" ); //$NON-NLS-1$
}
}
}
@@ -1326,7 +1295,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
if(!outputExtensionsSet.contains(extensionName) && !handledInputExtensionsSet.contains(extensionName)) {
handledInputExtensionsSet.add(extensionName);
StringBuffer macroName = getMacroName(extensionName);
- buffer.append(macroName + WHITESPACE + ":=" + WHITESPACE + NEWLINE);
+ buffer.append(macroName + WHITESPACE + ":=" + WHITESPACE + NEWLINE); //$NON-NLS-1$
}
}
}
@@ -1338,6 +1307,29 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
Util.save(buffer, fileHandle);
}
+ /* (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)
* @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator#regenerateDependencies()
*/
@@ -1410,7 +1402,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
checkCancel();
// Now finish up by adding all the object files
- IPath objFilePath = topBuildDir.addTrailingSeparator().append("objects.mk");
+ IPath objFilePath = topBuildDir.addTrailingSeparator().append(OBJECTS_MAKFILE);
IFile objsFileHandle = createFile(objFilePath);
populateObjectsMakefile(objsFileHandle);
checkCancel();