1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Patch for Sean Evoy

Hi All,
Details are in the change log, but this patch contains work that partially 
implements incremental build. There are 2 major use cases not implemented: 
full rebuild on project settings change and properly handling header file 
changes. Both problems require build model work, so I will deliver that 
functionality in another patch. There are also fixes for bugs 41412 and 
42735.

As always, I have run the JUnit tests on Solaris (Motif) and Linux (Gtk).
This commit is contained in:
John Camelon 2003-09-11 14:46:18 +00:00
parent 86bd34cb79
commit 64911fc186
15 changed files with 538 additions and 87 deletions

View file

@ -1,3 +1,9 @@
2003-09-10 Sean Evoy
Added a test for resetting the value of a configuration to the defaults defined in the
plugin file. Work completed to resolve [Bug 41412] Restore Default in Managed Build
project's settings Not Working.
* build/org/eclipse/cdt/core/build/managed/tests/ManagedBuildTests.java
2003-09-09 Hoda Amer
Moved three failed tests (bugs #42822, #42823, & #42822B)
from FailedCompleteParseASTExpressionTest to CompleteParseASTExpressionTest

View file

@ -64,6 +64,7 @@ public class ManagedBuildTests extends TestCase {
suite.addTest(new ManagedBuildTests("testExtensions"));
suite.addTest(new ManagedBuildTests("testProjectCreation"));
suite.addTest(new ManagedBuildTests("testConfigurations"));
suite.addTest(new ManagedBuildTests("testConfigurationReset"));
suite.addTest(new ManagedBuildTests("testTargetArtifacts"));
suite.addTest(new ManagedBuildTests("testScannerInfoInterface"));
suite.addTest(new ManagedBuildTests("cleanup"));
@ -266,6 +267,39 @@ public class ManagedBuildTests extends TestCase {
checkOptionReferences(project);
}
public void testConfigurationReset() {
// Open the test project
IProject project = null;
try {
project = createProject(projectName);
} catch (CoreException e) {
fail("Failed to open project: " + e.getLocalizedMessage());
}
// Get the default configuration
IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project);
assertNotNull(info);
ITarget defaultTarget = info.getDefaultTarget();
assertNotNull(defaultTarget);
IConfiguration defaultConfig = info.getDefaultConfiguration(defaultTarget);
assertNotNull(defaultConfig);
// See if it still contains the overridden values (see testProjectCreation())
try {
checkRootTarget(defaultTarget, "z");
} catch (BuildException e1) {
fail("Overridden root target check failed: " + e1.getLocalizedMessage());
}
// Reset the config and retest
ManagedBuildManager.resetConfiguration(project, defaultConfig);
try {
checkRootTarget(defaultTarget, "x");
} catch (BuildException e2) {
fail("Reset root target check failed: " + e2.getLocalizedMessage());
}
}
/**
* @throws CoreException
* @throws BuildException

View file

@ -1,3 +1,34 @@
2003-09-10 Sean Evoy
Work completed to resolve [Bug 41412] "Restore Default in Managed Build project's
settings Not Working". The configuration now has a reset method that removes
any user settings and replaces them with the values defined in the plugin
manifest. The Configuration class also has a new, safe accessor for getting
at the defined tool references. Replaced all the checks for null with the accessor.
Added some string constants to the IConfiguration and ITarget interfaces
so manifest element lookup will be easier to maintain should the element names change.
Switched the Target class to use the new string constants during element lookup.
Added back a method in IConfiguration to lookup the parent configuration (which is the
plugin element I need to do the reset).
* build/org/eclipse/cdt/internal/core/build/managed/Configuration.java
* build/org/eclipse/cdt/core/build/managed/IConfiguration.java
* build/org/eclipse/cdt/core/build/managed/ITarget.java
* build/org/eclipse/cdt/core/build/managed/ITool.java
* build/org/eclipse/cdt/internal/core/build/managed/Target.java
Work to resolve [Bug 42735] "Manage Make will try to generate makefile for Release or
Debug directory". Added a new method to return all the configuration names so
the generator will know that the directory <project_root>/<config_name> should be ignored.
* build/org/eclipse/cdt/internal/core/build/managed/ManagedBuildInfo.java
* build/org/eclipse/cdt/core/build/managed/IManagedBuildInfo.java
Work to partially implement incremental build. New incremental build logic in the
incrementalBuild() method in the GeneratedMakefileBuilder class. It now calls a
specialized method in the makefile generator that calculates and generates the
needed makefiles and fragments. It then calls build if there are any changes worthy
of a build.
* src/org/eclipse/cdt/internal/core/GeneratedMakefileBuilder.java
* src/org/eclipse/cdt/internal/core/MakefileGenerator.java
2003-09-05 Bogdan Gheorghe
Hooked in the dependency checking on file changes in Delta

View file

@ -14,8 +14,9 @@ import org.eclipse.core.resources.IResource;
public interface IConfiguration extends IBuildObject {
// Schema element names
public static final String TOOL_REF = "toolReference";
public static final String PARENT = "parent";
public static final String CONFIGURATION_ELEMENT_NAME = "configuration"; //$NON-NLS-1$
public static final String TOOL_REF = "toolReference"; //$NON-NLS-1$
public static final String PARENT = "parent"; //$NON-NLS-1$
/**
* Returns the target for this configuration.
@ -30,6 +31,13 @@ public interface IConfiguration extends IBuildObject {
*/
public IResource getOwner();
/**
* Answers the configuration that the receiver is based on.
*
* @return
*/
public IConfiguration getParent();
/**
* Returns the tools that are used in this configuration.
*

View file

@ -53,6 +53,14 @@ public interface IManagedBuildInfo {
*/
public String getConfigurationName();
/**
* Answers a <code>String</code> array containing the names of all the configurations
* defined for the project's current target.
*
* @return
*/
public String[] getConfigurationNames();
/**
* Get the default configuration associated with the receiver
*

View file

@ -17,6 +17,7 @@ import org.eclipse.core.resources.IResource;
* is some type of resource built using a given collection of tools.
*/
public interface ITarget extends IBuildObject {
public static final String TARGET_ELEMENT_NAME = "target"; //$NON-NLS-1$
/**
* Creates a configuration for the target populated with the tools and

View file

@ -15,15 +15,16 @@ package org.eclipse.cdt.core.build.managed;
*/
public interface ITool extends IBuildObject {
// Schema element names
public static final String COMMAND = "command";
public static final String OPTION = "option";
public static final String OPTION_CAT = "optionCategory";
public static final String OPTION_REF = "optionReference";
public static final String OUTPUT_FLAG = "outputFlag";
public static final String OUTPUT_PREFIX = "outputPrefix";
public static final String OUTPUTS = "outputs";
public static final String SOURCES = "sources";
public static final String WHITE_SPACE = " ";
public static final String TOOL_ELEMENT_NAME = "tool"; //$NON-NLS-1$
public static final String COMMAND = "command"; //$NON-NLS-1$
public static final String OPTION = "option"; //$NON-NLS-1$
public static final String OPTION_CAT = "optionCategory"; //$NON-NLS-1$
public static final String OPTION_REF = "optionReference"; //$NON-NLS-1$
public static final String OUTPUT_FLAG = "outputFlag"; //$NON-NLS-1$
public static final String OUTPUT_PREFIX = "outputPrefix"; //$NON-NLS-1$
public static final String OUTPUTS = "outputs"; //$NON-NLS-1$
public static final String SOURCES = "sources"; //$NON-NLS-1$
public static final String WHITE_SPACE = " "; //$NON-NLS-1$
/**
* Return <code>true</code> if the receiver builds files with the

View file

@ -31,6 +31,7 @@ import org.apache.xml.serialize.SerializerFactory;
import org.eclipse.cdt.core.AbstractCExtension;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.parser.*;
import org.eclipse.cdt.internal.core.build.managed.Configuration;
import org.eclipse.cdt.internal.core.build.managed.ManagedBuildInfo;
import org.eclipse.cdt.internal.core.build.managed.Target;
import org.eclipse.core.resources.IFile;
@ -52,10 +53,11 @@ import org.w3c.dom.Node;
public class ManagedBuildManager extends AbstractCExtension implements IScannerInfoProvider {
private static final QualifiedName buildInfoProperty = new QualifiedName(CCorePlugin.PLUGIN_ID, "managedBuildInfo");
private static final String ROOT_ELEM_NAME = "ManagedProjectBuildInfo";
private static final String FILE_NAME = ".cdtbuild";
private static final String ROOT_ELEM_NAME = "ManagedProjectBuildInfo"; //$NON-NLS-1$
private static final String FILE_NAME = ".cdtbuild"; //$NON-NLS-1$
private static final ITarget[] emptyTargets = new ITarget[0];
public static final String INTERFACE_IDENTITY = CCorePlugin.PLUGIN_ID + "." + "ManagedBuildManager";
public static final String INTERFACE_IDENTITY = CCorePlugin.PLUGIN_ID + "." + "ManagedBuildManager"; //$NON-NLS-1$
public static final String EXTENSION_POINT_ID = "ManagedBuildInfo"; //$NON-NLS-1$
// Targets defined by extensions (i.e., not associated with a resource)
private static boolean extensionTargetsLoaded = false;
@ -311,6 +313,9 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
}
}
/**
* @param resource
*/
public static void removeBuildInfo(IResource resource) {
try {
resource.setSessionProperty(buildInfoProperty, null);
@ -318,6 +323,47 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
}
}
/**
* Resets the build information for the project and configuration specified in the arguments.
* The build information will contain the settings defined in the plugin manifest.
*
* @param project
* @param configuration
*/
public static void resetConfiguration(IProject project, IConfiguration configuration) {
// Make sure the extensions are loaded
loadExtensions();
// Find out the parent of the configuration
IConfiguration parentConfig = configuration.getParent();
// Find the parent target the configuration
ITarget parentTarget = parentConfig.getTarget();
// Get the extension point information
IExtensionPoint extensionPoint = CCorePlugin.getDefault().getDescriptor().getExtensionPoint(EXTENSION_POINT_ID);
IExtension[] extensions = extensionPoint.getExtensions();
for (int i = 0; i < extensions.length; ++i) {
IExtension extension = extensions[i];
IConfigurationElement[] elements = extension.getConfigurationElements();
for (int j = 0; j < elements.length; ++j) {
IConfigurationElement element = elements[j];
if (element.getName().equals(ITarget.TARGET_ELEMENT_NAME) &&
element.getAttribute(ITarget.ID).equals(parentTarget.getId())) {
// We have the parent target so get the definition for the parent config
IConfigurationElement[] targetElements = element.getChildren();
for (int k = 0; k < targetElements.length; ++k) {
IConfigurationElement targetElement = targetElements[k];
if (targetElement.getName().equals(IConfiguration.CONFIGURATION_ELEMENT_NAME) &&
targetElement.getAttribute(IConfiguration.ID).equals(parentConfig.getId())) {
// We now have the plugin element the target was originally based on
((Configuration)configuration).reset(targetElement);
}
}
}
}
}
}
// Private stuff
public static void addExtensionTarget(Target target) {
@ -356,14 +402,14 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
return;
extensionTargetsLoaded = true;
IExtensionPoint extensionPoint = CCorePlugin.getDefault().getDescriptor().getExtensionPoint("ManagedBuildInfo");
IExtensionPoint extensionPoint = CCorePlugin.getDefault().getDescriptor().getExtensionPoint(EXTENSION_POINT_ID);
IExtension[] extensions = extensionPoint.getExtensions();
for (int i = 0; i < extensions.length; ++i) {
IExtension extension = extensions[i];
IConfigurationElement[] elements = extension.getConfigurationElements();
for (int j = 0; j < elements.length; ++j) {
IConfigurationElement element = elements[j];
if (element.getName().equals("target")) {
if (element.getName().equals(ITarget.TARGET_ELEMENT_NAME)) {
new Target(element);
}
}
@ -516,4 +562,5 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
map.put(project, list);
}
}
}

View file

@ -147,9 +147,8 @@ public class Configuration extends BuildObject implements IConfiguration {
if (parent != null)
element.setAttribute(IConfiguration.PARENT, parent.getId());
if (toolReferences != null)
for (int i = 0; i < toolReferences.size(); ++i) {
ToolReference toolRef = (ToolReference)toolReferences.get(i);
for (int i = 0; i < getToolReferences().size(); ++i) {
ToolReference toolRef = (ToolReference)getToolReferences().get(i);
Element toolRefElement = doc.createElement(IConfiguration.TOOL_REF);
element.appendChild(toolRefElement);
toolRef.serialize(doc, toolRefElement);
@ -163,6 +162,16 @@ public class Configuration extends BuildObject implements IConfiguration {
return (name == null && parent != null) ? parent.getName() : name;
}
/*
* @return
*/
private List getToolReferences() {
if (toolReferences == null) {
toolReferences = new ArrayList();
}
return toolReferences;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.build.managed.IConfiguration#getTools()
*/
@ -181,6 +190,21 @@ public class Configuration extends BuildObject implements IConfiguration {
return tools;
}
/**
* @param targetElement
*/
public void reset(IConfigurationElement element) {
// I just need to reset the tool references
getToolReferences().clear();
IConfigurationElement[] configElements = element.getChildren();
for (int l = 0; l < configElements.length; ++l) {
IConfigurationElement configElement = configElements[l];
if (configElement.getName().equals(IConfiguration.TOOL_REF)) {
new ToolReference(this, configElement);
}
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.build.managed.IConfiguration#getParent()
*/
@ -209,9 +233,8 @@ public class Configuration extends BuildObject implements IConfiguration {
* @return
*/
private ToolReference getToolReference(ITool tool) {
if (toolReferences != null)
for (int i = 0; i < toolReferences.size(); ++i) {
ToolReference toolRef = (ToolReference)toolReferences.get(i);
for (int i = 0; i < getToolReferences().size(); ++i) {
ToolReference toolRef = (ToolReference)getToolReferences().get(i);
if (toolRef.references(tool))
return toolRef;
}
@ -219,9 +242,7 @@ public class Configuration extends BuildObject implements IConfiguration {
}
public void addToolReference(ToolReference toolRef) {
if (toolReferences == null)
toolReferences = new ArrayList();
toolReferences.add(toolRef);
getToolReferences().add(toolRef);
}
public OptionReference createOptionReference(IOption option) {
@ -293,4 +314,6 @@ public class Configuration extends BuildObject implements IConfiguration {
if(!Arrays.equals(value, oldValue))
createOptionReference(option).setValue(value);
}
}

View file

@ -133,6 +133,19 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
return config == null ? new String() : config.getName();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getConfigurationNames()
*/
public String[] getConfigurationNames() {
ArrayList configNames = new ArrayList();
IConfiguration[] configs = getDefaultTarget().getConfigurations();
for (int i = 0; i < configs.length; i++) {
IConfiguration configuration = configs[i];
configNames.add(configuration.getName());
}
return (String[])configNames.toArray(new String[configNames.size()]);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getDefaultConfiguration()
*/

View file

@ -132,9 +132,9 @@ public class Target extends BuildObject implements ITarget {
IConfigurationElement[] targetElements = element.getChildren();
for (int k = 0; k < targetElements.length; ++k) {
IConfigurationElement targetElement = targetElements[k];
if (targetElement.getName().equals("tool")) {
if (targetElement.getName().equals(ITool.TOOL_ELEMENT_NAME)) {
new Tool(this, targetElement);
} else if (targetElement.getName().equals("configuration")) {
} else if (targetElement.getName().equals(IConfiguration.CONFIGURATION_ELEMENT_NAME)) {
new Configuration(this, targetElement);
}
}
@ -186,7 +186,7 @@ public class Target extends BuildObject implements ITarget {
Node child = element.getFirstChild();
while (child != null) {
if (child.getNodeName().equals("configuration")) {
if (child.getNodeName().equals(IConfiguration.CONFIGURATION_ELEMENT_NAME)) {
new Configuration(this, (Element)child);
}
child = child.getNextSibling();

View file

@ -64,18 +64,21 @@ public class GeneratedMakefileBuilder extends ACBuilder {
public class ResourceDeltaVisitor implements IResourceDeltaVisitor {
boolean bContinue;
private boolean buildNeeded = false;
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()) {
bContinue = true;
buildNeeded = true;
return false;
}
return true;
}
public boolean shouldBuild() {
return bContinue;
return buildNeeded;
}
}
@ -256,9 +259,26 @@ public class GeneratedMakefileBuilder extends ACBuilder {
statusMsg = CCorePlugin.getFormattedString(INCREMENTAL, currentProject.getName());
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);
} catch (CoreException e) {
if (e.getStatus().getCode() == GeneratedMakefileBuilder.EMPTY_PROJECT_BUILD_ERROR) {
// There is nothing to build so bail
monitor.worked(1);
return;
} else {
throw e;
}
}
// Run the build if there is any relevant change
if (generator.shouldRunBuild()) {
IPath buildDir = new Path(info.getConfigurationName());
invokeMake(false, buildDir, info, monitor);
}
monitor.worked(1);
}

View file

@ -29,6 +29,8 @@ 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;
@ -69,11 +71,13 @@ public class MakefileGenerator {
// Local variables needed by generator
protected IManagedBuildInfo info;
protected List moduleList;
protected List modifiedList;
protected IProgressMonitor monitor;
protected List subdirList;
protected IProject project;
protected List ruleList;
protected IPath topBuildDir;
protected boolean shouldRunBuild;
/**
* This class is used to recursively walk the project and determine which
@ -107,7 +111,9 @@ public class MakefileGenerator {
IResource resource = proxy.requestResource();
String ext = resource.getFileExtension();
if (info.buildsFileType(ext)) {
generator.appendModule(resource);
if (!generator.isGeneratedResource(resource)) {
generator.appendBuildSubdirectory(resource);
}
}
return false;
}
@ -118,6 +124,77 @@ public class MakefileGenerator {
}
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)
* @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();
switch (delta.getKind()) {
case IResourceDelta.ADDED:
case IResourceDelta.REMOVED:
// Add the container of the resource and any resources that depend on it
if (info.buildsFileType(ext)) {
if (!generator.isGeneratedResource(resource)) {
// Here's the container
generator.appendModifiedSubdirectory(resource);
// and all the dependents
DependencyManager depMgr = CCorePlugin.getDefault().getCoreModel().getDependencyManager();
List deps = depMgr.getProjectDependsForFile(resource.getLocation().toOSString());
if (deps != null) {
ListIterator iter = deps.listIterator();
while (iter.hasNext()) {
generator.appendModifiedSubdirectory(resource);
}
}
// A build should run
generator.shouldRunBuild(true);
}
}
break;
case IResourceDelta.CHANGED:
if (info.buildsFileType(ext)) {
switch (delta.getFlags()) {
case IResourceDelta.CONTENT:
// If the contents changed then just do a build
generator.shouldRunBuild(true);
keepLooking = true;
default:
keepLooking = true;
}
}
break;
default:
keepLooking = true;
break;
}
} else {
// If the resource is part of the generated directory structure don't recurse
if (!generator.isGeneratedResource(resource)) {
keepLooking = true;
}
}
return keepLooking;
}
}
public MakefileGenerator(IProject project, IManagedBuildInfo info, IProgressMonitor monitor) {
super();
// Save the project so we can get path and member information
@ -126,9 +203,12 @@ public class MakefileGenerator {
this.monitor = monitor;
// Get the build info for the project
this.info = info;
// By default a build never runs
shouldRunBuild = false;
}
/**
/* (non-javadoc)
*
* @param module
* @return
*/
@ -184,7 +264,7 @@ public class MakefileGenerator {
return buffer;
}
/**
/* (non-javadoc)
* @param buffer
* @param info
*/
@ -202,13 +282,13 @@ public class MakefileGenerator {
buffer.append("C_SRCS := " + NEWLINE);
buffer.append("CC_SRCS := " + NEWLINE + NEWLINE);
// Add the libraries this project dependes on
// Add the libraries this project depends on
buffer.append("LIBS := ");
buffer.append(NEWLINE + NEWLINE);
return buffer;
}
/**
/* (non-javadoc)
* @return
*/
protected StringBuffer addModules() {
@ -216,16 +296,21 @@ public class MakefileGenerator {
// Add the comment
buffer.append(CCorePlugin.getResourceString(MOD_LIST) + NEWLINE);
buffer.append("MODULES := " + LINEBREAK + NEWLINE);
buffer.append("." + LINEBREAK + NEWLINE);
// Get all the module names
ListIterator iter = getModuleList().listIterator();
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("." + 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(CCorePlugin.getResourceString(MOD_INCL) + NEWLINE);
buffer.append("include ${patsubst %, %/module.mk, $(MODULES)}" + NEWLINE);
@ -235,7 +320,7 @@ public class MakefileGenerator {
}
/**
/* (non-javadoc)
* Answers a <code>StringBuffer</code> containing all of the sources contributed by
* a container to the build.
* @param module
@ -282,7 +367,7 @@ public class MakefileGenerator {
return buffer;
}
/**
/* (non-javadoc)
* Answers a <code>StrinBuffer</code> containing all of the required targets to
* properly build the project.
*/
@ -398,26 +483,36 @@ public class MakefileGenerator {
}
/**
* 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 resouce is not generated as part of the build.
*
* @param resource
*/
public void appendModule(IResource resource) {
// The build model knows how to build this file
public void appendBuildSubdirectory(IResource resource) {
IContainer container = resource.getParent();
// But is this a generated directory ...
IPath root = new Path(info.getConfigurationName());
IPath path = container.getProjectRelativePath();
if (root.isPrefixOf(path)) {
return;
}
if (!getModuleList().contains(container)) {
getModuleList().add(container);
if (!getSubdirList().contains(container)) {
getSubdirList().add(container);
}
}
/**
* Check whether the build has been canceled. Cancellation requests
* 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);
}
}
/**
* 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()
@ -428,17 +523,93 @@ public class MakefileGenerator {
}
}
/**
* @return
*/
private List getModuleList() {
if (moduleList == null) {
moduleList = new ArrayList();
}
return moduleList;
}
/**
* 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. This is an incremental build, so if the top-level directory is not there, then
* a rebuild is needed anyway.
*/
IFolder folder = project.getFolder(info.getConfigurationName());
if (!folder.exists()) {
regenerateMakefiles();
shouldRunBuild(true);
return;
}
// Visit the resources in the delta and compile a list of subdirectories to regenerate
ResourceDeltaVisitor visitor = new ResourceDeltaVisitor(this, info);
delta.accept(visitor);
// There may be nothing to regenerate and no content changes that require a rebuild
if (getModifiedList().isEmpty() && !shouldRunBuild()) {
// There is nothing to build
IStatus status = new Status(IStatus.INFO, CCorePlugin.PLUGIN_ID, GeneratedMakefileBuilder.EMPTY_PROJECT_BUILD_ERROR, "", null);
throw new CoreException(status);
}
// 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);
if (getSubdirList().isEmpty()) {
// There is nothing to build (but we should never throw this exception)
IStatus status = new Status(IStatus.INFO, CCorePlugin.PLUGIN_ID, GeneratedMakefileBuilder.EMPTY_PROJECT_BUILD_ERROR, "", null);
throw new CoreException(status);
}
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);
checkCancel();
// Regenerate any fragments for modified directories
iter = getModifiedList().listIterator();
while (iter.hasNext()) {
populateFragmentMakefile((IContainer) iter.next());
checkCancel();
}
}
/* (non-javadoc)
* @return
*/
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.
*
*/
private List getRuleList() {
@ -448,7 +619,18 @@ public class MakefileGenerator {
return ruleList;
}
/**
/* (non-javadoc)
* Answers the list of subdirectories contributing source code to the build
* @return
*/
private List getSubdirList() {
if (subdirList == null) {
subdirList = new ArrayList();
}
return subdirList;
}
/* (non-javadoc)
* @param string
* @return
*/
@ -481,7 +663,7 @@ public class MakefileGenerator {
return folder.getFullPath();
}
/**
/* (non-javadoc)
* @param makefilePath
* @param monitor
* @return
@ -505,7 +687,7 @@ public class MakefileGenerator {
else
throw e;
}
// TODO handle long running file operation
return newFile;
}
@ -520,13 +702,32 @@ public class MakefileGenerator {
}
/**
* Answers <code>true</code> if the argument is found in a generated container
* @param resource
* @return
*/
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 info
* @param monitor
*/
protected void populateMakefile(IFile fileHandle) {
protected void populateTopMakefile(IFile fileHandle) {
StringBuffer buffer = new StringBuffer();
// Add the macro definitions
@ -541,16 +742,16 @@ public class MakefileGenerator {
// Save the file
try {
Util.save(buffer, fileHandle);
} catch (CoreException e1) {
} catch (CoreException e) {
// TODO Auto-generated catch block
e1.printStackTrace();
e.printStackTrace();
}
}
/**
/* (non-javadoc)
* @param module
*/
protected void populateModMakefile(IContainer 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);
@ -578,11 +779,14 @@ public class MakefileGenerator {
}
/**
* @throws CoreException
*/
public void regenerateMakefiles() throws CoreException {
// Visit the resources in the project
ResourceProxyVisitor visitor = new ResourceProxyVisitor(this, info);
project.accept(visitor, IResource.NONE);
if (getModuleList().isEmpty()) {
if (getSubdirList().isEmpty()) {
// There is nothing to build
IStatus status = new Status(IStatus.INFO, CCorePlugin.PLUGIN_ID, GeneratedMakefileBuilder.EMPTY_PROJECT_BUILD_ERROR, "", null);
throw new CoreException(status);
@ -599,15 +803,33 @@ public class MakefileGenerator {
IFile makefileHandle = createFile(makefilePath);
// Populate the makefile
populateMakefile(makefileHandle);
populateTopMakefile(makefileHandle);
checkCancel();
// Now populate the module makefiles
ListIterator iter = getModuleList().listIterator();
ListIterator iter = getSubdirList().listIterator();
while (iter.hasNext()) {
populateModMakefile((IContainer)iter.next());
populateFragmentMakefile((IContainer)iter.next());
checkCancel();
}
}
/**
* Answers whether a build is required after the makefiles have been
* generated.
*
* @return
*/
public boolean shouldRunBuild() {
return shouldRunBuild;
}
/**
* Sets the build flag to the value of the argument.
*
* @param b
*/
public void shouldRunBuild(boolean b) {
shouldRunBuild = b;
}
}

View file

@ -1,3 +1,11 @@
2003-09-10 Sean Evoy
Work completed to resolve [Bug 41412] Restore Default in Managed Build
project's settings Not Working. Added an event handler to reset the selected
configuration settings back to the defaults defined in the plugin manifest.
Work to resolve [Bug 42736] New: C/C++ Build Settings not remembering Configuration.
Used the managed build info to get the current config for the target.
* build/org/eclipse/cdt/ui/build/properties/BuildPropertyPage.java
2003-09-08 Bogdan Gheorghe
- Changed search pop up menu in CEditor and CContentOutlinePage

View file

@ -18,6 +18,7 @@ import java.util.ListIterator;
import java.util.Map;
import org.eclipse.cdt.core.build.managed.IConfiguration;
import org.eclipse.cdt.core.build.managed.IManagedBuildInfo;
import org.eclipse.cdt.core.build.managed.IOptionCategory;
import org.eclipse.cdt.core.build.managed.ITarget;
import org.eclipse.cdt.core.build.managed.ManagedBuildManager;
@ -276,7 +277,7 @@ public class BuildPropertyPage extends PropertyPage implements IWorkbenchPropert
*/
private void displayOptionsForCategory(IOptionCategory category) {
// Do nothing if the selected category is is unchanged
if (selectedCategory == category) {
if (category == selectedCategory) {
return;
}
selectedCategory = category;
@ -451,13 +452,38 @@ public class BuildPropertyPage extends PropertyPage implements IWorkbenchPropert
populateConfigurations();
}
/**
/*
* (non-javadoc)
* Initialize the relative weights (widths) of the 2 sides of the sash.
*/
protected void initializeSashForm() {
sashForm.setWeights(DEFAULT_SASH_WEIGHTS);
}
/*
* (non-Javadoc)
* @see org.eclipse.jface.preference.PreferencePage#performDefaults()
*/
protected void performDefaults() {
// Empty the page list
List pages = getPagesForConfig();
pages.clear();
// Get the build manager to reset build info for project
ManagedBuildManager.resetConfiguration(getProject(), getSelectedConfiguration());
// Recreate the settings store for the configuration
settingsStore = new BuildToolsSettingsStore(getSelectedConfiguration());
// Reset the category selection and run selection event handler
selectedCategory = null;
handleOptionSelection();
}
/*
* (non-Javadoc)
* @see org.eclipse.jface.preference.IPreferencePage#performOk()
*/
public boolean performOk() {
// Force each settings page to update
List pages = getPagesForConfig();
@ -485,7 +511,10 @@ public class BuildPropertyPage extends PropertyPage implements IWorkbenchPropert
configSelector.setItems(getConfigurationNames());
// Make sure the active configuration is selected
configSelector.select(0);
IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(getProject());
IConfiguration defaultConfig = info.getDefaultConfiguration(selectedTarget);
int index = configSelector.indexOf(defaultConfig.getName());
configSelector.select(index == -1 ? 0 : index);
handleConfigSelection();
}