1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-12 02:35:37 +02:00

Patch for Sean Evoy:

the logic for managing the makefiles in the face of a header file 
modification. There seems to be a problem (maybe with the dependency 
calculation) for dependants in other projects when a header file is moved, 
but other than that the builder seems to respond properly.
This commit is contained in:
Doug Schaefer 2003-10-01 14:25:35 +00:00
parent bd8a994627
commit 02de2c9788
14 changed files with 353 additions and 86 deletions

View file

@ -1,3 +1,31 @@
2003-09-30 Sean Evoy
Fix for bug 41826.
Finished the use case for changing header files and triggering a build. I had
to add a new attribute to the build model schema to allow a build information
client to determine that a file is considered a header file.
* schema/ManagedBuildTools.exsd
The ITool, and its implementors now have a method to test if an extension is
considered to belong to a header file. The Tool also pays attention to the new
attribute when it reads itself in from the plugin file.
* src/org/eclipse/cdt/managedbuilder/core/ITool.java
* src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java
* src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java
There is a method for clients of this information on the BuildInfo interface and
its implementor.
* src/org/eclipse/cdt/managedbuilder/core/IManagedBuildInfo.java
* src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java
The builder had to be tweaked in order to behave correctly on a build of an
empty project or non-managed projects.
* src/org/eclipse/cdt/managedbuilder/internal/core/GeneratedMakefileBuilder.java
The makefile generator had to be tweaked to properly add folders that are effected
by header file changes.
* src/org/eclipse/cdt/managedbuilder/internal/core/MakefileGenerator.java
2003-09-26 Sean Evoy 2003-09-26 Sean Evoy
A partial implementation for bug 41826. This patch contains the logic to properly A partial implementation for bug 41826. This patch contains the logic to properly
respond in the face of the following project changes: respond in the face of the following project changes:

View file

@ -104,13 +104,20 @@
<attribute name="dependencyCalculator" type="string"> <attribute name="dependencyCalculator" type="string">
<annotation> <annotation>
<documentation> <documentation>
This is an optional field that specifies the class that provides the dependency calculation for a given tool. This is an optional field that specifies the class that provides the dependency calculation for a given tool. This field is unused in CDT 1.2.
</documentation> </documentation>
<appInfo> <appInfo>
<meta.attribute kind="java" basedOn="org.eclipse.cdt.internal.core.sourcedependency.ISourceDependency"/> <meta.attribute kind="java" basedOn="org.eclipse.cdt.internal.core.sourcedependency.ISourceDependency"/>
</appInfo> </appInfo>
</annotation> </annotation>
</attribute> </attribute>
<attribute name="headerExtensions" type="string">
<annotation>
<documentation>
A comma-separated list of file extensions that are used for header files. Since many other files depend on the interfaces defined in header files, the build system needs to be able to determine that a header file has changed to properly rebuild its dependents.
</documentation>
</annotation>
</attribute>
</complexType> </complexType>
</element> </element>

View file

@ -168,8 +168,8 @@ public interface IManagedBuildInfo {
* Returns a <code>String</code> containing the command-line invocation * Returns a <code>String</code> containing the command-line invocation
* for the tool associated with the source extension. * for the tool associated with the source extension.
* *
* @param extension * @param extension the file extension of the file to be built
* @return * @return String
*/ */
public String getToolForSource(String extension); public String getToolForSource(String extension);
@ -183,7 +183,10 @@ public interface IManagedBuildInfo {
public String getToolForTarget(String extension); public String getToolForTarget(String extension);
/** /**
* @param extension * Answers a <code>String</code> array containing the contents of the
* user objects option, if one is defined for the target.
*
* @param extension the file ecxtension of the build target
* @return * @return
*/ */
public String[] getUserObjectsForTarget(String extension); public String[] getUserObjectsForTarget(String extension);
@ -191,10 +194,19 @@ public interface IManagedBuildInfo {
/** /**
* Answers true if the build model has been changed by the user. * Answers true if the build model has been changed by the user.
* *
* @return * @return boolean
*/ */
public boolean isDirty(); public boolean isDirty();
/**
* Answers <code>true</code> if the extension matches one of the special
* file extensions the tools for the target consider to be a header file.
*
* @param ext the file extension of the resource
* @return boolean
*/
public boolean isHeaderFile(String ext);
/** /**
* Set the dirty flag for the build model to the value of the argument. * Set the dirty flag for the build model to the value of the argument.
* *
@ -216,5 +228,4 @@ public interface IManagedBuildInfo {
* @param target * @param target
*/ */
public void setDefaultTarget(ITarget target); public void setDefaultTarget(ITarget target);
} }

View file

@ -24,27 +24,30 @@ public interface ITool extends IBuildObject {
public static final String OUTPUT_PREFIX = "outputPrefix"; //$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 OUTPUTS = "outputs"; //$NON-NLS-1$
public static final String SOURCES = "sources"; //$NON-NLS-1$ public static final String SOURCES = "sources"; //$NON-NLS-1$
public static final String INTERFACE_EXTS = "headerExtensions"; //$NON-NLS-1$
public static final String WHITE_SPACE = " "; //$NON-NLS-1$ public static final String WHITE_SPACE = " "; //$NON-NLS-1$
/** /**
* Return <code>true</code> if the receiver builds files with the * Return <code>true</code> if the receiver builds files with the
* specified extension, else <code>false</code>. * specified extension, else <code>false</code>.
* *
* @param extension * @param extension file extension of the source
* @return * @return boolean
*/ */
public boolean buildsFileType(String extension); public boolean buildsFileType(String extension);
/** /**
* Get a particular option. * Get a particular option.
* *
* @param id * @param id unique identifier of the option to search for
* @return * @return IOption
*/ */
public IOption getOption(String id); public IOption getOption(String id);
/** /**
* Returns the options that may be customized for this tool. * Answers the options that may be customized for this tool.
*
* @return IOption[]
*/ */
public IOption[] getOptions(); public IOption[] getOptions();
@ -53,7 +56,7 @@ public interface ITool extends IBuildObject {
* or <code>null</code> if the tool does not understand that extension. * or <code>null</code> if the tool does not understand that extension.
* *
* @param inputExtension The extension of the source file. * @param inputExtension The extension of the source file.
* @return * @return String
*/ */
public String getOutputExtension(String inputExtension); public String getOutputExtension(String inputExtension);
@ -62,27 +65,27 @@ public interface ITool extends IBuildObject {
* control the name of the output artifact. For example, the GCC compile and * control the name of the output artifact. For example, the GCC compile and
* linker use '-o', while the archiver does not. * linker use '-o', while the archiver does not.
* *
* @return * @return String
*/ */
public String getOutputFlag(); public String getOutputFlag();
/** /**
* Answers the prefix that the tool should prepend to the name of the build artifact. * Answers the prefix that the tool should prepend to the name of the build artifact.
* For example, a librarian usually prepends 'lib' to the target.a * For example, a librarian usually prepends 'lib' to the target.a
* @return * @return String
*/ */
public String getOutputPrefix(); public String getOutputPrefix();
/** /**
* Return the target that defines this tool, if applicable * Return the target that defines this tool, if applicable
* @return * @return ITarget
*/ */
public ITarget getTarget(); public ITarget getTarget();
/** /**
* Answers the command-line invocation defined for the receiver. * Answers the command-line invocation defined for the receiver.
* *
* @return * @return String
*/ */
public String getToolCommand(); public String getToolCommand();
@ -90,7 +93,7 @@ public interface ITool extends IBuildObject {
* Answers the additional command line arguments the user has specified for * Answers the additional command line arguments the user has specified for
* the tool. * the tool.
* *
* @return * @return String
*/ */
public String getToolFlags() throws BuildException ; public String getToolFlags() throws BuildException ;
@ -99,18 +102,26 @@ public interface ITool extends IBuildObject {
* These categories are organized into a tree. This is the root * These categories are organized into a tree. This is the root
* of that tree. * of that tree.
* *
* @return * @return IOptionCategory
*/ */
public IOptionCategory getTopOptionCategory(); public IOptionCategory getTopOptionCategory();
/**
* Answers <code>true</code> if the tool considers the file extension to be
* one associated with a header file.
*
* @param ext file extension of the source
* @return boolean
*/
public boolean isHeaderFile(String ext);
/** /**
* Answers <code>true</code> if the receiver builds a file with the extension specified * Answers <code>true</code> if the receiver builds a file with the extension specified
* in the argument, else <code>false</code>. * in the argument, else <code>false</code>.
* *
* @param outputExtension * @param outputExtension extension of the file being produced by a tool
* @return * @return boolean
*/ */
public boolean producesFileType(String outputExtension); public boolean producesFileType(String outputExtension);
} }

View file

@ -36,6 +36,7 @@ import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor; import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
@ -127,8 +128,11 @@ public class GeneratedMakefileBuilder extends ACBuilder {
for (int i = 0; i < deps.length; i++) { for (int i = 0; i < deps.length; i++) {
IProject project = deps[i]; IProject project = deps[i];
IManagedBuildInfo depInfo = ManagedBuildManager.getBuildInfo(project); IManagedBuildInfo depInfo = ManagedBuildManager.getBuildInfo(project);
// May not be a managed project
if (depInfo != null) {
depInfo.setDirty(false); depInfo.setDirty(false);
} }
}
// Ask build mechanism to compute deltas for project dependencies next time // Ask build mechanism to compute deltas for project dependencies next time
return deps; return deps;
@ -183,11 +187,14 @@ public class GeneratedMakefileBuilder extends ACBuilder {
// Throw the exception back to the builder // Throw the exception back to the builder
throw e; throw e;
} }
IPath topBuildDir = generator.getTopBuildDir();
// Now call make // Now call make
IPath topBuildDir = generator.getTopBuildDir();
if (topBuildDir != null) {
invokeMake(true, topBuildDir.removeFirstSegments(1), info, monitor); invokeMake(true, topBuildDir.removeFirstSegments(1), info, monitor);
monitor.worked(1); } else {
monitor.done();
}
} }
/* (non-javadoc) /* (non-javadoc)
@ -280,8 +287,6 @@ public class GeneratedMakefileBuilder extends ACBuilder {
// Run the build // Run the build
IPath buildDir = new Path(info.getConfigurationName()); IPath buildDir = new Path(info.getConfigurationName());
invokeMake(false, buildDir, info, monitor); invokeMake(false, buildDir, info, monitor);
monitor.worked(1);
} }
protected void invokeMake(boolean fullBuild, IPath buildDir, IManagedBuildInfo info, IProgressMonitor monitor) { protected void invokeMake(boolean fullBuild, IPath buildDir, IManagedBuildInfo info, IProgressMonitor monitor) {
@ -292,6 +297,21 @@ public class GeneratedMakefileBuilder extends ACBuilder {
} }
try { try {
// Figure out the working directory for the build and make sure there is a makefile there
IPath workingDirectory = getWorkingDirectory().append(buildDir);
IWorkspace workspace = currentProject.getWorkspace();
if (workspace == null) {
return;
}
IWorkspaceRoot root = workspace.getRoot();
if (root == null) {
return;
}
IPath makefile = workingDirectory.addTrailingSeparator().append(MakefileGenerator.MAKEFILE_NAME);
if (root.getFileForLocation(makefile) == null) {
return;
}
// Flag to the user that make is about to be called // Flag to the user that make is about to be called
IPath makeCommand = new Path(info.getMakeCommand()); IPath makeCommand = new Path(info.getMakeCommand());
if (makeCommand != null) { if (makeCommand != null) {
@ -313,8 +333,6 @@ public class GeneratedMakefileBuilder extends ACBuilder {
removeAllMarkers(project); removeAllMarkers(project);
} }
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
ArrayList makeArgs = new ArrayList(); ArrayList makeArgs = new ArrayList();
String args = info.getMakeArguments(); String args = info.getMakeArguments();

View file

@ -44,6 +44,7 @@ import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Path;
@ -61,10 +62,10 @@ public class MakefileGenerator {
// String constants for makefile contents // String constants for makefile contents
protected static final String COLON = ":"; protected static final String COLON = ":";
protected static final String DEPFILE_NAME = "module.dep"; //$NON-NLS-1$ protected static final String DEPFILE_NAME = "subdir.dep"; //$NON-NLS-1$
protected static final String DOT = "."; protected static final String DOT = ".";
protected static final String MAKEFILE_NAME = "makefile"; //$NON-NLS-1$ protected static final String MAKEFILE_NAME = "makefile"; //$NON-NLS-1$
protected static final String MODFILE_NAME = "module.mk"; //$NON-NLS-1$ protected static final String MODFILE_NAME = "subdir.mk"; //$NON-NLS-1$
protected static final String LINEBREAK = "\\"; protected static final String LINEBREAK = "\\";
protected static final String NEWLINE = System.getProperty("line.separator"); protected static final String NEWLINE = System.getProperty("line.separator");
protected static final String SEMI_COLON = ";"; protected static final String SEMI_COLON = ";";
@ -81,10 +82,9 @@ public class MakefileGenerator {
protected IProject project; protected IProject project;
protected List ruleList; protected List ruleList;
protected IPath topBuildDir; protected IPath topBuildDir;
private String target; private String target;
private String extension; private String extension;
/** /**
* This class is used to recursively walk the project and determine which * This class is used to recursively walk the project and determine which
* modules contribute buildable source files. * modules contribute buildable source files.
@ -142,6 +142,61 @@ public class MakefileGenerator {
this.info = info; this.info = info;
} }
/* (non-javadoc)
* Answers a list of resource names in the workspace that depend on the resource
* specified in the argument.
*
* @param resource the root of the dependency tree
* @return IResource[]
*/
private IResource[] findDependencies(IResource resource) {
PathCollector pathCollector = new PathCollector();
ICSearchScope scope = SearchEngine.createWorkspaceScope();
CSearchPattern pattern = CSearchPattern.createPattern(resource.getLocation().toOSString(), ICSearchConstants.INCLUDE, ICSearchConstants.REFERENCES, ICSearchConstants.EXACT_MATCH, true);
IndexManager indexManager = CCorePlugin.getDefault().getCoreModel().getIndexManager();
indexManager.performConcurrentJob(
new PatternSearchJob(
(CSearchPattern) pattern,
scope,
pathCollector,
indexManager),
ICSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
null);
// We will get back an array of resource names relative to the workspace
String[] deps = pathCollector.getPaths();
// Convert them to something useful
List depList = new ArrayList();
IResource res = null;
IWorkspaceRoot root = null;
if (generator.project != null) {
root = generator.project.getWorkspace().getRoot();
}
for (int index = 0; index < deps.length; ++index) {
res = root.findMember(deps[index]);
if (res != null) {
depList.add(res);
}
}
return (IResource[]) depList.toArray(new IResource[depList.size()]);
}
private void handleHeaderDependency(IResource resource, boolean moved) {
// If this is a move and the resource is external to the project, touch that resource
if (resource.getProject().equals(generator.project)) {
generator.appendModifiedSubdirectory(resource);
} else {
if (moved) {
try {
resource.touch(new NullProgressMonitor());
} catch (CoreException e) {
}
}
}
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta) * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta)
*/ */
@ -153,40 +208,53 @@ public class MakefileGenerator {
// What kind of resource change has occurred // What kind of resource change has occurred
if (resource.getType() == IResource.FILE) { if (resource.getType() == IResource.FILE) {
String ext = resource.getFileExtension(); String ext = resource.getFileExtension();
boolean moved = false;
switch (delta.getKind()) { switch (delta.getKind()) {
case IResourceDelta.ADDED: case IResourceDelta.ADDED:
case IResourceDelta.REMOVED: moved = delta.getFlags() == IResourceDelta.MOVED_TO;
// Add the container of the resource and any resources that depend on it
if (info.buildsFileType(ext)) {
if (!generator.isGeneratedResource(resource)) { if (!generator.isGeneratedResource(resource)) {
// Here's the container // This is a source file so just add its container
if (info.buildsFileType(ext)) {
generator.appendModifiedSubdirectory(resource); generator.appendModifiedSubdirectory(resource);
// and all the dependents } else if (info.isHeaderFile(ext)) {
PathCollector pathCollector = new PathCollector(); // Add the container of the resource and any resources that depend on it
ICSearchScope scope = SearchEngine.createWorkspaceScope();
CSearchPattern pattern = CSearchPattern.createPattern(resource.getLocation().toOSString(),ICSearchConstants.INCLUDE, ICSearchConstants.REFERENCES,ICSearchConstants.EXACT_MATCH,true);
IndexManager indexManager = CCorePlugin.getDefault().getCoreModel().getIndexManager();
indexManager.performConcurrentJob(
new PatternSearchJob(
(CSearchPattern) pattern,
scope,
pathCollector,
indexManager
),
ICSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
null );
String[] deps = pathCollector.getPaths();
if (deps.length > 0 ) {
for (int i=0; i<deps.length; i++){
generator.appendModifiedSubdirectory(resource); generator.appendModifiedSubdirectory(resource);
IResource[] deps = findDependencies(resource);
for (int i = 0; i < deps.length; ++i){
handleHeaderDependency(deps[i], moved);
} }
} }
} }
break;
case IResourceDelta.REMOVED:
moved = delta.getFlags() == IResourceDelta.MOVED_FROM;
if (!generator.isGeneratedResource(resource)) {
// This is a source file so just add its container
if (info.buildsFileType(ext)) {
generator.appendModifiedSubdirectory(resource);
} else if (info.isHeaderFile(ext)) {
// Add the container of the resource and any resources that depend on it
generator.appendModifiedSubdirectory(resource);
IResource[] deps = findDependencies(resource);
for (int i = 0; i < deps.length; ++i){
handleHeaderDependency(deps[i], moved);
}
}
} }
break; break;
case IResourceDelta.CHANGED: case IResourceDelta.CHANGED:
if (!generator.isGeneratedResource(resource)) {
if (info.buildsFileType(ext)) { if (info.buildsFileType(ext)) {
keepLooking = true; keepLooking = true;
} else if (info.isHeaderFile(ext)) {
// Add the container of the resource and any resources that depend on it
generator.appendModifiedSubdirectory(resource);
IResource[] deps= findDependencies(resource);
for (int i = 0; i < deps.length; ++i){
handleHeaderDependency(deps[i], moved);
}
// That does it for this directory, so don't bother to keep looking
}
} }
break; break;
default: default:
@ -360,7 +428,7 @@ public class MakefileGenerator {
// Now add the makefile instruction to include all the subdirectory makefile fragments // Now add the makefile instruction to include all the subdirectory makefile fragments
buffer.append(NEWLINE); buffer.append(NEWLINE);
buffer.append(ManagedBuilderCorePlugin.getResourceString(MOD_INCL) + NEWLINE); buffer.append(ManagedBuilderCorePlugin.getResourceString(MOD_INCL) + NEWLINE);
buffer.append("-include ${patsubst %, %/module.mk, $(SUBDIRS)}" + NEWLINE); buffer.append("-include ${patsubst %, %/subdir.mk, $(SUBDIRS)}" + NEWLINE);
buffer.append(NEWLINE + NEWLINE); buffer.append(NEWLINE + NEWLINE);
return buffer; return buffer;
@ -521,7 +589,7 @@ public class MakefileGenerator {
buffer.append(".PHONY: all clean deps" + NEWLINE + NEWLINE); buffer.append(".PHONY: all clean deps" + NEWLINE + NEWLINE);
buffer.append(ManagedBuilderCorePlugin.getResourceString(DEP_INCL) + NEWLINE); buffer.append(ManagedBuilderCorePlugin.getResourceString(DEP_INCL) + NEWLINE);
buffer.append("-include ${patsubst %, %/module.dep, $(SUBDIRS)}" + NEWLINE); buffer.append("-include ${patsubst %, %/subdir.dep, $(SUBDIRS)}" + NEWLINE);
return buffer; return buffer;
} }
@ -581,7 +649,7 @@ public class MakefileGenerator {
* Adds the container of the argument to the list of folders in the project that * 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 * 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 * 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. * the resource is not generated as part of the build.
* *
* @param resource * @param resource
*/ */
@ -590,6 +658,7 @@ public class MakefileGenerator {
if (!getSubdirList().contains(container)) { if (!getSubdirList().contains(container)) {
getSubdirList().add(container); getSubdirList().add(container);
} }
} }
/** /**
@ -874,6 +943,11 @@ public class MakefileGenerator {
// See if the user has cancelled the build // See if the user has cancelled the build
checkCancel(); checkCancel();
// Populate the makefile if any source files have been found in the project
if (getSubdirList().isEmpty()) {
return;
}
// Create the top-level directory for the build output // Create the top-level directory for the build output
topBuildDir = createDirectory(info.getConfigurationName()); topBuildDir = createDirectory(info.getConfigurationName());
@ -881,7 +955,6 @@ public class MakefileGenerator {
IPath makefilePath = topBuildDir.addTrailingSeparator().append(MAKEFILE_NAME); IPath makefilePath = topBuildDir.addTrailingSeparator().append(MAKEFILE_NAME);
IFile makefileHandle = createFile(makefilePath); IFile makefileHandle = createFile(makefilePath);
// Populate the makefile
populateTopMakefile(makefileHandle, true); populateTopMakefile(makefileHandle, true);
checkCancel(); checkCancel();

View file

@ -539,6 +539,22 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
return isDirty; return isDirty;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#isHeaderFile(java.lang.String)
*/
public boolean isHeaderFile(String ext) {
// Check to see if there is a rule to build a file with this extension
IConfiguration config = getDefaultConfiguration(getDefaultTarget());
ITool[] tools = config.getTools();
for (int index = 0; index < tools.length; index++) {
ITool tool = tools[index];
if (tool.isHeaderFile(ext)) {
return true;
}
}
return false;
}
/** /**
* Write the contents of the build model to the persistent store specified in the * Write the contents of the build model to the persistent store specified in the
* argument. * argument.

View file

@ -36,16 +36,17 @@ public class Tool extends BuildObject implements ITool, IOptionCategory {
private static final IOptionCategory[] EMPTY_CATEGORIES = new IOptionCategory[0]; private static final IOptionCategory[] EMPTY_CATEGORIES = new IOptionCategory[0];
private static final IOption[] EMPTY_OPTIONS = new IOption[0]; private static final IOption[] EMPTY_OPTIONS = new IOption[0];
private ITarget target;
private List options;
private Map optionMap;
private List childOptionCategories;
private Map categoryMap; private Map categoryMap;
private List childOptionCategories;
private String command; private String command;
private List inputExtensions; private List inputExtensions;
private List interfaceExtensions;
private Map optionMap;
private List options;
private String outputExtension; private String outputExtension;
private String outputFlag; private String outputFlag;
private String outputPrefix; private String outputPrefix;
private ITarget target;
public Tool(Target target) { public Tool(Target target) {
this.target = target; this.target = target;
@ -79,6 +80,16 @@ public class Tool extends BuildObject implements ITool, IOptionCategory {
getInputExtensions().add(tokenizer.nextElement()); getInputExtensions().add(tokenizer.nextElement());
} }
// Get the interface (header file) extensions
String headers = element.getAttribute(INTERFACE_EXTS);
if (headers == null) {
headers = new String();
}
tokenizer = new StringTokenizer(headers, DEFAULT_SEPARATOR);
while (tokenizer.hasMoreElements()) {
getInterfaceExtensions().add(tokenizer.nextElement());
}
// Get the output extension // Get the output extension
outputExtension = element.getAttribute(ITool.OUTPUTS) == null ? outputExtension = element.getAttribute(ITool.OUTPUTS) == null ?
new String() : new String() :
@ -170,7 +181,10 @@ public class Tool extends BuildObject implements ITool, IOptionCategory {
} }
/* (non-Javadoc) /* (non-Javadoc)
* @return * Safe accessor method to retrieve the list of valid source extensions
* the receiver know how to build.
*
* @return List
*/ */
private List getInputExtensions() { private List getInputExtensions() {
if (inputExtensions == null) { if (inputExtensions == null) {
@ -179,6 +193,13 @@ public class Tool extends BuildObject implements ITool, IOptionCategory {
return inputExtensions; return inputExtensions;
} }
private List getInterfaceExtensions() {
if (interfaceExtensions == null) {
interfaceExtensions = new ArrayList();
}
return interfaceExtensions;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.build.managed.IOptionCategory#createChildCategory() * @see org.eclipse.cdt.core.build.managed.IOptionCategory#createChildCategory()
*/ */
@ -350,6 +371,16 @@ public class Tool extends BuildObject implements ITool, IOptionCategory {
return null; return null;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.core.ITool#isHeaderFile(java.lang.String)
*/
public boolean isHeaderFile(String ext) {
if (ext == null) {
return false;
}
return getInterfaceExtensions().contains(ext);
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.build.managed.ITool#producesFileType(java.lang.String) * @see org.eclipse.cdt.core.build.managed.ITool#producesFileType(java.lang.String)
*/ */

View file

@ -256,6 +256,13 @@ public class ToolReference implements ITool {
return parent.getTopOptionCategory(); return parent.getTopOptionCategory();
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.core.ITool#isHeaderFile(java.lang.String)
*/
public boolean isHeaderFile(String ext) {
return parent.isHeaderFile(ext);
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.build.managed.ITool#producesFileType(java.lang.String) * @see org.eclipse.cdt.core.build.managed.ITool#producesFileType(java.lang.String)
*/ */

View file

@ -1,3 +1,10 @@
2003-09-30 Sean Evoy
Fix for bug 41826.
Updated the tool specifications for Win32, Linux, and Solaris so that header
file extension info is available.
* plugin.xml
2003-09-25 Sean Evoy 2003-09-25 Sean Evoy
For bug (really an enhancement request)43756, I added the word default to a For bug (really an enhancement request)43756, I added the word default to a
widget label to try and make it clear that a new configuration will be based widget label to try and make it clear that a new configuration will be based

View file

@ -79,6 +79,7 @@
<tool <tool
sources="c,cc,cpp,cxx,C" sources="c,cc,cpp,cxx,C"
name="%ToolName.compiler" name="%ToolName.compiler"
headerExtensions="h,H,hpp"
outputFlag="-o" outputFlag="-o"
outputs="o" outputs="o"
command="g++" command="g++"
@ -219,13 +220,29 @@
id="cygwin.preprocessor.undef.symbol"> id="cygwin.preprocessor.undef.symbol">
</option> </option>
<optionCategory <optionCategory
owner="org.eclipse.cdt.build.tool.cygwin.compiler" name="%OptionCategory.Dirs"
name="%OptionCategory.General" id="cygwin.gnu.compiler.category.dirs"
id="cygwin.compiler.category.general"> owner="org.eclipse.cdt.build.tool.cygwin.compiler">
</optionCategory>
<option
name="Include Paths"
category="cygwin.gnu.compiler.category.dirs"
command="-I"
valueType="includePath"
id="cygwin.compiler.general.include.paths">
<listOptionValue
value="C:\cygwin\usr\include\w32api"
builtIn="true">
</listOptionValue>
</option>
<optionCategory
name="%OptionCategory.Optimize"
id="cygwin.gnu.compiler.category.optimization"
owner="org.eclipse.cdt.build.tool.cygwin.compiler">
</optionCategory> </optionCategory>
<option <option
name="Optimization Level" name="Optimization Level"
category="cygwin.compiler.category.general" category="cygwin.gnu.compiler.category.optimization"
valueType="enumerated" valueType="enumerated"
id="cygwin.compiler.general.optimization.level"> id="cygwin.compiler.general.optimization.level">
<enumeratedOptionValue <enumeratedOptionValue
@ -251,9 +268,20 @@
id="cygwin.optimization.level.most"> id="cygwin.optimization.level.most">
</enumeratedOptionValue> </enumeratedOptionValue>
</option> </option>
<option
category="cygwin.gnu.compiler.category.optimization"
name="Other optimization flags"
id="cygwin.compiler.optimization.flags"
valueType="string">
</option>
<optionCategory
name="%OptionCategory.Debug"
id="cygwin.gnu.compiler.category.debug"
owner="org.eclipse.cdt.build.tool.cygwin.compiler">
</optionCategory>
<option <option
name="Debug Level" name="Debug Level"
category="cygwin.compiler.category.general" category="cygwin.gnu.compiler.category.debug"
valueType="enumerated" valueType="enumerated"
id="cygwin.compiler.debugging.level"> id="cygwin.compiler.debugging.level">
<enumeratedOptionValue <enumeratedOptionValue
@ -280,15 +308,26 @@
</enumeratedOptionValue> </enumeratedOptionValue>
</option> </option>
<option <option
name="Include Paths" category="cygwin.gnu.compiler.category.debug"
category="cygwin.compiler.category.general" name="Other debugging flags"
command="-I" id="cygwin.gnu.compiler.debugging.other"
valueType="includePath" valueType="string">
id="cygwin.compiler.general.include.paths"> </option>
<listOptionValue <option
value="C:\cygwin\usr\include\w32api" category="cygwin.gnu.compiler.category.debug"
builtIn="true"> id="cygwin.gnu.compiler.debugging.prof"
</listOptionValue> command="-p"
name="Generate prof information (-p)"
defaultValue="false"
valueType="boolean">
</option>
<option
category="cygwin.gnu.compiler.category.debug"
id="cygwin.gnu.compiler.debugging.gprof"
command="-pg"
name="Generate gprof information (-pg)"
defaultValue="false"
valueType="boolean">
</option> </option>
<optionCategory <optionCategory
owner="org.eclipse.cdt.build.tool.cygwin.compiler" owner="org.eclipse.cdt.build.tool.cygwin.compiler"
@ -783,6 +822,7 @@
<tool <tool
sources="c,C,cc,cxx,cpp" sources="c,C,cc,cxx,cpp"
name="%ToolName.compiler" name="%ToolName.compiler"
headerExtensions="h,H,hpp"
outputFlag="-o" outputFlag="-o"
outputs="o" outputs="o"
command="g++" command="g++"
@ -1403,6 +1443,7 @@
<tool <tool
sources="c,C,cc,cxx,cpp" sources="c,C,cc,cxx,cpp"
name="%ToolName.compiler" name="%ToolName.compiler"
headerExtensions="h,H,hpp"
outputFlag="-o" outputFlag="-o"
outputs="o" outputs="o"
command="g++" command="g++"

View file

@ -1,3 +1,11 @@
2003-09-30 Sean Evoy
Fix for bug 41826.
Updated the plugin file so that tool specifications have the new attribute
for header files. The test for the managed builder now insure that those
values are properly read.
* plugin.xml
* build/org/eclipse/cdt/core/build/managed/tests/ManagedBuildTests.java
2003-09-30 John Camelon 2003-09-30 John Camelon
Updated CompleteParseASTTest::testBug42872() Updated CompleteParseASTTest::testBug42872()
Moved FailedCompleteParseASTTest::testBug43503() to CompleteParseASTTest::testBug43503A(). Moved FailedCompleteParseASTTest::testBug43503() to CompleteParseASTTest::testBug43503A().

View file

@ -677,7 +677,8 @@ public class ManagedBuildTests extends TestCase {
// Root Config // Root Config
IConfiguration rootConfig = configs[0]; IConfiguration rootConfig = configs[0];
assertEquals("Root Config", rootConfig.getName()); assertEquals("Root Config", rootConfig.getName());
// Tools
// Tool elements
tools = rootConfig.getTools(); tools = rootConfig.getTools();
assertEquals(1, tools.length); assertEquals(1, tools.length);
assertEquals("Root Tool", tools[0].getName()); assertEquals("Root Tool", tools[0].getName());
@ -687,6 +688,9 @@ public class ManagedBuildTests extends TestCase {
assertTrue(tools[0].producesFileType("toor")); assertTrue(tools[0].producesFileType("toor"));
assertEquals("doIt", tools[0].getToolCommand()); assertEquals("doIt", tools[0].getToolCommand());
assertEquals("", tools[0].getOutputPrefix()); assertEquals("", tools[0].getOutputPrefix());
// The root tool defines one valid header file extension
assertTrue(rootTool.isHeaderFile("baz"));
assertTrue(tools[0].isHeaderFile("baz"));
// Partially Overriden Configuration // Partially Overriden Configuration
assertEquals("Root Override Config", configs[1].getName()); assertEquals("Root Override Config", configs[1].getName());
@ -722,6 +726,7 @@ public class ManagedBuildTests extends TestCase {
assertTrue(tools[0].buildsFileType("foo")); assertTrue(tools[0].buildsFileType("foo"));
assertTrue(tools[0].buildsFileType("bar")); assertTrue(tools[0].buildsFileType("bar"));
assertTrue(tools[0].producesFileType("toor")); assertTrue(tools[0].producesFileType("toor"));
assertTrue(tools[0].isHeaderFile("baz"));
assertEquals("doIt", tools[0].getToolCommand()); assertEquals("doIt", tools[0].getToolCommand());
// Completely Overridden configuration // Completely Overridden configuration
@ -813,6 +818,8 @@ public class ManagedBuildTests extends TestCase {
assertTrue(subTool.producesFileType("bus")); assertTrue(subTool.producesFileType("bus"));
assertEquals("", subTool.getToolCommand()); assertEquals("", subTool.getToolCommand());
assertEquals("lib", subTool.getOutputPrefix()); assertEquals("lib", subTool.getOutputPrefix());
assertTrue(subTool.isHeaderFile("arf"));
assertTrue(subTool.isHeaderFile("barf"));
// Do a sanity check on the options // Do a sanity check on the options
assertEquals("Include Paths", subOpts[0].getName()); assertEquals("Include Paths", subOpts[0].getName());

View file

@ -42,6 +42,7 @@
<tool <tool
sources="foo,bar" sources="foo,bar"
name="Root Tool" name="Root Tool"
headerExtensions="baz"
outputFlag="-r" outputFlag="-r"
outputs="toor" outputs="toor"
command="doIt" command="doIt"
@ -160,6 +161,7 @@
<tool <tool
sources="yarf" sources="yarf"
name="Sub Tool" name="Sub Tool"
headerExtensions="arf,barf"
outputs="bus" outputs="bus"
outputPrefix="lib" outputPrefix="lib"
id="tool.sub"> id="tool.sub">