diff --git a/build/org.eclipse.cdt.managedbuilder.core/ChangeLog b/build/org.eclipse.cdt.managedbuilder.core/ChangeLog index e03ee82d96b..c3f23ed0be0 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/ChangeLog +++ b/build/org.eclipse.cdt.managedbuilder.core/ChangeLog @@ -1,3 +1,24 @@ +2003-09-16 Sean Evoy + Patch contains a fix for bug 43017. Renamed the "addDeps" method to a + more descriptive "addSourceDependencies". Added a flag when the + inter-project dependencies are calculated so that clean and all are + properly passed to the make invocation. Finally, I replaced the hard-coded + 'make' with $(MAKE) + * src/org/eclipse/cdt/managedbuilder/internal/core/MakefileGenerator.java + + It also contains some more work on 41826, specifically on the logic to + implement a rebuild when the build settings change. The builder checks for + a build model change whenever a build is requested and responds appropriately. + The make targets (i.e. 'clean' and 'all') are also calculated differently now. + * src/org/eclipse/cdt/managedbuilder/internal/core/GeneratedMakefileBuilder.java + + The build model was modified to set a dirty flag when an option changes. I also + made a change to avoid an NPE when the build info was loaded. + * src/org/eclipse/cdt/managedbuilder/core/IManagedBuildInfo.java + * src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java + * src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java + + 2003-09-15 Sean Evoy First submission of code to new project. Moved the managed builder source code out of the cdt.core project. This includes the code to 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 cc0e747f272..6b9205d4985 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 @@ -182,6 +182,20 @@ public interface IManagedBuildInfo { */ public String getToolForTarget(String extension); + /** + * Answers true if the build model has been changed by the user. + * + * @return + */ + public boolean isDirty(); + + /** + * Set the dirty flag for the build model to the value of the argument. + * + * @param isDirty + */ + public void setDirty(boolean isDirty); + /** * Set the primary configuration for the receiver. * 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 14c74c84ec1..6d39ed13638 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 @@ -207,20 +207,24 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI * @param option */ private static void setDirty(IConfiguration config, IOption option) { - // Don't bother unless this is something that effect the + // Set the build info dirty so builder will rebuild + IResource resource = config.getOwner(); + IManagedBuildInfo info = getBuildInfo(resource); + info.setDirty(true); + + // Continue if change is something that effect the scanner if (!(option.getValueType() == IOption.INCLUDE_PATH || option.getValueType() == IOption.PREPROCESSOR_SYMBOLS)) { return; } // Figure out if there is a listener for this change - IResource resource = config.getOwner(); List listeners = (List) getBuildModelListeners().get(resource); if (listeners == null) { return; } ListIterator iter = listeners.listIterator(); while (iter.hasNext()) { - ((IScannerInfoChangeListener)iter.next()).changeNotification(resource, getScannerInfo(resource)); + ((IScannerInfoChangeListener)iter.next()).changeNotification(resource, (IScannerInfo)getBuildInfo(resource, false)); } } @@ -465,7 +469,7 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI if (buildInfo == null && create) { try { - buildInfo = new ManagedBuildInfo(); + buildInfo = new ManagedBuildInfo(resource); resource.setSessionProperty(buildInfoProperty, buildInfo); } catch (CoreException e) { buildInfo = null; @@ -493,21 +497,6 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI return buildModelListeners; } - /** - * Answers with an interface to the parse information that has been - * associated with the resource specified in the argument. - * - * @deprecated This method is not part of the registration interface. - * Clients of build information should now use getScannerInformation(IResource) - * for one-time information requests. - * - * @param resource - * @return - */ - public static IScannerInfo getScannerInfo(IResource resource) { - return (IScannerInfo) getBuildInfo(resource, false); - } - /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.IScannerInfoProvider#getScannerInformation(org.eclipse.core.resources.IResource) */ 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 ddf014c0f86..19b4aaf1a9a 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 @@ -99,23 +99,27 @@ public class GeneratedMakefileBuilder extends ACBuilder { monitor.subTask(statusMsg); } - if (kind == IncrementalProjectBuilder.FULL_BUILD) { - fullBuild(monitor); + IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(getProject()); + + if (kind == IncrementalProjectBuilder.FULL_BUILD || info.isDirty()) { + fullBuild(monitor, info); } else { // Create a delta visitor to make sure we should be rebuilding ResourceDeltaVisitor visitor = new ResourceDeltaVisitor(); IResourceDelta delta = getDelta(getProject()); if (delta == null) { - fullBuild(monitor); + fullBuild(monitor, info); } else { delta.accept(visitor); if (visitor.shouldBuild()) { - incrementalBuild(delta, monitor); + incrementalBuild(delta, info, monitor); } } } + info.setDirty(false); + // Checking to see if the user cancelled the build checkCancel(monitor); @@ -138,7 +142,7 @@ public class GeneratedMakefileBuilder extends ACBuilder { /** * @param monitor */ - protected void fullBuild(IProgressMonitor monitor) throws CoreException { + protected void fullBuild(IProgressMonitor monitor, IManagedBuildInfo info) throws CoreException { // Always need one of these bad boys if (monitor == null) { monitor = new NullProgressMonitor(); @@ -175,7 +179,6 @@ public class GeneratedMakefileBuilder extends ACBuilder { monitor.subTask(statusMsg); // Regenerate the makefiles for this project - IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(getProject()); MakefileGenerator generator = new MakefileGenerator(currentProject, info, monitor); try { generator.regenerateMakefiles(); @@ -194,20 +197,27 @@ public class GeneratedMakefileBuilder extends ACBuilder { monitor.worked(1); } - /** - * @param makefilePath - * @param info + /* (non-javadoc) + * Answers an array of strings with the proper make targets + * + * @param fullBuild * @return */ - protected String[] getMakeTargets() { + protected String[] getMakeTargets(boolean fullBuild) { List args = new ArrayList(); + if (fullBuild) { + args.add("clean"); + } // Add each target String sessionTarget = MakeUtil.getSessionTarget(getProject()); StringTokenizer tokens = new StringTokenizer(sessionTarget); while (tokens.hasMoreTokens()) { - args.add(tokens.nextToken().trim()); + String target = tokens.nextToken().trim(); + if (!args.contains(target)) { + args.add(target); + } } - if (args.isEmpty()) { + if (args.isEmpty() || !args.contains("all")) { args.add("all"); } return (String[])args.toArray(new String[args.size()]); @@ -248,7 +258,7 @@ public class GeneratedMakefileBuilder extends ACBuilder { * @param delta * @param monitor */ - protected void incrementalBuild(IResourceDelta delta, IProgressMonitor monitor) throws CoreException { + protected void incrementalBuild(IResourceDelta delta, IManagedBuildInfo info, IProgressMonitor monitor) throws CoreException { // Rebuild the resource tree in the delta IProject currentProject = getProject(); String statusMsg = null; @@ -261,7 +271,6 @@ public class GeneratedMakefileBuilder extends ACBuilder { monitor.subTask(statusMsg); // Ask the makefile generator to generate any makefiles needed to build delta - IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(getProject()); MakefileGenerator generator = new MakefileGenerator(currentProject, info, monitor); try { generator.generateMakefiles(delta); @@ -324,7 +333,7 @@ public class GeneratedMakefileBuilder extends ACBuilder { IPath workingDirectory = getWorkingDirectory().append(buildDir); // Get the arguments to be passed to make from build model - String[] makeTargets = getMakeTargets(); + String[] makeTargets = getMakeTargets(fullBuild); // Get a launcher for the make command String errMsg = null; 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 index 2d4c75d3fd7..840e40102cb 100644 --- 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 @@ -196,6 +196,11 @@ public class MakefileGenerator { } } + /** + * @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 @@ -209,11 +214,14 @@ public class MakefileGenerator { } /* (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 addDeps(IContainer module) throws CoreException { + protected StringBuffer addSourceDependencies(IContainer module) throws CoreException { // Calculate the new directory relative to the build output IPath moduleRelativePath = module.getProjectRelativePath(); String relativePath = moduleRelativePath.toString(); @@ -372,7 +380,7 @@ public class MakefileGenerator { * Answers a StrinBuffer containing all of the required targets to * properly build the project. */ - protected StringBuffer addTargets() { + protected StringBuffer addTargets(boolean rebuild) { StringBuffer buffer = new StringBuffer(); // Get the target and it's extension @@ -383,16 +391,16 @@ public class MakefileGenerator { /* * Write out the target rule as: * .: $(CC_SRCS:$(ROOT)/%.cpp=%.o) $(C_SRCS:$(ROOT)/%.c=%.o) - * ; make all> - * ; make all> - * ; make all> + * ; $(MAKE) all> + * ; $(MAKE) all> + * ; $(MAKE) all> * $(BUILD_TOOL) $(FLAGS) $(OUTPUT_FLAG) $@ $^ $(LIB_DEPS) */ 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"; buffer.append(outputPrefix + target + COLON + WHITESPACE + "$(CC_SRCS:$(ROOT)/%.cpp=%.o) $(C_SRCS:$(ROOT)/%.c=%.o)" + NEWLINE); IProject[] deps; try { @@ -404,11 +412,11 @@ public class MakefileGenerator { IManagedBuildInfo depInfo = ManagedBuildManager.getBuildInfo(dep); buildDir += SEPARATOR + depInfo.getConfigurationName(); } - buffer.append(TAB + "cd" + WHITESPACE + buildDir + SEMI_COLON + WHITESPACE + "make all" + NEWLINE); + buffer.append(TAB + "cd" + WHITESPACE + buildDir + SEMI_COLON + WHITESPACE + "$(MAKE) " + targets + NEWLINE); } } catch (CoreException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // There are 2 exceptions; the project does not exist or it is not open + // and neither conditions apply if we are building for it .... } buffer.append(TAB + cmd + WHITESPACE + flags + WHITESPACE + outflag + WHITESPACE + "$@" + WHITESPACE + "$^"); @@ -420,7 +428,7 @@ public class MakefileGenerator { buffer.append(NEWLINE); buffer.append(NEWLINE); - // TODO Generate 'all' for now but determine the real rules from UI + // We only have one target, 'all' buffer.append("all: " + outputPrefix + target + NEWLINE); buffer.append(NEWLINE); @@ -587,7 +595,7 @@ public class MakefileGenerator { topBuildDir = createDirectory(info.getConfigurationName()); IPath makefilePath = topBuildDir.addTrailingSeparator().append(MAKEFILE_NAME); IFile makefileHandle = createFile(makefilePath); - populateTopMakefile(makefileHandle); + populateTopMakefile(makefileHandle, false); checkCancel(); // Regenerate any fragments for modified directories @@ -725,10 +733,9 @@ public class MakefileGenerator { * Create the entire contents of the makefile. * * @param fileHandle The file to place the contents in. - * @param info - * @param monitor + * @param rebuild FLag signalling that the user is doing a full rebuild */ - protected void populateTopMakefile(IFile fileHandle) { + protected void populateTopMakefile(IFile fileHandle, boolean rebuild) { StringBuffer buffer = new StringBuffer(); // Add the macro definitions @@ -738,7 +745,7 @@ public class MakefileGenerator { buffer.append(addModules()); // Add targets - buffer.append(addTargets()); + buffer.append(addTargets(rebuild)); // Save the file try { @@ -772,7 +779,7 @@ public class MakefileGenerator { // Create a module dep file IFile modDepfile = createFile(moduleOutputDir.addTrailingSeparator().append(DEPFILE_NAME)); StringBuffer depBuf = new StringBuffer(); - depBuf.append(addDeps(module)); + depBuf.append(addSourceDependencies(module)); // Save the files Util.save(makeBuf, modMakefile); @@ -804,7 +811,7 @@ public class MakefileGenerator { IFile makefileHandle = createFile(makefilePath); // Populate the makefile - populateTopMakefile(makefileHandle); + populateTopMakefile(makefileHandle, true); checkCancel(); // Now populate the module makefiles 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 1409dc09cba..ae366d56b1c 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 @@ -33,20 +33,23 @@ import org.w3c.dom.Node; public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { + private boolean isDirty; private IResource owner; private Map targetMap; private List targets; private Map defaultConfigurations; private ITarget defaultTarget; - public ManagedBuildInfo() { + public ManagedBuildInfo(IResource owner) { targetMap = new HashMap(); targets = new ArrayList(); defaultConfigurations = new HashMap(); + this.owner = owner; } public ManagedBuildInfo(IResource owner, Element element) { - this(); + this(owner); + // The id of the default configuration String defaultTargetId = null; List configIds = new ArrayList(); @@ -460,6 +463,20 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { return null; } + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#isDirty() + */ + public boolean isDirty() { + return isDirty; + } + + /** + * Write the contents of the build model to the persistent store specified in the + * argument. + * + * @param doc + * @param element + */ public void serialize(Document doc, Element element) { // Write out each target and their default config for (int i = 0; i < targets.size(); ++i) { @@ -502,4 +519,11 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { defaultTarget = target; } + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setDirty(boolean) + */ + public void setDirty(boolean isDirty) { + this.isDirty = isDirty; + } + } diff --git a/build/org.eclipse.cdt.managedbuilder.ui/ChangeLog b/build/org.eclipse.cdt.managedbuilder.ui/ChangeLog index b670dfc5c0f..932af269d4c 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/ChangeLog +++ b/build/org.eclipse.cdt.managedbuilder.ui/ChangeLog @@ -1,3 +1,11 @@ +2003-09-16 Sean Evoy + Changed the initialization and button status logic so the list buttons are + enabled correctly on start-up and that the fist item in the list (if + any) is selected. Also changed the "Add" event handler to properly enable + the buttons and set the list selection. + + * src/org/eclipse/cdt/managedbuilder/ui/properties/BuildOptionListFieldEditor.java + 2003-09-15 Sean Evoy First submission of code to new project. Moved all the managed builder-specific UI elements out of the cdt.ui project. This diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildOptionListFieldEditor.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildOptionListFieldEditor.java index cc9930521b9..7f797aebe2e 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildOptionListFieldEditor.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildOptionListFieldEditor.java @@ -90,11 +90,14 @@ public class BuildOptionListFieldEditor extends FieldEditor { // Add it to the list if (input != null) { int index = list.getSelectionIndex(); - if (index >= 0) + if (index >= 0) { list.add(input, index + 1); - else + list.setSelection(index + 1); + } + else { list.add(input, 0); - selectionChanged(); + list.setSelection(0); + } } } @@ -213,6 +216,7 @@ public class BuildOptionListFieldEditor extends FieldEditor { // Create the buttons createButtons(buttonGroup); + selectionChanged(); } /* (non-Javadoc) @@ -284,6 +288,7 @@ public class BuildOptionListFieldEditor extends FieldEditor { for (int i = 0; i < array.length; i++){ list.add(array[i]); } + list.setSelection(0); } } diff --git a/core/org.eclipse.cdt.core.tests/build/org/eclipse/cdt/core/build/managed/tests/ManagedBuildTests.java b/core/org.eclipse.cdt.core.tests/build/org/eclipse/cdt/core/build/managed/tests/ManagedBuildTests.java index b9a63e004a4..98256add8d0 100644 --- a/core/org.eclipse.cdt.core.tests/build/org/eclipse/cdt/core/build/managed/tests/ManagedBuildTests.java +++ b/core/org.eclipse.cdt.core.tests/build/org/eclipse/cdt/core/build/managed/tests/ManagedBuildTests.java @@ -208,7 +208,12 @@ public class ManagedBuildTests extends TestCase { } } assertNotNull(symbolOpt); + IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project); + assertFalse(info.isDirty()); ManagedBuildManager.setOption(defaultConfig, symbolOpt, expectedSymbols); + assertTrue(info.isDirty()); + info.setDirty(false); + assertFalse(info.isDirty()); } /**