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 05d1a8f4352..dfee8dee5de 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 @@ -68,7 +68,8 @@ public class GeneratedMakefileBuilder extends ACBuilder { public class ResourceDeltaVisitor implements IResourceDeltaVisitor { private String buildGoalName; private IManagedBuildInfo buildInfo; - private boolean buildNeeded = true; + private boolean incrBuildNeeded = false; + private boolean fullBuildNeeded = false; private List reservedNames; /** @@ -103,7 +104,7 @@ public class GeneratedMakefileBuilder extends ACBuilder { } if (ext.length() > 0) { - buildGoalName = buildInfo.getOutputPrefix(ext) + name + "." + ext; //$NON-NLS-1$ + buildGoalName = buildInfo.getOutputPrefix(ext) + name + IManagedBuilderMakefileGenerator.DOT + ext; } else { buildGoalName = name; } @@ -135,10 +136,14 @@ public class GeneratedMakefileBuilder extends ACBuilder { return reservedNames.contains(resource.getName()); } - public boolean shouldBuild() { - return buildNeeded; + public boolean shouldBuildIncr() { + return incrBuildNeeded; } + public boolean shouldBuildFull() { + return fullBuildNeeded; + } + 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 @@ -151,28 +156,53 @@ public class GeneratedMakefileBuilder extends ACBuilder { } else { String name = changedResource.getName(); String ext = changedResource.getFileExtension(); - // There are some things we don't care about and some we do - if (name.equals(buildGoalName)) { - buildNeeded = true; - break; - } else 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; - } + + if ((!name.equals(buildGoalName) && + // TODO: Also need to check for secondary outputs + (changedResource.isDerived() || + (isProjectFile(changedResource)) || + (isGeneratedResource(changedResource))))) { + // The resource that changed has attributes which make it uninteresting, + // so don't do anything + ; + } + else { + // TODO: Should we do extra checks here to determine if a build is really needed, + // or do you just do exclusion checks like above? + // We could check for: + // o The build goal name + // o A secondary output + // o An input file to a tool: + // o Has an extension of a source file used by a tool + // o Has an extension of a header file used by a tool + // o Has the name of an input file specified in an InputType via: + // o An Option + // o An AdditionalInput + // + //if (resourceName.equals(buildGoalName) || + // (buildInfo.buildsFileType(ext) || buildInfo.isHeaderFile(ext))) { + + // We need to do an incremental build, at least + incrBuildNeeded = true; + if (kids[index].getKind() == IResourceDelta.REMOVED) { + // If a meaningful resource was removed, then force a full build + // This is required because an incremental build will trigger make to + // do nothing for a missing source, since the state after the file + // removal is uptodate, as far as make is concerned + // A full build will clean, and ultimately trigger a relink without + // the object generated from the deleted source, which is what we want + fullBuildNeeded = true; + // There is no point in checking anything else since we have + // decided to do a full build anyway + break; + } + + //} + } } } return false; } - return true; } } @@ -275,7 +305,10 @@ public class GeneratedMakefileBuilder extends ACBuilder { } else { delta.accept(visitor); - if (visitor.shouldBuild()) { + if (visitor.shouldBuildFull()) { + outputTrace(getProject().getName(), "Incremental build requested, full build needed"); //$NON-NLS-1$ + fullBuild(info, generator, monitor); + } else if (visitor.shouldBuildIncr()) { outputTrace(getProject().getName(), "Incremental build requested"); //$NON-NLS-1$ incrementalBuild(delta, info, generator, monitor); } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java index d32325a5eb7..d77a328731d 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java @@ -718,19 +718,7 @@ public class InputType extends BuildObject implements IInputType { if (superClass != null) { return superClass.getBuildVariable(); } else { - if (getMultipleOfType()) { - // Use default name - String name = getName(); - if (name == null || name.length() == 0) { - name = getId(); - } - String defaultName = name.toUpperCase(); - defaultName = defaultName.replaceAll("\\W", "_"); //$NON-NLS-1$ //$NON-NLS-2$ - defaultName += "_INPUTS"; //$NON-NLS-1$ - return defaultName; - } else { - return EMPTY_STRING; - } + return EMPTY_STRING; } } return buildVariable; diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedCommandLineGenerator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedCommandLineGenerator.java index 91008debd84..7034f98b161 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedCommandLineGenerator.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedCommandLineGenerator.java @@ -74,7 +74,11 @@ public class ManagedCommandLineGenerator implements int start = 0; int stop = 0; while( (start = commandLinePattern.indexOf( VAR_FIRST_CHAR, start )) >= 0 ) { - if( commandLinePattern.charAt( start + 1 ) != VAR_SECOND_CHAR ) continue; + if( commandLinePattern.charAt( start + 1 ) != VAR_SECOND_CHAR ) { + sb.append(VAR_FIRST_CHAR); + start++; + continue; + } if( start > stop ) { sb.append( commandLinePattern.substring(stop, start) ); } 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 e971b7f3f5f..d04449721be 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 @@ -20,6 +20,10 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashMap; // Note: We use LinkedHashMap instead of HashMap + // only to keep the generation of makefiles constant + // for our test set. Make itself doesn't care + // about the order. import java.util.Iterator; import java.util.List; import java.util.Map; @@ -275,7 +279,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { // Maps of macro names (String) to values (List) private HashMap buildSrcVars = new HashMap(); private HashMap buildOutVars = new HashMap(); - private HashMap topBuildOutVars = new HashMap(); + private LinkedHashMap topBuildOutVars = new LinkedHashMap(); public GnuMakefileGenerator() { super(); @@ -1582,22 +1586,24 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { for (int i=0; inull, use the file extension to find the name */ - protected void addFragmentMakefileEntriesForSource (HashMap buildVarToRuleStringMap, StringBuffer ruleBuffer, + protected void addFragmentMakefileEntriesForSource (LinkedHashMap buildVarToRuleStringMap, StringBuffer ruleBuffer, IFolder folder, String relativePath, IResource resource, String varName, boolean generatedSource) { // Determine which tool, if any, builds files with this extension String ext = resource.getFileExtension(); @@ -1848,8 +1854,9 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { addMacroAdditionFile(buildVarToRuleStringMap, varName, relativePath, resource, generatedSource); // Generate the rule to build this source file + IInputType primaryInputType = tool.getPrimaryInputType(); IInputType inputType = tool.getInputType(ext); - if ((inputType != null && !inputType.getMultipleOfType()) || + if ((primaryInputType != null && !primaryInputType.getMultipleOfType()) || (inputType == null && !(tool == info.getToolFromOutputExtension(buildTargetExt)))) { // Try to add the rule for the file @@ -2530,7 +2537,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { * C_SRCS += \ * ${addprefix $(ROOT)/, \ */ - protected void addMacroAdditionPrefix(HashMap map, String macroName, String relativePath, boolean addPrefix) { + protected void addMacroAdditionPrefix(LinkedHashMap map, String macroName, String relativePath, boolean addPrefix) { // there is no entry in the map, so create a buffer for this macro StringBuffer tempBuffer = new StringBuffer(); tempBuffer.append(macroName + WHITESPACE + MACRO_ADDITION_PREFIX_SUFFIX); @@ -2600,7 +2607,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { /* (non-Javadoc) * Write all macro addition entries in a map to the buffer */ - protected StringBuffer writeAdditionMacros(HashMap map) { + protected StringBuffer writeAdditionMacros(LinkedHashMap map) { StringBuffer buffer = new StringBuffer(); // Add the comment buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(MOD_VARS) + NEWLINE); @@ -2710,7 +2717,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { } // Initialize the build output variable to file additions map - HashMap map = getTopBuildOutputVars(); + LinkedHashMap map = getTopBuildOutputVars(); Iterator iterator = buildOutVars.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry entry = (Map.Entry)iterator.next(); @@ -2832,7 +2839,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { * * @return HashMap */ - public HashMap getTopBuildOutputVars() { + public LinkedHashMap getTopBuildOutputVars() { return topBuildOutVars; } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java index 0078034c988..fca406a638f 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java @@ -220,24 +220,30 @@ public class ManagedBuildGnuToolInfo implements IManagedBuildGnuToolInfo { // Calculate myEnumeratedInputs using the file extensions and the resources in the project // Note: This is only correct for tools with multipleOfType == true, but for other tools // it gives us an input resource for generating default names - String[] exts = tool.getAllInputExtensions(); + // Determine the set of source input macros to use + HashSet handledInputExtensions = new HashSet(); + String[] exts = type.getSourceExtensions(); if (projResources != null) { for (int j=0; j 0) { for (int i=0; i