1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 18:26:01 +02:00

Patch for Sean Evoy:

- The fix is for bug 43017, something I need anyway. The 
incremental build work is to make a full rebuild happen when the build 
settings change through the UI. Tested the changes on Linux and Win32.
This commit is contained in:
Doug Schaefer 2003-09-16 21:27:58 +00:00
parent 6b328b777c
commit c7a74ef049
9 changed files with 138 additions and 56 deletions

View file

@ -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 2003-09-15 Sean Evoy
First submission of code to new project. Moved the managed builder First submission of code to new project. Moved the managed builder
source code out of the cdt.core project. This includes the code to source code out of the cdt.core project. This includes the code to

View file

@ -182,6 +182,20 @@ public interface IManagedBuildInfo {
*/ */
public String getToolForTarget(String extension); 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. * Set the primary configuration for the receiver.
* *

View file

@ -207,20 +207,24 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
* @param option * @param option
*/ */
private static void setDirty(IConfiguration config, IOption 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 if (!(option.getValueType() == IOption.INCLUDE_PATH
|| option.getValueType() == IOption.PREPROCESSOR_SYMBOLS)) { || option.getValueType() == IOption.PREPROCESSOR_SYMBOLS)) {
return; return;
} }
// Figure out if there is a listener for this change // Figure out if there is a listener for this change
IResource resource = config.getOwner();
List listeners = (List) getBuildModelListeners().get(resource); List listeners = (List) getBuildModelListeners().get(resource);
if (listeners == null) { if (listeners == null) {
return; return;
} }
ListIterator iter = listeners.listIterator(); ListIterator iter = listeners.listIterator();
while (iter.hasNext()) { 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) { if (buildInfo == null && create) {
try { try {
buildInfo = new ManagedBuildInfo(); buildInfo = new ManagedBuildInfo(resource);
resource.setSessionProperty(buildInfoProperty, buildInfo); resource.setSessionProperty(buildInfoProperty, buildInfo);
} catch (CoreException e) { } catch (CoreException e) {
buildInfo = null; buildInfo = null;
@ -493,21 +497,6 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
return buildModelListeners; 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) /* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IScannerInfoProvider#getScannerInformation(org.eclipse.core.resources.IResource) * @see org.eclipse.cdt.core.parser.IScannerInfoProvider#getScannerInformation(org.eclipse.core.resources.IResource)
*/ */

View file

@ -99,23 +99,27 @@ public class GeneratedMakefileBuilder extends ACBuilder {
monitor.subTask(statusMsg); monitor.subTask(statusMsg);
} }
if (kind == IncrementalProjectBuilder.FULL_BUILD) { IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(getProject());
fullBuild(monitor);
if (kind == IncrementalProjectBuilder.FULL_BUILD || info.isDirty()) {
fullBuild(monitor, info);
} }
else { else {
// Create a delta visitor to make sure we should be rebuilding // Create a delta visitor to make sure we should be rebuilding
ResourceDeltaVisitor visitor = new ResourceDeltaVisitor(); ResourceDeltaVisitor visitor = new ResourceDeltaVisitor();
IResourceDelta delta = getDelta(getProject()); IResourceDelta delta = getDelta(getProject());
if (delta == null) { if (delta == null) {
fullBuild(monitor); fullBuild(monitor, info);
} }
else { else {
delta.accept(visitor); delta.accept(visitor);
if (visitor.shouldBuild()) { if (visitor.shouldBuild()) {
incrementalBuild(delta, monitor); incrementalBuild(delta, info, monitor);
} }
} }
} }
info.setDirty(false);
// Checking to see if the user cancelled the build // Checking to see if the user cancelled the build
checkCancel(monitor); checkCancel(monitor);
@ -138,7 +142,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
/** /**
* @param monitor * @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 // Always need one of these bad boys
if (monitor == null) { if (monitor == null) {
monitor = new NullProgressMonitor(); monitor = new NullProgressMonitor();
@ -175,7 +179,6 @@ public class GeneratedMakefileBuilder extends ACBuilder {
monitor.subTask(statusMsg); monitor.subTask(statusMsg);
// Regenerate the makefiles for this project // Regenerate the makefiles for this project
IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(getProject());
MakefileGenerator generator = new MakefileGenerator(currentProject, info, monitor); MakefileGenerator generator = new MakefileGenerator(currentProject, info, monitor);
try { try {
generator.regenerateMakefiles(); generator.regenerateMakefiles();
@ -194,20 +197,27 @@ public class GeneratedMakefileBuilder extends ACBuilder {
monitor.worked(1); monitor.worked(1);
} }
/** /* (non-javadoc)
* @param makefilePath * Answers an array of strings with the proper make targets
* @param info *
* @param fullBuild
* @return * @return
*/ */
protected String[] getMakeTargets() { protected String[] getMakeTargets(boolean fullBuild) {
List args = new ArrayList(); List args = new ArrayList();
if (fullBuild) {
args.add("clean");
}
// Add each target // Add each target
String sessionTarget = MakeUtil.getSessionTarget(getProject()); String sessionTarget = MakeUtil.getSessionTarget(getProject());
StringTokenizer tokens = new StringTokenizer(sessionTarget); StringTokenizer tokens = new StringTokenizer(sessionTarget);
while (tokens.hasMoreTokens()) { 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"); args.add("all");
} }
return (String[])args.toArray(new String[args.size()]); return (String[])args.toArray(new String[args.size()]);
@ -248,7 +258,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
* @param delta * @param delta
* @param monitor * @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 // Rebuild the resource tree in the delta
IProject currentProject = getProject(); IProject currentProject = getProject();
String statusMsg = null; String statusMsg = null;
@ -261,7 +271,6 @@ public class GeneratedMakefileBuilder extends ACBuilder {
monitor.subTask(statusMsg); monitor.subTask(statusMsg);
// Ask the makefile generator to generate any makefiles needed to build delta // Ask the makefile generator to generate any makefiles needed to build delta
IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(getProject());
MakefileGenerator generator = new MakefileGenerator(currentProject, info, monitor); MakefileGenerator generator = new MakefileGenerator(currentProject, info, monitor);
try { try {
generator.generateMakefiles(delta); generator.generateMakefiles(delta);
@ -324,7 +333,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
IPath workingDirectory = getWorkingDirectory().append(buildDir); IPath workingDirectory = getWorkingDirectory().append(buildDir);
// Get the arguments to be passed to make from build model // 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 // Get a launcher for the make command
String errMsg = null; String errMsg = null;

View file

@ -196,6 +196,11 @@ public class MakefileGenerator {
} }
} }
/**
* @param project
* @param info
* @param monitor
*/
public MakefileGenerator(IProject project, IManagedBuildInfo info, IProgressMonitor monitor) { public MakefileGenerator(IProject project, IManagedBuildInfo info, IProgressMonitor monitor) {
super(); super();
// Save the project so we can get path and member information // Save the project so we can get path and member information
@ -209,11 +214,14 @@ public class MakefileGenerator {
} }
/* (non-javadoc) /* (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 * @param module
* @return * @return
*/ */
protected StringBuffer addDeps(IContainer module) throws CoreException { protected StringBuffer addSourceDependencies(IContainer module) throws CoreException {
// Calculate the new directory relative to the build output // Calculate the new directory relative to the build output
IPath moduleRelativePath = module.getProjectRelativePath(); IPath moduleRelativePath = module.getProjectRelativePath();
String relativePath = moduleRelativePath.toString(); String relativePath = moduleRelativePath.toString();
@ -372,7 +380,7 @@ public class MakefileGenerator {
* Answers a <code>StrinBuffer</code> containing all of the required targets to * Answers a <code>StrinBuffer</code> containing all of the required targets to
* properly build the project. * properly build the project.
*/ */
protected StringBuffer addTargets() { protected StringBuffer addTargets(boolean rebuild) {
StringBuffer buffer = new StringBuffer(); StringBuffer buffer = new StringBuffer();
// Get the target and it's extension // Get the target and it's extension
@ -383,16 +391,16 @@ public class MakefileGenerator {
/* /*
* Write out the target rule as: * Write out the target rule as:
* <prefix><target>.<extension>: $(CC_SRCS:$(ROOT)/%.cpp=%.o) $(C_SRCS:$(ROOT)/%.c=%.o) * <prefix><target>.<extension>: $(CC_SRCS:$(ROOT)/%.cpp=%.o) $(C_SRCS:$(ROOT)/%.c=%.o)
* <cd <Proj_Dep_1/build_dir>; make all> * <cd <Proj_Dep_1/build_dir>; $(MAKE) all>
* <cd <Proj_Dep_.../build_dir>; make all> * <cd <Proj_Dep_.../build_dir>; $(MAKE) all>
* <cd <Proj_Dep_n/build_dir>; make all> * <cd <Proj_Dep_n/build_dir>; $(MAKE) all>
* $(BUILD_TOOL) $(FLAGS) $(OUTPUT_FLAG) $@ $^ $(LIB_DEPS) * $(BUILD_TOOL) $(FLAGS) $(OUTPUT_FLAG) $@ $^ $(LIB_DEPS)
*/ */
String cmd = info.getToolForTarget(extension); String cmd = info.getToolForTarget(extension);
String flags = info.getFlagsForTarget(extension); String flags = info.getFlagsForTarget(extension);
String outflag = info.getOutputFlag(extension); String outflag = info.getOutputFlag(extension);
String outputPrefix = info.getOutputPrefix(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); buffer.append(outputPrefix + target + COLON + WHITESPACE + "$(CC_SRCS:$(ROOT)/%.cpp=%.o) $(C_SRCS:$(ROOT)/%.c=%.o)" + NEWLINE);
IProject[] deps; IProject[] deps;
try { try {
@ -404,11 +412,11 @@ public class MakefileGenerator {
IManagedBuildInfo depInfo = ManagedBuildManager.getBuildInfo(dep); IManagedBuildInfo depInfo = ManagedBuildManager.getBuildInfo(dep);
buildDir += SEPARATOR + depInfo.getConfigurationName(); 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) { } catch (CoreException e) {
// TODO Auto-generated catch block // There are 2 exceptions; the project does not exist or it is not open
e.printStackTrace(); // and neither conditions apply if we are building for it ....
} }
buffer.append(TAB + cmd + WHITESPACE + flags + WHITESPACE + outflag + WHITESPACE + "$@" + WHITESPACE + "$^"); buffer.append(TAB + cmd + WHITESPACE + flags + WHITESPACE + outflag + WHITESPACE + "$@" + WHITESPACE + "$^");
@ -420,7 +428,7 @@ public class MakefileGenerator {
buffer.append(NEWLINE); buffer.append(NEWLINE);
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("all: " + outputPrefix + target + NEWLINE);
buffer.append(NEWLINE); buffer.append(NEWLINE);
@ -587,7 +595,7 @@ public class MakefileGenerator {
topBuildDir = createDirectory(info.getConfigurationName()); topBuildDir = createDirectory(info.getConfigurationName());
IPath makefilePath = topBuildDir.addTrailingSeparator().append(MAKEFILE_NAME); IPath makefilePath = topBuildDir.addTrailingSeparator().append(MAKEFILE_NAME);
IFile makefileHandle = createFile(makefilePath); IFile makefileHandle = createFile(makefilePath);
populateTopMakefile(makefileHandle); populateTopMakefile(makefileHandle, false);
checkCancel(); checkCancel();
// Regenerate any fragments for modified directories // Regenerate any fragments for modified directories
@ -725,10 +733,9 @@ public class MakefileGenerator {
* Create the entire contents of the makefile. * Create the entire contents of the makefile.
* *
* @param fileHandle The file to place the contents in. * @param fileHandle The file to place the contents in.
* @param info * @param rebuild FLag signalling that the user is doing a full rebuild
* @param monitor
*/ */
protected void populateTopMakefile(IFile fileHandle) { protected void populateTopMakefile(IFile fileHandle, boolean rebuild) {
StringBuffer buffer = new StringBuffer(); StringBuffer buffer = new StringBuffer();
// Add the macro definitions // Add the macro definitions
@ -738,7 +745,7 @@ public class MakefileGenerator {
buffer.append(addModules()); buffer.append(addModules());
// Add targets // Add targets
buffer.append(addTargets()); buffer.append(addTargets(rebuild));
// Save the file // Save the file
try { try {
@ -772,7 +779,7 @@ public class MakefileGenerator {
// Create a module dep file // Create a module dep file
IFile modDepfile = createFile(moduleOutputDir.addTrailingSeparator().append(DEPFILE_NAME)); IFile modDepfile = createFile(moduleOutputDir.addTrailingSeparator().append(DEPFILE_NAME));
StringBuffer depBuf = new StringBuffer(); StringBuffer depBuf = new StringBuffer();
depBuf.append(addDeps(module)); depBuf.append(addSourceDependencies(module));
// Save the files // Save the files
Util.save(makeBuf, modMakefile); Util.save(makeBuf, modMakefile);
@ -804,7 +811,7 @@ public class MakefileGenerator {
IFile makefileHandle = createFile(makefilePath); IFile makefileHandle = createFile(makefilePath);
// Populate the makefile // Populate the makefile
populateTopMakefile(makefileHandle); populateTopMakefile(makefileHandle, true);
checkCancel(); checkCancel();
// Now populate the module makefiles // Now populate the module makefiles

View file

@ -33,20 +33,23 @@ import org.w3c.dom.Node;
public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
private boolean isDirty;
private IResource owner; private IResource owner;
private Map targetMap; private Map targetMap;
private List targets; private List targets;
private Map defaultConfigurations; private Map defaultConfigurations;
private ITarget defaultTarget; private ITarget defaultTarget;
public ManagedBuildInfo() { public ManagedBuildInfo(IResource owner) {
targetMap = new HashMap(); targetMap = new HashMap();
targets = new ArrayList(); targets = new ArrayList();
defaultConfigurations = new HashMap(); defaultConfigurations = new HashMap();
this.owner = owner;
} }
public ManagedBuildInfo(IResource owner, Element element) { public ManagedBuildInfo(IResource owner, Element element) {
this(); this(owner);
// The id of the default configuration // The id of the default configuration
String defaultTargetId = null; String defaultTargetId = null;
List configIds = new ArrayList(); List configIds = new ArrayList();
@ -460,6 +463,20 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
return null; 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) { public void serialize(Document doc, Element element) {
// Write out each target and their default config // Write out each target and their default config
for (int i = 0; i < targets.size(); ++i) { for (int i = 0; i < targets.size(); ++i) {
@ -502,4 +519,11 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
defaultTarget = target; defaultTarget = target;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setDirty(boolean)
*/
public void setDirty(boolean isDirty) {
this.isDirty = isDirty;
}
} }

View file

@ -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 2003-09-15 Sean Evoy
First submission of code to new project. Moved all the managed First submission of code to new project. Moved all the managed
builder-specific UI elements out of the cdt.ui project. This builder-specific UI elements out of the cdt.ui project. This

View file

@ -90,11 +90,14 @@ public class BuildOptionListFieldEditor extends FieldEditor {
// Add it to the list // Add it to the list
if (input != null) { if (input != null) {
int index = list.getSelectionIndex(); int index = list.getSelectionIndex();
if (index >= 0) if (index >= 0) {
list.add(input, index + 1); list.add(input, index + 1);
else list.setSelection(index + 1);
}
else {
list.add(input, 0); list.add(input, 0);
selectionChanged(); list.setSelection(0);
}
} }
} }
@ -213,6 +216,7 @@ public class BuildOptionListFieldEditor extends FieldEditor {
// Create the buttons // Create the buttons
createButtons(buttonGroup); createButtons(buttonGroup);
selectionChanged();
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -284,6 +288,7 @@ public class BuildOptionListFieldEditor extends FieldEditor {
for (int i = 0; i < array.length; i++){ for (int i = 0; i < array.length; i++){
list.add(array[i]); list.add(array[i]);
} }
list.setSelection(0);
} }
} }

View file

@ -208,7 +208,12 @@ public class ManagedBuildTests extends TestCase {
} }
} }
assertNotNull(symbolOpt); assertNotNull(symbolOpt);
IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project);
assertFalse(info.isDirty());
ManagedBuildManager.setOption(defaultConfig, symbolOpt, expectedSymbols); ManagedBuildManager.setOption(defaultConfig, symbolOpt, expectedSymbols);
assertTrue(info.isDirty());
info.setDirty(false);
assertFalse(info.isDirty());
} }
/** /**