1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 09:46:02 +02:00

Fix for bug 67438 - All the actions on eclipse result in an error after performing "Rebuild" on a project referencing another project in a workspace with space in it's path.

This commit is contained in:
Sean Evoy 2004-06-21 16:14:35 +00:00
parent dad66224a2
commit fa3f0e854e
5 changed files with 313 additions and 136 deletions

View file

@ -12,6 +12,8 @@ package org.eclipse.cdt.managedbuilder.core;
public class BuildException extends Exception {
public static final int BUILD_FAILED = -1;
public BuildException(String msg) {
super(msg);
}

View file

@ -16,14 +16,17 @@ import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CommandLauncher;
import org.eclipse.cdt.core.ConsoleOutputStream;
import org.eclipse.cdt.core.ErrorParserManager;
import org.eclipse.cdt.core.IMarkerGenerator;
import org.eclipse.cdt.core.model.ICModelMarker;
import org.eclipse.cdt.core.resources.ACBuilder;
import org.eclipse.cdt.core.resources.IConsole;
@ -31,8 +34,8 @@ import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
import org.eclipse.cdt.managedbuilder.core.ITool;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator;
import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator;
import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
@ -47,6 +50,8 @@ import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
@ -156,10 +161,12 @@ public class GeneratedMakefileBuilder extends ACBuilder {
public static boolean VERBOSE = false;
// Local variables
protected Vector generationProblems;
protected IManagedBuilderMakefileGenerator generator;
protected IProject[] referencedProjects;
protected List resourcesToBuild;
protected List ruleList;
private IConsole console;
public static void outputTrace(String resourceName, String message) {
if (VERBOSE) {
@ -180,6 +187,21 @@ public class GeneratedMakefileBuilder extends ACBuilder {
public GeneratedMakefileBuilder() {
}
/**
* @param epm
*/
private void addBuilderMarkers(ErrorParserManager epm) {
IWorkspaceRoot root = CCorePlugin.getWorkspace().getRoot();
Iterator iter = getGenerationProblems().iterator();
while (iter.hasNext()) {
IStatus stat = (IStatus)iter.next();
IResource location = root.findMember(stat.getMessage());
if (stat.getCode() == IManagedBuilderMakefileGenerator.SPACES_IN_PATH) {
epm.generateMarker(location, -1, ManagedMakeMessages.getResourceString("MakefileGenerator.error.spaces"), IMarkerGenerator.SEVERITY_WARNING, null); //$NON-NLS-1$
}
}
}
/* (non-Javadoc)
* @see org.eclipse.core.internal.events.InternalBuilder#build(int, java.util.Map, org.eclipse.core.runtime.IProgressMonitor)
*/
@ -196,11 +218,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
}
// So let's figure out why we got called
if (kind == CLEAN_BUILD) {
outputTrace(getProject().getName(), "Clean build requested"); //$NON-NLS-1$
cleanBuild(monitor, info);
}
else if (kind == FULL_BUILD || info.needsRebuild()) {
if (kind == FULL_BUILD || info.needsRebuild()) {
outputTrace(getProject().getName(), "Full build needed/requested"); //$NON-NLS-1$
fullBuild(monitor, info);
}
@ -245,7 +263,21 @@ public class GeneratedMakefileBuilder extends ACBuilder {
}
}
/**
/* (non-Javadoc)
* @see org.eclipse.core.resources.IncrementalProjectBuilder#clean(org.eclipse.core.runtime.IProgressMonitor)
*/
protected void clean(IProgressMonitor monitor) throws CoreException {
referencedProjects = getProject().getReferencedProjects();
outputTrace(getProject().getName(), "Clean build requested"); //$NON-NLS-1$
IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(getProject());
if (info == null) {
outputError(getProject().getName(), "Build information was not found"); //$NON-NLS-1$
return;
}
cleanBuild(monitor, info);
}
/* (non-Javadoc)
* @param monitor
* @param info
*/
@ -253,7 +285,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
// Make sure that there is a top level directory and a set of makefiles
String targetID = info.getDefaultTarget().getParent().getId();
generator = ManagedBuildManager.getMakefileGenerator(targetID);
IPath buildDir = new Path(info.getConfigurationName());
IPath buildDir = getProject().getLocation().append(info.getConfigurationName());
IPath makefilePath = buildDir.append(generator.getMakefileName());
IWorkspaceRoot root = CCorePlugin.getWorkspace().getRoot();
IFile makefile = root.getFileForLocation(makefilePath);
@ -267,7 +299,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
}
}
/**
/* (non-Javadoc)
* @param monitor
*/
protected void fullBuild(IProgressMonitor monitor, IManagedBuildInfo info) throws CoreException {
@ -283,12 +315,11 @@ public class GeneratedMakefileBuilder extends ACBuilder {
String targetID = info.getDefaultTarget().getParent().getId();
generator = ManagedBuildManager.getMakefileGenerator(targetID);
generator.initialize(getProject(), info, monitor);
try {
generator.regenerateMakefiles();
} catch (CoreException e) {
// Throw the exception back to the builder
throw e;
MultiStatus result = generator.regenerateMakefiles();
if (result.getCode() != IStatus.OK) {
getGenerationProblems().addAll(Arrays.asList(result.getChildren()));
}
monitor.worked(1);
// Now call make
@ -352,6 +383,18 @@ public class GeneratedMakefileBuilder extends ACBuilder {
}
return null;
}
/* (non-Javadoc)
*
* @return
*/
private Vector getGenerationProblems() {
if (generationProblems == null) {
generationProblems = new Vector();
}
return generationProblems;
}
/* (non-javadoc)
* Answers an array of strings with the proper make targets
*
@ -422,12 +465,9 @@ public class GeneratedMakefileBuilder extends ACBuilder {
String targetID = info.getDefaultTarget().getParent().getId();
generator = ManagedBuildManager.getMakefileGenerator(targetID);
generator.initialize(getProject(), info, monitor);
try {
generator.generateMakefiles(delta);
} catch (CoreException e) {
// Throw the exception back to the builder
ManagedBuilderCorePlugin.log(e);
throw e;
MultiStatus result = generator.generateMakefiles(delta);
if (result.getCode() != IStatus.OK) {
getGenerationProblems().addAll(Arrays.asList(result.getChildren()));
}
monitor.worked(1);
@ -501,9 +541,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
// Get a build console for the project
StringBuffer buf = new StringBuffer();
IConsole console = CCorePlugin.getDefault().getConsole();
console.start(currentProject);
ConsoleOutputStream consoleOutStream = console.getOutputStream();
ConsoleOutputStream consoleOutStream = getConsole().getOutputStream();
String[] consoleHeader = new String[3];
switch (buildType) {
case FULL_BUILD:
@ -623,16 +661,29 @@ public class GeneratedMakefileBuilder extends ACBuilder {
stderr.close();
monitor.subTask(ManagedMakeMessages.getResourceString(MARKERS));
addBuilderMarkers(epm);
epm.reportProblems();
}
} catch (Exception e) {
ManagedBuilderCorePlugin.log(e);
forgetLastBuiltState();
} finally {
getGenerationProblems().clear();
monitor.done();
}
}
/**
* @return
*/
private IConsole getConsole() {
if (console == null) {
console = CCorePlugin.getDefault().getConsole();
console.start(getProject());
}
return console;
}
private void removeAllMarkers(IProject project) {
if (project == null || !project.exists()) return;

View file

@ -50,6 +50,7 @@ MakefileGenerator.comment.module.make.includes = Include the makefiles for each
MakefileGenerator.comment.module.dep.includes = Include automatically-generated dependency list:
MakefileGenerator.comment.autodeps = Automatically-generated dependency list:
MakefileGenerator.comment.header = Automatically-generated file. Do not edit!
MakefileGenerator.error.spaces = Cannot generate makefile for folder with spaces
ManagedBuildInfo.message.job.init = Initializing path container for {0}
ManagedBuildInfo.message.init.ok = Initializing path container succeeded for {0}

View file

@ -16,6 +16,7 @@ import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.MultiStatus;
/**
* @since 2.0
@ -50,6 +51,11 @@ public interface IManagedBuilderMakefileGenerator {
public final String WHITESPACE = " "; //$NON-NLS-1$
public final String WILDCARD = "%"; //$NON-NLS-1$
// Generation error codes
public static final int SPACES_IN_PATH = 0;
public static final int NO_SOURCE_FOLDERS = 1;
/**
* @throws CoreException
*/
@ -63,7 +69,7 @@ public interface IManagedBuilderMakefileGenerator {
* @param delta
* @throws CoreException
*/
public void generateMakefiles(IResourceDelta delta) throws CoreException ;
public MultiStatus generateMakefiles(IResourceDelta delta) throws CoreException ;
/**
* Answers the path of the top directory generated for the build
@ -96,6 +102,6 @@ public interface IManagedBuilderMakefileGenerator {
/**
* @throws CoreException
*/
public void regenerateMakefiles() throws CoreException;
public MultiStatus regenerateMakefiles() throws CoreException;
}

View file

@ -48,8 +48,11 @@ import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
/**
@ -210,6 +213,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
private Vector dependencyMakefiles;
private String extension;
private IManagedBuildInfo info;
private Vector invalidDirList;
private Vector modifiedList;
private IProgressMonitor monitor;
private Set outputExtensionsSet;
@ -374,6 +378,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
IPath moduleRelativePath = module.getProjectRelativePath();
String relativePath = moduleRelativePath.toString();
relativePath += relativePath.length() == 0 ? "" : SEPARATOR; //$NON-NLS-1$
relativePath = escapeWhitespaces(relativePath);
// For each tool for the target, lookup the kinds of sources it can handle and
// create a map which will map its extension to a string which holds its list of sources.
@ -400,7 +405,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
// there is no entry in the map, so create a buffer for this extension
StringBuffer tempBuffer = new StringBuffer();
tempBuffer.append(macroName + WHITESPACE + "+=" + WHITESPACE + LINEBREAK); //$NON-NLS-1$
tempBuffer.append("${addprefix $(ROOT)/" + relativePath + "," + LINEBREAK); //$NON-NLS-1$ //$NON-NLS-2$
tempBuffer.append("${addprefix $(ROOT)/" + relativePath + "," + WHITESPACE + LINEBREAK); //$NON-NLS-1$ //$NON-NLS-2$
// have to store the buffer in String form as StringBuffer is not a sublcass of Object
extensionToRuleStringMap.put(extensionName, tempBuffer.toString());
@ -549,9 +554,10 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
if (depExt.length() > 0) {
dependency += DOT + depExt;
}
dependency = escapeWhitespaces(dependency);
managedProjectOutputs.add(dependency);
}
buffer.append(TAB + "-cd" + WHITESPACE + buildDir + WHITESPACE + LOGICAL_AND + WHITESPACE + "$(MAKE) " + depTargets + NEWLINE); //$NON-NLS-1$ //$NON-NLS-2$
buffer.append(TAB + "-cd" + WHITESPACE + escapeWhitespaces(buildDir) + WHITESPACE + LOGICAL_AND + WHITESPACE + "$(MAKE) " + depTargets + NEWLINE); //$NON-NLS-1$ //$NON-NLS-2$
}
}
buffer.append(NEWLINE);
@ -619,10 +625,19 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
*/
protected void appendBuildSubdirectory(IResource resource) {
IContainer container = resource.getParent();
// If the path contains a space relative to the project, reject it from the build
if (resource.getProjectRelativePath().toString().indexOf(" ") != -1) { //$NON-NLS-1$
// Only add the container once
if (!getInvalidDirList().contains(container)) {
getInvalidDirList().add(container);
}
} else {
// Only add the container once
if (!getSubdirList().contains(container)) {
getSubdirList().add(container);
}
}
}
/**
* If a file is removed from a source folder (either because of a delete
@ -645,10 +660,18 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
*/
protected void appendModifiedSubdirectory(IResource resource) {
IContainer container = resource.getParent();
// If the path contains a space relative to the project, reject it from the build
if (resource.getProjectRelativePath().toString().indexOf(" ") != -1) { //$NON-NLS-1$
// Only add the container once
if (!getInvalidDirList().contains(container)) {
getInvalidDirList().add(container);
}
} else {
if (!getModifiedList().contains(container)) {
getModifiedList().add(container);
}
}
}
/* (non-Javadoc)
* @param message
@ -854,7 +877,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator#generateMakefiles(org.eclipse.core.resources.IResourceDelta)
*/
public void generateMakefiles(IResourceDelta delta) throws CoreException {
public MultiStatus generateMakefiles(IResourceDelta delta) throws CoreException {
/*
* Let's do a sanity check right now.
*
@ -863,8 +886,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
*/
IFolder folder = project.getFolder(info.getConfigurationName());
if (!folder.exists()) {
regenerateMakefiles();
return;
return regenerateMakefiles();
}
// Make sure the build directory is available
@ -920,6 +942,34 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
populateFragmentMakefile(subDir);
checkCancel();
}
// How did we do
MultiStatus status;
if (!getInvalidDirList().isEmpty()) {
status = new MultiStatus (
ManagedBuilderCorePlugin.getUniqueIdentifier(),
IStatus.WARNING,
new String(),
null);
// Add a new status for each of the bad folders
iter = getInvalidDirList().iterator();
while (iter.hasNext()) {
status.add(new Status (
IStatus.WARNING,
ManagedBuilderCorePlugin.getUniqueIdentifier(),
SPACES_IN_PATH,
((IContainer)iter.next()).getFullPath().toString(),
null));
}
} else {
status = new MultiStatus(
ManagedBuilderCorePlugin.getUniqueIdentifier(),
IStatus.OK,
new String(),
null);
}
return status;
}
/* (non-Javadoc)
@ -970,6 +1020,21 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
return answer;
}
/* (non-Javadoc)
* Answers a Vector containing a list of directories that are invalid for the
* build for some reason. At the moment, the only reason a directory would
* not be considered for the build is if it contains a space in the relative
* path from the project root.
*
* @return a a list of directories that are invalid for the build
*/
private Vector getInvalidDirList() {
if (invalidDirList == null) {
invalidDirList = new Vector();
}
return invalidDirList;
}
protected StringBuffer getMacroName(String extensionName) {
StringBuffer macroName = new StringBuffer();
@ -1125,23 +1190,50 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
}
contentStream.close();
// The rest of this operation is equally expensive, so
// if we are doing an incremental build, only update the
// files that do not have a comment
if (inBuffer == null) return;
String inBufferString = inBuffer.toString();
if (!force && inBufferString.startsWith(COMMENT_SYMBOL)) {
return;
}
// Reconstruct the buffer tokens into useful chunks of dependency information
Vector bufferTokens = new Vector(Arrays.asList(inBufferString.split("\\s"))); //$NON-NLS-1$
Vector deps = new Vector(bufferTokens.size());
Iterator tokenIter = bufferTokens.iterator();
while (tokenIter.hasNext()) {
String token = (String)tokenIter.next();
if (token.lastIndexOf("\\") == token.length() - 1 && token.length() > 1) { //$NON-NLS-1$
// This is escaped so keep adding to the token until we find the end
while (tokenIter.hasNext()) {
String nextToken = (String)tokenIter.next();
token += WHITESPACE + nextToken;
if (!nextToken.endsWith("\\")) { //$NON-NLS-1$
break;
}
}
}
deps.add(token);
}
deps.trimToSize();
// Now find the header file dependencies and make dummy targets for them
boolean save = false;
StringBuffer outBuffer = null;
if (inBuffer != null) {
// Here are the tokens in the file
String[] dependencies = inBuffer.toString().split("\\s"); //$NON-NLS-1$
if (dependencies.length == 0) return;
// If we are doing an incremental build, only update the files that do not have a comment
String firstLine = dependencies[0];
if (!force) {
if (firstLine.startsWith(COMMENT_SYMBOL)) {
String firstLine;
try {
firstLine = (String) deps.get(0);
} catch (ArrayIndexOutOfBoundsException e) {
// This makes no sense so bail
ManagedBuilderCorePlugin.log(e);
return;
}
}
// Put the generated comments in
// Put the generated comments in the output buffer
if (!firstLine.startsWith(COMMENT_SYMBOL)) {
outBuffer = addDefaultHeader();
} else {
@ -1150,15 +1242,6 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
// Some echo implementations misbehave and put the -n and newline in the output
if (firstLine.startsWith("-n")) { //$NON-NLS-1$
// Create a vector with all the strings
Vector tokens = new Vector(dependencies.length);
for (int index = 1; index < dependencies.length; ++index) {
String token = dependencies[index];
if (token.length() > 0) {
tokens.add(token);
}
}
tokens.trimToSize();
// Now let's parse:
// Win32 outputs -n '<path>/<file>.d <path>/'
@ -1166,7 +1249,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
// Get the dep file name
String secondLine;
try {
secondLine = (String) tokens.get(0);
secondLine = (String) deps.get(1);
} catch (ArrayIndexOutOfBoundsException e) {
secondLine = new String();
}
@ -1180,7 +1263,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
// The relative path to the build goal comes next
String thirdLine;
try {
thirdLine = (String) tokens.get(1);
thirdLine = (String) deps.get(2);
} catch (ArrayIndexOutOfBoundsException e) {
thirdLine = new String();
}
@ -1198,7 +1281,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
// followed by the actual dependencies
String fourthLine;
try {
fourthLine = (String) tokens.get(2);
fourthLine = (String) deps.get(3);
} catch (ArrayIndexOutOfBoundsException e) {
fourthLine = new String();
}
@ -1206,7 +1289,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
// Now do the rest
try {
Iterator iter = tokens.listIterator(3);
Iterator iter = deps.listIterator(4);
while (iter.hasNext()) {
String nextElement = (String)iter.next();
if (nextElement.endsWith("\\")) { //$NON-NLS-1$
@ -1226,16 +1309,17 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
save = true;
// Dummy targets to add to the makefile
for (int i = 0; i < dependencies.length; ++i) {
IPath dep = new Path(dependencies[i]);
Iterator dummyIter = deps.iterator();
while (dummyIter.hasNext()) {
String dummy = (String)dummyIter.next();
IPath dep = new Path(dummy);
String extension = dep.getFileExtension();
if (info.isHeaderFile(extension)) {
/*
* The formatting here is
* <dummy_target>:
*/
outBuffer.append(dependencies[i] + COLON + NEWLINE + NEWLINE);
}
outBuffer.append(dummy + COLON + NEWLINE + NEWLINE);
}
}
@ -1256,6 +1340,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
if (buildRoot == null) {
return;
}
IPath moduleOutputPath = buildRoot.append(moduleRelativePath);
// Now create the directory
@ -1446,7 +1531,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator#regenerateMakefiles()
*/
public void regenerateMakefiles() throws CoreException {
public MultiStatus regenerateMakefiles() throws CoreException {
// Visit the resources in the project
ResourceProxyVisitor visitor = new ResourceProxyVisitor(this, info);
project.accept(visitor, IResource.NONE);
@ -1456,7 +1541,12 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
// Populate the makefile if any source files have been found in the project
if (getSubdirList().isEmpty()) {
return;
throw new CoreException(new Status(
IStatus.WARNING,
ManagedBuilderCorePlugin.getUniqueIdentifier(),
NO_SOURCE_FOLDERS,
new String(),
null));
}
// Create the top-level directory for the build output
@ -1494,6 +1584,33 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator {
IFile objsFileHandle = createFile(objFilePath);
populateObjectsMakefile(objsFileHandle);
checkCancel();
// How did we do
MultiStatus status;
if (!getInvalidDirList().isEmpty()) {
status = new MultiStatus (
ManagedBuilderCorePlugin.getUniqueIdentifier(),
IStatus.WARNING,
new String(),
null);
// Add a new status for each of the bad folders
iter = getInvalidDirList().iterator();
while (iter.hasNext()) {
status.add(new Status (
IStatus.WARNING,
ManagedBuilderCorePlugin.getUniqueIdentifier(),
SPACES_IN_PATH,
((IContainer)iter.next()).getFullPath().toString(),
null));
}
} else {
status = new MultiStatus(
ManagedBuilderCorePlugin.getUniqueIdentifier(),
IStatus.OK,
new String(),
null);
}
return status;
}
}