From c7f73a40517ebbe266d35bf3a3c441c1f33003b8 Mon Sep 17 00:00:00 2001 From: Leo Treggiari Date: Thu, 23 Feb 2006 18:04:02 +0000 Subject: Add new dependency calculator interfaces Apply patch from bugzilla 127077 (Echo loses quotes) Apply patch from bugzilla 128333 (Limitations for project converter support) Fix problem in ResourceChangeHandler.sendClose when MBS project cannot be loaded --- .../cdt/managedbuilder/core/IInputType.java | 782 +- .../cdt/managedbuilder/core/IManagedBuildInfo.java | 1002 +-- .../org/eclipse/cdt/managedbuilder/core/ITool.java | 1451 ++-- .../internal/core/Configuration.java | 2891 +++---- .../internal/core/GeneratedMakefileBuilder.java | 2004 ++--- .../managedbuilder/internal/core/InputType.java | 2442 +++--- .../internal/core/ManagedBuildInfo.java | 2946 +++---- .../internal/core/ManagedProject.java | 1059 +-- .../cdt/managedbuilder/internal/core/Option.java | 3720 ++++----- .../internal/core/PluginResources.properties | 219 +- .../internal/core/ResourceChangeHandler.java | 913 +-- .../cdt/managedbuilder/internal/core/Tool.java | 5627 ++++++------- .../managedbuilder/internal/core/ToolChain.java | 3446 ++++---- .../internal/core/ToolReference.java | 2505 +++--- .../makegen/IManagedDependencyCalculator.java | 79 + .../makegen/IManagedDependencyCommands.java | 168 + .../makegen/IManagedDependencyGenerator.java | 62 +- .../makegen/IManagedDependencyGenerator2.java | 203 +- .../makegen/IManagedDependencyGeneratorType.java | 87 + .../makegen/IManagedDependencyInfo.java | 35 + .../makegen/IManagedDependencyPreBuild.java | 136 + .../gnu/DefaultGCCDependencyCalculator.java | 600 +- .../gnu/DefaultGCCDependencyCalculator2.java | 71 + .../DefaultGCCDependencyCalculator2Commands.java | 203 + .../DefaultGCCDependencyCalculatorPreBuild.java | 70 + ...ultGCCDependencyCalculatorPreBuildCommands.java | 308 + .../makegen/gnu/GnuDependencyGroupInfo.java | 37 + .../makegen/gnu/GnuMakefileGenerator.java | 8226 ++++++++++---------- .../makegen/gnu/IManagedBuildGnuToolInfo.java | 234 +- .../makegen/gnu/ManagedBuildGnuToolInfo.java | 1976 ++--- .../DefaultIndexerDependencyCalculator.java | 174 +- 31 files changed, 22682 insertions(+), 20994 deletions(-) create mode 100755 build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyCalculator.java create mode 100755 build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyCommands.java create mode 100755 build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGeneratorType.java create mode 100755 build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyInfo.java create mode 100755 build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyPreBuild.java create mode 100755 build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator2.java create mode 100755 build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator2Commands.java create mode 100755 build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculatorPreBuild.java create mode 100755 build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculatorPreBuildCommands.java create mode 100755 build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuDependencyGroupInfo.java (limited to 'build/org.eclipse.cdt.managedbuilder.core/src/org') diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IInputType.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IInputType.java index 9db563dff8a..91dc116939f 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IInputType.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IInputType.java @@ -1,391 +1,391 @@ -/******************************************************************************* - * Copyright (c) 2005 Intel Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Intel Corporation - Initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.core; - -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.content.IContentType; - -/** - * This interface represents an inputType instance in the managed build system. - * It describes one category of input files to a Tool. A tool can have - * multiple inputType children. - * - * @since 3.0 - */ -public interface IInputType extends IBuildObject { - public static final String INPUT_TYPE_ELEMENT_NAME = "inputType"; //$NON-NLS-1$ - public static final String SOURCE_CONTENT_TYPE = "sourceContentType"; //$NON-NLS-1$ - public static final String SOURCES = "sources"; //$NON-NLS-1$ - public static final String DEPENDENCY_CONTENT_TYPE = "dependencyContentType"; //$NON-NLS-1$ - public static final String DEPENDENCY_EXTENSIONS = "dependencyExtensions"; //$NON-NLS-1$ - public static final String OPTION = "option"; //$NON-NLS-1$ - public static final String ASSIGN_TO_OPTION = "assignToOption"; //$NON-NLS-1$ - public static final String MULTIPLE_OF_TYPE = "multipleOfType"; //$NON-NLS-1$ - public static final String PRIMARY_INPUT = "primaryInput"; //$NON-NLS-1$ - public static final String BUILD_VARIABLE = "buildVariable"; //$NON-NLS-1$ - - /** - * Creates an inputOrder child for this InputType. - * - * @param path The path associated with the InputOrder element - * @return IInputOrder of the new element - */ - public IInputOrder createInputOrder(String path); - - /** - * Removes the InputOrder element with the path specified in the argument. - * - * @param path The path associated with the InputOrder element - */ - public void removeInputOrder(String path); - - /** - * Removes the InputOrder element specified in the argument. - * - * @param path The InputOrder element - */ - public void removeInputOrder(IInputOrder element); - - /** - * Returns all of the InputOrder children of this InputType - * - * @return IInputOrder[] - */ - public IInputOrder[] getInputOrders(); - - /** - * Returns the InputOrder element with the path specified in the argument. - * - * @param path The path associated with the InputOrder element - * @return IInputOrder - */ - public IInputOrder getInputOrder(String path); - - /** - * Creates an additionalInput child for this InputType. - * - * @param path The path associated with the AdditionalInput element - * @return IAdditionalInput of the new element - */ - public IAdditionalInput createAdditionalInput(String path); - - /** - * Removes the AdditionalInput element with the path specified in the argument. - * - * @param path The path associated with the AdditionalInput element - */ - public void removeAdditionalInput(String path); - - /** - * Removes the AdditionalInput element specified in the argument. - * - * @param element The AdditionalInput element - */ - public void removeAdditionalInput(IAdditionalInput element); - - /** - * Returns all of the AdditionalInput children of this InputType - * - * @return IAdditionalInput[] - */ - public IAdditionalInput[] getAdditionalInputs(); - - /** - * Returns the AdditionalInput element with the path specified in the argument. - * - * @param path The path associated with the AdditionalInput element - * @return IAdditionalInput - */ - public IAdditionalInput getAdditionalInput(String path); - - /** - * Returns all of the additional input resources of this InputType. - * Note: This does not include additional dependencies. - * - * @return IPath[] - */ - public IPath[] getAdditionalResources(); - - /** - * Returns all of the additional dependency resources of this InputType. - * Note: This does not include additional inputs. - * - * @return IPath[] - */ - public IPath[] getAdditionalDependencies(); - - /** - * Returns the tool parent of this InputType. - * - * @return ITool - */ - public ITool getParent(); - - /** - * Returns the IInputType that is the superclass of this - * InputType, or null if the attribute was not specified. - * - * @return IInputType - */ - public IInputType getSuperClass(); - - /** - * Returns the Eclipse IContentType that describes this - * input type. If both the sources attribute and the sourceContentType - * attribute are specified, the sourceContentType will be used if it - * is registered in Eclipse. - * - * @return IContentType - */ - public IContentType getSourceContentType(); - - /** - * Sets the Eclipse IContentType that describes this - * input type. - * - * @param contentType The Eclipse content type - */ - public void setSourceContentType(IContentType contentType); - - /** - * Returns the list of valid source extensions from the - * sourceExtensions attribute. Note that this value is not used - * if source content type is specified and registered with Eclipse. - * Also, the user will not be able to modify the set of file - * extensions as they can when sourceContentType is specified. - * - * @return String[] - */ - public String[] getSourceExtensionsAttribute(); - - /** - * Sets the list of valid source extensions for this input type. - * NOTE: The value of this attribute will NOT be used if a - * source content type is specified and is registered with - * Eclipse. - * - * @param extensions The comma-separated list of valid file extensions - * - not including the separator period. - */ - public void setSourceExtensionsAttribute(String extensions); - - /** - * Returns the list of valid source extensions for this input type. - * Note that the list will come from the sourceContentType if it - * is specified and registered with Eclipse. Otherwise the - * sourceExtensions attribute will be used. - * - * @param tool the tool that contains the input-type - * @return String[] - */ - public String[] getSourceExtensions(ITool tool); - - /** - * Answers true if the input type considers the file extension to be - * one associated with a source file. - * - * @param tool the tool that contains the input-type - * @param ext file extension of the source - * @return boolean - */ - public boolean isSourceExtension(ITool tool, String ext); - - /** - * Returns the Eclipse IContentType that describes the - * dependency files of this input type. If both the dependencyExtensions - * attribute and the dependencyContentType attribute are specified, - * the dependencyContentType will be used if it is defined in Eclipse. - * - * @return IContentType - */ - public IContentType getDependencyContentType(); - - /** - * Sets the Eclipse IContentType that describes the - * dependency files of this input type. - * - * @return type - */ - public void setDependencyContentType(IContentType type); - - /** - * Returns the list of valid dependency extensions from the - * dependencyExtensions attribute. Note that this value is not used - * if dependency content type is specified and registered with Eclipse. - * Also, the user will not be able to modify the set of file - * extensions as they can when dependencyContentType is specified. - * - * @return String[] - */ - public String[] getDependencyExtensionsAttribute(); - - /** - * Sets the list of valid dependency extensions for this input type. - * NOTE: The value of this attribute will NOT be used if a - * dependency content type is specified and is registered with - * Eclipse. - * - * @param extensions The comma-separated list of valid dependency extensions - * - not including the separator period. - */ - public void setDependencyExtensionsAttribute(String extensions); - - /** - * Returns the list of valid dependency extensions for this input type. - * Note that the list will come from the dependencyContentType if it - * is specified and registered with Eclipse. Otherwise the - * dependencyExtensions attribute will be used. - * - * @param tool the tool that contains the input-type - * @return String[] - */ - public String[] getDependencyExtensions(ITool tool); - - /** - * Answers true if the input type considers the file extension to be - * one associated with a dependency file. - * - * @param tool the tool that contains the input-type - * @param ext file extension of the source - * @return boolean - */ - public boolean isDependencyExtension(ITool tool, String ext); - - /** - * Returns the id of the option that is associated with this input - * type on the command line. If specified, the name(s) of the input - * files for this input type are taken from the value specified - * for the option. - * - * @return String - */ - public String getOptionId(); - - /** - * Sets the id of the option that is associated with this input type on - * the command line. If specified, the name(s) of the input files for - * this input type are taken from the value specified for the option. - * - * @param optionId - */ - public void setOptionId(String optionId); - - /** - * Returns the id of the option whose value is to be assigned to the - * file(s) calculated for this input type. The default is not to - * assign the input file(s) to a command line option but to assign the - * files to the ${Inputs} part of the command line. Note that the - * option value is only updated during build file generation and therefore - * could be out of sync with the project until build file generation - * occurs. - * - * @return String - */ - public String getAssignToOptionId(); - - /** - * Sets the id of the option whose value is to be assigned to the - * file(s) calculated for this input type. The default is not to - * assign the input file(s) to a command line option but to assign the - * files to the ${Inputs} part of the command line. Note that the - * option value is only updated during build file generation and therefore - * could be out of sync with the project until build file generation - * occurs. - * - * @param optionId - */ - public void setAssignToOptionId(String optionId); - - /** - * Returns true if this inputType can contain multiple input - * resources, else false. The inputs can be project resources, - * or the outputs of other tools in the tool-chain. - * - * @return boolean - */ - public boolean getMultipleOfType(); - - /** - * Sets whether this inputType can contain multiple input resources - * - * @param multiple - */ - public void setMultipleOfType(boolean multiple); - - /** - * Returns true if this inputType is considered the primary input - * of the tool, else false. - * - * @return boolean - */ - public boolean getPrimaryInput(); - - /** - * Sets whether this inputType is considered the primary input of the tool - * - * @param primary - */ - public void setPrimaryInput(boolean primary); - - /** - * Returns a class instance that implements an interface to generate - * source-level dependencies for this input type. - * This method may return null in which case, the receiver - * should assume that the input type does not require dependency information - * when the project is built. - * - * @return IManagedDependencyGenerator - */ - public IManagedDependencyGenerator getDependencyGenerator(); - - /** - * Returns the name of the build variable associated this this input type's resources - * The build variable used in the build file to represent the list of input files when - * multipleOfType is True. The same variable name can be used by an outputType to - * identify a set of output files that contribute to this tool’s input - * (i.e., those using the same buildVariable name). The default name is chosen by MBS. - * - * @return String - */ - public String getBuildVariable(); - - /** - * Sets the name of the build variable associated this this input type's resources - * - * @return variableName - */ - public void setBuildVariable(String variableName); - - /** - * Returns true if this element has changes that need to - * be saved in the project file, else false. - * - * @return boolean - */ - public boolean isDirty(); - - /** - * Returns true if this InputType was loaded from a manifest file, - * and false if it was loaded from a project (.cdtbuild) file. - * - * @return boolean - */ - public boolean isExtensionElement(); - - /** - * Sets the element's "dirty" (have I been modified?) flag. - * - * @param isDirty - */ - public void setDirty(boolean isDirty); - -} +/******************************************************************************* + * Copyright (c) 2005, 2006 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.core; + +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.content.IContentType; + +/** + * This interface represents an inputType instance in the managed build system. + * It describes one category of input files to a Tool. A tool can have + * multiple inputType children. + * + * @since 3.0 + */ +public interface IInputType extends IBuildObject { + public static final String INPUT_TYPE_ELEMENT_NAME = "inputType"; //$NON-NLS-1$ + public static final String SOURCE_CONTENT_TYPE = "sourceContentType"; //$NON-NLS-1$ + public static final String SOURCES = "sources"; //$NON-NLS-1$ + public static final String DEPENDENCY_CONTENT_TYPE = "dependencyContentType"; //$NON-NLS-1$ + public static final String DEPENDENCY_EXTENSIONS = "dependencyExtensions"; //$NON-NLS-1$ + public static final String OPTION = "option"; //$NON-NLS-1$ + public static final String ASSIGN_TO_OPTION = "assignToOption"; //$NON-NLS-1$ + public static final String MULTIPLE_OF_TYPE = "multipleOfType"; //$NON-NLS-1$ + public static final String PRIMARY_INPUT = "primaryInput"; //$NON-NLS-1$ + public static final String BUILD_VARIABLE = "buildVariable"; //$NON-NLS-1$ + + /** + * Creates an inputOrder child for this InputType. + * + * @param path The path associated with the InputOrder element + * @return IInputOrder of the new element + */ + public IInputOrder createInputOrder(String path); + + /** + * Removes the InputOrder element with the path specified in the argument. + * + * @param path The path associated with the InputOrder element + */ + public void removeInputOrder(String path); + + /** + * Removes the InputOrder element specified in the argument. + * + * @param path The InputOrder element + */ + public void removeInputOrder(IInputOrder element); + + /** + * Returns all of the InputOrder children of this InputType + * + * @return IInputOrder[] + */ + public IInputOrder[] getInputOrders(); + + /** + * Returns the InputOrder element with the path specified in the argument. + * + * @param path The path associated with the InputOrder element + * @return IInputOrder + */ + public IInputOrder getInputOrder(String path); + + /** + * Creates an additionalInput child for this InputType. + * + * @param path The path associated with the AdditionalInput element + * @return IAdditionalInput of the new element + */ + public IAdditionalInput createAdditionalInput(String path); + + /** + * Removes the AdditionalInput element with the path specified in the argument. + * + * @param path The path associated with the AdditionalInput element + */ + public void removeAdditionalInput(String path); + + /** + * Removes the AdditionalInput element specified in the argument. + * + * @param element The AdditionalInput element + */ + public void removeAdditionalInput(IAdditionalInput element); + + /** + * Returns all of the AdditionalInput children of this InputType + * + * @return IAdditionalInput[] + */ + public IAdditionalInput[] getAdditionalInputs(); + + /** + * Returns the AdditionalInput element with the path specified in the argument. + * + * @param path The path associated with the AdditionalInput element + * @return IAdditionalInput + */ + public IAdditionalInput getAdditionalInput(String path); + + /** + * Returns all of the additional input resources of this InputType. + * Note: This does not include additional dependencies. + * + * @return IPath[] + */ + public IPath[] getAdditionalResources(); + + /** + * Returns all of the additional dependency resources of this InputType. + * Note: This does not include additional inputs. + * + * @return IPath[] + */ + public IPath[] getAdditionalDependencies(); + + /** + * Returns the tool parent of this InputType. + * + * @return ITool + */ + public ITool getParent(); + + /** + * Returns the IInputType that is the superclass of this + * InputType, or null if the attribute was not specified. + * + * @return IInputType + */ + public IInputType getSuperClass(); + + /** + * Returns the Eclipse IContentType that describes this + * input type. If both the sources attribute and the sourceContentType + * attribute are specified, the sourceContentType will be used if it + * is registered in Eclipse. + * + * @return IContentType + */ + public IContentType getSourceContentType(); + + /** + * Sets the Eclipse IContentType that describes this + * input type. + * + * @param contentType The Eclipse content type + */ + public void setSourceContentType(IContentType contentType); + + /** + * Returns the list of valid source extensions from the + * sourceExtensions attribute. Note that this value is not used + * if source content type is specified and registered with Eclipse. + * Also, the user will not be able to modify the set of file + * extensions as they can when sourceContentType is specified. + * + * @return String[] + */ + public String[] getSourceExtensionsAttribute(); + + /** + * Sets the list of valid source extensions for this input type. + * NOTE: The value of this attribute will NOT be used if a + * source content type is specified and is registered with + * Eclipse. + * + * @param extensions The comma-separated list of valid file extensions + * - not including the separator period. + */ + public void setSourceExtensionsAttribute(String extensions); + + /** + * Returns the list of valid source extensions for this input type. + * Note that the list will come from the sourceContentType if it + * is specified and registered with Eclipse. Otherwise the + * sourceExtensions attribute will be used. + * + * @param tool the tool that contains the input-type + * @return String[] + */ + public String[] getSourceExtensions(ITool tool); + + /** + * Answers true if the input type considers the file extension to be + * one associated with a source file. + * + * @param tool the tool that contains the input-type + * @param ext file extension of the source + * @return boolean + */ + public boolean isSourceExtension(ITool tool, String ext); + + /** + * Returns the Eclipse IContentType that describes the + * dependency files of this input type. If both the dependencyExtensions + * attribute and the dependencyContentType attribute are specified, + * the dependencyContentType will be used if it is defined in Eclipse. + * + * @return IContentType + */ + public IContentType getDependencyContentType(); + + /** + * Sets the Eclipse IContentType that describes the + * dependency files of this input type. + * + * @return type + */ + public void setDependencyContentType(IContentType type); + + /** + * Returns the list of valid dependency extensions from the + * dependencyExtensions attribute. Note that this value is not used + * if dependency content type is specified and registered with Eclipse. + * Also, the user will not be able to modify the set of file + * extensions as they can when dependencyContentType is specified. + * + * @return String[] + */ + public String[] getDependencyExtensionsAttribute(); + + /** + * Sets the list of valid dependency extensions for this input type. + * NOTE: The value of this attribute will NOT be used if a + * dependency content type is specified and is registered with + * Eclipse. + * + * @param extensions The comma-separated list of valid dependency extensions + * - not including the separator period. + */ + public void setDependencyExtensionsAttribute(String extensions); + + /** + * Returns the list of valid dependency extensions for this input type. + * Note that the list will come from the dependencyContentType if it + * is specified and registered with Eclipse. Otherwise the + * dependencyExtensions attribute will be used. + * + * @param tool the tool that contains the input-type + * @return String[] + */ + public String[] getDependencyExtensions(ITool tool); + + /** + * Answers true if the input type considers the file extension to be + * one associated with a dependency file. + * + * @param tool the tool that contains the input-type + * @param ext file extension of the source + * @return boolean + */ + public boolean isDependencyExtension(ITool tool, String ext); + + /** + * Returns the id of the option that is associated with this input + * type on the command line. If specified, the name(s) of the input + * files for this input type are taken from the value specified + * for the option. + * + * @return String + */ + public String getOptionId(); + + /** + * Sets the id of the option that is associated with this input type on + * the command line. If specified, the name(s) of the input files for + * this input type are taken from the value specified for the option. + * + * @param optionId + */ + public void setOptionId(String optionId); + + /** + * Returns the id of the option whose value is to be assigned to the + * file(s) calculated for this input type. The default is not to + * assign the input file(s) to a command line option but to assign the + * files to the ${Inputs} part of the command line. Note that the + * option value is only updated during build file generation and therefore + * could be out of sync with the project until build file generation + * occurs. + * + * @return String + */ + public String getAssignToOptionId(); + + /** + * Sets the id of the option whose value is to be assigned to the + * file(s) calculated for this input type. The default is not to + * assign the input file(s) to a command line option but to assign the + * files to the ${Inputs} part of the command line. Note that the + * option value is only updated during build file generation and therefore + * could be out of sync with the project until build file generation + * occurs. + * + * @param optionId + */ + public void setAssignToOptionId(String optionId); + + /** + * Returns true if this inputType can contain multiple input + * resources, else false. The inputs can be project resources, + * or the outputs of other tools in the tool-chain. + * + * @return boolean + */ + public boolean getMultipleOfType(); + + /** + * Sets whether this inputType can contain multiple input resources + * + * @param multiple + */ + public void setMultipleOfType(boolean multiple); + + /** + * Returns true if this inputType is considered the primary input + * of the tool, else false. + * + * @return boolean + */ + public boolean getPrimaryInput(); + + /** + * Sets whether this inputType is considered the primary input of the tool + * + * @param primary + */ + public void setPrimaryInput(boolean primary); + + /** + * Returns a class instance that implements an interface to generate + * source-level dependencies for this input type. + * This method may return null in which case, the receiver + * should assume that the input type does not require dependency information + * when the project is built. + * + * @return IManagedDependencyGeneratorType + */ + public IManagedDependencyGeneratorType getDependencyGenerator(); + + /** + * Returns the name of the build variable associated this this input type's resources + * The build variable used in the build file to represent the list of input files when + * multipleOfType is True. The same variable name can be used by an outputType to + * identify a set of output files that contribute to this tool’s input + * (i.e., those using the same buildVariable name). The default name is chosen by MBS. + * + * @return String + */ + public String getBuildVariable(); + + /** + * Sets the name of the build variable associated this this input type's resources + * + * @return variableName + */ + public void setBuildVariable(String variableName); + + /** + * Returns true if this element has changes that need to + * be saved in the project file, else false. + * + * @return boolean + */ + public boolean isDirty(); + + /** + * Returns true if this InputType was loaded from a manifest file, + * and false if it was loaded from a project (.cdtbuild) file. + * + * @return boolean + */ + public boolean isExtensionElement(); + + /** + * Sets the element's "dirty" (have I been modified?) flag. + * + * @param isDirty + */ + public void setDirty(boolean isDirty); + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IManagedBuildInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IManagedBuildInfo.java index f50edcf6f3e..58a95cdf21b 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IManagedBuildInfo.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IManagedBuildInfo.java @@ -1,501 +1,501 @@ -/******************************************************************************* - * Copyright (c) 2003, 2005 Rational Software Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Rational Software - Initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.core; - -import java.util.List; - -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; -import org.eclipse.core.runtime.IPath; - -/* - * There is a ManagedBuildInfo per CDT managed build project. Here are - * some notes on their usage: - * o You can look up the managed build info associated with a CDT - * project by using ManagedBuildManager.getBuildInfo(IProject). - * o Given a ManagedBuildInfo, you can retrieve the associated CDT - * managed build system project by using getManagedProject. - * o The usage model of a ManagedBuildInfo is: - * 1. Call setDefaultConfiguration to set the context - * 2. Call other methods (e.g. getBuildArtifactName) which get - * information from the default configuration, and the other managed - * build system model elements that can be reached from the - * configuration. - */ -public interface IManagedBuildInfo { - public static final String DEFAULT_CONFIGURATION = "defaultConfig"; //$NON-NLS-1$ - public static final String DEFAULT_TARGET = "defaultTarget"; //$NON-NLS-1$ - - /* - * Note: "Target" routines are only currently applicable when loading a CDT 2.0 - * or earlier managed build project file (.cdtbuild) - */ - - /** - * Add a new target to the build information for the receiver - * - * @param target - */ - public void addTarget(ITarget target); - - /** - * Answers true if the build system knows how to - * build a file with the extension passed in the argument. - * - * @param srcExt - * @return - */ - public boolean buildsFileType(String srcExt); - - /** - * Returns IManagedCommandLineInfo for source with extension - * The command line info contains values with - * build macros resolved to the makefile format. - * That is if a user has chosen to expand all macros in the buildfile, - * command line info contains values contain all macro references resolved, otherwise, if a user has - * chosen to keep the environment build macros unresolved, the command line info contains values contain - * the environment macro references converted to the buildfile variable format, - * all other macro references are resolved - * - * @param sourceExtension - source extension - * @param flags - build flags - * @param outputFlag - output flag for build tool - * @param outputPrefix - * @param outputName - * @param inputResources - * @return IManagedCommandLineInfo - * - * @deprecated - use generateToolCommandLineInfo instead - */ - public IManagedCommandLineInfo generateCommandLineInfo( String sourceExtension, String[] flags, - String outputFlag, String outputPrefix, String outputName, String[] inputResources ); - - /** - * Returns IManagedCommandLineInfo for source with extension - * The command line info contains values with - * build macros resolved to the makefile format. - * That is if a user has chosen to expand all macros in the buildfile, - * command line info contains values contain all macro references resolved, otherwise, if a user has - * chosen to keep the environment build macros unresolved, the command line info contains values contain - * the environment macro references converted to the buildfile variable format, - * all other macro references are resolved - * - * @param sourceExtension - * @param flags - * @param outputFlag - * @param outputPrefix - * @param outputName - * @param inputResources - * @param inputLocation - * @param outputLocation - * @return - */ - public IManagedCommandLineInfo generateToolCommandLineInfo( String sourceExtension, String[] flags, - String outputFlag, String outputPrefix, String outputName, String[] inputResources, IPath inputLocation, IPath outputLocation ); - - /** - * Answers a String containing the arguments to be passed to make. - * For example, if the user has selected a build that keeps going on error, the - * answer would contain {"-k"}. - * - * @return String - */ - public String getBuildArguments(); - - - /** - * Answers the file extension for the receivers build goal without a separator. - * - * @return the extension or an empty string if none is defined - */ - public String getBuildArtifactExtension(); - - /** - * Returns the name of the artifact to build for the receiver. - * - * @return - */ - public String getBuildArtifactName(); - - /** - * Answers a String containing the make command invocation - * for the default configuration. - */ - public String getBuildCommand(); - - /** - * Answers the prebuild step for the default configuration - * - * @return String - */ - public String getPrebuildStep(); - - /** - * Answers the postbuild step for the default configuration - * - * @return String - */ - public String getPostbuildStep(); - - /** - * Answers the display string associated with the prebuild step for the default configuration - * - * @return String - */ - public String getPreannouncebuildStep(); - - /** - * Answers the display string associated with the postbuild step for the default configuration - * - * @return String - */ - public String getPostannouncebuildStep(); - - /** - * Answers the command needed to remove files on the build machine - * - * @return - */ - public String getCleanCommand(); - - /** - * Answers the name of the default configuration, for example Debug - * or Release. - * - * @return - */ - public String getConfigurationName(); - - /** - * Answers a String array containing the names of all the configurations - * defined for the project. - * - * @return - */ - public String[] getConfigurationNames(); - - /** - * Get the default configuration associated with the receiver - * - * @return - */ - public IConfiguration getDefaultConfiguration(); - - /** - * @param sourceExtension - * @return - */ - public IManagedDependencyGenerator getDependencyGenerator(String sourceExtension); - - /** - * Returns a String containing the flags, including - * those overridden by the user, for the tool in the configuration - * defined by the argument. - * The string contains build macros resolved to the makefile format. - * That is if a user has chosen to expand all macros in the buildfile, - * the string contains all macro references resolved, otherwise, if a user has - * chosen to keep the environment build macros unresolved, the string contains - * the environment macro references converted to the buildfile variable format, - * all other macro references are resolved - * - * @param extension - * @return - * - * @deprecated - use getToolFlagsForConfiguration - */ - public String getFlagsForConfiguration(String extension); - - /** - * Returns a String containing the flags, including - * those overridden by the user, for the tool in the configuration - * defined by the argument. - * The string contains build macros resolved to the makefile format. - * That is if a user has chosen to expand all macros in the buildfile, - * the string contains all macro references resolved, otherwise, if a user has - * chosen to keep the environment build macros unresolved, the string contains - * the environment macro references converted to the buildfile variable format, - * all other macro references are resolved - * - * @param extension - * @param inputLocation - * @param outputLocation - * @return - */ - public String getToolFlagsForConfiguration(String extension, IPath inputLocation, IPath outputLocation); - - /** - * Returns a String containing the flags, including - * those overridden by the user, for the tool that handles the - * type of source file defined by the argument. - * The string contains build macros resolved to the makefile format. - * That is if a user has chosen to expand all macros in the buildfile, - * the string contains all macro references resolved, otherwise, if a user has - * chosen to keep the environment build macros unresolved, the string contains - * the environment macro references converted to the buildfile variable format, - * all other macro references are resolved - * - * @param extension - * @return - * - * @deprecated - use getToolFlagsForSource - */ - public String getFlagsForSource(String extension); - - /** - * Returns a String containing the flags, including - * those overridden by the user, for the tool that handles the - * type of source file defined by the argument. - * The string contains build macros resolved to the makefile format. - * That is if a user has chosen to expand all macros in the buildfile, - * the string contains all macro references resolved, otherwise, if a user has - * chosen to keep the environment build macros unresolved, the string contains - * the environment macro references converted to the buildfile variable format, - * all other macro references are resolved - * - * @param extension - * @param inputLocation - * @param outputLocation - * @return - */ - public String getToolFlagsForSource(String extension, IPath inputLocation, IPath outputLocation); - - /** - * Answers the libraries the project links in. - * - * @param extension - * @return - */ - public String[] getLibsForConfiguration(String extension); - - /** - * Returns the ManagedProject associated with this build info - * - * @return IManagedProject - */ - public IManagedProject getManagedProject( ); - - /** - * Answers the extension that will be built by the current configuration - * for the extension passed in the argument or null. - * - * @param resourceName - * @return - */ - public String getOutputExtension(String resourceExtension); - - /** - * Answers the flag to be passed to the build tool to produce a specific output - * or an empty String if there is no special flag. For example, the - * GCC tools use the '-o' flag to produce a named output, for example - * gcc -c foo.c -o foo.o - * - * @param outputExt - * @return - */ - public String getOutputFlag(String outputExt); - - /** - * Answers the prefix that should be prepended to the name of the build - * artifact. For example, a library foo, should have the prefix 'lib' and - * the extension '.a', so the final goal would be 'libfoo.a' - * - * @param extension - * @return the prefix or an empty string - */ - public String getOutputPrefix(String outputExtension); - - /** - * Returns the currently selected configuration. This is used while the project - * property pages are displayed - * - * @return IConfiguration - */ - public IConfiguration getSelectedConfiguration(); - - /** - * Get the target specified in the argument. - * - * @param id - * @return - */ - public ITarget getTarget(String id); - - /** - * Get all of the targets associated with the receiver. - * - * @return - */ - public List getTargets(); - - /** - * Returns a String containing the command-line invocation - * for the tool associated with the output extension. - * - * @param extension the file extension of the output file - * @return a String containing the command line invocation for the tool - */ - public String getToolForConfiguration(String extension); - - /** - * Returns a String containing the command-line invocation - * for the tool associated with the source extension. - * - * @param sourceExtension the file extension of the file to be built - * @return a String containing the command line invocation for the tool - */ - public String getToolForSource(String sourceExtension); - - /** - * Returns a ITool for the tool associated with the - * input extension. - * - * @param extension the file extension of the input file - * @return ITool - */ - public ITool getToolFromInputExtension(String extension); - - /** - * Returns a ITool for the tool associated with the - * output extension. - * - * @param extension the file extension of the output file - * @return ITool - */ - public ITool getToolFromOutputExtension(String extension); - - /** - * Answers a String 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 - */ - public String[] getUserObjectsForConfiguration(String extension); - - - /** - * Answers the version of the build information in the format - * @return a String containing the build information - * version - */ - public String getVersion(); - - /** - * Answers true if the build model has been changed by the user. - * - * @return boolean - */ - public boolean isDirty(); - - /** - * Answers true if the extension matches one of the special - * file extensions the tools for the configuration consider to be a header file. - * - * @param ext the file extension of the resource - * @return boolean - */ - public boolean isHeaderFile(String ext); - - /** - * Gets the read only status of Managed Build Info - * - * @return true if Managed Build Info is read only - * otherwise returns false - */ - public boolean isReadOnly(); - - /** - * Gets the "valid" status of Managed Build Info. Managed Build Info is invalid - * if the loading of, or conversion to, the Managed Build Info failed. - * - * @return true if Managed Build Info is valid, - * otherwise returns false - */ - public boolean isValid(); - - /** - * Answers whether the receiver has been changed and requires the - * project to be rebuilt. When a project is first created, it is - * assumed that the user will need it to be fully rebuilt. However - * only option and tool command changes will trigger the build - * information for an existing project to require a rebuild. - *

- * Clients can reset the state to force or clear the rebuild status - * using setRebuildState() - * @see ManagedBuildInfo#setRebuildState(boolean) - * - * @return true if the resource managed by the - * receiver needs to be rebuilt - */ - public boolean needsRebuild(); - - public void removeTarget(String id); - - /** - * Set the primary configuration for the receiver. - * - * @param configuration The IConfiguration that will be used as the default - * for all building. - */ - public void setDefaultConfiguration(IConfiguration configuration); - - /** - * - * @param configuration - * @return - */ - public boolean setDefaultConfiguration(String configName); - - /** - * Sets the dirty flag for the build model to the value of the argument. - * - * @param isDirty - */ - public void setDirty(boolean isDirty); - - /** - * Sets the valid flag for the build model to the value of the argument. - * - * @param isValid - */ - public void setValid(boolean isValid); - - /** - * Sets the ManagedProject associated with this build info - * - * @param project - */ - public void setManagedProject(IManagedProject project); - - /** - * sets the read only status of Managed Build Info - * - * @param readOnly - */ - public void setReadOnly(boolean readOnly); - - /** - * Sets the rebuild state in the receiver to the value of the argument. - * This is a potentially expensive option, so setting it to true should - * only be done if a project resource or setting has been modified in a - * way that would invalidate the previous build. - * - * @param true will force a rebuild the next time the project builds - */ - public void setRebuildState(boolean rebuild); - - /** - * Sets the currently selected configuration. This is used while the project - * property pages are displayed - * - * @param configuration the user selection - */ - public void setSelectedConfiguration(IConfiguration configuration); -} +/******************************************************************************* + * Copyright (c) 2003, 2006 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.core; + +import java.util.List; + +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType; +import org.eclipse.core.runtime.IPath; + +/* + * There is a ManagedBuildInfo per CDT managed build project. Here are + * some notes on their usage: + * o You can look up the managed build info associated with a CDT + * project by using ManagedBuildManager.getBuildInfo(IProject). + * o Given a ManagedBuildInfo, you can retrieve the associated CDT + * managed build system project by using getManagedProject. + * o The usage model of a ManagedBuildInfo is: + * 1. Call setDefaultConfiguration to set the context + * 2. Call other methods (e.g. getBuildArtifactName) which get + * information from the default configuration, and the other managed + * build system model elements that can be reached from the + * configuration. + */ +public interface IManagedBuildInfo { + public static final String DEFAULT_CONFIGURATION = "defaultConfig"; //$NON-NLS-1$ + public static final String DEFAULT_TARGET = "defaultTarget"; //$NON-NLS-1$ + + /* + * Note: "Target" routines are only currently applicable when loading a CDT 2.0 + * or earlier managed build project file (.cdtbuild) + */ + + /** + * Add a new target to the build information for the receiver + * + * @param target + */ + public void addTarget(ITarget target); + + /** + * Answers true if the build system knows how to + * build a file with the extension passed in the argument. + * + * @param srcExt + * @return + */ + public boolean buildsFileType(String srcExt); + + /** + * Returns IManagedCommandLineInfo for source with extension + * The command line info contains values with + * build macros resolved to the makefile format. + * That is if a user has chosen to expand all macros in the buildfile, + * command line info contains values contain all macro references resolved, otherwise, if a user has + * chosen to keep the environment build macros unresolved, the command line info contains values contain + * the environment macro references converted to the buildfile variable format, + * all other macro references are resolved + * + * @param sourceExtension - source extension + * @param flags - build flags + * @param outputFlag - output flag for build tool + * @param outputPrefix + * @param outputName + * @param inputResources + * @return IManagedCommandLineInfo + * + * @deprecated - use generateToolCommandLineInfo instead + */ + public IManagedCommandLineInfo generateCommandLineInfo( String sourceExtension, String[] flags, + String outputFlag, String outputPrefix, String outputName, String[] inputResources ); + + /** + * Returns IManagedCommandLineInfo for source with extension + * The command line info contains values with + * build macros resolved to the makefile format. + * That is if a user has chosen to expand all macros in the buildfile, + * command line info contains values contain all macro references resolved, otherwise, if a user has + * chosen to keep the environment build macros unresolved, the command line info contains values contain + * the environment macro references converted to the buildfile variable format, + * all other macro references are resolved + * + * @param sourceExtension + * @param flags + * @param outputFlag + * @param outputPrefix + * @param outputName + * @param inputResources + * @param inputLocation + * @param outputLocation + * @return + */ + public IManagedCommandLineInfo generateToolCommandLineInfo( String sourceExtension, String[] flags, + String outputFlag, String outputPrefix, String outputName, String[] inputResources, IPath inputLocation, IPath outputLocation ); + + /** + * Answers a String containing the arguments to be passed to make. + * For example, if the user has selected a build that keeps going on error, the + * answer would contain {"-k"}. + * + * @return String + */ + public String getBuildArguments(); + + + /** + * Answers the file extension for the receivers build goal without a separator. + * + * @return the extension or an empty string if none is defined + */ + public String getBuildArtifactExtension(); + + /** + * Returns the name of the artifact to build for the receiver. + * + * @return + */ + public String getBuildArtifactName(); + + /** + * Answers a String containing the make command invocation + * for the default configuration. + */ + public String getBuildCommand(); + + /** + * Answers the prebuild step for the default configuration + * + * @return String + */ + public String getPrebuildStep(); + + /** + * Answers the postbuild step for the default configuration + * + * @return String + */ + public String getPostbuildStep(); + + /** + * Answers the display string associated with the prebuild step for the default configuration + * + * @return String + */ + public String getPreannouncebuildStep(); + + /** + * Answers the display string associated with the postbuild step for the default configuration + * + * @return String + */ + public String getPostannouncebuildStep(); + + /** + * Answers the command needed to remove files on the build machine + * + * @return + */ + public String getCleanCommand(); + + /** + * Answers the name of the default configuration, for example Debug + * or Release. + * + * @return + */ + public String getConfigurationName(); + + /** + * Answers a String array containing the names of all the configurations + * defined for the project. + * + * @return + */ + public String[] getConfigurationNames(); + + /** + * Get the default configuration associated with the receiver + * + * @return + */ + public IConfiguration getDefaultConfiguration(); + + /** + * @param sourceExtension + * @return + */ + public IManagedDependencyGeneratorType getDependencyGenerator(String sourceExtension); + + /** + * Returns a String containing the flags, including + * those overridden by the user, for the tool in the configuration + * defined by the argument. + * The string contains build macros resolved to the makefile format. + * That is if a user has chosen to expand all macros in the buildfile, + * the string contains all macro references resolved, otherwise, if a user has + * chosen to keep the environment build macros unresolved, the string contains + * the environment macro references converted to the buildfile variable format, + * all other macro references are resolved + * + * @param extension + * @return + * + * @deprecated - use getToolFlagsForConfiguration + */ + public String getFlagsForConfiguration(String extension); + + /** + * Returns a String containing the flags, including + * those overridden by the user, for the tool in the configuration + * defined by the argument. + * The string contains build macros resolved to the makefile format. + * That is if a user has chosen to expand all macros in the buildfile, + * the string contains all macro references resolved, otherwise, if a user has + * chosen to keep the environment build macros unresolved, the string contains + * the environment macro references converted to the buildfile variable format, + * all other macro references are resolved + * + * @param extension + * @param inputLocation + * @param outputLocation + * @return + */ + public String getToolFlagsForConfiguration(String extension, IPath inputLocation, IPath outputLocation); + + /** + * Returns a String containing the flags, including + * those overridden by the user, for the tool that handles the + * type of source file defined by the argument. + * The string contains build macros resolved to the makefile format. + * That is if a user has chosen to expand all macros in the buildfile, + * the string contains all macro references resolved, otherwise, if a user has + * chosen to keep the environment build macros unresolved, the string contains + * the environment macro references converted to the buildfile variable format, + * all other macro references are resolved + * + * @param extension + * @return + * + * @deprecated - use getToolFlagsForSource + */ + public String getFlagsForSource(String extension); + + /** + * Returns a String containing the flags, including + * those overridden by the user, for the tool that handles the + * type of source file defined by the argument. + * The string contains build macros resolved to the makefile format. + * That is if a user has chosen to expand all macros in the buildfile, + * the string contains all macro references resolved, otherwise, if a user has + * chosen to keep the environment build macros unresolved, the string contains + * the environment macro references converted to the buildfile variable format, + * all other macro references are resolved + * + * @param extension + * @param inputLocation + * @param outputLocation + * @return + */ + public String getToolFlagsForSource(String extension, IPath inputLocation, IPath outputLocation); + + /** + * Answers the libraries the project links in. + * + * @param extension + * @return + */ + public String[] getLibsForConfiguration(String extension); + + /** + * Returns the ManagedProject associated with this build info + * + * @return IManagedProject + */ + public IManagedProject getManagedProject( ); + + /** + * Answers the extension that will be built by the current configuration + * for the extension passed in the argument or null. + * + * @param resourceName + * @return + */ + public String getOutputExtension(String resourceExtension); + + /** + * Answers the flag to be passed to the build tool to produce a specific output + * or an empty String if there is no special flag. For example, the + * GCC tools use the '-o' flag to produce a named output, for example + * gcc -c foo.c -o foo.o + * + * @param outputExt + * @return + */ + public String getOutputFlag(String outputExt); + + /** + * Answers the prefix that should be prepended to the name of the build + * artifact. For example, a library foo, should have the prefix 'lib' and + * the extension '.a', so the final goal would be 'libfoo.a' + * + * @param extension + * @return the prefix or an empty string + */ + public String getOutputPrefix(String outputExtension); + + /** + * Returns the currently selected configuration. This is used while the project + * property pages are displayed + * + * @return IConfiguration + */ + public IConfiguration getSelectedConfiguration(); + + /** + * Get the target specified in the argument. + * + * @param id + * @return + */ + public ITarget getTarget(String id); + + /** + * Get all of the targets associated with the receiver. + * + * @return + */ + public List getTargets(); + + /** + * Returns a String containing the command-line invocation + * for the tool associated with the output extension. + * + * @param extension the file extension of the output file + * @return a String containing the command line invocation for the tool + */ + public String getToolForConfiguration(String extension); + + /** + * Returns a String containing the command-line invocation + * for the tool associated with the source extension. + * + * @param sourceExtension the file extension of the file to be built + * @return a String containing the command line invocation for the tool + */ + public String getToolForSource(String sourceExtension); + + /** + * Returns a ITool for the tool associated with the + * input extension. + * + * @param extension the file extension of the input file + * @return ITool + */ + public ITool getToolFromInputExtension(String extension); + + /** + * Returns a ITool for the tool associated with the + * output extension. + * + * @param extension the file extension of the output file + * @return ITool + */ + public ITool getToolFromOutputExtension(String extension); + + /** + * Answers a String 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 + */ + public String[] getUserObjectsForConfiguration(String extension); + + + /** + * Answers the version of the build information in the format + * @return a String containing the build information + * version + */ + public String getVersion(); + + /** + * Answers true if the build model has been changed by the user. + * + * @return boolean + */ + public boolean isDirty(); + + /** + * Answers true if the extension matches one of the special + * file extensions the tools for the configuration consider to be a header file. + * + * @param ext the file extension of the resource + * @return boolean + */ + public boolean isHeaderFile(String ext); + + /** + * Gets the read only status of Managed Build Info + * + * @return true if Managed Build Info is read only + * otherwise returns false + */ + public boolean isReadOnly(); + + /** + * Gets the "valid" status of Managed Build Info. Managed Build Info is invalid + * if the loading of, or conversion to, the Managed Build Info failed. + * + * @return true if Managed Build Info is valid, + * otherwise returns false + */ + public boolean isValid(); + + /** + * Answers whether the receiver has been changed and requires the + * project to be rebuilt. When a project is first created, it is + * assumed that the user will need it to be fully rebuilt. However + * only option and tool command changes will trigger the build + * information for an existing project to require a rebuild. + *

+ * Clients can reset the state to force or clear the rebuild status + * using setRebuildState() + * @see ManagedBuildInfo#setRebuildState(boolean) + * + * @return true if the resource managed by the + * receiver needs to be rebuilt + */ + public boolean needsRebuild(); + + public void removeTarget(String id); + + /** + * Set the primary configuration for the receiver. + * + * @param configuration The IConfiguration that will be used as the default + * for all building. + */ + public void setDefaultConfiguration(IConfiguration configuration); + + /** + * + * @param configuration + * @return + */ + public boolean setDefaultConfiguration(String configName); + + /** + * Sets the dirty flag for the build model to the value of the argument. + * + * @param isDirty + */ + public void setDirty(boolean isDirty); + + /** + * Sets the valid flag for the build model to the value of the argument. + * + * @param isValid + */ + public void setValid(boolean isValid); + + /** + * Sets the ManagedProject associated with this build info + * + * @param project + */ + public void setManagedProject(IManagedProject project); + + /** + * sets the read only status of Managed Build Info + * + * @param readOnly + */ + public void setReadOnly(boolean readOnly); + + /** + * Sets the rebuild state in the receiver to the value of the argument. + * This is a potentially expensive option, so setting it to true should + * only be done if a project resource or setting has been modified in a + * way that would invalidate the previous build. + * + * @param true will force a rebuild the next time the project builds + */ + public void setRebuildState(boolean rebuild); + + /** + * Sets the currently selected configuration. This is used while the project + * property pages are displayed + * + * @param configuration the user selection + */ + public void setSelectedConfiguration(IConfiguration configuration); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ITool.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ITool.java index 35648ee55fd..3d04cd8d696 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ITool.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ITool.java @@ -1,725 +1,726 @@ -/******************************************************************************* - * Copyright (c) 2003, 2005 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.core; - -import java.util.List; - -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IPath; - -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; - -/** - * This interface represents a utility of some sort that is used in the build process. - * A tool will generally process one or more resources to produce output resources. - * Most tools have a set of options that can be used to modify the behavior of the tool. - */ -public interface ITool extends IBuildObject, IHoldsOptions { - // Schema element names - public static final String COMMAND = "command"; //$NON-NLS-1$ - public static final String COMMAND_LINE_PATTERN = "commandLinePattern"; //$NON-NLS-1$ - public static final String COMMAND_LINE_GENERATOR = "commandLineGenerator"; //$NON-NLS-1$ - public static final String DEP_CALC_ID ="dependencyCalculator"; //$NON-NLS-1$ - public static final String INTERFACE_EXTS = "headerExtensions"; //$NON-NLS-1$ - public static final String NATURE = "natureFilter"; //$NON-NLS-1$ - public static final String OUTPUT_FLAG = "outputFlag"; //$NON-NLS-1$ - public static final String INPUT_TYPE = "inputType"; //$NON-NLS-1$ - public static final String OUTPUT_TYPE = "outputType"; //$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 ADVANCED_INPUT_CATEGORY = "advancedInputCategory"; //$NON-NLS-1$ - public static final String CUSTOM_BUILD_STEP = "customBuildStep"; //$NON-NLS-1$ - public static final String ANNOUNCEMENT = "announcement"; //$NON-NLS-1$ - public static final String TOOL_ELEMENT_NAME = "tool"; //$NON-NLS-1$ - public static final String WHITE_SPACE = " "; //$NON-NLS-1$ - public static final String EMPTY_STRING = ""; //$NON-NLS-1$ - - public static final String VERSIONS_SUPPORTED = "versionsSupported"; //$NON-NLS-1$ - public static final String CONVERT_TO_ID = "convertToId"; //$NON-NLS-1$ - - public static final int FILTER_C = 0; - public static final int FILTER_CC = 1; - public static final int FILTER_BOTH = 2; - - /** - * Returns the tool-chain or resource configuration that is the parent of this tool. - * - * @return IBuildObject - */ - public IBuildObject getParent(); - - /** - * Creates a child InputType for this tool. - * - * @param InputType The superClass, if any - * @param String The id for the new InputType - * @param String The name for the new InputType - * @param boolean Indicates whether this is an extension element or a managed project element - * - * @return IInputType - * @since 3.0 - */ - public IInputType createInputType(IInputType superClass, String Id, String name, boolean isExtensionElement); - - /** - * Removes an InputType from the tool's list. - * - * @param type - * @since 3.0 - */ - public void removeInputType(IInputType type); - - /** - * Returns the complete list of input types that are available for this tool. - * The list is a merging of the input types specified for this tool with the - * input types of its superclasses. The lowest input type instance in the hierarchy - * takes precedence. - * - * @return IInputType[] - * @since 3.0 - */ - public IInputType[] getInputTypes(); - - /** - * Returns the IInputType in the tool with the specified - * ID. This is an efficient search in the receiver. - * - *

If the receiver does not have an InputType with that ID, the method - * returns null. It is the responsibility of the caller to - * verify the return value. - * - * @param id unique identifier of the InputType to search for - * @return IInputType - * @since 3.0 - */ - public IInputType getInputTypeById(String id); - - /** - * Returns the IInputType in the tool that uses the - * specified extension. - * - *

If the receiver does not have an InputType that uses the extension, - * the method returns null. It is the responsibility of the - * caller to verify the return value. - * - * @param inputExtension File extension - * @return IInputType - * @since 3.0 - */ - public IInputType getInputType(String inputExtension); - - /** - * Returns the primary IInputType in this tool - * - *

If the receiver has no InputTypes, - * the method returns null. It is the responsibility of the - * caller to verify the return value. - * - * @return IInputType - * @since 3.0 - */ - public IInputType getPrimaryInputType(); - - /** - * Returns all of the additional input resources of all InputType children. - * Note: This does not include the primary InputType and does not include - * additional dependencies. - * - * @return IPath[] - */ - public IPath[] getAdditionalResources(); - - /** - * Returns all of the additional dependency resources of all InputType children. - * Note: This does not include the primary InputType and does not include - * additional inputs. - * - * @return IPath[] - */ - public IPath[] getAdditionalDependencies(); - - /** - * Creates a child OutputType for this tool. - * - * @param OutputType The superClass, if any - * @param String The id for the new OutputType - * @param String The name for the new OutputType - * @param boolean Indicates whether this is an extension element or a managed project element - * - * @return IOutputType - * @since 3.0 - */ - public IOutputType createOutputType(IOutputType superClass, String Id, String name, boolean isExtensionElement); - - /** - * Removes an OutputType from the tool's list. - * - * @param type - * @since 3.0 - */ - public void removeOutputType(IOutputType type); - - /** - * Returns the complete list of output types that are available for this tool. - * The list is a merging of the output types specified for this tool with the - * output types of its superclasses. The lowest output type instance in the hierarchy - * takes precedence. - * - * @return IOutputType[] - * @since 3.0 - */ - public IOutputType[] getOutputTypes(); - /** - * Get the IOutputType in the receiver with the specified - * ID. This is an efficient search in the receiver. - * - *

If the receiver does not have an OutputType with that ID, the method - * returns null. It is the responsibility of the caller to - * verify the return value. - * - * @param id unique identifier of the OutputType to search for - * @return IOutputType - * @since 3.0 - */ - public IOutputType getOutputTypeById(String id); - - /** - * Returns the IOutputType in the tool that creates the - * specified extension. - * - *

If the receiver does not have an OutputType that creates the extension, - * the method returns null. It is the responsibility of the - * caller to verify the return value. - * - * @param outputExtension File extension - * @return IOutputType - * @since 3.0 - */ - public IOutputType getOutputType(String outputExtension); - - /** - * Returns the primary IOutputType in this tool - * - *

If the receiver has no OutputTypes, - * the method returns null. It is the responsibility of the - * caller to verify the return value. - * - * @return IOutputType - * @since 3.0 - */ - public IOutputType getPrimaryOutputType(); - - /** - * Returns the ITool that is the superclass of this - * tool, or null if the attribute was not specified. - * - * @return ITool - */ - public ITool getSuperClass(); - - /** - * Returns whether this element is abstract. Returns false - * if the attribute was not specified. - * @return boolean - */ - public boolean isAbstract(); - - /** - * Sets the isAbstract attribute of the tool-chain. - * - * @param b - */ - public void setIsAbstract(boolean b); - - /** - * Returns a semi-colon delimited list of child Ids of the superclass' - * children that should not be automatically inherited by this element. - * Returns an empty string if the attribute was not specified. - * @return String - */ - public String getUnusedChildren(); - - /** - * Returns the semicolon separated list of unique IDs of the error parsers associated - * with the tool. - * - * @return String - */ - public String getErrorParserIds(); - - /** - * Returns the ordered list of unique IDs of the error parsers associated with the - * tool. - * - * @return String[] - */ - public String[] getErrorParserList(); - - /** - * Sets the semicolon separated list of error parser ids - * - * @param ids - */ - public void setErrorParserIds(String ids); - - /** - * Returns the list of valid source extensions this tool knows how to build. - * The list may be empty but will never be null. - * - * @return List - * @deprecated - use getPrimaryInputExtensions or getAllInputExtensions - */ - public List getInputExtensions(); - - /** - * Returns the array of valid primary source extensions this tool knows how to build. - * The array may be empty but will never be null. - * - * @return String[] - */ - public String[] getPrimaryInputExtensions(); - - /** - * Returns the array of all valid source extensions this tool knows how to build. - * The array may be empty but will never be null. - * - * @return String[] - */ - public String[] getAllInputExtensions(); - - /** - * Returns the default input extension for the primary input of the tool - * - * @return String - */ - public String getDefaultInputExtension(); - - /** - * Returns the array of all valid dependency extensions for this tool's inputs. - * The array may be empty but will never be null. - * - * @return String[] - */ - public String[] getAllDependencyExtensions(); - - /** - * Returns the list of valid header extensions for this tool. - * Returns the value of the headerExtensions attribute - * The list may be empty but will never be null. - * - * @return List - * @deprecated - use getDependency* methods - */ - public List getInterfaceExtensions(); - - /** - * Answers a constant corresponding to the project nature the tool should be used - * for. Possible answers are: - * - *

- *
ITool.FILTER_C - *
The tool should only be displayed for C projects. Notes: even - * though a C++ project has a C nature, this flag will mask the tool for C++ - * projects. - *
ITool.FILTER_CC - *
The tool should only be displayed for C++ projects. - *
ITool.FILTER_BOTH - *
The tool should be displayed for projects with both natures. - *
- * - * @return int - */ - public int getNatureFilter(); - - /** - * Returns the array of all valid output extensions this tool can create. - * The array may be empty but will never be null. - * - * @return String[] - */ - public String[] getAllOutputExtensions(); - - /** - * Answers all of the output extensions that the receiver can build. - * This routine returns the value if the outputs attribute. - * - * @return String[] of extensions - * @deprecated - use getAllOutputExtensions - */ - public String[] getOutputExtensions(); - - /** - * Answers all of the output extensions that the receiver can build, - * from the value of the outputs attribute - * - * @return String[] of extensions - */ - public String[] getOutputsAttribute(); - - /** - * Answer the output extension the receiver will create from the input, - * or null if the tool does not understand that extension. - * - * @param inputExtension The extension of the source file. - * @return String - */ - public String getOutputExtension(String inputExtension); - - /** - * Sets all of the output extensions that the receiver can build, - * into the outputs attribute. Note that the outputs attribute is - * ignored when one or more outputTypes are specified. - * - * @param String - */ - public void setOutputsAttribute(String extensions); - - /** - * Answers the argument that must be passed to a specific tool in order to - * control the name of the output artifact. For example, the GCC compile and - * linker use '-o', while the archiver does not. - * - * @return String - */ - public String getOutputFlag(); - - /** - * Sets the argument that must be passed to a specific tool in order to - * control the name of the output artifact. For example, the GCC compile and - * linker use '-o', while the archiver does not. - * - * @param String - */ - public void setOutputFlag(String flag); - - /** - * 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 - * @return String - */ - public String getOutputPrefix(); - - /** - * Sets 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 - * @param String - */ - public void setOutputPrefix(String prefix); - - /** - * Returns true if the Tool wants the MBS to display the Advanced - * Input category that allows the user to specify additional input resources and - * dependencies, else false. - * - * @return boolean - */ - public boolean getAdvancedInputCategory(); - - /** - * Sets whether the Tool wants the MBS to display the Advanced - * Input category that allows the user to specify additional input resources and - * dependencies. - * - * @param display - */ - public void setAdvancedInputCategory(boolean display); - - /** - * Returns true if the Tool represents a user-define custom build - * step, else false. - * - * @return boolean - */ - public boolean getCustomBuildStep(); - - /** - * Sets whether the Tool represents a user-define custom build step. - * - * @param customBuildStep - */ - public void setCustomBuildStep(boolean customBuildStep); - - /** - * Returns the announcement string for this tool - * @return String - */ - public String getAnnouncement(); - - /** - * Sets the announcement string for this tool - * @param announcement - */ - public void setAnnouncement(String announcement); - - /** - * Answers the command-line invocation defined for the receiver. - * - * @return String - */ - public String getToolCommand(); - - /** - * Sets the command-line invocation command defined for this tool. - * - * @param String - * - * @return boolean if true, then the tool command was modified - */ - public boolean setToolCommand(String command); - - /** - * Returns command line pattern for this tool - * @return String - */ - public String getCommandLinePattern(); - - /** - * Sets the command line pattern for this tool - * @param String - */ - public void setCommandLinePattern(String pattern); - - /** - * Returns the plugin.xml element of the commandLineGenerator extension or null if none. - * - * @return IConfigurationElement - * - * @deprecated - use getCommandLineGenerator - */ - public IConfigurationElement getCommandLineGeneratorElement(); - - /** - * Sets the CommandLineGenerator plugin.xml element - * - * @param element - * @deprecated - */ - public void setCommandLineGeneratorElement(IConfigurationElement element); - - /** - * Returns the command line generator specified for this tool - * @return IManagedCommandLineGenerator - */ - public IManagedCommandLineGenerator getCommandLineGenerator(); - - /** - * Returns the plugin.xml element of the dependencyGenerator extension or null if none. - * - * @return IConfigurationElement - * @deprecated - use getDependencyGeneratorForExtension or IInputType#getDependencyGenerator method - */ - public IConfigurationElement getDependencyGeneratorElement(); - - /** - * Sets the DependencyGenerator plugin.xml element - * - * @param element - * @deprecated - */ - public void setDependencyGeneratorElement(IConfigurationElement element); - - /** - * Returns a class instance that implements an interface to generate - * source-level dependencies for the tool specified in the argument. - * This method may return null in which case, the receiver - * should assume that the tool does not require dependency information - * when the project is built. - * - * @return IManagedDependencyGenerator - * @deprecated - use getDependencyGeneratorForExtension or IInputType method - */ - public IManagedDependencyGenerator getDependencyGenerator(); - - /** - * Returns a class instance that implements an interface to generate - * source-level dependencies for the tool specified in the argument. - * This method may return null in which case, the receiver - * should assume that the tool does not require dependency information - * when the project is built. - * - * @param sourceExt source file extension - * @return IManagedDependencyGenerator - */ - public IManagedDependencyGenerator getDependencyGeneratorForExtension(String sourceExt); - - /** - * Returns an array of command line arguments that have been specified for - * the tool. - * The flags contain build macros resolved to the makefile format. - * That is if a user has chosen to expand all macros in the buildfile, - * the flags contain all macro references resolved, otherwise, if a user has - * chosen to keep the environment build macros unresolved, the flags contain - * the environment macro references converted to the buildfile variable format, - * all other macro references are resolved - * - * @return String[] - * @throws BuildException - * - * @deprecated - use getToolCommandFlags instead - */ - public String[] getCommandFlags() throws BuildException; - - /** - * Returns the command line arguments that have been specified for - * the tool. - * The string contains build macros resolved to the makefile format. - * That is if a user has chosen to expand all macros in the buildfile, - * the string contains all macro references resolved, otherwise, if a user has - * chosen to keep the environment build macros unresolved, the string contains - * the environment macro references converted to the buildfile variable format, - * all other macro references are resolved - * - * @return String - * - * @deprecated - use getToolCommandFlagsString instead - */ - public String getToolFlags() throws BuildException ; - - /** - * Returns an array of command line arguments that have been specified for - * the tool. - * The flags contain build macros resolved to the makefile format. - * That is if a user has chosen to expand all macros in the buildfile, - * the flags contain all macro references resolved, otherwise, if a user has - * chosen to keep the environment build macros unresolved, the flags contain - * the environment macro references converted to the buildfile variable format, - * all other macro references are resolved - * - * @param inputFileLocation - * @param outputFileLocation - * @return - * @throws BuildException - */ - public String[] getToolCommandFlags(IPath inputFileLocation, IPath outputFileLocation) throws BuildException; - - /** - * Returns the command line arguments that have been specified for - * the tool. - * The string contains build macros resolved to the makefile format. - * That is if a user has chosen to expand all macros in the buildfile, - * the string contains all macro references resolved, otherwise, if a user has - * chosen to keep the environment build macros unresolved, the string contains - * the environment macro references converted to the buildfile variable format, - * all other macro references are resolved - * - * @param inputFileLocation - * @param outputFileLocation - * @return - * @throws BuildException - */ - public String getToolCommandFlagsString(IPath inputFileLocation, IPath outputFileLocation) throws BuildException; - - /** - * Options are organized into categories for UI purposes. - * These categories are organized into a tree. This is the root - * of that tree. - * - * @return IOptionCategory - */ - public IOptionCategory getTopOptionCategory(); - - /** - * Return true if the receiver builds files with the - * specified extension, else false. - * - * @param extension file extension of the source - * @return boolean - */ - public boolean buildsFileType(String extension); - - /** - * Return true if the receiver uses files with the - * specified extension as input, else false. This - * returns true for a superset of the extensions that buildFileType - * returns true for - it includes secondary inputs. - * - * @param extension file extension of the source - * @return boolean - */ - public boolean isInputFileType(String extension); - - /** - * Answers true 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 true if the receiver builds a file with the extension specified - * in the argument, else false. - * - * @param outputExtension extension of the file being produced by a tool - * @return boolean - */ - public boolean producesFileType(String outputExtension); - - /** - * Returns true if this tool has changes that need to - * be saved in the project file, else false. - * - * @return boolean - */ - public boolean isDirty(); - - /** - * Sets the element's "dirty" (have I been modified?) flag. - * - * @param isDirty - */ - public void setDirty(boolean isDirty); - - /** - * Returns true if this tool was loaded from a manifest file, - * and false if it was loaded from a project (.cdtbuild) file. - * - * @return boolean - */ - public boolean isExtensionElement(); - - /** - * Returns the 'versionsSupported' of this tool - * - * @return String - */ - public String getVersionsSupported(); - - /** - * Returns the 'convertToId' of this tool - * - * @return String - */ - public String getConvertToId(); - - /** - * Sets the 'versionsSupported' attribute of the tool. - * - * @param versionsSupported - */ - public void setVersionsSupported(String versionsSupported); - - /** - * Sets the 'convertToId' attribute of the tool. - * - * @param convertToId - */ - public void setConvertToId(String convertToId); - - /** - * Returns an array of the Environment Build Path variable descriptors - * - * @return IEnvVarBuildPath[] - */ - public IEnvVarBuildPath[] getEnvVarBuildPaths(); -} +/******************************************************************************* + * Copyright (c) 2003, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.core; + +import java.util.List; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IPath; + +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType; + +/** + * This interface represents a utility of some sort that is used in the build process. + * A tool will generally process one or more resources to produce output resources. + * Most tools have a set of options that can be used to modify the behavior of the tool. + */ +public interface ITool extends IBuildObject, IHoldsOptions { + // Schema element names + public static final String COMMAND = "command"; //$NON-NLS-1$ + public static final String COMMAND_LINE_PATTERN = "commandLinePattern"; //$NON-NLS-1$ + public static final String COMMAND_LINE_GENERATOR = "commandLineGenerator"; //$NON-NLS-1$ + public static final String DEP_CALC_ID ="dependencyCalculator"; //$NON-NLS-1$ + public static final String INTERFACE_EXTS = "headerExtensions"; //$NON-NLS-1$ + public static final String NATURE = "natureFilter"; //$NON-NLS-1$ + public static final String OUTPUT_FLAG = "outputFlag"; //$NON-NLS-1$ + public static final String INPUT_TYPE = "inputType"; //$NON-NLS-1$ + public static final String OUTPUT_TYPE = "outputType"; //$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 ADVANCED_INPUT_CATEGORY = "advancedInputCategory"; //$NON-NLS-1$ + public static final String CUSTOM_BUILD_STEP = "customBuildStep"; //$NON-NLS-1$ + public static final String ANNOUNCEMENT = "announcement"; //$NON-NLS-1$ + public static final String TOOL_ELEMENT_NAME = "tool"; //$NON-NLS-1$ + public static final String WHITE_SPACE = " "; //$NON-NLS-1$ + public static final String EMPTY_STRING = ""; //$NON-NLS-1$ + + public static final String VERSIONS_SUPPORTED = "versionsSupported"; //$NON-NLS-1$ + public static final String CONVERT_TO_ID = "convertToId"; //$NON-NLS-1$ + + public static final int FILTER_C = 0; + public static final int FILTER_CC = 1; + public static final int FILTER_BOTH = 2; + + /** + * Returns the tool-chain or resource configuration that is the parent of this tool. + * + * @return IBuildObject + */ + public IBuildObject getParent(); + + /** + * Creates a child InputType for this tool. + * + * @param InputType The superClass, if any + * @param String The id for the new InputType + * @param String The name for the new InputType + * @param boolean Indicates whether this is an extension element or a managed project element + * + * @return IInputType + * @since 3.0 + */ + public IInputType createInputType(IInputType superClass, String Id, String name, boolean isExtensionElement); + + /** + * Removes an InputType from the tool's list. + * + * @param type + * @since 3.0 + */ + public void removeInputType(IInputType type); + + /** + * Returns the complete list of input types that are available for this tool. + * The list is a merging of the input types specified for this tool with the + * input types of its superclasses. The lowest input type instance in the hierarchy + * takes precedence. + * + * @return IInputType[] + * @since 3.0 + */ + public IInputType[] getInputTypes(); + + /** + * Returns the IInputType in the tool with the specified + * ID. This is an efficient search in the receiver. + * + *

If the receiver does not have an InputType with that ID, the method + * returns null. It is the responsibility of the caller to + * verify the return value. + * + * @param id unique identifier of the InputType to search for + * @return IInputType + * @since 3.0 + */ + public IInputType getInputTypeById(String id); + + /** + * Returns the IInputType in the tool that uses the + * specified extension. + * + *

If the receiver does not have an InputType that uses the extension, + * the method returns null. It is the responsibility of the + * caller to verify the return value. + * + * @param inputExtension File extension + * @return IInputType + * @since 3.0 + */ + public IInputType getInputType(String inputExtension); + + /** + * Returns the primary IInputType in this tool + * + *

If the receiver has no InputTypes, + * the method returns null. It is the responsibility of the + * caller to verify the return value. + * + * @return IInputType + * @since 3.0 + */ + public IInputType getPrimaryInputType(); + + /** + * Returns all of the additional input resources of all InputType children. + * Note: This does not include the primary InputType and does not include + * additional dependencies. + * + * @return IPath[] + */ + public IPath[] getAdditionalResources(); + + /** + * Returns all of the additional dependency resources of all InputType children. + * Note: This does not include the primary InputType and does not include + * additional inputs. + * + * @return IPath[] + */ + public IPath[] getAdditionalDependencies(); + + /** + * Creates a child OutputType for this tool. + * + * @param OutputType The superClass, if any + * @param String The id for the new OutputType + * @param String The name for the new OutputType + * @param boolean Indicates whether this is an extension element or a managed project element + * + * @return IOutputType + * @since 3.0 + */ + public IOutputType createOutputType(IOutputType superClass, String Id, String name, boolean isExtensionElement); + + /** + * Removes an OutputType from the tool's list. + * + * @param type + * @since 3.0 + */ + public void removeOutputType(IOutputType type); + + /** + * Returns the complete list of output types that are available for this tool. + * The list is a merging of the output types specified for this tool with the + * output types of its superclasses. The lowest output type instance in the hierarchy + * takes precedence. + * + * @return IOutputType[] + * @since 3.0 + */ + public IOutputType[] getOutputTypes(); + /** + * Get the IOutputType in the receiver with the specified + * ID. This is an efficient search in the receiver. + * + *

If the receiver does not have an OutputType with that ID, the method + * returns null. It is the responsibility of the caller to + * verify the return value. + * + * @param id unique identifier of the OutputType to search for + * @return IOutputType + * @since 3.0 + */ + public IOutputType getOutputTypeById(String id); + + /** + * Returns the IOutputType in the tool that creates the + * specified extension. + * + *

If the receiver does not have an OutputType that creates the extension, + * the method returns null. It is the responsibility of the + * caller to verify the return value. + * + * @param outputExtension File extension + * @return IOutputType + * @since 3.0 + */ + public IOutputType getOutputType(String outputExtension); + + /** + * Returns the primary IOutputType in this tool + * + *

If the receiver has no OutputTypes, + * the method returns null. It is the responsibility of the + * caller to verify the return value. + * + * @return IOutputType + * @since 3.0 + */ + public IOutputType getPrimaryOutputType(); + + /** + * Returns the ITool that is the superclass of this + * tool, or null if the attribute was not specified. + * + * @return ITool + */ + public ITool getSuperClass(); + + /** + * Returns whether this element is abstract. Returns false + * if the attribute was not specified. + * @return boolean + */ + public boolean isAbstract(); + + /** + * Sets the isAbstract attribute of the tool-chain. + * + * @param b + */ + public void setIsAbstract(boolean b); + + /** + * Returns a semi-colon delimited list of child Ids of the superclass' + * children that should not be automatically inherited by this element. + * Returns an empty string if the attribute was not specified. + * @return String + */ + public String getUnusedChildren(); + + /** + * Returns the semicolon separated list of unique IDs of the error parsers associated + * with the tool. + * + * @return String + */ + public String getErrorParserIds(); + + /** + * Returns the ordered list of unique IDs of the error parsers associated with the + * tool. + * + * @return String[] + */ + public String[] getErrorParserList(); + + /** + * Sets the semicolon separated list of error parser ids + * + * @param ids + */ + public void setErrorParserIds(String ids); + + /** + * Returns the list of valid source extensions this tool knows how to build. + * The list may be empty but will never be null. + * + * @return List + * @deprecated - use getPrimaryInputExtensions or getAllInputExtensions + */ + public List getInputExtensions(); + + /** + * Returns the array of valid primary source extensions this tool knows how to build. + * The array may be empty but will never be null. + * + * @return String[] + */ + public String[] getPrimaryInputExtensions(); + + /** + * Returns the array of all valid source extensions this tool knows how to build. + * The array may be empty but will never be null. + * + * @return String[] + */ + public String[] getAllInputExtensions(); + + /** + * Returns the default input extension for the primary input of the tool + * + * @return String + */ + public String getDefaultInputExtension(); + + /** + * Returns the array of all valid dependency extensions for this tool's inputs. + * The array may be empty but will never be null. + * + * @return String[] + */ + public String[] getAllDependencyExtensions(); + + /** + * Returns the list of valid header extensions for this tool. + * Returns the value of the headerExtensions attribute + * The list may be empty but will never be null. + * + * @return List + * @deprecated - use getDependency* methods + */ + public List getInterfaceExtensions(); + + /** + * Answers a constant corresponding to the project nature the tool should be used + * for. Possible answers are: + * + *

+ *
ITool.FILTER_C + *
The tool should only be displayed for C projects. Notes: even + * though a C++ project has a C nature, this flag will mask the tool for C++ + * projects. + *
ITool.FILTER_CC + *
The tool should only be displayed for C++ projects. + *
ITool.FILTER_BOTH + *
The tool should be displayed for projects with both natures. + *
+ * + * @return int + */ + public int getNatureFilter(); + + /** + * Returns the array of all valid output extensions this tool can create. + * The array may be empty but will never be null. + * + * @return String[] + */ + public String[] getAllOutputExtensions(); + + /** + * Answers all of the output extensions that the receiver can build. + * This routine returns the value if the outputs attribute. + * + * @return String[] of extensions + * @deprecated - use getAllOutputExtensions + */ + public String[] getOutputExtensions(); + + /** + * Answers all of the output extensions that the receiver can build, + * from the value of the outputs attribute + * + * @return String[] of extensions + */ + public String[] getOutputsAttribute(); + + /** + * Answer the output extension the receiver will create from the input, + * or null if the tool does not understand that extension. + * + * @param inputExtension The extension of the source file. + * @return String + */ + public String getOutputExtension(String inputExtension); + + /** + * Sets all of the output extensions that the receiver can build, + * into the outputs attribute. Note that the outputs attribute is + * ignored when one or more outputTypes are specified. + * + * @param String + */ + public void setOutputsAttribute(String extensions); + + /** + * Answers the argument that must be passed to a specific tool in order to + * control the name of the output artifact. For example, the GCC compile and + * linker use '-o', while the archiver does not. + * + * @return String + */ + public String getOutputFlag(); + + /** + * Sets the argument that must be passed to a specific tool in order to + * control the name of the output artifact. For example, the GCC compile and + * linker use '-o', while the archiver does not. + * + * @param String + */ + public void setOutputFlag(String flag); + + /** + * 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 + * @return String + */ + public String getOutputPrefix(); + + /** + * Sets 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 + * @param String + */ + public void setOutputPrefix(String prefix); + + /** + * Returns true if the Tool wants the MBS to display the Advanced + * Input category that allows the user to specify additional input resources and + * dependencies, else false. + * + * @return boolean + */ + public boolean getAdvancedInputCategory(); + + /** + * Sets whether the Tool wants the MBS to display the Advanced + * Input category that allows the user to specify additional input resources and + * dependencies. + * + * @param display + */ + public void setAdvancedInputCategory(boolean display); + + /** + * Returns true if the Tool represents a user-define custom build + * step, else false. + * + * @return boolean + */ + public boolean getCustomBuildStep(); + + /** + * Sets whether the Tool represents a user-define custom build step. + * + * @param customBuildStep + */ + public void setCustomBuildStep(boolean customBuildStep); + + /** + * Returns the announcement string for this tool + * @return String + */ + public String getAnnouncement(); + + /** + * Sets the announcement string for this tool + * @param announcement + */ + public void setAnnouncement(String announcement); + + /** + * Answers the command-line invocation defined for the receiver. + * + * @return String + */ + public String getToolCommand(); + + /** + * Sets the command-line invocation command defined for this tool. + * + * @param String + * + * @return boolean if true, then the tool command was modified + */ + public boolean setToolCommand(String command); + + /** + * Returns command line pattern for this tool + * @return String + */ + public String getCommandLinePattern(); + + /** + * Sets the command line pattern for this tool + * @param String + */ + public void setCommandLinePattern(String pattern); + + /** + * Returns the plugin.xml element of the commandLineGenerator extension or null if none. + * + * @return IConfigurationElement + * + * @deprecated - use getCommandLineGenerator + */ + public IConfigurationElement getCommandLineGeneratorElement(); + + /** + * Sets the CommandLineGenerator plugin.xml element + * + * @param element + * @deprecated + */ + public void setCommandLineGeneratorElement(IConfigurationElement element); + + /** + * Returns the command line generator specified for this tool + * @return IManagedCommandLineGenerator + */ + public IManagedCommandLineGenerator getCommandLineGenerator(); + + /** + * Returns the plugin.xml element of the dependencyGenerator extension or null if none. + * + * @return IConfigurationElement + * @deprecated - use getDependencyGeneratorForExtension or IInputType#getDependencyGenerator method + */ + public IConfigurationElement getDependencyGeneratorElement(); + + /** + * Sets the DependencyGenerator plugin.xml element + * + * @param element + * @deprecated + */ + public void setDependencyGeneratorElement(IConfigurationElement element); + + /** + * Returns a class instance that implements an interface to generate + * source-level dependencies for the tool specified in the argument. + * This method may return null in which case, the receiver + * should assume that the tool does not require dependency information + * when the project is built. + * + * @return IManagedDependencyGenerator + * @deprecated - use getDependencyGeneratorForExtension or IInputType method + */ + public IManagedDependencyGenerator getDependencyGenerator(); + + /** + * Returns a class instance that implements an interface to generate + * source-level dependencies for the tool specified in the argument. + * This method may return null in which case, the receiver + * should assume that the tool does not require dependency information + * when the project is built. + * + * @param sourceExt source file extension + * @return IManagedDependencyGeneratorType + */ + public IManagedDependencyGeneratorType getDependencyGeneratorForExtension(String sourceExt); + + /** + * Returns an array of command line arguments that have been specified for + * the tool. + * The flags contain build macros resolved to the makefile format. + * That is if a user has chosen to expand all macros in the buildfile, + * the flags contain all macro references resolved, otherwise, if a user has + * chosen to keep the environment build macros unresolved, the flags contain + * the environment macro references converted to the buildfile variable format, + * all other macro references are resolved + * + * @return String[] + * @throws BuildException + * + * @deprecated - use getToolCommandFlags instead + */ + public String[] getCommandFlags() throws BuildException; + + /** + * Returns the command line arguments that have been specified for + * the tool. + * The string contains build macros resolved to the makefile format. + * That is if a user has chosen to expand all macros in the buildfile, + * the string contains all macro references resolved, otherwise, if a user has + * chosen to keep the environment build macros unresolved, the string contains + * the environment macro references converted to the buildfile variable format, + * all other macro references are resolved + * + * @return String + * + * @deprecated - use getToolCommandFlagsString instead + */ + public String getToolFlags() throws BuildException ; + + /** + * Returns an array of command line arguments that have been specified for + * the tool. + * The flags contain build macros resolved to the makefile format. + * That is if a user has chosen to expand all macros in the buildfile, + * the flags contain all macro references resolved, otherwise, if a user has + * chosen to keep the environment build macros unresolved, the flags contain + * the environment macro references converted to the buildfile variable format, + * all other macro references are resolved + * + * @param inputFileLocation + * @param outputFileLocation + * @return + * @throws BuildException + */ + public String[] getToolCommandFlags(IPath inputFileLocation, IPath outputFileLocation) throws BuildException; + + /** + * Returns the command line arguments that have been specified for + * the tool. + * The string contains build macros resolved to the makefile format. + * That is if a user has chosen to expand all macros in the buildfile, + * the string contains all macro references resolved, otherwise, if a user has + * chosen to keep the environment build macros unresolved, the string contains + * the environment macro references converted to the buildfile variable format, + * all other macro references are resolved + * + * @param inputFileLocation + * @param outputFileLocation + * @return + * @throws BuildException + */ + public String getToolCommandFlagsString(IPath inputFileLocation, IPath outputFileLocation) throws BuildException; + + /** + * Options are organized into categories for UI purposes. + * These categories are organized into a tree. This is the root + * of that tree. + * + * @return IOptionCategory + */ + public IOptionCategory getTopOptionCategory(); + + /** + * Return true if the receiver builds files with the + * specified extension, else false. + * + * @param extension file extension of the source + * @return boolean + */ + public boolean buildsFileType(String extension); + + /** + * Return true if the receiver uses files with the + * specified extension as input, else false. This + * returns true for a superset of the extensions that buildFileType + * returns true for - it includes secondary inputs. + * + * @param extension file extension of the source + * @return boolean + */ + public boolean isInputFileType(String extension); + + /** + * Answers true 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 true if the receiver builds a file with the extension specified + * in the argument, else false. + * + * @param outputExtension extension of the file being produced by a tool + * @return boolean + */ + public boolean producesFileType(String outputExtension); + + /** + * Returns true if this tool has changes that need to + * be saved in the project file, else false. + * + * @return boolean + */ + public boolean isDirty(); + + /** + * Sets the element's "dirty" (have I been modified?) flag. + * + * @param isDirty + */ + public void setDirty(boolean isDirty); + + /** + * Returns true if this tool was loaded from a manifest file, + * and false if it was loaded from a project (.cdtbuild) file. + * + * @return boolean + */ + public boolean isExtensionElement(); + + /** + * Returns the 'versionsSupported' of this tool + * + * @return String + */ + public String getVersionsSupported(); + + /** + * Returns the 'convertToId' of this tool + * + * @return String + */ + public String getConvertToId(); + + /** + * Sets the 'versionsSupported' attribute of the tool. + * + * @param versionsSupported + */ + public void setVersionsSupported(String versionsSupported); + + /** + * Sets the 'convertToId' attribute of the tool. + * + * @param convertToId + */ + public void setConvertToId(String convertToId); + + /** + * Returns an array of the Environment Build Path variable descriptors + * + * @return IEnvVarBuildPath[] + */ + public IEnvVarBuildPath[] getEnvVarBuildPaths(); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java index cbf9e1d0be4..164b5639fe3 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java @@ -1,1441 +1,1450 @@ -/******************************************************************************* - * Copyright (c) 2003, 2005 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.internal.core; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; -import java.util.Vector; - -import org.eclipse.cdt.core.CCProjectNature; -import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.CProjectNature; -import org.eclipse.cdt.managedbuilder.core.BuildException; -import org.eclipse.cdt.managedbuilder.core.IBuilder; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IHoldsOptions; -import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; -import org.eclipse.cdt.managedbuilder.core.IManagedOptionValueHandler; -import org.eclipse.cdt.managedbuilder.core.IManagedProject; -import org.eclipse.cdt.managedbuilder.core.IOption; -import org.eclipse.cdt.managedbuilder.core.IProjectType; -import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.IToolChain; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier; -import org.eclipse.cdt.managedbuilder.internal.envvar.EnvironmentVariableProvider; -import org.eclipse.cdt.managedbuilder.internal.envvar.UserDefinedEnvironmentSupplier; -import org.eclipse.cdt.managedbuilder.internal.macros.BuildMacroProvider; -import org.eclipse.cdt.managedbuilder.internal.macros.UserDefinedMacroSupplier; -import org.eclipse.cdt.managedbuilder.macros.IConfigurationBuildMacroSupplier; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.PluginVersionIdentifier; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -public class Configuration extends BuildObject implements IConfiguration { - - private static final String EMPTY_STRING = new String(); - - // Parent and children - private IConfiguration parent; - private ProjectType projectType; - private ManagedProject managedProject; - private ToolChain toolChain; - private List resourceConfigurationList; - private Map resourceConfigurationMap; - // Managed Build model attributes - private String artifactName; - private String cleanCommand; - private String artifactExtension; - private String errorParserIds; - private String prebuildStep; - private String postbuildStep; - private String preannouncebuildStep; - private String postannouncebuildStep; - private String description; - // Miscellaneous - private boolean isExtensionConfig = false; - private boolean isDirty = false; - private boolean rebuildNeeded = false; - private boolean resolved = true; - private boolean isTemporary = false; - - - /* - * C O N S T R U C T O R S - */ - - /** - * Create an extension configuration from the project manifest file element. - * - * @param projectType The ProjectType the configuration will be added to. - * @param element The element from the manifest that contains the configuration information. - * @param managedBuildRevision - */ - public Configuration(ProjectType projectType, IManagedConfigElement element, String managedBuildRevision) { - this.projectType = projectType; - isExtensionConfig = true; - - // setup for resolving - resolved = false; - - setManagedBuildRevision(managedBuildRevision); - - // Initialize from the XML attributes - loadFromManifest(element); - - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionConfiguration(this); - - // Hook me up to the ProjectType - if (projectType != null) { - projectType.addConfiguration(this); - } - - // Load the children - IManagedConfigElement[] configElements = element.getChildren(); - for (int l = 0; l < configElements.length; ++l) { - IManagedConfigElement configElement = configElements[l]; - if (configElement.getName().equals(IToolChain.TOOL_CHAIN_ELEMENT_NAME)) { - toolChain = new ToolChain(this, configElement, managedBuildRevision); - }else if (configElement.getName().equals(IResourceConfiguration.RESOURCE_CONFIGURATION_ELEMENT_NAME)) { - ResourceConfiguration resConfig = new ResourceConfiguration(this, configElement, managedBuildRevision); - addResourceConfiguration(resConfig); - } - } - } - - /** - * Create a new extension configuration based on one already defined. - * - * @param projectType The ProjectType the configuration will be added to. - * @param parentConfig The IConfiguration that is the parent configuration of this configuration - * @param id A unique ID for the new configuration. - */ - public Configuration(ProjectType projectType, IConfiguration parentConfig, String id) { - setId(id); - this.projectType = projectType; - isExtensionConfig = true; - - // setup for resolving - resolved = false; - - if (parentConfig != null) { - name = parentConfig.getName(); - // If this contructor is called to clone an existing - // configuration, the parent of the parent should be stored. - // As of 2.1, there is still one single level of inheritence to - // worry about - parent = parentConfig.getParent() == null ? parentConfig : parentConfig.getParent(); - } - - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionConfiguration(this); - - // Hook me up to the ProjectType - if (projectType != null) { - projectType.addConfiguration(this); - // set managedBuildRevision - setManagedBuildRevision(projectType.getManagedBuildRevision()); - } - } - - /** - * Create a new extension configuration and fill in the attributes and childen later. - * - * @param projectType The ProjectType the configuration will be added to. - * @param parentConfig The IConfiguration that is the parent configuration of this configuration - * @param id A unique ID for the new configuration. - * @param name A name for the new configuration. - */ - public Configuration(ProjectType projectType, IConfiguration parentConfig, String id, String name) { - setId(id); - setName(name); - this.projectType = projectType; - parent = parentConfig; - isExtensionConfig = true; - - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionConfiguration(this); - - // Hook me up to the ProjectType - if (projectType != null) { - projectType.addConfiguration(this); - setManagedBuildRevision(projectType.getManagedBuildRevision()); - } - } - - /** - * Create a Configuration based on the specification stored in the - * project file (.cdtbuild). - * - * @param managedProject The ManagedProject the configuration will be added to. - * @param element The XML element that contains the configuration settings. - * - */ - public Configuration(ManagedProject managedProject, Element element, String managedBuildRevision) { - this.managedProject = managedProject; - isExtensionConfig = false; - - setManagedBuildRevision(managedBuildRevision); - - // Initialize from the XML attributes - loadFromProject(element); - - // Hook me up - managedProject.addConfiguration(this); - - NodeList configElements = element.getChildNodes(); - for (int i = 0; i < configElements.getLength(); ++i) { - Node configElement = configElements.item(i); - if (configElement.getNodeName().equals(IToolChain.TOOL_CHAIN_ELEMENT_NAME)) { - toolChain = new ToolChain(this, (Element)configElement, managedBuildRevision); - }else if (configElement.getNodeName().equals(IResourceConfiguration.RESOURCE_CONFIGURATION_ELEMENT_NAME)) { - ResourceConfiguration resConfig = new ResourceConfiguration(this, (Element)configElement, managedBuildRevision); - addResourceConfiguration(resConfig); - } - } - } - - /** - * Create a new project, non-extension, configuration based on one already defined. - * - * @param managedProject The ManagedProject the configuration will be added to. - * @param cloneConfig The IConfiguration to copy the settings from. - * @param id A unique ID for the new configuration. - * @param cloneChildren If true, the configuration's tools are cloned - */ - public Configuration(ManagedProject managedProject, Configuration cloneConfig, String id, boolean cloneChildren, boolean temporary) { - setId(id); - setName(cloneConfig.getName()); - this.description = cloneConfig.getDescription(); - this.managedProject = managedProject; - isExtensionConfig = false; - this.isTemporary = temporary; - - // set managedBuildRevision - setManagedBuildRevision(cloneConfig.getManagedBuildRevision()); - - // If this contructor is called to clone an existing - // configuration, the parent of the cloning config should be stored. - parent = cloneConfig.getParent() == null ? cloneConfig : cloneConfig.getParent(); - - // Copy the remaining attributes - projectType = cloneConfig.projectType; - if (cloneConfig.artifactName != null) { - artifactName = new String(cloneConfig.artifactName); - } - if (cloneConfig.cleanCommand != null) { - cleanCommand = new String(cloneConfig.cleanCommand); - } - if (cloneConfig.artifactExtension != null) { - artifactExtension = new String(cloneConfig.artifactExtension); - } - if (cloneConfig.errorParserIds != null) { - errorParserIds = new String(cloneConfig.errorParserIds); - } - if (cloneConfig.prebuildStep != null) { - prebuildStep = new String(cloneConfig.prebuildStep); - } - if (cloneConfig.postbuildStep != null) { - postbuildStep = new String(cloneConfig.postbuildStep); - } - if (cloneConfig.preannouncebuildStep != null) { - preannouncebuildStep = new String(cloneConfig.preannouncebuildStep); - } - if (cloneConfig.postannouncebuildStep != null) { - postannouncebuildStep = new String(cloneConfig.postannouncebuildStep); - } - - // Clone the configuration's children - // Tool Chain - String subId; - String subName; - if (cloneConfig.parent != null) { - subId = ManagedBuildManager.calculateChildId( - cloneConfig.parent.getToolChain().getId(), - null); - subName = cloneConfig.parent.getToolChain().getName(); - - } else { - subId = ManagedBuildManager.calculateChildId( - cloneConfig.getToolChain().getId(), - null); - subName = cloneConfig.getToolChain().getName(); - } - - if (cloneChildren) { - toolChain = new ToolChain(this, subId, subName, (ToolChain)cloneConfig.getToolChain()); - - //copy expand build macros setting - BuildMacroProvider macroProvider = (BuildMacroProvider)ManagedBuildManager.getBuildMacroProvider(); - macroProvider.expandMacrosInBuildfile(this, - macroProvider.areMacrosExpandedInBuildfile(cloneConfig)); - - //copy user-defined build macros - UserDefinedMacroSupplier userMacros = BuildMacroProvider.fUserDefinedMacroSupplier; - userMacros.setMacros( - userMacros.getMacros(BuildMacroProvider.CONTEXT_CONFIGURATION,cloneConfig), - BuildMacroProvider.CONTEXT_CONFIGURATION, - this); - - //copy user-defined environment - UserDefinedEnvironmentSupplier userEnv = EnvironmentVariableProvider.fUserSupplier; - userEnv.setVariables( - userEnv.getVariables(cloneConfig), this); - - } else { - // Add a tool-chain element that specifies as its superClass the - // tool-chain that is the child of the configuration. - ToolChain superChain = (ToolChain)cloneConfig.getToolChain(); - subId = ManagedBuildManager.calculateChildId( - superChain.getId(), - null); - IToolChain newChain = createToolChain(superChain, subId, superChain.getName(), false); - - // For each option/option category child of the tool-chain that is - // the child of the selected configuration element, create an option/ - // option category child of the cloned configuration's tool-chain element - // that specifies the original tool element as its superClass. - newChain.createOptions(superChain); - - // For each tool element child of the tool-chain that is the child of - // the selected configuration element, create a tool element child of - // the cloned configuration's tool-chain element that specifies the - // original tool element as its superClass. - ITool[] tools = superChain.getTools(); - for (int i=0; iProjectType the configuration will be added to. + * @param element The element from the manifest that contains the configuration information. + * @param managedBuildRevision + */ + public Configuration(ProjectType projectType, IManagedConfigElement element, String managedBuildRevision) { + this.projectType = projectType; + isExtensionConfig = true; + + // setup for resolving + resolved = false; + + setManagedBuildRevision(managedBuildRevision); + + // Initialize from the XML attributes + loadFromManifest(element); + + // Hook me up to the Managed Build Manager + ManagedBuildManager.addExtensionConfiguration(this); + + // Hook me up to the ProjectType + if (projectType != null) { + projectType.addConfiguration(this); + } + + // Load the children + IManagedConfigElement[] configElements = element.getChildren(); + for (int l = 0; l < configElements.length; ++l) { + IManagedConfigElement configElement = configElements[l]; + if (configElement.getName().equals(IToolChain.TOOL_CHAIN_ELEMENT_NAME)) { + toolChain = new ToolChain(this, configElement, managedBuildRevision); + }else if (configElement.getName().equals(IResourceConfiguration.RESOURCE_CONFIGURATION_ELEMENT_NAME)) { + ResourceConfiguration resConfig = new ResourceConfiguration(this, configElement, managedBuildRevision); + addResourceConfiguration(resConfig); + } + } + } + + /** + * Create a new extension configuration based on one already defined. + * + * @param projectType The ProjectType the configuration will be added to. + * @param parentConfig The IConfiguration that is the parent configuration of this configuration + * @param id A unique ID for the new configuration. + */ + public Configuration(ProjectType projectType, IConfiguration parentConfig, String id) { + setId(id); + this.projectType = projectType; + isExtensionConfig = true; + + // setup for resolving + resolved = false; + + if (parentConfig != null) { + name = parentConfig.getName(); + // If this contructor is called to clone an existing + // configuration, the parent of the parent should be stored. + // As of 2.1, there is still one single level of inheritence to + // worry about + parent = parentConfig.getParent() == null ? parentConfig : parentConfig.getParent(); + } + + // Hook me up to the Managed Build Manager + ManagedBuildManager.addExtensionConfiguration(this); + + // Hook me up to the ProjectType + if (projectType != null) { + projectType.addConfiguration(this); + // set managedBuildRevision + setManagedBuildRevision(projectType.getManagedBuildRevision()); + } + } + + /** + * Create a new extension configuration and fill in the attributes and childen later. + * + * @param projectType The ProjectType the configuration will be added to. + * @param parentConfig The IConfiguration that is the parent configuration of this configuration + * @param id A unique ID for the new configuration. + * @param name A name for the new configuration. + */ + public Configuration(ProjectType projectType, IConfiguration parentConfig, String id, String name) { + setId(id); + setName(name); + this.projectType = projectType; + parent = parentConfig; + isExtensionConfig = true; + + // Hook me up to the Managed Build Manager + ManagedBuildManager.addExtensionConfiguration(this); + + // Hook me up to the ProjectType + if (projectType != null) { + projectType.addConfiguration(this); + setManagedBuildRevision(projectType.getManagedBuildRevision()); + } + } + + /** + * Create a Configuration based on the specification stored in the + * project file (.cdtbuild). + * + * @param managedProject The ManagedProject the configuration will be added to. + * @param element The XML element that contains the configuration settings. + * + */ + public Configuration(ManagedProject managedProject, Element element, String managedBuildRevision) { + this.managedProject = managedProject; + isExtensionConfig = false; + + setManagedBuildRevision(managedBuildRevision); + + // Initialize from the XML attributes + loadFromProject(element); + + // Hook me up + managedProject.addConfiguration(this); + + NodeList configElements = element.getChildNodes(); + for (int i = 0; i < configElements.getLength(); ++i) { + Node configElement = configElements.item(i); + if (configElement.getNodeName().equals(IToolChain.TOOL_CHAIN_ELEMENT_NAME)) { + toolChain = new ToolChain(this, (Element)configElement, managedBuildRevision); + }else if (configElement.getNodeName().equals(IResourceConfiguration.RESOURCE_CONFIGURATION_ELEMENT_NAME)) { + ResourceConfiguration resConfig = new ResourceConfiguration(this, (Element)configElement, managedBuildRevision); + addResourceConfiguration(resConfig); + } + } + } + + /** + * Create a new project, non-extension, configuration based on one already defined. + * + * @param managedProject The ManagedProject the configuration will be added to. + * @param cloneConfig The IConfiguration to copy the settings from. + * @param id A unique ID for the new configuration. + * @param cloneChildren If true, the configuration's tools are cloned + */ + public Configuration(ManagedProject managedProject, Configuration cloneConfig, String id, boolean cloneChildren, boolean temporary) { + setId(id); + setName(cloneConfig.getName()); + this.description = cloneConfig.getDescription(); + this.managedProject = managedProject; + isExtensionConfig = false; + this.isTemporary = temporary; + + // set managedBuildRevision + setManagedBuildRevision(cloneConfig.getManagedBuildRevision()); + + // If this contructor is called to clone an existing + // configuration, the parent of the cloning config should be stored. + parent = cloneConfig.getParent() == null ? cloneConfig : cloneConfig.getParent(); + + // Copy the remaining attributes + projectType = cloneConfig.projectType; + if (cloneConfig.artifactName != null) { + artifactName = new String(cloneConfig.artifactName); + } + if (cloneConfig.cleanCommand != null) { + cleanCommand = new String(cloneConfig.cleanCommand); + } + if (cloneConfig.artifactExtension != null) { + artifactExtension = new String(cloneConfig.artifactExtension); + } + if (cloneConfig.errorParserIds != null) { + errorParserIds = new String(cloneConfig.errorParserIds); + } + if (cloneConfig.prebuildStep != null) { + prebuildStep = new String(cloneConfig.prebuildStep); + } + if (cloneConfig.postbuildStep != null) { + postbuildStep = new String(cloneConfig.postbuildStep); + } + if (cloneConfig.preannouncebuildStep != null) { + preannouncebuildStep = new String(cloneConfig.preannouncebuildStep); + } + if (cloneConfig.postannouncebuildStep != null) { + postannouncebuildStep = new String(cloneConfig.postannouncebuildStep); + } + + // Clone the configuration's children + // Tool Chain + String subId; + String subName; + if (cloneConfig.parent != null) { + subId = ManagedBuildManager.calculateChildId( + cloneConfig.parent.getToolChain().getId(), + null); + subName = cloneConfig.parent.getToolChain().getName(); + + } else { + subId = ManagedBuildManager.calculateChildId( + cloneConfig.getToolChain().getId(), + null); + subName = cloneConfig.getToolChain().getName(); + } + + if (cloneChildren) { + toolChain = new ToolChain(this, subId, subName, (ToolChain)cloneConfig.getToolChain()); + + //copy expand build macros setting + BuildMacroProvider macroProvider = (BuildMacroProvider)ManagedBuildManager.getBuildMacroProvider(); + macroProvider.expandMacrosInBuildfile(this, + macroProvider.areMacrosExpandedInBuildfile(cloneConfig)); + + //copy user-defined build macros + UserDefinedMacroSupplier userMacros = BuildMacroProvider.fUserDefinedMacroSupplier; + userMacros.setMacros( + userMacros.getMacros(BuildMacroProvider.CONTEXT_CONFIGURATION,cloneConfig), + BuildMacroProvider.CONTEXT_CONFIGURATION, + this); + + //copy user-defined environment + UserDefinedEnvironmentSupplier userEnv = EnvironmentVariableProvider.fUserSupplier; + userEnv.setVariables( + userEnv.getVariables(cloneConfig), this); + + } else { + // Add a tool-chain element that specifies as its superClass the + // tool-chain that is the child of the configuration. + ToolChain superChain = (ToolChain)cloneConfig.getToolChain(); + subId = ManagedBuildManager.calculateChildId( + superChain.getId(), + null); + IToolChain newChain = createToolChain(superChain, subId, superChain.getName(), false); + + // For each option/option category child of the tool-chain that is + // the child of the selected configuration element, create an option/ + // option category child of the cloned configuration's tool-chain element + // that specifies the original tool element as its superClass. + newChain.createOptions(superChain); + + // For each tool element child of the tool-chain that is the child of + // the selected configuration element, create a tool element child of + // the cloned configuration's tool-chain element that specifies the + // original tool element as its superClass. + ITool[] tools = superChain.getTools(); + for (int i=0; i 0) - name = resolved; - } catch (BuildMacroException e){ - } - - if (ext.length() > 0) { - buildGoalName = buildInfo.getOutputPrefix(ext) + name + IManagedBuilderMakefileGenerator.DOT + ext; - } else { - buildGoalName = name; - } - reservedNames = Arrays.asList(new String[]{".cdtbuild", ".cdtproject", ".project"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - - /** - * @param changedResource - * @return - */ - private boolean isGeneratedResource(IResource resource) { - // Is this a generated directory ... - IPath path = resource.getProjectRelativePath(); - String[] configNames = buildInfo.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; - } - - /** - * @param resource - * @return - */ - private boolean isProjectFile(IResource resource) { - return reservedNames.contains(resource.getName()); - } - - public boolean shouldBuildIncr() { - return incrBuildNeeded; - } - - public boolean shouldBuildFull() { - return fullBuildNeeded; - } - - 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()) { - IResourceDelta[] kids = delta.getAffectedChildren(); - for (int index = kids.length - 1; index >= 0; --index) { - IResource changedResource = kids[index].getResource(); - if (changedResource instanceof IFolder) { - return true; - } else { - String name = changedResource.getName(); - if ((!name.equals(buildGoalName) && - // TODO: Also need to check for secondary outputs - (changedResource.isDerived() || - (isProjectFile(changedResource)) || - (isGeneratedResource(changedResource))))) { - // The resource that changed has attributes which make it uninteresting, - // so don't do anything - ; - } - else { - // TODO: Should we do extra checks here to determine if a build is really needed, - // or do you just do exclusion checks like above? - // We could check for: - // o The build goal name - // o A secondary output - // o An input file to a tool: - // o Has an extension of a source file used by a tool - // o Has an extension of a header file used by a tool - // o Has the name of an input file specified in an InputType via: - // o An Option - // o An AdditionalInput - // - //if (resourceName.equals(buildGoalName) || - // (buildInfo.buildsFileType(ext) || buildInfo.isHeaderFile(ext))) { - - // We need to do an incremental build, at least - incrBuildNeeded = true; - if (kids[index].getKind() == IResourceDelta.REMOVED) { - // If a meaningful resource was removed, then force a full build - // This is required because an incremental build will trigger make to - // do nothing for a missing source, since the state after the file - // removal is uptodate, as far as make is concerned - // A full build will clean, and ultimately trigger a relink without - // the object generated from the deleted source, which is what we want - fullBuildNeeded = true; - // There is no point in checking anything else since we have - // decided to do a full build anyway - break; - } - - //} - } - } - } - return false; - } - return true; - } - } - - // String constants - private static final String BUILD_ERROR = "ManagedMakeBuilder.message.error"; //$NON-NLS-1$ - private static final String BUILD_FINISHED = "ManagedMakeBuilder.message.finished"; //$NON-NLS-1$ - private static final String CONSOLE_HEADER = "ManagedMakeBuilder.message.console.header"; //$NON-NLS-1$ - private static final String ERROR_HEADER = "GeneratedmakefileBuilder error ["; //$NON-NLS-1$ - private static final String MAKE = "ManagedMakeBuilder.message.make"; //$NON-NLS-1$ - private static final String MARKERS = "ManagedMakeBuilder.message.creating.markers"; //$NON-NLS-1$ - private static final String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$ - private static final String NOTHING_BUILT = "ManagedMakeBuilder.message.no.build"; //$NON-NLS-1$ - private static final String REFRESH = "ManagedMakeBuilder.message.updating"; //$NON-NLS-1$ - private static final String REFRESH_ERROR = BUILD_ERROR + ".refresh"; //$NON-NLS-1$ - private static final String TRACE_FOOTER = "]: "; //$NON-NLS-1$ - private static final String TRACE_HEADER = "GeneratedmakefileBuilder trace ["; //$NON-NLS-1$ - private static final String TYPE_CLEAN = "ManagedMakeBuilder.type.clean"; //$NON-NLS-1$ - private static final String TYPE_INC = "ManagedMakeBuider.type.incremental"; //$NON-NLS-1$ - private static final String WARNING_UNSUPPORTED_CONFIGURATION = "ManagedMakeBuilder.warning.unsupported.configuration"; //$NON-NLS-1$ - public static boolean VERBOSE = false; - - // Local variables - protected Vector generationProblems; - protected IProject[] referencedProjects; - protected List resourcesToBuild; - public static void outputTrace(String resourceName, String message) { - if (VERBOSE) { - System.out.println(TRACE_HEADER + resourceName + TRACE_FOOTER + message + NEWLINE); - } - } - - public static void outputError(String resourceName, String message) { - if (VERBOSE) { - System.err.println(ERROR_HEADER + resourceName + TRACE_FOOTER + message + NEWLINE); - } - } - - /** - * Zero-argument constructor needed to fulfill the contract of an - * incremental builder. - */ - 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) - * Emits a message to the console indicating that there were no source files to build - * @param buildType - * @param status - * @param configName - */ - private void emitNoSourceMessage(int buildType, IStatus status, String configName) throws CoreException { - try { - StringBuffer buf = new StringBuffer(); - IConsole console = CCorePlugin.getDefault().getConsole(); - console.start(getProject()); - ConsoleOutputStream consoleOutStream = console.getOutputStream(); - // Report a successful clean - String[] consoleHeader = new String[3]; - if (buildType == FULL_BUILD || buildType == INCREMENTAL_BUILD) { - consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_INC); - } else { - consoleHeader[0] = new String(); - outputError(getProject().getName(), "The given build type is not supported in this context"); //$NON-NLS-1$ - } - consoleHeader[1] = configName; - consoleHeader[2] = getProject().getName(); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ - buf.append(ManagedMakeMessages.getFormattedString(CONSOLE_HEADER, consoleHeader)); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ - buf.append(status.getMessage()); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ - consoleOutStream.write(buf.toString().getBytes()); - consoleOutStream.flush(); - consoleOutStream.close(); - } catch (CoreException e) { - // Throw the exception back to the builder - throw e; - } catch (IOException io) { // Ignore console failures... - } - } - - /** - * - * This method has been created so that subclasses can override how the builder obtains its - * build info. The default implementation retrieves the info from the build manager. - * - * @return An IManagedBuildInfo object representing the build info. - */ - protected IManagedBuildInfo getBuildInfo() { - return ManagedBuildManager.getBuildInfo(getProject()); - } - - /* (non-Javadoc) - * @see org.eclipse.core.internal.events.InternalBuilder#build(int, java.util.Map, org.eclipse.core.runtime.IProgressMonitor) - */ - protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException { - // We should always tell the build system what projects we reference - referencedProjects = getProject().getReferencedProjects(); - - // Get the build information - IManagedBuildInfo info = getBuildInfo(); - if (info == null) { - outputError(getProject().getName(), "Build information was not found"); //$NON-NLS-1$ - return referencedProjects; - } - if (!info.isValid()) { - outputError(getProject().getName(), "Build information is not valid"); //$NON-NLS-1$ - return referencedProjects; - } - - // Create a makefile generator for the build - IManagedBuilderMakefileGenerator generator = ManagedBuildManager.getBuildfileGenerator(info.getDefaultConfiguration()); - generator.initialize(getProject(), info, monitor); - - // So let's figure out why we got called - if (kind == FULL_BUILD || info.needsRebuild()) { - outputTrace(getProject().getName(), "Full build needed/requested"); //$NON-NLS-1$ - fullBuild(info, generator, monitor); - } - else if (kind == AUTO_BUILD && info.needsRebuild()) { - outputTrace(getProject().getName(), "Autobuild requested, full build needed"); //$NON-NLS-1$ - fullBuild(info, generator, monitor); - } - else { - // Create a delta visitor to make sure we should be rebuilding - ResourceDeltaVisitor visitor = new ResourceDeltaVisitor(info); - IResourceDelta delta = getDelta(getProject()); - if (delta == null) { - outputTrace(getProject().getName(), "Incremental build requested, full build needed"); //$NON-NLS-1$ - fullBuild(info, generator, monitor); - } - else { - delta.accept(visitor); - if (visitor.shouldBuildFull()) { - outputTrace(getProject().getName(), "Incremental build requested, full build needed"); //$NON-NLS-1$ - fullBuild(info, generator, monitor); - } else if (visitor.shouldBuildIncr()) { - outputTrace(getProject().getName(), "Incremental build requested"); //$NON-NLS-1$ - incrementalBuild(delta, info, generator, monitor); - } - else if (referencedProjects != null) { - // Also check to see is any of the dependent projects changed - for (int i=0; iOperationCanceledException. - * - * @see org.eclipse.core.runtime.OperationCanceledException#OperationCanceledException() - */ - public void checkCancel(IProgressMonitor monitor) { - if (monitor != null && monitor.isCanceled()) { - outputTrace(getProject().getName(), "Build cancelled"); //$NON-NLS-1$ - forgetLastBuiltState(); - throw new OperationCanceledException(); - } - } - - /* (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 = getBuildInfo(); - if (info == null) { - outputError(getProject().getName(), "Build information was not found"); //$NON-NLS-1$ - return; - } - if (!info.isValid()) { - outputError(getProject().getName(), "Build information is not valid"); //$NON-NLS-1$ - return; - } - IPath buildDirPath = getProject().getLocation().append(info.getConfigurationName()); - IWorkspace workspace = CCorePlugin.getWorkspace(); - IContainer buildDir = workspace.getRoot().getContainerForLocation(buildDirPath); - if (buildDir == null || !buildDir.isAccessible()){ - outputError(buildDir.getName(), "Could not delete the build directory"); //$NON-NLS-1$ - return; - } - String status; - try { - // try the brute force approach first - status = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.clean.deleting.output", buildDir.getName()); //$NON-NLS-1$ - monitor.subTask(status); - workspace.delete(new IResource[]{buildDir}, true, monitor); - StringBuffer buf = new StringBuffer(); - // write to the console - IConsole console = CCorePlugin.getDefault().getConsole(); - console.start(getProject()); - ConsoleOutputStream consoleOutStream = console.getOutputStream(); - String[] consoleHeader = new String[3]; - consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_CLEAN); - consoleHeader[1] = info.getConfigurationName(); - consoleHeader[2] = getProject().getName(); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ - buf.append(ManagedMakeMessages.getFormattedString(CONSOLE_HEADER, consoleHeader)); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ - consoleOutStream.write(buf.toString().getBytes()); - consoleOutStream.flush(); - buf = new StringBuffer(); - // Report a successful clean - String successMsg = ManagedMakeMessages.getFormattedString(BUILD_FINISHED, getProject().getName()); - buf.append(successMsg); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ - consoleOutStream.write(buf.toString().getBytes()); - consoleOutStream.flush(); - consoleOutStream.close(); - } catch (CoreException e) { - // Create a makefile generator for the build - status = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.clean.build.clean", buildDir.getName()); //$NON-NLS-1$ - monitor.subTask(status); - IManagedBuilderMakefileGenerator generator = ManagedBuildManager.getBuildfileGenerator(info.getDefaultConfiguration()); - generator.initialize(getProject(), info, monitor); - cleanBuild(info, generator, monitor); - } catch (IOException io) {} // Ignore console failures... - } - - /* (non-Javadoc) - * @param info - * @param generator - * @param monitor - */ - protected void cleanBuild(IManagedBuildInfo info, IManagedBuilderMakefileGenerator generator, IProgressMonitor monitor) { - // Make sure that there is a top level directory and a set of makefiles - IPath buildDir = generator.getBuildWorkingDir(); - if (buildDir == null) { - buildDir = new Path(info.getConfigurationName()); - } - IPath makefilePath = getProject().getLocation().append(buildDir.append(generator.getMakefileName())); - IWorkspaceRoot root = CCorePlugin.getWorkspace().getRoot(); - IFile makefile = root.getFileForLocation(makefilePath); - - if (buildDir != null && makefile != null && makefile.isAccessible()) { - // invoke make with the clean argument - String statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.starting", getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); - checkCancel(monitor); - invokeMake(CLEAN_BUILD, buildDir, info, generator, monitor); - } - } - - /* (non-Javadoc) - * @param info - * @param generator - * @param monitor - */ - protected void fullBuild(IManagedBuildInfo info, IManagedBuilderMakefileGenerator generator, IProgressMonitor monitor) throws CoreException { - // Always need one of these bad boys - if (monitor == null) { - monitor = new NullProgressMonitor(); - } - - checkCancel(monitor); - //If the previous builder invocation was cancelled, generated files might be corrupted - //in case one or more of the generated makefiles (e.g. dep files) are corrupted, - //the builder invocation might fail because of the possible syntax errors, so e.g. "make clean" will not work - //we need to explicitly clean the generated directories - clean(new SubProgressMonitor(monitor, IProgressMonitor.UNKNOWN)); - - // Regenerate the makefiles for this project - checkCancel(monitor); - String statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.rebuild.makefiles", getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); - //generator = ManagedBuildManager.getBuildfileGenerator(info.getDefaultConfiguration()); - generator.initialize(getProject(), info, monitor); - MultiStatus result = generator.regenerateMakefiles(); - if (result.getCode() == IStatus.WARNING || result.getCode() == IStatus.INFO) { - IStatus[] kids = result.getChildren(); - for (int index = 0; index < kids.length; ++index) { - // One possibility is that there is nothing to build - IStatus status = kids[index]; - if (status.getCode() == IManagedBuilderMakefileGenerator.NO_SOURCE_FOLDERS) { - // Inform the user, via the console, that there is nothing to build - // either because there are no buildable sources files or all potentially - // buildable files have been excluded from build - try { - emitNoSourceMessage(FULL_BUILD, status, info.getConfigurationName()); - } catch (CoreException e) { - // Throw the exception back to the builder - throw e; - } - // Dude, we're done - return; - } else { - // Stick this in the list of stuff to warn the user about - getGenerationProblems().add(status); - } - } - } - - // Now call make - checkCancel(monitor); - statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.starting", getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); - IPath topBuildDir = generator.getBuildWorkingDir(); - if (topBuildDir != null) { - invokeMake(FULL_BUILD, topBuildDir, info, generator, monitor); - } else { - statusMsg = ManagedMakeMessages.getFormattedString(NOTHING_BUILT, getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); - return; - } - - // Now regenerate the dependencies - checkCancel(monitor); - statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.regen.deps", getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); - try { - generator.regenerateDependencies(false); - } catch (CoreException e) { - // Throw the exception back to the builder - throw e; - } - - // Build finished message - statusMsg = ManagedMakeMessages.getFormattedString(BUILD_FINISHED, getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); - } - - /* (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 - * for a build with no custom prebuild/postbuild steps - * - * @param fullBuild - * @return - */ - protected String[] getMakeTargets(int buildType) { - List args = new ArrayList(); - switch (buildType) { - case CLEAN_BUILD: - args.add("clean"); //$NON-NLS-1$ - break; - case FULL_BUILD: - case INCREMENTAL_BUILD: - args.add("all"); //$NON-NLS-1$ - break; - } - return (String[])args.toArray(new String[args.size()]); - } - - /** - * @return - */ - protected List getResourcesToBuild() { - if (resourcesToBuild == null) { - resourcesToBuild = new ArrayList(); - } - return resourcesToBuild; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.resources.ACBuilder#getWorkingDirectory() - */ - public IPath getWorkingDirectory() { - return getProject().getLocation(); - } - - /* (non-Javadoc) - * @param delta - * @param info - * @param monitor - * @throws CoreException - */ - protected void incrementalBuild(IResourceDelta delta, IManagedBuildInfo info, IManagedBuilderMakefileGenerator generator, IProgressMonitor monitor) throws CoreException { - // Need to report status to the user - if (monitor == null) { - monitor = new NullProgressMonitor(); - } - - // Ask the makefile generator to generate any makefiles needed to build delta - checkCancel(monitor); - String statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.update.makefiles", getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); - MultiStatus result = generator.generateMakefiles(delta); - if (result.getCode() == IStatus.WARNING || result.getCode() == IStatus.INFO) { - IStatus[] kids = result.getChildren(); - for (int index = 0; index < kids.length; ++index) { - // One possibility is that there is nothing to build - IStatus status = kids[index]; - if (status.getCode() == IManagedBuilderMakefileGenerator.NO_SOURCE_FOLDERS) { - // Inform the user, via the console, that there is nothing to build - // either because there are no buildable sources files or all potentially - // buildable files have been excluded from build - try { - emitNoSourceMessage(INCREMENTAL_BUILD, status, info.getConfigurationName()); - } catch (CoreException e) { - // Throw the exception back to the builder - throw e; - } - // Dude, we're done - return; - } else { - // Stick this in the list of stuff to warn the user about - getGenerationProblems().add(status); - } - } - } - - // Run the build - checkCancel(monitor); - statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.starting", getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); - IPath buildDir = generator.getBuildWorkingDir(); - if (buildDir != null) { - invokeMake(INCREMENTAL_BUILD, buildDir, info, generator, monitor); - } else { - statusMsg = ManagedMakeMessages.getFormattedString(NOTHING_BUILT, getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); - return; - } - - // Generate the dependencies for all changes - checkCancel(monitor); - statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.updating.deps", getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); - try { - generator.generateDependencies(); - } catch (CoreException e) { - throw e; - } - - // Build finished message - statusMsg = ManagedMakeMessages.getFormattedString(BUILD_FINISHED, getProject().getName()); //$NON-NLS-1$ - monitor.subTask(statusMsg); -} - - /* (non-Javadoc) - * @param buildType - * @param buildDir - * @param info - * @param generator - * @param monitor - */ - protected void invokeMake(int buildType, IPath buildDir, IManagedBuildInfo info, IManagedBuilderMakefileGenerator generator, IProgressMonitor monitor) { - // Get the project and make sure there's a monitor to cancel the build - IProject currentProject = getProject(); - if (monitor == null) { - monitor = new NullProgressMonitor(); - } - - 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.append(generator.getMakefileName()); - if (root.getFileForLocation(makefile) == null) { - return; - } - - // Flag to the user that make is about to be called - String makeCmd = info.getBuildCommand(); - //try to resolve the build macros in the builder command - try{ - String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( - makeCmd, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_CONFIGURATION, - info.getDefaultConfiguration()); - if((resolved = resolved.trim()).length() > 0) - makeCmd = resolved; - } catch (BuildMacroException e){ - } - - IPath makeCommand = new Path(makeCmd); - if (makeCommand != null) { - String[] msgs = new String[2]; - msgs[0] = makeCommand.toString(); - msgs[1] = currentProject.getName(); - monitor.subTask(ManagedMakeMessages.getFormattedString(MAKE, msgs)); - - // Get a build console for the project - StringBuffer buf = new StringBuffer(); - IConsole console = CCorePlugin.getDefault().getConsole(); - console.start(currentProject); - ConsoleOutputStream consoleOutStream = console.getOutputStream(); - String[] consoleHeader = new String[3]; - switch (buildType) { - case FULL_BUILD: - case INCREMENTAL_BUILD: - consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_INC); - break; - case CLEAN_BUILD: - consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_CLEAN); - break; - } - - consoleHeader[1] = info.getConfigurationName(); - consoleHeader[2] = currentProject.getName(); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ - buf.append(ManagedMakeMessages.getFormattedString(CONSOLE_HEADER, consoleHeader)); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ - - IConfiguration cfg = info.getDefaultConfiguration(); - if(!cfg.isSupported()){ - buf.append(ManagedMakeMessages.getFormattedString(WARNING_UNSUPPORTED_CONFIGURATION,new String[] {cfg.getName(),cfg.getToolChain().getName()})); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ - } - consoleOutStream.write(buf.toString().getBytes()); - consoleOutStream.flush(); - - // Remove all markers for this project - removeAllMarkers(currentProject); - - // Get a launcher for the make command - String errMsg = null; - CommandLauncher launcher = new CommandLauncher(); - launcher.showCommand(true); - - // Set the environmennt - IBuildEnvironmentVariable variables[] = ManagedBuildManager.getEnvironmentVariableProvider().getVariables(cfg,true,true); - String[] env = null; - ArrayList envList = new ArrayList(); - if (variables != null) { - for(int i = 0; i < variables.length; i++){ - envList.add(variables[i].getName() + "=" + variables[i].getValue()); //$NON-NLS-1$ - } - env = (String[]) envList.toArray(new String[envList.size()]); - } - - // Hook up an error parser manager - String[] errorParsers = info.getDefaultConfiguration().getErrorParserList(); - ErrorParserManager epm = new ErrorParserManager(getProject(), workingDirectory, this, errorParsers); - epm.setOutputStream(consoleOutStream); - // This variable is necessary to ensure that the EPM stream stay open - // until we explicitly close it. See bug#123302. - OutputStream epmOutputStream = epm.getOutputStream(); - - // Get the arguments to be passed to make from build model - ArrayList makeArgs = new ArrayList(); - String arg = info.getBuildArguments(); - if (arg.length() > 0) { - String[] args = arg.split("\\s"); //$NON-NLS-1$ - for (int i = 0; i < args.length; ++i) { - makeArgs.add(args[i]); - } - } - - String[] makeTargets; - String prebuildStep = info.getPrebuildStep(); - //try to resolve the build macros in the prebuildStep - try{ - prebuildStep = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( - prebuildStep, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_CONFIGURATION, - cfg); - } catch (BuildMacroException e){ - } - boolean prebuildStepPresent = (prebuildStep.length() > 0); - Process proc = null; - boolean isuptodate = false; - - if (prebuildStepPresent) { - ArrayList premakeArgs = (ArrayList) makeArgs.clone(); - String[] premakeTargets; - switch (buildType) { - case INCREMENTAL_BUILD: { - // For an incremental build with a prebuild step: - // Check the status of the main build with "make -q main-build" - // If up to date: - // then: don't invoke the prebuild step, which should be run only if - // something needs to be built in the main build - // else: invoke the prebuild step and the main build step - premakeArgs.add("-q"); //$NON-NLS-1$ - premakeArgs.add("main-build"); //$NON-NLS-1$ - premakeTargets = (String[]) premakeArgs.toArray(new String[premakeArgs.size()]); - proc = launcher.execute(makeCommand, premakeTargets, env, workingDirectory); - if (proc != null) { - try { - // Close the input of the process since we will never write to it - proc.getOutputStream().close(); - } catch (IOException e) { - } - if (launcher.waitAndRead(epm.getOutputStream(), epm.getOutputStream(), - new SubProgressMonitor(monitor, - IProgressMonitor.UNKNOWN)) != CommandLauncher.OK) { - errMsg = launcher.getErrorMessage(); - } - } else { - errMsg = launcher.getErrorMessage(); - } - - if ((errMsg != null && errMsg.length() > 0) || proc == null) { - // Can't tell if the build is needed, so assume it is, and let any errors be triggered - // when the "real" build is invoked below - makeArgs.add("pre-build"); //$NON-NLS-1$ - makeArgs.add("main-build"); //$NON-NLS-1$ - } else { - // The "make -q" command launch was successful - if (proc.exitValue() == 0) { - // If the status value returned from "make -q" is 0, then the build state is up-to-date - isuptodate = true; - // Report that the build was up to date, and thus nothing needs to be built - String uptodateMsg = ManagedMakeMessages - .getFormattedString(NOTHING_BUILT, currentProject.getName()); - buf = new StringBuffer(); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ - buf.append(uptodateMsg); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ - // Write message on the console - consoleOutStream.write(buf.toString().getBytes()); - consoleOutStream.flush(); - epmOutputStream.close(); - consoleOutStream.close(); - } else { - // The status value was other than 0, so press on with the build process - makeArgs.add("pre-build"); //$NON-NLS-1$ - makeArgs.add("main-build"); //$NON-NLS-1$ - } - } - break; - } - case FULL_BUILD: { - makeArgs.add("clean"); //$NON-NLS-1$ - makeArgs.add("pre-build"); //$NON-NLS-1$ - makeArgs.add("main-build"); //$NON-NLS-1$ - break; - } - case CLEAN_BUILD: { - makeArgs.add("clean"); //$NON-NLS-1$ - break; - } - } - - } else { - // No prebuild step - // - makeArgs.addAll(Arrays.asList(getMakeTargets(buildType))); - } - - makeTargets = (String[]) makeArgs.toArray(new String[makeArgs.size()]); - - // Launch make - main invocation - if (!isuptodate) { - proc = launcher.execute(makeCommand, makeTargets, env, - workingDirectory); - if (proc != null) { - try { - // Close the input of the process since we will never write to it - proc.getOutputStream().close(); - } catch (IOException e) { - } - - if (launcher.waitAndRead(epm.getOutputStream(), epm.getOutputStream(), - new SubProgressMonitor(monitor, - IProgressMonitor.UNKNOWN)) != CommandLauncher.OK) { - errMsg = launcher.getErrorMessage(); - } - - // Force a resync of the projects without allowing the user to cancel. - // This is probably unkind, but short of this there is no way to insure - // the UI is up-to-date with the build results - monitor.subTask(ManagedMakeMessages - .getResourceString(REFRESH)); - try { - currentProject.refreshLocal( - IResource.DEPTH_INFINITE, null); - } catch (CoreException e) { - monitor.subTask(ManagedMakeMessages - .getResourceString(REFRESH_ERROR)); - } - } else { - errMsg = launcher.getErrorMessage(); - } - - // Report either the success or failure of our mission - buf = new StringBuffer(); - if (errMsg != null && errMsg.length() > 0) { - String errorDesc = ManagedMakeMessages - .getResourceString(BUILD_ERROR); - buf.append(errorDesc); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ - buf.append("(").append(errMsg).append(")"); //$NON-NLS-1$ //$NON-NLS-2$ - } else { - // Report a successful build - String successMsg = ManagedMakeMessages - .getFormattedString(BUILD_FINISHED, - currentProject.getName()); - buf.append(successMsg); - buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ - } - - // Write message on the console - consoleOutStream.write(buf.toString().getBytes()); - consoleOutStream.flush(); - epmOutputStream.close(); - - // Generate any error markers that the build has discovered - monitor.subTask(ManagedMakeMessages - .getResourceString(MARKERS)); - addBuilderMarkers(epm); - epm.reportProblems(); - consoleOutStream.close(); - } - } - } catch (Exception e) { - forgetLastBuiltState(); - } finally { - getGenerationProblems().clear(); - } - } - - /* (non-Javadoc) - * Removes the IMarkers for the project specified in the argument if the - * project exists, and is open. - * - * @param project - */ - private void removeAllMarkers(IProject project) { - if (project == null || !project.isAccessible()) return; - - // Clear out the problem markers - IWorkspace workspace = project.getWorkspace(); - IMarker[] markers; - try { - markers = project.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); - } catch (CoreException e) { - // Handled just about every case in the sanity check - return; - } - if (markers != null) { - try { - workspace.deleteMarkers(markers); - } catch (CoreException e) { - // The only situation that might cause this is some sort of resource change event - return; - } - } - } -} +/******************************************************************************* + * Copyright (c) 2002, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.core; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +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; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IMarker; +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.IWorkspace; +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.NullProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.SubProgressMonitor; + +/** + * This is the incremental builder associated with a managed build project. It dynamically + * decides the makefile generator it wants to use for a specific target. + * + * @since 1.2 + */ +public class GeneratedMakefileBuilder extends ACBuilder { + + /** + * @since 1.2 + */ + public class ResourceDeltaVisitor implements IResourceDeltaVisitor { + private String buildGoalName; + private IManagedBuildInfo buildInfo; + private boolean incrBuildNeeded = false; + private boolean fullBuildNeeded = false; + private List reservedNames; + + /** + * + */ + public ResourceDeltaVisitor(IManagedBuildInfo info) { + buildInfo = info; + String ext = buildInfo.getBuildArtifactExtension(); + //try to resolve build macros in the build artifact extension + try{ + ext = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + ext, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + info.getDefaultConfiguration()); + } catch (BuildMacroException e){ + } + + String name = buildInfo.getBuildArtifactName(); + //try to resolve build macros in the build artifact name + try{ + String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + name, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + info.getDefaultConfiguration()); + if((resolved = resolved.trim()).length() > 0) + name = resolved; + } catch (BuildMacroException e){ + } + + if (ext.length() > 0) { + buildGoalName = buildInfo.getOutputPrefix(ext) + name + IManagedBuilderMakefileGenerator.DOT + ext; + } else { + buildGoalName = name; + } + reservedNames = Arrays.asList(new String[]{".cdtbuild", ".cdtproject", ".project"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + /** + * @param changedResource + * @return + */ + private boolean isGeneratedResource(IResource resource) { + // Is this a generated directory ... + IPath path = resource.getProjectRelativePath(); + String[] configNames = buildInfo.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; + } + + /** + * @param resource + * @return + */ + private boolean isProjectFile(IResource resource) { + return reservedNames.contains(resource.getName()); + } + + public boolean shouldBuildIncr() { + return incrBuildNeeded; + } + + public boolean shouldBuildFull() { + return fullBuildNeeded; + } + + 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()) { + IResourceDelta[] kids = delta.getAffectedChildren(); + for (int index = kids.length - 1; index >= 0; --index) { + IResource changedResource = kids[index].getResource(); + if (changedResource instanceof IFolder) { + return true; + } else { + String name = changedResource.getName(); + if ((!name.equals(buildGoalName) && + // TODO: Also need to check for secondary outputs + (changedResource.isDerived() || + (isProjectFile(changedResource)) || + (isGeneratedResource(changedResource))))) { + // The resource that changed has attributes which make it uninteresting, + // so don't do anything + ; + } + else { + // TODO: Should we do extra checks here to determine if a build is really needed, + // or do you just do exclusion checks like above? + // We could check for: + // o The build goal name + // o A secondary output + // o An input file to a tool: + // o Has an extension of a source file used by a tool + // o Has an extension of a header file used by a tool + // o Has the name of an input file specified in an InputType via: + // o An Option + // o An AdditionalInput + // + //if (resourceName.equals(buildGoalName) || + // (buildInfo.buildsFileType(ext) || buildInfo.isHeaderFile(ext))) { + + // We need to do an incremental build, at least + incrBuildNeeded = true; + if (kids[index].getKind() == IResourceDelta.REMOVED) { + // If a meaningful resource was removed, then force a full build + // This is required because an incremental build will trigger make to + // do nothing for a missing source, since the state after the file + // removal is uptodate, as far as make is concerned + // A full build will clean, and ultimately trigger a relink without + // the object generated from the deleted source, which is what we want + fullBuildNeeded = true; + // There is no point in checking anything else since we have + // decided to do a full build anyway + break; + } + + //} + } + } + } + return false; + } + return true; + } + } + + // String constants + private static final String BUILD_ERROR = "ManagedMakeBuilder.message.error"; //$NON-NLS-1$ + private static final String BUILD_FINISHED = "ManagedMakeBuilder.message.finished"; //$NON-NLS-1$ + private static final String CONSOLE_HEADER = "ManagedMakeBuilder.message.console.header"; //$NON-NLS-1$ + private static final String ERROR_HEADER = "GeneratedmakefileBuilder error ["; //$NON-NLS-1$ + private static final String MAKE = "ManagedMakeBuilder.message.make"; //$NON-NLS-1$ + private static final String MARKERS = "ManagedMakeBuilder.message.creating.markers"; //$NON-NLS-1$ + private static final String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$ + private static final String NOTHING_BUILT = "ManagedMakeBuilder.message.no.build"; //$NON-NLS-1$ + private static final String REFRESH = "ManagedMakeBuilder.message.updating"; //$NON-NLS-1$ + private static final String REFRESH_ERROR = BUILD_ERROR + ".refresh"; //$NON-NLS-1$ + private static final String TRACE_FOOTER = "]: "; //$NON-NLS-1$ + private static final String TRACE_HEADER = "GeneratedmakefileBuilder trace ["; //$NON-NLS-1$ + private static final String TYPE_CLEAN = "ManagedMakeBuilder.type.clean"; //$NON-NLS-1$ + private static final String TYPE_INC = "ManagedMakeBuider.type.incremental"; //$NON-NLS-1$ + private static final String WARNING_UNSUPPORTED_CONFIGURATION = "ManagedMakeBuilder.warning.unsupported.configuration"; //$NON-NLS-1$ + public static boolean VERBOSE = false; + + // Local variables + protected Vector generationProblems; + protected IProject[] referencedProjects; + protected List resourcesToBuild; + public static void outputTrace(String resourceName, String message) { + if (VERBOSE) { + System.out.println(TRACE_HEADER + resourceName + TRACE_FOOTER + message + NEWLINE); + } + } + + public static void outputError(String resourceName, String message) { + if (VERBOSE) { + System.err.println(ERROR_HEADER + resourceName + TRACE_FOOTER + message + NEWLINE); + } + } + + /** + * Zero-argument constructor needed to fulfill the contract of an + * incremental builder. + */ + 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) + * Emits a message to the console indicating that there were no source files to build + * @param buildType + * @param status + * @param configName + */ + private void emitNoSourceMessage(int buildType, IStatus status, String configName) throws CoreException { + try { + StringBuffer buf = new StringBuffer(); + IConsole console = CCorePlugin.getDefault().getConsole(); + console.start(getProject()); + ConsoleOutputStream consoleOutStream = console.getOutputStream(); + // Report a successful clean + String[] consoleHeader = new String[3]; + if (buildType == FULL_BUILD || buildType == INCREMENTAL_BUILD) { + consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_INC); + } else { + consoleHeader[0] = new String(); + outputError(getProject().getName(), "The given build type is not supported in this context"); //$NON-NLS-1$ + } + consoleHeader[1] = configName; + consoleHeader[2] = getProject().getName(); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + buf.append(ManagedMakeMessages.getFormattedString(CONSOLE_HEADER, consoleHeader)); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + buf.append(status.getMessage()); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ + consoleOutStream.write(buf.toString().getBytes()); + consoleOutStream.flush(); + consoleOutStream.close(); + } catch (CoreException e) { + // Throw the exception back to the builder + throw e; + } catch (IOException io) { // Ignore console failures... + } + } + + /** + * + * This method has been created so that subclasses can override how the builder obtains its + * build info. The default implementation retrieves the info from the build manager. + * + * @return An IManagedBuildInfo object representing the build info. + */ + protected IManagedBuildInfo getBuildInfo() { + return ManagedBuildManager.getBuildInfo(getProject()); + } + + /* (non-Javadoc) + * @see org.eclipse.core.internal.events.InternalBuilder#build(int, java.util.Map, org.eclipse.core.runtime.IProgressMonitor) + */ + protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException { + // We should always tell the build system what projects we reference + referencedProjects = getProject().getReferencedProjects(); + + // Get the build information + IManagedBuildInfo info = getBuildInfo(); + if (info == null) { + outputError(getProject().getName(), "Build information was not found"); //$NON-NLS-1$ + return referencedProjects; + } + if (!info.isValid()) { + outputError(getProject().getName(), "Build information is not valid"); //$NON-NLS-1$ + return referencedProjects; + } + + // Create a makefile generator for the build + IManagedBuilderMakefileGenerator generator = ManagedBuildManager.getBuildfileGenerator(info.getDefaultConfiguration()); + generator.initialize(getProject(), info, monitor); + + // So let's figure out why we got called + if (kind == FULL_BUILD || info.needsRebuild()) { + outputTrace(getProject().getName(), "Full build needed/requested"); //$NON-NLS-1$ + fullBuild(info, generator, monitor); + } + else if (kind == AUTO_BUILD && info.needsRebuild()) { + outputTrace(getProject().getName(), "Autobuild requested, full build needed"); //$NON-NLS-1$ + fullBuild(info, generator, monitor); + } + else { + // Create a delta visitor to make sure we should be rebuilding + ResourceDeltaVisitor visitor = new ResourceDeltaVisitor(info); + IResourceDelta delta = getDelta(getProject()); + if (delta == null) { + outputTrace(getProject().getName(), "Incremental build requested, full build needed"); //$NON-NLS-1$ + fullBuild(info, generator, monitor); + } + else { + delta.accept(visitor); + if (visitor.shouldBuildFull()) { + outputTrace(getProject().getName(), "Incremental build requested, full build needed"); //$NON-NLS-1$ + fullBuild(info, generator, monitor); + } else if (visitor.shouldBuildIncr()) { + outputTrace(getProject().getName(), "Incremental build requested"); //$NON-NLS-1$ + incrementalBuild(delta, info, generator, monitor); + } + else if (referencedProjects != null) { + // Also check to see is any of the dependent projects changed + for (int i=0; iOperationCanceledException. + * + * @see org.eclipse.core.runtime.OperationCanceledException#OperationCanceledException() + */ + public void checkCancel(IProgressMonitor monitor) { + if (monitor != null && monitor.isCanceled()) { + outputTrace(getProject().getName(), "Build cancelled"); //$NON-NLS-1$ + forgetLastBuiltState(); + throw new OperationCanceledException(); + } + } + + /* (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 = getBuildInfo(); + if (info == null) { + outputError(getProject().getName(), "Build information was not found"); //$NON-NLS-1$ + return; + } + if (!info.isValid()) { + outputError(getProject().getName(), "Build information is not valid"); //$NON-NLS-1$ + return; + } + IPath buildDirPath = getProject().getLocation().append(info.getConfigurationName()); + IWorkspace workspace = CCorePlugin.getWorkspace(); + IContainer buildDir = workspace.getRoot().getContainerForLocation(buildDirPath); + if (buildDir == null || !buildDir.isAccessible()){ + outputError(buildDir.getName(), "Could not delete the build directory"); //$NON-NLS-1$ + return; + } + String status; + try { + // try the brute force approach first + status = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.clean.deleting.output", buildDir.getName()); //$NON-NLS-1$ + monitor.subTask(status); + workspace.delete(new IResource[]{buildDir}, true, monitor); + StringBuffer buf = new StringBuffer(); + // write to the console + IConsole console = CCorePlugin.getDefault().getConsole(); + console.start(getProject()); + ConsoleOutputStream consoleOutStream = console.getOutputStream(); + String[] consoleHeader = new String[3]; + consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_CLEAN); + consoleHeader[1] = info.getConfigurationName(); + consoleHeader[2] = getProject().getName(); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + buf.append(ManagedMakeMessages.getFormattedString(CONSOLE_HEADER, consoleHeader)); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + consoleOutStream.write(buf.toString().getBytes()); + consoleOutStream.flush(); + buf = new StringBuffer(); + // Report a successful clean + String successMsg = ManagedMakeMessages.getFormattedString(BUILD_FINISHED, getProject().getName()); + buf.append(successMsg); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ + consoleOutStream.write(buf.toString().getBytes()); + consoleOutStream.flush(); + consoleOutStream.close(); + } catch (CoreException e) { + // Create a makefile generator for the build + status = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.clean.build.clean", buildDir.getName()); //$NON-NLS-1$ + monitor.subTask(status); + IManagedBuilderMakefileGenerator generator = ManagedBuildManager.getBuildfileGenerator(info.getDefaultConfiguration()); + generator.initialize(getProject(), info, monitor); + cleanBuild(info, generator, monitor); + } catch (IOException io) {} // Ignore console failures... + } + + /* (non-Javadoc) + * @param info + * @param generator + * @param monitor + */ + protected void cleanBuild(IManagedBuildInfo info, IManagedBuilderMakefileGenerator generator, IProgressMonitor monitor) { + // Make sure that there is a top level directory and a set of makefiles + IPath buildDir = generator.getBuildWorkingDir(); + if (buildDir == null) { + buildDir = new Path(info.getConfigurationName()); + } + IPath makefilePath = getProject().getLocation().append(buildDir.append(generator.getMakefileName())); + IWorkspaceRoot root = CCorePlugin.getWorkspace().getRoot(); + IFile makefile = root.getFileForLocation(makefilePath); + + if (buildDir != null && makefile != null && makefile.isAccessible()) { + // invoke make with the clean argument + String statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.starting", getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); + checkCancel(monitor); + invokeMake(CLEAN_BUILD, buildDir, info, generator, monitor); + } + } + + /* (non-Javadoc) + * @param info + * @param generator + * @param monitor + */ + protected void fullBuild(IManagedBuildInfo info, IManagedBuilderMakefileGenerator generator, IProgressMonitor monitor) throws CoreException { + // Always need one of these bad boys + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + + checkCancel(monitor); + //If the previous builder invocation was cancelled, generated files might be corrupted + //in case one or more of the generated makefiles (e.g. dep files) are corrupted, + //the builder invocation might fail because of the possible syntax errors, so e.g. "make clean" will not work + //we need to explicitly clean the generated directories + clean(new SubProgressMonitor(monitor, IProgressMonitor.UNKNOWN)); + + // Regenerate the makefiles for this project + checkCancel(monitor); + String statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.rebuild.makefiles", getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); + //generator = ManagedBuildManager.getBuildfileGenerator(info.getDefaultConfiguration()); + generator.initialize(getProject(), info, monitor); + MultiStatus result = generator.regenerateMakefiles(); + if (result.getCode() == IStatus.WARNING || result.getCode() == IStatus.INFO) { + IStatus[] kids = result.getChildren(); + for (int index = 0; index < kids.length; ++index) { + // One possibility is that there is nothing to build + IStatus status = kids[index]; + if (status.getCode() == IManagedBuilderMakefileGenerator.NO_SOURCE_FOLDERS) { + // Inform the user, via the console, that there is nothing to build + // either because there are no buildable sources files or all potentially + // buildable files have been excluded from build + try { + emitNoSourceMessage(FULL_BUILD, status, info.getConfigurationName()); + } catch (CoreException e) { + // Throw the exception back to the builder + throw e; + } + // Dude, we're done + return; + } else { + // Stick this in the list of stuff to warn the user about + getGenerationProblems().add(status); + } + } + } + + // Now call make + checkCancel(monitor); + statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.starting", getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); + IPath topBuildDir = generator.getBuildWorkingDir(); + if (topBuildDir != null) { + invokeMake(FULL_BUILD, topBuildDir, info, generator, monitor); + } else { + statusMsg = ManagedMakeMessages.getFormattedString(NOTHING_BUILT, getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); + return; + } + + // Now regenerate the dependencies + checkCancel(monitor); + statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.regen.deps", getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); + try { + generator.regenerateDependencies(false); + } catch (CoreException e) { + // Throw the exception back to the builder + throw e; + } + + // Build finished message + statusMsg = ManagedMakeMessages.getFormattedString(BUILD_FINISHED, getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); + } + + /* (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 + * for a build with no custom prebuild/postbuild steps + * + * @param fullBuild + * @return + */ + protected String[] getMakeTargets(int buildType) { + List args = new ArrayList(); + switch (buildType) { + case CLEAN_BUILD: + args.add("clean"); //$NON-NLS-1$ + break; + case FULL_BUILD: + case INCREMENTAL_BUILD: + args.add("all"); //$NON-NLS-1$ + break; + } + return (String[])args.toArray(new String[args.size()]); + } + + /** + * @return + */ + protected List getResourcesToBuild() { + if (resourcesToBuild == null) { + resourcesToBuild = new ArrayList(); + } + return resourcesToBuild; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.resources.ACBuilder#getWorkingDirectory() + */ + public IPath getWorkingDirectory() { + return getProject().getLocation(); + } + + /* (non-Javadoc) + * @param delta + * @param info + * @param monitor + * @throws CoreException + */ + protected void incrementalBuild(IResourceDelta delta, IManagedBuildInfo info, IManagedBuilderMakefileGenerator generator, IProgressMonitor monitor) throws CoreException { + // Need to report status to the user + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + + // Ask the makefile generator to generate any makefiles needed to build delta + checkCancel(monitor); + String statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.update.makefiles", getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); + MultiStatus result = generator.generateMakefiles(delta); + if (result.getCode() == IStatus.WARNING || result.getCode() == IStatus.INFO) { + IStatus[] kids = result.getChildren(); + for (int index = 0; index < kids.length; ++index) { + // One possibility is that there is nothing to build + IStatus status = kids[index]; + if (status.getCode() == IManagedBuilderMakefileGenerator.NO_SOURCE_FOLDERS) { + // Inform the user, via the console, that there is nothing to build + // either because there are no buildable sources files or all potentially + // buildable files have been excluded from build + try { + emitNoSourceMessage(INCREMENTAL_BUILD, status, info.getConfigurationName()); + } catch (CoreException e) { + // Throw the exception back to the builder + throw e; + } + // Dude, we're done + return; + } else { + // Stick this in the list of stuff to warn the user about + getGenerationProblems().add(status); + } + } + } + + // Run the build + checkCancel(monitor); + statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.starting", getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); + IPath buildDir = generator.getBuildWorkingDir(); + if (buildDir != null) { + invokeMake(INCREMENTAL_BUILD, buildDir, info, generator, monitor); + } else { + statusMsg = ManagedMakeMessages.getFormattedString(NOTHING_BUILT, getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); + return; + } + + // Generate the dependencies for all changes + checkCancel(monitor); + statusMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.updating.deps", getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); + try { + generator.generateDependencies(); + } catch (CoreException e) { + throw e; + } + + // Build finished message + statusMsg = ManagedMakeMessages.getFormattedString(BUILD_FINISHED, getProject().getName()); //$NON-NLS-1$ + monitor.subTask(statusMsg); +} + + /* (non-Javadoc) + * @param buildType + * @param buildDir + * @param info + * @param generator + * @param monitor + */ + protected void invokeMake(int buildType, IPath buildDir, IManagedBuildInfo info, IManagedBuilderMakefileGenerator generator, IProgressMonitor monitor) { + // Get the project and make sure there's a monitor to cancel the build + IProject currentProject = getProject(); + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + + 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.append(generator.getMakefileName()); + if (root.getFileForLocation(makefile) == null) { + return; + } + + // Flag to the user that make is about to be called + String makeCmd = info.getBuildCommand(); + //try to resolve the build macros in the builder command + try{ + String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + makeCmd, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + info.getDefaultConfiguration()); + if((resolved = resolved.trim()).length() > 0) + makeCmd = resolved; + } catch (BuildMacroException e){ + } + + IPath makeCommand = new Path(makeCmd); + if (makeCommand != null) { + String[] msgs = new String[2]; + msgs[0] = makeCommand.toString(); + msgs[1] = currentProject.getName(); + monitor.subTask(ManagedMakeMessages.getFormattedString(MAKE, msgs)); + + // Get a build console for the project + StringBuffer buf = new StringBuffer(); + IConsole console = CCorePlugin.getDefault().getConsole(); + console.start(currentProject); + ConsoleOutputStream consoleOutStream = console.getOutputStream(); + String[] consoleHeader = new String[3]; + switch (buildType) { + case FULL_BUILD: + case INCREMENTAL_BUILD: + consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_INC); + break; + case CLEAN_BUILD: + consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_CLEAN); + break; + } + + consoleHeader[1] = info.getConfigurationName(); + consoleHeader[2] = currentProject.getName(); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + buf.append(ManagedMakeMessages.getFormattedString(CONSOLE_HEADER, consoleHeader)); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + + IConfiguration cfg = info.getDefaultConfiguration(); + if(!cfg.isSupported()){ + buf.append(ManagedMakeMessages.getFormattedString(WARNING_UNSUPPORTED_CONFIGURATION,new String[] {cfg.getName(),cfg.getToolChain().getName()})); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + } + consoleOutStream.write(buf.toString().getBytes()); + consoleOutStream.flush(); + + // Remove all markers for this project + removeAllMarkers(currentProject); + + // Get a launcher for the make command + String errMsg = null; + CommandLauncher launcher = new CommandLauncher(); + launcher.showCommand(true); + + // Set the environmennt + IBuildEnvironmentVariable variables[] = ManagedBuildManager.getEnvironmentVariableProvider().getVariables(cfg,true,true); + String[] env = null; + ArrayList envList = new ArrayList(); + if (variables != null) { + for(int i = 0; i < variables.length; i++){ + envList.add(variables[i].getName() + "=" + variables[i].getValue()); //$NON-NLS-1$ + } + env = (String[]) envList.toArray(new String[envList.size()]); + } + + // Hook up an error parser manager + String[] errorParsers = info.getDefaultConfiguration().getErrorParserList(); + ErrorParserManager epm = new ErrorParserManager(getProject(), workingDirectory, this, errorParsers); + epm.setOutputStream(consoleOutStream); + // This variable is necessary to ensure that the EPM stream stay open + // until we explicitly close it. See bug#123302. + OutputStream epmOutputStream = epm.getOutputStream(); + + // Get the arguments to be passed to make from build model + ArrayList makeArgs = new ArrayList(); + String arg = info.getBuildArguments(); + if (arg.length() > 0) { + String[] args = arg.split("\\s"); //$NON-NLS-1$ + for (int i = 0; i < args.length; ++i) { + makeArgs.add(args[i]); + } + } + + String[] makeTargets; + String prebuildStep = info.getPrebuildStep(); + //try to resolve the build macros in the prebuildStep + try{ + prebuildStep = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + prebuildStep, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + cfg); + } catch (BuildMacroException e){ + } + boolean prebuildStepPresent = (prebuildStep.length() > 0); + Process proc = null; + boolean isuptodate = false; + + if (prebuildStepPresent) { + ArrayList premakeArgs = (ArrayList) makeArgs.clone(); + String[] premakeTargets; + switch (buildType) { + case INCREMENTAL_BUILD: { + // For an incremental build with a prebuild step: + // Check the status of the main build with "make -q main-build" + // If up to date: + // then: don't invoke the prebuild step, which should be run only if + // something needs to be built in the main build + // else: invoke the prebuild step and the main build step + premakeArgs.add("-q"); //$NON-NLS-1$ + premakeArgs.add("main-build"); //$NON-NLS-1$ + premakeTargets = (String[]) premakeArgs.toArray(new String[premakeArgs.size()]); + proc = launcher.execute(makeCommand, premakeTargets, env, workingDirectory); + if (proc != null) { + try { + // Close the input of the process since we will never write to it + proc.getOutputStream().close(); + } catch (IOException e) { + } + if (launcher.waitAndRead(epm.getOutputStream(), epm.getOutputStream(), + new SubProgressMonitor(monitor, + IProgressMonitor.UNKNOWN)) != CommandLauncher.OK) { + errMsg = launcher.getErrorMessage(); + } + } else { + errMsg = launcher.getErrorMessage(); + } + + if ((errMsg != null && errMsg.length() > 0) || proc == null) { + // Can't tell if the build is needed, so assume it is, and let any errors be triggered + // when the "real" build is invoked below + makeArgs.add("pre-build"); //$NON-NLS-1$ + makeArgs.add("main-build"); //$NON-NLS-1$ + } else { + // The "make -q" command launch was successful + if (proc.exitValue() == 0) { + // If the status value returned from "make -q" is 0, then the build state is up-to-date + isuptodate = true; + // Report that the build was up to date, and thus nothing needs to be built + String uptodateMsg = ManagedMakeMessages + .getFormattedString(NOTHING_BUILT, currentProject.getName()); + buf = new StringBuffer(); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ + buf.append(uptodateMsg); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ + // Write message on the console + consoleOutStream.write(buf.toString().getBytes()); + consoleOutStream.flush(); + epmOutputStream.close(); + consoleOutStream.close(); + } else { + // The status value was other than 0, so press on with the build process + makeArgs.add("pre-build"); //$NON-NLS-1$ + makeArgs.add("main-build"); //$NON-NLS-1$ + } + } + break; + } + case FULL_BUILD: { + makeArgs.add("clean"); //$NON-NLS-1$ + makeArgs.add("pre-build"); //$NON-NLS-1$ + makeArgs.add("main-build"); //$NON-NLS-1$ + break; + } + case CLEAN_BUILD: { + makeArgs.add("clean"); //$NON-NLS-1$ + break; + } + } + + } else { + // No prebuild step + // + makeArgs.addAll(Arrays.asList(getMakeTargets(buildType))); + } + + makeTargets = (String[]) makeArgs.toArray(new String[makeArgs.size()]); + + // Launch make - main invocation + if (!isuptodate) { + proc = launcher.execute(makeCommand, makeTargets, env, + workingDirectory); + if (proc != null) { + try { + // Close the input of the process since we will never write to it + proc.getOutputStream().close(); + } catch (IOException e) { + } + + if (launcher.waitAndRead(epm.getOutputStream(), epm.getOutputStream(), + new SubProgressMonitor(monitor, + IProgressMonitor.UNKNOWN)) != CommandLauncher.OK) { + errMsg = launcher.getErrorMessage(); + } + + // Force a resync of the projects without allowing the user to cancel. + // This is probably unkind, but short of this there is no way to insure + // the UI is up-to-date with the build results + monitor.subTask(ManagedMakeMessages + .getResourceString(REFRESH)); + try { + currentProject.refreshLocal( + IResource.DEPTH_INFINITE, null); + } catch (CoreException e) { + monitor.subTask(ManagedMakeMessages + .getResourceString(REFRESH_ERROR)); + } + } else { + errMsg = launcher.getErrorMessage(); + } + + // Report either the success or failure of our mission + buf = new StringBuffer(); + if (errMsg != null && errMsg.length() > 0) { + String errorDesc = ManagedMakeMessages + .getResourceString(BUILD_ERROR); + buf.append(errorDesc); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ + buf.append("(").append(errMsg).append(")"); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + // Report a successful build + String successMsg = ManagedMakeMessages + .getFormattedString(BUILD_FINISHED, + currentProject.getName()); + buf.append(successMsg); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ + } + + // Write message on the console + consoleOutStream.write(buf.toString().getBytes()); + consoleOutStream.flush(); + epmOutputStream.close(); + + // Generate any error markers that the build has discovered + monitor.subTask(ManagedMakeMessages + .getResourceString(MARKERS)); + addBuilderMarkers(epm); + epm.reportProblems(); + consoleOutStream.close(); + } + } + } catch (Exception e) { + forgetLastBuiltState(); + } finally { + getGenerationProblems().clear(); + } + } + + /* (non-Javadoc) + * Removes the IMarkers for the project specified in the argument if the + * project exists, and is open. + * + * @param project + */ + private void removeAllMarkers(IProject project) { + if (project == null || !project.isAccessible()) return; + + // Clear out the problem markers + IWorkspace workspace = project.getWorkspace(); + IMarker[] markers; + try { + markers = project.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); + } catch (CoreException e) { + // Handled just about every case in the sanity check + return; + } + if (markers != null) { + try { + workspace.deleteMarkers(markers); + } catch (CoreException e) { + // The only situation that might cause this is some sort of resource change event + return; + } + } + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java index 070dd4695d9..6380d298951 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java @@ -1,1221 +1,1221 @@ -/******************************************************************************* - * Copyright (c) 2005 Intel Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Intel Corporation - Initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.internal.core; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.StringTokenizer; -import java.util.Vector; - -import org.eclipse.core.runtime.content.*; -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IProjectType; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.IInputType; -import org.eclipse.cdt.managedbuilder.core.IInputOrder; -import org.eclipse.cdt.managedbuilder.core.IAdditionalInput; -import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.PluginVersionIdentifier; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -public class InputType extends BuildObject implements IInputType { - - private static final String DEFAULT_SEPARATOR = ","; //$NON-NLS-1$ - private static final String EMPTY_STRING = new String(); - - // Superclass - private IInputType superClass; - private String superClassId; - // Parent and children - private ITool parent; - private Vector inputOrderList; - private Vector additionalInputList; - // Managed Build model attributes - private String sourceContentTypeId; - private IContentType sourceContentType; - private List inputExtensions; - private String dependencyContentTypeId; - private IContentType dependencyContentType; - private List dependencyExtensions; - private String optionId; - private String assignToOptionId; - private String buildVariable; - private Boolean multipleOfType; - private Boolean primaryInput; - private IConfigurationElement dependencyGeneratorElement = null; - private IManagedDependencyGenerator dependencyGenerator = null; - // Miscellaneous - private boolean isExtensionInputType = false; - private boolean isDirty = false; - private boolean resolved = true; - - /* - * C O N S T R U C T O R S - */ - - /** - * This constructor is called to create an InputType defined by an extension point in - * a plugin manifest file, or returned by a dynamic element provider - * - * @param parent The ITool parent of this InputType - * @param element The InputType definition from the manifest file or a dynamic element - * provider - */ - public InputType(ITool parent, IManagedConfigElement element) { - this.parent = parent; - isExtensionInputType = true; - - // setup for resolving - resolved = false; - - loadFromManifest(element); - - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionInputType(this); - - // Load Children - IManagedConfigElement[] iElements = element.getChildren(); - for (int l = 0; l < iElements.length; ++l) { - IManagedConfigElement iElement = iElements[l]; - if (iElement.getName().equals(IInputOrder.INPUT_ORDER_ELEMENT_NAME)) { - InputOrder inputOrder = new InputOrder(this, iElement); - getInputOrderList().add(inputOrder); - } else if (iElement.getName().equals(IAdditionalInput.ADDITIONAL_INPUT_ELEMENT_NAME)) { - AdditionalInput addlInput = new AdditionalInput(this, iElement); - getAdditionalInputList().add(addlInput); - } - } - } - - /** - * This constructor is called to create an InputType whose attributes and children will be - * added by separate calls. - * - * @param Tool The parent of the an InputType - * @param InputType The superClass, if any - * @param String The id for the new InputType - * @param String The name for the new InputType - * @param boolean Indicates whether this is an extension element or a managed project element - */ - public InputType(Tool parent, IInputType superClass, String Id, String name, boolean isExtensionElement) { - this.parent = parent; - this.superClass = superClass; - if (this.superClass != null) { - superClassId = this.superClass.getId(); - } - setId(Id); - setName(name); - - isExtensionInputType = isExtensionElement; - if (isExtensionElement) { - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionInputType(this); - } else { - setDirty(true); - } - } - - /** - * Create an InputType based on the specification stored in the - * project file (.cdtbuild). - * - * @param parent The ITool the InputType will be added to. - * @param element The XML element that contains the InputType settings. - * - */ - public InputType(ITool parent, Element element) { - this.parent = parent; - isExtensionInputType = false; - - // Initialize from the XML attributes - loadFromProject(element); - - // Load children - NodeList configElements = element.getChildNodes(); - for (int i = 0; i < configElements.getLength(); ++i) { - Node configElement = configElements.item(i); - if (configElement.getNodeName().equals(IInputOrder.INPUT_ORDER_ELEMENT_NAME)) { - InputOrder inputOrder = new InputOrder(this, (Element)configElement); - getInputOrderList().add(inputOrder); - } else if (configElement.getNodeName().equals(IAdditionalInput.ADDITIONAL_INPUT_ELEMENT_NAME)) { - AdditionalInput addlInput = new AdditionalInput(this, (Element)configElement); - getAdditionalInputList().add(addlInput); - } - } - } - - /** - * Create an InputType based upon an existing InputType. - * - * @param parent The ITool the InputType will be added to. - * @param Id The identifier of the new InputType - * @param name The name of the new InputType - * @param inputType The existing InputType to clone. - */ - public InputType(ITool parent, String Id, String name, InputType inputType) { - this.parent = parent; - superClass = inputType.superClass; - if (superClass != null) { - if (inputType.superClassId != null) { - superClassId = new String(inputType.superClassId); - } - } - setId(Id); - setName(name); - - isExtensionInputType = false; - - // Copy the remaining attributes - - if (inputType.sourceContentTypeId != null) { - sourceContentTypeId = new String(inputType.sourceContentTypeId); - } - sourceContentType = inputType.sourceContentType; - if (inputType.inputExtensions != null) { - inputExtensions = new ArrayList(inputType.inputExtensions); - } - if (inputType.dependencyContentTypeId != null) { - dependencyContentTypeId = new String(inputType.dependencyContentTypeId); - } - dependencyContentType = inputType.dependencyContentType; - if (inputType.dependencyExtensions != null) { - dependencyExtensions = new ArrayList(inputType.dependencyExtensions); - } - if (inputType.optionId != null) { - optionId = new String(inputType.optionId); - } - if (inputType.assignToOptionId != null) { - assignToOptionId = new String(inputType.assignToOptionId); - } - if (inputType.buildVariable != null) { - buildVariable = new String(inputType.buildVariable); - } - if (inputType.multipleOfType != null) { - multipleOfType = new Boolean(inputType.multipleOfType.booleanValue()); - } - if (inputType.primaryInput != null) { - primaryInput = new Boolean(inputType.primaryInput.booleanValue()); - } - dependencyGeneratorElement = inputType.dependencyGeneratorElement; - dependencyGenerator = inputType.dependencyGenerator; - - // Clone the children - if (inputType.inputOrderList != null) { - Iterator iter = inputType.getInputOrderList().listIterator(); - while (iter.hasNext()) { - InputOrder inputOrder = (InputOrder) iter.next(); - InputOrder newInputOrder = new InputOrder(this, inputOrder); - getInputOrderList().add(newInputOrder); - } - } - if (inputType.additionalInputList != null) { - Iterator iter = inputType.getAdditionalInputList().listIterator(); - while (iter.hasNext()) { - AdditionalInput additionalInput = (AdditionalInput) iter.next(); - AdditionalInput newAdditionalInput = new AdditionalInput(this, additionalInput); - getAdditionalInputList().add(newAdditionalInput); - } - } - - setDirty(true); - } - - /* - * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S - */ - - /* (non-Javadoc) - * Loads the InputType information from the ManagedConfigElement specified in the - * argument. - * - * @param element Contains the InputType information - */ - protected void loadFromManifest(IManagedConfigElement element) { - ManagedBuildManager.putConfigElement(this, element); - - // id - setId(element.getAttribute(IBuildObject.ID)); - - // Get the name - setName(element.getAttribute(IBuildObject.NAME)); - - // superClass - superClassId = element.getAttribute(IProjectType.SUPERCLASS); - - // sourceContentType - sourceContentTypeId = element.getAttribute(IInputType.SOURCE_CONTENT_TYPE); - - // Get the supported input file extensions - String inputs = element.getAttribute(ITool.SOURCES); - if (inputs != null) { - StringTokenizer tokenizer = new StringTokenizer(inputs, DEFAULT_SEPARATOR); - while (tokenizer.hasMoreElements()) { - getInputExtensionsList().add(tokenizer.nextElement()); - } - } - - // dependencyContentType - dependencyContentTypeId = element.getAttribute(IInputType.DEPENDENCY_CONTENT_TYPE); - - // Get the dependency (header file) extensions - String headers = element.getAttribute(IInputType.DEPENDENCY_EXTENSIONS); - if (headers != null) { - StringTokenizer tokenizer = new StringTokenizer(headers, DEFAULT_SEPARATOR); - while (tokenizer.hasMoreElements()) { - getDependencyExtensionsList().add(tokenizer.nextElement()); - } - } - - // option - optionId = element.getAttribute(IInputType.OPTION); - - // assignToOption - assignToOptionId = element.getAttribute(IInputType.ASSIGN_TO_OPTION); - - // multipleOfType - String isMOT = element.getAttribute(IInputType.MULTIPLE_OF_TYPE); - if (isMOT != null){ - multipleOfType = new Boolean("true".equals(isMOT)); //$NON-NLS-1$ - } - - // primaryInput - String isPI = element.getAttribute(IInputType.PRIMARY_INPUT); - if (isPI != null){ - primaryInput = new Boolean("true".equals(isPI)); //$NON-NLS-1$ - } - - // buildVariable - buildVariable = element.getAttribute(IInputType.BUILD_VARIABLE); - - // Store the configuration element IFF there is a dependency generator defined - String depGenerator = element.getAttribute(ITool.DEP_CALC_ID); - if (depGenerator != null && element instanceof DefaultManagedConfigElement) { - dependencyGeneratorElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); - } - } - - /* (non-Javadoc) - * Initialize the InputType information from the XML element - * specified in the argument - * - * @param element An XML element containing the InputType information - */ - protected boolean loadFromProject(Element element) { - - // id - setId(element.getAttribute(IBuildObject.ID)); - - // name - if (element.hasAttribute(IBuildObject.NAME)) { - setName(element.getAttribute(IBuildObject.NAME)); - } - - // superClass - superClassId = element.getAttribute(IProjectType.SUPERCLASS); - if (superClassId != null && superClassId.length() > 0) { - superClass = ManagedBuildManager.getExtensionInputType(superClassId); - if (superClass == null) { - // TODO: Report error - } - } - - // sourceContentType - IContentTypeManager manager = Platform.getContentTypeManager(); - if (element.hasAttribute(IInputType.SOURCE_CONTENT_TYPE)) { - sourceContentTypeId = element.getAttribute(IInputType.SOURCE_CONTENT_TYPE); - if (sourceContentTypeId != null && sourceContentTypeId.length() > 0) { - sourceContentType = manager.getContentType(sourceContentTypeId); - } - } - - // sources - if (element.hasAttribute(IInputType.SOURCES)) { - String inputs = element.getAttribute(ITool.SOURCES); - if (inputs != null) { - StringTokenizer tokenizer = new StringTokenizer(inputs, DEFAULT_SEPARATOR); - while (tokenizer.hasMoreElements()) { - getInputExtensionsList().add(tokenizer.nextElement()); - } - } - } - - // dependencyContentType - if (element.hasAttribute(IInputType.DEPENDENCY_CONTENT_TYPE)) { - dependencyContentTypeId = element.getAttribute(IInputType.DEPENDENCY_CONTENT_TYPE); - if (dependencyContentTypeId != null && dependencyContentTypeId.length() > 0) { - dependencyContentType = manager.getContentType(dependencyContentTypeId); - } - } - - // dependencyExtensions - // Get the dependency (header file) extensions - if (element.hasAttribute(IInputType.DEPENDENCY_EXTENSIONS)) { - String headers = element.getAttribute(IInputType.DEPENDENCY_EXTENSIONS); - if (headers != null) { - StringTokenizer tokenizer = new StringTokenizer(headers, DEFAULT_SEPARATOR); - while (tokenizer.hasMoreElements()) { - getDependencyExtensionsList().add(tokenizer.nextElement()); - } - } - } - - // option - if (element.hasAttribute(IInputType.OPTION)) { - optionId = element.getAttribute(IInputType.OPTION); - } - - // assignToOption - if (element.hasAttribute(IInputType.ASSIGN_TO_OPTION)) { - assignToOptionId = element.getAttribute(IInputType.ASSIGN_TO_OPTION); - } - - // multipleOfType - if (element.hasAttribute(IInputType.MULTIPLE_OF_TYPE)) { - String isMOT = element.getAttribute(IInputType.MULTIPLE_OF_TYPE); - if (isMOT != null){ - multipleOfType = new Boolean("true".equals(isMOT)); //$NON-NLS-1$ - } - } - - // primaryInput - if (element.hasAttribute(IInputType.PRIMARY_INPUT)) { - String isPI = element.getAttribute(IInputType.PRIMARY_INPUT); - if (isPI != null){ - primaryInput = new Boolean("true".equals(isPI)); //$NON-NLS-1$ - } - } - - // buildVariable - if (element.hasAttribute(IInputType.BUILD_VARIABLE)) { - buildVariable = element.getAttribute(IInputType.BUILD_VARIABLE); - } - - // Note: dependency generator cannot be specified in a project file because - // an IConfigurationElement is needed to load it! - if (element.hasAttribute(ITool.DEP_CALC_ID)) { - // TODO: Issue warning? - } - - return true; - } - - /** - * Persist the InputType to the project file. - * - * @param doc - * @param element - */ - public void serialize(Document doc, Element element) { - if (superClass != null) - element.setAttribute(IProjectType.SUPERCLASS, superClass.getId()); - - element.setAttribute(IBuildObject.ID, id); - - if (name != null) { - element.setAttribute(IBuildObject.NAME, name); - } - - // sourceContentType - if (sourceContentTypeId != null) { - element.setAttribute(IInputType.SOURCE_CONTENT_TYPE, sourceContentTypeId); - } - - // input file extensions - if (getInputExtensionsList().size() > 0) { - String inputs; - List list = getInputExtensionsList(); - Iterator iter = list.listIterator(); - inputs = (String)iter.next(); - while (iter.hasNext()) { - inputs += DEFAULT_SEPARATOR; - inputs += iter.next(); - } - element.setAttribute(IInputType.SOURCES, inputs); - } - - // dependencyContentType - if (dependencyContentTypeId != null) { - element.setAttribute(IInputType.DEPENDENCY_CONTENT_TYPE, dependencyContentTypeId); - } - - // dependency (header file) extensions - if (getDependencyExtensionsList().size() > 0) { - String headers; - List list = getDependencyExtensionsList(); - Iterator iter = list.listIterator(); - headers = (String)iter.next(); - while (iter.hasNext()) { - headers += DEFAULT_SEPARATOR; - headers += iter.next(); - } - element.setAttribute(IInputType.DEPENDENCY_EXTENSIONS, headers); - } - - if (optionId != null) { - element.setAttribute(IInputType.OPTION, optionId); - } - - if (assignToOptionId != null) { - element.setAttribute(IInputType.ASSIGN_TO_OPTION, assignToOptionId); - } - - if (multipleOfType != null) { - element.setAttribute(IInputType.MULTIPLE_OF_TYPE, multipleOfType.toString()); - } - - if (primaryInput != null) { - element.setAttribute(IInputType.PRIMARY_INPUT, primaryInput.toString()); - } - - if (buildVariable != null) { - element.setAttribute(IInputType.BUILD_VARIABLE, buildVariable); - } - - // Note: dependency generator cannot be specified in a project file because - // an IConfigurationElement is needed to load it! - if (dependencyGeneratorElement != null) { - // TODO: issue warning? - } - - // Serialize my children - List childElements = getInputOrderList(); - Iterator iter = childElements.listIterator(); - while (iter.hasNext()) { - InputOrder io = (InputOrder) iter.next(); - Element ioElement = doc.createElement(InputOrder.INPUT_ORDER_ELEMENT_NAME); - element.appendChild(ioElement); - io.serialize(doc, ioElement); - } - childElements = getAdditionalInputList(); - iter = childElements.listIterator(); - while (iter.hasNext()) { - AdditionalInput ai = (AdditionalInput) iter.next(); - Element aiElement = doc.createElement(AdditionalInput.ADDITIONAL_INPUT_ELEMENT_NAME); - element.appendChild(aiElement); - ai.serialize(doc, aiElement); - } - - // I am clean now - isDirty = false; - } - - /* - * P A R E N T A N D C H I L D H A N D L I N G - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getParent() - */ - public ITool getParent() { - return parent; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#createInputOrder() - */ - public IInputOrder createInputOrder(String path) { - InputOrder inputOrder = new InputOrder(this, false); - inputOrder.setPath(path); - getInputOrderList().add(inputOrder); - setDirty(true); - return inputOrder; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getInputOrders() - */ - public IInputOrder[] getInputOrders() { - IInputOrder[] orders; - Vector ours = getInputOrderList(); - orders = (IInputOrder[])ours.toArray(new IInputOrder[ours.size()]); - return orders; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getInputOrder() - */ - public IInputOrder getInputOrder(String path) { - // TODO Convert both paths to absolute? - List orders = getInputOrderList(); - Iterator iter = orders.listIterator(); - while (iter.hasNext()) { - InputOrder io = (InputOrder) iter.next(); - if (path.compareToIgnoreCase(io.getPath()) != 0) { - return io; - } - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#removeInputOrder() - */ - public void removeInputOrder(String path) { - IInputOrder order = getInputOrder(path); - if (order != null) removeInputOrder(order); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#removeInputOrder() - */ - public void removeInputOrder(IInputOrder element) { - getInputOrderList().remove(element); - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#createAdditionalInput() - */ - public IAdditionalInput createAdditionalInput(String paths) { - AdditionalInput addlInput = new AdditionalInput(this, false); - addlInput.setPaths(paths); - getAdditionalInputList().add(addlInput); - setDirty(true); - return addlInput; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getAdditionalInputs() - */ - public IAdditionalInput[] getAdditionalInputs() { - IAdditionalInput[] inputs; - Vector ours = getAdditionalInputList(); - inputs = (IAdditionalInput[])ours.toArray(new IAdditionalInput[ours.size()]); - return inputs; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getAdditionalInput() - */ - public IAdditionalInput getAdditionalInput(String paths) { - // TODO Convert both paths to absolute? - // Must match all strings - String[] inputTokens = paths.split(";"); //$NON-NLS-1$ - List inputs = getInputOrderList(); - Iterator iter = inputs.listIterator(); - while (iter.hasNext()) { - AdditionalInput ai = (AdditionalInput) iter.next(); - boolean match = false; - String[] tokens = ai.getPaths(); - if (tokens.length == inputTokens.length) { - match = true; - for (int i = 0; i < tokens.length; i++) { - if (tokens[i].compareToIgnoreCase(inputTokens[i]) != 0) { - match = false; - break; - } - } - } - if (match) return ai; - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#removeAdditionalInput() - */ - public void removeAdditionalInput(String path) { - IAdditionalInput input = getAdditionalInput(path); - if (input != null) removeAdditionalInput(input); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#removeAdditionalInput() - */ - public void removeAdditionalInput(IAdditionalInput element) { - getAdditionalInputList().remove(element); - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getAdditionalDependencies() - */ - public IPath[] getAdditionalDependencies() { - List deps = new ArrayList(); - Iterator typeIter = getAdditionalInputList().iterator(); - while (typeIter.hasNext()) { - AdditionalInput current = (AdditionalInput)typeIter.next(); - int kind = current.getKind(); - if (kind == IAdditionalInput.KIND_ADDITIONAL_DEPENDENCY || - kind == IAdditionalInput.KIND_ADDITIONAL_INPUT_DEPENDENCY) { - String[] paths = current.getPaths(); - if (paths != null) { - for (int i = 0; i < paths.length; i++) { - if (paths[i].length() > 0) { - deps.add(Path.fromOSString(paths[i])); - } - } - } - } - } - return (IPath[])deps.toArray(new IPath[deps.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getAdditionalResources() - */ - public IPath[] getAdditionalResources() { - List ins = new ArrayList(); - Iterator typeIter = getAdditionalInputList().iterator(); - while (typeIter.hasNext()) { - AdditionalInput current = (AdditionalInput)typeIter.next(); - int kind = current.getKind(); - if (kind == IAdditionalInput.KIND_ADDITIONAL_INPUT || - kind == IAdditionalInput.KIND_ADDITIONAL_INPUT_DEPENDENCY) { - String[] paths = current.getPaths(); - if (paths != null) { - for (int i = 0; i < paths.length; i++) { - if (paths[i].length() > 0) { - ins.add(Path.fromOSString(paths[i])); - } - } - } - } - } - return (IPath[])ins.toArray(new IPath[ins.size()]); - } - - /* (non-Javadoc) - * Memory-safe way to access the list of input orders - */ - private Vector getInputOrderList() { - if (inputOrderList == null) { - inputOrderList = new Vector(); - } - return inputOrderList; - } - - /* (non-Javadoc) - * Memory-safe way to access the list of input orders - */ - private Vector getAdditionalInputList() { - if (additionalInputList == null) { - additionalInputList = new Vector(); - } - return additionalInputList; - } - - - /* - * M O D E L A T T R I B U T E A C C E S S O R S - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IInputType#getSuperClass() - */ - public IInputType getSuperClass() { - return superClass; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getName() - */ - public String getName() { - return (name == null && superClass != null) ? superClass.getName() : name; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getBuildVariable() - */ - public String getBuildVariable() { - if (buildVariable == null) { - // If I have a superClass, ask it - if (superClass != null) { - return superClass.getBuildVariable(); - } else { - return EMPTY_STRING; - } - } - return buildVariable; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#setBuildVariable() - */ - public void setBuildVariable(String variableName) { - if (variableName == null && buildVariable == null) return; - if (buildVariable == null || variableName == null || !(variableName.equals(buildVariable))) { - buildVariable = variableName; - setDirty(true); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getDependencyContentType() - */ - public IContentType getDependencyContentType() { - if (dependencyContentType == null) { - if (superClass != null) { - return superClass.getDependencyContentType(); - } else { - return null; - } - } - return dependencyContentType; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#setDependencyContentType() - */ - public void setDependencyContentType(IContentType type) { - if (dependencyContentType != type) { - dependencyContentType = type; - if (dependencyContentType != null) { - dependencyContentTypeId = dependencyContentType.getId(); - } else { - dependencyContentTypeId = null; - } - setDirty(true); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getDependencyExtensionsAttribute() - */ - public String[] getDependencyExtensionsAttribute() { - if (dependencyExtensions == null || dependencyExtensions.size() == 0) { - // If I have a superClass, ask it - if (superClass != null) { - return superClass.getDependencyExtensionsAttribute(); - } else { - if (dependencyExtensions == null) { - dependencyExtensions = new ArrayList(); - } - } - } - return (String[])dependencyExtensions.toArray(new String[dependencyExtensions.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#setDependencyExtensionsAttribute() - */ - public void setDependencyExtensionsAttribute(String extensions) { - getDependencyExtensionsList().clear(); - if (extensions != null) { - StringTokenizer tokenizer = new StringTokenizer(extensions, DEFAULT_SEPARATOR); - while (tokenizer.hasMoreElements()) { - getDependencyExtensionsList().add(tokenizer.nextElement()); - } - } - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IInputType#getDependencyExtensions() - */ - public String[] getDependencyExtensions(ITool tool) { - // Use content type if specified and registered with Eclipse - IContentType type = getDependencyContentType(); - if (type != null) { - String[] exts = ((Tool)tool).getContentTypeFileSpecs(type); - // TODO: This is a temporary hack until we decide how to specify the langauge (C vs. C++) - // of a .h file. If the content type is the CDT-defined C/C++ content type, then - // add "h" to the list if it is not already there. - if (type.getId().compareTo("org.eclipse.cdt.core.cxxHeader") == 0) { // $NON-NLS-1$ - boolean h_found = false; - for (int i=0; i 0) { - superClass = ManagedBuildManager.getExtensionInputType(superClassId); - if (superClass == null) { - // Report error - ManagedBuildManager.OutputResolveError( - "superClass", //$NON-NLS-1$ - superClassId, - "inputType", //$NON-NLS-1$ - getId()); - } - } - - // Resolve content types - IContentTypeManager manager = Platform.getContentTypeManager(); - if (sourceContentTypeId != null && sourceContentTypeId.length() > 0) { - sourceContentType = manager.getContentType(sourceContentTypeId); - } - if (dependencyContentTypeId != null && dependencyContentTypeId.length() > 0) { - dependencyContentType = manager.getContentType(dependencyContentTypeId); - } - - // Call resolveReferences on our children - Iterator typeIter = getInputOrderList().iterator(); - while (typeIter.hasNext()) { - InputOrder current = (InputOrder)typeIter.next(); - current.resolveReferences(); - } - typeIter = getAdditionalInputList().iterator(); - while (typeIter.hasNext()) { - AdditionalInput current = (AdditionalInput)typeIter.next(); - current.resolveReferences(); - } - } - } - - /** - * @return Returns the managedBuildRevision. - */ - public String getManagedBuildRevision() { - if ( managedBuildRevision == null) { - if ( getParent() != null) { - return getParent().getManagedBuildRevision(); - } - } - return managedBuildRevision; - } - - /** - * @return Returns the version. - */ - public PluginVersionIdentifier getVersion() { - if ( version == null) { - if ( getParent() != null) { - return getParent().getVersion(); - } - } - return version; - } - - public void setVersion(PluginVersionIdentifier version) { - // Do nothing - } -} +/******************************************************************************* + * Copyright (c) 2005, 2006 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.core; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.StringTokenizer; +import java.util.Vector; + +import org.eclipse.core.runtime.content.*; +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IProjectType; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.IInputType; +import org.eclipse.cdt.managedbuilder.core.IInputOrder; +import org.eclipse.cdt.managedbuilder.core.IAdditionalInput; +import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.PluginVersionIdentifier; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class InputType extends BuildObject implements IInputType { + + private static final String DEFAULT_SEPARATOR = ","; //$NON-NLS-1$ + private static final String EMPTY_STRING = new String(); + + // Superclass + private IInputType superClass; + private String superClassId; + // Parent and children + private ITool parent; + private Vector inputOrderList; + private Vector additionalInputList; + // Managed Build model attributes + private String sourceContentTypeId; + private IContentType sourceContentType; + private List inputExtensions; + private String dependencyContentTypeId; + private IContentType dependencyContentType; + private List dependencyExtensions; + private String optionId; + private String assignToOptionId; + private String buildVariable; + private Boolean multipleOfType; + private Boolean primaryInput; + private IConfigurationElement dependencyGeneratorElement = null; + private IManagedDependencyGeneratorType dependencyGenerator = null; + // Miscellaneous + private boolean isExtensionInputType = false; + private boolean isDirty = false; + private boolean resolved = true; + + /* + * C O N S T R U C T O R S + */ + + /** + * This constructor is called to create an InputType defined by an extension point in + * a plugin manifest file, or returned by a dynamic element provider + * + * @param parent The ITool parent of this InputType + * @param element The InputType definition from the manifest file or a dynamic element + * provider + */ + public InputType(ITool parent, IManagedConfigElement element) { + this.parent = parent; + isExtensionInputType = true; + + // setup for resolving + resolved = false; + + loadFromManifest(element); + + // Hook me up to the Managed Build Manager + ManagedBuildManager.addExtensionInputType(this); + + // Load Children + IManagedConfigElement[] iElements = element.getChildren(); + for (int l = 0; l < iElements.length; ++l) { + IManagedConfigElement iElement = iElements[l]; + if (iElement.getName().equals(IInputOrder.INPUT_ORDER_ELEMENT_NAME)) { + InputOrder inputOrder = new InputOrder(this, iElement); + getInputOrderList().add(inputOrder); + } else if (iElement.getName().equals(IAdditionalInput.ADDITIONAL_INPUT_ELEMENT_NAME)) { + AdditionalInput addlInput = new AdditionalInput(this, iElement); + getAdditionalInputList().add(addlInput); + } + } + } + + /** + * This constructor is called to create an InputType whose attributes and children will be + * added by separate calls. + * + * @param Tool The parent of the an InputType + * @param InputType The superClass, if any + * @param String The id for the new InputType + * @param String The name for the new InputType + * @param boolean Indicates whether this is an extension element or a managed project element + */ + public InputType(Tool parent, IInputType superClass, String Id, String name, boolean isExtensionElement) { + this.parent = parent; + this.superClass = superClass; + if (this.superClass != null) { + superClassId = this.superClass.getId(); + } + setId(Id); + setName(name); + + isExtensionInputType = isExtensionElement; + if (isExtensionElement) { + // Hook me up to the Managed Build Manager + ManagedBuildManager.addExtensionInputType(this); + } else { + setDirty(true); + } + } + + /** + * Create an InputType based on the specification stored in the + * project file (.cdtbuild). + * + * @param parent The ITool the InputType will be added to. + * @param element The XML element that contains the InputType settings. + * + */ + public InputType(ITool parent, Element element) { + this.parent = parent; + isExtensionInputType = false; + + // Initialize from the XML attributes + loadFromProject(element); + + // Load children + NodeList configElements = element.getChildNodes(); + for (int i = 0; i < configElements.getLength(); ++i) { + Node configElement = configElements.item(i); + if (configElement.getNodeName().equals(IInputOrder.INPUT_ORDER_ELEMENT_NAME)) { + InputOrder inputOrder = new InputOrder(this, (Element)configElement); + getInputOrderList().add(inputOrder); + } else if (configElement.getNodeName().equals(IAdditionalInput.ADDITIONAL_INPUT_ELEMENT_NAME)) { + AdditionalInput addlInput = new AdditionalInput(this, (Element)configElement); + getAdditionalInputList().add(addlInput); + } + } + } + + /** + * Create an InputType based upon an existing InputType. + * + * @param parent The ITool the InputType will be added to. + * @param Id The identifier of the new InputType + * @param name The name of the new InputType + * @param inputType The existing InputType to clone. + */ + public InputType(ITool parent, String Id, String name, InputType inputType) { + this.parent = parent; + superClass = inputType.superClass; + if (superClass != null) { + if (inputType.superClassId != null) { + superClassId = new String(inputType.superClassId); + } + } + setId(Id); + setName(name); + + isExtensionInputType = false; + + // Copy the remaining attributes + + if (inputType.sourceContentTypeId != null) { + sourceContentTypeId = new String(inputType.sourceContentTypeId); + } + sourceContentType = inputType.sourceContentType; + if (inputType.inputExtensions != null) { + inputExtensions = new ArrayList(inputType.inputExtensions); + } + if (inputType.dependencyContentTypeId != null) { + dependencyContentTypeId = new String(inputType.dependencyContentTypeId); + } + dependencyContentType = inputType.dependencyContentType; + if (inputType.dependencyExtensions != null) { + dependencyExtensions = new ArrayList(inputType.dependencyExtensions); + } + if (inputType.optionId != null) { + optionId = new String(inputType.optionId); + } + if (inputType.assignToOptionId != null) { + assignToOptionId = new String(inputType.assignToOptionId); + } + if (inputType.buildVariable != null) { + buildVariable = new String(inputType.buildVariable); + } + if (inputType.multipleOfType != null) { + multipleOfType = new Boolean(inputType.multipleOfType.booleanValue()); + } + if (inputType.primaryInput != null) { + primaryInput = new Boolean(inputType.primaryInput.booleanValue()); + } + dependencyGeneratorElement = inputType.dependencyGeneratorElement; + dependencyGenerator = inputType.dependencyGenerator; + + // Clone the children + if (inputType.inputOrderList != null) { + Iterator iter = inputType.getInputOrderList().listIterator(); + while (iter.hasNext()) { + InputOrder inputOrder = (InputOrder) iter.next(); + InputOrder newInputOrder = new InputOrder(this, inputOrder); + getInputOrderList().add(newInputOrder); + } + } + if (inputType.additionalInputList != null) { + Iterator iter = inputType.getAdditionalInputList().listIterator(); + while (iter.hasNext()) { + AdditionalInput additionalInput = (AdditionalInput) iter.next(); + AdditionalInput newAdditionalInput = new AdditionalInput(this, additionalInput); + getAdditionalInputList().add(newAdditionalInput); + } + } + + setDirty(true); + } + + /* + * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S + */ + + /* (non-Javadoc) + * Loads the InputType information from the ManagedConfigElement specified in the + * argument. + * + * @param element Contains the InputType information + */ + protected void loadFromManifest(IManagedConfigElement element) { + ManagedBuildManager.putConfigElement(this, element); + + // id + setId(element.getAttribute(IBuildObject.ID)); + + // Get the name + setName(element.getAttribute(IBuildObject.NAME)); + + // superClass + superClassId = element.getAttribute(IProjectType.SUPERCLASS); + + // sourceContentType + sourceContentTypeId = element.getAttribute(IInputType.SOURCE_CONTENT_TYPE); + + // Get the supported input file extensions + String inputs = element.getAttribute(ITool.SOURCES); + if (inputs != null) { + StringTokenizer tokenizer = new StringTokenizer(inputs, DEFAULT_SEPARATOR); + while (tokenizer.hasMoreElements()) { + getInputExtensionsList().add(tokenizer.nextElement()); + } + } + + // dependencyContentType + dependencyContentTypeId = element.getAttribute(IInputType.DEPENDENCY_CONTENT_TYPE); + + // Get the dependency (header file) extensions + String headers = element.getAttribute(IInputType.DEPENDENCY_EXTENSIONS); + if (headers != null) { + StringTokenizer tokenizer = new StringTokenizer(headers, DEFAULT_SEPARATOR); + while (tokenizer.hasMoreElements()) { + getDependencyExtensionsList().add(tokenizer.nextElement()); + } + } + + // option + optionId = element.getAttribute(IInputType.OPTION); + + // assignToOption + assignToOptionId = element.getAttribute(IInputType.ASSIGN_TO_OPTION); + + // multipleOfType + String isMOT = element.getAttribute(IInputType.MULTIPLE_OF_TYPE); + if (isMOT != null){ + multipleOfType = new Boolean("true".equals(isMOT)); //$NON-NLS-1$ + } + + // primaryInput + String isPI = element.getAttribute(IInputType.PRIMARY_INPUT); + if (isPI != null){ + primaryInput = new Boolean("true".equals(isPI)); //$NON-NLS-1$ + } + + // buildVariable + buildVariable = element.getAttribute(IInputType.BUILD_VARIABLE); + + // Store the configuration element IFF there is a dependency generator defined + String depGenerator = element.getAttribute(ITool.DEP_CALC_ID); + if (depGenerator != null && element instanceof DefaultManagedConfigElement) { + dependencyGeneratorElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); + } + } + + /* (non-Javadoc) + * Initialize the InputType information from the XML element + * specified in the argument + * + * @param element An XML element containing the InputType information + */ + protected boolean loadFromProject(Element element) { + + // id + setId(element.getAttribute(IBuildObject.ID)); + + // name + if (element.hasAttribute(IBuildObject.NAME)) { + setName(element.getAttribute(IBuildObject.NAME)); + } + + // superClass + superClassId = element.getAttribute(IProjectType.SUPERCLASS); + if (superClassId != null && superClassId.length() > 0) { + superClass = ManagedBuildManager.getExtensionInputType(superClassId); + if (superClass == null) { + // TODO: Report error + } + } + + // sourceContentType + IContentTypeManager manager = Platform.getContentTypeManager(); + if (element.hasAttribute(IInputType.SOURCE_CONTENT_TYPE)) { + sourceContentTypeId = element.getAttribute(IInputType.SOURCE_CONTENT_TYPE); + if (sourceContentTypeId != null && sourceContentTypeId.length() > 0) { + sourceContentType = manager.getContentType(sourceContentTypeId); + } + } + + // sources + if (element.hasAttribute(IInputType.SOURCES)) { + String inputs = element.getAttribute(ITool.SOURCES); + if (inputs != null) { + StringTokenizer tokenizer = new StringTokenizer(inputs, DEFAULT_SEPARATOR); + while (tokenizer.hasMoreElements()) { + getInputExtensionsList().add(tokenizer.nextElement()); + } + } + } + + // dependencyContentType + if (element.hasAttribute(IInputType.DEPENDENCY_CONTENT_TYPE)) { + dependencyContentTypeId = element.getAttribute(IInputType.DEPENDENCY_CONTENT_TYPE); + if (dependencyContentTypeId != null && dependencyContentTypeId.length() > 0) { + dependencyContentType = manager.getContentType(dependencyContentTypeId); + } + } + + // dependencyExtensions + // Get the dependency (header file) extensions + if (element.hasAttribute(IInputType.DEPENDENCY_EXTENSIONS)) { + String headers = element.getAttribute(IInputType.DEPENDENCY_EXTENSIONS); + if (headers != null) { + StringTokenizer tokenizer = new StringTokenizer(headers, DEFAULT_SEPARATOR); + while (tokenizer.hasMoreElements()) { + getDependencyExtensionsList().add(tokenizer.nextElement()); + } + } + } + + // option + if (element.hasAttribute(IInputType.OPTION)) { + optionId = element.getAttribute(IInputType.OPTION); + } + + // assignToOption + if (element.hasAttribute(IInputType.ASSIGN_TO_OPTION)) { + assignToOptionId = element.getAttribute(IInputType.ASSIGN_TO_OPTION); + } + + // multipleOfType + if (element.hasAttribute(IInputType.MULTIPLE_OF_TYPE)) { + String isMOT = element.getAttribute(IInputType.MULTIPLE_OF_TYPE); + if (isMOT != null){ + multipleOfType = new Boolean("true".equals(isMOT)); //$NON-NLS-1$ + } + } + + // primaryInput + if (element.hasAttribute(IInputType.PRIMARY_INPUT)) { + String isPI = element.getAttribute(IInputType.PRIMARY_INPUT); + if (isPI != null){ + primaryInput = new Boolean("true".equals(isPI)); //$NON-NLS-1$ + } + } + + // buildVariable + if (element.hasAttribute(IInputType.BUILD_VARIABLE)) { + buildVariable = element.getAttribute(IInputType.BUILD_VARIABLE); + } + + // Note: dependency generator cannot be specified in a project file because + // an IConfigurationElement is needed to load it! + if (element.hasAttribute(ITool.DEP_CALC_ID)) { + // TODO: Issue warning? + } + + return true; + } + + /** + * Persist the InputType to the project file. + * + * @param doc + * @param element + */ + public void serialize(Document doc, Element element) { + if (superClass != null) + element.setAttribute(IProjectType.SUPERCLASS, superClass.getId()); + + element.setAttribute(IBuildObject.ID, id); + + if (name != null) { + element.setAttribute(IBuildObject.NAME, name); + } + + // sourceContentType + if (sourceContentTypeId != null) { + element.setAttribute(IInputType.SOURCE_CONTENT_TYPE, sourceContentTypeId); + } + + // input file extensions + if (getInputExtensionsList().size() > 0) { + String inputs; + List list = getInputExtensionsList(); + Iterator iter = list.listIterator(); + inputs = (String)iter.next(); + while (iter.hasNext()) { + inputs += DEFAULT_SEPARATOR; + inputs += iter.next(); + } + element.setAttribute(IInputType.SOURCES, inputs); + } + + // dependencyContentType + if (dependencyContentTypeId != null) { + element.setAttribute(IInputType.DEPENDENCY_CONTENT_TYPE, dependencyContentTypeId); + } + + // dependency (header file) extensions + if (getDependencyExtensionsList().size() > 0) { + String headers; + List list = getDependencyExtensionsList(); + Iterator iter = list.listIterator(); + headers = (String)iter.next(); + while (iter.hasNext()) { + headers += DEFAULT_SEPARATOR; + headers += iter.next(); + } + element.setAttribute(IInputType.DEPENDENCY_EXTENSIONS, headers); + } + + if (optionId != null) { + element.setAttribute(IInputType.OPTION, optionId); + } + + if (assignToOptionId != null) { + element.setAttribute(IInputType.ASSIGN_TO_OPTION, assignToOptionId); + } + + if (multipleOfType != null) { + element.setAttribute(IInputType.MULTIPLE_OF_TYPE, multipleOfType.toString()); + } + + if (primaryInput != null) { + element.setAttribute(IInputType.PRIMARY_INPUT, primaryInput.toString()); + } + + if (buildVariable != null) { + element.setAttribute(IInputType.BUILD_VARIABLE, buildVariable); + } + + // Note: dependency generator cannot be specified in a project file because + // an IConfigurationElement is needed to load it! + if (dependencyGeneratorElement != null) { + // TODO: issue warning? + } + + // Serialize my children + List childElements = getInputOrderList(); + Iterator iter = childElements.listIterator(); + while (iter.hasNext()) { + InputOrder io = (InputOrder) iter.next(); + Element ioElement = doc.createElement(InputOrder.INPUT_ORDER_ELEMENT_NAME); + element.appendChild(ioElement); + io.serialize(doc, ioElement); + } + childElements = getAdditionalInputList(); + iter = childElements.listIterator(); + while (iter.hasNext()) { + AdditionalInput ai = (AdditionalInput) iter.next(); + Element aiElement = doc.createElement(AdditionalInput.ADDITIONAL_INPUT_ELEMENT_NAME); + element.appendChild(aiElement); + ai.serialize(doc, aiElement); + } + + // I am clean now + isDirty = false; + } + + /* + * P A R E N T A N D C H I L D H A N D L I N G + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getParent() + */ + public ITool getParent() { + return parent; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#createInputOrder() + */ + public IInputOrder createInputOrder(String path) { + InputOrder inputOrder = new InputOrder(this, false); + inputOrder.setPath(path); + getInputOrderList().add(inputOrder); + setDirty(true); + return inputOrder; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getInputOrders() + */ + public IInputOrder[] getInputOrders() { + IInputOrder[] orders; + Vector ours = getInputOrderList(); + orders = (IInputOrder[])ours.toArray(new IInputOrder[ours.size()]); + return orders; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getInputOrder() + */ + public IInputOrder getInputOrder(String path) { + // TODO Convert both paths to absolute? + List orders = getInputOrderList(); + Iterator iter = orders.listIterator(); + while (iter.hasNext()) { + InputOrder io = (InputOrder) iter.next(); + if (path.compareToIgnoreCase(io.getPath()) != 0) { + return io; + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#removeInputOrder() + */ + public void removeInputOrder(String path) { + IInputOrder order = getInputOrder(path); + if (order != null) removeInputOrder(order); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#removeInputOrder() + */ + public void removeInputOrder(IInputOrder element) { + getInputOrderList().remove(element); + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#createAdditionalInput() + */ + public IAdditionalInput createAdditionalInput(String paths) { + AdditionalInput addlInput = new AdditionalInput(this, false); + addlInput.setPaths(paths); + getAdditionalInputList().add(addlInput); + setDirty(true); + return addlInput; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getAdditionalInputs() + */ + public IAdditionalInput[] getAdditionalInputs() { + IAdditionalInput[] inputs; + Vector ours = getAdditionalInputList(); + inputs = (IAdditionalInput[])ours.toArray(new IAdditionalInput[ours.size()]); + return inputs; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getAdditionalInput() + */ + public IAdditionalInput getAdditionalInput(String paths) { + // TODO Convert both paths to absolute? + // Must match all strings + String[] inputTokens = paths.split(";"); //$NON-NLS-1$ + List inputs = getInputOrderList(); + Iterator iter = inputs.listIterator(); + while (iter.hasNext()) { + AdditionalInput ai = (AdditionalInput) iter.next(); + boolean match = false; + String[] tokens = ai.getPaths(); + if (tokens.length == inputTokens.length) { + match = true; + for (int i = 0; i < tokens.length; i++) { + if (tokens[i].compareToIgnoreCase(inputTokens[i]) != 0) { + match = false; + break; + } + } + } + if (match) return ai; + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#removeAdditionalInput() + */ + public void removeAdditionalInput(String path) { + IAdditionalInput input = getAdditionalInput(path); + if (input != null) removeAdditionalInput(input); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#removeAdditionalInput() + */ + public void removeAdditionalInput(IAdditionalInput element) { + getAdditionalInputList().remove(element); + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getAdditionalDependencies() + */ + public IPath[] getAdditionalDependencies() { + List deps = new ArrayList(); + Iterator typeIter = getAdditionalInputList().iterator(); + while (typeIter.hasNext()) { + AdditionalInput current = (AdditionalInput)typeIter.next(); + int kind = current.getKind(); + if (kind == IAdditionalInput.KIND_ADDITIONAL_DEPENDENCY || + kind == IAdditionalInput.KIND_ADDITIONAL_INPUT_DEPENDENCY) { + String[] paths = current.getPaths(); + if (paths != null) { + for (int i = 0; i < paths.length; i++) { + if (paths[i].length() > 0) { + deps.add(Path.fromOSString(paths[i])); + } + } + } + } + } + return (IPath[])deps.toArray(new IPath[deps.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getAdditionalResources() + */ + public IPath[] getAdditionalResources() { + List ins = new ArrayList(); + Iterator typeIter = getAdditionalInputList().iterator(); + while (typeIter.hasNext()) { + AdditionalInput current = (AdditionalInput)typeIter.next(); + int kind = current.getKind(); + if (kind == IAdditionalInput.KIND_ADDITIONAL_INPUT || + kind == IAdditionalInput.KIND_ADDITIONAL_INPUT_DEPENDENCY) { + String[] paths = current.getPaths(); + if (paths != null) { + for (int i = 0; i < paths.length; i++) { + if (paths[i].length() > 0) { + ins.add(Path.fromOSString(paths[i])); + } + } + } + } + } + return (IPath[])ins.toArray(new IPath[ins.size()]); + } + + /* (non-Javadoc) + * Memory-safe way to access the list of input orders + */ + private Vector getInputOrderList() { + if (inputOrderList == null) { + inputOrderList = new Vector(); + } + return inputOrderList; + } + + /* (non-Javadoc) + * Memory-safe way to access the list of input orders + */ + private Vector getAdditionalInputList() { + if (additionalInputList == null) { + additionalInputList = new Vector(); + } + return additionalInputList; + } + + + /* + * M O D E L A T T R I B U T E A C C E S S O R S + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IInputType#getSuperClass() + */ + public IInputType getSuperClass() { + return superClass; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getName() + */ + public String getName() { + return (name == null && superClass != null) ? superClass.getName() : name; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getBuildVariable() + */ + public String getBuildVariable() { + if (buildVariable == null) { + // If I have a superClass, ask it + if (superClass != null) { + return superClass.getBuildVariable(); + } else { + return EMPTY_STRING; + } + } + return buildVariable; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#setBuildVariable() + */ + public void setBuildVariable(String variableName) { + if (variableName == null && buildVariable == null) return; + if (buildVariable == null || variableName == null || !(variableName.equals(buildVariable))) { + buildVariable = variableName; + setDirty(true); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getDependencyContentType() + */ + public IContentType getDependencyContentType() { + if (dependencyContentType == null) { + if (superClass != null) { + return superClass.getDependencyContentType(); + } else { + return null; + } + } + return dependencyContentType; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#setDependencyContentType() + */ + public void setDependencyContentType(IContentType type) { + if (dependencyContentType != type) { + dependencyContentType = type; + if (dependencyContentType != null) { + dependencyContentTypeId = dependencyContentType.getId(); + } else { + dependencyContentTypeId = null; + } + setDirty(true); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getDependencyExtensionsAttribute() + */ + public String[] getDependencyExtensionsAttribute() { + if (dependencyExtensions == null || dependencyExtensions.size() == 0) { + // If I have a superClass, ask it + if (superClass != null) { + return superClass.getDependencyExtensionsAttribute(); + } else { + if (dependencyExtensions == null) { + dependencyExtensions = new ArrayList(); + } + } + } + return (String[])dependencyExtensions.toArray(new String[dependencyExtensions.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#setDependencyExtensionsAttribute() + */ + public void setDependencyExtensionsAttribute(String extensions) { + getDependencyExtensionsList().clear(); + if (extensions != null) { + StringTokenizer tokenizer = new StringTokenizer(extensions, DEFAULT_SEPARATOR); + while (tokenizer.hasMoreElements()) { + getDependencyExtensionsList().add(tokenizer.nextElement()); + } + } + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IInputType#getDependencyExtensions() + */ + public String[] getDependencyExtensions(ITool tool) { + // Use content type if specified and registered with Eclipse + IContentType type = getDependencyContentType(); + if (type != null) { + String[] exts = ((Tool)tool).getContentTypeFileSpecs(type); + // TODO: This is a temporary hack until we decide how to specify the langauge (C vs. C++) + // of a .h file. If the content type is the CDT-defined C/C++ content type, then + // add "h" to the list if it is not already there. + if (type.getId().compareTo("org.eclipse.cdt.core.cxxHeader") == 0) { // $NON-NLS-1$ + boolean h_found = false; + for (int i=0; i 0) { + superClass = ManagedBuildManager.getExtensionInputType(superClassId); + if (superClass == null) { + // Report error + ManagedBuildManager.OutputResolveError( + "superClass", //$NON-NLS-1$ + superClassId, + "inputType", //$NON-NLS-1$ + getId()); + } + } + + // Resolve content types + IContentTypeManager manager = Platform.getContentTypeManager(); + if (sourceContentTypeId != null && sourceContentTypeId.length() > 0) { + sourceContentType = manager.getContentType(sourceContentTypeId); + } + if (dependencyContentTypeId != null && dependencyContentTypeId.length() > 0) { + dependencyContentType = manager.getContentType(dependencyContentTypeId); + } + + // Call resolveReferences on our children + Iterator typeIter = getInputOrderList().iterator(); + while (typeIter.hasNext()) { + InputOrder current = (InputOrder)typeIter.next(); + current.resolveReferences(); + } + typeIter = getAdditionalInputList().iterator(); + while (typeIter.hasNext()) { + AdditionalInput current = (AdditionalInput)typeIter.next(); + current.resolveReferences(); + } + } + } + + /** + * @return Returns the managedBuildRevision. + */ + public String getManagedBuildRevision() { + if ( managedBuildRevision == null) { + if ( getParent() != null) { + return getParent().getManagedBuildRevision(); + } + } + return managedBuildRevision; + } + + /** + * @return Returns the version. + */ + public PluginVersionIdentifier getVersion() { + if ( version == null) { + if ( getParent() != null) { + return getParent().getVersion(); + } + } + return version; + } + + public void setVersion(PluginVersionIdentifier version) { + // Do nothing + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java index 8c59f47b8c4..d454572a0c5 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java @@ -1,1473 +1,1473 @@ -/******************************************************************************* - * Copyright (c) 2002, 2005 IBM Software Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Rational Software - Initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.internal.core; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Vector; - -import org.eclipse.cdt.core.CCProjectNature; -import org.eclipse.cdt.core.CProjectNature; -import org.eclipse.cdt.core.model.CModelException; -import org.eclipse.cdt.core.model.CoreModel; -import org.eclipse.cdt.core.model.ICProject; -import org.eclipse.cdt.core.model.IContainerEntry; -import org.eclipse.cdt.core.model.IIncludeEntry; -import org.eclipse.cdt.core.model.IMacroEntry; -import org.eclipse.cdt.core.model.IPathEntry; -import org.eclipse.cdt.core.model.IPathEntryContainer; -import org.eclipse.cdt.core.parser.IScannerInfo; -import org.eclipse.cdt.managedbuilder.core.BuildException; -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IBuilder; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IEnvVarBuildPath; -import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; -import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; -import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo; -import org.eclipse.cdt.managedbuilder.core.IManagedProject; -import org.eclipse.cdt.managedbuilder.core.IOption; -import org.eclipse.cdt.managedbuilder.core.IOptionApplicability; -import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; -import org.eclipse.cdt.managedbuilder.core.ITarget; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.IToolChain; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; -import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable; -import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider; -import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; -import org.eclipse.cdt.managedbuilder.internal.macros.OptionContextData; -import org.eclipse.cdt.managedbuilder.internal.scannerconfig.ManagedBuildCPathEntryContainer; -import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; -import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.QualifiedName; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; - -/** - * - * @since 1.2 - */ -public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { - // The path container used for all managed projects - public static final IContainerEntry containerEntry = CoreModel.newContainerEntry(new Path("org.eclipse.cdt.managedbuilder.MANAGED_CONTAINER")); //$NON-NLS-1$ - private static final QualifiedName defaultConfigProperty = new QualifiedName(ManagedBuilderCorePlugin.getUniqueIdentifier(), DEFAULT_CONFIGURATION); - //private static final QualifiedName defaultTargetProperty = new QualifiedName(ManagedBuilderCorePlugin.getUniqueIdentifier(), DEFAULT_TARGET); - public static final String MAJOR_SEPERATOR = ";"; //$NON-NLS-1$ - public static final String MINOR_SEPERATOR = "::"; //$NON-NLS-1$ - private static final String EMPTY_STRING = new String(); - - private IManagedProject managedProject; - private ICProject cProject; - private IConfiguration defaultConfig; - private String defaultConfigId; - private boolean isDirty; - private boolean isValid = false; - private IResource owner; - private boolean rebuildNeeded; - private String version; - private IConfiguration selectedConfig; - - private List targetList; - private Map targetMap; - - private boolean isReadOnly = false; - private boolean bIsContainerInited = false; - - - /** - * Basic contructor used when the project is brand new. - * - * @param owner - */ - public ManagedBuildInfo(IResource owner) { - this.owner = owner; - cProject = CoreModel.getDefault().create(owner.getProject()); - - // Does not need a save but should be rebuilt - isDirty = false; - rebuildNeeded = true; - - // Get the default configs - IProject project = owner.getProject(); - defaultConfigId = null; - try { - defaultConfigId = project.getPersistentProperty(defaultConfigProperty); - } catch (CoreException e) { - // Hitting this error just means the default config is not set - return; - } - } - - /** - * Reads the build information from the project file and creates the - * internal representation of the build settings for the project. - * - * @param owner - * @param element - * @param managedBuildRevision - */ - public ManagedBuildInfo(IResource owner, Element element, String managedBuildRevision) { - this(owner); - - // Recreate the managed build project element and its children - NodeList projNodes = element.getElementsByTagName(IManagedProject.MANAGED_PROJECT_ELEMENT_NAME); - // TODO: There should only be 1? - for (int projIndex = projNodes.getLength() - 1; projIndex >= 0; --projIndex) { - ManagedProject proj = new ManagedProject(this, (Element)projNodes.item(projIndex), managedBuildRevision); - if (!proj.resolveReferences()) - proj.setValid(false); - } - - // Switch the rebuild off since this is an existing project - rebuildNeeded = false; - - version = managedBuildRevision; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#setManagedProject(IManagedProject) - */ - public void setManagedProject(IManagedProject managedProject) { - this.managedProject = managedProject; - //setDirty(true); - It is primarily up to the ManagedProject to maintain the dirty state - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getManagedProject() - */ - public IManagedProject getManagedProject() { - return managedProject; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#buildsFileType(java.lang.String) - */ - public boolean buildsFileType(String srcExt) { - // Check to see if there is a rule to build a file with this extension - IConfiguration config = getDefaultConfiguration(); - ITool[] tools = config.getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - if (tool != null && tool.buildsFileType(srcExt)) { - return true; - } - } - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getBuildArtifactExtension() - */ - public String getBuildArtifactExtension() { - String ext = new String(); - IConfiguration config = getDefaultConfiguration(); - if (config != null) { - ext = config.getArtifactExtension(); - } - return ext; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getBuildArtifactName() - */ - public String getBuildArtifactName() { - // Get the default configuration and use its value - String name = new String(); - IConfiguration config = getDefaultConfiguration(); - if (config != null) { - name = config.getArtifactName(); - } - return name; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getCleanCommand() - */ - public String getCleanCommand() { - // Get from the model - String command = new String(); - IConfiguration config = getDefaultConfiguration(); - if (config != null) { - command = config.getCleanCommand(); - } - return command; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getConfigurationName() - */ - public String getConfigurationName() { - // Return the human-readable name of the default configuration - IConfiguration config = getDefaultConfiguration(); - 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 = managedProject.getConfigurations(); - for (int i = 0; i < configs.length; i++) { - IConfiguration configuration = configs[i]; - configNames.add(configuration.getName()); - } - configNames.trimToSize(); - return (String[])configNames.toArray(new String[configNames.size()]); - } - - public ICProject getCProject() { - return cProject; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getDefaultConfiguration() - */ - public IConfiguration getDefaultConfiguration() { - // Get the default config associated with the project - if (defaultConfig == null) { - if (managedProject != null) { - if (defaultConfigId != null) { - defaultConfig = managedProject.getConfiguration(defaultConfigId); - } - if (defaultConfig == null) { - IConfiguration[] configs = managedProject.getConfigurations(); - for (int i = 0; i < configs.length; i++){ - if (configs[i].isSupported()){ - defaultConfig = configs[i]; - defaultConfigId = defaultConfig.getId(); - break; - } - } - if (defaultConfig == null && configs.length > 0) { - defaultConfig = configs[0]; - defaultConfigId = defaultConfig.getId(); - } - } - } - } - return defaultConfig; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IScannerInfo#getDefinedSymbols() - */ - public Map getDefinedSymbols() { - // Return the defined symbols for the default configuration - HashMap symbols = getMacroPathEntries(); - return symbols; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getDependencyGenerator(java.lang.String) - */ - public IManagedDependencyGenerator getDependencyGenerator(String sourceExtension) { - // Find the tool and ask the Managed Build Manager for its dep generator - try { - if (getDefaultConfiguration() != null) { - ITool[] tools = getDefaultConfiguration().getFilteredTools(); - for (int index = 0; index < tools.length; ++index) { - if(tools[index].buildsFileType(sourceExtension)) { - return tools[index].getDependencyGeneratorForExtension(sourceExtension); - } - } - } - } catch (NullPointerException e) { - return null; - } - - return null; - } - - /* (non-Javadoc) - * Helper method to extract a list of valid tools that are filtered by the - * project nature. - * - * @return - */ - private ITool[] getFilteredTools() { - // Get all the tools for the current config filtered by the project nature - IConfiguration config = getDefaultConfiguration(); - return config.getFilteredTools(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getFlagsForSource(java.lang.String) - */ - public String getFlagsForSource(String extension) { - return getToolFlagsForSource(extension,null,null); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getToolFlagsForSource(java.lang.String, org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) - */ - public String getToolFlagsForSource(String extension, IPath inputLocation, IPath outputLocation){ - // Get all the tools for the current config - ITool[] tools = getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - if (tool != null && tool.buildsFileType(extension)) { - try { - return tool.getToolCommandFlagsString(inputLocation,outputLocation); - } catch (BuildException e) { - return null; - } - } - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getFlagsForConfiguration(java.lang.String) - */ - public String getFlagsForConfiguration(String extension) { - return getToolFlagsForConfiguration(extension, null, null); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getToolFlagsForConfiguration(java.lang.String, org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) - */ - public String getToolFlagsForConfiguration(String extension, IPath inputLocation, IPath outputLocation){ - // Treat null extensions as an empty string - String ext = extension == null ? new String() : extension; - - // Get all the tools for the current config - ITool[] tools = getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - if (tool.producesFileType(ext)) { - try { - return tool.getToolCommandFlagsString(inputLocation,outputLocation); - } catch (BuildException e) { - return null; - } - } - } - return null; - } - - private ArrayList getIncludePathEntries() { - // Extract the resolved paths from the project (if any) - ArrayList paths = new ArrayList(); - if (cProject != null) { - try { - IPathEntry[] entries = cProject.getResolvedPathEntries(); - for (int index = 0; index < entries.length; ++index) { - int kind = entries[index].getEntryKind(); - if (kind == IPathEntry.CDT_INCLUDE) { - IIncludeEntry include = (IIncludeEntry) entries[index]; - if (include.isSystemInclude()) { - IPath entryPath = include.getFullIncludePath(); - paths.add(entryPath.toString()); - } - } - } - } catch (CModelException e) { - // Just return an empty array - paths.clear(); - return paths; - } - } - return paths; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IScannerInfo#getIncludePaths() - */ - public String[] getIncludePaths() { - // Return the include paths for the default configuration - ArrayList paths = getIncludePathEntries(); - return (String[])paths.toArray(new String[paths.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getLibsForConfiguration(java.lang.String) - */ - public String[] getLibsForConfiguration(String extension) { - Vector libs = new Vector(); - ITool tool = getDefaultConfiguration().getTargetTool(); - if(tool == null) - tool = getToolFromOutputExtension(extension); - - if(tool != null){ - IOption[] opts = tool.getOptions(); - // Look for the lib option type - for (int i = 0; i < opts.length; i++) { - IOption option = opts[i]; - try { - if (option.getValueType() == IOption.LIBRARIES) { - - // check to see if the option has an applicability calculator - IOptionApplicability applicabilitytCalculator = option.getApplicabilityCalculator(); - - if (applicabilitytCalculator == null - || applicabilitytCalculator.isOptionUsedInCommandLine(getDefaultConfiguration(), tool, option)) { - String command = option.getCommand(); - String[] allLibs = option.getLibraries(); - for (int j = 0; j < allLibs.length; j++) - { - try { - String resolved[] = ManagedBuildManager.getBuildMacroProvider().resolveStringListValueToMakefileFormat( - allLibs[j], - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_OPTION, - new OptionContextData(option, tool)); - if(resolved != null && resolved.length > 0){ - for(int k = 0; k < resolved.length; k++){ - String string = resolved[k]; - if(string.length() > 0) - libs.add(command + string); - } - } - } catch (BuildMacroException e) { - // TODO: report error - continue; - } - - } - } - } - } catch (BuildException e) { - // TODO: report error - continue; - } - } - } - return (String[])libs.toArray(new String[libs.size()]); - } - - private HashMap getMacroPathEntries() { - HashMap macros = new HashMap(); - if (cProject != null) { - try { - IPathEntry[] entries = cProject.getResolvedPathEntries(); - for (int index = 0; index < entries.length; ++index) { - if (entries[index].getEntryKind() == IPathEntry.CDT_MACRO) { - IMacroEntry macro = (IMacroEntry) entries[index]; - macros.put(macro.getMacroName(), macro.getMacroValue()); - } - } - } catch (CModelException e) { - // return an empty map - macros.clear(); - return macros; - } - - } - return macros; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getMakeArguments() - */ - public String getBuildArguments() { - if (getDefaultConfiguration() != null) { - IToolChain toolChain = getDefaultConfiguration().getToolChain(); - IBuilder builder = toolChain.getBuilder(); - if (builder != null) { - return builder.getArguments(); - } - } - return new String("-k"); //$NON-NLS-1$ - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getMakeCommand() - */ - public String getBuildCommand() { - if (getDefaultConfiguration() != null) { - IToolChain toolChain = getDefaultConfiguration().getToolChain(); - IBuilder builder = toolChain.getBuilder(); - if (builder != null) { - return builder.getCommand(); - } - } - return new String("make"); //$NON-NLS-1$ - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getPrebuildStep() - */ - public String getPrebuildStep() { - // Get the default configuration and use its value - String name = new String(); - IConfiguration config = getDefaultConfiguration(); - if (config != null) { - name = config.getPrebuildStep(); - } - return name; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getPostbuildStep() - */ - public String getPostbuildStep() { - // Get the default configuration and use its value - String name = new String(); - IConfiguration config = getDefaultConfiguration(); - if (config != null) { - name = config.getPostbuildStep(); - } - return name; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getPreannouncebuildStep() - */ - public String getPreannouncebuildStep() { - // Get the default configuration and use its value - String name = new String(); - IConfiguration config = getDefaultConfiguration(); - if (config != null) { - name = config.getPreannouncebuildStep(); - } - return name; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getPostannouncebuildStep() - */ - public String getPostannouncebuildStep() { - // Get the default configuration and use its value - String name = new String(); - IConfiguration config = getDefaultConfiguration(); - if (config != null) { - name = config.getPostannouncebuildStep(); - } - return name; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getOutputExtension(java.lang.String) - */ - public String getOutputExtension(String resourceExtension) { - String outputExtension = null; - ITool[] tools = getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - outputExtension = tool.getOutputExtension(resourceExtension); - if (outputExtension != null) { - return outputExtension; - } - } - return null; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getOutputFlag() - */ - public String getOutputFlag(String outputExt) { - // Treat null extension as an empty string - String ext = outputExt == null ? new String() : outputExt; - - // Get all the tools for the current config - String flags = new String(); - ITool[] tools = getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - // It's OK - if (tool.producesFileType(ext)) { - flags = tool.getOutputFlag(); - } - } - return flags; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getOutputPrefix(java.lang.String) - */ - public String getOutputPrefix(String outputExtension) { - // Treat null extensions as empty string - String ext = outputExtension == null ? new String() : outputExtension; - - // Get all the tools for the current config - String flags = new String(); - ITool[] tools = getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - if (tool.producesFileType(ext)) { - flags = tool.getOutputPrefix(); - } - } - return flags; - } - - /** - * @return - */ - public IResource getOwner() { - return owner; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getToolForSource(java.lang.String) - */ - public String getToolForSource(String sourceExtension) { - // Get all the tools for the current config - ITool[] tools = getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - if (tool.buildsFileType(sourceExtension)) { - return tool.getToolCommand(); - } - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getToolForConfiguration(java.lang.String) - */ - public String getToolForConfiguration(String extension) { - // Treat a null argument as an empty string - String ext = extension == null ? new String() : extension; - // Get all the tools for the current config - ITool[] tools = getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - if (tool.producesFileType(ext)) { - return tool.getToolCommand(); - } - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getToolFromInputExtension(java.lang.String) - */ - public ITool getToolFromInputExtension(String sourceExtension) { - // Get all the tools for the current config - ITool[] tools = getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - if (tool.buildsFileType(sourceExtension)) { - return tool; - } - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getToolFromOutputExtension(java.lang.String) - */ - public ITool getToolFromOutputExtension(String extension) { - // Treat a null argument as an empty string - String ext = extension == null ? new String() : extension; - // Get all the tools for the current config - ITool[] tools = getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - if (tool.producesFileType(ext)) { - return tool; - } - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#generateCommandLineInfo(java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String[]) - */ - public IManagedCommandLineInfo generateCommandLineInfo( - String sourceExtension, String[] flags, String outputFlag, - String outputPrefix, String outputName, String[] inputResources) { - return generateToolCommandLineInfo( sourceExtension, flags, - outputFlag, outputPrefix, outputName, inputResources, null, null ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#generateToolCommandLineInfo(java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String[], org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) - */ - public IManagedCommandLineInfo generateToolCommandLineInfo( String sourceExtension, String[] flags, - String outputFlag, String outputPrefix, String outputName, String[] inputResources, IPath inputLocation, IPath outputLocation ){ - ITool[] tools = getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - if (tool.buildsFileType(sourceExtension)) { - String cmd = tool.getToolCommand(); - //try to resolve the build macros in the tool command - try{ - String resolvedCommand = null; - - if ((inputLocation != null && inputLocation.toString().indexOf(" ") != -1) || //$NON-NLS-1$ - (outputLocation != null && outputLocation.toString().indexOf(" ") != -1) ) //$NON-NLS-1$ - { - resolvedCommand = ManagedBuildManager - .getBuildMacroProvider().resolveValue( - cmd, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(inputLocation, - outputLocation, null, - tool)); - } - - else { - resolvedCommand = ManagedBuildManager - .getBuildMacroProvider() - .resolveValueToMakefileFormat( - cmd, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(inputLocation, - outputLocation, null, - tool)); - } - if((resolvedCommand = resolvedCommand.trim()).length() > 0) - cmd = resolvedCommand; - - } catch (BuildMacroException e){ - } - - IManagedCommandLineGenerator gen = tool.getCommandLineGenerator(); - return gen.generateCommandLineInfo( tool, cmd, - flags, outputFlag, outputPrefix, outputName, inputResources, - tool.getCommandLinePattern() ); - } - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getUserObjectsForConfiguration(java.lang.String) - */ - public String[] getUserObjectsForConfiguration(String extension) { - Vector objs = new Vector(); - ITool tool = getDefaultConfiguration().getTargetTool(); - if(tool == null) - tool = getToolFromOutputExtension(extension); - - if(tool != null){ - IOption[] opts = tool.getOptions(); - // Look for the user object option type - for (int i = 0; i < opts.length; i++) { - IOption option = opts[i]; - try { - if (option.getValueType() == IOption.OBJECTS) { - String unresolved[] = option.getUserObjects(); - if(unresolved != null && unresolved.length > 0){ - for(int k = 0; k < unresolved.length; k++){ - try { - String resolved[] = ManagedBuildManager.getBuildMacroProvider().resolveStringListValueToMakefileFormat( - unresolved[k], - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_OPTION, - new OptionContextData(option, tool)); - if(resolved != null && resolved.length > 0) - objs.addAll(Arrays.asList(resolved)); - } catch (BuildMacroException e) { - // TODO: report error - continue; - } - } - } - } - } catch (BuildException e) { - // TODO: report error - continue; - } - } - } - return (String[])objs.toArray(new String[objs.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getVersion() - */ - public String getVersion() { - return version; - } - - /* (non-Javadoc) - * - */ - public void initializePathEntries() { - if (!isValid()) return; - try { - IPathEntryContainer container = new ManagedBuildCPathEntryContainer(getOwner().getProject()); - CoreModel.setPathEntryContainer(new ICProject[]{cProject}, container, new NullProgressMonitor()); - } catch (CModelException e) { - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#isDirty() - */ - public boolean isDirty() { - // If the info has been flagged dirty, answer true - if (isDirty) { - return true; - } - - // Check if the project is dirty - if (managedProject != null) { - return managedProject.isDirty(); - } - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#isValid() - */ - public boolean isValid() { - // If the info has been flagged as valid, answer true - return isValid; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#isReadOnly() - */ - public boolean isReadOnly(){ - return isReadOnly; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#isHeaderFile(java.lang.String) - */ - public boolean isHeaderFile(String ext) { - IProject project = (IProject)owner; - - // Check to see if there is a rule to build a file with this extension - IConfiguration config = getDefaultConfiguration(); - ITool[] tools = config.getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tool = tools[index]; - try { - // Make sure the tool is right for the project - switch (tool.getNatureFilter()) { - case ITool.FILTER_C: - if (project.hasNature(CProjectNature.C_NATURE_ID) && !project.hasNature(CCProjectNature.CC_NATURE_ID)) { - return tool.isHeaderFile(ext); - } - break; - case ITool.FILTER_CC: - if (project.hasNature(CCProjectNature.CC_NATURE_ID)) { - return tool.isHeaderFile(ext); - } - break; - case ITool.FILTER_BOTH: - return tool.isHeaderFile(ext); - } - } catch (CoreException e) { - continue; - } - } - return false; - } - - /** - * - * @return boolean - */ - public boolean isContainerInited() { - return bIsContainerInited; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#needsRebuild() - */ - public boolean needsRebuild() { - if (rebuildNeeded) return true; - - if (getDefaultConfiguration() != null) { - return getDefaultConfiguration().needsRebuild(); - } - return false; - } - - /* (non-Javadoc) - * - */ - private void persistDefaultConfiguration() { - // Persist the default configuration - IProject project = owner.getProject(); - try { - if(defaultConfigId != null) - project.setPersistentProperty(defaultConfigProperty, defaultConfigId.toString().trim()); - } catch (CoreException e) { - // Too bad - } - } - - /** - * Write the contents of the build model to the persistent store - * specified in the argument. - * - * @param doc - * @param element - */ - public void serialize(Document doc, Element element) { - // Write out the managed build project - - if(managedProject != null){ - Element projElement = doc.createElement(IManagedProject.MANAGED_PROJECT_ELEMENT_NAME); - element.appendChild(projElement); - managedProject.serialize(doc, projElement); - } - else{ - Iterator iter = getTargets().listIterator(); - while (iter.hasNext()) { - // Get the target - Target targ = (Target)iter.next(); - // Create an XML element to hold the target settings - Element targetElement = doc.createElement(ITarget.TARGET_ELEMENT_NAME); - element.appendChild(targetElement); - targ.serialize(doc, targetElement); - } -// persistDefaultTarget(); - } - - - // Remember the default configuration - persistDefaultConfiguration(); - - // I'm clean now - setDirty(false); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#setDefaultConfiguration(org.eclipse.cdt.core.build.managed.IConfiguration) - */ - public void setDefaultConfiguration(IConfiguration configuration) { - // TODO: This is probably wrong. I'll bet we don't handle the case where all configs are deleted... - // But, at least, our UI does not allow the last config to be deleted. - // Sanity - if (configuration == null) return; - - if (!configuration.equals(getDefaultConfiguration())) { - // Save it - defaultConfig = configuration; - defaultConfigId = configuration.getId(); - // TODO: is this appropriate? - persistDefaultConfiguration(); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setDefaultConfiguration(java.lang.String) - */ - public boolean setDefaultConfiguration(String configName) { - if (configName != null) { - // Look for the configuration with the same name as the argument - IConfiguration[] configs = managedProject.getConfigurations(); - for (int index = configs.length - 1; index >= 0; --index) { - IConfiguration config = configs[index]; - if (configName.equalsIgnoreCase(config.getName())) { - setDefaultConfiguration(config); - return true; - } - } - } - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setDirty(boolean) - */ - public void setDirty(boolean isDirty) { - // Reset the dirty status here - this.isDirty = isDirty; - // and in the managed project - if (managedProject != null) { - managedProject.setDirty(isDirty); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setValid(boolean) - */ - public void setValid(boolean isValid) { - // Reset the valid status - this.isValid = isValid; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setReadOnly(boolean) - */ - public void setReadOnly(boolean readOnly){ - if(!readOnly && isReadOnly) - setDirty(true); - isReadOnly = readOnly; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setRebuildState(boolean) - */ - public void setRebuildState(boolean rebuild) { - // Reset the status here - rebuildNeeded = rebuild; - // TODO: Is the appropriate? Should the rebuild state be stored in the project file? - // and in the managed project - if (getDefaultConfiguration() != null) { - getDefaultConfiguration().setRebuildState(rebuild); - } - } - - /** - * @param version - */ - public void setVersion(String version) { - if (version != null && !version.equals(this.version)) { - this.version = version; - //setDirty(true); - It is primarily up to the ManagedProject to maintain the dirty state - } - updateRevision(version); - } - - /** - * @param boolean - */ - public void setContainerInited(boolean bInited) { - bIsContainerInited = bInited; - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - public String toString() { - // Just print out the name of the project - return "Managed build information for " + owner.getName(); //$NON-NLS-1$ - } - - /** - * Sets the owner of the receiver to be the IResource specified - * in the argument. - * - * @param resource - */ - public void updateOwner(IResource resource) { - // Check to see if the owner is the same as the argument - if (resource != null) { - if (!owner.equals(resource)) { - owner = resource; - // Do the same for the managed project - managedProject.updateOwner(resource); - // And finally update the cModelElement - cProject = CoreModel.getDefault().create(owner.getProject()); - - // Save everything - setDirty(true); - setRebuildState(true); - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getSelectedConfiguration() - */ - public IConfiguration getSelectedConfiguration() { - return selectedConfig; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#setSelectedConfiguration(org.eclipse.cdt.core.build.managed.IConfiguration) - */ - public void setSelectedConfiguration(IConfiguration config) { - selectedConfig = config; - } - - /* - * Note: "Target" routines are only currently applicable when loading a CDT 2.0 - * or earlier managed build project file (.cdtbuild) - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#addTarget(org.eclipse.cdt.core.build.managed.ITarget) - */ - public void addTarget(ITarget target) { - getTargetMap().put(target.getId(), target); - getTargets().add(target); - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#removeTarget(java.lang.String) - */ - public void removeTarget(String id) { - getTargets().remove(getTarget(id)); - getTargetMap().remove(id); - setDirty(true); - - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getTarget(org.eclipse.cdt.core.build.managed.IConfiguration) - */ - public ITarget getTarget(String id) { - return (ITarget) getTargetMap().get(id); - } - - /* (non-Javadoc) - * Safe accessor. - * - * @return Returns the map of IDs to ITargets. - */ - private Map getTargetMap() { - if (targetMap == null) { - targetMap = new HashMap(); - } - return targetMap; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getTargets(org.eclipse.cdt.core.build.managed.IConfiguration) - */ - public List getTargets() { - if (targetList == null) { - targetList = new ArrayList(); - } - return targetList; - } - - /** - * - * @return - */ - private String getCWD() { - String cwd = ""; //$NON-NLS-1$ - IBuildEnvironmentVariable cwdvar = ManagedBuildManager.getEnvironmentVariableProvider().getVariable("CWD", getDefaultConfiguration(), false, true); //$NON-NLS-1$ - if (cwdvar != null) { cwd = cwdvar.getValue().replace('\\','/'); } //$NON-NLS-1$ //$NON-NLS-2$ - return cwd; - } - - /** - */ - private List processPath(List list, String path, int context, Object obj) { - final String EMPTY = ""; //$NON-NLS-1$ - if (path != null) { - if (context != 0) { - try { - String paths[] = ManagedBuildManager.getBuildMacroProvider().resolveStringListValue(path, EMPTY, " ", context, obj); //$NON-NLS-1$ - if (paths != null) { - for(int i = 0; i < paths.length; i++){ - list.add(checkPath(paths[i])); - } - } - } catch (BuildMacroException e) { - } - } else { - list.add(checkPath(path)); - } - } - return list; - } - - private String checkPath(String p){ - final String QUOTE = "\""; //$NON-NLS-1$ - final String EMPTY = ""; //$NON-NLS-1$ - - if(p == null) - return EMPTY; - - if (p.length()> 1 && p.startsWith(QUOTE) && p.endsWith(QUOTE)) { - p = p.substring(1, p.length()-1); - } - - if ( ".".equals(p) ) { //$NON-NLS-1$ - String cwd = getCWD(); - if (cwd.length()>0) { p = cwd; } - } - if (!(new Path(p)).isAbsolute()) { - String cwd = getCWD(); - if (cwd.length()>0) { p = cwd + "/" + p; } //$NON-NLS-1$ - } - return p; - - } - - /** - * Obtain all possible Managed build values - * @return - */ - public IPathEntry[] getManagedBuildValues() { - List entries = new ArrayList(); - int i=0; - IPathEntry[] a = getManagedBuildValues(IPathEntry.CDT_INCLUDE); - if (a != null) { for (i=0; i 0) { - List list = new ArrayList(); - for (int k=0; k 1) ? tokens[1].trim() : new String(); - // Make sure the current entries do not contain a duplicate - boolean add = true; - Iterator entryIter = entries.listIterator(); - while (entryIter.hasNext()) { - IPathEntry entry = (IPathEntry) entryIter.next(); - if (entry.getEntryKind() == IPathEntry.CDT_MACRO) { - if (((IMacroEntry)entry).getMacroName().equals(key) && - ((IMacroEntry)entry).getMacroValue().equals(value)) { - add = false; - break; - } - } - } - if (add) { entries.add(CoreModel.newMacroEntry(resPath, key, value)); } - } - return entries; - } - - public void updateRevision(String revision){ - if(managedProject != null) - ((ManagedProject)managedProject).updateManagedBuildRevision(revision); - } - -} +/******************************************************************************* + * Copyright (c) 2002, 2006 IBM Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.core; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Vector; + +import org.eclipse.cdt.core.CCProjectNature; +import org.eclipse.cdt.core.CProjectNature; +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.IContainerEntry; +import org.eclipse.cdt.core.model.IIncludeEntry; +import org.eclipse.cdt.core.model.IMacroEntry; +import org.eclipse.cdt.core.model.IPathEntry; +import org.eclipse.cdt.core.model.IPathEntryContainer; +import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IBuilder; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IEnvVarBuildPath; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; +import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedProject; +import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.cdt.managedbuilder.core.IOptionApplicability; +import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITarget; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; +import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable; +import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider; +import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; +import org.eclipse.cdt.managedbuilder.internal.macros.OptionContextData; +import org.eclipse.cdt.managedbuilder.internal.scannerconfig.ManagedBuildCPathEntryContainer; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.QualifiedName; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +/** + * + * @since 1.2 + */ +public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { + // The path container used for all managed projects + public static final IContainerEntry containerEntry = CoreModel.newContainerEntry(new Path("org.eclipse.cdt.managedbuilder.MANAGED_CONTAINER")); //$NON-NLS-1$ + private static final QualifiedName defaultConfigProperty = new QualifiedName(ManagedBuilderCorePlugin.getUniqueIdentifier(), DEFAULT_CONFIGURATION); + //private static final QualifiedName defaultTargetProperty = new QualifiedName(ManagedBuilderCorePlugin.getUniqueIdentifier(), DEFAULT_TARGET); + public static final String MAJOR_SEPERATOR = ";"; //$NON-NLS-1$ + public static final String MINOR_SEPERATOR = "::"; //$NON-NLS-1$ + private static final String EMPTY_STRING = new String(); + + private IManagedProject managedProject; + private ICProject cProject; + private IConfiguration defaultConfig; + private String defaultConfigId; + private boolean isDirty; + private boolean isValid = false; + private IResource owner; + private boolean rebuildNeeded; + private String version; + private IConfiguration selectedConfig; + + private List targetList; + private Map targetMap; + + private boolean isReadOnly = false; + private boolean bIsContainerInited = false; + + + /** + * Basic contructor used when the project is brand new. + * + * @param owner + */ + public ManagedBuildInfo(IResource owner) { + this.owner = owner; + cProject = CoreModel.getDefault().create(owner.getProject()); + + // Does not need a save but should be rebuilt + isDirty = false; + rebuildNeeded = true; + + // Get the default configs + IProject project = owner.getProject(); + defaultConfigId = null; + try { + defaultConfigId = project.getPersistentProperty(defaultConfigProperty); + } catch (CoreException e) { + // Hitting this error just means the default config is not set + return; + } + } + + /** + * Reads the build information from the project file and creates the + * internal representation of the build settings for the project. + * + * @param owner + * @param element + * @param managedBuildRevision + */ + public ManagedBuildInfo(IResource owner, Element element, String managedBuildRevision) { + this(owner); + + // Recreate the managed build project element and its children + NodeList projNodes = element.getElementsByTagName(IManagedProject.MANAGED_PROJECT_ELEMENT_NAME); + // TODO: There should only be 1? + for (int projIndex = projNodes.getLength() - 1; projIndex >= 0; --projIndex) { + ManagedProject proj = new ManagedProject(this, (Element)projNodes.item(projIndex), managedBuildRevision); + if (!proj.resolveReferences()) + proj.setValid(false); + } + + // Switch the rebuild off since this is an existing project + rebuildNeeded = false; + + version = managedBuildRevision; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#setManagedProject(IManagedProject) + */ + public void setManagedProject(IManagedProject managedProject) { + this.managedProject = managedProject; + //setDirty(true); - It is primarily up to the ManagedProject to maintain the dirty state + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getManagedProject() + */ + public IManagedProject getManagedProject() { + return managedProject; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#buildsFileType(java.lang.String) + */ + public boolean buildsFileType(String srcExt) { + // Check to see if there is a rule to build a file with this extension + IConfiguration config = getDefaultConfiguration(); + ITool[] tools = config.getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + if (tool != null && tool.buildsFileType(srcExt)) { + return true; + } + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getBuildArtifactExtension() + */ + public String getBuildArtifactExtension() { + String ext = new String(); + IConfiguration config = getDefaultConfiguration(); + if (config != null) { + ext = config.getArtifactExtension(); + } + return ext; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getBuildArtifactName() + */ + public String getBuildArtifactName() { + // Get the default configuration and use its value + String name = new String(); + IConfiguration config = getDefaultConfiguration(); + if (config != null) { + name = config.getArtifactName(); + } + return name; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getCleanCommand() + */ + public String getCleanCommand() { + // Get from the model + String command = new String(); + IConfiguration config = getDefaultConfiguration(); + if (config != null) { + command = config.getCleanCommand(); + } + return command; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getConfigurationName() + */ + public String getConfigurationName() { + // Return the human-readable name of the default configuration + IConfiguration config = getDefaultConfiguration(); + 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 = managedProject.getConfigurations(); + for (int i = 0; i < configs.length; i++) { + IConfiguration configuration = configs[i]; + configNames.add(configuration.getName()); + } + configNames.trimToSize(); + return (String[])configNames.toArray(new String[configNames.size()]); + } + + public ICProject getCProject() { + return cProject; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getDefaultConfiguration() + */ + public IConfiguration getDefaultConfiguration() { + // Get the default config associated with the project + if (defaultConfig == null) { + if (managedProject != null) { + if (defaultConfigId != null) { + defaultConfig = managedProject.getConfiguration(defaultConfigId); + } + if (defaultConfig == null) { + IConfiguration[] configs = managedProject.getConfigurations(); + for (int i = 0; i < configs.length; i++){ + if (configs[i].isSupported()){ + defaultConfig = configs[i]; + defaultConfigId = defaultConfig.getId(); + break; + } + } + if (defaultConfig == null && configs.length > 0) { + defaultConfig = configs[0]; + defaultConfigId = defaultConfig.getId(); + } + } + } + } + return defaultConfig; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IScannerInfo#getDefinedSymbols() + */ + public Map getDefinedSymbols() { + // Return the defined symbols for the default configuration + HashMap symbols = getMacroPathEntries(); + return symbols; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getDependencyGenerator(java.lang.String) + */ + public IManagedDependencyGeneratorType getDependencyGenerator(String sourceExtension) { + // Find the tool and ask the Managed Build Manager for its dep generator + try { + if (getDefaultConfiguration() != null) { + ITool[] tools = getDefaultConfiguration().getFilteredTools(); + for (int index = 0; index < tools.length; ++index) { + if(tools[index].buildsFileType(sourceExtension)) { + return tools[index].getDependencyGeneratorForExtension(sourceExtension); + } + } + } + } catch (NullPointerException e) { + return null; + } + + return null; + } + + /* (non-Javadoc) + * Helper method to extract a list of valid tools that are filtered by the + * project nature. + * + * @return + */ + private ITool[] getFilteredTools() { + // Get all the tools for the current config filtered by the project nature + IConfiguration config = getDefaultConfiguration(); + return config.getFilteredTools(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getFlagsForSource(java.lang.String) + */ + public String getFlagsForSource(String extension) { + return getToolFlagsForSource(extension,null,null); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getToolFlagsForSource(java.lang.String, org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) + */ + public String getToolFlagsForSource(String extension, IPath inputLocation, IPath outputLocation){ + // Get all the tools for the current config + ITool[] tools = getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + if (tool != null && tool.buildsFileType(extension)) { + try { + return tool.getToolCommandFlagsString(inputLocation,outputLocation); + } catch (BuildException e) { + return null; + } + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getFlagsForConfiguration(java.lang.String) + */ + public String getFlagsForConfiguration(String extension) { + return getToolFlagsForConfiguration(extension, null, null); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getToolFlagsForConfiguration(java.lang.String, org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) + */ + public String getToolFlagsForConfiguration(String extension, IPath inputLocation, IPath outputLocation){ + // Treat null extensions as an empty string + String ext = extension == null ? new String() : extension; + + // Get all the tools for the current config + ITool[] tools = getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + if (tool.producesFileType(ext)) { + try { + return tool.getToolCommandFlagsString(inputLocation,outputLocation); + } catch (BuildException e) { + return null; + } + } + } + return null; + } + + private ArrayList getIncludePathEntries() { + // Extract the resolved paths from the project (if any) + ArrayList paths = new ArrayList(); + if (cProject != null) { + try { + IPathEntry[] entries = cProject.getResolvedPathEntries(); + for (int index = 0; index < entries.length; ++index) { + int kind = entries[index].getEntryKind(); + if (kind == IPathEntry.CDT_INCLUDE) { + IIncludeEntry include = (IIncludeEntry) entries[index]; + if (include.isSystemInclude()) { + IPath entryPath = include.getFullIncludePath(); + paths.add(entryPath.toString()); + } + } + } + } catch (CModelException e) { + // Just return an empty array + paths.clear(); + return paths; + } + } + return paths; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IScannerInfo#getIncludePaths() + */ + public String[] getIncludePaths() { + // Return the include paths for the default configuration + ArrayList paths = getIncludePathEntries(); + return (String[])paths.toArray(new String[paths.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getLibsForConfiguration(java.lang.String) + */ + public String[] getLibsForConfiguration(String extension) { + Vector libs = new Vector(); + ITool tool = getDefaultConfiguration().getTargetTool(); + if(tool == null) + tool = getToolFromOutputExtension(extension); + + if(tool != null){ + IOption[] opts = tool.getOptions(); + // Look for the lib option type + for (int i = 0; i < opts.length; i++) { + IOption option = opts[i]; + try { + if (option.getValueType() == IOption.LIBRARIES) { + + // check to see if the option has an applicability calculator + IOptionApplicability applicabilitytCalculator = option.getApplicabilityCalculator(); + + if (applicabilitytCalculator == null + || applicabilitytCalculator.isOptionUsedInCommandLine(getDefaultConfiguration(), tool, option)) { + String command = option.getCommand(); + String[] allLibs = option.getLibraries(); + for (int j = 0; j < allLibs.length; j++) + { + try { + String resolved[] = ManagedBuildManager.getBuildMacroProvider().resolveStringListValueToMakefileFormat( + allLibs[j], + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_OPTION, + new OptionContextData(option, tool)); + if(resolved != null && resolved.length > 0){ + for(int k = 0; k < resolved.length; k++){ + String string = resolved[k]; + if(string.length() > 0) + libs.add(command + string); + } + } + } catch (BuildMacroException e) { + // TODO: report error + continue; + } + + } + } + } + } catch (BuildException e) { + // TODO: report error + continue; + } + } + } + return (String[])libs.toArray(new String[libs.size()]); + } + + private HashMap getMacroPathEntries() { + HashMap macros = new HashMap(); + if (cProject != null) { + try { + IPathEntry[] entries = cProject.getResolvedPathEntries(); + for (int index = 0; index < entries.length; ++index) { + if (entries[index].getEntryKind() == IPathEntry.CDT_MACRO) { + IMacroEntry macro = (IMacroEntry) entries[index]; + macros.put(macro.getMacroName(), macro.getMacroValue()); + } + } + } catch (CModelException e) { + // return an empty map + macros.clear(); + return macros; + } + + } + return macros; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getMakeArguments() + */ + public String getBuildArguments() { + if (getDefaultConfiguration() != null) { + IToolChain toolChain = getDefaultConfiguration().getToolChain(); + IBuilder builder = toolChain.getBuilder(); + if (builder != null) { + return builder.getArguments(); + } + } + return new String("-k"); //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getMakeCommand() + */ + public String getBuildCommand() { + if (getDefaultConfiguration() != null) { + IToolChain toolChain = getDefaultConfiguration().getToolChain(); + IBuilder builder = toolChain.getBuilder(); + if (builder != null) { + return builder.getCommand(); + } + } + return new String("make"); //$NON-NLS-1$ + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getPrebuildStep() + */ + public String getPrebuildStep() { + // Get the default configuration and use its value + String name = new String(); + IConfiguration config = getDefaultConfiguration(); + if (config != null) { + name = config.getPrebuildStep(); + } + return name; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getPostbuildStep() + */ + public String getPostbuildStep() { + // Get the default configuration and use its value + String name = new String(); + IConfiguration config = getDefaultConfiguration(); + if (config != null) { + name = config.getPostbuildStep(); + } + return name; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getPreannouncebuildStep() + */ + public String getPreannouncebuildStep() { + // Get the default configuration and use its value + String name = new String(); + IConfiguration config = getDefaultConfiguration(); + if (config != null) { + name = config.getPreannouncebuildStep(); + } + return name; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getPostannouncebuildStep() + */ + public String getPostannouncebuildStep() { + // Get the default configuration and use its value + String name = new String(); + IConfiguration config = getDefaultConfiguration(); + if (config != null) { + name = config.getPostannouncebuildStep(); + } + return name; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getOutputExtension(java.lang.String) + */ + public String getOutputExtension(String resourceExtension) { + String outputExtension = null; + ITool[] tools = getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + outputExtension = tool.getOutputExtension(resourceExtension); + if (outputExtension != null) { + return outputExtension; + } + } + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getOutputFlag() + */ + public String getOutputFlag(String outputExt) { + // Treat null extension as an empty string + String ext = outputExt == null ? new String() : outputExt; + + // Get all the tools for the current config + String flags = new String(); + ITool[] tools = getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + // It's OK + if (tool.producesFileType(ext)) { + flags = tool.getOutputFlag(); + } + } + return flags; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getOutputPrefix(java.lang.String) + */ + public String getOutputPrefix(String outputExtension) { + // Treat null extensions as empty string + String ext = outputExtension == null ? new String() : outputExtension; + + // Get all the tools for the current config + String flags = new String(); + ITool[] tools = getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + if (tool.producesFileType(ext)) { + flags = tool.getOutputPrefix(); + } + } + return flags; + } + + /** + * @return + */ + public IResource getOwner() { + return owner; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getToolForSource(java.lang.String) + */ + public String getToolForSource(String sourceExtension) { + // Get all the tools for the current config + ITool[] tools = getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + if (tool.buildsFileType(sourceExtension)) { + return tool.getToolCommand(); + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getToolForConfiguration(java.lang.String) + */ + public String getToolForConfiguration(String extension) { + // Treat a null argument as an empty string + String ext = extension == null ? new String() : extension; + // Get all the tools for the current config + ITool[] tools = getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + if (tool.producesFileType(ext)) { + return tool.getToolCommand(); + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getToolFromInputExtension(java.lang.String) + */ + public ITool getToolFromInputExtension(String sourceExtension) { + // Get all the tools for the current config + ITool[] tools = getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + if (tool.buildsFileType(sourceExtension)) { + return tool; + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getToolFromOutputExtension(java.lang.String) + */ + public ITool getToolFromOutputExtension(String extension) { + // Treat a null argument as an empty string + String ext = extension == null ? new String() : extension; + // Get all the tools for the current config + ITool[] tools = getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + if (tool.producesFileType(ext)) { + return tool; + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#generateCommandLineInfo(java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String[]) + */ + public IManagedCommandLineInfo generateCommandLineInfo( + String sourceExtension, String[] flags, String outputFlag, + String outputPrefix, String outputName, String[] inputResources) { + return generateToolCommandLineInfo( sourceExtension, flags, + outputFlag, outputPrefix, outputName, inputResources, null, null ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#generateToolCommandLineInfo(java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String[], org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) + */ + public IManagedCommandLineInfo generateToolCommandLineInfo( String sourceExtension, String[] flags, + String outputFlag, String outputPrefix, String outputName, String[] inputResources, IPath inputLocation, IPath outputLocation ){ + ITool[] tools = getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + if (tool.buildsFileType(sourceExtension)) { + String cmd = tool.getToolCommand(); + //try to resolve the build macros in the tool command + try{ + String resolvedCommand = null; + + if ((inputLocation != null && inputLocation.toString().indexOf(" ") != -1) || //$NON-NLS-1$ + (outputLocation != null && outputLocation.toString().indexOf(" ") != -1) ) //$NON-NLS-1$ + { + resolvedCommand = ManagedBuildManager + .getBuildMacroProvider().resolveValue( + cmd, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(inputLocation, + outputLocation, null, + tool)); + } + + else { + resolvedCommand = ManagedBuildManager + .getBuildMacroProvider() + .resolveValueToMakefileFormat( + cmd, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(inputLocation, + outputLocation, null, + tool)); + } + if((resolvedCommand = resolvedCommand.trim()).length() > 0) + cmd = resolvedCommand; + + } catch (BuildMacroException e){ + } + + IManagedCommandLineGenerator gen = tool.getCommandLineGenerator(); + return gen.generateCommandLineInfo( tool, cmd, + flags, outputFlag, outputPrefix, outputName, inputResources, + tool.getCommandLinePattern() ); + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getUserObjectsForConfiguration(java.lang.String) + */ + public String[] getUserObjectsForConfiguration(String extension) { + Vector objs = new Vector(); + ITool tool = getDefaultConfiguration().getTargetTool(); + if(tool == null) + tool = getToolFromOutputExtension(extension); + + if(tool != null){ + IOption[] opts = tool.getOptions(); + // Look for the user object option type + for (int i = 0; i < opts.length; i++) { + IOption option = opts[i]; + try { + if (option.getValueType() == IOption.OBJECTS) { + String unresolved[] = option.getUserObjects(); + if(unresolved != null && unresolved.length > 0){ + for(int k = 0; k < unresolved.length; k++){ + try { + String resolved[] = ManagedBuildManager.getBuildMacroProvider().resolveStringListValueToMakefileFormat( + unresolved[k], + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_OPTION, + new OptionContextData(option, tool)); + if(resolved != null && resolved.length > 0) + objs.addAll(Arrays.asList(resolved)); + } catch (BuildMacroException e) { + // TODO: report error + continue; + } + } + } + } + } catch (BuildException e) { + // TODO: report error + continue; + } + } + } + return (String[])objs.toArray(new String[objs.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getVersion() + */ + public String getVersion() { + return version; + } + + /* (non-Javadoc) + * + */ + public void initializePathEntries() { + if (!isValid()) return; + try { + IPathEntryContainer container = new ManagedBuildCPathEntryContainer(getOwner().getProject()); + CoreModel.setPathEntryContainer(new ICProject[]{cProject}, container, new NullProgressMonitor()); + } catch (CModelException e) { + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#isDirty() + */ + public boolean isDirty() { + // If the info has been flagged dirty, answer true + if (isDirty) { + return true; + } + + // Check if the project is dirty + if (managedProject != null) { + return managedProject.isDirty(); + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#isValid() + */ + public boolean isValid() { + // If the info has been flagged as valid, answer true + return isValid; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#isReadOnly() + */ + public boolean isReadOnly(){ + return isReadOnly; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#isHeaderFile(java.lang.String) + */ + public boolean isHeaderFile(String ext) { + IProject project = (IProject)owner; + + // Check to see if there is a rule to build a file with this extension + IConfiguration config = getDefaultConfiguration(); + ITool[] tools = config.getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tool = tools[index]; + try { + // Make sure the tool is right for the project + switch (tool.getNatureFilter()) { + case ITool.FILTER_C: + if (project.hasNature(CProjectNature.C_NATURE_ID) && !project.hasNature(CCProjectNature.CC_NATURE_ID)) { + return tool.isHeaderFile(ext); + } + break; + case ITool.FILTER_CC: + if (project.hasNature(CCProjectNature.CC_NATURE_ID)) { + return tool.isHeaderFile(ext); + } + break; + case ITool.FILTER_BOTH: + return tool.isHeaderFile(ext); + } + } catch (CoreException e) { + continue; + } + } + return false; + } + + /** + * + * @return boolean + */ + public boolean isContainerInited() { + return bIsContainerInited; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#needsRebuild() + */ + public boolean needsRebuild() { + if (rebuildNeeded) return true; + + if (getDefaultConfiguration() != null) { + return getDefaultConfiguration().needsRebuild(); + } + return false; + } + + /* (non-Javadoc) + * + */ + private void persistDefaultConfiguration() { + // Persist the default configuration + IProject project = owner.getProject(); + try { + if(defaultConfigId != null) + project.setPersistentProperty(defaultConfigProperty, defaultConfigId.toString().trim()); + } catch (CoreException e) { + // Too bad + } + } + + /** + * Write the contents of the build model to the persistent store + * specified in the argument. + * + * @param doc + * @param element + */ + public void serialize(Document doc, Element element) { + // Write out the managed build project + + if(managedProject != null){ + Element projElement = doc.createElement(IManagedProject.MANAGED_PROJECT_ELEMENT_NAME); + element.appendChild(projElement); + managedProject.serialize(doc, projElement); + } + else{ + Iterator iter = getTargets().listIterator(); + while (iter.hasNext()) { + // Get the target + Target targ = (Target)iter.next(); + // Create an XML element to hold the target settings + Element targetElement = doc.createElement(ITarget.TARGET_ELEMENT_NAME); + element.appendChild(targetElement); + targ.serialize(doc, targetElement); + } +// persistDefaultTarget(); + } + + + // Remember the default configuration + persistDefaultConfiguration(); + + // I'm clean now + setDirty(false); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#setDefaultConfiguration(org.eclipse.cdt.core.build.managed.IConfiguration) + */ + public void setDefaultConfiguration(IConfiguration configuration) { + // TODO: This is probably wrong. I'll bet we don't handle the case where all configs are deleted... + // But, at least, our UI does not allow the last config to be deleted. + // Sanity + if (configuration == null) return; + + if (!configuration.equals(getDefaultConfiguration())) { + // Save it + defaultConfig = configuration; + defaultConfigId = configuration.getId(); + // TODO: is this appropriate? + persistDefaultConfiguration(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setDefaultConfiguration(java.lang.String) + */ + public boolean setDefaultConfiguration(String configName) { + if (configName != null) { + // Look for the configuration with the same name as the argument + IConfiguration[] configs = managedProject.getConfigurations(); + for (int index = configs.length - 1; index >= 0; --index) { + IConfiguration config = configs[index]; + if (configName.equalsIgnoreCase(config.getName())) { + setDefaultConfiguration(config); + return true; + } + } + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setDirty(boolean) + */ + public void setDirty(boolean isDirty) { + // Reset the dirty status here + this.isDirty = isDirty; + // and in the managed project + if (managedProject != null) { + managedProject.setDirty(isDirty); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setValid(boolean) + */ + public void setValid(boolean isValid) { + // Reset the valid status + this.isValid = isValid; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setReadOnly(boolean) + */ + public void setReadOnly(boolean readOnly){ + if(!readOnly && isReadOnly) + setDirty(true); + isReadOnly = readOnly; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setRebuildState(boolean) + */ + public void setRebuildState(boolean rebuild) { + // Reset the status here + rebuildNeeded = rebuild; + // TODO: Is the appropriate? Should the rebuild state be stored in the project file? + // and in the managed project + if (getDefaultConfiguration() != null) { + getDefaultConfiguration().setRebuildState(rebuild); + } + } + + /** + * @param version + */ + public void setVersion(String version) { + if (version != null && !version.equals(this.version)) { + this.version = version; + //setDirty(true); - It is primarily up to the ManagedProject to maintain the dirty state + } + updateRevision(version); + } + + /** + * @param boolean + */ + public void setContainerInited(boolean bInited) { + bIsContainerInited = bInited; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + // Just print out the name of the project + return "Managed build information for " + owner.getName(); //$NON-NLS-1$ + } + + /** + * Sets the owner of the receiver to be the IResource specified + * in the argument. + * + * @param resource + */ + public void updateOwner(IResource resource) { + // Check to see if the owner is the same as the argument + if (resource != null) { + if (!owner.equals(resource)) { + owner = resource; + // Do the same for the managed project + managedProject.updateOwner(resource); + // And finally update the cModelElement + cProject = CoreModel.getDefault().create(owner.getProject()); + + // Save everything + setDirty(true); + setRebuildState(true); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getSelectedConfiguration() + */ + public IConfiguration getSelectedConfiguration() { + return selectedConfig; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#setSelectedConfiguration(org.eclipse.cdt.core.build.managed.IConfiguration) + */ + public void setSelectedConfiguration(IConfiguration config) { + selectedConfig = config; + } + + /* + * Note: "Target" routines are only currently applicable when loading a CDT 2.0 + * or earlier managed build project file (.cdtbuild) + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#addTarget(org.eclipse.cdt.core.build.managed.ITarget) + */ + public void addTarget(ITarget target) { + getTargetMap().put(target.getId(), target); + getTargets().add(target); + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#removeTarget(java.lang.String) + */ + public void removeTarget(String id) { + getTargets().remove(getTarget(id)); + getTargetMap().remove(id); + setDirty(true); + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getTarget(org.eclipse.cdt.core.build.managed.IConfiguration) + */ + public ITarget getTarget(String id) { + return (ITarget) getTargetMap().get(id); + } + + /* (non-Javadoc) + * Safe accessor. + * + * @return Returns the map of IDs to ITargets. + */ + private Map getTargetMap() { + if (targetMap == null) { + targetMap = new HashMap(); + } + return targetMap; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getTargets(org.eclipse.cdt.core.build.managed.IConfiguration) + */ + public List getTargets() { + if (targetList == null) { + targetList = new ArrayList(); + } + return targetList; + } + + /** + * + * @return + */ + private String getCWD() { + String cwd = ""; //$NON-NLS-1$ + IBuildEnvironmentVariable cwdvar = ManagedBuildManager.getEnvironmentVariableProvider().getVariable("CWD", getDefaultConfiguration(), false, true); //$NON-NLS-1$ + if (cwdvar != null) { cwd = cwdvar.getValue().replace('\\','/'); } //$NON-NLS-1$ //$NON-NLS-2$ + return cwd; + } + + /** + */ + private List processPath(List list, String path, int context, Object obj) { + final String EMPTY = ""; //$NON-NLS-1$ + if (path != null) { + if (context != 0) { + try { + String paths[] = ManagedBuildManager.getBuildMacroProvider().resolveStringListValue(path, EMPTY, " ", context, obj); //$NON-NLS-1$ + if (paths != null) { + for(int i = 0; i < paths.length; i++){ + list.add(checkPath(paths[i])); + } + } + } catch (BuildMacroException e) { + } + } else { + list.add(checkPath(path)); + } + } + return list; + } + + private String checkPath(String p){ + final String QUOTE = "\""; //$NON-NLS-1$ + final String EMPTY = ""; //$NON-NLS-1$ + + if(p == null) + return EMPTY; + + if (p.length()> 1 && p.startsWith(QUOTE) && p.endsWith(QUOTE)) { + p = p.substring(1, p.length()-1); + } + + if ( ".".equals(p) ) { //$NON-NLS-1$ + String cwd = getCWD(); + if (cwd.length()>0) { p = cwd; } + } + if (!(new Path(p)).isAbsolute()) { + String cwd = getCWD(); + if (cwd.length()>0) { p = cwd + "/" + p; } //$NON-NLS-1$ + } + return p; + + } + + /** + * Obtain all possible Managed build values + * @return + */ + public IPathEntry[] getManagedBuildValues() { + List entries = new ArrayList(); + int i=0; + IPathEntry[] a = getManagedBuildValues(IPathEntry.CDT_INCLUDE); + if (a != null) { for (i=0; i 0) { + List list = new ArrayList(); + for (int k=0; k 1) ? tokens[1].trim() : new String(); + // Make sure the current entries do not contain a duplicate + boolean add = true; + Iterator entryIter = entries.listIterator(); + while (entryIter.hasNext()) { + IPathEntry entry = (IPathEntry) entryIter.next(); + if (entry.getEntryKind() == IPathEntry.CDT_MACRO) { + if (((IMacroEntry)entry).getMacroName().equals(key) && + ((IMacroEntry)entry).getMacroValue().equals(value)) { + add = false; + break; + } + } + } + if (add) { entries.add(CoreModel.newMacroEntry(resPath, key, value)); } + } + return entries; + } + + public void updateRevision(String revision){ + if(managedProject != null) + ((ManagedProject)managedProject).updateManagedBuildRevision(revision); + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedProject.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedProject.java index ff3b433773f..1d3d52488e2 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedProject.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedProject.java @@ -1,524 +1,535 @@ -/******************************************************************************* - * Copyright (c) 2004, 2005 Intel Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Intel Corporation - Initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.internal.core; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; -import org.eclipse.cdt.managedbuilder.core.IManagedOptionValueHandler; -import org.eclipse.cdt.managedbuilder.core.IManagedProject; -import org.eclipse.cdt.managedbuilder.core.IProjectType; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.internal.envvar.EnvironmentVariableProvider; -import org.eclipse.cdt.managedbuilder.internal.envvar.StorableEnvironment; -import org.eclipse.cdt.managedbuilder.internal.macros.StorableMacros; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspaceRunnable; -import org.eclipse.core.resources.IncrementalProjectBuilder; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.PluginVersionIdentifier; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -public class ManagedProject extends BuildObject implements IManagedProject { - - private static final String EMPTY_STRING = new String(); - private static final IConfiguration[] emptyConfigs = new IConfiguration[0]; - - // Parent and children - private IProjectType projectType; - private String projectTypeId; - private IResource owner; - private List configList; // Configurations of this project type - private Map configMap; - // Miscellaneous - private boolean isDirty = false; - private boolean isValid = true; - private boolean resolved = true; - //holds the user-defined macros - private StorableMacros userDefinedMacros; - //holds user-defined environment - private StorableEnvironment userDefinedEnvironment; - /* - * C O N S T R U C T O R S - */ - - /* (non-Javadoc) - * Sets the Eclipse project that owns the Managed Project - * - * @param owner - */ - protected ManagedProject(IResource owner) { - this.owner = owner; - } - - /** - * Create a project instance from the project-type specified in the argument, - * that is owned by the specified Eclipse project. - * - * @param owner the Eclipse project that owns the Managed Project - * @param projectType - */ - public ManagedProject(IResource owner, IProjectType projectType) { - // Make the owner of the ProjectType the project resource - this(owner); - - // Copy the parent's identity - this.projectType = projectType; - int id = ManagedBuildManager.getRandomNumber(); - setId(owner.getName() + "." + projectType.getId() + "." + id); //$NON-NLS-1$ //$NON-NLS-2$ - setName(projectType.getName()); - - setManagedBuildRevision(projectType.getManagedBuildRevision()); - - // Hook me up - IManagedBuildInfo buildInfo = ManagedBuildManager.getBuildInfo(owner); - buildInfo.setManagedProject(this); - setDirty(true); - } - - /** - * Create the project instance from project file. - * - * @param buildInfo - * @param element - * @param managedBuildRevision the fileVersion of Managed Build System - */ - public ManagedProject(ManagedBuildInfo buildInfo, Element element, String managedBuildRevision) { - this(buildInfo.getOwner()); - - setManagedBuildRevision(managedBuildRevision); - - // Initialize from the XML attributes - if (loadFromProject(element)) { - - // check for migration support. - boolean isSupportAvailable = projectType.checkForMigrationSupport(); - if (isSupportAvailable == false) { - setValid(false); - } - - // Load children - NodeList configElements = element.getChildNodes(); - for (int i = 0; i < configElements.getLength(); ++i) { - Node configElement = configElements.item(i); - if (configElement.getNodeName().equals(IConfiguration.CONFIGURATION_ELEMENT_NAME)) { - Configuration config = new Configuration(this, (Element)configElement, managedBuildRevision); - }else if (configElement.getNodeName().equals(StorableMacros.MACROS_ELEMENT_NAME)) { - //load user-defined macros - userDefinedMacros = new StorableMacros((Element)configElement); - } - - } - } else { - setValid(false); - } - - // hook me up - buildInfo.setManagedProject(this); - } - - /* - * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S - */ - - /* (non-Javadoc) - * Initialize the project information from the XML element - * specified in the argument - * - * @param element An XML element containing the project information - */ - protected boolean loadFromProject(Element element) { - - // id - setId(element.getAttribute(IBuildObject.ID)); - - // name - if (element.hasAttribute(IBuildObject.NAME)) { - setName(element.getAttribute(IBuildObject.NAME)); - } - - // projectType - projectTypeId = element.getAttribute(PROJECTTYPE); - if (projectTypeId != null && projectTypeId.length() > 0) { - projectType = ManagedBuildManager.getExtensionProjectType(projectTypeId); - if (projectType == null) { - return false; - } - } - return true; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#serialize() - */ - public void serialize(Document doc, Element element) { - element.setAttribute(IBuildObject.ID, id); - - if (name != null) { - element.setAttribute(IBuildObject.NAME, name); - } - - if (projectType != null) { - element.setAttribute(PROJECTTYPE, projectType.getId()); - } - - // Serialize my children - List configElements = getConfigurationList(); - Iterator iter = configElements.listIterator(); - while (iter.hasNext()) { - Configuration config = (Configuration) iter.next(); - Element configElement = doc.createElement(IConfiguration.CONFIGURATION_ELEMENT_NAME); - element.appendChild(configElement); - config.serialize(doc, configElement); - } - - //serialize user-defined macros - if(userDefinedMacros != null){ - Element macrosElement = doc.createElement(StorableMacros.MACROS_ELEMENT_NAME); - element.appendChild(macrosElement); - userDefinedMacros.serialize(doc,macrosElement); - } - - if(userDefinedEnvironment != null){ - EnvironmentVariableProvider.fUserSupplier.storeEnvironment(this,true); - } - - // I am clean now - isDirty = false; - } - - /* - * P A R E N T A N D C H I L D H A N D L I N G - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#getOwner() - */ - public IResource getOwner() { - return owner; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#updateOwner(org.eclipse.core.resources.IResource) - */ - public void updateOwner(IResource resource) { - if (!resource.equals(owner)) { - // Set the owner correctly - owner = resource; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#getProjectType() - */ - public IProjectType getProjectType() { - return projectType; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedProject#createConfiguration(org.eclipse.cdt.core.build.managed.IConfiguration) - */ - public IConfiguration createConfiguration(IConfiguration parent, String id) { - Configuration config = new Configuration(this, (Configuration)parent, id, false, false); - ManagedBuildManager.performValueHandlerEvent(config, IManagedOptionValueHandler.EVENT_OPEN); - return (IConfiguration)config; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedProject#createConfigurationClone(org.eclipse.cdt.core.build.managed.IConfiguration) - */ - public IConfiguration createConfigurationClone(IConfiguration parent, String id) { - Configuration config = new Configuration(this, (Configuration)parent, id, true, false); - // Inform all options in the configuration and all its resource configurations - ManagedBuildManager.performValueHandlerEvent(config, IManagedOptionValueHandler.EVENT_OPEN); - return (IConfiguration)config; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IManagedProject#getConfiguration() - */ - public IConfiguration getConfiguration(String id) { - return (IConfiguration)getConfigurationMap().get(id); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#getConfigurations() - */ - public IConfiguration[] getConfigurations() { - IConfiguration[] configs = new IConfiguration[getConfigurationList().size()]; - Iterator iter = getConfigurationList().listIterator(); - int i = 0; - while (iter.hasNext()) { - Configuration config = (Configuration)iter.next(); - configs[i++] = (IConfiguration)config; - } - return configs; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#removeConfiguration(java.lang.String) - */ - public void removeConfiguration(String id) { - final String removeId = id; - - //handle the case of temporary configuration - if(getConfigurationMap().get(id) == null) - return; - - IWorkspaceRunnable remover = new IWorkspaceRunnable() { - public void run(IProgressMonitor monitor) throws CoreException { - // Remove the specified configuration from the list and map - Iterator iter = getConfigurationList().listIterator(); - while (iter.hasNext()) { - IConfiguration config = (IConfiguration)iter.next(); - if (config.getId().equals(removeId)) { - // TODO: For now we clean the entire project. This may be overkill, but - // it avoids a problem with leaving the configuration output directory - // around and having the outputs try to be used by the makefile generator code. - IResource proj = config.getOwner(); - IManagedBuildInfo info = null; - if (proj instanceof IProject) { - info = ManagedBuildManager.getBuildInfo(proj); - } - IConfiguration currentConfig = null; - boolean isCurrent = true; - if (info != null) { - currentConfig = info.getDefaultConfiguration(); - if (!currentConfig.getId().equals(removeId)) { - info.setDefaultConfiguration(config); - isCurrent = false; - } - } - ((IProject)proj).build(IncrementalProjectBuilder.CLEAN_BUILD, monitor); - - ManagedBuildManager.performValueHandlerEvent(config, - IManagedOptionValueHandler.EVENT_CLOSE); - getConfigurationList().remove(config); - getConfigurationMap().remove(removeId); - - if (info != null) { - if (!isCurrent) { - info.setDefaultConfiguration(currentConfig); - } else { - // If the current default config is the one being removed, reset the default config - String[] configs = info.getConfigurationNames(); - if (configs.length > 0) { - info.setDefaultConfiguration(configs[0]); - } - } - } - break; - } - } - } - }; - try { - ResourcesPlugin.getWorkspace().run( remover, null ); - } - catch( CoreException e ) {} - setDirty(true); - } - - /* (non-Javadoc) - * Adds the Configuration to the Configuration list and map - * - * @param Tool - */ - public void addConfiguration(Configuration configuration) { - if(!configuration.isTemporary()){ - getConfigurationList().add(configuration); - getConfigurationMap().put(configuration.getId(), configuration); - } - } - - /* (non-Javadoc) - * Safe accessor for the list of configurations. - * - * @return List containing the configurations - */ - private List getConfigurationList() { - if (configList == null) { - configList = new ArrayList(); - } - return configList; - } - - /* (non-Javadoc) - * Safe accessor for the map of configuration ids to configurations - * - * @return - */ - private Map getConfigurationMap() { - if (configMap == null) { - configMap = new HashMap(); - } - return configMap; - } - - /* - * M O D E L A T T R I B U T E A C C E S S O R S - */ - - /* - * O B J E C T S T A T E M A I N T E N A N C E - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#(getDefaultArtifactName) - */ - public String getDefaultArtifactName(){ - String name = new String(); - // Check for spaces - String[] tokens = getOwner().getName().split("\\s"); //$NON-NLS-1$ - for (int index = 0; index < tokens.length; ++index) { - name += tokens[index]; - } - return name; - } - - /* (non-Javadoc) - * Resolve the element IDs to interface references - */ - public boolean resolveReferences() { - if (!resolved) { - resolved = true; - // Resolve project-type - if (projectTypeId != null && projectTypeId.length() > 0) { - projectType = ManagedBuildManager.getExtensionProjectType(projectTypeId); - if (projectType == null) { - return false; - } - } - - // call resolve references on any children - Iterator configIter = getConfigurationList().iterator(); - while (configIter.hasNext()) { - Configuration current = (Configuration)configIter.next(); - current.resolveReferences(); - } - } - return true; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#isDirty() - */ - public boolean isDirty() { - // If I need saving, just say yes - if (isDirty) return true; - - //check whether the project - specific macros are dirty - if(userDefinedMacros != null && userDefinedMacros.isDirty()) - return true; - - //check whether the project - specific environment is dirty - if(userDefinedEnvironment != null && userDefinedEnvironment.isDirty()) - return true; - - - // Otherwise see if any configurations need saving - Iterator iter = getConfigurationList().listIterator(); - while (iter.hasNext()) { - Configuration current = (Configuration) iter.next(); - if (current.isDirty()) return true; - } - - return isDirty; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#setDirty(boolean) - */ - public void setDirty(boolean isDirty) { - this.isDirty = isDirty; - // Propagate "false" to the children - if (!isDirty) { - Iterator iter = getConfigurationList().listIterator(); - while (iter.hasNext()) { - Configuration current = (Configuration) iter.next(); - current.setDirty(false); - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#isValid() - */ - public boolean isValid() { - // TODO: In the future, children could also have a "valid" state that should be checked - return isValid; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#setValid(boolean) - */ - public void setValid(boolean isValid) { - // TODO: In the future, children could also have a "valid" state... - this.isValid = isValid; - } - - /** - * @return Returns the version. - */ - public PluginVersionIdentifier getVersion() { - if (version == null) { - if ( getProjectType() != null) { - return getProjectType().getVersion(); - } - } - return version; - } - - public void setVersion(PluginVersionIdentifier version) { - // Do nothing - } - - /* - * this method is called by the UserDefinedMacroSupplier to obtain user-defined - * macros available for this managed project - */ - public StorableMacros getUserDefinedMacros(){ - if(userDefinedMacros == null) - userDefinedMacros = new StorableMacros(); - return userDefinedMacros; - } - - public StorableEnvironment getUserDefinedEnvironmet(){ - return userDefinedEnvironment; - } - - public void setUserDefinedEnvironmet(StorableEnvironment env){ - userDefinedEnvironment = env; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.internal.core.BuildObject#updateManagedBuildRevision(java.lang.String) - */ - public void updateManagedBuildRevision(String revision){ - super.updateManagedBuildRevision(revision); - for(Iterator iter = getConfigurationList().iterator(); iter.hasNext();){ - Configuration cfg = (Configuration)iter.next(); - cfg.updateManagedBuildRevision(revision); - } - } -} +/******************************************************************************* + * Copyright (c) 2004, 2005 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.core; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedOptionValueHandler; +import org.eclipse.cdt.managedbuilder.core.IManagedProject; +import org.eclipse.cdt.managedbuilder.core.IProjectType; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.internal.envvar.EnvironmentVariableProvider; +import org.eclipse.cdt.managedbuilder.internal.envvar.StorableEnvironment; +import org.eclipse.cdt.managedbuilder.internal.macros.StorableMacros; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.IncrementalProjectBuilder; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.PluginVersionIdentifier; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class ManagedProject extends BuildObject implements IManagedProject { + + private static final String EMPTY_STRING = new String(); + private static final IConfiguration[] emptyConfigs = new IConfiguration[0]; + + // Parent and children + private IProjectType projectType; + private String projectTypeId; + private IResource owner; + private List configList; // Configurations of this project type + private Map configMap; + // Miscellaneous + private boolean isDirty = false; + private boolean isValid = true; + private boolean resolved = true; + //holds the user-defined macros + private StorableMacros userDefinedMacros; + //holds user-defined environment + private StorableEnvironment userDefinedEnvironment; + /* + * C O N S T R U C T O R S + */ + + /* (non-Javadoc) + * Sets the Eclipse project that owns the Managed Project + * + * @param owner + */ + protected ManagedProject(IResource owner) { + this.owner = owner; + } + + /** + * Create a project instance from the project-type specified in the argument, + * that is owned by the specified Eclipse project. + * + * @param owner the Eclipse project that owns the Managed Project + * @param projectType + */ + public ManagedProject(IResource owner, IProjectType projectType) { + // Make the owner of the ProjectType the project resource + this(owner); + + // Copy the parent's identity + this.projectType = projectType; + int id = ManagedBuildManager.getRandomNumber(); + setId(owner.getName() + "." + projectType.getId() + "." + id); //$NON-NLS-1$ //$NON-NLS-2$ + setName(projectType.getName()); + + setManagedBuildRevision(projectType.getManagedBuildRevision()); + + // Hook me up + IManagedBuildInfo buildInfo = ManagedBuildManager.getBuildInfo(owner); + buildInfo.setManagedProject(this); + setDirty(true); + } + + /** + * Create the project instance from project file. + * + * @param buildInfo + * @param element + * @param managedBuildRevision the fileVersion of Managed Build System + */ + public ManagedProject(ManagedBuildInfo buildInfo, Element element, String managedBuildRevision) { + this(buildInfo.getOwner()); + + setManagedBuildRevision(managedBuildRevision); + + // Initialize from the XML attributes + if (loadFromProject(element)) { + + // check for migration support. + boolean isSupportAvailable = projectType.checkForMigrationSupport(); + if (isSupportAvailable == false) { + setValid(false); + } + + // Load children + NodeList configElements = element.getChildNodes(); + for (int i = 0; i < configElements.getLength(); ++i) { + Node configElement = configElements.item(i); + if (configElement.getNodeName().equals(IConfiguration.CONFIGURATION_ELEMENT_NAME)) { + Configuration config = new Configuration(this, (Element)configElement, managedBuildRevision); + }else if (configElement.getNodeName().equals(StorableMacros.MACROS_ELEMENT_NAME)) { + //load user-defined macros + userDefinedMacros = new StorableMacros((Element)configElement); + } + + } + } else { + setValid(false); + } + + // hook me up + buildInfo.setManagedProject(this); + } + + /* + * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S + */ + + /* (non-Javadoc) + * Initialize the project information from the XML element + * specified in the argument + * + * @param element An XML element containing the project information + */ + protected boolean loadFromProject(Element element) { + + // id + setId(element.getAttribute(IBuildObject.ID)); + + // name + if (element.hasAttribute(IBuildObject.NAME)) { + setName(element.getAttribute(IBuildObject.NAME)); + } + + // projectType + projectTypeId = element.getAttribute(PROJECTTYPE); + if (projectTypeId != null && projectTypeId.length() > 0) { + projectType = ManagedBuildManager.getExtensionProjectType(projectTypeId); + if (projectType == null) { + return false; + } + } + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#serialize() + */ + public void serialize(Document doc, Element element) { + element.setAttribute(IBuildObject.ID, id); + + if (name != null) { + element.setAttribute(IBuildObject.NAME, name); + } + + if (projectType != null) { + element.setAttribute(PROJECTTYPE, projectType.getId()); + } + + // Serialize my children + List configElements = getConfigurationList(); + Iterator iter = configElements.listIterator(); + while (iter.hasNext()) { + Configuration config = (Configuration) iter.next(); + Element configElement = doc.createElement(IConfiguration.CONFIGURATION_ELEMENT_NAME); + element.appendChild(configElement); + config.serialize(doc, configElement); + } + + //serialize user-defined macros + if(userDefinedMacros != null){ + Element macrosElement = doc.createElement(StorableMacros.MACROS_ELEMENT_NAME); + element.appendChild(macrosElement); + userDefinedMacros.serialize(doc,macrosElement); + } + + if(userDefinedEnvironment != null){ + EnvironmentVariableProvider.fUserSupplier.storeEnvironment(this,true); + } + + // I am clean now + isDirty = false; + } + + /* + * P A R E N T A N D C H I L D H A N D L I N G + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#getOwner() + */ + public IResource getOwner() { + return owner; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#updateOwner(org.eclipse.core.resources.IResource) + */ + public void updateOwner(IResource resource) { + if (!resource.equals(owner)) { + // Set the owner correctly + owner = resource; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#getProjectType() + */ + public IProjectType getProjectType() { + return projectType; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedProject#createConfiguration(org.eclipse.cdt.core.build.managed.IConfiguration) + */ + public IConfiguration createConfiguration(IConfiguration parent, String id) { + Configuration config = new Configuration(this, (Configuration)parent, id, false, false); + ManagedBuildManager.performValueHandlerEvent(config, IManagedOptionValueHandler.EVENT_OPEN); + return (IConfiguration)config; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedProject#createConfigurationClone(org.eclipse.cdt.core.build.managed.IConfiguration) + */ + public IConfiguration createConfigurationClone(IConfiguration parent, String id) { + Configuration config = new Configuration(this, (Configuration)parent, id, true, false); + // Inform all options in the configuration and all its resource configurations + ManagedBuildManager.performValueHandlerEvent(config, IManagedOptionValueHandler.EVENT_OPEN); + return (IConfiguration)config; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IManagedProject#getConfiguration() + */ + public IConfiguration getConfiguration(String id) { + return (IConfiguration)getConfigurationMap().get(id); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#getConfigurations() + */ + public IConfiguration[] getConfigurations() { + IConfiguration[] configs = new IConfiguration[getConfigurationList().size()]; + Iterator iter = getConfigurationList().listIterator(); + int i = 0; + while (iter.hasNext()) { + Configuration config = (Configuration)iter.next(); + configs[i++] = (IConfiguration)config; + } + return configs; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#removeConfiguration(java.lang.String) + */ + public void removeConfiguration(String id) { + final String removeId = id; + + //handle the case of temporary configuration + if(getConfigurationMap().get(id) == null) + return; + + IWorkspaceRunnable remover = new IWorkspaceRunnable() { + public void run(IProgressMonitor monitor) throws CoreException { + // Remove the specified configuration from the list and map + Iterator iter = getConfigurationList().listIterator(); + while (iter.hasNext()) { + IConfiguration config = (IConfiguration)iter.next(); + if (config.getId().equals(removeId)) { + // TODO: For now we clean the entire project. This may be overkill, but + // it avoids a problem with leaving the configuration output directory + // around and having the outputs try to be used by the makefile generator code. + IResource proj = config.getOwner(); + IManagedBuildInfo info = null; + if (proj instanceof IProject) { + info = ManagedBuildManager.getBuildInfo(proj); + } + IConfiguration currentConfig = null; + boolean isCurrent = true; + if (info != null) { + currentConfig = info.getDefaultConfiguration(); + if (!currentConfig.getId().equals(removeId)) { + info.setDefaultConfiguration(config); + isCurrent = false; + } + } + ((IProject)proj).build(IncrementalProjectBuilder.CLEAN_BUILD, monitor); + + ManagedBuildManager.performValueHandlerEvent(config, + IManagedOptionValueHandler.EVENT_CLOSE); + getConfigurationList().remove(config); + getConfigurationMap().remove(removeId); + + if (info != null) { + if (!isCurrent) { + info.setDefaultConfiguration(currentConfig); + } else { + // If the current default config is the one being removed, reset the default config + String[] configs = info.getConfigurationNames(); + if (configs.length > 0) { + info.setDefaultConfiguration(configs[0]); + } + } + } + break; + } + } + } + }; + try { + ResourcesPlugin.getWorkspace().run( remover, null ); + } + catch( CoreException e ) {} + setDirty(true); + } + + /* (non-Javadoc) + * Adds the Configuration to the Configuration list and map + * + * @param Tool + */ + public void addConfiguration(Configuration configuration) { + if(!configuration.isTemporary()){ + getConfigurationList().add(configuration); + getConfigurationMap().put(configuration.getId(), configuration); + } + } + + /* (non-Javadoc) + * Safe accessor for the list of configurations. + * + * @return List containing the configurations + */ + private List getConfigurationList() { + if (configList == null) { + configList = new ArrayList(); + } + return configList; + } + + /* (non-Javadoc) + * Safe accessor for the map of configuration ids to configurations + * + * @return + */ + public Map getConfigurationMap() { + if (configMap == null) { + configMap = new HashMap(); + } + return configMap; + } + + /* + * M O D E L A T T R I B U T E A C C E S S O R S + */ + + /* + * O B J E C T S T A T E M A I N T E N A N C E + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#(getDefaultArtifactName) + */ + public String getDefaultArtifactName(){ + String name = new String(); + // Check for spaces + String[] tokens = getOwner().getName().split("\\s"); //$NON-NLS-1$ + for (int index = 0; index < tokens.length; ++index) { + name += tokens[index]; + } + return name; + } + + /* (non-Javadoc) + * Resolve the element IDs to interface references + */ + public boolean resolveReferences() { + if (!resolved) { + resolved = true; + // Resolve project-type + if (projectTypeId != null && projectTypeId.length() > 0) { + projectType = ManagedBuildManager.getExtensionProjectType(projectTypeId); + if (projectType == null) { + return false; + } + } + + // call resolve references on any children + Iterator configIter = getConfigurationList().iterator(); + while (configIter.hasNext()) { + Configuration current = (Configuration)configIter.next(); + current.resolveReferences(); + } + } + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#isDirty() + */ + public boolean isDirty() { + // If I need saving, just say yes + if (isDirty) return true; + + //check whether the project - specific macros are dirty + if(userDefinedMacros != null && userDefinedMacros.isDirty()) + return true; + + //check whether the project - specific environment is dirty + if(userDefinedEnvironment != null && userDefinedEnvironment.isDirty()) + return true; + + + // Otherwise see if any configurations need saving + Iterator iter = getConfigurationList().listIterator(); + while (iter.hasNext()) { + Configuration current = (Configuration) iter.next(); + if (current.isDirty()) return true; + } + + return isDirty; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#setDirty(boolean) + */ + public void setDirty(boolean isDirty) { + this.isDirty = isDirty; + // Propagate "false" to the children + if (!isDirty) { + Iterator iter = getConfigurationList().listIterator(); + while (iter.hasNext()) { + Configuration current = (Configuration) iter.next(); + current.setDirty(false); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#isValid() + */ + public boolean isValid() { + // TODO: In the future, children could also have a "valid" state that should be checked + return isValid; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedProject#setValid(boolean) + */ + public void setValid(boolean isValid) { + // TODO: In the future, children could also have a "valid" state... + this.isValid = isValid; + } + + /** + * @return Returns the version. + */ + public PluginVersionIdentifier getVersion() { + if (version == null) { + if ( getProjectType() != null) { + return getProjectType().getVersion(); + } + } + return version; + } + + public void setVersion(PluginVersionIdentifier version) { + // Do nothing + } + + /* + * this method is called by the UserDefinedMacroSupplier to obtain user-defined + * macros available for this managed project + */ + public StorableMacros getUserDefinedMacros(){ + if(userDefinedMacros == null) + userDefinedMacros = new StorableMacros(); + return userDefinedMacros; + } + + public StorableEnvironment getUserDefinedEnvironmet(){ + return userDefinedEnvironment; + } + + public void setUserDefinedEnvironmet(StorableEnvironment env){ + userDefinedEnvironment = env; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.core.BuildObject#updateManagedBuildRevision(java.lang.String) + */ + public void updateManagedBuildRevision(String revision){ + super.updateManagedBuildRevision(revision); + for(Iterator iter = getConfigurationList().iterator(); iter.hasNext();){ + Configuration cfg = (Configuration)iter.next(); + cfg.updateManagedBuildRevision(revision); + } + } + + public void setProjectType(IProjectType projectType) { + if ( this.projectType != projectType ) { + this.projectType = projectType; + if ( this.projectType == null) { + projectTypeId = null; + } else { + projectTypeId = this.projectType.getId(); + } + } + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java index 334f35e861b..b64fb0af337 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java @@ -1,1853 +1,1867 @@ -/******************************************************************************* - * Copyright (c) 2003, 2005 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - * ARM Ltd. - basic tooltip support - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.internal.core; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Set; - -import org.eclipse.cdt.managedbuilder.core.BuildException; -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IHoldsOptions; -import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; -import org.eclipse.cdt.managedbuilder.core.IManagedOptionValueHandler; -import org.eclipse.cdt.managedbuilder.core.IOption; -import org.eclipse.cdt.managedbuilder.core.IOptionApplicability; -import org.eclipse.cdt.managedbuilder.core.IOptionCategory; -import org.eclipse.cdt.managedbuilder.core.IProjectType; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.IToolChain; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.core.ManagedOptionValueHandler; -import org.eclipse.cdt.managedbuilder.internal.enablement.OptionEnablementExpression; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.PluginVersionIdentifier; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -public class Option extends BuildObject implements IOption { - // Static default return values - private static final String EMPTY_STRING = new String(); - private static final String[] EMPTY_STRING_ARRAY = new String[0]; - - // Superclass - private IOption superClass; - private String superClassId; - // Parent and children - private IHoldsOptions holder; - // Managed Build model attributes - private String unusedChildren; - private Integer browseType; - private List builtIns; - private IOptionCategory category; - private String categoryId; - private String command; - private String commandFalse; - private String tip; - private List enumList; - private Map enumCommands; - private Map enumNames; - private Object value; - private Object defaultValue; - private Integer valueType; - private Boolean isAbstract; - private Integer resourceFilter; - private IConfigurationElement valueHandlerElement = null; - private IManagedOptionValueHandler valueHandler = null; - private String valueHandlerExtraArgument; - private IConfigurationElement applicabilityCalculatorElement = null; - private IOptionApplicability applicabilityCalculator = null; - private BooleanExpressionApplicabilityCalculator booleanExpressionCalculator = null; - // Miscellaneous - private boolean isExtensionOption = false; - private boolean isDirty = false; - private boolean resolved = true; - private boolean verified = false; - private boolean isValid = true; /** False for options which are invalid. getOption() - * routines will ignore invalid options. */ - private boolean wasOptRef = false; /** True for options which are created because of an - * MBS 2.0 model OptionReference element - */ - private boolean isUdjusted = false; - - /* - * C O N S T R U C T O R S - */ - - /** - * This constructor is called to create an option defined by an extension point in - * a plugin manifest file, or returned by a dynamic element provider - * - * @param parent The IHoldsOptions parent of this option, or null if - * defined at the top level - * @param element The option definition from the manifest file or a dynamic element - * provider - */ - public Option(IHoldsOptions parent, IManagedConfigElement element) { - this.holder = parent; - isExtensionOption = true; - - // setup for resolving - resolved = false; - - loadFromManifest(element); - - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionOption(this); - } - - /** - * This constructor is called to create an Option whose attributes and children will be - * added by separate calls. - * - * @param IHoldsOptions The parent of the option, if any - * @param Option The superClass, if any - * @param String The id for the new option - * @param String The name for the new option - * @param boolean Indicates whether this is an extension element or a managed project element - */ - public Option(IHoldsOptions parent, IOption superClass, String Id, String name, boolean isExtensionElement) { - this.holder = parent; - this.superClass = superClass; - if (this.superClass != null) { - superClassId = this.superClass.getId(); - } - setId(Id); - setName(name); - isExtensionOption = isExtensionElement; - if (isExtensionElement) { - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionOption(this); - } else { - setDirty(true); - } - } - - /** - * Create an Option based on the specification stored in the - * project file (.cdtbuild). - * - * @param parent The IHoldsOptions the option will be added to. - * @param element The XML element that contains the option settings. - */ - public Option(IHoldsOptions parent, Element element) { - this.holder = parent; - isExtensionOption = false; - - // Initialize from the XML attributes - loadFromProject(element); - } - - /** - * Create an Option based upon an existing option. - * - * @param parent The IHoldsOptions the option will be added to. - * @param Id New ID for the option. - * @param name New name for the option. - * @param option The existing option to clone, except for the above fields. - */ - public Option(IHoldsOptions parent, String Id, String name, Option option){ - this.holder = parent; - superClass = option.superClass; - if (superClass != null) { - superClassId = option.superClass.getId(); - } - setId(Id); - setName(name); - isExtensionOption = false; - - // Copy the remaining attributes - if (option.unusedChildren != null) { - unusedChildren = new String(option.unusedChildren); - } - if (option.isAbstract != null) { - isAbstract = new Boolean(option.isAbstract.booleanValue()); - } - if (option.command != null) { - command = new String(option.command); - } - if (option.commandFalse != null) { - commandFalse = new String(option.commandFalse); - } - if (option.tip != null) { - tip = new String(option.tip); - } - if (option.categoryId != null) { - categoryId = new String(option.categoryId); - } - if (option.builtIns != null) { - builtIns = new ArrayList(option.builtIns); - } - if (option.browseType != null) { - browseType = new Integer(option.browseType.intValue()); - } - if (option.resourceFilter != null) { - resourceFilter = new Integer(option.resourceFilter.intValue()); - } - if (option.enumList != null) { - enumList = new ArrayList(option.enumList); - enumCommands = new HashMap(option.enumCommands); - enumNames = new HashMap(option.enumNames); - } - - if (option.valueType != null) { - valueType = new Integer(option.valueType.intValue()); - } - Integer vType = null; - try { - vType = new Integer(option.getValueType()); - if (vType != null) { - switch (vType.intValue()) { - case BOOLEAN: - if (option.value != null) { - value = new Boolean(((Boolean)option.value).booleanValue()); - } - if (option.defaultValue != null) { - defaultValue = new Boolean(((Boolean)option.defaultValue).booleanValue()); - } - break; - case STRING: - case ENUMERATED: - if (option.value != null) { - value = new String((String)option.value); - } - if (option.defaultValue != null) { - defaultValue = new String((String)option.defaultValue); - } - break; - case STRING_LIST: - case INCLUDE_PATH: - case PREPROCESSOR_SYMBOLS: - case LIBRARIES: - case OBJECTS: - if (option.value != null) { - value = new ArrayList((ArrayList)option.value); - } - if (option.defaultValue != null) { - defaultValue = new ArrayList((ArrayList)option.defaultValue); - } - break; - } - } - } catch (BuildException be) { - // TODO: should we ignore this?? - } - - category = option.category; - applicabilityCalculatorElement = option.applicabilityCalculatorElement; - applicabilityCalculator = option.applicabilityCalculator; - - booleanExpressionCalculator = option.booleanExpressionCalculator; - - if (option.valueHandlerElement != null) { - valueHandlerElement = option.valueHandlerElement; - valueHandler = option.valueHandler; - } - if (option.valueHandlerExtraArgument != null) { - valueHandlerExtraArgument = new String(option.valueHandlerExtraArgument); - } - - if(!isExtensionElement()) - setDirty(true); - } - - /* - * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S - */ - - /* (non-Javadoc) - * Loads the option information from the ManagedConfigElement specified in the - * argument. - * - * @param element Contains the option information - */ - protected void loadFromManifest(IManagedConfigElement element) { - ManagedBuildManager.putConfigElement(this, element); - - // id - setId(element.getAttribute(IBuildObject.ID)); - - // Get the name - setName(element.getAttribute(IBuildObject.NAME)); - - // superClass - superClassId = element.getAttribute(IProjectType.SUPERCLASS); - - // Get the unused children, if any - unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); - - // isAbstract - String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); - if (isAbs != null){ - isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ - } - - // Get the command defined for the option - command = element.getAttribute(COMMAND); - - // Get the command defined for a Boolean option when the value is False - commandFalse = element.getAttribute(COMMAND_FALSE); - - // Get the tooltip for the option - tip = element.getAttribute(TOOL_TIP); - - // Options hold different types of values - String valueTypeStr = element.getAttribute(VALUE_TYPE); - if (valueTypeStr != null) { - valueType = new Integer(ValueTypeStrToInt(valueTypeStr)); - } - - // Note: The value and defaultValue attributes are loaded in the resolveReferences routine. - // This is because we need to have the value-type, and this may be defined in a - // superClass that is not yet loaded. - - // Determine if there needs to be a browse button - String browseTypeStr = element.getAttribute(BROWSE_TYPE); - if (browseTypeStr == null) { - // Set to null, to indicate no browse type specification - // This will allow any superclasses to be searched for the - // browse type specification, and thus inherited, if found, - // which they should be - browseType = null; - } else if (browseTypeStr.equals(NONE)) { - browseType = new Integer(BROWSE_NONE); - } else if (browseTypeStr.equals(FILE)) { - browseType = new Integer(BROWSE_FILE); - } else if (browseTypeStr.equals(DIR)) { - browseType = new Integer(BROWSE_DIR); - } - - categoryId = element.getAttribute(CATEGORY); - - // Get the resourceFilter attribute - String resFilterStr = element.getAttribute(RESOURCE_FILTER); - if (resFilterStr == null) { - // Set to null, to indicate no resource filter specification - // This will allow any superclasses to be searched for the - // resource filter specification, and thus inherited, if found, - // which they should be - resourceFilter = null; - } else if (resFilterStr.equals(ALL)) { - resourceFilter = new Integer(FILTER_ALL); - } else if (resFilterStr.equals(FILE)) { - resourceFilter = new Integer(FILTER_FILE); - } else if (resFilterStr.equals(PROJECT)) { - resourceFilter = new Integer(FILTER_PROJECT); - } - - //get enablements - IManagedConfigElement enablements[] = element.getChildren(OptionEnablementExpression.NAME); - if(enablements.length > 0) - booleanExpressionCalculator = new BooleanExpressionApplicabilityCalculator(enablements); - - // get the applicability calculator, if any - String applicabilityCalculatorStr = element.getAttribute(APPLICABILITY_CALCULATOR); - if (applicabilityCalculatorStr != null && element instanceof DefaultManagedConfigElement) { - applicabilityCalculatorElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); - } else { - applicabilityCalculator = booleanExpressionCalculator; - } - - // valueHandler - // Store the configuration element IFF there is a value handler defined - String valueHandler = element.getAttribute(VALUE_HANDLER); - if (valueHandler != null && element instanceof DefaultManagedConfigElement) { - valueHandlerElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); - } - // valueHandlerExtraArgument - valueHandlerExtraArgument = element.getAttribute(VALUE_HANDLER_EXTRA_ARGUMENT); - } - - /* (non-Javadoc) - * Initialize the option information from the XML element - * specified in the argument - * - * @param element An XML element containing the option information - */ - protected void loadFromProject(Element element) { - - // id - setId(element.getAttribute(IBuildObject.ID)); - - // name - if (element.hasAttribute(IBuildObject.NAME)) { - setName(element.getAttribute(IBuildObject.NAME)); - } - - // superClass - superClassId = element.getAttribute(IProjectType.SUPERCLASS); - if (superClassId != null && superClassId.length() > 0) { - superClass = ManagedBuildManager.getExtensionOption(superClassId); - if (superClass == null) { - // TODO: Report error - } - } - - // Get the unused children, if any - if (element.hasAttribute(IProjectType.UNUSED_CHILDREN)) { - unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); - } - - // isAbstract - if (element.hasAttribute(IProjectType.IS_ABSTRACT)) { - String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); - if (isAbs != null){ - isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ - } - } - - // Get the command defined for the option - if (element.hasAttribute(COMMAND)) { - command = element.getAttribute(COMMAND); - } - - // Get the command defined for a Boolean option when the value is False - if (element.hasAttribute(COMMAND_FALSE)) { - commandFalse = element.getAttribute(COMMAND_FALSE); - } - - // Get the tooltip for the option - if (element.hasAttribute(TOOL_TIP)) { - tip = element.getAttribute(TOOL_TIP); - } - - // Options hold different types of values - if (element.hasAttribute(VALUE_TYPE)) { - String valueTypeStr = element.getAttribute(VALUE_TYPE); - valueType = new Integer(ValueTypeStrToInt(valueTypeStr)); - } - - // Now get the actual value based upon value-type - try { - int valType = getValueType(); - switch (valType) { - case BOOLEAN: - // Convert the string to a boolean - if (element.hasAttribute(VALUE)) { - value = new Boolean(element.getAttribute(VALUE)); - } - if (element.hasAttribute(DEFAULT_VALUE)) { - defaultValue = new Boolean(element.getAttribute(DEFAULT_VALUE)); - } - break; - case STRING: - // Just get the value out of the option directly - if (element.hasAttribute(VALUE)) { - value = element.getAttribute(VALUE); - } - if (element.hasAttribute(DEFAULT_VALUE)) { - defaultValue = element.getAttribute(DEFAULT_VALUE); - } - break; - case ENUMERATED: - if (element.hasAttribute(VALUE)) { - value = element.getAttribute(VALUE); - } - if (element.hasAttribute(DEFAULT_VALUE)) { - defaultValue = element.getAttribute(DEFAULT_VALUE); - } - - // Do we have enumeratedOptionValue children? If so, load them - // to define the valid values and the default value. - NodeList configElements = element.getChildNodes(); - for (int i = 0; i < configElements.getLength(); ++i) { - Node configNode = configElements.item(i); - if (configNode.getNodeName().equals(ENUM_VALUE)) { - Element configElement = (Element)configNode; - String optId = configElement.getAttribute(ID); - if (i == 0) { - enumList = new ArrayList(); - if (defaultValue == null) { - defaultValue = optId; // Default value to be overridden is default is specified - } - } - enumList.add(optId); - if (configElement.hasAttribute(COMMAND)) { - getEnumCommandMap().put(optId, configElement.getAttribute(COMMAND)); - } else { - getEnumCommandMap().put(optId, EMPTY_STRING); - } - getEnumNameMap().put(optId, configElement.getAttribute(NAME)); - if (configElement.hasAttribute(IS_DEFAULT)) { - Boolean isDefault = new Boolean(configElement.getAttribute(IS_DEFAULT)); - if (isDefault.booleanValue()) { - defaultValue = optId; - } - } - } - } - break; - case STRING_LIST: - case INCLUDE_PATH: - case PREPROCESSOR_SYMBOLS: - case LIBRARIES: - case OBJECTS: - // Note: These string-list options do not load either the "value" or - // "defaultValue" attributes. Instead, the ListOptionValue children - // are loaded in the value field. - List valueList = null; - configElements = element.getChildNodes(); - for (int i = 0; i < configElements.getLength(); ++i) { - if (i == 0) { - valueList = new ArrayList(); - builtIns = new ArrayList(); - } - Node configNode = configElements.item(i); - if (configNode.getNodeName().equals(LIST_VALUE)) { - Element valueElement = (Element)configNode; - Boolean isBuiltIn; - if (valueElement.hasAttribute(IS_DEFAULT)) { - isBuiltIn = new Boolean(valueElement.getAttribute(LIST_ITEM_BUILTIN)); - } else { - isBuiltIn = new Boolean(false); - } - if (isBuiltIn.booleanValue()) { - builtIns.add(valueElement.getAttribute(LIST_ITEM_VALUE)); - } - else { - valueList.add(valueElement.getAttribute(LIST_ITEM_VALUE)); - } - } - } - value = valueList; - break; - default : - break; - } - } catch (BuildException e) { - // TODO: report error - } - - // Determine if there needs to be a browse button - if (element.hasAttribute(BROWSE_TYPE)) { - String browseTypeStr = element.getAttribute(BROWSE_TYPE); - - if (browseTypeStr == null) { - // Set to null, to indicate no browse type specification - // This will allow any superclasses to be searched for the - // browse type specification, and thus inherited, if found, - // which they should be - browseType = null; - } else if (browseTypeStr.equals(NONE)) { - browseType = new Integer(BROWSE_NONE); - } else if (browseTypeStr.equals(FILE)) { - browseType = new Integer(BROWSE_FILE); - } else if (browseTypeStr.equals(DIR)) { - browseType = new Integer(BROWSE_DIR); - } - } - - if (element.hasAttribute(CATEGORY)) { - categoryId = element.getAttribute(CATEGORY); - if (categoryId != null) { - category = holder.getOptionCategory(categoryId); - } - } - - // Get the resourceFilter attribute - if (element.hasAttribute(RESOURCE_FILTER)) { - String resFilterStr = element.getAttribute(RESOURCE_FILTER); - if (resFilterStr == null) { - // Set to null, to indicate no resource filter specification - // This will allow any superclasses to be searched for the - // resource filter specification, and thus inherited, if found, - // which they should be - resourceFilter = null; - } else if (resFilterStr.equals(ALL)) { - resourceFilter = new Integer(FILTER_ALL); - } else if (resFilterStr.equals(FILE)) { - resourceFilter = new Integer(FILTER_FILE); - } else if (resFilterStr.equals(PROJECT)) { - resourceFilter = new Integer(FILTER_PROJECT); - } - } - - // Note: valueHandlerElement and VALUE_HANDLER are not restored, - // as they are not saved. See note in serialize(). - - // valueHandlerExtraArgument - if (element.hasAttribute(VALUE_HANDLER_EXTRA_ARGUMENT)) { - valueHandlerExtraArgument = element.getAttribute(VALUE_HANDLER_EXTRA_ARGUMENT); - } - } - - private int ValueTypeStrToInt(String valueTypeStr) { - if (valueTypeStr == null) return -1; - if (valueTypeStr.equals(TYPE_STRING)) - return STRING; - else if (valueTypeStr.equals(TYPE_STR_LIST)) - return STRING_LIST; - else if (valueTypeStr.equals(TYPE_BOOL)) - return BOOLEAN; - else if (valueTypeStr.equals(TYPE_ENUM)) - return ENUMERATED; - else if (valueTypeStr.equals(TYPE_INC_PATH)) - return INCLUDE_PATH; - else if (valueTypeStr.equals(TYPE_LIB)) - return LIBRARIES; - else if (valueTypeStr.equals(TYPE_USER_OBJS)) - return OBJECTS; - else if (valueTypeStr.equals(TYPE_DEFINED_SYMBOLS)) - return PREPROCESSOR_SYMBOLS; - else { - // TODO: This was the CDT 2.0 default - should we keep it? - return PREPROCESSOR_SYMBOLS; - } - } - - /** - * Persist the option to the project file. - * - * @param doc - * @param element - */ - public void serialize(Document doc, Element element) throws BuildException { - if (superClass != null) - element.setAttribute(IProjectType.SUPERCLASS, superClass.getId()); - - element.setAttribute(IBuildObject.ID, id); - - if (name != null) { - element.setAttribute(IBuildObject.NAME, name); - } - - if (unusedChildren != null) { - element.setAttribute(IProjectType.UNUSED_CHILDREN, unusedChildren); - } - - if (isAbstract != null) { - element.setAttribute(IProjectType.IS_ABSTRACT, isAbstract.toString()); - } - - if (command != null) { - element.setAttribute(COMMAND, command); - } - - if (commandFalse != null) { - element.setAttribute(COMMAND_FALSE, commandFalse); - } - - if (tip != null) { - element.setAttribute(TOOL_TIP, tip); - } - - /* - * Note: We store value & value-type as a pair, so we know what type of value we are - * dealing with when we read it back in. - * This is also true of defaultValue. - */ - boolean storeValueType = false; - - // value - if (value != null) { - storeValueType = true; - switch (getValueType()) { - case BOOLEAN: - element.setAttribute(VALUE, ((Boolean)value).toString()); - break; - case STRING: - case ENUMERATED: - element.setAttribute(VALUE, (String)value); - break; - case STRING_LIST: - case INCLUDE_PATH: - case PREPROCESSOR_SYMBOLS: - case LIBRARIES: - case OBJECTS: - if (value != null) { - ArrayList stringList = (ArrayList)value; - ListIterator iter = stringList.listIterator(); - while (iter.hasNext()) { - Element valueElement = doc.createElement(LIST_VALUE); - valueElement.setAttribute(LIST_ITEM_VALUE, (String)iter.next()); - valueElement.setAttribute(LIST_ITEM_BUILTIN, "false"); //$NON-NLS-1$ - element.appendChild(valueElement); - } - } - // Serialize the built-ins that have been overridden - if (builtIns != null) { - ListIterator iter = builtIns.listIterator(); - while (iter.hasNext()) { - Element valueElement = doc.createElement(LIST_VALUE); - valueElement.setAttribute(LIST_ITEM_VALUE, (String)iter.next()); - valueElement.setAttribute(LIST_ITEM_BUILTIN, "true"); //$NON-NLS-1$ - element.appendChild(valueElement); - } - } - break; - } - } - - // defaultValue - if (defaultValue != null) { - storeValueType = true; - switch (getValueType()) { - case BOOLEAN: - element.setAttribute(DEFAULT_VALUE, ((Boolean)defaultValue).toString()); - break; - case STRING: - case ENUMERATED: - element.setAttribute(DEFAULT_VALUE, (String)defaultValue); - break; - default: - break; - } - } - - if (storeValueType) { - String str; - switch (getValueType()) { - case BOOLEAN: - str = TYPE_BOOL; - break; - case STRING: - str = TYPE_STRING; - break; - case ENUMERATED: - str = TYPE_ENUM; - break; - case STRING_LIST: - str = TYPE_STR_LIST; - break; - case INCLUDE_PATH: - str = TYPE_INC_PATH; - break; - case LIBRARIES: - str = TYPE_LIB; - break; - case OBJECTS: - str = TYPE_USER_OBJS; - break; - case PREPROCESSOR_SYMBOLS: - str = TYPE_DEFINED_SYMBOLS; - break; - default: - // TODO; is this a problem... - str = EMPTY_STRING; - break; - } - element.setAttribute(VALUE_TYPE, str); - } - - // browse type - if (browseType != null) { - String str; - switch (getBrowseType()) { - case BROWSE_NONE: - str = NONE; - break; - case BROWSE_FILE: - str = FILE; - break; - case BROWSE_DIR: - str = DIR; - break; - default: - str = EMPTY_STRING; - break; - } - element.setAttribute(BROWSE_TYPE, str); - } - - if (categoryId != null) { - element.setAttribute(CATEGORY, categoryId); - } - - // resource filter - if (resourceFilter != null) { - String str; - switch (getResourceFilter()) { - case FILTER_ALL: - str = ALL; - break; - case FILTER_FILE: - str = FILE; - break; - case FILTER_PROJECT: - str = PROJECT; - break; - default: - str = EMPTY_STRING; - break; - } - element.setAttribute(RESOURCE_FILTER, str); - } - - // Note: applicability calculator cannot be specified in a project file because - // an IConfigurationElement is needed to load it! - if (applicabilityCalculatorElement != null) { - // TODO: issue warning? - } - - // Note: a value handler cannot be specified in a project file because - // an IConfigurationElement is needed to load it! - if (valueHandlerElement != null) { - // TODO: Issue warning? Stuck with behavior of this elsewhere in - // CDT, e.g. the implementation of Tool - } - if (valueHandlerExtraArgument != null) { - element.setAttribute(VALUE_HANDLER_EXTRA_ARGUMENT, valueHandlerExtraArgument); - } - - // I am clean now - isDirty = false; - } - - /* - * P A R E N T A N D C H I L D H A N D L I N G - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getParent() - */ - public IBuildObject getParent() { - return holder; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getOptionHolder() - */ - public IHoldsOptions getOptionHolder() { - // Do not take superclasses into account - return holder; - } - - /* - * M O D E L A T T R I B U T E A C C E S S O R S - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getSuperClass() - */ - public IOption getSuperClass() { - return superClass; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getName() - */ - public String getName() { - return (name == null && superClass != null) ? superClass.getName() : name; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getApplicableValues() - */ - public String[] getApplicableValues() { - // Does this option instance have the list of values? - if (enumList == null) { - if (superClass != null) { - return superClass.getApplicableValues(); - } else { - return EMPTY_STRING_ARRAY; - } - } - // Get all of the enumerated names from the option - if (enumList.size() == 0) { - return EMPTY_STRING_ARRAY; - } else { - // Return the elements in the order they are specified in the manifest - String[] enumNames = new String[enumList.size()]; - for (int index = 0; index < enumList.size(); ++ index) { - enumNames[index] = (String) getEnumNameMap().get(enumList.get(index)); - } - return enumNames; - } - } - - public boolean getBooleanValue() { - return ((Boolean)getValue()).booleanValue(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getBrowseType() - */ - public int getBrowseType() { - if (browseType == null) { - if (superClass != null) { - return superClass.getBrowseType(); - } else { - return BROWSE_NONE; - } - } - return browseType.intValue(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getResourceFilter() - */ - public int getResourceFilter() { - if (resourceFilter == null) { - if (superClass != null) { - return superClass.getResourceFilter(); - } else { - return FILTER_ALL; - } - } - return resourceFilter.intValue(); - } - - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.managedbuilder.core.IOption#getApplicabilityCalculatorElement() - */ - public IConfigurationElement getApplicabilityCalculatorElement() { -/* if (applicabilityCalculatorElement == null) { - if (superClass != null) { - return ((Option)superClass).getApplicabilityCalculatorElement(); - } - } -*/ - return applicabilityCalculatorElement; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.managedbuilder.core.IOption#getApplicabilityCalculator() - */ - public IOptionApplicability getApplicabilityCalculator() { - if (applicabilityCalculator == null) { - if (applicabilityCalculatorElement != null) { - try { - if (applicabilityCalculatorElement.getAttribute(APPLICABILITY_CALCULATOR) != null) - applicabilityCalculator = (IOptionApplicability) applicabilityCalculatorElement - .createExecutableExtension(APPLICABILITY_CALCULATOR); - } catch (CoreException e) { - } - } - else if(superClass != null) - applicabilityCalculator = superClass.getApplicabilityCalculator(); - } - - return applicabilityCalculator; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getBuiltIns() - */ - public String[] getBuiltIns() { - // Return the list of built-ins as an array - if (builtIns == null) { - if (superClass != null) { - return superClass.getBuiltIns(); - } else { - return EMPTY_STRING_ARRAY; - } - } - return (String[])builtIns.toArray(new String[builtIns.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getCategory() - */ - public IOptionCategory getCategory() { - if (category == null) { - if (superClass != null) { - return superClass.getCategory(); - } else { - if (getOptionHolder() instanceof ITool) { - return ((ITool)getOptionHolder()).getTopOptionCategory(); - } else { - return null; - } - } - } - return category; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getCommand() - */ - public String getCommand() { - if (command == null) { - if (superClass != null) { - return superClass.getCommand(); - } else { - return EMPTY_STRING; - } - } - return command; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getCommandFalse() - */ - public String getCommandFalse() { - if (commandFalse == null) { - if (superClass != null) { - return superClass.getCommandFalse(); - } else { - return EMPTY_STRING; - } - } - return commandFalse; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getToolTip() - */ - public String getToolTip() { - if (tip == null) { - if (superClass != null) { - return superClass.getToolTip(); - } else { - return EMPTY_STRING; - } - } - return tip; - } - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getDefinedSymbols() - */ - public String[] getDefinedSymbols() throws BuildException { - if (getValueType() != PREPROCESSOR_SYMBOLS) { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - ArrayList v = (ArrayList)getValue(); - if (v == null) { - return EMPTY_STRING_ARRAY; - } else { - v.trimToSize(); - return (String[]) v.toArray(new String[v.size()]); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getEnumCommand(java.lang.String) - */ - public String getEnumCommand(String id) throws BuildException { - // Sanity - if (id == null) return EMPTY_STRING; - - // Does this option instance have the list of values? - if (enumList == null) { - if (superClass != null) { - return superClass.getEnumCommand(id); - } else { - return EMPTY_STRING; - } - } - if (getValueType() != ENUMERATED) { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - - // First check for the command in ID->command map - String cmd = (String) getEnumCommandMap().get(id); - if (cmd == null) { - // This may be a 1.2 project or plugin manifest. If so, the argument is the human readable - // name of the enumeration. Search for the ID that maps to the name and use that to find the - // command. - ListIterator iter = enumList.listIterator(); - while (iter.hasNext()) { - String realID = (String) iter.next(); - String name = (String) getEnumNameMap().get(realID); - if (id.equals(name)) { - cmd = (String) getEnumCommandMap().get(realID); - break; - } - } - } - return cmd == null ? EMPTY_STRING : cmd; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getEnumName(java.lang.String) - */ - public String getEnumName(String id) throws BuildException { - // Sanity - if (id == null) return EMPTY_STRING; - - // Does this option instance have the list of values? - if (enumList == null) { - if (superClass != null) { - return superClass.getEnumName(id); - } else { - return EMPTY_STRING; - } - } - if (getValueType() != ENUMERATED) { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - - // First check for the command in ID->name map - String name = (String) getEnumNameMap().get(id); - if (name == null) { - // This may be a 1.2 project or plugin manifest. If so, the argument is the human readable - // name of the enumeration. - name = id; - } - return name; - } - - /* (non-Javadoc) - * A memory-safe accessor to the map of enumerated option value IDs to the commands - * that a tool understands. - * - * @return a Map of enumerated option value IDs to actual commands that are passed - * to a tool on the command line. - */ - private Map getEnumCommandMap() { - if (enumCommands == null) { - enumCommands = new HashMap(); - } - return enumCommands; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getEnumeratedId(java.lang.String) - */ - public String getEnumeratedId(String name) throws BuildException { - if (name == null) return null; - - // Does this option instance have the list of values? - if (enumList == null) { - if (superClass != null) { - return superClass.getEnumeratedId(name); - } else { - return EMPTY_STRING; - } - } - if (getValueType() != ENUMERATED) { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - - Set idSet = getEnumNameMap().keySet(); - Iterator iter = idSet.iterator(); - while (iter.hasNext()) { - String id = (String) iter.next(); - String enumName = (String) getEnumNameMap().get(id); - if (name.equals(enumName)) { - return id; - } - } - return null; - } - - /* (non-Javadoc) - * - * @return a Map of enumerated option value IDs to the selection displayed to the user. - */ - private Map getEnumNameMap() { - if (enumNames == null) { - enumNames = new HashMap(); - } - return enumNames; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getIncludePaths() - */ - public String[] getIncludePaths() throws BuildException { - if (getValueType() != INCLUDE_PATH) { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - ArrayList v = (ArrayList)getValue(); - if (v == null) { - return EMPTY_STRING_ARRAY; - } else { - v.trimToSize(); - return (String[]) v.toArray(new String[v.size()]); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getLibraries() - */ - public String[] getLibraries() throws BuildException { - if (getValueType() != LIBRARIES) { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - ArrayList v = (ArrayList)getValue(); - if (v == null) { - return EMPTY_STRING_ARRAY; - } else { - v.trimToSize(); - return (String[]) v.toArray(new String[v.size()]); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getDefaultEnumValue() - */ - public String getSelectedEnum() throws BuildException { - if (getValueType() != ENUMERATED) { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - return getStringValue(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getStringListValue() - */ - public String[] getStringListValue() throws BuildException { - if (getValueType() != STRING_LIST) { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - ArrayList v = (ArrayList)getValue(); - if (v == null) { - return EMPTY_STRING_ARRAY; - } else { - v.trimToSize(); - return (String[]) v.toArray(new String[v.size()]); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getStringValue() - */ - public String getStringValue() throws BuildException { - if (getValueType() != STRING && getValueType() != ENUMERATED) { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - return getValue() == null ? EMPTY_STRING : (String)getValue(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getUserObjects() - */ - public String[] getUserObjects() throws BuildException { - if (getValueType() != OBJECTS) { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - // This is the right puppy, so return its list value - ArrayList v = (ArrayList)getValue(); - if (v == null) { - return EMPTY_STRING_ARRAY; - } else { - v.trimToSize(); - return (String[]) v.toArray(new String[v.size()]); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getValueType() - */ - public int getValueType() throws BuildException { - if (valueType == null) { - if (superClass != null) { - return superClass.getValueType(); - } else { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$; - } - } - return valueType.intValue(); - } - - /* (non-Javadoc) - * Gets the value, applying appropriate defaults if necessary. - */ - public Object getValue() { - /* - * In order to determine the current value of an option, perform the following steps until a value is found: - * 1. Examine the value attribute of the option. - * 2. Examine the value attribute of the option’s superClass recursively. - * 3. Examine the dynamicDefaultValue attribute of the option and invoke it if specified. (not yet implemented) - * 4. Examine the defaultValue attribute of the option. - * 5. Examine the dynamicDefaultValue attribute of the option’s superClass and invoke it if specified. (not yet implemented) - * 6. Examine the defaultValue attribute of the option’s superClass. - * 7. Go to step 5 recursively until no more super classes. - * 8. Use the default value for the option type. - */ - - Object val = getRawValue(); - if (val == null) { - val = getDefaultValue(); - if (val == null) { - int valType; - try { - valType = getValueType(); - } catch (BuildException e) { - return EMPTY_STRING; - } - switch (valType) { - case BOOLEAN: - val = new Boolean(false); - break; - case STRING: - val = EMPTY_STRING; - break; - case ENUMERATED: - // TODO: Can we default to the first enumerated id? - val = EMPTY_STRING; - break; - case STRING_LIST: - case INCLUDE_PATH: - case PREPROCESSOR_SYMBOLS: - case LIBRARIES: - case OBJECTS: - val = new ArrayList(); - break; - default: - val = EMPTY_STRING; - break; - } - } - } - return val; - } - - /* (non-Javadoc) - * Gets the raw value, applying appropriate defauls if necessary. - */ - public Object getRawValue() { - if (value == null) { - if (superClass != null) { - Option mySuperClass = (Option)superClass; - return mySuperClass.getRawValue(); - } - } - return value; - } - - /* (non-Javadoc) - * Gets the raw default value. - */ - public Object getDefaultValue() { - // Note: string-list options do not have a default value - if (defaultValue == null) { - if (superClass != null) { - return superClass.getDefaultValue(); - } - } - return defaultValue; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setValue(Object) - */ - public void setDefaultValue(Object v) { - defaultValue = v; - if(!isExtensionElement()) - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setCategory(org.eclipse.cdt.managedbuilder.core.IOptionCategory) - */ - public void setCategory(IOptionCategory category) { - if (this.category != category) { - this.category = category; - if (category != null) { - categoryId = category.getId(); - } else { - categoryId = null; - } - if(!isExtensionElement()) - setDirty(true); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setCommand(String) - */ - public void setCommand(String cmd) { - if (cmd == null && command == null) return; - if (cmd == null || command == null || !cmd.equals(command)) { - command = cmd; - if(!isExtensionElement()) - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setCommandFalse(String) - */ - public void setCommandFalse(String cmd) { - if (cmd == null && commandFalse == null) return; - if (cmd == null || commandFalse == null || !cmd.equals(commandFalse)) { - commandFalse = cmd; - if(!isExtensionElement()) - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setToolTip(String) - */ - public void setToolTip(String tooltip) { - if (tooltip == null && tip == null) return; - if (tooltip == null || tip == null || !tooltip.equals(tip)) { - tip = tooltip; - if(!isExtensionElement()) - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setResourceFilter(int) - */ - public void setResourceFilter(int filter) { - if (resourceFilter == null || !(filter == resourceFilter.intValue())) { - resourceFilter = new Integer(filter); - if(!isExtensionElement()) - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setBrowseType(int) - */ - public void setBrowseType(int type) { - if (browseType == null || !(type == browseType.intValue())) { - browseType = new Integer(type); - if(!isExtensionElement()) - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setValue(boolean) - */ - public void setValue(boolean value) throws BuildException { - if (/*!isExtensionElement() && */getValueType() == BOOLEAN){ - this.value = new Boolean(value); - } else { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - if(!isExtensionElement()) - setDirty(true); - } - - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setValue(String) - */ - public void setValue(String value) throws BuildException { - // Note that we can still set the human-readable value here - if (/*!isExtensionElement() && */(getValueType() == STRING || getValueType() == ENUMERATED)) { - this.value = value; - } else { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - if(!isExtensionElement()) - setDirty(true); - } - - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setValue(String []) - */ - public void setValue(String [] value) throws BuildException { - if (/*!isExtensionElement() && */ - (getValueType() == STRING_LIST - || getValueType() == INCLUDE_PATH - || getValueType() == PREPROCESSOR_SYMBOLS - || getValueType() == LIBRARIES - || getValueType() == OBJECTS)) { - // Just replace what the option reference is holding onto - if(value == null) - this.value = null; - else - this.value = new ArrayList(Arrays.asList(value)); - } - else { - throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ - } - if(!isExtensionElement()) - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setValue(Object) - */ - public void setValue(Object v) { - value = v; - if(!isExtensionElement()) - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setValueType() - */ - public void setValueType(int type) { - // TODO: Verify that this is a valid type - if (valueType == null || valueType.intValue() != type) { - valueType = new Integer(type); - if(!isExtensionElement()) - setDirty(true); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getValueHandlerElement() - */ - public IConfigurationElement getValueHandlerElement() { - if (valueHandlerElement == null) { - if (superClass != null) { - return ((Option)superClass).getValueHandlerElement(); - } - } - return valueHandlerElement; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setValueHandlerElement(IConfigurationElement) - */ - public void setValueHandlerElement(IConfigurationElement element) { - valueHandlerElement = element; - if(!isExtensionElement()) - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getValueHandler() - */ - public IManagedOptionValueHandler getValueHandler() { - if (valueHandler != null) { - return valueHandler; - } - IConfigurationElement element = getValueHandlerElement(); - if (element != null) { - try { - if (element.getAttribute(VALUE_HANDLER) != null) { - valueHandler = (IManagedOptionValueHandler) element.createExecutableExtension(VALUE_HANDLER); - return valueHandler; - } - } catch (CoreException e) { - ManagedBuildManager.OptionValueHandlerError(element.getAttribute(VALUE_HANDLER), getId()); - // Assign the default handler to avoid further error messages - valueHandler = ManagedOptionValueHandler.getManagedOptionValueHandler(); - return valueHandler; - } - } - // If no handler is provided, then use the default handler - return ManagedOptionValueHandler.getManagedOptionValueHandler(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#getValueHandlerExtraArgument()) - */ - public String getValueHandlerExtraArgument() { - if (valueHandlerExtraArgument == null) { - if (superClass != null) { - return superClass.getValueHandlerExtraArgument(); - } else { - return EMPTY_STRING; - } - } - return valueHandlerExtraArgument; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#setValueHandlerExtraArgument(String)) - */ - public void setValueHandlerExtraArgument(String extraArgument) { - if (extraArgument == null && valueHandlerExtraArgument == null) return; - if (extraArgument == null || - valueHandlerExtraArgument == null || - !extraArgument.equals(valueHandlerExtraArgument)) { - valueHandlerExtraArgument = extraArgument; - if(!isExtensionElement()) - isDirty = true; - } - } - - - /* - * O B J E C T S T A T E M A I N T E N A N C E - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#isExtensionElement() - */ - public boolean isExtensionElement() { - return isExtensionOption; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#overridesOnlyValue() - * Deprecated since 3.0.1 - */ - public boolean overridesOnlyValue() { - if (superClass != null && - unusedChildren == null && - browseType == null && - (builtIns == null || builtIns.size() == 0) && - category == null && - categoryId == null && - command == null && - commandFalse == null && - tip == null && - enumList == null && - enumCommands == null && - enumNames == null && - defaultValue == null) { - return true; - } else { - return false; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#isDirty() - */ - public boolean isDirty() { - // This shouldn't be called for an extension option - if (isExtensionOption) return false; - return isDirty; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setDirty(boolean) - */ - public void setDirty(boolean isDirty) { - this.isDirty = isDirty; - } - - public void resolveReferences() { - - if (!resolved) { - resolved = true; - // Resolve superClass - if (superClassId != null && superClassId.length() > 0) { - superClass = ManagedBuildManager.getExtensionOption(superClassId); - if (superClass == null) { - // Report error - ManagedBuildManager.OutputResolveError( - "superClass", //$NON-NLS-1$ - superClassId, - "option", //$NON-NLS-1$ - getId()); - } else { - // All of our superclasses must be resolved in order to call - // getValueType below. - ((Option)superClass).resolveReferences(); - } - } - if (categoryId != null) { - category = holder.getOptionCategory(categoryId); - if (category == null) { - // Report error - ManagedBuildManager.OutputResolveError( - "category", //$NON-NLS-1$ - categoryId, - "option", //$NON-NLS-1$ - getId()); - } - } - // Process the value and default value attributes. This is delayed until now - // because we may not know the valueType until after we have resolved the superClass above - // Now get the actual value - try { - IManagedConfigElement element = ManagedBuildManager.getConfigElement(this); - switch (getValueType()) { - case BOOLEAN: - // Convert the string to a boolean - String val = element.getAttribute(VALUE); - if (val != null) { - value = new Boolean(val); - } - val = element.getAttribute(DEFAULT_VALUE); - if (val != null) { - defaultValue = new Boolean(val); - } - break; - case STRING: - // Just get the value out of the option directly - value = element.getAttribute(VALUE); - defaultValue = element.getAttribute(DEFAULT_VALUE); - break; - case ENUMERATED: - value = element.getAttribute(VALUE); - defaultValue = element.getAttribute(DEFAULT_VALUE); - - // Do we have enumeratedOptionValue children? If so, load them - // to define the valid values and the default value. - IManagedConfigElement[] enumElements = element.getChildren(ENUM_VALUE); - for (int i = 0; i < enumElements.length; ++i) { - String optId = enumElements[i].getAttribute(ID); - if (i == 0) { - enumList = new ArrayList(); - if (defaultValue == null) { - defaultValue = optId; // Default value to be overridden if default is specified - } - } - enumList.add(optId); - getEnumCommandMap().put(optId, enumElements[i].getAttribute(COMMAND)); - getEnumNameMap().put(optId, enumElements[i].getAttribute(NAME)); - Boolean isDefault = new Boolean(enumElements[i].getAttribute(IS_DEFAULT)); - if (isDefault.booleanValue()) { - defaultValue = optId; - } - } - break; - case STRING_LIST: - case INCLUDE_PATH: - case PREPROCESSOR_SYMBOLS: - case LIBRARIES: - case OBJECTS: - // Note: These string-list options do not load either the "value" or - // "defaultValue" attributes. Instead, the ListOptionValue children - // are loaded in the value field. - List valueList = null; - IManagedConfigElement[] valueElements = element.getChildren(LIST_VALUE); - for (int i = 0; i < valueElements.length; ++i) { - if (i == 0) { - valueList = new ArrayList(); - builtIns = new ArrayList(); - } - IManagedConfigElement valueElement = valueElements[i]; - Boolean isBuiltIn = new Boolean(valueElement.getAttribute(LIST_ITEM_BUILTIN)); - if (isBuiltIn.booleanValue()) { - builtIns.add(valueElement.getAttribute(LIST_ITEM_VALUE)); - } - else { - valueList.add(valueElement.getAttribute(LIST_ITEM_VALUE)); - } - } - value = valueList; - break; - default : - break; - } - } catch (BuildException e) { - // TODO: report error - } - } - } - - /** - * @return Returns the managedBuildRevision. - */ - public String getManagedBuildRevision() { - if ( managedBuildRevision == null) { - if ( getParent() != null) { - return getParent().getManagedBuildRevision(); - } - } - return managedBuildRevision; - } - - /* (non-Javadoc) - * For now implement this method just as a utility to make code - * within the Option class cleaner. - * TODO: In future we may want to move this to IOption - */ - protected boolean isAbstract() { - if (isAbstract != null) { - return isAbstract.booleanValue(); - } else { - return false; // Note: no inheritance from superClass - } - } - - /** - * Verifies whether the option is valid and handles - * any errors for the option. The following errors - * can occur: - * (a) Options that are children of a ToolChain must - * ALWAYS have a category - * (b) Options that are children of a ToolChain must - * NEVER have a resourceFilter of "file". - * If an error occurs, the option is set to being invalid. - * - * @pre All references have been resolved. - */ - private void verify() { - if (verified) return; - verified = true; - // Ignore elements that are superclasses - if ( getOptionHolder() instanceof IToolChain && isAbstract() == false ) { - // Check for error (a) - if (getCategory() == null) { - ManagedBuildManager.OptionValidError(ManagedBuildManager.ERROR_CATEGORY, getId()); - // Object becomes invalid - isValid = false; - } - // Check for error (b). Not specifying an attribute is OK. - // Do not use getResourceFilter as it does not allow - // differentiating between "all" and no attribute specified. - if ( resourceFilter != null ) - { - switch (getResourceFilter()) { - case Option.FILTER_FILE: - // TODO: Cannot differentiate between "all" and attribute not - // specified. Thus do not produce an error. We can argue that "all" - // means all valid resource configurations. - ManagedBuildManager.OptionValidError(ManagedBuildManager.ERROR_FILTER, getId()); - // Object becomes invalid - isValid = false; - } - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IOption#isValid() - */ - public boolean isValid() { - // We use a lazy scheme to check whether the option is valid. - // Note that by default an option is valid. verify() is only called if - // the option has been resolved. This gets us around having to deal with - // ordering problems during a resolve, or introducing another global - // stage to verify the configuration after a resolve. - // The trade-off is that errors in the MBS grammar may not be - // detected on load, but only when a particular grammar element - // is used, say in the GUI. - if (verified == false && resolved == true) { - verify(); - } - return isValid; - } - - /** - * @return Returns true if this Option was created from an MBS 2.0 model - * OptionReference element. - */ - public boolean wasOptRef() { - return wasOptRef; - } - - public void setWasOptRef(boolean was) { - wasOptRef = was; - } - - /** - * @return Returns the version. - */ - public PluginVersionIdentifier getVersion() { - if ( version == null) { - if ( getParent() != null) { - return getParent().getVersion(); - } - } - return version; - } - - public void setVersion(PluginVersionIdentifier version) { - // Do nothing - } - - public BooleanExpressionApplicabilityCalculator getBooleanExpressionCalculator(){ - return booleanExpressionCalculator; - } - - public boolean isAdjustedExtension(){ - return isUdjusted; - } - - public void setAdjusted(boolean adjusted) { - isUdjusted = adjusted; - } - -} +/******************************************************************************* + * Copyright (c) 2003, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + * ARM Ltd. - basic tooltip support + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.core; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IHoldsOptions; +import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; +import org.eclipse.cdt.managedbuilder.core.IManagedOptionValueHandler; +import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.cdt.managedbuilder.core.IOptionApplicability; +import org.eclipse.cdt.managedbuilder.core.IOptionCategory; +import org.eclipse.cdt.managedbuilder.core.IProjectType; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.core.ManagedOptionValueHandler; +import org.eclipse.cdt.managedbuilder.internal.enablement.OptionEnablementExpression; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.PluginVersionIdentifier; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class Option extends BuildObject implements IOption { + // Static default return values + private static final String EMPTY_STRING = new String(); + private static final String[] EMPTY_STRING_ARRAY = new String[0]; + + // Superclass + private IOption superClass; + private String superClassId; + // Parent and children + private IHoldsOptions holder; + // Managed Build model attributes + private String unusedChildren; + private Integer browseType; + private List builtIns; + private IOptionCategory category; + private String categoryId; + private String command; + private String commandFalse; + private String tip; + private List enumList; + private Map enumCommands; + private Map enumNames; + private Object value; + private Object defaultValue; + private Integer valueType; + private Boolean isAbstract; + private Integer resourceFilter; + private IConfigurationElement valueHandlerElement = null; + private IManagedOptionValueHandler valueHandler = null; + private String valueHandlerExtraArgument; + private IConfigurationElement applicabilityCalculatorElement = null; + private IOptionApplicability applicabilityCalculator = null; + private BooleanExpressionApplicabilityCalculator booleanExpressionCalculator = null; + // Miscellaneous + private boolean isExtensionOption = false; + private boolean isDirty = false; + private boolean resolved = true; + private boolean verified = false; + private boolean isValid = true; /** False for options which are invalid. getOption() + * routines will ignore invalid options. */ + private boolean wasOptRef = false; /** True for options which are created because of an + * MBS 2.0 model OptionReference element + */ + private boolean isUdjusted = false; + + /* + * C O N S T R U C T O R S + */ + + /** + * This constructor is called to create an option defined by an extension point in + * a plugin manifest file, or returned by a dynamic element provider + * + * @param parent The IHoldsOptions parent of this option, or null if + * defined at the top level + * @param element The option definition from the manifest file or a dynamic element + * provider + */ + public Option(IHoldsOptions parent, IManagedConfigElement element) { + this.holder = parent; + isExtensionOption = true; + + // setup for resolving + resolved = false; + + loadFromManifest(element); + + // Hook me up to the Managed Build Manager + ManagedBuildManager.addExtensionOption(this); + } + + /** + * This constructor is called to create an Option whose attributes and children will be + * added by separate calls. + * + * @param IHoldsOptions The parent of the option, if any + * @param Option The superClass, if any + * @param String The id for the new option + * @param String The name for the new option + * @param boolean Indicates whether this is an extension element or a managed project element + */ + public Option(IHoldsOptions parent, IOption superClass, String Id, String name, boolean isExtensionElement) { + this.holder = parent; + this.superClass = superClass; + if (this.superClass != null) { + superClassId = this.superClass.getId(); + } + setId(Id); + setName(name); + isExtensionOption = isExtensionElement; + if (isExtensionElement) { + // Hook me up to the Managed Build Manager + ManagedBuildManager.addExtensionOption(this); + } else { + setDirty(true); + } + } + + /** + * Create an Option based on the specification stored in the + * project file (.cdtbuild). + * + * @param parent The IHoldsOptions the option will be added to. + * @param element The XML element that contains the option settings. + */ + public Option(IHoldsOptions parent, Element element) { + this.holder = parent; + isExtensionOption = false; + + // Initialize from the XML attributes + loadFromProject(element); + } + + /** + * Create an Option based upon an existing option. + * + * @param parent The IHoldsOptions the option will be added to. + * @param Id New ID for the option. + * @param name New name for the option. + * @param option The existing option to clone, except for the above fields. + */ + public Option(IHoldsOptions parent, String Id, String name, Option option){ + this.holder = parent; + superClass = option.superClass; + if (superClass != null) { + superClassId = option.superClass.getId(); + } + setId(Id); + setName(name); + isExtensionOption = false; + + // Copy the remaining attributes + if (option.unusedChildren != null) { + unusedChildren = new String(option.unusedChildren); + } + if (option.isAbstract != null) { + isAbstract = new Boolean(option.isAbstract.booleanValue()); + } + if (option.command != null) { + command = new String(option.command); + } + if (option.commandFalse != null) { + commandFalse = new String(option.commandFalse); + } + if (option.tip != null) { + tip = new String(option.tip); + } + if (option.categoryId != null) { + categoryId = new String(option.categoryId); + } + if (option.builtIns != null) { + builtIns = new ArrayList(option.builtIns); + } + if (option.browseType != null) { + browseType = new Integer(option.browseType.intValue()); + } + if (option.resourceFilter != null) { + resourceFilter = new Integer(option.resourceFilter.intValue()); + } + if (option.enumList != null) { + enumList = new ArrayList(option.enumList); + enumCommands = new HashMap(option.enumCommands); + enumNames = new HashMap(option.enumNames); + } + + if (option.valueType != null) { + valueType = new Integer(option.valueType.intValue()); + } + Integer vType = null; + try { + vType = new Integer(option.getValueType()); + if (vType != null) { + switch (vType.intValue()) { + case BOOLEAN: + if (option.value != null) { + value = new Boolean(((Boolean)option.value).booleanValue()); + } + if (option.defaultValue != null) { + defaultValue = new Boolean(((Boolean)option.defaultValue).booleanValue()); + } + break; + case STRING: + case ENUMERATED: + if (option.value != null) { + value = new String((String)option.value); + } + if (option.defaultValue != null) { + defaultValue = new String((String)option.defaultValue); + } + break; + case STRING_LIST: + case INCLUDE_PATH: + case PREPROCESSOR_SYMBOLS: + case LIBRARIES: + case OBJECTS: + if (option.value != null) { + value = new ArrayList((ArrayList)option.value); + } + if (option.defaultValue != null) { + defaultValue = new ArrayList((ArrayList)option.defaultValue); + } + break; + } + } + } catch (BuildException be) { + // TODO: should we ignore this?? + } + + category = option.category; + applicabilityCalculatorElement = option.applicabilityCalculatorElement; + applicabilityCalculator = option.applicabilityCalculator; + + booleanExpressionCalculator = option.booleanExpressionCalculator; + + if (option.valueHandlerElement != null) { + valueHandlerElement = option.valueHandlerElement; + valueHandler = option.valueHandler; + } + if (option.valueHandlerExtraArgument != null) { + valueHandlerExtraArgument = new String(option.valueHandlerExtraArgument); + } + + if(!isExtensionElement()) + setDirty(true); + } + + /* + * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S + */ + + /* (non-Javadoc) + * Loads the option information from the ManagedConfigElement specified in the + * argument. + * + * @param element Contains the option information + */ + protected void loadFromManifest(IManagedConfigElement element) { + ManagedBuildManager.putConfigElement(this, element); + + // id + setId(element.getAttribute(IBuildObject.ID)); + + // Get the name + setName(element.getAttribute(IBuildObject.NAME)); + + // superClass + superClassId = element.getAttribute(IProjectType.SUPERCLASS); + + // Get the unused children, if any + unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); + + // isAbstract + String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); + if (isAbs != null){ + isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ + } + + // Get the command defined for the option + command = element.getAttribute(COMMAND); + + // Get the command defined for a Boolean option when the value is False + commandFalse = element.getAttribute(COMMAND_FALSE); + + // Get the tooltip for the option + tip = element.getAttribute(TOOL_TIP); + + // Options hold different types of values + String valueTypeStr = element.getAttribute(VALUE_TYPE); + if (valueTypeStr != null) { + valueType = new Integer(ValueTypeStrToInt(valueTypeStr)); + } + + // Note: The value and defaultValue attributes are loaded in the resolveReferences routine. + // This is because we need to have the value-type, and this may be defined in a + // superClass that is not yet loaded. + + // Determine if there needs to be a browse button + String browseTypeStr = element.getAttribute(BROWSE_TYPE); + if (browseTypeStr == null) { + // Set to null, to indicate no browse type specification + // This will allow any superclasses to be searched for the + // browse type specification, and thus inherited, if found, + // which they should be + browseType = null; + } else if (browseTypeStr.equals(NONE)) { + browseType = new Integer(BROWSE_NONE); + } else if (browseTypeStr.equals(FILE)) { + browseType = new Integer(BROWSE_FILE); + } else if (browseTypeStr.equals(DIR)) { + browseType = new Integer(BROWSE_DIR); + } + + categoryId = element.getAttribute(CATEGORY); + + // Get the resourceFilter attribute + String resFilterStr = element.getAttribute(RESOURCE_FILTER); + if (resFilterStr == null) { + // Set to null, to indicate no resource filter specification + // This will allow any superclasses to be searched for the + // resource filter specification, and thus inherited, if found, + // which they should be + resourceFilter = null; + } else if (resFilterStr.equals(ALL)) { + resourceFilter = new Integer(FILTER_ALL); + } else if (resFilterStr.equals(FILE)) { + resourceFilter = new Integer(FILTER_FILE); + } else if (resFilterStr.equals(PROJECT)) { + resourceFilter = new Integer(FILTER_PROJECT); + } + + //get enablements + IManagedConfigElement enablements[] = element.getChildren(OptionEnablementExpression.NAME); + if(enablements.length > 0) + booleanExpressionCalculator = new BooleanExpressionApplicabilityCalculator(enablements); + + // get the applicability calculator, if any + String applicabilityCalculatorStr = element.getAttribute(APPLICABILITY_CALCULATOR); + if (applicabilityCalculatorStr != null && element instanceof DefaultManagedConfigElement) { + applicabilityCalculatorElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); + } else { + applicabilityCalculator = booleanExpressionCalculator; + } + + // valueHandler + // Store the configuration element IFF there is a value handler defined + String valueHandler = element.getAttribute(VALUE_HANDLER); + if (valueHandler != null && element instanceof DefaultManagedConfigElement) { + valueHandlerElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); + } + // valueHandlerExtraArgument + valueHandlerExtraArgument = element.getAttribute(VALUE_HANDLER_EXTRA_ARGUMENT); + } + + /* (non-Javadoc) + * Initialize the option information from the XML element + * specified in the argument + * + * @param element An XML element containing the option information + */ + protected void loadFromProject(Element element) { + + // id + setId(element.getAttribute(IBuildObject.ID)); + + // name + if (element.hasAttribute(IBuildObject.NAME)) { + setName(element.getAttribute(IBuildObject.NAME)); + } + + // superClass + superClassId = element.getAttribute(IProjectType.SUPERCLASS); + if (superClassId != null && superClassId.length() > 0) { + superClass = ManagedBuildManager.getExtensionOption(superClassId); + if (superClass == null) { + // TODO: Report error + } + } + + // Get the unused children, if any + if (element.hasAttribute(IProjectType.UNUSED_CHILDREN)) { + unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); + } + + // isAbstract + if (element.hasAttribute(IProjectType.IS_ABSTRACT)) { + String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); + if (isAbs != null){ + isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ + } + } + + // Get the command defined for the option + if (element.hasAttribute(COMMAND)) { + command = element.getAttribute(COMMAND); + } + + // Get the command defined for a Boolean option when the value is False + if (element.hasAttribute(COMMAND_FALSE)) { + commandFalse = element.getAttribute(COMMAND_FALSE); + } + + // Get the tooltip for the option + if (element.hasAttribute(TOOL_TIP)) { + tip = element.getAttribute(TOOL_TIP); + } + + // Options hold different types of values + if (element.hasAttribute(VALUE_TYPE)) { + String valueTypeStr = element.getAttribute(VALUE_TYPE); + valueType = new Integer(ValueTypeStrToInt(valueTypeStr)); + } + + // Now get the actual value based upon value-type + try { + int valType = getValueType(); + switch (valType) { + case BOOLEAN: + // Convert the string to a boolean + if (element.hasAttribute(VALUE)) { + value = new Boolean(element.getAttribute(VALUE)); + } + if (element.hasAttribute(DEFAULT_VALUE)) { + defaultValue = new Boolean(element.getAttribute(DEFAULT_VALUE)); + } + break; + case STRING: + // Just get the value out of the option directly + if (element.hasAttribute(VALUE)) { + value = element.getAttribute(VALUE); + } + if (element.hasAttribute(DEFAULT_VALUE)) { + defaultValue = element.getAttribute(DEFAULT_VALUE); + } + break; + case ENUMERATED: + if (element.hasAttribute(VALUE)) { + value = element.getAttribute(VALUE); + } + if (element.hasAttribute(DEFAULT_VALUE)) { + defaultValue = element.getAttribute(DEFAULT_VALUE); + } + + // Do we have enumeratedOptionValue children? If so, load them + // to define the valid values and the default value. + NodeList configElements = element.getChildNodes(); + for (int i = 0; i < configElements.getLength(); ++i) { + Node configNode = configElements.item(i); + if (configNode.getNodeName().equals(ENUM_VALUE)) { + Element configElement = (Element)configNode; + String optId = configElement.getAttribute(ID); + if (i == 0) { + enumList = new ArrayList(); + if (defaultValue == null) { + defaultValue = optId; // Default value to be overridden is default is specified + } + } + enumList.add(optId); + if (configElement.hasAttribute(COMMAND)) { + getEnumCommandMap().put(optId, configElement.getAttribute(COMMAND)); + } else { + getEnumCommandMap().put(optId, EMPTY_STRING); + } + getEnumNameMap().put(optId, configElement.getAttribute(NAME)); + if (configElement.hasAttribute(IS_DEFAULT)) { + Boolean isDefault = new Boolean(configElement.getAttribute(IS_DEFAULT)); + if (isDefault.booleanValue()) { + defaultValue = optId; + } + } + } + } + break; + case STRING_LIST: + case INCLUDE_PATH: + case PREPROCESSOR_SYMBOLS: + case LIBRARIES: + case OBJECTS: + // Note: These string-list options do not load either the "value" or + // "defaultValue" attributes. Instead, the ListOptionValue children + // are loaded in the value field. + List valueList = null; + configElements = element.getChildNodes(); + for (int i = 0; i < configElements.getLength(); ++i) { + if (i == 0) { + valueList = new ArrayList(); + builtIns = new ArrayList(); + } + Node configNode = configElements.item(i); + if (configNode.getNodeName().equals(LIST_VALUE)) { + Element valueElement = (Element)configNode; + Boolean isBuiltIn; + if (valueElement.hasAttribute(IS_DEFAULT)) { + isBuiltIn = new Boolean(valueElement.getAttribute(LIST_ITEM_BUILTIN)); + } else { + isBuiltIn = new Boolean(false); + } + if (isBuiltIn.booleanValue()) { + builtIns.add(valueElement.getAttribute(LIST_ITEM_VALUE)); + } + else { + valueList.add(valueElement.getAttribute(LIST_ITEM_VALUE)); + } + } + } + value = valueList; + break; + default : + break; + } + } catch (BuildException e) { + // TODO: report error + } + + // Determine if there needs to be a browse button + if (element.hasAttribute(BROWSE_TYPE)) { + String browseTypeStr = element.getAttribute(BROWSE_TYPE); + + if (browseTypeStr == null) { + // Set to null, to indicate no browse type specification + // This will allow any superclasses to be searched for the + // browse type specification, and thus inherited, if found, + // which they should be + browseType = null; + } else if (browseTypeStr.equals(NONE)) { + browseType = new Integer(BROWSE_NONE); + } else if (browseTypeStr.equals(FILE)) { + browseType = new Integer(BROWSE_FILE); + } else if (browseTypeStr.equals(DIR)) { + browseType = new Integer(BROWSE_DIR); + } + } + + if (element.hasAttribute(CATEGORY)) { + categoryId = element.getAttribute(CATEGORY); + if (categoryId != null) { + category = holder.getOptionCategory(categoryId); + } + } + + // Get the resourceFilter attribute + if (element.hasAttribute(RESOURCE_FILTER)) { + String resFilterStr = element.getAttribute(RESOURCE_FILTER); + if (resFilterStr == null) { + // Set to null, to indicate no resource filter specification + // This will allow any superclasses to be searched for the + // resource filter specification, and thus inherited, if found, + // which they should be + resourceFilter = null; + } else if (resFilterStr.equals(ALL)) { + resourceFilter = new Integer(FILTER_ALL); + } else if (resFilterStr.equals(FILE)) { + resourceFilter = new Integer(FILTER_FILE); + } else if (resFilterStr.equals(PROJECT)) { + resourceFilter = new Integer(FILTER_PROJECT); + } + } + + // Note: valueHandlerElement and VALUE_HANDLER are not restored, + // as they are not saved. See note in serialize(). + + // valueHandlerExtraArgument + if (element.hasAttribute(VALUE_HANDLER_EXTRA_ARGUMENT)) { + valueHandlerExtraArgument = element.getAttribute(VALUE_HANDLER_EXTRA_ARGUMENT); + } + } + + private int ValueTypeStrToInt(String valueTypeStr) { + if (valueTypeStr == null) return -1; + if (valueTypeStr.equals(TYPE_STRING)) + return STRING; + else if (valueTypeStr.equals(TYPE_STR_LIST)) + return STRING_LIST; + else if (valueTypeStr.equals(TYPE_BOOL)) + return BOOLEAN; + else if (valueTypeStr.equals(TYPE_ENUM)) + return ENUMERATED; + else if (valueTypeStr.equals(TYPE_INC_PATH)) + return INCLUDE_PATH; + else if (valueTypeStr.equals(TYPE_LIB)) + return LIBRARIES; + else if (valueTypeStr.equals(TYPE_USER_OBJS)) + return OBJECTS; + else if (valueTypeStr.equals(TYPE_DEFINED_SYMBOLS)) + return PREPROCESSOR_SYMBOLS; + else { + // TODO: This was the CDT 2.0 default - should we keep it? + return PREPROCESSOR_SYMBOLS; + } + } + + /** + * Persist the option to the project file. + * + * @param doc + * @param element + */ + public void serialize(Document doc, Element element) throws BuildException { + if (superClass != null) + element.setAttribute(IProjectType.SUPERCLASS, superClass.getId()); + + element.setAttribute(IBuildObject.ID, id); + + if (name != null) { + element.setAttribute(IBuildObject.NAME, name); + } + + if (unusedChildren != null) { + element.setAttribute(IProjectType.UNUSED_CHILDREN, unusedChildren); + } + + if (isAbstract != null) { + element.setAttribute(IProjectType.IS_ABSTRACT, isAbstract.toString()); + } + + if (command != null) { + element.setAttribute(COMMAND, command); + } + + if (commandFalse != null) { + element.setAttribute(COMMAND_FALSE, commandFalse); + } + + if (tip != null) { + element.setAttribute(TOOL_TIP, tip); + } + + /* + * Note: We store value & value-type as a pair, so we know what type of value we are + * dealing with when we read it back in. + * This is also true of defaultValue. + */ + boolean storeValueType = false; + + // value + if (value != null) { + storeValueType = true; + switch (getValueType()) { + case BOOLEAN: + element.setAttribute(VALUE, ((Boolean)value).toString()); + break; + case STRING: + case ENUMERATED: + element.setAttribute(VALUE, (String)value); + break; + case STRING_LIST: + case INCLUDE_PATH: + case PREPROCESSOR_SYMBOLS: + case LIBRARIES: + case OBJECTS: + if (value != null) { + ArrayList stringList = (ArrayList)value; + ListIterator iter = stringList.listIterator(); + while (iter.hasNext()) { + Element valueElement = doc.createElement(LIST_VALUE); + valueElement.setAttribute(LIST_ITEM_VALUE, (String)iter.next()); + valueElement.setAttribute(LIST_ITEM_BUILTIN, "false"); //$NON-NLS-1$ + element.appendChild(valueElement); + } + } + // Serialize the built-ins that have been overridden + if (builtIns != null) { + ListIterator iter = builtIns.listIterator(); + while (iter.hasNext()) { + Element valueElement = doc.createElement(LIST_VALUE); + valueElement.setAttribute(LIST_ITEM_VALUE, (String)iter.next()); + valueElement.setAttribute(LIST_ITEM_BUILTIN, "true"); //$NON-NLS-1$ + element.appendChild(valueElement); + } + } + break; + } + } + + // defaultValue + if (defaultValue != null) { + storeValueType = true; + switch (getValueType()) { + case BOOLEAN: + element.setAttribute(DEFAULT_VALUE, ((Boolean)defaultValue).toString()); + break; + case STRING: + case ENUMERATED: + element.setAttribute(DEFAULT_VALUE, (String)defaultValue); + break; + default: + break; + } + } + + if (storeValueType) { + String str; + switch (getValueType()) { + case BOOLEAN: + str = TYPE_BOOL; + break; + case STRING: + str = TYPE_STRING; + break; + case ENUMERATED: + str = TYPE_ENUM; + break; + case STRING_LIST: + str = TYPE_STR_LIST; + break; + case INCLUDE_PATH: + str = TYPE_INC_PATH; + break; + case LIBRARIES: + str = TYPE_LIB; + break; + case OBJECTS: + str = TYPE_USER_OBJS; + break; + case PREPROCESSOR_SYMBOLS: + str = TYPE_DEFINED_SYMBOLS; + break; + default: + // TODO; is this a problem... + str = EMPTY_STRING; + break; + } + element.setAttribute(VALUE_TYPE, str); + } + + // browse type + if (browseType != null) { + String str; + switch (getBrowseType()) { + case BROWSE_NONE: + str = NONE; + break; + case BROWSE_FILE: + str = FILE; + break; + case BROWSE_DIR: + str = DIR; + break; + default: + str = EMPTY_STRING; + break; + } + element.setAttribute(BROWSE_TYPE, str); + } + + if (categoryId != null) { + element.setAttribute(CATEGORY, categoryId); + } + + // resource filter + if (resourceFilter != null) { + String str; + switch (getResourceFilter()) { + case FILTER_ALL: + str = ALL; + break; + case FILTER_FILE: + str = FILE; + break; + case FILTER_PROJECT: + str = PROJECT; + break; + default: + str = EMPTY_STRING; + break; + } + element.setAttribute(RESOURCE_FILTER, str); + } + + // Note: applicability calculator cannot be specified in a project file because + // an IConfigurationElement is needed to load it! + if (applicabilityCalculatorElement != null) { + // TODO: issue warning? + } + + // Note: a value handler cannot be specified in a project file because + // an IConfigurationElement is needed to load it! + if (valueHandlerElement != null) { + // TODO: Issue warning? Stuck with behavior of this elsewhere in + // CDT, e.g. the implementation of Tool + } + if (valueHandlerExtraArgument != null) { + element.setAttribute(VALUE_HANDLER_EXTRA_ARGUMENT, valueHandlerExtraArgument); + } + + // I am clean now + isDirty = false; + } + + /* + * P A R E N T A N D C H I L D H A N D L I N G + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getParent() + */ + public IBuildObject getParent() { + return holder; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getOptionHolder() + */ + public IHoldsOptions getOptionHolder() { + // Do not take superclasses into account + return holder; + } + + /* + * M O D E L A T T R I B U T E A C C E S S O R S + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getSuperClass() + */ + public IOption getSuperClass() { + return superClass; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getName() + */ + public String getName() { + return (name == null && superClass != null) ? superClass.getName() : name; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getApplicableValues() + */ + public String[] getApplicableValues() { + // Does this option instance have the list of values? + if (enumList == null) { + if (superClass != null) { + return superClass.getApplicableValues(); + } else { + return EMPTY_STRING_ARRAY; + } + } + // Get all of the enumerated names from the option + if (enumList.size() == 0) { + return EMPTY_STRING_ARRAY; + } else { + // Return the elements in the order they are specified in the manifest + String[] enumNames = new String[enumList.size()]; + for (int index = 0; index < enumList.size(); ++ index) { + enumNames[index] = (String) getEnumNameMap().get(enumList.get(index)); + } + return enumNames; + } + } + + public boolean getBooleanValue() { + return ((Boolean)getValue()).booleanValue(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getBrowseType() + */ + public int getBrowseType() { + if (browseType == null) { + if (superClass != null) { + return superClass.getBrowseType(); + } else { + return BROWSE_NONE; + } + } + return browseType.intValue(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getResourceFilter() + */ + public int getResourceFilter() { + if (resourceFilter == null) { + if (superClass != null) { + return superClass.getResourceFilter(); + } else { + return FILTER_ALL; + } + } + return resourceFilter.intValue(); + } + + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.managedbuilder.core.IOption#getApplicabilityCalculatorElement() + */ + public IConfigurationElement getApplicabilityCalculatorElement() { +/* if (applicabilityCalculatorElement == null) { + if (superClass != null) { + return ((Option)superClass).getApplicabilityCalculatorElement(); + } + } +*/ + return applicabilityCalculatorElement; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.managedbuilder.core.IOption#getApplicabilityCalculator() + */ + public IOptionApplicability getApplicabilityCalculator() { + if (applicabilityCalculator == null) { + if (applicabilityCalculatorElement != null) { + try { + if (applicabilityCalculatorElement.getAttribute(APPLICABILITY_CALCULATOR) != null) + applicabilityCalculator = (IOptionApplicability) applicabilityCalculatorElement + .createExecutableExtension(APPLICABILITY_CALCULATOR); + } catch (CoreException e) { + } + } + else if(superClass != null) + applicabilityCalculator = superClass.getApplicabilityCalculator(); + } + + return applicabilityCalculator; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getBuiltIns() + */ + public String[] getBuiltIns() { + // Return the list of built-ins as an array + if (builtIns == null) { + if (superClass != null) { + return superClass.getBuiltIns(); + } else { + return EMPTY_STRING_ARRAY; + } + } + return (String[])builtIns.toArray(new String[builtIns.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getCategory() + */ + public IOptionCategory getCategory() { + if (category == null) { + if (superClass != null) { + return superClass.getCategory(); + } else { + if (getOptionHolder() instanceof ITool) { + return ((ITool)getOptionHolder()).getTopOptionCategory(); + } else { + return null; + } + } + } + return category; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getCommand() + */ + public String getCommand() { + if (command == null) { + if (superClass != null) { + return superClass.getCommand(); + } else { + return EMPTY_STRING; + } + } + return command; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getCommandFalse() + */ + public String getCommandFalse() { + if (commandFalse == null) { + if (superClass != null) { + return superClass.getCommandFalse(); + } else { + return EMPTY_STRING; + } + } + return commandFalse; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getToolTip() + */ + public String getToolTip() { + if (tip == null) { + if (superClass != null) { + return superClass.getToolTip(); + } else { + return EMPTY_STRING; + } + } + return tip; + } + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getDefinedSymbols() + */ + public String[] getDefinedSymbols() throws BuildException { + if (getValueType() != PREPROCESSOR_SYMBOLS) { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + ArrayList v = (ArrayList)getValue(); + if (v == null) { + return EMPTY_STRING_ARRAY; + } else { + v.trimToSize(); + return (String[]) v.toArray(new String[v.size()]); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getEnumCommand(java.lang.String) + */ + public String getEnumCommand(String id) throws BuildException { + // Sanity + if (id == null) return EMPTY_STRING; + + // Does this option instance have the list of values? + if (enumList == null) { + if (superClass != null) { + return superClass.getEnumCommand(id); + } else { + return EMPTY_STRING; + } + } + if (getValueType() != ENUMERATED) { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + + // First check for the command in ID->command map + String cmd = (String) getEnumCommandMap().get(id); + if (cmd == null) { + // This may be a 1.2 project or plugin manifest. If so, the argument is the human readable + // name of the enumeration. Search for the ID that maps to the name and use that to find the + // command. + ListIterator iter = enumList.listIterator(); + while (iter.hasNext()) { + String realID = (String) iter.next(); + String name = (String) getEnumNameMap().get(realID); + if (id.equals(name)) { + cmd = (String) getEnumCommandMap().get(realID); + break; + } + } + } + return cmd == null ? EMPTY_STRING : cmd; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getEnumName(java.lang.String) + */ + public String getEnumName(String id) throws BuildException { + // Sanity + if (id == null) return EMPTY_STRING; + + // Does this option instance have the list of values? + if (enumList == null) { + if (superClass != null) { + return superClass.getEnumName(id); + } else { + return EMPTY_STRING; + } + } + if (getValueType() != ENUMERATED) { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + + // First check for the command in ID->name map + String name = (String) getEnumNameMap().get(id); + if (name == null) { + // This may be a 1.2 project or plugin manifest. If so, the argument is the human readable + // name of the enumeration. + name = id; + } + return name; + } + + /* (non-Javadoc) + * A memory-safe accessor to the map of enumerated option value IDs to the commands + * that a tool understands. + * + * @return a Map of enumerated option value IDs to actual commands that are passed + * to a tool on the command line. + */ + private Map getEnumCommandMap() { + if (enumCommands == null) { + enumCommands = new HashMap(); + } + return enumCommands; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getEnumeratedId(java.lang.String) + */ + public String getEnumeratedId(String name) throws BuildException { + if (name == null) return null; + + // Does this option instance have the list of values? + if (enumList == null) { + if (superClass != null) { + return superClass.getEnumeratedId(name); + } else { + return EMPTY_STRING; + } + } + if (getValueType() != ENUMERATED) { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + + Set idSet = getEnumNameMap().keySet(); + Iterator iter = idSet.iterator(); + while (iter.hasNext()) { + String id = (String) iter.next(); + String enumName = (String) getEnumNameMap().get(id); + if (name.equals(enumName)) { + return id; + } + } + return null; + } + + /* (non-Javadoc) + * + * @return a Map of enumerated option value IDs to the selection displayed to the user. + */ + private Map getEnumNameMap() { + if (enumNames == null) { + enumNames = new HashMap(); + } + return enumNames; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getIncludePaths() + */ + public String[] getIncludePaths() throws BuildException { + if (getValueType() != INCLUDE_PATH) { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + ArrayList v = (ArrayList)getValue(); + if (v == null) { + return EMPTY_STRING_ARRAY; + } else { + v.trimToSize(); + return (String[]) v.toArray(new String[v.size()]); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getLibraries() + */ + public String[] getLibraries() throws BuildException { + if (getValueType() != LIBRARIES) { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + ArrayList v = (ArrayList)getValue(); + if (v == null) { + return EMPTY_STRING_ARRAY; + } else { + v.trimToSize(); + return (String[]) v.toArray(new String[v.size()]); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getDefaultEnumValue() + */ + public String getSelectedEnum() throws BuildException { + if (getValueType() != ENUMERATED) { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + return getStringValue(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getStringListValue() + */ + public String[] getStringListValue() throws BuildException { + if (getValueType() != STRING_LIST) { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + ArrayList v = (ArrayList)getValue(); + if (v == null) { + return EMPTY_STRING_ARRAY; + } else { + v.trimToSize(); + return (String[]) v.toArray(new String[v.size()]); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getStringValue() + */ + public String getStringValue() throws BuildException { + if (getValueType() != STRING && getValueType() != ENUMERATED) { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + return getValue() == null ? EMPTY_STRING : (String)getValue(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getUserObjects() + */ + public String[] getUserObjects() throws BuildException { + if (getValueType() != OBJECTS) { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + // This is the right puppy, so return its list value + ArrayList v = (ArrayList)getValue(); + if (v == null) { + return EMPTY_STRING_ARRAY; + } else { + v.trimToSize(); + return (String[]) v.toArray(new String[v.size()]); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getValueType() + */ + public int getValueType() throws BuildException { + if (valueType == null) { + if (superClass != null) { + return superClass.getValueType(); + } else { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$; + } + } + return valueType.intValue(); + } + + /* (non-Javadoc) + * Gets the value, applying appropriate defaults if necessary. + */ + public Object getValue() { + /* + * In order to determine the current value of an option, perform the following steps until a value is found: + * 1. Examine the value attribute of the option. + * 2. Examine the value attribute of the option’s superClass recursively. + * 3. Examine the dynamicDefaultValue attribute of the option and invoke it if specified. (not yet implemented) + * 4. Examine the defaultValue attribute of the option. + * 5. Examine the dynamicDefaultValue attribute of the option’s superClass and invoke it if specified. (not yet implemented) + * 6. Examine the defaultValue attribute of the option’s superClass. + * 7. Go to step 5 recursively until no more super classes. + * 8. Use the default value for the option type. + */ + + Object val = getRawValue(); + if (val == null) { + val = getDefaultValue(); + if (val == null) { + int valType; + try { + valType = getValueType(); + } catch (BuildException e) { + return EMPTY_STRING; + } + switch (valType) { + case BOOLEAN: + val = new Boolean(false); + break; + case STRING: + val = EMPTY_STRING; + break; + case ENUMERATED: + // TODO: Can we default to the first enumerated id? + val = EMPTY_STRING; + break; + case STRING_LIST: + case INCLUDE_PATH: + case PREPROCESSOR_SYMBOLS: + case LIBRARIES: + case OBJECTS: + val = new ArrayList(); + break; + default: + val = EMPTY_STRING; + break; + } + } + } + return val; + } + + /* (non-Javadoc) + * Gets the raw value, applying appropriate defauls if necessary. + */ + public Object getRawValue() { + if (value == null) { + if (superClass != null) { + Option mySuperClass = (Option)superClass; + return mySuperClass.getRawValue(); + } + } + return value; + } + + /* (non-Javadoc) + * Gets the raw default value. + */ + public Object getDefaultValue() { + // Note: string-list options do not have a default value + if (defaultValue == null) { + if (superClass != null) { + return superClass.getDefaultValue(); + } + } + return defaultValue; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setValue(Object) + */ + public void setDefaultValue(Object v) { + defaultValue = v; + if(!isExtensionElement()) + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setCategory(org.eclipse.cdt.managedbuilder.core.IOptionCategory) + */ + public void setCategory(IOptionCategory category) { + if (this.category != category) { + this.category = category; + if (category != null) { + categoryId = category.getId(); + } else { + categoryId = null; + } + if(!isExtensionElement()) + setDirty(true); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setCommand(String) + */ + public void setCommand(String cmd) { + if (cmd == null && command == null) return; + if (cmd == null || command == null || !cmd.equals(command)) { + command = cmd; + if(!isExtensionElement()) + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setCommandFalse(String) + */ + public void setCommandFalse(String cmd) { + if (cmd == null && commandFalse == null) return; + if (cmd == null || commandFalse == null || !cmd.equals(commandFalse)) { + commandFalse = cmd; + if(!isExtensionElement()) + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setToolTip(String) + */ + public void setToolTip(String tooltip) { + if (tooltip == null && tip == null) return; + if (tooltip == null || tip == null || !tooltip.equals(tip)) { + tip = tooltip; + if(!isExtensionElement()) + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setResourceFilter(int) + */ + public void setResourceFilter(int filter) { + if (resourceFilter == null || !(filter == resourceFilter.intValue())) { + resourceFilter = new Integer(filter); + if(!isExtensionElement()) + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setBrowseType(int) + */ + public void setBrowseType(int type) { + if (browseType == null || !(type == browseType.intValue())) { + browseType = new Integer(type); + if(!isExtensionElement()) + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setValue(boolean) + */ + public void setValue(boolean value) throws BuildException { + if (/*!isExtensionElement() && */getValueType() == BOOLEAN){ + this.value = new Boolean(value); + } else { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + if(!isExtensionElement()) + setDirty(true); + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setValue(String) + */ + public void setValue(String value) throws BuildException { + // Note that we can still set the human-readable value here + if (/*!isExtensionElement() && */(getValueType() == STRING || getValueType() == ENUMERATED)) { + this.value = value; + } else { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + if(!isExtensionElement()) + setDirty(true); + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setValue(String []) + */ + public void setValue(String [] value) throws BuildException { + if (/*!isExtensionElement() && */ + (getValueType() == STRING_LIST + || getValueType() == INCLUDE_PATH + || getValueType() == PREPROCESSOR_SYMBOLS + || getValueType() == LIBRARIES + || getValueType() == OBJECTS)) { + // Just replace what the option reference is holding onto + if(value == null) + this.value = null; + else + this.value = new ArrayList(Arrays.asList(value)); + } + else { + throw new BuildException(ManagedMakeMessages.getResourceString("Option.error.bad_value_type")); //$NON-NLS-1$ + } + if(!isExtensionElement()) + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setValue(Object) + */ + public void setValue(Object v) { + value = v; + if(!isExtensionElement()) + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setValueType() + */ + public void setValueType(int type) { + // TODO: Verify that this is a valid type + if (valueType == null || valueType.intValue() != type) { + valueType = new Integer(type); + if(!isExtensionElement()) + setDirty(true); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getValueHandlerElement() + */ + public IConfigurationElement getValueHandlerElement() { + if (valueHandlerElement == null) { + if (superClass != null) { + return ((Option)superClass).getValueHandlerElement(); + } + } + return valueHandlerElement; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setValueHandlerElement(IConfigurationElement) + */ + public void setValueHandlerElement(IConfigurationElement element) { + valueHandlerElement = element; + if(!isExtensionElement()) + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getValueHandler() + */ + public IManagedOptionValueHandler getValueHandler() { + if (valueHandler != null) { + return valueHandler; + } + IConfigurationElement element = getValueHandlerElement(); + if (element != null) { + try { + if (element.getAttribute(VALUE_HANDLER) != null) { + valueHandler = (IManagedOptionValueHandler) element.createExecutableExtension(VALUE_HANDLER); + return valueHandler; + } + } catch (CoreException e) { + ManagedBuildManager.OptionValueHandlerError(element.getAttribute(VALUE_HANDLER), getId()); + // Assign the default handler to avoid further error messages + valueHandler = ManagedOptionValueHandler.getManagedOptionValueHandler(); + return valueHandler; + } + } + // If no handler is provided, then use the default handler + return ManagedOptionValueHandler.getManagedOptionValueHandler(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#getValueHandlerExtraArgument()) + */ + public String getValueHandlerExtraArgument() { + if (valueHandlerExtraArgument == null) { + if (superClass != null) { + return superClass.getValueHandlerExtraArgument(); + } else { + return EMPTY_STRING; + } + } + return valueHandlerExtraArgument; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#setValueHandlerExtraArgument(String)) + */ + public void setValueHandlerExtraArgument(String extraArgument) { + if (extraArgument == null && valueHandlerExtraArgument == null) return; + if (extraArgument == null || + valueHandlerExtraArgument == null || + !extraArgument.equals(valueHandlerExtraArgument)) { + valueHandlerExtraArgument = extraArgument; + if(!isExtensionElement()) + isDirty = true; + } + } + + + /* + * O B J E C T S T A T E M A I N T E N A N C E + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#isExtensionElement() + */ + public boolean isExtensionElement() { + return isExtensionOption; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#overridesOnlyValue() + * Deprecated since 3.0.1 + */ + public boolean overridesOnlyValue() { + if (superClass != null && + unusedChildren == null && + browseType == null && + (builtIns == null || builtIns.size() == 0) && + category == null && + categoryId == null && + command == null && + commandFalse == null && + tip == null && + enumList == null && + enumCommands == null && + enumNames == null && + defaultValue == null) { + return true; + } else { + return false; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#isDirty() + */ + public boolean isDirty() { + // This shouldn't be called for an extension option + if (isExtensionOption) return false; + return isDirty; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setDirty(boolean) + */ + public void setDirty(boolean isDirty) { + this.isDirty = isDirty; + } + + public void resolveReferences() { + + if (!resolved) { + resolved = true; + // Resolve superClass + if (superClassId != null && superClassId.length() > 0) { + superClass = ManagedBuildManager.getExtensionOption(superClassId); + if (superClass == null) { + // Report error + ManagedBuildManager.OutputResolveError( + "superClass", //$NON-NLS-1$ + superClassId, + "option", //$NON-NLS-1$ + getId()); + } else { + // All of our superclasses must be resolved in order to call + // getValueType below. + ((Option)superClass).resolveReferences(); + } + } + if (categoryId != null) { + category = holder.getOptionCategory(categoryId); + if (category == null) { + // Report error + ManagedBuildManager.OutputResolveError( + "category", //$NON-NLS-1$ + categoryId, + "option", //$NON-NLS-1$ + getId()); + } + } + // Process the value and default value attributes. This is delayed until now + // because we may not know the valueType until after we have resolved the superClass above + // Now get the actual value + try { + IManagedConfigElement element = ManagedBuildManager.getConfigElement(this); + switch (getValueType()) { + case BOOLEAN: + // Convert the string to a boolean + String val = element.getAttribute(VALUE); + if (val != null) { + value = new Boolean(val); + } + val = element.getAttribute(DEFAULT_VALUE); + if (val != null) { + defaultValue = new Boolean(val); + } + break; + case STRING: + // Just get the value out of the option directly + value = element.getAttribute(VALUE); + defaultValue = element.getAttribute(DEFAULT_VALUE); + break; + case ENUMERATED: + value = element.getAttribute(VALUE); + defaultValue = element.getAttribute(DEFAULT_VALUE); + + // Do we have enumeratedOptionValue children? If so, load them + // to define the valid values and the default value. + IManagedConfigElement[] enumElements = element.getChildren(ENUM_VALUE); + for (int i = 0; i < enumElements.length; ++i) { + String optId = enumElements[i].getAttribute(ID); + if (i == 0) { + enumList = new ArrayList(); + if (defaultValue == null) { + defaultValue = optId; // Default value to be overridden if default is specified + } + } + enumList.add(optId); + getEnumCommandMap().put(optId, enumElements[i].getAttribute(COMMAND)); + getEnumNameMap().put(optId, enumElements[i].getAttribute(NAME)); + Boolean isDefault = new Boolean(enumElements[i].getAttribute(IS_DEFAULT)); + if (isDefault.booleanValue()) { + defaultValue = optId; + } + } + break; + case STRING_LIST: + case INCLUDE_PATH: + case PREPROCESSOR_SYMBOLS: + case LIBRARIES: + case OBJECTS: + // Note: These string-list options do not load either the "value" or + // "defaultValue" attributes. Instead, the ListOptionValue children + // are loaded in the value field. + List valueList = null; + IManagedConfigElement[] valueElements = element.getChildren(LIST_VALUE); + for (int i = 0; i < valueElements.length; ++i) { + if (i == 0) { + valueList = new ArrayList(); + builtIns = new ArrayList(); + } + IManagedConfigElement valueElement = valueElements[i]; + Boolean isBuiltIn = new Boolean(valueElement.getAttribute(LIST_ITEM_BUILTIN)); + if (isBuiltIn.booleanValue()) { + builtIns.add(valueElement.getAttribute(LIST_ITEM_VALUE)); + } + else { + valueList.add(valueElement.getAttribute(LIST_ITEM_VALUE)); + } + } + value = valueList; + break; + default : + break; + } + } catch (BuildException e) { + // TODO: report error + } + } + } + + /** + * @return Returns the managedBuildRevision. + */ + public String getManagedBuildRevision() { + if ( managedBuildRevision == null) { + if ( getParent() != null) { + return getParent().getManagedBuildRevision(); + } + } + return managedBuildRevision; + } + + /* (non-Javadoc) + * For now implement this method just as a utility to make code + * within the Option class cleaner. + * TODO: In future we may want to move this to IOption + */ + protected boolean isAbstract() { + if (isAbstract != null) { + return isAbstract.booleanValue(); + } else { + return false; // Note: no inheritance from superClass + } + } + + /** + * Verifies whether the option is valid and handles + * any errors for the option. The following errors + * can occur: + * (a) Options that are children of a ToolChain must + * ALWAYS have a category + * (b) Options that are children of a ToolChain must + * NEVER have a resourceFilter of "file". + * If an error occurs, the option is set to being invalid. + * + * @pre All references have been resolved. + */ + private void verify() { + if (verified) return; + verified = true; + // Ignore elements that are superclasses + if ( getOptionHolder() instanceof IToolChain && isAbstract() == false ) { + // Check for error (a) + if (getCategory() == null) { + ManagedBuildManager.OptionValidError(ManagedBuildManager.ERROR_CATEGORY, getId()); + // Object becomes invalid + isValid = false; + } + // Check for error (b). Not specifying an attribute is OK. + // Do not use getResourceFilter as it does not allow + // differentiating between "all" and no attribute specified. + if ( resourceFilter != null ) + { + switch (getResourceFilter()) { + case Option.FILTER_FILE: + // TODO: Cannot differentiate between "all" and attribute not + // specified. Thus do not produce an error. We can argue that "all" + // means all valid resource configurations. + ManagedBuildManager.OptionValidError(ManagedBuildManager.ERROR_FILTER, getId()); + // Object becomes invalid + isValid = false; + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IOption#isValid() + */ + public boolean isValid() { + // We use a lazy scheme to check whether the option is valid. + // Note that by default an option is valid. verify() is only called if + // the option has been resolved. This gets us around having to deal with + // ordering problems during a resolve, or introducing another global + // stage to verify the configuration after a resolve. + // The trade-off is that errors in the MBS grammar may not be + // detected on load, but only when a particular grammar element + // is used, say in the GUI. + if (verified == false && resolved == true) { + verify(); + } + return isValid; + } + + /** + * @return Returns true if this Option was created from an MBS 2.0 model + * OptionReference element. + */ + public boolean wasOptRef() { + return wasOptRef; + } + + public void setWasOptRef(boolean was) { + wasOptRef = was; + } + + /** + * @return Returns the version. + */ + public PluginVersionIdentifier getVersion() { + if ( version == null) { + if ( getParent() != null) { + return getParent().getVersion(); + } + } + return version; + } + + public void setVersion(PluginVersionIdentifier version) { + // Do nothing + } + + public BooleanExpressionApplicabilityCalculator getBooleanExpressionCalculator(){ + return booleanExpressionCalculator; + } + + public boolean isAdjustedExtension(){ + return isUdjusted; + } + + public void setAdjusted(boolean adjusted) { + isUdjusted = adjusted; + } + + public void setSuperClass(IOption superClass) { + if ( this.superClass != superClass ) { + this.superClass = superClass; + if ( this.superClass == null) { + superClassId = null; + } else { + superClassId = this.superClass.getId(); + } + + if(!isExtensionElement()) + setDirty(true); + } + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties index e82f0fee629..f3fc0fc7815 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties @@ -1,110 +1,111 @@ -############################################################################### -# Copyright (c) 2002, 2005 Rational Software Corporation and others. -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# IBM Rational Software - Initial API and implementation -############################################################################### - -# Generated makefile builder messages -ManagedMakeBuilder.message.starting = Starting the build for project {0} -ManagedMakeBuilder.message.rebuild.makefiles = Regenerating makefiles for project {0} -ManagedMakeBuilder.message.update.makefiles = Updating makefiles for project {0} -ManagedMakeBuilder.message.incremental = Updating makefiles for project {0} -ManagedMakeBuilder.message.updating = Updating project files... -ManagedMakeBuilder.message.make = Calling {0} for project {1} -ManagedMakeBuilder.message.regen.deps = Regenerating dependency files for {0} -ManagedMakeBuilder.message.updating.deps = Updating dependency files for {0} -ManagedMakeBuilder.message.creating.markers = Generating markers... -ManagedMakeBuilder.message.console.header = **** {0} of configuration {1} for project {2} **** -ManagedMakeBuilder.message.no.build = Nothing to build for {0} -ManagedMakeBuilder.message.error = Build error -ManagedMakeBuilder.message.error.refresh = Error refreshing project -ManagedMakeBuilder.message.finished = Build complete for project {0} -ManagedMakeBuilder.message.clean.deleting.output=Removing build artifacts from {0} -ManagedMakeBuilder.message.clean.build.clean=Trying a make clean in {0} -ManagedMakeBuilder.type.clean = Clean-only build -ManagedMakeBuider.type.incremental = Build -ManagedMakeBuilder.warning.unsupported.configuration=**** WARNING: The "{0}" Configuration may not build ****\n**** because it uses the "{1}" ****\n**** tool-chain that is unsupported on this system. ****\n\n**** Attempting to build... **** - -# Option exception messages -Option.error.bad_value_type=Bad value for type - -# Managed build manager exception messages -ManagedBuildManager.error.owner_not_null=addTarget: owner not null -ManagedBuildManager.error.null_owner=addTarget: null owner -ManagedBuildManager.error.owner_not_project=addTarget: owner not project -ManagedBuildManager.error.manifest_load_failed_title=Managed Build System Version Error -ManagedBuildManager.error.manifest.version.error=The version number defined in the plugin manifest file\n{0}\nis greater than the version of the Managed Build System.\nThe definitions in the manifest file will not be loaded. -ManagedBuildManager.error.manifest.header=Managed Build system manifest file error: -ManagedBuildManager.error.manifest.resolving=Unable to resolve the {0} identifier {1} in the {2} {3}. -ManagedBuildManager.error.manifest.duplicate=Duplicate identifier {1} for element type {0}. -ManagedBuildManager.error.manifest.icon=Could not load icon "{0}". -ManagedBuildManager.error.manifest.option.category=Option {0} uses a null category that is invalid in its context. The option was ignored. -ManagedBuildManager.error.manifest.option.filter=Option {0} uses an unsupported resourceFilter attribute value. The option was ignored. -ManagedBuildManager.error.manifest.option.valuehandler=Could not load value handler {0} in option {1}. -ManagedBuildManager.error.open_failed_title=Managed Make Project File Error -ManagedBuildManager.error.open_failed=The Managed Make project file could not be read because of the following error:\n\n{0}\n\nManaged Make functionality will not be available for this project. -ManagedBuildManager.error.write_failed_title=Managed Make Project File Write Error -ManagedBuildManager.error.write_failed=The Managed Make project file could not be written because of the following error:\n\n{0}\n -ManagedBuildManager.error.read_only=File {0} is read-only. -ManagedBuildManager.error.project.version.error=The version number of the project {0} is greater than the Managed Build System version number. -ManagedBuildManager.error.id.nomatch=Error loading Managed Make project information for project {0}. The tool definitions used to create the project are not available. -ManagedBuildManager.error.project.file.missing=The Managed Make project file for project {0} is missing. -# Makefile Generator Messages -MakefileGenerator.message.start.file=Building file: -MakefileGenerator.message.finish.file=Finished building: -MakefileGenerator.message.start.build=Building target: -MakefileGenerator.message.finish.build=Finished building target: -MakefileGenerator.message.no.target=No tool found that can build the extension specified with the build arrtifact name -MakefileGenerator.message.adding.source.folder=Adding folder {0} to sources -MakefileGenerator.message.gen.source.makefile=Generating makefile for source folder {0} -MakefileGenerator.message.calc.delta=Calculating the delta for project {0} -MakefileGenerator.message.finding.sources=Finding source files in project {0} -MakefileGenerator.comment.module.list = Every subdirectory with source files must be described here -MakefileGenerator.comment.module.variables = Add inputs and outputs from these tool invocations to the build variables -MakefileGenerator.comment.source.list = All of the sources participating in the build are defined here -MakefileGenerator.comment.build.rule = Each subdirectory must supply rules for building sources it contributes -MakefileGenerator.comment.build.toprules = Tool invocations -MakefileGenerator.comment.build.alltarget = All Target -MakefileGenerator.comment.build.mainbuildtarget = Main-build Target -MakefileGenerator.comment.build.toptargets = Other Targets -MakefileGenerator.comment.module.make.includes = Include the makefiles for each source subdirectory -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 in name -MakefileGenerator.warning.no.source=Nothing to build for project {0} -MakefileGenerator.error.no.nameprovider=A nameProvider or outputNames must be specified with multipleType == true - -ManagedBuildInfo.message.job.init = Initializing path container for {0} -ManagedBuildInfo.message.init.ok = Initializing path container succeeded for {0} - -# Default GNU Makefile Generator messages -GnuMakefileGenerator.message.postproc.dep.file=Verifying contents of dependency file {0} - -# Tool strings -Tool.default.announcement=Invoking: -#Environment loader messages -StorableEnvironmentLoader.storeOutputStream.wrong.arguments=Wrong arguments - -#User Defined Macro Supplier -UserDefinedMacroSupplier.storeOutputStream.wrong.arguments=Failed to persist macros: Wrong arguments - -# BuildMacroStatus messages -BuildMacroStatus.status.macro.undefined=Macro {0} is undefined -BuildMacroStatus.status.reference.eachother=Macros {0} and {1} reference each other -BuildMacroStatus.status.reference.incorrect=Macro {0} reference is incorrect -BuildMacroStatus.status.macro.not.string=Macro {0} is not of String type -BuildMacroStatus.status.macro.not.stringlist=Macro {0} is not of String-list type -BuildMacroStatus.status.error=Error occured -BuildMacroStatus.value.undefined= - -#ResourceChangeHandler messages -ResourceChangeHandler.buildInfoSerializationJob=Build Info Serialization - -#ManagedBuilderCorePlugin messages +############################################################################### +# Copyright (c) 2002, 2006 Rational Software Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# IBM Rational Software - Initial API and implementation +############################################################################### + +# Generated makefile builder messages +ManagedMakeBuilder.message.starting = Starting the build for project {0} +ManagedMakeBuilder.message.rebuild.makefiles = Regenerating makefiles for project {0} +ManagedMakeBuilder.message.update.makefiles = Updating makefiles for project {0} +ManagedMakeBuilder.message.incremental = Updating makefiles for project {0} +ManagedMakeBuilder.message.updating = Updating project files... +ManagedMakeBuilder.message.make = Calling {0} for project {1} +ManagedMakeBuilder.message.regen.deps = Regenerating dependency files for {0} +ManagedMakeBuilder.message.updating.deps = Updating dependency files for {0} +ManagedMakeBuilder.message.creating.markers = Generating markers... +ManagedMakeBuilder.message.console.header = **** {0} of configuration {1} for project {2} **** +ManagedMakeBuilder.message.no.build = Nothing to build for {0} +ManagedMakeBuilder.message.error = Build error +ManagedMakeBuilder.message.error.refresh = Error refreshing project +ManagedMakeBuilder.message.finished = Build complete for project {0} +ManagedMakeBuilder.message.clean.deleting.output=Removing build artifacts from {0} +ManagedMakeBuilder.message.clean.build.clean=Trying a make clean in {0} +ManagedMakeBuilder.type.clean = Clean-only build +ManagedMakeBuider.type.incremental = Build +ManagedMakeBuilder.warning.unsupported.configuration=**** WARNING: The "{0}" Configuration may not build ****\n**** because it uses the "{1}" ****\n**** tool-chain that is unsupported on this system. ****\n\n**** Attempting to build... **** + +# Option exception messages +Option.error.bad_value_type=Bad value for type + +# Managed build manager exception messages +ManagedBuildManager.error.owner_not_null=addTarget: owner not null +ManagedBuildManager.error.null_owner=addTarget: null owner +ManagedBuildManager.error.owner_not_project=addTarget: owner not project +ManagedBuildManager.error.manifest_load_failed_title=Managed Build System Version Error +ManagedBuildManager.error.manifest.version.error=The version number defined in the plugin manifest file\n{0}\nis greater than the version of the Managed Build System.\nThe definitions in the manifest file will not be loaded. +ManagedBuildManager.error.manifest.header=Managed Build system manifest file error: +ManagedBuildManager.error.manifest.resolving=Unable to resolve the {0} identifier {1} in the {2} {3}. +ManagedBuildManager.error.manifest.duplicate=Duplicate identifier {1} for element type {0}. +ManagedBuildManager.error.manifest.icon=Could not load icon "{0}". +ManagedBuildManager.error.manifest.option.category=Option {0} uses a null category that is invalid in its context. The option was ignored. +ManagedBuildManager.error.manifest.option.filter=Option {0} uses an unsupported resourceFilter attribute value. The option was ignored. +ManagedBuildManager.error.manifest.option.valuehandler=Could not load value handler {0} in option {1}. +ManagedBuildManager.error.open_failed_title=Managed Make Project File Error +ManagedBuildManager.error.open_failed=The Managed Make project file could not be read because of the following error:\n\n{0}\n\nManaged Make functionality will not be available for this project. +ManagedBuildManager.error.write_failed_title=Managed Make Project File Write Error +ManagedBuildManager.error.write_failed=The Managed Make project file could not be written because of the following error:\n\n{0}\n +ManagedBuildManager.error.read_only=File {0} is read-only. +ManagedBuildManager.error.project.version.error=The version number of the project {0} is greater than the Managed Build System version number. +ManagedBuildManager.error.id.nomatch=Error loading Managed Make project information for project {0}. The tool definitions used to create the project are not available. +ManagedBuildManager.error.project.file.missing=The Managed Make project file for project {0} is missing. +# Makefile Generator Messages +MakefileGenerator.message.start.file=Building file: +MakefileGenerator.message.finish.file=Finished building: +MakefileGenerator.message.start.build=Building target: +MakefileGenerator.message.finish.build=Finished building target: +MakefileGenerator.message.start.dependency=Regenerating dependency file: +MakefileGenerator.message.no.target=No tool found that can build the extension specified with the build arrtifact name +MakefileGenerator.message.adding.source.folder=Adding folder {0} to sources +MakefileGenerator.message.gen.source.makefile=Generating makefile for source folder {0} +MakefileGenerator.message.calc.delta=Calculating the delta for project {0} +MakefileGenerator.message.finding.sources=Finding source files in project {0} +MakefileGenerator.comment.module.list = Every subdirectory with source files must be described here +MakefileGenerator.comment.module.variables = Add inputs and outputs from these tool invocations to the build variables +MakefileGenerator.comment.source.list = All of the sources participating in the build are defined here +MakefileGenerator.comment.build.rule = Each subdirectory must supply rules for building sources it contributes +MakefileGenerator.comment.build.toprules = Tool invocations +MakefileGenerator.comment.build.alltarget = All Target +MakefileGenerator.comment.build.mainbuildtarget = Main-build Target +MakefileGenerator.comment.build.toptargets = Other Targets +MakefileGenerator.comment.module.make.includes = Include the makefiles for each source subdirectory +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 in name +MakefileGenerator.warning.no.source=Nothing to build for project {0} +MakefileGenerator.error.no.nameprovider=A nameProvider or outputNames must be specified with multipleType == true + +ManagedBuildInfo.message.job.init = Initializing path container for {0} +ManagedBuildInfo.message.init.ok = Initializing path container succeeded for {0} + +# Default GNU Makefile Generator messages +GnuMakefileGenerator.message.postproc.dep.file=Verifying contents of dependency file {0} + +# Tool strings +Tool.default.announcement=Invoking: +#Environment loader messages +StorableEnvironmentLoader.storeOutputStream.wrong.arguments=Wrong arguments + +#User Defined Macro Supplier +UserDefinedMacroSupplier.storeOutputStream.wrong.arguments=Failed to persist macros: Wrong arguments + +# BuildMacroStatus messages +BuildMacroStatus.status.macro.undefined=Macro {0} is undefined +BuildMacroStatus.status.reference.eachother=Macros {0} and {1} reference each other +BuildMacroStatus.status.reference.incorrect=Macro {0} reference is incorrect +BuildMacroStatus.status.macro.not.string=Macro {0} is not of String type +BuildMacroStatus.status.macro.not.stringlist=Macro {0} is not of String-list type +BuildMacroStatus.status.error=Error occured +BuildMacroStatus.value.undefined= + +#ResourceChangeHandler messages +ResourceChangeHandler.buildInfoSerializationJob=Build Info Serialization + +#ManagedBuilderCorePlugin messages ManagedBuilderCorePlugin.resourceChangeHandlingInitializationJob=Initializing Resource Change Handling \ No newline at end of file diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ResourceChangeHandler.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ResourceChangeHandler.java index 749d1a97eb9..136104c5753 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ResourceChangeHandler.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ResourceChangeHandler.java @@ -1,455 +1,458 @@ -/******************************************************************************* - * Copyright (c) 2005 Intel Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Intel Corporation - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.cdt.managedbuilder.internal.core; - -import java.util.HashMap; -import java.util.HashSet; - -import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; -import org.eclipse.cdt.managedbuilder.core.IManagedOptionValueHandler; -import org.eclipse.cdt.managedbuilder.core.IManagedProject; -import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; -import org.eclipse.cdt.managedbuilder.core.ManagedCProjectNature; -import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceChangeEvent; -import org.eclipse.core.resources.IResourceChangeListener; -import org.eclipse.core.resources.IResourceDelta; -import org.eclipse.core.resources.IResourceDeltaVisitor; -import org.eclipse.core.resources.IResourceRuleFactory; -import org.eclipse.core.resources.ISaveContext; -import org.eclipse.core.resources.ISaveParticipant; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.core.resources.ResourcesPlugin; -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.NullProgressMonitor; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.core.runtime.jobs.MultiRule; - -public class ResourceChangeHandler implements IResourceChangeListener, ISaveParticipant { - - private class ResourceConfigurationChecker implements IResourceDeltaVisitor{ - private IResourceDelta fRootDelta; - private HashMap fBuildFileGeneratorMap = new HashMap(); - private HashSet fValidatedFilesSet = new HashSet(); - private HashSet fModifiedProjects = new HashSet(); - - public ResourceConfigurationChecker(IResourceDelta rootDelta){ - fRootDelta = rootDelta; - } - - public IProject[] getModifiedProjects(){ - return (IProject[])fModifiedProjects.toArray(new IProject[fModifiedProjects.size()]); - } - - public boolean visit(IResourceDelta delta) throws CoreException { - IResource dResource = delta.getResource(); - int rcType = dResource.getType(); - - if(rcType == IResource.PROJECT || rcType == IResource.FOLDER){ - IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); - IProject project = null; - IResource rcToCheck = null; - switch (delta.getKind()) { - case IResourceDelta.REMOVED : - if ((delta.getFlags() & IResourceDelta.MOVED_TO) == 0 && rcType == IResource.PROJECT) { - sendClose((IProject)dResource); - break; - } - case IResourceDelta.CHANGED : - if ((delta.getFlags() & IResourceDelta.MOVED_TO) != 0) { - IPath path = delta.getMovedToPath(); - if(path != null){ - project = root.findMember(path.segment(0)).getProject(); - if(project != null && rcType == IResource.FOLDER) - rcToCheck = root.getFolder(substituteProject(dResource.getFullPath(),project.getName())); - } - break; - } - default: - project = dResource.getProject(); - if(rcType == IResource.FOLDER) - rcToCheck = dResource; - break; - } - - if(project != null) { - IManagedBuilderMakefileGenerator makeGen = getInitializedGenerator(project); - if(makeGen != null){ - if(rcToCheck == null || !makeGen.isGeneratedResource(rcToCheck)) - return true; - } - } - return false; - } else if (rcType == IResource.FILE && !dResource.isDerived()) { - int flags = delta.getFlags(); - switch (delta.getKind()) { - case IResourceDelta.REMOVED : - if ((flags & IResourceDelta.MOVED_TO) == 0) { - handleDeleteFile(dResource.getFullPath()); - break; - } - case IResourceDelta.ADDED : - case IResourceDelta.CHANGED : - if ((flags & IResourceDelta.MOVED_TO) != 0) { - IPath path = delta.getMovedToPath(); - if (path != null) { - handleRenamedFile( - dResource.getFullPath(), - path); - } - } else if ((flags & IResourceDelta.MOVED_FROM) != 0) { - IPath path = delta.getMovedFromPath(); - if (path != null) { - handleRenamedFile( - path, - dResource.getFullPath()); - } - } - break; - - default: - break; - } - return false; - } - return true; // visit the children - } - - private IPath substituteProject(IPath path, String projectName){ - return new Path(projectName).makeAbsolute().append(path.removeFirstSegments(1)); - } - - private void handleRenamedFile(IPath fromPath, IPath toPath){ - if(!fValidatedFilesSet.add(fromPath)) - return; - - IProject fromProject = findModifiedProject(fromPath.segment(0)); - if(fromProject == null) - return; - IManagedBuilderMakefileGenerator fromMakeGen = getInitializedGenerator(fromProject); - IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); - if(fromMakeGen == null || fromMakeGen.isGeneratedResource(root.getFile(substituteProject(fromPath,fromProject.getName())))) - return; - - IManagedBuildInfo fromInfo = fromProject != null ? - ManagedBuildManager.getBuildInfo(fromProject) : - null; - - IProject toProject = root.findMember(toPath.uptoSegment(1)).getProject(); - IManagedBuildInfo toInfo = toProject != null ? - ManagedBuildManager.getBuildInfo(toProject) : - null; - IManagedBuilderMakefileGenerator toMakeGen = toProject != null ? - getInitializedGenerator(toProject) : - null; - if(toMakeGen != null && toMakeGen.isGeneratedResource(root.getFile(toPath))) - toInfo = null; - - if(fromInfo == toInfo){ - //the resource was moved whithing the project scope - if(updateResourceConfigurations(fromInfo,fromPath,toPath) && toProject != null) - fModifiedProjects.add(toProject); - } else { - if(fromInfo != null && toInfo != null){ - //TODO: this is the case when the resource - //is moved from one managed project to another - //should we handle this? - //e.g. add resource configurations to the destination project? - } - if(fromInfo != null && removeResourceConfigurations(fromInfo,fromPath) && fromProject != null) - fModifiedProjects.add(fromProject); - } - } - - private void handleDeleteFile(IPath path){ - IProject project = findModifiedProject(path.segment(0)); - if(project != null){ - IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project); - if(info != null - && removeResourceConfigurations(info,path)) - fModifiedProjects.add(project); - } - } - - //finds the project geven the initial project name - //That is: - // if the project of a given name was renamed returns the renamed project - // if the project of a given name was removed returns null - // if the project of a given name was neither renamed or removed - // returns the project of that name or null if the project does not exist - // - private IProject findModifiedProject(final String oldProjectName){ - IResourceDelta projectDelta = fRootDelta.findMember(new Path(oldProjectName)); - boolean replaced = false; - if(projectDelta != null) { - switch(projectDelta.getKind()){ - case IResourceDelta.REMOVED : - if ((projectDelta.getFlags() & IResourceDelta.MOVED_TO) == 0) { - return null; - } - case IResourceDelta.CHANGED : - if ((projectDelta.getFlags() & IResourceDelta.MOVED_TO) != 0) { - IPath path = projectDelta.getMovedToPath(); - if(path != null) - return ResourcesPlugin.getWorkspace().getRoot().findMember(path).getProject(); - } - break; - } - } - - final IProject project[] = new IProject[1]; - try { - fRootDelta.accept(new IResourceDeltaVisitor() { - public boolean visit(IResourceDelta delta) throws CoreException { - IResource dResource = delta.getResource(); - int rcType = dResource.getType(); - if(rcType == IResource.ROOT) { - return true; - } else if(rcType == IResource.PROJECT){ - switch(delta.getKind()){ - case IResourceDelta.ADDED : - case IResourceDelta.CHANGED : - if ((delta.getFlags() & IResourceDelta.MOVED_FROM) != 0) { - IPath path = delta.getMovedFromPath(); - if (path != null && path.segment(0).equals(oldProjectName)) { - project[0] = dResource.getProject(); - } - } - break; - default: - break; - } - } - return false; - } - }); - } catch (CoreException e) { - } - - if(project[0] == null && !replaced) - project[0] = ResourcesPlugin.getWorkspace().getRoot().findMember(oldProjectName).getProject(); - return project[0]; - } - - private IManagedBuilderMakefileGenerator getInitializedGenerator(IProject project){ - IManagedBuilderMakefileGenerator makeGen = (IManagedBuilderMakefileGenerator)fBuildFileGeneratorMap.get(project); - if (makeGen == null) { - try { - if (project.hasNature(ManagedCProjectNature.MNG_NATURE_ID)) { - // Determine if we can access the build info before actually trying - // If not, don't try, to avoid putting up a dialog box warning the user - if (!ManagedBuildManager.canGetBuildInfo(project)) return null; - - IManagedBuildInfo buildInfo = ManagedBuildManager.getBuildInfo(project); - if (buildInfo != null){ - IConfiguration defaultCfg = buildInfo.getDefaultConfiguration(); - if (defaultCfg != null) { - makeGen = ManagedBuildManager.getBuildfileGenerator(defaultCfg); - makeGen.initialize(project,buildInfo,new NullProgressMonitor()); - fBuildFileGeneratorMap.put(project,makeGen); - } - } - } - } catch (CoreException e){ - return null; - } - } - return makeGen; - } - } - - public void sendClose(IProject project){ - IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project,false); - if(info != null){ - IConfiguration cfgs[] = info.getManagedProject().getConfigurations(); - - for(int i = 0; i < cfgs.length; i++) - ManagedBuildManager.performValueHandlerEvent(cfgs[i], IManagedOptionValueHandler.EVENT_CLOSE, true); - } - } - - /* - * I R e s o u r c e C h a n g e L i s t e n e r - */ - - /* (non-Javadoc) - * - * Handle the renaming and deletion of project resources - * This is necessary in order to update ResourceConfigurations and AdditionalInputs - * - * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) - */ - public void resourceChanged(IResourceChangeEvent event) { - if (event.getSource() instanceof IWorkspace) { - - switch (event.getType()) { - case IResourceChangeEvent.PRE_CLOSE: - IResource proj = event.getResource(); - if(proj instanceof IProject) - sendClose((IProject)proj); - break; - case IResourceChangeEvent.POST_CHANGE : - case IResourceChangeEvent.POST_BUILD : - case IResourceChangeEvent.PRE_DELETE : - IResourceDelta resDelta = event.getDelta(); - if (resDelta == null) { - break; - } - try { - ResourceConfigurationChecker rcChecker = new ResourceConfigurationChecker(resDelta); - resDelta.accept(rcChecker); - - //saving info for the modified projects - initInfoSerialization(rcChecker.getModifiedProjects()); - - } catch (CoreException e) { - CCorePlugin.log(e); - } - break; - default : - break; - } - } - } - - private void initInfoSerialization(final IProject projects[]){ - if(projects.length == 0) - return; - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - IResourceRuleFactory ruleFactory = workspace.getRuleFactory(); - ISchedulingRule buildInfoSaveRule; - if(projects.length == 1){ - buildInfoSaveRule = ruleFactory.modifyRule(projects[0]); - } else { - ISchedulingRule rules[] = new ISchedulingRule[projects.length]; - for(int i = 0; i < rules.length; i++) - rules[i] = ruleFactory.modifyRule(projects[i]); - buildInfoSaveRule = MultiRule.combine(rules); - } - - Job savingJob = new Job(ManagedMakeMessages.getResourceString("ResourceChangeHandler.buildInfoSerializationJob")){ //$NON-NLS-1$ - protected IStatus run(IProgressMonitor monitor) { - for(int i = 0; i < projects.length; i++){ - ManagedBuildManager.saveBuildInfo(projects[i],true); - } - return new Status( - IStatus.OK, - ManagedBuilderCorePlugin.getUniqueIdentifier(), - IStatus.OK, - new String(), - null); - } - }; - savingJob.setRule(buildInfoSaveRule); - - savingJob.schedule(); - } - - private boolean updateResourceConfigurations(IManagedBuildInfo info, IPath oldPath, IPath newPath){ - boolean changed = false; - if(!oldPath.equals(newPath)){ - IManagedProject mngProj = info.getManagedProject(); - if(mngProj != null){ - IConfiguration configs[] = mngProj.getConfigurations(); - if(configs != null && configs.length > 0){ - for(int i = 0; i < configs.length; i++){ - if(updateResourceConfiguration(configs[i],oldPath,newPath)) - changed = true; - } - } - } - } - return changed; - } - - private boolean removeResourceConfigurations(IManagedBuildInfo info, IPath path){ - boolean changed = false; - IManagedProject mngProj = info.getManagedProject(); - if(mngProj != null){ - IConfiguration configs[] = mngProj.getConfigurations(); - if(configs != null && configs.length > 0){ - for(int i = 0; i < configs.length; i++){ - if(removeResourceConfiguration(configs[i],path)) - changed = true; - } - } - } - return changed; - } - - private boolean updateResourceConfiguration(IConfiguration config, IPath oldPath, IPath newPath){ - IResourceConfiguration rcCfg = config.getResourceConfiguration(oldPath.toString()); - if(rcCfg != null && !oldPath.equals(newPath)){ - config.removeResourceConfiguration(rcCfg); - rcCfg.setResourcePath(newPath.toString()); - ((Configuration)config).addResourceConfiguration((ResourceConfiguration)rcCfg); - config.setRebuildState(true); - return true; - } - return false; - } - - private boolean removeResourceConfiguration(IConfiguration config, IPath path){ - IResourceConfiguration rcCfg = config.getResourceConfiguration(path.toString()); - if(rcCfg != null){ - config.removeResourceConfiguration(rcCfg); - config.setRebuildState(true); - return true; - } - return false; - } - - /* - * I S a v e P a r t i c i p a n t - */ - - /* (non-Javadoc) - * @see org.eclipse.core.resources.ISaveParticipant#saving(org.eclipse.core.resources.ISaveContext) - */ - public void saving(ISaveContext context) throws CoreException { - // No state to be saved by the plug-in, but request a - // resource delta to be used on next activation. - context.needDelta(); - } - - /* (non-Javadoc) - * @see org.eclipse.core.resources.ISaveParticipant#doneSaving(org.eclipse.core.resources.ISaveContext) - */ - public void doneSaving(ISaveContext context) { - } - - /* (non-Javadoc) - * @see org.eclipse.core.resources.ISaveParticipant#prepareToSave(org.eclipse.core.resources.ISaveContext) - */ - public void prepareToSave(ISaveContext context) throws CoreException { - } - - /* (non-Javadoc) - * @see org.eclipse.core.resources.ISaveParticipant#rollback(org.eclipse.core.resources.ISaveContext) - */ - public void rollback(ISaveContext context) { - } - -} +/******************************************************************************* + * Copyright (c) 2005 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.managedbuilder.internal.core; + +import java.util.HashMap; +import java.util.HashSet; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedOptionValueHandler; +import org.eclipse.cdt.managedbuilder.core.IManagedProject; +import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; +import org.eclipse.cdt.managedbuilder.core.ManagedCProjectNature; +import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IResourceDeltaVisitor; +import org.eclipse.core.resources.IResourceRuleFactory; +import org.eclipse.core.resources.ISaveContext; +import org.eclipse.core.resources.ISaveParticipant; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +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.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.jobs.MultiRule; + +public class ResourceChangeHandler implements IResourceChangeListener, ISaveParticipant { + + private class ResourceConfigurationChecker implements IResourceDeltaVisitor{ + private IResourceDelta fRootDelta; + private HashMap fBuildFileGeneratorMap = new HashMap(); + private HashSet fValidatedFilesSet = new HashSet(); + private HashSet fModifiedProjects = new HashSet(); + + public ResourceConfigurationChecker(IResourceDelta rootDelta){ + fRootDelta = rootDelta; + } + + public IProject[] getModifiedProjects(){ + return (IProject[])fModifiedProjects.toArray(new IProject[fModifiedProjects.size()]); + } + + public boolean visit(IResourceDelta delta) throws CoreException { + IResource dResource = delta.getResource(); + int rcType = dResource.getType(); + + if(rcType == IResource.PROJECT || rcType == IResource.FOLDER){ + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + IProject project = null; + IResource rcToCheck = null; + switch (delta.getKind()) { + case IResourceDelta.REMOVED : + if ((delta.getFlags() & IResourceDelta.MOVED_TO) == 0 && rcType == IResource.PROJECT) { + sendClose((IProject)dResource); + break; + } + case IResourceDelta.CHANGED : + if ((delta.getFlags() & IResourceDelta.MOVED_TO) != 0) { + IPath path = delta.getMovedToPath(); + if(path != null){ + project = root.findMember(path.segment(0)).getProject(); + if(project != null && rcType == IResource.FOLDER) + rcToCheck = root.getFolder(substituteProject(dResource.getFullPath(),project.getName())); + } + break; + } + default: + project = dResource.getProject(); + if(rcType == IResource.FOLDER) + rcToCheck = dResource; + break; + } + + if(project != null) { + IManagedBuilderMakefileGenerator makeGen = getInitializedGenerator(project); + if(makeGen != null){ + if(rcToCheck == null || !makeGen.isGeneratedResource(rcToCheck)) + return true; + } + } + return false; + } else if (rcType == IResource.FILE && !dResource.isDerived()) { + int flags = delta.getFlags(); + switch (delta.getKind()) { + case IResourceDelta.REMOVED : + if ((flags & IResourceDelta.MOVED_TO) == 0) { + handleDeleteFile(dResource.getFullPath()); + break; + } + case IResourceDelta.ADDED : + case IResourceDelta.CHANGED : + if ((flags & IResourceDelta.MOVED_TO) != 0) { + IPath path = delta.getMovedToPath(); + if (path != null) { + handleRenamedFile( + dResource.getFullPath(), + path); + } + } else if ((flags & IResourceDelta.MOVED_FROM) != 0) { + IPath path = delta.getMovedFromPath(); + if (path != null) { + handleRenamedFile( + path, + dResource.getFullPath()); + } + } + break; + + default: + break; + } + return false; + } + return true; // visit the children + } + + private IPath substituteProject(IPath path, String projectName){ + return new Path(projectName).makeAbsolute().append(path.removeFirstSegments(1)); + } + + private void handleRenamedFile(IPath fromPath, IPath toPath){ + if(!fValidatedFilesSet.add(fromPath)) + return; + + IProject fromProject = findModifiedProject(fromPath.segment(0)); + if(fromProject == null) + return; + IManagedBuilderMakefileGenerator fromMakeGen = getInitializedGenerator(fromProject); + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + if(fromMakeGen == null || fromMakeGen.isGeneratedResource(root.getFile(substituteProject(fromPath,fromProject.getName())))) + return; + + IManagedBuildInfo fromInfo = fromProject != null ? + ManagedBuildManager.getBuildInfo(fromProject) : + null; + + IProject toProject = root.findMember(toPath.uptoSegment(1)).getProject(); + IManagedBuildInfo toInfo = toProject != null ? + ManagedBuildManager.getBuildInfo(toProject) : + null; + IManagedBuilderMakefileGenerator toMakeGen = toProject != null ? + getInitializedGenerator(toProject) : + null; + if(toMakeGen != null && toMakeGen.isGeneratedResource(root.getFile(toPath))) + toInfo = null; + + if(fromInfo == toInfo){ + //the resource was moved whithing the project scope + if(updateResourceConfigurations(fromInfo,fromPath,toPath) && toProject != null) + fModifiedProjects.add(toProject); + } else { + if(fromInfo != null && toInfo != null){ + //TODO: this is the case when the resource + //is moved from one managed project to another + //should we handle this? + //e.g. add resource configurations to the destination project? + } + if(fromInfo != null && removeResourceConfigurations(fromInfo,fromPath) && fromProject != null) + fModifiedProjects.add(fromProject); + } + } + + private void handleDeleteFile(IPath path){ + IProject project = findModifiedProject(path.segment(0)); + if(project != null){ + IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project); + if(info != null + && removeResourceConfigurations(info,path)) + fModifiedProjects.add(project); + } + } + + //finds the project geven the initial project name + //That is: + // if the project of a given name was renamed returns the renamed project + // if the project of a given name was removed returns null + // if the project of a given name was neither renamed or removed + // returns the project of that name or null if the project does not exist + // + private IProject findModifiedProject(final String oldProjectName){ + IResourceDelta projectDelta = fRootDelta.findMember(new Path(oldProjectName)); + boolean replaced = false; + if(projectDelta != null) { + switch(projectDelta.getKind()){ + case IResourceDelta.REMOVED : + if ((projectDelta.getFlags() & IResourceDelta.MOVED_TO) == 0) { + return null; + } + case IResourceDelta.CHANGED : + if ((projectDelta.getFlags() & IResourceDelta.MOVED_TO) != 0) { + IPath path = projectDelta.getMovedToPath(); + if(path != null) + return ResourcesPlugin.getWorkspace().getRoot().findMember(path).getProject(); + } + break; + } + } + + final IProject project[] = new IProject[1]; + try { + fRootDelta.accept(new IResourceDeltaVisitor() { + public boolean visit(IResourceDelta delta) throws CoreException { + IResource dResource = delta.getResource(); + int rcType = dResource.getType(); + if(rcType == IResource.ROOT) { + return true; + } else if(rcType == IResource.PROJECT){ + switch(delta.getKind()){ + case IResourceDelta.ADDED : + case IResourceDelta.CHANGED : + if ((delta.getFlags() & IResourceDelta.MOVED_FROM) != 0) { + IPath path = delta.getMovedFromPath(); + if (path != null && path.segment(0).equals(oldProjectName)) { + project[0] = dResource.getProject(); + } + } + break; + default: + break; + } + } + return false; + } + }); + } catch (CoreException e) { + } + + if(project[0] == null && !replaced) + project[0] = ResourcesPlugin.getWorkspace().getRoot().findMember(oldProjectName).getProject(); + return project[0]; + } + + private IManagedBuilderMakefileGenerator getInitializedGenerator(IProject project){ + IManagedBuilderMakefileGenerator makeGen = (IManagedBuilderMakefileGenerator)fBuildFileGeneratorMap.get(project); + if (makeGen == null) { + try { + if (project.hasNature(ManagedCProjectNature.MNG_NATURE_ID)) { + // Determine if we can access the build info before actually trying + // If not, don't try, to avoid putting up a dialog box warning the user + if (!ManagedBuildManager.canGetBuildInfo(project)) return null; + + IManagedBuildInfo buildInfo = ManagedBuildManager.getBuildInfo(project); + if (buildInfo != null){ + IConfiguration defaultCfg = buildInfo.getDefaultConfiguration(); + if (defaultCfg != null) { + makeGen = ManagedBuildManager.getBuildfileGenerator(defaultCfg); + makeGen.initialize(project,buildInfo,new NullProgressMonitor()); + fBuildFileGeneratorMap.put(project,makeGen); + } + } + } + } catch (CoreException e){ + return null; + } + } + return makeGen; + } + } + + public void sendClose(IProject project){ + IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project,false); + if(info != null){ + IManagedProject managedProj = info.getManagedProject(); + if (managedProj != null) { + IConfiguration cfgs[] = managedProj.getConfigurations(); + + for(int i = 0; i < cfgs.length; i++) + ManagedBuildManager.performValueHandlerEvent(cfgs[i], IManagedOptionValueHandler.EVENT_CLOSE, true); + } + } + } + + /* + * I R e s o u r c e C h a n g e L i s t e n e r + */ + + /* (non-Javadoc) + * + * Handle the renaming and deletion of project resources + * This is necessary in order to update ResourceConfigurations and AdditionalInputs + * + * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) + */ + public void resourceChanged(IResourceChangeEvent event) { + if (event.getSource() instanceof IWorkspace) { + + switch (event.getType()) { + case IResourceChangeEvent.PRE_CLOSE: + IResource proj = event.getResource(); + if(proj instanceof IProject) + sendClose((IProject)proj); + break; + case IResourceChangeEvent.POST_CHANGE : + case IResourceChangeEvent.POST_BUILD : + case IResourceChangeEvent.PRE_DELETE : + IResourceDelta resDelta = event.getDelta(); + if (resDelta == null) { + break; + } + try { + ResourceConfigurationChecker rcChecker = new ResourceConfigurationChecker(resDelta); + resDelta.accept(rcChecker); + + //saving info for the modified projects + initInfoSerialization(rcChecker.getModifiedProjects()); + + } catch (CoreException e) { + CCorePlugin.log(e); + } + break; + default : + break; + } + } + } + + private void initInfoSerialization(final IProject projects[]){ + if(projects.length == 0) + return; + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + IResourceRuleFactory ruleFactory = workspace.getRuleFactory(); + ISchedulingRule buildInfoSaveRule; + if(projects.length == 1){ + buildInfoSaveRule = ruleFactory.modifyRule(projects[0]); + } else { + ISchedulingRule rules[] = new ISchedulingRule[projects.length]; + for(int i = 0; i < rules.length; i++) + rules[i] = ruleFactory.modifyRule(projects[i]); + buildInfoSaveRule = MultiRule.combine(rules); + } + + Job savingJob = new Job(ManagedMakeMessages.getResourceString("ResourceChangeHandler.buildInfoSerializationJob")){ //$NON-NLS-1$ + protected IStatus run(IProgressMonitor monitor) { + for(int i = 0; i < projects.length; i++){ + ManagedBuildManager.saveBuildInfo(projects[i],true); + } + return new Status( + IStatus.OK, + ManagedBuilderCorePlugin.getUniqueIdentifier(), + IStatus.OK, + new String(), + null); + } + }; + savingJob.setRule(buildInfoSaveRule); + + savingJob.schedule(); + } + + private boolean updateResourceConfigurations(IManagedBuildInfo info, IPath oldPath, IPath newPath){ + boolean changed = false; + if(!oldPath.equals(newPath)){ + IManagedProject mngProj = info.getManagedProject(); + if(mngProj != null){ + IConfiguration configs[] = mngProj.getConfigurations(); + if(configs != null && configs.length > 0){ + for(int i = 0; i < configs.length; i++){ + if(updateResourceConfiguration(configs[i],oldPath,newPath)) + changed = true; + } + } + } + } + return changed; + } + + private boolean removeResourceConfigurations(IManagedBuildInfo info, IPath path){ + boolean changed = false; + IManagedProject mngProj = info.getManagedProject(); + if(mngProj != null){ + IConfiguration configs[] = mngProj.getConfigurations(); + if(configs != null && configs.length > 0){ + for(int i = 0; i < configs.length; i++){ + if(removeResourceConfiguration(configs[i],path)) + changed = true; + } + } + } + return changed; + } + + private boolean updateResourceConfiguration(IConfiguration config, IPath oldPath, IPath newPath){ + IResourceConfiguration rcCfg = config.getResourceConfiguration(oldPath.toString()); + if(rcCfg != null && !oldPath.equals(newPath)){ + config.removeResourceConfiguration(rcCfg); + rcCfg.setResourcePath(newPath.toString()); + ((Configuration)config).addResourceConfiguration((ResourceConfiguration)rcCfg); + config.setRebuildState(true); + return true; + } + return false; + } + + private boolean removeResourceConfiguration(IConfiguration config, IPath path){ + IResourceConfiguration rcCfg = config.getResourceConfiguration(path.toString()); + if(rcCfg != null){ + config.removeResourceConfiguration(rcCfg); + config.setRebuildState(true); + return true; + } + return false; + } + + /* + * I S a v e P a r t i c i p a n t + */ + + /* (non-Javadoc) + * @see org.eclipse.core.resources.ISaveParticipant#saving(org.eclipse.core.resources.ISaveContext) + */ + public void saving(ISaveContext context) throws CoreException { + // No state to be saved by the plug-in, but request a + // resource delta to be used on next activation. + context.needDelta(); + } + + /* (non-Javadoc) + * @see org.eclipse.core.resources.ISaveParticipant#doneSaving(org.eclipse.core.resources.ISaveContext) + */ + public void doneSaving(ISaveContext context) { + } + + /* (non-Javadoc) + * @see org.eclipse.core.resources.ISaveParticipant#prepareToSave(org.eclipse.core.resources.ISaveContext) + */ + public void prepareToSave(ISaveContext context) throws CoreException { + } + + /* (non-Javadoc) + * @see org.eclipse.core.resources.ISaveParticipant#rollback(org.eclipse.core.resources.ISaveContext) + */ + public void rollback(ISaveContext context) { + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java index 483380af6a4..c2b0c270a4d 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java @@ -1,2802 +1,2825 @@ -/******************************************************************************* - * Copyright (c) 2003, 2006 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.internal.core; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.SortedMap; -import java.util.StringTokenizer; -import java.util.Vector; - -import org.eclipse.cdt.managedbuilder.core.BuildException; -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IEnvVarBuildPath; -import org.eclipse.cdt.managedbuilder.core.IHoldsOptions; -import org.eclipse.cdt.managedbuilder.core.IManagedProject; -import org.eclipse.cdt.managedbuilder.core.IOptionApplicability; -import org.eclipse.cdt.managedbuilder.core.IInputType; -import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; -import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; -import org.eclipse.cdt.managedbuilder.core.IOption; -import org.eclipse.cdt.managedbuilder.core.IOptionCategory; -import org.eclipse.cdt.managedbuilder.core.IOutputType; -import org.eclipse.cdt.managedbuilder.core.IProjectType; -import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.IToolChain; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.internal.macros.BuildfileMacroSubstitutor; -import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; -import org.eclipse.cdt.managedbuilder.internal.macros.IMacroSubstitutor; -import org.eclipse.cdt.managedbuilder.internal.macros.MacroResolver; -import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; -import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ProjectScope; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IExtension; -import org.eclipse.core.runtime.IExtensionPoint; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.PluginVersionIdentifier; -import org.eclipse.core.runtime.content.IContentType; -import org.eclipse.core.runtime.content.IContentTypeSettings; -import org.eclipse.core.runtime.preferences.IScopeContext; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -/** - * Represents a tool that can be invoked during a build. - * Note that this class implements IOptionCategory to represent the top - * category. - */ -public class Tool extends HoldsOptions implements ITool, IOptionCategory { - - public static final String DEFAULT_PATTERN = "${COMMAND} ${FLAGS} ${OUTPUT_FLAG}${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}"; //$NON-NLS-1$ - public static final String DEFAULT_CBS_PATTERN = "${COMMAND}"; //$NON-NLS-1$ - - private static final String DEFAULT_SEPARATOR = ","; //$NON-NLS-1$ - //private static final IOptionCategory[] EMPTY_CATEGORIES = new IOptionCategory[0]; - //private static final IOption[] EMPTY_OPTIONS = new IOption[0]; - private static final String EMPTY_STRING = new String(); - private static final String[] EMPTY_STRING_ARRAY = new String[0]; - private static final String DEFAULT_ANNOUNCEMENT_PREFIX = "Tool.default.announcement"; //$NON-NLS-1$ - private static final String WHITESPACE = " "; //$NON-NLS-1$ - - private static final boolean resolvedDefault = true; - - // Superclass - // Note that superClass itself is defined in the base and that the methods - // getSuperClass() and setSuperClass(), defined in Tool must be used to - // access it. This avoids widespread casts from IHoldsOptions to ITool. - private String superClassId; - // Parent and children - private IBuildObject parent; - private Vector inputTypeList; - private Map inputTypeMap; - private Vector outputTypeList; - private Map outputTypeMap; - private List envVarBuildPathList; - // Managed Build model attributes - private String unusedChildren; - private Boolean isAbstract; - private String command; - private List inputExtensions; - private List interfaceExtensions; - private Integer natureFilter; - private String outputExtensions; - private String outputFlag; - private String outputPrefix; - private String errorParserIds; - private String commandLinePattern; - private String versionsSupported; - private String convertToId; - private Boolean advancedInputCategory; - private Boolean customBuildStep; - private String announcement; - private IConfigurationElement commandLineGeneratorElement = null; - private IManagedCommandLineGenerator commandLineGenerator = null; - private IConfigurationElement dependencyGeneratorElement = null; - private IManagedDependencyGenerator dependencyGenerator = null; - private URL iconPathURL; - // Miscellaneous - private boolean isExtensionTool = false; - private boolean isDirty = false; - private boolean resolved = resolvedDefault; - private IConfigurationElement previousMbsVersionConversionElement = null; - private IConfigurationElement currentMbsVersionConversionElement = null; - - /* - * C O N S T R U C T O R S - */ - - /** - * Constructor to create a tool based on an element from the plugin - * manifest. - * - * @param element The element containing the information about the tool. - * @param managedBuildRevision the fileVersion of Managed Build System - */ - public Tool(IManagedConfigElement element, String managedBuildRevision) { - // setup for resolving - super(false); - resolved = false; - - isExtensionTool = true; - - // Set the managedBuildRevision - setManagedBuildRevision(managedBuildRevision); - - loadFromManifest(element); - - // hook me up - ManagedBuildManager.addExtensionTool(this); - - // set up the category map - addOptionCategory(this); - - // Load children - IManagedConfigElement[] toolElements = element.getChildren(); - for (int l = 0; l < toolElements.length; ++l) { - IManagedConfigElement toolElement = toolElements[l]; - if (loadChild(toolElement)) { - // do nothing - } else if (toolElement.getName().equals(ITool.INPUT_TYPE)) { - InputType inputType = new InputType(this, toolElement); - addInputType(inputType); - } else if (toolElement.getName().equals(ITool.OUTPUT_TYPE)) { - OutputType outputType = new OutputType(this, toolElement); - addOutputType(outputType); - } else if (toolElement.getName().equals(IEnvVarBuildPath.BUILD_PATH_ELEMENT_NAME)){ - addEnvVarBuildPath(new EnvVarBuildPath(this,toolElement)); - } - } - } - - /** - * Constructor to create a new tool for a tool-chain based on the information - * defined in the plugin.xml manifest. - * - * @param parent The parent of this tool. This can be a ToolChain or a - * ResourceConfiguration. - * @param element The element containing the information about the tool. - * @param managedBuildRevision the fileVersion of Managed Build System - */ - public Tool(IBuildObject parent, IManagedConfigElement element, String managedBuildRevision) { - this(element, managedBuildRevision); - this.parent = parent; - } - - /** - * This constructor is called to create a Tool whose attributes and children will be - * added by separate calls. - * - * @param ToolChain The parent of the tool, if any - * @param Tool The superClass, if any - * @param String The id for the new tool - * @param String The name for the new tool - * @param boolean Indicates whether this is an extension element or a managed project element - */ - public Tool(ToolChain parent, ITool superClass, String Id, String name, boolean isExtensionElement) { - super(resolvedDefault); - this.parent = parent; - setSuperClass(superClass); - setManagedBuildRevision(parent.getManagedBuildRevision()); - if (getSuperClass() != null) { - superClassId = getSuperClass().getId(); - } - - setId(Id); - setName(name); - setVersion(getVersionFromId()); - - isExtensionTool = isExtensionElement; - if (isExtensionElement) { - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionTool(this); - } else { - setDirty(true); - } - } - - /** - * This constructor is called to create a Tool whose attributes and children will be - * added by separate calls. - * - * @param ResourceConfiguration, The parent of the tool, if any - * @param Tool The superClass, if any - * @param String The id for the new tool - * @param String The name for the new tool - * @param boolean Indicates whether this is an extension element or a managed project element - */ - - public Tool(ResourceConfiguration parent, ITool superClass, String Id, String name, boolean isExtensionElement) { - super(resolvedDefault); - this.parent = parent; - setSuperClass( superClass ); - setManagedBuildRevision(parent.getManagedBuildRevision()); - if (getSuperClass() != null) { - superClassId = getSuperClass().getId(); - } - setId(Id); - setName(name); - setVersion(getVersionFromId()); - - isExtensionTool = isExtensionElement; - if (isExtensionElement) { - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionTool(this); - } else { - setDirty(true); - } - } - - /** - * Create a Tool based on the specification stored in the - * project file (.cdtbuild). - * - * @param parent The IToolChain or IResourceConfiguration - * the tool will be added to. - * @param element The XML element that contains the tool settings. - * @param managedBuildRevision the fileVersion of Managed Build System - */ - public Tool(IBuildObject parent, Element element, String managedBuildRevision) { - super(resolvedDefault); - this.parent = parent; - isExtensionTool = false; - - // Set the managedBuildRevsion - setManagedBuildRevision(managedBuildRevision); - - // Initialize from the XML attributes - loadFromProject(element); - - // set up the category map - addOptionCategory(this); - - // Load children - NodeList toolElements = element.getChildNodes(); - for (int i = 0; i < toolElements.getLength(); ++i) { - Node toolElement = toolElements.item(i); - if (loadChild(toolElement)) { - // do nothing - } else if (toolElement.getNodeName().equals(ITool.INPUT_TYPE)) { - InputType inputType = new InputType(this, (Element)toolElement); - addInputType(inputType); - } else if (toolElement.getNodeName().equals(ITool.OUTPUT_TYPE)) { - OutputType outputType = new OutputType(this, (Element)toolElement); - addOutputType(outputType); - } - } - } - - /** - * Create a Tool based upon an existing tool. - * - * @param parent The IToolChain or IResourceConfiguration - * the tool will be added to. - * @param tool The existing tool to clone. - */ - public Tool(IBuildObject parent, ITool toolSuperClass, String Id, String name, Tool tool){ - super(resolvedDefault); - this.parent = parent; - if (toolSuperClass != null) { - setSuperClass( toolSuperClass ); - } else { - setSuperClass( tool.getSuperClass() ); - } - if (getSuperClass() != null) { - superClassId = getSuperClass().getId(); - } - setId(Id); - setName(name); - - // Set the managedBuildRevision & the version - setManagedBuildRevision(tool.getManagedBuildRevision()); - setVersion(getVersionFromId()); - - isExtensionTool = false; - - // Copy the remaining attributes - if(tool.versionsSupported != null) { - versionsSupported = new String(tool.versionsSupported); - } - if(tool.convertToId != null) { - convertToId = new String(tool.convertToId); - } - if (tool.unusedChildren != null) { - unusedChildren = new String(tool.unusedChildren); - } - if (tool.errorParserIds != null) { - errorParserIds = new String(tool.errorParserIds); - } - if (tool.isAbstract != null) { - isAbstract = new Boolean(tool.isAbstract.booleanValue()); - } - if (tool.command != null) { - command = new String(tool.command); - } - if (tool.commandLinePattern != null) { - commandLinePattern = new String(tool.commandLinePattern); - } - if (tool.inputExtensions != null) { - inputExtensions = new ArrayList(tool.inputExtensions); - } - if (tool.interfaceExtensions != null) { - interfaceExtensions = new ArrayList(tool.interfaceExtensions); - } - if (tool.natureFilter != null) { - natureFilter = new Integer(tool.natureFilter.intValue()); - } - if (tool.outputExtensions != null) { - outputExtensions = new String(tool.outputExtensions); - } - if (tool.outputFlag != null) { - outputFlag = new String(tool.outputFlag); - } - if (tool.outputPrefix != null) { - outputPrefix = new String(tool.outputPrefix); - } - if (tool.advancedInputCategory != null) { - advancedInputCategory = new Boolean(tool.advancedInputCategory.booleanValue()); - } - if (tool.customBuildStep != null) { - customBuildStep = new Boolean(tool.customBuildStep.booleanValue()); - } - if (tool.announcement != null) { - announcement = new String(tool.announcement); - } - - commandLineGeneratorElement = tool.commandLineGeneratorElement; - commandLineGenerator = tool.commandLineGenerator; - dependencyGeneratorElement = tool.dependencyGeneratorElement; - dependencyGenerator = tool.dependencyGenerator; - - if(tool.envVarBuildPathList != null) - envVarBuildPathList = new ArrayList(tool.envVarBuildPathList); - - // Clone the children in superclass - super.copyChildren(tool); - // Clone the children - if (tool.inputTypeList != null) { - Iterator iter = tool.getInputTypeList().listIterator(); - while (iter.hasNext()) { - InputType inputType = (InputType) iter.next(); - int nnn = ManagedBuildManager.getRandomNumber(); - String subId; - String subName; - if (inputType.getSuperClass() != null) { - subId = inputType.getSuperClass().getId() + "." + nnn; //$NON-NLS-1$ - subName = inputType.getSuperClass().getName(); - } else { - subId = inputType.getId() + "." + nnn; //$NON-NLS-1$ - subName = inputType.getName(); - } - InputType newInputType = new InputType(this, subId, subName, inputType); - addInputType(newInputType); - } - } - if (tool.outputTypeList != null) { - Iterator iter = tool.getOutputTypeList().listIterator(); - while (iter.hasNext()) { - OutputType outputType = (OutputType) iter.next(); - int nnn = ManagedBuildManager.getRandomNumber(); - String subId; - String subName; - if (outputType.getSuperClass() != null) { - subId = outputType.getSuperClass().getId() + "." + nnn; //$NON-NLS-1$ - subName = outputType.getSuperClass().getName(); - } else { - subId = outputType.getId() + "." + nnn; //$NON-NLS-1$ - subName = outputType.getName(); - } - OutputType newOutputType = new OutputType(this, subId, subName, outputType); - addOutputType(newOutputType); - } - } - - // icon - if ( tool.iconPathURL != null ) { - iconPathURL = tool.iconPathURL; - } - - setDirty(true); - } - - /* - * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S - */ - - /* (non-Javadoc) - * Load the tool information from the XML element specified in the - * argument - * @param element An XML element containing the tool information - */ - protected void loadFromManifest(IManagedConfigElement element) { - // setup for resolving - ManagedBuildManager.putConfigElement(this, element); - - // id - setId(element.getAttribute(ITool.ID)); - - // name - setName(element.getAttribute(ITool.NAME)); - - // version - setVersion(getVersionFromId()); - - // superClass - superClassId = element.getAttribute(IProjectType.SUPERCLASS); - - // Get the unused children, if any - unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); - - // Get the 'versionsSupported' attribute - versionsSupported =element.getAttribute(VERSIONS_SUPPORTED); - - // Get the 'convertToId' attribute - convertToId = element.getAttribute(CONVERT_TO_ID); - - // isAbstract - String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); - if (isAbs != null){ - isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ - } - - // Get the semicolon separated list of IDs of the error parsers - errorParserIds = element.getAttribute(IToolChain.ERROR_PARSERS); - - // Get the nature filter - String nature = element.getAttribute(NATURE); - if (nature != null) { - if ("both".equals(nature)) { //$NON-NLS-1$ - natureFilter = new Integer(FILTER_BOTH); - } else if ("cnature".equals(nature)) { //$NON-NLS-1$ - natureFilter = new Integer(FILTER_C); - } else if ("ccnature".equals(nature)) { //$NON-NLS-1$ - natureFilter = new Integer(FILTER_CC); - } else { - natureFilter = new Integer(FILTER_BOTH); - } - } - - // Get the supported input file extensions - String inputs = element.getAttribute(ITool.SOURCES); - if (inputs != null) { - StringTokenizer tokenizer = new StringTokenizer(inputs, DEFAULT_SEPARATOR); - while (tokenizer.hasMoreElements()) { - getInputExtensionsList().add(tokenizer.nextElement()); - } - } - - // Get the interface (header file) extensions - String headers = element.getAttribute(INTERFACE_EXTS); - if (headers != null) { - StringTokenizer tokenizer = new StringTokenizer(headers, DEFAULT_SEPARATOR); - while (tokenizer.hasMoreElements()) { - getInterfaceExtensionsList().add(tokenizer.nextElement()); - } - } - - // Get the output extension - outputExtensions = element.getAttribute(ITool.OUTPUTS); - - // Get the tool invocation command - command = element.getAttribute(ITool.COMMAND); - - // Get the flag to control output - outputFlag = element.getAttribute(ITool.OUTPUT_FLAG); - - // Get the output prefix - outputPrefix = element.getAttribute(ITool.OUTPUT_PREFIX); - - // Get command line pattern - commandLinePattern = element.getAttribute( ITool.COMMAND_LINE_PATTERN ); - - // Get advancedInputCategory - String advInput = element.getAttribute(ITool.ADVANCED_INPUT_CATEGORY); - if (advInput != null){ - advancedInputCategory = new Boolean("true".equals(advInput)); //$NON-NLS-1$ - } - - // Get customBuildStep - String cbs = element.getAttribute(ITool.CUSTOM_BUILD_STEP); - if (cbs != null){ - customBuildStep = new Boolean("true".equals(cbs)); //$NON-NLS-1$ - } - - // Get the announcement text - announcement = element.getAttribute(ITool.ANNOUNCEMENT); - - // Store the configuration element IFF there is a command line generator defined - String commandLineGenerator = element.getAttribute(COMMAND_LINE_GENERATOR); - if (commandLineGenerator != null && element instanceof DefaultManagedConfigElement) { - commandLineGeneratorElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); - } - - // Store the configuration element IFF there is a dependency generator defined - String depGenerator = element.getAttribute(DEP_CALC_ID); - if (depGenerator != null && element instanceof DefaultManagedConfigElement) { - dependencyGeneratorElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); - } - - // icon - if ( element.getAttribute(IOptionCategory.ICON) != null && element instanceof DefaultManagedConfigElement) - { - String icon = element.getAttribute(IOptionCategory.ICON); - iconPathURL = ManagedBuildManager.getURLInBuildDefinitions( (DefaultManagedConfigElement)element, new Path(icon) ); - } - } - - /* (non-Javadoc) - * Initialize the tool information from the XML element - * specified in the argument - * - * @param element An XML element containing the tool information - */ - protected void loadFromProject(Element element) { - - // id - setId(element.getAttribute(IBuildObject.ID)); - - // name - if (element.hasAttribute(IBuildObject.NAME)) { - setName(element.getAttribute(IBuildObject.NAME)); - } - - // version - setVersion(getVersionFromId()); - - // superClass - superClassId = element.getAttribute(IProjectType.SUPERCLASS); - if (superClassId != null && superClassId.length() > 0) { - if( getParent() instanceof IResourceConfiguration ) { - IResourceConfiguration resConfig = (IResourceConfiguration) getParent(); - setSuperClass( resConfig.getParent().getTool(superClassId) ); - } else { - setSuperClass( ManagedBuildManager.getExtensionTool(superClassId) ); - } - - // Check for migration support - checkForMigrationSupport(); - - } - - // Get the unused children, if any - if (element.hasAttribute(IProjectType.UNUSED_CHILDREN)) { - unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); - } - - // isAbstract - if (element.hasAttribute(IProjectType.IS_ABSTRACT)) { - String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); - if (isAbs != null){ - isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ - } - } - - // Get the 'versionSupported' attribute - if (element.hasAttribute(VERSIONS_SUPPORTED)) { - versionsSupported = element.getAttribute(VERSIONS_SUPPORTED); - } - - // Get the 'convertToId' id - if (element.hasAttribute(CONVERT_TO_ID)) { - convertToId = element.getAttribute(CONVERT_TO_ID); - } - - // Get the semicolon separated list of IDs of the error parsers - if (element.hasAttribute(IToolChain.ERROR_PARSERS)) { - errorParserIds = element.getAttribute(IToolChain.ERROR_PARSERS); - } - - // Get the nature filter - if (element.hasAttribute(NATURE)) { - String nature = element.getAttribute(NATURE); - if (nature != null) { - if ("both".equals(nature)) { //$NON-NLS-1$ - natureFilter = new Integer(FILTER_BOTH); - } else if ("cnature".equals(nature)) { //$NON-NLS-1$ - natureFilter = new Integer(FILTER_C); - } else if ("ccnature".equals(nature)) { //$NON-NLS-1$ - natureFilter = new Integer(FILTER_CC); - } else { - natureFilter = new Integer(FILTER_BOTH); - } - } - } - - // Get the supported input file extension - if (element.hasAttribute(ITool.SOURCES)) { - String inputs = element.getAttribute(ITool.SOURCES); - if (inputs != null) { - StringTokenizer tokenizer = new StringTokenizer(inputs, DEFAULT_SEPARATOR); - while (tokenizer.hasMoreElements()) { - getInputExtensionsList().add(tokenizer.nextElement()); - } - } - } - - // Get the interface (header file) extensions - if (element.hasAttribute(INTERFACE_EXTS)) { - String headers = element.getAttribute(INTERFACE_EXTS); - if (headers != null) { - StringTokenizer tokenizer = new StringTokenizer(headers, DEFAULT_SEPARATOR); - while (tokenizer.hasMoreElements()) { - getInterfaceExtensionsList().add(tokenizer.nextElement()); - } - } - } - - // Get the output extension - if (element.hasAttribute(ITool.OUTPUTS)) { - outputExtensions = element.getAttribute(ITool.OUTPUTS); - } - - // Get the tool invocation command - if (element.hasAttribute(ITool.COMMAND)) { - command = element.getAttribute(ITool.COMMAND); - } - - // Get the flag to control output - if (element.hasAttribute(ITool.OUTPUT_FLAG)) { - outputFlag = element.getAttribute(ITool.OUTPUT_FLAG); - } - - // Get the output prefix - if (element.hasAttribute(ITool.OUTPUT_PREFIX)) { - outputPrefix = element.getAttribute(ITool.OUTPUT_PREFIX); - } - - // Get command line pattern - if( element.hasAttribute( ITool.COMMAND_LINE_PATTERN ) ) { - commandLinePattern = element.getAttribute( ITool.COMMAND_LINE_PATTERN ); - } - - // advancedInputCategory - if (element.hasAttribute(ITool.ADVANCED_INPUT_CATEGORY)) { - String advInput = element.getAttribute(ITool.ADVANCED_INPUT_CATEGORY); - if (advInput != null){ - advancedInputCategory = new Boolean("true".equals(advInput)); //$NON-NLS-1$ - } - } - - // customBuildStep - if (element.hasAttribute(ITool.CUSTOM_BUILD_STEP)) { - String cbs = element.getAttribute(ITool.CUSTOM_BUILD_STEP); - if (cbs != null){ - customBuildStep = new Boolean("true".equals(cbs)); //$NON-NLS-1$ - } - } - - // Get the announcement text - if (element.hasAttribute(ITool.ANNOUNCEMENT)) { - announcement = element.getAttribute(ITool.ANNOUNCEMENT); - } - - // icon - was saved as URL in string form - if (element.hasAttribute(IOptionCategory.ICON)) { - String iconPath = element.getAttribute(IOptionCategory.ICON); - try { - iconPathURL = new URL(iconPath); - } catch (MalformedURLException e) { - // Print a warning - ManagedBuildManager.OutputIconError(iconPath); - iconPathURL = null; - } - } - } - - /** - * Persist the tool to the project file. - * - * @param doc - * @param element - */ - public void serialize(Document doc, Element element) { - try { - if (getSuperClass() != null) - element.setAttribute(IProjectType.SUPERCLASS, getSuperClass().getId()); - - // id - element.setAttribute(IBuildObject.ID, id); - - // name - if (name != null) { - element.setAttribute(IBuildObject.NAME, name); - } - - // unused children - if (unusedChildren != null) { - element.setAttribute(IProjectType.UNUSED_CHILDREN, unusedChildren); - } - - // isAbstract - if (isAbstract != null) { - element.setAttribute(IProjectType.IS_ABSTRACT, isAbstract.toString()); - } - - // versionsSupported - if (versionsSupported != null) { - element.setAttribute(VERSIONS_SUPPORTED, versionsSupported); - } - - // convertToId - if (convertToId != null) { - element.setAttribute(CONVERT_TO_ID, convertToId); - } - - // error parsers - if (errorParserIds != null) { - element.setAttribute(IToolChain.ERROR_PARSERS, errorParserIds); - } - - // nature filter - if (natureFilter != null) { - String nature; - if (natureFilter.intValue() == FILTER_C) { - nature = "cnature"; //$NON-NLS-1$ - } else if (natureFilter.intValue() == FILTER_CC) { - nature = "ccnature"; //$NON-NLS-1$ - } else { - nature = "both"; //$NON-NLS-1$ - } - element.setAttribute(NATURE, nature); - } - - // input file extensions - if (getInputExtensionsList().size() > 0) { - String inputs; - List list = getInputExtensionsList(); - Iterator iter = list.listIterator(); - inputs = (String)iter.next(); - while (iter.hasNext()) { - inputs += DEFAULT_SEPARATOR; - inputs += iter.next(); - } - element.setAttribute(ITool.SOURCES, inputs); - } - - // interface (header file) extensions - if (getInterfaceExtensionsList().size() > 0) { - String headers; - List list = getInterfaceExtensionsList(); - Iterator iter = list.listIterator(); - headers = (String)iter.next(); - while (iter.hasNext()) { - headers += DEFAULT_SEPARATOR; - headers += iter.next(); - } - element.setAttribute(INTERFACE_EXTS, headers); - } - - // output extension - if (outputExtensions != null) { - element.setAttribute(ITool.OUTPUTS, outputExtensions); - } - - // command - if (command != null) { - element.setAttribute(ITool.COMMAND, command); - } - - // flag to control output - if (outputFlag != null) { - element.setAttribute(ITool.OUTPUT_FLAG, outputFlag); - } - - // output prefix - if (outputPrefix != null) { - element.setAttribute(ITool.OUTPUT_PREFIX, outputPrefix); - } - - // command line pattern - if (commandLinePattern != null) { - element.setAttribute(ITool.COMMAND_LINE_PATTERN, commandLinePattern); - } - - // advancedInputCategory - if (advancedInputCategory != null) { - element.setAttribute(ITool.ADVANCED_INPUT_CATEGORY, advancedInputCategory.toString()); - } - - // customBuildStep - if (customBuildStep != null) { - element.setAttribute(ITool.CUSTOM_BUILD_STEP, customBuildStep.toString()); - } - - // announcement text - if (announcement != null) { - element.setAttribute(ITool.ANNOUNCEMENT, announcement); - } - - // Serialize elements from my super class - super.serialize(doc, element); - - // Serialize my children - Iterator iter; - List typeElements = getInputTypeList(); - iter = typeElements.listIterator(); - while (iter.hasNext()) { - InputType type = (InputType) iter.next(); - Element typeElement = doc.createElement(INPUT_TYPE); - element.appendChild(typeElement); - type.serialize(doc, typeElement); - } - typeElements = getOutputTypeList(); - iter = typeElements.listIterator(); - while (iter.hasNext()) { - OutputType type = (OutputType) iter.next(); - Element typeElement = doc.createElement(OUTPUT_TYPE); - element.appendChild(typeElement); - type.serialize(doc, typeElement); - } - - // Note: command line generator cannot be specified in a project file because - // an IConfigurationElement is needed to load it! - if (commandLineGeneratorElement != null) { - // TODO: issue warning? - } - - // Note: dependency generator cannot be specified in a project file because - // an IConfigurationElement is needed to load it! - if (dependencyGeneratorElement != null) { - // TODO: issue warning? - } - - if (iconPathURL != null) { - // Save as URL in string form - element.setAttribute(IOptionCategory.ICON, iconPathURL.toString()); - } - - // I am clean now - isDirty = false; - } catch (Exception e) { - // TODO: issue an error message - } - } - - /* - * P A R E N T A N D C H I L D H A N D L I N G - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getParent() - */ - public IBuildObject getParent() { - return parent; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setParent(IBuildObject) - */ - public void setToolParent(IBuildObject newParent) { - this.parent = newParent; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getTopOptionCategory() - */ - public IOptionCategory getTopOptionCategory() { - return this; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#createInputType(IInputType, String, String, boolean) - */ - public IInputType createInputType(IInputType superClass, String Id, String name, boolean isExtensionElement) { - InputType type = new InputType(this, superClass, Id, name, isExtensionElement); - addInputType(type); - setDirty(true); - return type; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#removeInputType(IInputType) - */ - public void removeInputType(IInputType type) { - getInputTypeList().remove(type); - getInputTypeMap().remove(type.getId()); - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getInputTypes() - */ - public IInputType[] getInputTypes() { - IInputType[] types = null; - // Merge our input types with our superclass' input types. - if (getSuperClass() != null) { - types = getSuperClass().getInputTypes(); - } - // Our options take precedence. - Vector ourTypes = getInputTypeList(); - if (types != null) { - for (int i = 0; i < ourTypes.size(); i++) { - IInputType ourType = (IInputType)ourTypes.get(i); - int j; - for (j = 0; j < types.length; j++) { - if (ourType.getSuperClass() != null && - ourType.getSuperClass().getId().equals(types[j].getId())) { - types[j] = ourType; - break; - } - } - // No Match? Add it. - if (j == types.length) { - IInputType[] newTypes = new IInputType[types.length + 1]; - for (int k = 0; k < types.length; k++) { - newTypes[k] = types[k]; - } - newTypes[j] = ourType; - types = newTypes; - } - } - } else { - types = (IInputType[])ourTypes.toArray(new IInputType[ourTypes.size()]); - } - return types; - } - - private boolean hasInputTypes() { - Vector ourTypes = getInputTypeList(); - if (ourTypes.size() > 0) return true; - return false; - } - - public IInputType getInputTypeById(String id) { - IInputType type = (IInputType)getInputTypeMap().get(id); - if (type == null) { - if (getSuperClass() != null) { - return getSuperClass().getInputTypeById(id); - } - } - return type; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#createOutputType(IOutputType, String, String, boolean) - */ - public IOutputType createOutputType(IOutputType superClass, String Id, String name, boolean isExtensionElement) { - OutputType type = new OutputType(this, superClass, Id, name, isExtensionElement); - addOutputType(type); - setDirty(true); - return type; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#removeOutputType(IOutputType) - */ - public void removeOutputType(IOutputType type) { - getOutputTypeList().remove(type); - getOutputTypeMap().remove(type.getId()); - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputTypes() - */ - public IOutputType[] getOutputTypes() { - IOutputType[] types = null; - // Merge our output types with our superclass' output types. - if (getSuperClass() != null) { - types = getSuperClass().getOutputTypes(); - } - // Our options take precedence. - Vector ourTypes = getOutputTypeList(); - if (types != null) { - for (int i = 0; i < ourTypes.size(); i++) { - IOutputType ourType = (IOutputType)ourTypes.get(i); - int j; - for (j = 0; j < types.length; j++) { - if (ourType.getSuperClass() != null && - ourType.getSuperClass().getId().equals(types[j].getId())) { - types[j] = ourType; - break; - } - } - // No Match? Add it. - if (j == types.length) { - IOutputType[] newTypes = new IOutputType[types.length + 1]; - for (int k = 0; k < types.length; k++) { - newTypes[k] = types[k]; - } - newTypes[j] = ourType; - types = newTypes; - } - } - } else { - types = (IOutputType[])ourTypes.toArray(new IOutputType[ourTypes.size()]); - } - return types; - } - - private boolean hasOutputTypes() { - Vector ourTypes = getOutputTypeList(); - if (ourTypes.size() > 0) return true; - return false; - } - - public IOutputType getPrimaryOutputType() { - IOutputType type = null; - IOutputType[] types = getOutputTypes(); - if (types != null && types.length > 0) { - for (int i=0; i 0) return exts[0]; - } - // If none, use the input extensions specified for the Tool (backwards compatibility) - List extsList = getInputExtensionsAttribute(); - // Use the first entry in the list - if (extsList != null && extsList.size() > 0) return (String)extsList.get(0); - return EMPTY_STRING; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getPrimaryInputExtensions() - */ - public String[] getPrimaryInputExtensions() { - IInputType type = getPrimaryInputType(); - if (type != null) { - String[] exts = type.getSourceExtensions(this); - // Use the first entry in the list - if (exts.length > 0) return exts; - } - // If none, use the input extensions specified for the Tool (backwards compatibility) - List extsList = getInputExtensionsAttribute(); - // Use the first entry in the list - if (extsList != null && extsList.size() > 0) { - return (String[])extsList.toArray(new String[extsList.size()]); - } - return EMPTY_STRING_ARRAY; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getAllInputExtensions() - */ - public String[] getAllInputExtensions() { - IInputType[] types = getInputTypes(); - if (types != null && types.length > 0) { - List allExts = new ArrayList(); - for (int i=0; i 0) { - return (String[])allExts.toArray(new String[allExts.size()]); - } - } - // If none, use the input extensions specified for the Tool (backwards compatibility) - List extsList = getInputExtensionsAttribute(); - if (extsList != null && extsList.size() > 0) { - return (String[])extsList.toArray(new String[extsList.size()]); - } - return EMPTY_STRING_ARRAY; - } - - public IInputType getPrimaryInputType() { - IInputType type = null; - IInputType[] types = getInputTypes(); - if (types != null && types.length > 0) { - for (int i=0; i 0) { - for (int i=0; i 0) { - allDeps.add(Path.fromOSString("$(" + type.getBuildVariable() + ")")); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - } - return (IPath[])allDeps.toArray(new IPath[allDeps.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getAdditionalResources() - */ - public IPath[] getAdditionalResources() { - List allRes = new ArrayList(); - IInputType[] types = getInputTypes(); - for (int i=0; i 0) { - allRes.add(Path.fromOSString("$(" + type.getBuildVariable() + ")")); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - } - return (IPath[])allRes.toArray(new IPath[allRes.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getAllDependencyExtensions() - */ - public String[] getAllDependencyExtensions() { - IInputType[] types = getInputTypes(); - if (types != null && types.length > 0) { - List allExts = new ArrayList(); - for (int i=0; i 0) { - return (String[])allExts.toArray(new String[allExts.size()]); - } - } - // If none, use the header extensions specified for the Tool (backwards compatibility) - List extsList = getHeaderExtensionsAttribute(); - if (extsList != null && extsList.size() > 0) { - return (String[])extsList.toArray(new String[extsList.size()]); - } - return EMPTY_STRING_ARRAY; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getInterfaceExtension() - * @deprecated - */ - public List getInterfaceExtensions() { - return getHeaderExtensionsAttribute(); - } - - private List getHeaderExtensionsAttribute() { - if (interfaceExtensions == null || interfaceExtensions.size() == 0) { - // If I have a superClass, ask it - if (getSuperClass() != null) { - return ((Tool)getSuperClass()).getHeaderExtensionsAttribute(); - } else { - if (interfaceExtensions == null) { - interfaceExtensions = new ArrayList(); - } - } - } - return interfaceExtensions; - } - - private List getInterfaceExtensionsList() { - if (interfaceExtensions == null) { - interfaceExtensions = new ArrayList(); - } - return interfaceExtensions; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getOutputFlag() - */ - public String getOutputFlag() { - if (outputFlag == null) { - // If I have a superClass, ask it - if (getSuperClass() != null) { - return getSuperClass().getOutputFlag(); - } else { - return EMPTY_STRING; - } - } - return outputFlag; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getOutputPrefix() - */ - public String getOutputPrefix() { - // Get the outputPrefix from an OutputType, if any. - IOutputType type = null; - IOutputType[] types = getOutputTypes(); - if (types != null && types.length > 0) { - for (int i=0; i 0) { - List allExts = new ArrayList(); - for (int i=0; i 0) { - return (String[])allExts.toArray(new String[allExts.size()]); - } - } - // If none, use the outputs specified for the Tool (backwards compatibility) - String[] extsList = getOutputsAttribute(); - if (extsList != null && extsList.length > 0) { - return extsList; - } - return EMPTY_STRING_ARRAY; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputExtensions() - * @deprecated - */ - public String[] getOutputExtensions() { - return getOutputsAttribute(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputsAttribute() - */ - public String[] getOutputsAttribute() { - // TODO: Why is this treated differently than inputExtensions? - if (outputExtensions == null) { - if (getSuperClass() != null) { - return getSuperClass().getOutputsAttribute(); - } else { - return null; - } - } - return outputExtensions.split(DEFAULT_SEPARATOR); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getOutputExtension(java.lang.String) - */ - public String getOutputExtension(String inputExtension) { - // Search thru the output-types to find one that has a primary input type with this extension - IOutputType[] types = getOutputTypes(); - int i; - if (types != null) { - for (i=0; i 0) { - return exts[0]; - } - } - } - // Does any input type produce this extension? - if (getInputType(inputExtension) != null) { - // Return the first extension of the primary output type - IOutputType outType = getPrimaryOutputType(); - String[] exts = outType.getOutputExtensions(this); - if (exts != null && exts.length > 0) { - return exts[0]; - } - } - } - // If no OutputTypes specified, examine the list of input extensions - String[] inputExts = getAllInputExtensions(); - for (i=0; i 0) { - for (int i=0; i 0) { - sb.append(boolCmd); - } - break; - - case IOption.ENUMERATED : - String enumVal = option.getEnumCommand(option.getSelectedEnum()); - if (enumVal.length() > 0) { - sb.append(enumVal); - } - break; - - case IOption.STRING : - String strCmd = option.getCommand(); - String val = option.getStringValue(); - macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(inputFileLocation, outputFileLocation, option, this)); - if (val.length() > 0 - && (val = MacroResolver.resolveToString(val, macroSubstitutor)).length() > 0) { - sb.append( evaluateCommand( strCmd, val ) ); - } - break; - - case IOption.STRING_LIST : - String listCmd = option.getCommand(); - macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(inputFileLocation, outputFileLocation, option, this)); - String[] list = MacroResolver.resolveStringListValues(option.getStringListValue(), macroSubstitutor, true); - if(list != null){ - for (int j = 0; j < list.length; j++) { - String temp = list[j]; - if(temp.length() > 0) - sb.append( evaluateCommand( listCmd, temp ) + WHITE_SPACE ); - } - } - break; - - case IOption.INCLUDE_PATH : - String incCmd = option.getCommand(); - macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(inputFileLocation, outputFileLocation, option, this)); - String[] paths = MacroResolver.resolveStringListValues(option.getIncludePaths(), macroSubstitutor, true); - if(paths != null){ - for (int j = 0; j < paths.length; j++) { - String temp = paths[j]; - if(temp.length() > 0) - sb.append( evaluateCommand( incCmd, temp ) + WHITE_SPACE); - } - } - break; - - case IOption.PREPROCESSOR_SYMBOLS : - String defCmd = option.getCommand(); - macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(inputFileLocation, outputFileLocation, option, this)); - String[] symbols = MacroResolver.resolveStringListValues(option.getDefinedSymbols(), macroSubstitutor, true); - if(symbols != null){ - for (int j = 0; j < symbols.length; j++) { - String temp = symbols[j]; - if(temp.length() > 0) - sb.append( evaluateCommand( defCmd, temp ) + WHITE_SPACE); - } - } - break; - - default : - break; - } - - if (sb.toString().trim().length() > 0) - flags.add(sb.toString().trim()); - } catch (BuildMacroException e) { - - } - } - } - String[] f = new String[ flags.size() ]; - return (String[])flags.toArray( f ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getToolCommandFlags(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) - */ - public String[] getToolCommandFlags(IPath inputFileLocation, IPath outputFileLocation) throws BuildException{ - IMacroSubstitutor macroSubstitutor = new BuildfileMacroSubstitutor(null,EMPTY_STRING,WHITE_SPACE); - return getToolCommandFlags(inputFileLocation, outputFileLocation, macroSubstitutor ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getToolCommandFlagsString(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) - */ - public String getToolCommandFlagsString(IPath inputFileLocation, IPath outputFileLocation) throws BuildException{ - // Get all of the optionList - StringBuffer buf = new StringBuffer(); - String[] flags = getToolCommandFlags(inputFileLocation,outputFileLocation); - for (int index = 0; index < flags.length; index++) { - if( flags[ index ] != null ) { - buf.append( flags[ index ] + WHITE_SPACE ); - } - } - - return buf.toString().trim(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#isHeaderFile(java.lang.String) - */ - public boolean isHeaderFile(String ext) { - if (ext == null) { - return false; - } - String[] exts = getAllDependencyExtensions(); - for (int i=0; i 0) { - return false; - } - // 3. If the assignToOption attribute is specified, no - if (it.getAssignToOptionId() != null && it.getAssignToOptionId().length() > 0) { - return false; - } - // Else, yes - return true; - } - // If no InputTypes, check the inputExtensions attribute - if (!hasInputTypes()) { - return getInputExtensionsAttribute().contains(extension); - } - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#isInputFileType(java.lang.String) - */ - public boolean isInputFileType(String extension) { - if (extension == null) { - return false; - } - IInputType it = getInputType(extension); - if (it != null) { - return true; - } - // If no InputTypes, check the inputExtensions attribute - if (!hasInputTypes()) { - return getInputExtensionsAttribute().contains(extension); - } - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#producesFileType(java.lang.String) - */ - public boolean producesFileType(String extension) { - if (extension == null) { - return false; - } - // Check the output-types first - if (getOutputType(extension) != null) { - return true; - } - // If there are no OutputTypes, check the attribute - if (!hasOutputTypes()) { - String[] exts = getOutputsAttribute(); - if (exts != null) { - for (int i = 0; i < exts.length; i++) { - if (exts[i].equals(extension)) - return true; - } - } - } - return false; - } - -/* - * O B J E C T S T A T E M A I N T E N A N C E - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#isExtensionElement() - */ - public boolean isExtensionElement() { - return isExtensionTool; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#isDirty() - */ - public boolean isDirty() { - // This shouldn't be called for an extension tool - if (isExtensionTool) return false; - - // If I need saving, just say yes - if (isDirty) return true; - - // Check my children - List typeElements = getInputTypeList(); - Iterator iter = typeElements.listIterator(); - while (iter.hasNext()) { - InputType type = (InputType) iter.next(); - if (type.isDirty()) return true; - } - typeElements = getOutputTypeList(); - iter = typeElements.listIterator(); - while (iter.hasNext()) { - OutputType type = (OutputType) iter.next(); - if (type.isDirty()) return true; - } - - // Otherwise see if any options need saving - if (super.isDirty()) { - return true; - } - - return isDirty; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setDirty(boolean) - */ - public void setDirty(boolean isDirty) { - this.isDirty = isDirty; - // Propagate "false" to options - super.setDirty(isDirty); - // Propagate "false" to the children - if (!isDirty) { - List typeElements = getInputTypeList(); - Iterator iter = typeElements.listIterator(); - while (iter.hasNext()) { - InputType type = (InputType) iter.next(); - type.setDirty(false); - } - typeElements = getOutputTypeList(); - iter = typeElements.listIterator(); - while (iter.hasNext()) { - OutputType type = (OutputType) iter.next(); - type.setDirty(false); - } - } - } - - /* (non-Javadoc) - * Resolve the element IDs to interface references - */ - public void resolveReferences() { - if (!resolved) { - resolved = true; - // Resolve superClass - if (superClassId != null && superClassId.length() > 0) { - setSuperClass( ManagedBuildManager.getExtensionTool(superClassId) ); - if (getSuperClass() == null) { - // Report error - ManagedBuildManager.OutputResolveError( - "superClass", //$NON-NLS-1$ - superClassId, - "tool", //$NON-NLS-1$ - getId()); - } - } - // Resolve HoldsOptions - super.resolveReferences(); - // Call resolveReferences on our children - Iterator typeIter = getInputTypeList().iterator(); - while (typeIter.hasNext()) { - InputType current = (InputType)typeIter.next(); - current.resolveReferences(); - } - typeIter = getOutputTypeList().iterator(); - while (typeIter.hasNext()) { - OutputType current = (OutputType)typeIter.next(); - current.resolveReferences(); - } - } - } - - /** - * Look for ${VALUE} in the command string - */ - public String evaluateCommand( String command, String values ) { - final int DOLLAR_VALUE_LENGTH = 8; - - if( command == null ) return values.trim(); - - String ret = command; - boolean found = false; - int start = 0; - int index; - int len; - while ((index = ret.indexOf( "${", start )) >= 0 && //$NON-NLS-1$ - (len = ret.length()) >= index + DOLLAR_VALUE_LENGTH) { - start = index; - index = index+2; - int ch = ret.charAt(index); - if ( ch == 'v' || ch == 'V' ) { - index++; - ch = ret.charAt(index); - if ( ch == 'a' || ch == 'A' ) { - index++; - ch = ret.charAt(index); - if ( ch == 'l' || ch == 'L' ) { - index++; - ch = ret.charAt(index); - if ( ch == 'u' || ch == 'U' ) { - index++; - ch = ret.charAt(index); - if ( ch == 'e' || ch == 'E' ) { - index++; - ch = ret.charAt(index); - if ( ch == '}' ) { - String temp = ""; //$NON-NLS-1$ - index++; - found = true; - if (start > 0) { - temp = ret.substring(0, start); - } - temp = temp.concat(values.trim()); - if (len > index) { - start = temp.length(); - ret = temp.concat(ret.substring(index)); - index = start; - } - else { - ret = temp; - break; - } - } - } - } - } - } - } - start = index; - } - if (found) - return ret.trim(); - return (new String(command + values)).trim(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getConvertToId() - */ - public String getConvertToId() { - if (convertToId == null) { - // If I have a superClass, ask it - if (getSuperClass() != null) { - return getSuperClass().getConvertToId(); - } else { - return EMPTY_STRING; - } - } - return convertToId; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setConvertToId(String) - */ - public void setConvertToId(String convertToId) { - if (convertToId == null && this.convertToId == null) return; - if (convertToId == null || this.convertToId == null || !convertToId.equals(this.convertToId)) { - this.convertToId = convertToId; - setDirty(true); - } - return; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getVersionsSupported() - */ - public String getVersionsSupported() { - if (versionsSupported == null) { - // If I have a superClass, ask it - if (getSuperClass() != null) { - return getSuperClass().getVersionsSupported(); - } else { - return EMPTY_STRING; - } - } - return versionsSupported; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setVersionsSupported(String) - */ - public void setVersionsSupported(String versionsSupported) { - if (versionsSupported == null && this.versionsSupported == null) return; - if (versionsSupported == null || this.versionsSupported == null || !versionsSupported.equals(this.versionsSupported)) { - this.versionsSupported = versionsSupported; - setDirty(true); - } - return; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getEnvVarBuildPaths() - */ - public IEnvVarBuildPath[] getEnvVarBuildPaths(){ - if(envVarBuildPathList != null){ - return (IEnvVarBuildPath[])envVarBuildPathList.toArray( - new IEnvVarBuildPath[envVarBuildPathList.size()]); - } - else if(getSuperClass() != null) - return getSuperClass().getEnvVarBuildPaths(); - return null; - } - - private void addEnvVarBuildPath(IEnvVarBuildPath path){ - if(path == null) - return; - if(envVarBuildPathList == null) - envVarBuildPathList = new ArrayList(); - - envVarBuildPathList.add(path); - } - - /* - * This function checks for migration support for the tool, while - * loading. If migration support is needed, looks for the available - * converters and stores them. - */ - - public void checkForMigrationSupport() { - - boolean isExists = false; - - if ( getSuperClass() == null) { - // If 'getSuperClass()' is null, then there is no tool available in - // plugin manifest file with the same 'id' & version. - // Look for the 'versionsSupported' attribute - String high = (String) ManagedBuildManager.getExtensionToolMap() - .lastKey(); - - SortedMap subMap = null; - if (superClassId.compareTo(high) <= 0) { - subMap = ManagedBuildManager.getExtensionToolMap().subMap( - superClassId, high + "\0"); //$NON-NLS-1$ - } else { - // It means there are no entries in the map for the given id. - // make the project is invalid - - // It means there are no entries in the map for the given id. - // make the project is invalid - // If the parent is a tool chain - IToolChain parent = (IToolChain) getParent(); - IConfiguration parentConfig = parent.getParent(); - IManagedProject managedProject = parentConfig - .getManagedProject(); - if (managedProject != null) { - managedProject.setValid(false); - } - return; - } - - // for each element in the 'subMap', - // check the 'versionsSupported' attribute whether the given - // builder version is supported - - String baseId = ManagedBuildManager - .getIdFromIdAndVersion(superClassId); - String version = ManagedBuildManager - .getVersionFromIdAndVersion(superClassId); - - ITool[] toolElements = (ITool[]) subMap.values().toArray(); - - for (int i = 0; i < toolElements.length; i++) { - ITool toolElement = toolElements[i]; - - if (ManagedBuildManager.getIdFromIdAndVersion( - toolElement.getId()).compareTo(baseId) > 0) - break; - - // First check if both base ids are equal - if (ManagedBuildManager.getIdFromIdAndVersion( - toolElement.getId()).equals(baseId)) { - - // Check if 'versionsSupported' attribute is available' - String versionsSupported = toolElement - .getVersionsSupported(); - - if ((versionsSupported != null) - && (!versionsSupported.equals(""))) { //$NON-NLS-1$ - String[] tmpVersions = versionsSupported.split(","); //$NON-NLS-1$ - - for (int j = 0; j < tmpVersions.length; j++) { - if (new PluginVersionIdentifier(version) - .equals(new PluginVersionIdentifier( - tmpVersions[j]))) { - // version is supported. - // Do the automatic conversion without - // prompting the user. - // Get the supported version - String supportedVersion = ManagedBuildManager - .getVersionFromIdAndVersion(toolElement - .getId()); - setId(ManagedBuildManager - .getIdFromIdAndVersion(getId()) - + "_" + supportedVersion); //$NON-NLS-1$ - - // If control comes here means that superClass - // is null. - // So, set the superClass to this tool element - setSuperClass(toolElement); - superClassId = getSuperClass().getId(); - isExists = true; - break; - } - } - if (isExists) - break; // break the outer for loop if 'isExists' is - // true - } - } - } - } - - if (getSuperClass() != null) { - // If 'getSuperClass()' is not null, look for 'convertToId' - // attribute in plugin - // manifest file for this tool. - String convertToId = getSuperClass().getConvertToId(); - if ((convertToId == null) || (convertToId.equals(""))) { //$NON-NLS-1$ - // It means there is no 'convertToId' attribute available and - // the version is still actively - // supported by the tool integrator. So do nothing, just return - return; - } else { - // Incase the 'convertToId' attribute is available, - // it means that Tool integrator currently does not support this - // version of tool. - // Look for the converters available for this tool version. - - getConverter(convertToId); - } - - } else { - // make the project is invalid - // - // It means there are no entries in the map for the given id. - // make the project is invalid - IToolChain parent = (IToolChain) getParent(); - IConfiguration parentConfig = parent.getParent(); - IManagedProject managedProject = parentConfig.getManagedProject(); - if (managedProject != null) { - managedProject.setValid(false); - } - } - return; - } - - - private void getConverter(String convertToId) { - - String fromId = null; - String toId = null; - - // Get the Converter Extension Point - IExtensionPoint extensionPoint = Platform.getExtensionRegistry() - .getExtensionPoint("org.eclipse.cdt.managedbuilder.core", //$NON-NLS-1$ - "projectConverter"); //$NON-NLS-1$ - if (extensionPoint != null) { - // Get the extensions - IExtension[] extensions = extensionPoint.getExtensions(); - for (int i = 0; i < extensions.length; i++) { - // Get the configuration elements of each extension - IConfigurationElement[] configElements = extensions[i] - .getConfigurationElements(); - for (int j = 0; j < configElements.length; j++) { - - IConfigurationElement element = configElements[j]; - - if (element.getName().equals("converter")) { //$NON-NLS-1$ - - fromId = element.getAttribute("fromId"); //$NON-NLS-1$ - toId = element.getAttribute("toId"); //$NON-NLS-1$ - // Check whether the current converter can be used for - // the selected tool - - if (fromId.equals(getSuperClass().getId()) - && toId.equals(convertToId)) { - // If it matches - String mbsVersion = element - .getAttribute("mbsVersion"); //$NON-NLS-1$ - PluginVersionIdentifier currentMbsVersion = ManagedBuildManager - .getBuildInfoVersion(); - - // set the converter element based on the MbsVersion - if (currentMbsVersion - .isGreaterThan(new PluginVersionIdentifier( - mbsVersion))) { - previousMbsVersionConversionElement = element; - } else { - currentMbsVersionConversionElement = element; - } - return; - } - } - } - } - } - - // If control comes here, it means 'Tool Integrator' specified - // 'convertToId' attribute in toolchain definition file, but - // has not provided any converter. - // So, make the project is invalid - - // It means there are no entries in the map for the given id. - // make the project is invalid - IToolChain parent = (IToolChain) getParent(); - IConfiguration parentConfig = parent.getParent(); - IManagedProject managedProject = parentConfig.getManagedProject(); - if (managedProject != null) { - managedProject.setValid(false); - } - return; - } - - public IConfigurationElement getPreviousMbsVersionConversionElement() { - return previousMbsVersionConversionElement; - } - - public IConfigurationElement getCurrentMbsVersionConversionElement() { - return currentMbsVersionConversionElement; - } - - public IProject getProject() { - IBuildObject toolParent = getParent(); - if (toolParent != null) { - if (toolParent instanceof IToolChain) { - IConfiguration config = ((IToolChain)toolParent).getParent(); - if (config == null) return null; - return (IProject)config.getOwner(); - } else if (toolParent instanceof IResourceConfiguration) { - return (IProject)((IResourceConfiguration)toolParent).getOwner(); - } - } - return null; - } - - public String[] getContentTypeFileSpecs (IContentType type) { - String[] globalSpecs = type.getFileSpecs(IContentType.FILE_EXTENSION_SPEC); - IContentTypeSettings settings = null; - IProject project = getProject(); - if (project != null) { - IScopeContext projectScope = new ProjectScope(project); - try { - settings = type.getSettings(projectScope); - } catch (Exception e) {} - if (settings != null) { - String[] specs = settings.getFileSpecs(IContentType.FILE_EXTENSION_SPEC); - if (specs.length > 0) { - int total = globalSpecs.length + specs.length; - String[] projSpecs = new String[total]; - int i=0; - for (int j=0; jTool based on the specification stored in the + * project file (.cdtbuild). + * + * @param parent The IToolChain or IResourceConfiguration + * the tool will be added to. + * @param element The XML element that contains the tool settings. + * @param managedBuildRevision the fileVersion of Managed Build System + */ + public Tool(IBuildObject parent, Element element, String managedBuildRevision) { + super(resolvedDefault); + this.parent = parent; + isExtensionTool = false; + + // Set the managedBuildRevsion + setManagedBuildRevision(managedBuildRevision); + + // Initialize from the XML attributes + loadFromProject(element); + + // set up the category map + addOptionCategory(this); + + // Load children + NodeList toolElements = element.getChildNodes(); + for (int i = 0; i < toolElements.getLength(); ++i) { + Node toolElement = toolElements.item(i); + if (loadChild(toolElement)) { + // do nothing + } else if (toolElement.getNodeName().equals(ITool.INPUT_TYPE)) { + InputType inputType = new InputType(this, (Element)toolElement); + addInputType(inputType); + } else if (toolElement.getNodeName().equals(ITool.OUTPUT_TYPE)) { + OutputType outputType = new OutputType(this, (Element)toolElement); + addOutputType(outputType); + } + } + } + + /** + * Create a Tool based upon an existing tool. + * + * @param parent The IToolChain or IResourceConfiguration + * the tool will be added to. + * @param tool The existing tool to clone. + */ + public Tool(IBuildObject parent, ITool toolSuperClass, String Id, String name, Tool tool){ + super(resolvedDefault); + this.parent = parent; + if (toolSuperClass != null) { + setSuperClassInternal( toolSuperClass ); + } else { + setSuperClassInternal( tool.getSuperClass() ); + } + if (getSuperClass() != null) { + superClassId = getSuperClass().getId(); + } + setId(Id); + setName(name); + + // Set the managedBuildRevision & the version + setManagedBuildRevision(tool.getManagedBuildRevision()); + setVersion(getVersionFromId()); + + isExtensionTool = false; + + // Copy the remaining attributes + if(tool.versionsSupported != null) { + versionsSupported = new String(tool.versionsSupported); + } + if(tool.convertToId != null) { + convertToId = new String(tool.convertToId); + } + if (tool.unusedChildren != null) { + unusedChildren = new String(tool.unusedChildren); + } + if (tool.errorParserIds != null) { + errorParserIds = new String(tool.errorParserIds); + } + if (tool.isAbstract != null) { + isAbstract = new Boolean(tool.isAbstract.booleanValue()); + } + if (tool.command != null) { + command = new String(tool.command); + } + if (tool.commandLinePattern != null) { + commandLinePattern = new String(tool.commandLinePattern); + } + if (tool.inputExtensions != null) { + inputExtensions = new ArrayList(tool.inputExtensions); + } + if (tool.interfaceExtensions != null) { + interfaceExtensions = new ArrayList(tool.interfaceExtensions); + } + if (tool.natureFilter != null) { + natureFilter = new Integer(tool.natureFilter.intValue()); + } + if (tool.outputExtensions != null) { + outputExtensions = new String(tool.outputExtensions); + } + if (tool.outputFlag != null) { + outputFlag = new String(tool.outputFlag); + } + if (tool.outputPrefix != null) { + outputPrefix = new String(tool.outputPrefix); + } + if (tool.advancedInputCategory != null) { + advancedInputCategory = new Boolean(tool.advancedInputCategory.booleanValue()); + } + if (tool.customBuildStep != null) { + customBuildStep = new Boolean(tool.customBuildStep.booleanValue()); + } + if (tool.announcement != null) { + announcement = new String(tool.announcement); + } + + commandLineGeneratorElement = tool.commandLineGeneratorElement; + commandLineGenerator = tool.commandLineGenerator; + dependencyGeneratorElement = tool.dependencyGeneratorElement; + dependencyGenerator = tool.dependencyGenerator; + + if(tool.envVarBuildPathList != null) + envVarBuildPathList = new ArrayList(tool.envVarBuildPathList); + + // Clone the children in superclass + super.copyChildren(tool); + // Clone the children + if (tool.inputTypeList != null) { + Iterator iter = tool.getInputTypeList().listIterator(); + while (iter.hasNext()) { + InputType inputType = (InputType) iter.next(); + int nnn = ManagedBuildManager.getRandomNumber(); + String subId; + String subName; + if (inputType.getSuperClass() != null) { + subId = inputType.getSuperClass().getId() + "." + nnn; //$NON-NLS-1$ + subName = inputType.getSuperClass().getName(); + } else { + subId = inputType.getId() + "." + nnn; //$NON-NLS-1$ + subName = inputType.getName(); + } + InputType newInputType = new InputType(this, subId, subName, inputType); + addInputType(newInputType); + } + } + if (tool.outputTypeList != null) { + Iterator iter = tool.getOutputTypeList().listIterator(); + while (iter.hasNext()) { + OutputType outputType = (OutputType) iter.next(); + int nnn = ManagedBuildManager.getRandomNumber(); + String subId; + String subName; + if (outputType.getSuperClass() != null) { + subId = outputType.getSuperClass().getId() + "." + nnn; //$NON-NLS-1$ + subName = outputType.getSuperClass().getName(); + } else { + subId = outputType.getId() + "." + nnn; //$NON-NLS-1$ + subName = outputType.getName(); + } + OutputType newOutputType = new OutputType(this, subId, subName, outputType); + addOutputType(newOutputType); + } + } + + // icon + if ( tool.iconPathURL != null ) { + iconPathURL = tool.iconPathURL; + } + + setDirty(true); + } + + /* + * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S + */ + + /* (non-Javadoc) + * Load the tool information from the XML element specified in the + * argument + * @param element An XML element containing the tool information + */ + protected void loadFromManifest(IManagedConfigElement element) { + // setup for resolving + ManagedBuildManager.putConfigElement(this, element); + + // id + setId(element.getAttribute(ITool.ID)); + + // name + setName(element.getAttribute(ITool.NAME)); + + // version + setVersion(getVersionFromId()); + + // superClass + superClassId = element.getAttribute(IProjectType.SUPERCLASS); + + // Get the unused children, if any + unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); + + // Get the 'versionsSupported' attribute + versionsSupported =element.getAttribute(VERSIONS_SUPPORTED); + + // Get the 'convertToId' attribute + convertToId = element.getAttribute(CONVERT_TO_ID); + + // isAbstract + String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); + if (isAbs != null){ + isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ + } + + // Get the semicolon separated list of IDs of the error parsers + errorParserIds = element.getAttribute(IToolChain.ERROR_PARSERS); + + // Get the nature filter + String nature = element.getAttribute(NATURE); + if (nature != null) { + if ("both".equals(nature)) { //$NON-NLS-1$ + natureFilter = new Integer(FILTER_BOTH); + } else if ("cnature".equals(nature)) { //$NON-NLS-1$ + natureFilter = new Integer(FILTER_C); + } else if ("ccnature".equals(nature)) { //$NON-NLS-1$ + natureFilter = new Integer(FILTER_CC); + } else { + natureFilter = new Integer(FILTER_BOTH); + } + } + + // Get the supported input file extensions + String inputs = element.getAttribute(ITool.SOURCES); + if (inputs != null) { + StringTokenizer tokenizer = new StringTokenizer(inputs, DEFAULT_SEPARATOR); + while (tokenizer.hasMoreElements()) { + getInputExtensionsList().add(tokenizer.nextElement()); + } + } + + // Get the interface (header file) extensions + String headers = element.getAttribute(INTERFACE_EXTS); + if (headers != null) { + StringTokenizer tokenizer = new StringTokenizer(headers, DEFAULT_SEPARATOR); + while (tokenizer.hasMoreElements()) { + getInterfaceExtensionsList().add(tokenizer.nextElement()); + } + } + + // Get the output extension + outputExtensions = element.getAttribute(ITool.OUTPUTS); + + // Get the tool invocation command + command = element.getAttribute(ITool.COMMAND); + + // Get the flag to control output + outputFlag = element.getAttribute(ITool.OUTPUT_FLAG); + + // Get the output prefix + outputPrefix = element.getAttribute(ITool.OUTPUT_PREFIX); + + // Get command line pattern + commandLinePattern = element.getAttribute( ITool.COMMAND_LINE_PATTERN ); + + // Get advancedInputCategory + String advInput = element.getAttribute(ITool.ADVANCED_INPUT_CATEGORY); + if (advInput != null){ + advancedInputCategory = new Boolean("true".equals(advInput)); //$NON-NLS-1$ + } + + // Get customBuildStep + String cbs = element.getAttribute(ITool.CUSTOM_BUILD_STEP); + if (cbs != null){ + customBuildStep = new Boolean("true".equals(cbs)); //$NON-NLS-1$ + } + + // Get the announcement text + announcement = element.getAttribute(ITool.ANNOUNCEMENT); + + // Store the configuration element IFF there is a command line generator defined + String commandLineGenerator = element.getAttribute(COMMAND_LINE_GENERATOR); + if (commandLineGenerator != null && element instanceof DefaultManagedConfigElement) { + commandLineGeneratorElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); + } + + // Store the configuration element IFF there is a dependency generator defined + String depGenerator = element.getAttribute(DEP_CALC_ID); + if (depGenerator != null && element instanceof DefaultManagedConfigElement) { + dependencyGeneratorElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); + } + + // icon + if ( element.getAttribute(IOptionCategory.ICON) != null && element instanceof DefaultManagedConfigElement) + { + String icon = element.getAttribute(IOptionCategory.ICON); + iconPathURL = ManagedBuildManager.getURLInBuildDefinitions( (DefaultManagedConfigElement)element, new Path(icon) ); + } + } + + /* (non-Javadoc) + * Initialize the tool information from the XML element + * specified in the argument + * + * @param element An XML element containing the tool information + */ + protected void loadFromProject(Element element) { + + // id + setId(element.getAttribute(IBuildObject.ID)); + + // name + if (element.hasAttribute(IBuildObject.NAME)) { + setName(element.getAttribute(IBuildObject.NAME)); + } + + // version + setVersion(getVersionFromId()); + + // superClass + superClassId = element.getAttribute(IProjectType.SUPERCLASS); + if (superClassId != null && superClassId.length() > 0) { + if( getParent() instanceof IResourceConfiguration ) { + IResourceConfiguration resConfig = (IResourceConfiguration) getParent(); + setSuperClassInternal( resConfig.getParent().getTool(superClassId) ); + } else { + setSuperClassInternal( ManagedBuildManager.getExtensionTool(superClassId) ); + } + + // Check for migration support + checkForMigrationSupport(); + + } + + // Get the unused children, if any + if (element.hasAttribute(IProjectType.UNUSED_CHILDREN)) { + unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); + } + + // isAbstract + if (element.hasAttribute(IProjectType.IS_ABSTRACT)) { + String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); + if (isAbs != null){ + isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ + } + } + + // Get the 'versionSupported' attribute + if (element.hasAttribute(VERSIONS_SUPPORTED)) { + versionsSupported = element.getAttribute(VERSIONS_SUPPORTED); + } + + // Get the 'convertToId' id + if (element.hasAttribute(CONVERT_TO_ID)) { + convertToId = element.getAttribute(CONVERT_TO_ID); + } + + // Get the semicolon separated list of IDs of the error parsers + if (element.hasAttribute(IToolChain.ERROR_PARSERS)) { + errorParserIds = element.getAttribute(IToolChain.ERROR_PARSERS); + } + + // Get the nature filter + if (element.hasAttribute(NATURE)) { + String nature = element.getAttribute(NATURE); + if (nature != null) { + if ("both".equals(nature)) { //$NON-NLS-1$ + natureFilter = new Integer(FILTER_BOTH); + } else if ("cnature".equals(nature)) { //$NON-NLS-1$ + natureFilter = new Integer(FILTER_C); + } else if ("ccnature".equals(nature)) { //$NON-NLS-1$ + natureFilter = new Integer(FILTER_CC); + } else { + natureFilter = new Integer(FILTER_BOTH); + } + } + } + + // Get the supported input file extension + if (element.hasAttribute(ITool.SOURCES)) { + String inputs = element.getAttribute(ITool.SOURCES); + if (inputs != null) { + StringTokenizer tokenizer = new StringTokenizer(inputs, DEFAULT_SEPARATOR); + while (tokenizer.hasMoreElements()) { + getInputExtensionsList().add(tokenizer.nextElement()); + } + } + } + + // Get the interface (header file) extensions + if (element.hasAttribute(INTERFACE_EXTS)) { + String headers = element.getAttribute(INTERFACE_EXTS); + if (headers != null) { + StringTokenizer tokenizer = new StringTokenizer(headers, DEFAULT_SEPARATOR); + while (tokenizer.hasMoreElements()) { + getInterfaceExtensionsList().add(tokenizer.nextElement()); + } + } + } + + // Get the output extension + if (element.hasAttribute(ITool.OUTPUTS)) { + outputExtensions = element.getAttribute(ITool.OUTPUTS); + } + + // Get the tool invocation command + if (element.hasAttribute(ITool.COMMAND)) { + command = element.getAttribute(ITool.COMMAND); + } + + // Get the flag to control output + if (element.hasAttribute(ITool.OUTPUT_FLAG)) { + outputFlag = element.getAttribute(ITool.OUTPUT_FLAG); + } + + // Get the output prefix + if (element.hasAttribute(ITool.OUTPUT_PREFIX)) { + outputPrefix = element.getAttribute(ITool.OUTPUT_PREFIX); + } + + // Get command line pattern + if( element.hasAttribute( ITool.COMMAND_LINE_PATTERN ) ) { + commandLinePattern = element.getAttribute( ITool.COMMAND_LINE_PATTERN ); + } + + // advancedInputCategory + if (element.hasAttribute(ITool.ADVANCED_INPUT_CATEGORY)) { + String advInput = element.getAttribute(ITool.ADVANCED_INPUT_CATEGORY); + if (advInput != null){ + advancedInputCategory = new Boolean("true".equals(advInput)); //$NON-NLS-1$ + } + } + + // customBuildStep + if (element.hasAttribute(ITool.CUSTOM_BUILD_STEP)) { + String cbs = element.getAttribute(ITool.CUSTOM_BUILD_STEP); + if (cbs != null){ + customBuildStep = new Boolean("true".equals(cbs)); //$NON-NLS-1$ + } + } + + // Get the announcement text + if (element.hasAttribute(ITool.ANNOUNCEMENT)) { + announcement = element.getAttribute(ITool.ANNOUNCEMENT); + } + + // icon - was saved as URL in string form + if (element.hasAttribute(IOptionCategory.ICON)) { + String iconPath = element.getAttribute(IOptionCategory.ICON); + try { + iconPathURL = new URL(iconPath); + } catch (MalformedURLException e) { + // Print a warning + ManagedBuildManager.OutputIconError(iconPath); + iconPathURL = null; + } + } + } + + /** + * Persist the tool to the project file. + * + * @param doc + * @param element + */ + public void serialize(Document doc, Element element) { + try { + if (getSuperClass() != null) + element.setAttribute(IProjectType.SUPERCLASS, getSuperClass().getId()); + + // id + element.setAttribute(IBuildObject.ID, id); + + // name + if (name != null) { + element.setAttribute(IBuildObject.NAME, name); + } + + // unused children + if (unusedChildren != null) { + element.setAttribute(IProjectType.UNUSED_CHILDREN, unusedChildren); + } + + // isAbstract + if (isAbstract != null) { + element.setAttribute(IProjectType.IS_ABSTRACT, isAbstract.toString()); + } + + // versionsSupported + if (versionsSupported != null) { + element.setAttribute(VERSIONS_SUPPORTED, versionsSupported); + } + + // convertToId + if (convertToId != null) { + element.setAttribute(CONVERT_TO_ID, convertToId); + } + + // error parsers + if (errorParserIds != null) { + element.setAttribute(IToolChain.ERROR_PARSERS, errorParserIds); + } + + // nature filter + if (natureFilter != null) { + String nature; + if (natureFilter.intValue() == FILTER_C) { + nature = "cnature"; //$NON-NLS-1$ + } else if (natureFilter.intValue() == FILTER_CC) { + nature = "ccnature"; //$NON-NLS-1$ + } else { + nature = "both"; //$NON-NLS-1$ + } + element.setAttribute(NATURE, nature); + } + + // input file extensions + if (getInputExtensionsList().size() > 0) { + String inputs; + List list = getInputExtensionsList(); + Iterator iter = list.listIterator(); + inputs = (String)iter.next(); + while (iter.hasNext()) { + inputs += DEFAULT_SEPARATOR; + inputs += iter.next(); + } + element.setAttribute(ITool.SOURCES, inputs); + } + + // interface (header file) extensions + if (getInterfaceExtensionsList().size() > 0) { + String headers; + List list = getInterfaceExtensionsList(); + Iterator iter = list.listIterator(); + headers = (String)iter.next(); + while (iter.hasNext()) { + headers += DEFAULT_SEPARATOR; + headers += iter.next(); + } + element.setAttribute(INTERFACE_EXTS, headers); + } + + // output extension + if (outputExtensions != null) { + element.setAttribute(ITool.OUTPUTS, outputExtensions); + } + + // command + if (command != null) { + element.setAttribute(ITool.COMMAND, command); + } + + // flag to control output + if (outputFlag != null) { + element.setAttribute(ITool.OUTPUT_FLAG, outputFlag); + } + + // output prefix + if (outputPrefix != null) { + element.setAttribute(ITool.OUTPUT_PREFIX, outputPrefix); + } + + // command line pattern + if (commandLinePattern != null) { + element.setAttribute(ITool.COMMAND_LINE_PATTERN, commandLinePattern); + } + + // advancedInputCategory + if (advancedInputCategory != null) { + element.setAttribute(ITool.ADVANCED_INPUT_CATEGORY, advancedInputCategory.toString()); + } + + // customBuildStep + if (customBuildStep != null) { + element.setAttribute(ITool.CUSTOM_BUILD_STEP, customBuildStep.toString()); + } + + // announcement text + if (announcement != null) { + element.setAttribute(ITool.ANNOUNCEMENT, announcement); + } + + // Serialize elements from my super class + super.serialize(doc, element); + + // Serialize my children + Iterator iter; + List typeElements = getInputTypeList(); + iter = typeElements.listIterator(); + while (iter.hasNext()) { + InputType type = (InputType) iter.next(); + Element typeElement = doc.createElement(INPUT_TYPE); + element.appendChild(typeElement); + type.serialize(doc, typeElement); + } + typeElements = getOutputTypeList(); + iter = typeElements.listIterator(); + while (iter.hasNext()) { + OutputType type = (OutputType) iter.next(); + Element typeElement = doc.createElement(OUTPUT_TYPE); + element.appendChild(typeElement); + type.serialize(doc, typeElement); + } + + // Note: command line generator cannot be specified in a project file because + // an IConfigurationElement is needed to load it! + if (commandLineGeneratorElement != null) { + // TODO: issue warning? + } + + // Note: dependency generator cannot be specified in a project file because + // an IConfigurationElement is needed to load it! + if (dependencyGeneratorElement != null) { + // TODO: issue warning? + } + + if (iconPathURL != null) { + // Save as URL in string form + element.setAttribute(IOptionCategory.ICON, iconPathURL.toString()); + } + + // I am clean now + isDirty = false; + } catch (Exception e) { + // TODO: issue an error message + } + } + + /* + * P A R E N T A N D C H I L D H A N D L I N G + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getParent() + */ + public IBuildObject getParent() { + return parent; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setParent(IBuildObject) + */ + public void setToolParent(IBuildObject newParent) { + this.parent = newParent; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getTopOptionCategory() + */ + public IOptionCategory getTopOptionCategory() { + return this; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#createInputType(IInputType, String, String, boolean) + */ + public IInputType createInputType(IInputType superClass, String Id, String name, boolean isExtensionElement) { + InputType type = new InputType(this, superClass, Id, name, isExtensionElement); + addInputType(type); + setDirty(true); + return type; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#removeInputType(IInputType) + */ + public void removeInputType(IInputType type) { + getInputTypeList().remove(type); + getInputTypeMap().remove(type.getId()); + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getInputTypes() + */ + public IInputType[] getInputTypes() { + IInputType[] types = null; + // Merge our input types with our superclass' input types. + if (getSuperClass() != null) { + types = getSuperClass().getInputTypes(); + } + // Our options take precedence. + Vector ourTypes = getInputTypeList(); + if (types != null) { + for (int i = 0; i < ourTypes.size(); i++) { + IInputType ourType = (IInputType)ourTypes.get(i); + int j; + for (j = 0; j < types.length; j++) { + if (ourType.getSuperClass() != null && + ourType.getSuperClass().getId().equals(types[j].getId())) { + types[j] = ourType; + break; + } + } + // No Match? Add it. + if (j == types.length) { + IInputType[] newTypes = new IInputType[types.length + 1]; + for (int k = 0; k < types.length; k++) { + newTypes[k] = types[k]; + } + newTypes[j] = ourType; + types = newTypes; + } + } + } else { + types = (IInputType[])ourTypes.toArray(new IInputType[ourTypes.size()]); + } + return types; + } + + private boolean hasInputTypes() { + Vector ourTypes = getInputTypeList(); + if (ourTypes.size() > 0) return true; + return false; + } + + public IInputType getInputTypeById(String id) { + IInputType type = (IInputType)getInputTypeMap().get(id); + if (type == null) { + if (getSuperClass() != null) { + return getSuperClass().getInputTypeById(id); + } + } + return type; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#createOutputType(IOutputType, String, String, boolean) + */ + public IOutputType createOutputType(IOutputType superClass, String Id, String name, boolean isExtensionElement) { + OutputType type = new OutputType(this, superClass, Id, name, isExtensionElement); + addOutputType(type); + setDirty(true); + return type; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#removeOutputType(IOutputType) + */ + public void removeOutputType(IOutputType type) { + getOutputTypeList().remove(type); + getOutputTypeMap().remove(type.getId()); + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputTypes() + */ + public IOutputType[] getOutputTypes() { + IOutputType[] types = null; + // Merge our output types with our superclass' output types. + if (getSuperClass() != null) { + types = getSuperClass().getOutputTypes(); + } + // Our options take precedence. + Vector ourTypes = getOutputTypeList(); + if (types != null) { + for (int i = 0; i < ourTypes.size(); i++) { + IOutputType ourType = (IOutputType)ourTypes.get(i); + int j; + for (j = 0; j < types.length; j++) { + if (ourType.getSuperClass() != null && + ourType.getSuperClass().getId().equals(types[j].getId())) { + types[j] = ourType; + break; + } + } + // No Match? Add it. + if (j == types.length) { + IOutputType[] newTypes = new IOutputType[types.length + 1]; + for (int k = 0; k < types.length; k++) { + newTypes[k] = types[k]; + } + newTypes[j] = ourType; + types = newTypes; + } + } + } else { + types = (IOutputType[])ourTypes.toArray(new IOutputType[ourTypes.size()]); + } + return types; + } + + private boolean hasOutputTypes() { + Vector ourTypes = getOutputTypeList(); + if (ourTypes.size() > 0) return true; + return false; + } + + public IOutputType getPrimaryOutputType() { + IOutputType type = null; + IOutputType[] types = getOutputTypes(); + if (types != null && types.length > 0) { + for (int i=0; i 0) return exts[0]; + } + // If none, use the input extensions specified for the Tool (backwards compatibility) + List extsList = getInputExtensionsAttribute(); + // Use the first entry in the list + if (extsList != null && extsList.size() > 0) return (String)extsList.get(0); + return EMPTY_STRING; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getPrimaryInputExtensions() + */ + public String[] getPrimaryInputExtensions() { + IInputType type = getPrimaryInputType(); + if (type != null) { + String[] exts = type.getSourceExtensions(this); + // Use the first entry in the list + if (exts.length > 0) return exts; + } + // If none, use the input extensions specified for the Tool (backwards compatibility) + List extsList = getInputExtensionsAttribute(); + // Use the first entry in the list + if (extsList != null && extsList.size() > 0) { + return (String[])extsList.toArray(new String[extsList.size()]); + } + return EMPTY_STRING_ARRAY; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getAllInputExtensions() + */ + public String[] getAllInputExtensions() { + IInputType[] types = getInputTypes(); + if (types != null && types.length > 0) { + List allExts = new ArrayList(); + for (int i=0; i 0) { + return (String[])allExts.toArray(new String[allExts.size()]); + } + } + // If none, use the input extensions specified for the Tool (backwards compatibility) + List extsList = getInputExtensionsAttribute(); + if (extsList != null && extsList.size() > 0) { + return (String[])extsList.toArray(new String[extsList.size()]); + } + return EMPTY_STRING_ARRAY; + } + + public IInputType getPrimaryInputType() { + IInputType type = null; + IInputType[] types = getInputTypes(); + if (types != null && types.length > 0) { + for (int i=0; i 0) { + for (int i=0; i 0) { + allDeps.add(Path.fromOSString("$(" + type.getBuildVariable() + ")")); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + } + return (IPath[])allDeps.toArray(new IPath[allDeps.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getAdditionalResources() + */ + public IPath[] getAdditionalResources() { + List allRes = new ArrayList(); + IInputType[] types = getInputTypes(); + for (int i=0; i 0) { + allRes.add(Path.fromOSString("$(" + type.getBuildVariable() + ")")); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + } + return (IPath[])allRes.toArray(new IPath[allRes.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getAllDependencyExtensions() + */ + public String[] getAllDependencyExtensions() { + IInputType[] types = getInputTypes(); + if (types != null && types.length > 0) { + List allExts = new ArrayList(); + for (int i=0; i 0) { + return (String[])allExts.toArray(new String[allExts.size()]); + } + } + // If none, use the header extensions specified for the Tool (backwards compatibility) + List extsList = getHeaderExtensionsAttribute(); + if (extsList != null && extsList.size() > 0) { + return (String[])extsList.toArray(new String[extsList.size()]); + } + return EMPTY_STRING_ARRAY; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getInterfaceExtension() + * @deprecated + */ + public List getInterfaceExtensions() { + return getHeaderExtensionsAttribute(); + } + + private List getHeaderExtensionsAttribute() { + if (interfaceExtensions == null || interfaceExtensions.size() == 0) { + // If I have a superClass, ask it + if (getSuperClass() != null) { + return ((Tool)getSuperClass()).getHeaderExtensionsAttribute(); + } else { + if (interfaceExtensions == null) { + interfaceExtensions = new ArrayList(); + } + } + } + return interfaceExtensions; + } + + private List getInterfaceExtensionsList() { + if (interfaceExtensions == null) { + interfaceExtensions = new ArrayList(); + } + return interfaceExtensions; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getOutputFlag() + */ + public String getOutputFlag() { + if (outputFlag == null) { + // If I have a superClass, ask it + if (getSuperClass() != null) { + return getSuperClass().getOutputFlag(); + } else { + return EMPTY_STRING; + } + } + return outputFlag; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getOutputPrefix() + */ + public String getOutputPrefix() { + // Get the outputPrefix from an OutputType, if any. + IOutputType type = null; + IOutputType[] types = getOutputTypes(); + if (types != null && types.length > 0) { + for (int i=0; i 0) { + List allExts = new ArrayList(); + for (int i=0; i 0) { + return (String[])allExts.toArray(new String[allExts.size()]); + } + } + // If none, use the outputs specified for the Tool (backwards compatibility) + String[] extsList = getOutputsAttribute(); + if (extsList != null && extsList.length > 0) { + return extsList; + } + return EMPTY_STRING_ARRAY; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputExtensions() + * @deprecated + */ + public String[] getOutputExtensions() { + return getOutputsAttribute(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputsAttribute() + */ + public String[] getOutputsAttribute() { + // TODO: Why is this treated differently than inputExtensions? + if (outputExtensions == null) { + if (getSuperClass() != null) { + return getSuperClass().getOutputsAttribute(); + } else { + return null; + } + } + return outputExtensions.split(DEFAULT_SEPARATOR); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getOutputExtension(java.lang.String) + */ + public String getOutputExtension(String inputExtension) { + // Search thru the output-types to find one that has a primary input type with this extension + IOutputType[] types = getOutputTypes(); + int i; + if (types != null) { + for (i=0; i 0) { + return exts[0]; + } + } + } + // Does any input type produce this extension? + if (getInputType(inputExtension) != null) { + // Return the first extension of the primary output type + IOutputType outType = getPrimaryOutputType(); + String[] exts = outType.getOutputExtensions(this); + if (exts != null && exts.length > 0) { + return exts[0]; + } + } + } + // If no OutputTypes specified, examine the list of input extensions + String[] inputExts = getAllInputExtensions(); + for (i=0; i 0) { + for (int i=0; i 0) { + sb.append(boolCmd); + } + break; + + case IOption.ENUMERATED : + String enumVal = option.getEnumCommand(option.getSelectedEnum()); + if (enumVal.length() > 0) { + sb.append(enumVal); + } + break; + + case IOption.STRING : + String strCmd = option.getCommand(); + String val = option.getStringValue(); + macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(inputFileLocation, outputFileLocation, option, this)); + if (val.length() > 0 + && (val = MacroResolver.resolveToString(val, macroSubstitutor)).length() > 0) { + sb.append( evaluateCommand( strCmd, val ) ); + } + break; + + case IOption.STRING_LIST : + String listCmd = option.getCommand(); + macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(inputFileLocation, outputFileLocation, option, this)); + String[] list = MacroResolver.resolveStringListValues(option.getStringListValue(), macroSubstitutor, true); + if(list != null){ + for (int j = 0; j < list.length; j++) { + String temp = list[j]; + if(temp.length() > 0) + sb.append( evaluateCommand( listCmd, temp ) + WHITE_SPACE ); + } + } + break; + + case IOption.INCLUDE_PATH : + String incCmd = option.getCommand(); + macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(inputFileLocation, outputFileLocation, option, this)); + String[] paths = MacroResolver.resolveStringListValues(option.getIncludePaths(), macroSubstitutor, true); + if(paths != null){ + for (int j = 0; j < paths.length; j++) { + String temp = paths[j]; + if(temp.length() > 0) + sb.append( evaluateCommand( incCmd, temp ) + WHITE_SPACE); + } + } + break; + + case IOption.PREPROCESSOR_SYMBOLS : + String defCmd = option.getCommand(); + macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(inputFileLocation, outputFileLocation, option, this)); + String[] symbols = MacroResolver.resolveStringListValues(option.getDefinedSymbols(), macroSubstitutor, true); + if(symbols != null){ + for (int j = 0; j < symbols.length; j++) { + String temp = symbols[j]; + if(temp.length() > 0) + sb.append( evaluateCommand( defCmd, temp ) + WHITE_SPACE); + } + } + break; + + default : + break; + } + + if (sb.toString().trim().length() > 0) + flags.add(sb.toString().trim()); + } catch (BuildMacroException e) { + + } + } + } + String[] f = new String[ flags.size() ]; + return (String[])flags.toArray( f ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getToolCommandFlags(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) + */ + public String[] getToolCommandFlags(IPath inputFileLocation, IPath outputFileLocation) throws BuildException{ + IMacroSubstitutor macroSubstitutor = new BuildfileMacroSubstitutor(null,EMPTY_STRING,WHITE_SPACE); + return getToolCommandFlags(inputFileLocation, outputFileLocation, macroSubstitutor ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getToolCommandFlagsString(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) + */ + public String getToolCommandFlagsString(IPath inputFileLocation, IPath outputFileLocation) throws BuildException{ + // Get all of the optionList + StringBuffer buf = new StringBuffer(); + String[] flags = getToolCommandFlags(inputFileLocation,outputFileLocation); + for (int index = 0; index < flags.length; index++) { + if( flags[ index ] != null ) { + buf.append( flags[ index ] + WHITE_SPACE ); + } + } + + return buf.toString().trim(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#isHeaderFile(java.lang.String) + */ + public boolean isHeaderFile(String ext) { + if (ext == null) { + return false; + } + String[] exts = getAllDependencyExtensions(); + for (int i=0; i 0) { + return false; + } + // 3. If the assignToOption attribute is specified, no + if (it.getAssignToOptionId() != null && it.getAssignToOptionId().length() > 0) { + return false; + } + // Else, yes + return true; + } + // If no InputTypes, check the inputExtensions attribute + if (!hasInputTypes()) { + return getInputExtensionsAttribute().contains(extension); + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#isInputFileType(java.lang.String) + */ + public boolean isInputFileType(String extension) { + if (extension == null) { + return false; + } + IInputType it = getInputType(extension); + if (it != null) { + return true; + } + // If no InputTypes, check the inputExtensions attribute + if (!hasInputTypes()) { + return getInputExtensionsAttribute().contains(extension); + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#producesFileType(java.lang.String) + */ + public boolean producesFileType(String extension) { + if (extension == null) { + return false; + } + // Check the output-types first + if (getOutputType(extension) != null) { + return true; + } + // If there are no OutputTypes, check the attribute + if (!hasOutputTypes()) { + String[] exts = getOutputsAttribute(); + if (exts != null) { + for (int i = 0; i < exts.length; i++) { + if (exts[i].equals(extension)) + return true; + } + } + } + return false; + } + +/* + * O B J E C T S T A T E M A I N T E N A N C E + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#isExtensionElement() + */ + public boolean isExtensionElement() { + return isExtensionTool; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#isDirty() + */ + public boolean isDirty() { + // This shouldn't be called for an extension tool + if (isExtensionTool) return false; + + // If I need saving, just say yes + if (isDirty) return true; + + // Check my children + List typeElements = getInputTypeList(); + Iterator iter = typeElements.listIterator(); + while (iter.hasNext()) { + InputType type = (InputType) iter.next(); + if (type.isDirty()) return true; + } + typeElements = getOutputTypeList(); + iter = typeElements.listIterator(); + while (iter.hasNext()) { + OutputType type = (OutputType) iter.next(); + if (type.isDirty()) return true; + } + + // Otherwise see if any options need saving + if (super.isDirty()) { + return true; + } + + return isDirty; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setDirty(boolean) + */ + public void setDirty(boolean isDirty) { + this.isDirty = isDirty; + // Propagate "false" to options + super.setDirty(isDirty); + // Propagate "false" to the children + if (!isDirty) { + List typeElements = getInputTypeList(); + Iterator iter = typeElements.listIterator(); + while (iter.hasNext()) { + InputType type = (InputType) iter.next(); + type.setDirty(false); + } + typeElements = getOutputTypeList(); + iter = typeElements.listIterator(); + while (iter.hasNext()) { + OutputType type = (OutputType) iter.next(); + type.setDirty(false); + } + } + } + + /* (non-Javadoc) + * Resolve the element IDs to interface references + */ + public void resolveReferences() { + if (!resolved) { + resolved = true; + // Resolve superClass + if (superClassId != null && superClassId.length() > 0) { + setSuperClassInternal( ManagedBuildManager.getExtensionTool(superClassId) ); + if (getSuperClass() == null) { + // Report error + ManagedBuildManager.OutputResolveError( + "superClass", //$NON-NLS-1$ + superClassId, + "tool", //$NON-NLS-1$ + getId()); + } + } + // Resolve HoldsOptions + super.resolveReferences(); + // Call resolveReferences on our children + Iterator typeIter = getInputTypeList().iterator(); + while (typeIter.hasNext()) { + InputType current = (InputType)typeIter.next(); + current.resolveReferences(); + } + typeIter = getOutputTypeList().iterator(); + while (typeIter.hasNext()) { + OutputType current = (OutputType)typeIter.next(); + current.resolveReferences(); + } + } + } + + /** + * Look for ${VALUE} in the command string + */ + public String evaluateCommand( String command, String values ) { + final int DOLLAR_VALUE_LENGTH = 8; + + if( command == null ) return values.trim(); + + String ret = command; + boolean found = false; + int start = 0; + int index; + int len; + while ((index = ret.indexOf( "${", start )) >= 0 && //$NON-NLS-1$ + (len = ret.length()) >= index + DOLLAR_VALUE_LENGTH) { + start = index; + index = index+2; + int ch = ret.charAt(index); + if ( ch == 'v' || ch == 'V' ) { + index++; + ch = ret.charAt(index); + if ( ch == 'a' || ch == 'A' ) { + index++; + ch = ret.charAt(index); + if ( ch == 'l' || ch == 'L' ) { + index++; + ch = ret.charAt(index); + if ( ch == 'u' || ch == 'U' ) { + index++; + ch = ret.charAt(index); + if ( ch == 'e' || ch == 'E' ) { + index++; + ch = ret.charAt(index); + if ( ch == '}' ) { + String temp = ""; //$NON-NLS-1$ + index++; + found = true; + if (start > 0) { + temp = ret.substring(0, start); + } + temp = temp.concat(values.trim()); + if (len > index) { + start = temp.length(); + ret = temp.concat(ret.substring(index)); + index = start; + } + else { + ret = temp; + break; + } + } + } + } + } + } + } + start = index; + } + if (found) + return ret.trim(); + return (new String(command + values)).trim(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getConvertToId() + */ + public String getConvertToId() { + if (convertToId == null) { + // If I have a superClass, ask it + if (getSuperClass() != null) { + return getSuperClass().getConvertToId(); + } else { + return EMPTY_STRING; + } + } + return convertToId; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setConvertToId(String) + */ + public void setConvertToId(String convertToId) { + if (convertToId == null && this.convertToId == null) return; + if (convertToId == null || this.convertToId == null || !convertToId.equals(this.convertToId)) { + this.convertToId = convertToId; + setDirty(true); + } + return; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getVersionsSupported() + */ + public String getVersionsSupported() { + if (versionsSupported == null) { + // If I have a superClass, ask it + if (getSuperClass() != null) { + return getSuperClass().getVersionsSupported(); + } else { + return EMPTY_STRING; + } + } + return versionsSupported; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setVersionsSupported(String) + */ + public void setVersionsSupported(String versionsSupported) { + if (versionsSupported == null && this.versionsSupported == null) return; + if (versionsSupported == null || this.versionsSupported == null || !versionsSupported.equals(this.versionsSupported)) { + this.versionsSupported = versionsSupported; + setDirty(true); + } + return; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getEnvVarBuildPaths() + */ + public IEnvVarBuildPath[] getEnvVarBuildPaths(){ + if(envVarBuildPathList != null){ + return (IEnvVarBuildPath[])envVarBuildPathList.toArray( + new IEnvVarBuildPath[envVarBuildPathList.size()]); + } + else if(getSuperClass() != null) + return getSuperClass().getEnvVarBuildPaths(); + return null; + } + + private void addEnvVarBuildPath(IEnvVarBuildPath path){ + if(path == null) + return; + if(envVarBuildPathList == null) + envVarBuildPathList = new ArrayList(); + + envVarBuildPathList.add(path); + } + + /* + * This function checks for migration support for the tool, while + * loading. If migration support is needed, looks for the available + * converters and stores them. + */ + + public void checkForMigrationSupport() { + + boolean isExists = false; + + if ( getSuperClass() == null) { + // If 'getSuperClass()' is null, then there is no tool available in + // plugin manifest file with the same 'id' & version. + // Look for the 'versionsSupported' attribute + String high = (String) ManagedBuildManager.getExtensionToolMap() + .lastKey(); + + SortedMap subMap = null; + if (superClassId.compareTo(high) <= 0) { + subMap = ManagedBuildManager.getExtensionToolMap().subMap( + superClassId, high + "\0"); //$NON-NLS-1$ + } else { + // It means there are no entries in the map for the given id. + // make the project is invalid + + // It means there are no entries in the map for the given id. + // make the project is invalid + // If the parent is a tool chain + IToolChain parent = (IToolChain) getParent(); + IConfiguration parentConfig = parent.getParent(); + IManagedProject managedProject = parentConfig + .getManagedProject(); + if (managedProject != null) { + managedProject.setValid(false); + } + return; + } + + // for each element in the 'subMap', + // check the 'versionsSupported' attribute whether the given + // builder version is supported + + String baseId = ManagedBuildManager + .getIdFromIdAndVersion(superClassId); + String version = ManagedBuildManager + .getVersionFromIdAndVersion(superClassId); + + ITool[] toolElements = (ITool[]) subMap.values().toArray(); + + for (int i = 0; i < toolElements.length; i++) { + ITool toolElement = toolElements[i]; + + if (ManagedBuildManager.getIdFromIdAndVersion( + toolElement.getId()).compareTo(baseId) > 0) + break; + + // First check if both base ids are equal + if (ManagedBuildManager.getIdFromIdAndVersion( + toolElement.getId()).equals(baseId)) { + + // Check if 'versionsSupported' attribute is available' + String versionsSupported = toolElement + .getVersionsSupported(); + + if ((versionsSupported != null) + && (!versionsSupported.equals(""))) { //$NON-NLS-1$ + String[] tmpVersions = versionsSupported.split(","); //$NON-NLS-1$ + + for (int j = 0; j < tmpVersions.length; j++) { + if (new PluginVersionIdentifier(version) + .equals(new PluginVersionIdentifier( + tmpVersions[j]))) { + // version is supported. + // Do the automatic conversion without + // prompting the user. + // Get the supported version + String supportedVersion = ManagedBuildManager + .getVersionFromIdAndVersion(toolElement + .getId()); + setId(ManagedBuildManager + .getIdFromIdAndVersion(getId()) + + "_" + supportedVersion); //$NON-NLS-1$ + + // If control comes here means that superClass + // is null. + // So, set the superClass to this tool element + setSuperClassInternal(toolElement); + superClassId = getSuperClass().getId(); + isExists = true; + break; + } + } + if (isExists) + break; // break the outer for loop if 'isExists' is + // true + } + } + } + } + + if (getSuperClass() != null) { + // If 'getSuperClass()' is not null, look for 'convertToId' + // attribute in plugin + // manifest file for this tool. + String convertToId = getSuperClass().getConvertToId(); + if ((convertToId == null) || (convertToId.equals(""))) { //$NON-NLS-1$ + // It means there is no 'convertToId' attribute available and + // the version is still actively + // supported by the tool integrator. So do nothing, just return + return; + } else { + // Incase the 'convertToId' attribute is available, + // it means that Tool integrator currently does not support this + // version of tool. + // Look for the converters available for this tool version. + + getConverter(convertToId); + } + + } else { + // make the project is invalid + // + // It means there are no entries in the map for the given id. + // make the project is invalid + IToolChain parent = (IToolChain) getParent(); + IConfiguration parentConfig = parent.getParent(); + IManagedProject managedProject = parentConfig.getManagedProject(); + if (managedProject != null) { + managedProject.setValid(false); + } + } + return; + } + + + private void getConverter(String convertToId) { + + String fromId = null; + String toId = null; + + // Get the Converter Extension Point + IExtensionPoint extensionPoint = Platform.getExtensionRegistry() + .getExtensionPoint("org.eclipse.cdt.managedbuilder.core", //$NON-NLS-1$ + "projectConverter"); //$NON-NLS-1$ + if (extensionPoint != null) { + // Get the extensions + IExtension[] extensions = extensionPoint.getExtensions(); + for (int i = 0; i < extensions.length; i++) { + // Get the configuration elements of each extension + IConfigurationElement[] configElements = extensions[i] + .getConfigurationElements(); + for (int j = 0; j < configElements.length; j++) { + + IConfigurationElement element = configElements[j]; + + if (element.getName().equals("converter")) { //$NON-NLS-1$ + + fromId = element.getAttribute("fromId"); //$NON-NLS-1$ + toId = element.getAttribute("toId"); //$NON-NLS-1$ + // Check whether the current converter can be used for + // the selected tool + + if (fromId.equals(getSuperClass().getId()) + && toId.equals(convertToId)) { + // If it matches + String mbsVersion = element + .getAttribute("mbsVersion"); //$NON-NLS-1$ + PluginVersionIdentifier currentMbsVersion = ManagedBuildManager + .getBuildInfoVersion(); + + // set the converter element based on the MbsVersion + if (currentMbsVersion + .isGreaterThan(new PluginVersionIdentifier( + mbsVersion))) { + previousMbsVersionConversionElement = element; + } else { + currentMbsVersionConversionElement = element; + } + return; + } + } + } + } + } + + // If control comes here, it means 'Tool Integrator' specified + // 'convertToId' attribute in toolchain definition file, but + // has not provided any converter. + // So, make the project is invalid + + // It means there are no entries in the map for the given id. + // make the project is invalid + IToolChain parent = (IToolChain) getParent(); + IConfiguration parentConfig = parent.getParent(); + IManagedProject managedProject = parentConfig.getManagedProject(); + if (managedProject != null) { + managedProject.setValid(false); + } + return; + } + + public IConfigurationElement getPreviousMbsVersionConversionElement() { + return previousMbsVersionConversionElement; + } + + public IConfigurationElement getCurrentMbsVersionConversionElement() { + return currentMbsVersionConversionElement; + } + + public IProject getProject() { + IBuildObject toolParent = getParent(); + if (toolParent != null) { + if (toolParent instanceof IToolChain) { + IConfiguration config = ((IToolChain)toolParent).getParent(); + if (config == null) return null; + return (IProject)config.getOwner(); + } else if (toolParent instanceof IResourceConfiguration) { + return (IProject)((IResourceConfiguration)toolParent).getOwner(); + } + } + return null; + } + + public String[] getContentTypeFileSpecs (IContentType type) { + String[] globalSpecs = type.getFileSpecs(IContentType.FILE_EXTENSION_SPEC); + IContentTypeSettings settings = null; + IProject project = getProject(); + if (project != null) { + IScopeContext projectScope = new ProjectScope(project); + try { + settings = type.getSettings(projectScope); + } catch (Exception e) {} + if (settings != null) { + String[] specs = settings.getFileSpecs(IContentType.FILE_EXTENSION_SPEC); + if (specs.length > 0) { + int total = globalSpecs.length + specs.length; + String[] projSpecs = new String[total]; + int i=0; + for (int j=0; jnull if - * defined at the top level - * @param element The tool-chain definition from the manifest file or a dynamic element - * provider - * @param managedBuildRevision the fileVersion of Managed Build System - */ - public ToolChain(IConfiguration parent, IManagedConfigElement element, String managedBuildRevision) { - // setup for resolving - super(false); - resolved = false; - - this.parent = parent; - isExtensionToolChain = true; - - // Set the managedBuildRevision - setManagedBuildRevision(managedBuildRevision); - - loadFromManifest(element); - - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionToolChain(this); - - // Load the TargetPlatform child - IManagedConfigElement[] targetPlatforms = - element.getChildren(ITargetPlatform.TARGET_PLATFORM_ELEMENT_NAME); - if (targetPlatforms.length < 1 || targetPlatforms.length > 1) { - // TODO: Report error - } - if (targetPlatforms.length > 0) { - targetPlatform = new TargetPlatform(this, targetPlatforms[0], managedBuildRevision); - } - - // Load the Builder child - IManagedConfigElement[] builders = - element.getChildren(IBuilder.BUILDER_ELEMENT_NAME); - if (builders.length < 1 || builders.length > 1) { - // TODO: Report error - } - if (builders.length > 0) { - builder = new Builder(this, builders[0], managedBuildRevision); - } - - // Load children - IManagedConfigElement[] toolChainElements = element.getChildren(); - for (int l = 0; l < toolChainElements.length; ++l) { - IManagedConfigElement toolChainElement = toolChainElements[l]; - if (loadChild(toolChainElement)) { - // do nothing - } else if (toolChainElement.getName().equals(ITool.TOOL_ELEMENT_NAME)) { - Tool toolChild = new Tool(this, toolChainElement, managedBuildRevision); - addTool(toolChild); - } - } - } - - /** - * This constructor is called to create a ToolChain whose attributes and children will be - * added by separate calls. - * - * @param Configuration The parent of the tool chain, if any - * @param ToolChain The superClass, if any - * @param String The id for the new tool chain - * @param String The name for the new tool chain - * @param boolean Indicates whether this is an extension element or a managed project element - */ - public ToolChain(Configuration parent, IToolChain superClass, String Id, String name, boolean isExtensionElement) { - super(resolvedDefault); - this.parent = parent; - setSuperClass(superClass); - setManagedBuildRevision(parent.getManagedBuildRevision()); - - if (getSuperClass() != null) { - superClassId = getSuperClass().getId(); - } - setId(Id); - setName(name); - setVersion(getVersionFromId()); - - isExtensionToolChain = isExtensionElement; - if (isExtensionElement) { - // Hook me up to the Managed Build Manager - ManagedBuildManager.addExtensionToolChain(this); - } else { - setDirty(true); - } - } - - /** - * Create a ToolChain based on the specification stored in the - * project file (.cdtbuild). - * - * @param parent The IConfiguration the tool-chain will be added to. - * @param element The XML element that contains the tool-chain settings. - * @param managedBuildRevision the fileVersion of Managed Build System - */ - public ToolChain(IConfiguration parent, Element element, String managedBuildRevision) { - super(resolvedDefault); - this.parent = parent; - isExtensionToolChain = false; - - // Set the managedBuildRevision - setManagedBuildRevision(managedBuildRevision); - - // Initialize from the XML attributes - loadFromProject(element); - - // Load children - NodeList configElements = element.getChildNodes(); - for (int i = 0; i < configElements.getLength(); ++i) { - Node configElement = configElements.item(i); - if (loadChild(configElement)) { - // do nothing - } else if (configElement.getNodeName().equals(ITool.TOOL_ELEMENT_NAME)) { - Tool tool = new Tool(this, (Element)configElement, managedBuildRevision); - addTool(tool); - }else if (configElement.getNodeName().equals(ITargetPlatform.TARGET_PLATFORM_ELEMENT_NAME)) { - if (targetPlatform != null) { - // TODO: report error - } - targetPlatform = new TargetPlatform(this, (Element)configElement, managedBuildRevision); - }else if (configElement.getNodeName().equals(IBuilder.BUILDER_ELEMENT_NAME)) { - if (builder != null) { - // TODO: report error - } - builder = new Builder(this, (Element)configElement, managedBuildRevision); - }else if (configElement.getNodeName().equals(StorableMacros.MACROS_ELEMENT_NAME)) { - //load user-defined macros - userDefinedMacros = new StorableMacros((Element)configElement); - - } - } - } - - /** - * Create a ToolChain based upon an existing tool chain. - * - * @param parent The IConfiguration the tool-chain will be added to. - * @param toolChain The existing tool-chain to clone. - */ - public ToolChain(IConfiguration parent, String Id, String name, ToolChain toolChain) { - super(resolvedDefault); - this.parent = parent; - setSuperClass(toolChain.getSuperClass()); - if (getSuperClass() != null) { - if (toolChain.superClassId != null) { - superClassId = new String(toolChain.superClassId); - } - } - setId(Id); - setName(name); - - // Set the managedBuildRevision and the version - setManagedBuildRevision(toolChain.getManagedBuildRevision()); - setVersion(getVersionFromId()); - - isExtensionToolChain = false; - - // Copy the remaining attributes - if(toolChain.versionsSupported != null) { - versionsSupported = new String(toolChain.versionsSupported); - } - if(toolChain.convertToId != null) { - convertToId = new String(toolChain.convertToId); - } - - if (toolChain.unusedChildren != null) { - unusedChildren = new String(toolChain.unusedChildren); - } - if (toolChain.errorParserIds != null) { - errorParserIds = new String(toolChain.errorParserIds); - } - if (toolChain.osList != null) { - osList = new ArrayList(toolChain.osList); - } - if (toolChain.archList != null) { - archList = new ArrayList(toolChain.archList); - } - if (toolChain.targetToolIds != null) { - targetToolIds = new String(toolChain.targetToolIds); - } - if (toolChain.secondaryOutputIds != null) { - secondaryOutputIds = new String(toolChain.secondaryOutputIds); - } - if (toolChain.isAbstract != null) { - isAbstract = new Boolean(toolChain.isAbstract.booleanValue()); - } - if (toolChain.scannerConfigDiscoveryProfileId != null) { - scannerConfigDiscoveryProfileId = new String(toolChain.scannerConfigDiscoveryProfileId); - } - managedIsToolChainSupportedElement = toolChain.managedIsToolChainSupportedElement; - managedIsToolChainSupported = toolChain.managedIsToolChainSupported; - - environmentVariableSupplierElement = toolChain.environmentVariableSupplierElement; - environmentVariableSupplier = toolChain.environmentVariableSupplier; - - buildMacroSupplierElement = toolChain.buildMacroSupplierElement; - buildMacroSupplier = toolChain.buildMacroSupplier; - - // Clone the children in superclass - super.copyChildren(toolChain); - // Clone the children - if (toolChain.builder != null) { - String subId; - String subName; - - if (toolChain.builder.getSuperClass() != null) { - subId = ManagedBuildManager.calculateChildId( - toolChain.builder.getSuperClass().getId(), - null); - subName = toolChain.builder.getSuperClass().getName(); - } else { - subId = ManagedBuildManager.calculateChildId( - toolChain.builder.getId(), - null); - subName = toolChain.builder.getName(); - } - - builder = new Builder(this, subId, subName, toolChain.builder); - } - if (toolChain.targetPlatform != null) { - int nnn = ManagedBuildManager.getRandomNumber(); - String subId; - String subName; - if (toolChain.targetPlatform.getSuperClass() != null) { - subId = toolChain.targetPlatform.getSuperClass().getId() + "." + nnn; //$NON-NLS-1$ - subName = toolChain.targetPlatform.getSuperClass().getName(); - } else { - subId = toolChain.targetPlatform.getId() + "." + nnn; //$NON-NLS-1$ - subName = toolChain.targetPlatform.getName(); - } - targetPlatform = new TargetPlatform(this, subId, subName, toolChain.targetPlatform); - } - if (toolChain.toolList != null) { - Iterator iter = toolChain.getToolList().listIterator(); - while (iter.hasNext()) { - Tool toolChild = (Tool) iter.next(); - int nnn = ManagedBuildManager.getRandomNumber(); - String subId; - String tmpId; - String subName; - String version; - - if (toolChild.getSuperClass() != null) { - tmpId = toolChild.getSuperClass().getId(); - subName = toolChild.getSuperClass().getName(); - } else { - tmpId = toolChild.getId(); - subName = toolChild.getName(); - } - version = ManagedBuildManager.getVersionFromIdAndVersion(tmpId); - if ( version != null) { // If the 'tmpId' contains version information - subId = ManagedBuildManager.getIdFromIdAndVersion(tmpId) + "." + nnn + "_" + version; //$NON-NLS-1$ //$NON-NLS-2$ - } else { - subId = tmpId + "." + nnn; //$NON-NLS-1$ - } - - Tool newTool = new Tool(this, null, subId, subName, toolChild); - addTool(newTool); - } - } - - setDirty(true); - } - - /* - * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S - */ - - /* (non-Javadoc) - * Loads the tool-chain information from the ManagedConfigElement specified in the - * argument. - * - * @param element Contains the tool-chain information - */ - protected void loadFromManifest(IManagedConfigElement element) { - ManagedBuildManager.putConfigElement(this, element); - - // id - setId(element.getAttribute(IBuildObject.ID)); - - // Get the name - setName(element.getAttribute(IBuildObject.NAME)); - - // version - setVersion(getVersionFromId()); - - // superClass - superClassId = element.getAttribute(IProjectType.SUPERCLASS); - - // Get the unused children, if any - unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); - - // isAbstract - String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); - if (isAbs != null){ - isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ - } - - // Get the semicolon separated list of IDs of the error parsers - errorParserIds = element.getAttribute(ERROR_PARSERS); - - // Get the semicolon separated list of IDs of the secondary outputs - secondaryOutputIds = element.getAttribute(SECONDARY_OUTPUTS); - - // Get the target tool id - targetToolIds = element.getAttribute(TARGET_TOOL); - - // Get the scanner config discovery profile id - scannerConfigDiscoveryProfileId = element.getAttribute(SCANNER_CONFIG_PROFILE_ID); - - // Get the 'versionsSupported' attribute - versionsSupported =element.getAttribute(VERSIONS_SUPPORTED); - - // Get the 'convertToId' attribute - convertToId = element.getAttribute(CONVERT_TO_ID); - - // Get the comma-separated list of valid OS - String os = element.getAttribute(OS_LIST); - if (os != null) { - osList = new ArrayList(); - String[] osTokens = os.split(","); //$NON-NLS-1$ - for (int i = 0; i < osTokens.length; ++i) { - osList.add(osTokens[i].trim()); - } - } - - // Get the comma-separated list of valid Architectures - String arch = element.getAttribute(ARCH_LIST); - if (arch != null) { - archList = new ArrayList(); - String[] archTokens = arch.split(","); //$NON-NLS-1$ - for (int j = 0; j < archTokens.length; ++j) { - archList.add(archTokens[j].trim()); - } - } - - // Get the isToolchainSupported configuration element - String managedIsToolChainSupported = element.getAttribute(IS_TOOL_CHAIN_SUPPORTED); - if (managedIsToolChainSupported != null && element instanceof DefaultManagedConfigElement) { - managedIsToolChainSupportedElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); - } - - // Get the environmentVariableSupplier configuration element - String environmentVariableSupplier = element.getAttribute(CONFIGURATION_ENVIRONMENT_SUPPLIER); - if(environmentVariableSupplier != null && element instanceof DefaultManagedConfigElement){ - environmentVariableSupplierElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); - } - - // Get the configurationMacroSupplier configuration element - String buildMacroSupplier = element.getAttribute(CONFIGURATION_MACRO_SUPPLIER); - if(buildMacroSupplier != null && element instanceof DefaultManagedConfigElement){ - buildMacroSupplierElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); - } - - } - - - /* (non-Javadoc) - * Initialize the tool-chain information from the XML element - * specified in the argument - * - * @param element An XML element containing the tool-chain information - */ - protected void loadFromProject(Element element) { - - // id - setId(element.getAttribute(IBuildObject.ID)); - - // name - if (element.hasAttribute(IBuildObject.NAME)) { - setName(element.getAttribute(IBuildObject.NAME)); - } - - // version - setVersion(getVersionFromId()); - - // superClass - superClassId = element.getAttribute(IProjectType.SUPERCLASS); - if (superClassId != null && superClassId.length() > 0) { - setSuperClass( ManagedBuildManager.getExtensionToolChain(superClassId) ); - // Check for migration support - checkForMigrationSupport(); - } - - // Get the unused children, if any - if (element.hasAttribute(IProjectType.UNUSED_CHILDREN)) { - unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); - } - - // isAbstract - if (element.hasAttribute(IProjectType.IS_ABSTRACT)) { - String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); - if (isAbs != null){ - isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ - } - } - - // Get the semicolon separated list of IDs of the error parsers - if (element.hasAttribute(ERROR_PARSERS)) { - errorParserIds = element.getAttribute(ERROR_PARSERS); - } - - // Get the semicolon separated list of IDs of the secondary outputs - if (element.hasAttribute(SECONDARY_OUTPUTS)) { - secondaryOutputIds = element.getAttribute(SECONDARY_OUTPUTS); - } - - // Get the target tool id - if (element.hasAttribute(TARGET_TOOL)) { - targetToolIds = element.getAttribute(TARGET_TOOL); - } - - // Get the scanner config discovery profile id - if (element.hasAttribute(SCANNER_CONFIG_PROFILE_ID)) { - scannerConfigDiscoveryProfileId = element.getAttribute(SCANNER_CONFIG_PROFILE_ID); - } - - // Get the 'versionSupported' attribute - if (element.hasAttribute(VERSIONS_SUPPORTED)) { - versionsSupported = element.getAttribute(VERSIONS_SUPPORTED); - } - - // Get the 'convertToId' id - if (element.hasAttribute(CONVERT_TO_ID)) { - convertToId = element.getAttribute(CONVERT_TO_ID); - } - - // Get the comma-separated list of valid OS - if (element.hasAttribute(OS_LIST)) { - String os = element.getAttribute(OS_LIST); - if (os != null) { - osList = new ArrayList(); - String[] osTokens = os.split(","); //$NON-NLS-1$ - for (int i = 0; i < osTokens.length; ++i) { - osList.add(osTokens[i].trim()); - } - } - } - - // Get the comma-separated list of valid Architectures - if (element.hasAttribute(ARCH_LIST)) { - String arch = element.getAttribute(ARCH_LIST); - if (arch != null) { - archList = new ArrayList(); - String[] archTokens = arch.split(","); //$NON-NLS-1$ - for (int j = 0; j < archTokens.length; ++j) { - archList.add(archTokens[j].trim()); - } - } - } - } - - /** - * Persist the tool-chain to the project file. - * - * @param doc - * @param element - */ - public void serialize(Document doc, Element element) { - try { - if (getSuperClass() != null) - element.setAttribute(IProjectType.SUPERCLASS, getSuperClass().getId()); - - element.setAttribute(IBuildObject.ID, id); - - if (name != null) { - element.setAttribute(IBuildObject.NAME, name); - } - - if (unusedChildren != null) { - element.setAttribute(IProjectType.UNUSED_CHILDREN, unusedChildren); - } - - if (isAbstract != null) { - element.setAttribute(IProjectType.IS_ABSTRACT, isAbstract.toString()); - } - - if (errorParserIds != null) { - element.setAttribute(ERROR_PARSERS, errorParserIds); - } - - if (secondaryOutputIds != null) { - element.setAttribute(SECONDARY_OUTPUTS, secondaryOutputIds); - } - - if (targetToolIds != null) { - element.setAttribute(TARGET_TOOL, targetToolIds); - } - - if (scannerConfigDiscoveryProfileId != null) { - element.setAttribute(SCANNER_CONFIG_PROFILE_ID, scannerConfigDiscoveryProfileId); - } - - // versionsSupported - if (versionsSupported != null) { - element.setAttribute(VERSIONS_SUPPORTED, versionsSupported); - } - - // convertToId - if (convertToId != null) { - element.setAttribute(CONVERT_TO_ID, convertToId); - } - - if (osList != null) { - Iterator osIter = osList.listIterator(); - String listValue = EMPTY_STRING; - while (osIter.hasNext()) { - String current = (String) osIter.next(); - listValue += current; - if ((osIter.hasNext())) { - listValue += ","; //$NON-NLS-1$ - } - } - element.setAttribute(OS_LIST, listValue); - } - - if (archList != null) { - Iterator archIter = archList.listIterator(); - String listValue = EMPTY_STRING; - while (archIter.hasNext()) { - String current = (String) archIter.next(); - listValue += current; - if ((archIter.hasNext())) { - listValue += ","; //$NON-NLS-1$ - } - } - element.setAttribute(ARCH_LIST, listValue); - } - - // Serialize elements from my super class - super.serialize(doc, element); - - // Serialize my children - if (targetPlatform != null) { - Element targetPlatformElement = doc.createElement(ITargetPlatform.TARGET_PLATFORM_ELEMENT_NAME); - element.appendChild(targetPlatformElement); - targetPlatform.serialize(doc, targetPlatformElement); - } - if (builder != null) { - Element builderElement = doc.createElement(IBuilder.BUILDER_ELEMENT_NAME); - element.appendChild(builderElement); - builder.serialize(doc, builderElement); - } - List toolElements = getToolList(); - Iterator iter = toolElements.listIterator(); - while (iter.hasNext()) { - Tool tool = (Tool) iter.next(); - Element toolElement = doc.createElement(ITool.TOOL_ELEMENT_NAME); - element.appendChild(toolElement); - tool.serialize(doc, toolElement); - } - - // Note: isToolChainSupported cannot be specified in a project file because - // an IConfigurationElement is needed to load it! - if (managedIsToolChainSupportedElement != null) { - // TODO: issue warning? - } - - // Note: environmentVariableSupplier cannot be specified in a project file because - // an IConfigurationElement is needed to load it! - if(environmentVariableSupplierElement != null) { - // TODO: issue warning? - } - - // Note: buildMacroSupplier cannot be specified in a project file because - // an IConfigurationElement is needed to load it! - if(buildMacroSupplierElement != null) { - // TODO: issue warning? - } - - //serialize user-defined macros - if(userDefinedMacros != null){ - Element macrosElement = doc.createElement(StorableMacros.MACROS_ELEMENT_NAME); - element.appendChild(macrosElement); - userDefinedMacros.serialize(doc,macrosElement); - } - - if(userDefinedEnvironment != null) - EnvironmentVariableProvider.fUserSupplier.storeEnvironment(getParent(),true); - - // I am clean now - isDirty = false; - } catch (Exception e) { - // TODO: issue an error message - } -} - - /* - * P A R E N T A N D C H I L D H A N D L I N G - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#getConfiguration() - */ - public IConfiguration getParent() { - return parent; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#createTargetPlatform(ITargetPlatform, String, String, boolean) - */ - public ITargetPlatform createTargetPlatform(ITargetPlatform superClass, String id, String name, boolean isExtensionElement) { - targetPlatform = new TargetPlatform(this, superClass, id, name, isExtensionElement); - setDirty(true); - return (ITargetPlatform)targetPlatform; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#getTargetPlatform() - */ - public ITargetPlatform getTargetPlatform() { - if (targetPlatform == null) { - if (getSuperClass() != null) { - return getSuperClass().getTargetPlatform(); - } - } - return (ITargetPlatform)targetPlatform; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#removeLocalTargetPlatform() - */ - public void removeLocalTargetPlatform() { - if (targetPlatform == null) return; - targetPlatform = null; - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#createBuilder(IBuilder, String, String, boolean) - */ - public IBuilder createBuilder(IBuilder superClass, String id, String name, boolean isExtensionElement) { - builder = new Builder(this, superClass, id, name, isExtensionElement); - setDirty(true); - return (IBuilder)builder; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#getBuilder() - */ - public IBuilder getBuilder() { - if (builder == null) { - if (getSuperClass() != null) { - return getSuperClass().getBuilder(); - } - } - return (IBuilder)builder; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#removeLocalBuilder() - */ - public void removeLocalBuilder() { - if (builder == null) return; - builder = null; - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#createTool(ITool, String, String, boolean) - */ - public ITool createTool(ITool superClass, String id, String name, boolean isExtensionElement) { - Tool tool = new Tool(this, superClass, id, name, isExtensionElement); - addTool(tool); - setDirty(true); - return (ITool)tool; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#getTools() - */ - public ITool[] getTools() { - ITool[] tools = null; - // Merge our tools with our superclass' tools - if (getSuperClass() != null) { - tools = getSuperClass().getTools(); - } - // Our tools take precedence - if (tools != null) { - Iterator iter = getToolList().listIterator(); - while (iter.hasNext()) { - Tool tool = (Tool)iter.next(); - int j; - for (j = 0; j < tools.length; j++) { - if (tool.getSuperClass() != null // Remove assumption that ALL tools must have superclasses - && tool.getSuperClass().getId().equals(tools[j].getId())) { - tools[j] = tool; - break; - } - } - // No Match? Insert it (may be re-ordered) - if (j == tools.length) { - ITool[] newTools = new ITool[tools.length + 1]; - for (int k = 0; k < tools.length; k++) { - newTools[k] = tools[k]; - } - newTools[j] = tool; - tools = newTools; - } - } - } else { - tools = new ITool[getToolList().size()]; - Iterator iter = getToolList().listIterator(); - int i = 0; - while (iter.hasNext()) { - Tool tool = (Tool)iter.next(); - tools[i++] = (ITool)tool; - } - } - return tools; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getTool(java.lang.String) - */ - public ITool getTool(String id) { - Tool tool = (Tool)getToolMap().get(id); - return (ITool)tool; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getToolsBySuperClassId(java.lang.String) - */ - public ITool[] getToolsBySuperClassId(String id) { - List retTools = new ArrayList(); - if (id != null) { - // Look for a tool with this ID, or the tool(s) with a superclass with this id - ITool[] tools = getTools(); - for (int i = 0; i < tools.length; i++) { - ITool targetTool = tools[i]; - ITool tool = targetTool; - do { - if (id.equals(tool.getId())) { - retTools.add(targetTool); - break; - } - tool = tool.getSuperClass(); - } while (tool != null); - } - } - return (ITool[])retTools.toArray( new ITool[retTools.size()]); - } - - /* (non-Javadoc) - * Safe accessor for the list of tools. - * - * @return List containing the tools - */ - public List getToolList() { - if (toolList == null) { - toolList = new ArrayList(); - } - return toolList; - } - - /* (non-Javadoc) - * Safe accessor for the map of tool ids to tools - * - * @return - */ - private Map getToolMap() { - if (toolMap == null) { - toolMap = new HashMap(); - } - return toolMap; - } - - /* (non-Javadoc) - * Adds the Tool to the Tool-chain list and map - * - * @param Tool - */ - public void addTool(Tool tool) { - getToolList().add(tool); - getToolMap().put(tool.getId(), tool); - } - - /* - * M O D E L A T T R I B U T E A C C E S S O R S - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getSuperClass() - */ - public IToolChain getSuperClass() { - return (IToolChain)superClass; - } - - /* (non-Javadoc) - * Access function to set the superclass element that is defined in - * the base class. - */ - private void setSuperClass(IToolChain superClass) { - this.superClass = superClass; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#getName() - */ - public String getName() { - return (name == null && getSuperClass() != null) ? getSuperClass().getName() : name; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#isAbstract() - */ - public boolean isAbstract() { - if (isAbstract != null) { - return isAbstract.booleanValue(); - } else { - return false; // Note: no inheritance from superClass - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IToolChain#getUnusedChildren() - */ - public String getUnusedChildren() { - if (unusedChildren != null) { - return unusedChildren; - } else - return EMPTY_STRING; // Note: no inheritance from superClass - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getErrorParserIds() - */ - public String getErrorParserIds() { - String ids = errorParserIds; - if (ids == null) { - // If I have a superClass, ask it - if (getSuperClass() != null) { - ids = getSuperClass().getErrorParserIds(); - } - } - if (ids == null) { - // Collect the error parsers from my children - ids = builder.getErrorParserIds(); - ITool[] tools = getTools(); - for (int i = 0; i < tools.length; i++) { - ITool tool = tools[i]; - String toolIds = tool.getErrorParserIds(); - if (toolIds != null && toolIds.length() > 0) { - if (ids != null) { - ids += ";"; //$NON-NLS-1$ - ids += toolIds; - } else { - ids = toolIds; - } - } - } - } - return ids; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getSecondaryOutputs() - */ - public IOutputType[] getSecondaryOutputs() { - IOutputType[] types = null; - String ids = secondaryOutputIds; - if (ids == null) { - if (getSuperClass() != null) { - return getSuperClass().getSecondaryOutputs(); - } - else { - return new IOutputType[0]; - } - } - StringTokenizer tok = new StringTokenizer(ids, ";"); //$NON-NLS-1$ - types = new IOutputType[tok.countTokens()]; - ITool[] tools = getTools(); - int i = 0; - while (tok.hasMoreElements()) { - String id = tok.nextToken(); - for (int j=0; j 0) { - if (ids != null) { - ids += ";"; //$NON-NLS-1$ - ids += toolIds; - } else { - ids = toolIds; - } - } - } - } - return ids; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getErrorParserList() - */ - public String[] getErrorParserList() { - String parserIDs = getErrorParserIds(); - String[] errorParsers; - if (parserIDs != null) { - // Check for an empty string - if (parserIDs.length() == 0) { - errorParsers = new String[0]; - } else { - StringTokenizer tok = new StringTokenizer(parserIDs, ";"); //$NON-NLS-1$ - List list = new ArrayList(tok.countTokens()); - while (tok.hasMoreElements()) { - list.add(tok.nextToken()); - } - String[] strArr = {""}; //$NON-NLS-1$ - errorParsers = (String[]) list.toArray(strArr); - } - } else { - errorParsers = new String[0]; - } - return errorParsers; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getArchList() - */ - public String[] getArchList() { - if (archList == null) { - // Ask superClass for its list - if (getSuperClass() != null) { - return getSuperClass().getArchList(); - } else { - // I have no superClass and no defined list - return new String[] {"all"}; //$NON-NLS-1$ - } - } - return (String[]) archList.toArray(new String[archList.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getOSList() - */ - public String[] getOSList() { - if (osList == null) { - // Ask superClass for its list - if (getSuperClass() != null) { - return getSuperClass().getOSList(); - } else { - // I have no superClass and no defined filter list - return new String[] {"all"}; //$NON-NLS-1$ - } - } - return (String[]) osList.toArray(new String[osList.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setIsAbstract(boolean) - */ - public void setIsAbstract(boolean b) { - isAbstract = new Boolean(b); - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setErrorParserIds(String) - */ - public void setErrorParserIds(String ids) { - String currentIds = getErrorParserIds(); - if (ids == null && currentIds == null) return; - if (currentIds == null || ids == null || !(currentIds.equals(ids))) { - errorParserIds = ids; - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setSecondaryOutputs() - */ - public void setSecondaryOutputs(String newIds) { - if (secondaryOutputIds == null && newIds == null) return; - if (secondaryOutputIds == null || newIds == null || !newIds.equals(secondaryOutputIds)) { - secondaryOutputIds = newIds; - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setTargetToolIds() - */ - public void setTargetToolIds(String newIds) { - if (targetToolIds == null && newIds == null) return; - if (targetToolIds == null || newIds == null || !newIds.equals(targetToolIds)) { - targetToolIds = newIds; - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setOSList(String[]) - */ - public void setOSList(String[] OSs) { - if (osList == null) { - osList = new ArrayList(); - } else { - osList.clear(); - } - for (int i = 0; i < OSs.length; i++) { - osList.add(OSs[i]); - } - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setArchList(String[]) - */ - public void setArchList(String[] archs) { - if (archList == null) { - archList = new ArrayList(); - } else { - archList.clear(); - } - for (int i = 0; i < archs.length; i++) { - archList.add(archs[i]); - } - setDirty(true); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getScannerConfigDiscoveryProfileId() - */ - public String getScannerConfigDiscoveryProfileId() { - if (scannerConfigDiscoveryProfileId == null) { - if (getSuperClass() != null) { - return getSuperClass().getScannerConfigDiscoveryProfileId(); - } - } - return scannerConfigDiscoveryProfileId; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setScannerConfigDiscoveryProfileId(java.lang.String) - */ - public void setScannerConfigDiscoveryProfileId(String profileId) { - if (scannerConfigDiscoveryProfileId == null && profileId == null) return; - if (scannerConfigDiscoveryProfileId == null || - !scannerConfigDiscoveryProfileId.equals(profileId)) { - scannerConfigDiscoveryProfileId = profileId; - setDirty(true); - } - } - - /* - * O B J E C T S T A T E M A I N T E N A N C E - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#isExtensionElement() - */ - public boolean isExtensionElement() { - return isExtensionToolChain; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#isDirty() - */ - public boolean isDirty() { - // This shouldn't be called for an extension tool-chain - if (isExtensionToolChain) return false; - - // If I need saving, just say yes - if (isDirty) return true; - - //check whether the tool-chain - specific macros are dirty - if(userDefinedMacros != null && userDefinedMacros.isDirty()) - return true; - - if(userDefinedEnvironment != null && userDefinedEnvironment.isDirty()) - return true; - - if(builder != null && builder.isDirty()) - return true; - - // Otherwise see if any tools need saving - Iterator iter = getToolList().listIterator(); - while (iter.hasNext()) { - Tool toolChild = (Tool) iter.next(); - if (toolChild.isDirty()) return true; - } - - // Otherwise see if any options need saving - if (super.isDirty()) { - return true; - } - - return isDirty; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setDirty(boolean) - */ - public void setDirty(boolean isDirty) { - this.isDirty = isDirty; - // Propagate "false" to options - super.setDirty(isDirty); - // Propagate "false" to the children - if (!isDirty) { - Iterator iter = getToolList().listIterator(); - while (iter.hasNext()) { - Tool toolChild = (Tool) iter.next(); - toolChild.setDirty(false); - } - } - } - - /* (non-Javadoc) - * Resolve the element IDs to interface references - */ - public void resolveReferences() { - if (!resolved) { - resolved = true; - // Resolve superClass - if (superClassId != null && superClassId.length() > 0) { - setSuperClass(ManagedBuildManager.getExtensionToolChain(superClassId)); - if (getSuperClass() == null) { - // Report error - ManagedBuildManager.OutputResolveError( - "superClass", //$NON-NLS-1$ - superClassId, - "toolChain", //$NON-NLS-1$ - getId()); - } - } - // Resolve HoldsOptions - super.resolveReferences(); - // Call resolveReferences on our children - if (targetPlatform != null) { - targetPlatform.resolveReferences(); - } - if (builder != null) { - builder.resolveReferences(); - } - Iterator iter = getToolList().listIterator(); - while (iter.hasNext()) { - Tool toolChild = (Tool) iter.next(); - toolChild.resolveReferences(); - } - } - } - - /* (non-Javadoc) - * Normalize the list of output extensions,for all tools in the toolchain by populating the list - * with an empty string for those tools which have no explicit output extension (as defined in the - * manifest file. In a post 2.1 manifest, all tools must have a specifed output extension, even - * if it is "") - */ - public void normalizeOutputExtensions(){ - ITool[] tools = getTools(); - if (tools != null) { - for (int i = 0; i < tools.length; i++) { - ITool tool = tools[i]; - String[] extensions = tool.getOutputsAttribute(); - if (extensions == null) { - tool.setOutputsAttribute(""); //$NON-NLS-1$ - continue; - } - if (extensions.length == 0){ - tool.setOutputsAttribute(""); //$NON-NLS-1$ - continue; - } - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getConvertToId() - */ - public String getConvertToId() { - if (convertToId == null) { - // If I have a superClass, ask it - if (getSuperClass() != null) { - return getSuperClass().getConvertToId(); - } else { - return EMPTY_STRING; - } - } - return convertToId; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setConvertToId(String) - */ - public void setConvertToId(String convertToId) { - if (convertToId == null && this.convertToId == null) return; - if (convertToId == null || this.convertToId == null || !convertToId.equals(this.convertToId)) { - this.convertToId = convertToId; - setDirty(true); - } - return; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getVersionsSupported() - */ - public String getVersionsSupported() { - if (versionsSupported == null) { - // If I have a superClass, ask it - if (getSuperClass() != null) { - return getSuperClass().getVersionsSupported(); - } else { - return EMPTY_STRING; - } - } - return versionsSupported; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setVersionsSupported(String) - */ - public void setVersionsSupported(String versionsSupported) { - if (versionsSupported == null && this.versionsSupported == null) return; - if (versionsSupported == null || this.versionsSupported == null || !versionsSupported.equals(this.versionsSupported)) { - this.versionsSupported = versionsSupported; - setDirty(true); - } - return; - } - - private IConfigurationElement getIsToolChainSupportedElement(){ - if (managedIsToolChainSupportedElement == null) { - if (superClass != null && superClass instanceof ToolChain) { - return ((ToolChain)superClass).getIsToolChainSupportedElement(); - } - } - return managedIsToolChainSupportedElement; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#isSupported() - */ - public boolean isSupported(){ - if (managedIsToolChainSupported == null) { - IConfigurationElement element = getIsToolChainSupportedElement(); - if (element != null) { - try { - if (element.getAttribute(IS_TOOL_CHAIN_SUPPORTED) != null) { - managedIsToolChainSupported = (IManagedIsToolChainSupported) element.createExecutableExtension(IS_TOOL_CHAIN_SUPPORTED); - } - } catch (CoreException e) {} - } - } - - if(managedIsToolChainSupported != null) - return managedIsToolChainSupported.isSupported(this,null,null); - return true; - } - - /** - * Returns the plugin.xml element of the configurationEnvironmentSupplier extension or null if none. - * - * @return IConfigurationElement - */ - public IConfigurationElement getEnvironmentVariableSupplierElement(){ - if (environmentVariableSupplierElement == null) { - if (getSuperClass() != null && getSuperClass() instanceof ToolChain) { - return ((ToolChain)getSuperClass()).getEnvironmentVariableSupplierElement(); - } - } - return environmentVariableSupplierElement; - } - - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getEnvironmentVariableSupplier() - */ - public IConfigurationEnvironmentVariableSupplier getEnvironmentVariableSupplier(){ - if (environmentVariableSupplier != null) { - return environmentVariableSupplier; - } - IConfigurationElement element = getEnvironmentVariableSupplierElement(); - if (element != null) { - try { - if (element.getAttribute(CONFIGURATION_ENVIRONMENT_SUPPLIER) != null) { - environmentVariableSupplier = (IConfigurationEnvironmentVariableSupplier) element.createExecutableExtension(CONFIGURATION_ENVIRONMENT_SUPPLIER); - return environmentVariableSupplier; - } - } catch (CoreException e) {} - } - return null; - } - - /* - * this method is called by the UserDefinedMacroSupplier to obtain user-defined - * macros available for this tool-chain - */ - public StorableMacros getUserDefinedMacros(){ - if(isExtensionToolChain) - return null; - - if(userDefinedMacros == null) - userDefinedMacros = new StorableMacros(); - return userDefinedMacros; - } - - public StorableEnvironment getUserDefinedEnvironment(){ - if(isExtensionToolChain) - return null; - - return userDefinedEnvironment; - } - - public void setUserDefinedEnvironment(StorableEnvironment env){ - if(!isExtensionToolChain) - userDefinedEnvironment = env; - } - - - /** - * Returns the plugin.xml element of the configurationMacroSupplier extension or null if none. - * - * @return IConfigurationElement - */ - public IConfigurationElement getBuildMacroSupplierElement(){ - if (buildMacroSupplierElement == null) { - if (superClass != null && superClass instanceof ToolChain) { - return ((ToolChain)superClass).getBuildMacroSupplierElement(); - } - } - return buildMacroSupplierElement; - } - - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getBuildMacroSupplier() - */ - public IConfigurationBuildMacroSupplier getBuildMacroSupplier(){ - if (buildMacroSupplier != null) { - return buildMacroSupplier; - } - IConfigurationElement element = getBuildMacroSupplierElement(); - if (element != null) { - try { - if (element.getAttribute(CONFIGURATION_MACRO_SUPPLIER) != null) { - buildMacroSupplier = (IConfigurationBuildMacroSupplier) element.createExecutableExtension(CONFIGURATION_MACRO_SUPPLIER); - return buildMacroSupplier; - } - } catch (CoreException e) {} - } - return null; - } - - /* - * This function checks for migration support for the toolchain, while - * loading. If migration support is needed, looks for the available - * converters and adds them to the list. - */ - - public void checkForMigrationSupport() { - - boolean isExists = false; - - if (getSuperClass() == null) { - // If 'getSuperClass()' is null, then there is no toolchain available in - // plugin manifest file with the 'id' & version. - // Look for the 'versionsSupported' attribute - String high = (String) ManagedBuildManager - .getExtensionToolChainMap().lastKey(); - - SortedMap subMap = null; - if (superClassId.compareTo(high) <= 0) { - subMap = ManagedBuildManager.getExtensionToolChainMap().subMap( - superClassId, high + "\0"); //$NON-NLS-1$ - } else { - // It means there are no entries in the map for the given id. - // make the project is invalid - IConfiguration parentConfig = getParent(); - IManagedProject managedProject = parentConfig.getManagedProject(); - if (managedProject != null) { - managedProject.setValid(false); - } - return; - } - - // for each element in the 'subMap', - // check the 'versionsSupported' attribute whether the given - // toolChain version is supported - - String baseId = ManagedBuildManager.getIdFromIdAndVersion(superClassId); - String version = getVersionFromId().toString(); - - IToolChain[] toolChainElements = (IToolChain[]) subMap.values().toArray(); - - for (int i = 0; i < toolChainElements.length; i++) { - IToolChain toolChainElement = toolChainElements[i]; - - if (ManagedBuildManager.getIdFromIdAndVersion( - toolChainElement.getId()).compareTo(baseId) > 0) - break; - - // First check if both base ids are equal - if (ManagedBuildManager.getIdFromIdAndVersion( - toolChainElement.getId()).equals(baseId)) { - - // Check if 'versionsSupported' attribute is available' - String versionsSupported = toolChainElement.getVersionsSupported(); - - if ((versionsSupported != null) - && (!versionsSupported.equals(""))) { //$NON-NLS-1$ - String[] tmpVersions = versionsSupported.split(","); //$NON-NLS-1$ - - for (int j = 0; j < tmpVersions.length; j++) { - if (new PluginVersionIdentifier(version).equals(new PluginVersionIdentifier(tmpVersions[j]))) { - // version is supported. - // Do the automatic conversion without - // prompting the user. - // Get the supported version - String supportedVersion = ManagedBuildManager.getVersionFromIdAndVersion( - toolChainElement.getId()); - setId(ManagedBuildManager.getIdFromIdAndVersion(getId()) - + "_" + supportedVersion); //$NON-NLS-1$ - - // If control comes here means that 'superClass' is null - // So, set the superClass to this toolChain element - setSuperClass(toolChainElement); - superClassId = getSuperClass().getId(); - isExists = true; - break; - } - } - if(isExists) - break; // break the outer for loop if 'isExists' is true - } - } - } - } - - if (getSuperClass() != null) { - // If 'getSuperClass()' is not null, look for 'convertToId' attribute in plugin - // manifest file for this toolchain. - String convertToId = getSuperClass().getConvertToId(); - if ((convertToId == null) || (convertToId.equals(""))) { //$NON-NLS-1$ - // It means there is no 'convertToId' attribute available and - // the version is still actively - // supported by the tool integrator. So do nothing, just return - return; - } else { - // In case the 'convertToId' attribute is available, - // it means that Tool integrator currently does not support this - // version of toolchain. - // Look for the converters available for this toolchain version. - - getConverter(convertToId); - } - - } else { - // make the project is invalid - // - IConfiguration parentConfig = getParent(); - IManagedProject managedProject = parentConfig.getManagedProject(); - if (managedProject != null) { - managedProject.setValid(false); - } - } - return; - } - - private void getConverter(String convertToId) { - - String fromId = null; - String toId = null; - - // Get the Converter Extension Point - IExtensionPoint extensionPoint = Platform.getExtensionRegistry() - .getExtensionPoint("org.eclipse.cdt.managedbuilder.core", //$NON-NLS-1$ - "projectConverter"); //$NON-NLS-1$ - if (extensionPoint != null) { - // Get the extensions - IExtension[] extensions = extensionPoint.getExtensions(); - for (int i = 0; i < extensions.length; i++) { - // Get the configuration elements of each extension - IConfigurationElement[] configElements = extensions[i] - .getConfigurationElements(); - for (int j = 0; j < configElements.length; j++) { - - IConfigurationElement element = configElements[j]; - - if (element.getName().equals("converter")) { //$NON-NLS-1$ - - fromId = element.getAttribute("fromId"); //$NON-NLS-1$ - toId = element.getAttribute("toId"); //$NON-NLS-1$ - // Check whether the current converter can be used for - // the selected toolchain - - if (fromId.equals(getSuperClass().getId()) - && toId.equals(convertToId)) { - // If it matches - String mbsVersion = element - .getAttribute("mbsVersion"); //$NON-NLS-1$ - PluginVersionIdentifier currentMbsVersion = ManagedBuildManager - .getBuildInfoVersion(); - - // set the converter element based on the MbsVersion - if (currentMbsVersion - .isGreaterThan(new PluginVersionIdentifier( - mbsVersion))) { - previousMbsVersionConversionElement = element; - } else { - currentMbsVersionConversionElement = element; - } - return; - } - } - } - } - } - - // If control comes here, it means 'Tool Integrator' specified - // 'convertToId' attribute in toolchain definition file, but - // has not provided any converter. - // So, make the project is invalid - - IConfiguration parentConfig = getParent(); - IManagedProject managedProject = parentConfig.getManagedProject(); - if (managedProject != null) { - managedProject.setValid(false); - } - } - - - public IConfigurationElement getPreviousMbsVersionConversionElement() { - return previousMbsVersionConversionElement; - } - - public IConfigurationElement getCurrentMbsVersionConversionElement() { - return currentMbsVersionConversionElement; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.internal.core.BuildObject#updateManagedBuildRevision(java.lang.String) - */ - public void updateManagedBuildRevision(String revision){ - super.updateManagedBuildRevision(revision); - - for(Iterator iter = getToolList().iterator(); iter.hasNext();){ - ((Tool)iter.next()).updateManagedBuildRevision(revision); - } - - if(builder != null) - builder.updateManagedBuildRevision(revision); - } - -} +/******************************************************************************* + * Copyright (c) 2004, 2005 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.core; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.SortedMap; +import java.util.StringTokenizer; + +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IBuilder; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; +import org.eclipse.cdt.managedbuilder.core.IManagedIsToolChainSupported; +import org.eclipse.cdt.managedbuilder.core.IManagedProject; +import org.eclipse.cdt.managedbuilder.core.IOutputType; +import org.eclipse.cdt.managedbuilder.core.IProjectType; +import org.eclipse.cdt.managedbuilder.core.ITargetPlatform; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier; +import org.eclipse.cdt.managedbuilder.internal.envvar.EnvironmentVariableProvider; +import org.eclipse.cdt.managedbuilder.internal.envvar.StorableEnvironment; +import org.eclipse.cdt.managedbuilder.internal.macros.StorableMacros; +import org.eclipse.cdt.managedbuilder.macros.IConfigurationBuildMacroSupplier; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.PluginVersionIdentifier; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class ToolChain extends HoldsOptions implements IToolChain { + + private static final String EMPTY_STRING = new String(); + + private static final boolean resolvedDefault = true; + + // Superclass + // Note that superClass itself is defined in the base and that the methods + // getSuperClass() and setSuperClassInternal(), defined in ToolChain must be used + // to access it. This avoids widespread casts from IHoldsOptions to IToolChain. + private String superClassId; + // Parent and children + private IConfiguration parent; + private List toolList; + private Map toolMap; + private TargetPlatform targetPlatform; + private Builder builder; + // Managed Build model attributes + private String unusedChildren; + private String errorParserIds; + private List osList; + private List archList; + private String targetToolIds; + private String secondaryOutputIds; + private Boolean isAbstract; + private String scannerConfigDiscoveryProfileId; + private String versionsSupported; + private String convertToId; + private IConfigurationElement managedIsToolChainSupportedElement = null; + private IManagedIsToolChainSupported managedIsToolChainSupported = null; + private IConfigurationElement environmentVariableSupplierElement = null; + private IConfigurationEnvironmentVariableSupplier environmentVariableSupplier = null; + private IConfigurationElement buildMacroSupplierElement = null; + private IConfigurationBuildMacroSupplier buildMacroSupplier = null; + + // Miscellaneous + private boolean isExtensionToolChain = false; + private boolean isDirty = false; + private boolean resolved = resolvedDefault; + //holds the user-defined macros + private StorableMacros userDefinedMacros; + //holds user-defined macros + private StorableEnvironment userDefinedEnvironment; + + private IConfigurationElement previousMbsVersionConversionElement = null; + private IConfigurationElement currentMbsVersionConversionElement = null; + + /* + * C O N S T R U C T O R S + */ + + /** + * This constructor is called to create a tool-chain defined by an extension point in + * a plugin manifest file, or returned by a dynamic element provider + * + * @param parent The IConfiguration parent of this tool-chain, or null if + * defined at the top level + * @param element The tool-chain definition from the manifest file or a dynamic element + * provider + * @param managedBuildRevision the fileVersion of Managed Build System + */ + public ToolChain(IConfiguration parent, IManagedConfigElement element, String managedBuildRevision) { + // setup for resolving + super(false); + resolved = false; + + this.parent = parent; + isExtensionToolChain = true; + + // Set the managedBuildRevision + setManagedBuildRevision(managedBuildRevision); + + loadFromManifest(element); + + // Hook me up to the Managed Build Manager + ManagedBuildManager.addExtensionToolChain(this); + + // Load the TargetPlatform child + IManagedConfigElement[] targetPlatforms = + element.getChildren(ITargetPlatform.TARGET_PLATFORM_ELEMENT_NAME); + if (targetPlatforms.length < 1 || targetPlatforms.length > 1) { + // TODO: Report error + } + if (targetPlatforms.length > 0) { + targetPlatform = new TargetPlatform(this, targetPlatforms[0], managedBuildRevision); + } + + // Load the Builder child + IManagedConfigElement[] builders = + element.getChildren(IBuilder.BUILDER_ELEMENT_NAME); + if (builders.length < 1 || builders.length > 1) { + // TODO: Report error + } + if (builders.length > 0) { + builder = new Builder(this, builders[0], managedBuildRevision); + } + + // Load children + IManagedConfigElement[] toolChainElements = element.getChildren(); + for (int l = 0; l < toolChainElements.length; ++l) { + IManagedConfigElement toolChainElement = toolChainElements[l]; + if (loadChild(toolChainElement)) { + // do nothing + } else if (toolChainElement.getName().equals(ITool.TOOL_ELEMENT_NAME)) { + Tool toolChild = new Tool(this, toolChainElement, managedBuildRevision); + addTool(toolChild); + } + } + } + + /** + * This constructor is called to create a ToolChain whose attributes and children will be + * added by separate calls. + * + * @param Configuration The parent of the tool chain, if any + * @param ToolChain The superClass, if any + * @param String The id for the new tool chain + * @param String The name for the new tool chain + * @param boolean Indicates whether this is an extension element or a managed project element + */ + public ToolChain(Configuration parent, IToolChain superClass, String Id, String name, boolean isExtensionElement) { + super(resolvedDefault); + this.parent = parent; + setSuperClassInternal(superClass); + setManagedBuildRevision(parent.getManagedBuildRevision()); + + if (getSuperClass() != null) { + superClassId = getSuperClass().getId(); + } + setId(Id); + setName(name); + setVersion(getVersionFromId()); + + isExtensionToolChain = isExtensionElement; + if (isExtensionElement) { + // Hook me up to the Managed Build Manager + ManagedBuildManager.addExtensionToolChain(this); + } else { + setDirty(true); + } + } + + /** + * Create a ToolChain based on the specification stored in the + * project file (.cdtbuild). + * + * @param parent The IConfiguration the tool-chain will be added to. + * @param element The XML element that contains the tool-chain settings. + * @param managedBuildRevision the fileVersion of Managed Build System + */ + public ToolChain(IConfiguration parent, Element element, String managedBuildRevision) { + super(resolvedDefault); + this.parent = parent; + isExtensionToolChain = false; + + // Set the managedBuildRevision + setManagedBuildRevision(managedBuildRevision); + + // Initialize from the XML attributes + loadFromProject(element); + + // Load children + NodeList configElements = element.getChildNodes(); + for (int i = 0; i < configElements.getLength(); ++i) { + Node configElement = configElements.item(i); + if (loadChild(configElement)) { + // do nothing + } else if (configElement.getNodeName().equals(ITool.TOOL_ELEMENT_NAME)) { + Tool tool = new Tool(this, (Element)configElement, managedBuildRevision); + addTool(tool); + }else if (configElement.getNodeName().equals(ITargetPlatform.TARGET_PLATFORM_ELEMENT_NAME)) { + if (targetPlatform != null) { + // TODO: report error + } + targetPlatform = new TargetPlatform(this, (Element)configElement, managedBuildRevision); + }else if (configElement.getNodeName().equals(IBuilder.BUILDER_ELEMENT_NAME)) { + if (builder != null) { + // TODO: report error + } + builder = new Builder(this, (Element)configElement, managedBuildRevision); + }else if (configElement.getNodeName().equals(StorableMacros.MACROS_ELEMENT_NAME)) { + //load user-defined macros + userDefinedMacros = new StorableMacros((Element)configElement); + + } + } + } + + /** + * Create a ToolChain based upon an existing tool chain. + * + * @param parent The IConfiguration the tool-chain will be added to. + * @param toolChain The existing tool-chain to clone. + */ + public ToolChain(IConfiguration parent, String Id, String name, ToolChain toolChain) { + super(resolvedDefault); + this.parent = parent; + setSuperClassInternal(toolChain.getSuperClass()); + if (getSuperClass() != null) { + if (toolChain.superClassId != null) { + superClassId = new String(toolChain.superClassId); + } + } + setId(Id); + setName(name); + + // Set the managedBuildRevision and the version + setManagedBuildRevision(toolChain.getManagedBuildRevision()); + setVersion(getVersionFromId()); + + isExtensionToolChain = false; + + // Copy the remaining attributes + if(toolChain.versionsSupported != null) { + versionsSupported = new String(toolChain.versionsSupported); + } + if(toolChain.convertToId != null) { + convertToId = new String(toolChain.convertToId); + } + + if (toolChain.unusedChildren != null) { + unusedChildren = new String(toolChain.unusedChildren); + } + if (toolChain.errorParserIds != null) { + errorParserIds = new String(toolChain.errorParserIds); + } + if (toolChain.osList != null) { + osList = new ArrayList(toolChain.osList); + } + if (toolChain.archList != null) { + archList = new ArrayList(toolChain.archList); + } + if (toolChain.targetToolIds != null) { + targetToolIds = new String(toolChain.targetToolIds); + } + if (toolChain.secondaryOutputIds != null) { + secondaryOutputIds = new String(toolChain.secondaryOutputIds); + } + if (toolChain.isAbstract != null) { + isAbstract = new Boolean(toolChain.isAbstract.booleanValue()); + } + if (toolChain.scannerConfigDiscoveryProfileId != null) { + scannerConfigDiscoveryProfileId = new String(toolChain.scannerConfigDiscoveryProfileId); + } + managedIsToolChainSupportedElement = toolChain.managedIsToolChainSupportedElement; + managedIsToolChainSupported = toolChain.managedIsToolChainSupported; + + environmentVariableSupplierElement = toolChain.environmentVariableSupplierElement; + environmentVariableSupplier = toolChain.environmentVariableSupplier; + + buildMacroSupplierElement = toolChain.buildMacroSupplierElement; + buildMacroSupplier = toolChain.buildMacroSupplier; + + // Clone the children in superclass + super.copyChildren(toolChain); + // Clone the children + if (toolChain.builder != null) { + String subId; + String subName; + + if (toolChain.builder.getSuperClass() != null) { + subId = ManagedBuildManager.calculateChildId( + toolChain.builder.getSuperClass().getId(), + null); + subName = toolChain.builder.getSuperClass().getName(); + } else { + subId = ManagedBuildManager.calculateChildId( + toolChain.builder.getId(), + null); + subName = toolChain.builder.getName(); + } + + builder = new Builder(this, subId, subName, toolChain.builder); + } + if (toolChain.targetPlatform != null) { + int nnn = ManagedBuildManager.getRandomNumber(); + String subId; + String subName; + if (toolChain.targetPlatform.getSuperClass() != null) { + subId = toolChain.targetPlatform.getSuperClass().getId() + "." + nnn; //$NON-NLS-1$ + subName = toolChain.targetPlatform.getSuperClass().getName(); + } else { + subId = toolChain.targetPlatform.getId() + "." + nnn; //$NON-NLS-1$ + subName = toolChain.targetPlatform.getName(); + } + targetPlatform = new TargetPlatform(this, subId, subName, toolChain.targetPlatform); + } + if (toolChain.toolList != null) { + Iterator iter = toolChain.getToolList().listIterator(); + while (iter.hasNext()) { + Tool toolChild = (Tool) iter.next(); + int nnn = ManagedBuildManager.getRandomNumber(); + String subId; + String tmpId; + String subName; + String version; + + if (toolChild.getSuperClass() != null) { + tmpId = toolChild.getSuperClass().getId(); + subName = toolChild.getSuperClass().getName(); + } else { + tmpId = toolChild.getId(); + subName = toolChild.getName(); + } + version = ManagedBuildManager.getVersionFromIdAndVersion(tmpId); + if ( version != null) { // If the 'tmpId' contains version information + subId = ManagedBuildManager.getIdFromIdAndVersion(tmpId) + "." + nnn + "_" + version; //$NON-NLS-1$ //$NON-NLS-2$ + } else { + subId = tmpId + "." + nnn; //$NON-NLS-1$ + } + + Tool newTool = new Tool(this, null, subId, subName, toolChild); + addTool(newTool); + } + } + + setDirty(true); + } + + /* + * E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S + */ + + /* (non-Javadoc) + * Loads the tool-chain information from the ManagedConfigElement specified in the + * argument. + * + * @param element Contains the tool-chain information + */ + protected void loadFromManifest(IManagedConfigElement element) { + ManagedBuildManager.putConfigElement(this, element); + + // id + setId(element.getAttribute(IBuildObject.ID)); + + // Get the name + setName(element.getAttribute(IBuildObject.NAME)); + + // version + setVersion(getVersionFromId()); + + // superClass + superClassId = element.getAttribute(IProjectType.SUPERCLASS); + + // Get the unused children, if any + unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); + + // isAbstract + String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); + if (isAbs != null){ + isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ + } + + // Get the semicolon separated list of IDs of the error parsers + errorParserIds = element.getAttribute(ERROR_PARSERS); + + // Get the semicolon separated list of IDs of the secondary outputs + secondaryOutputIds = element.getAttribute(SECONDARY_OUTPUTS); + + // Get the target tool id + targetToolIds = element.getAttribute(TARGET_TOOL); + + // Get the scanner config discovery profile id + scannerConfigDiscoveryProfileId = element.getAttribute(SCANNER_CONFIG_PROFILE_ID); + + // Get the 'versionsSupported' attribute + versionsSupported =element.getAttribute(VERSIONS_SUPPORTED); + + // Get the 'convertToId' attribute + convertToId = element.getAttribute(CONVERT_TO_ID); + + // Get the comma-separated list of valid OS + String os = element.getAttribute(OS_LIST); + if (os != null) { + osList = new ArrayList(); + String[] osTokens = os.split(","); //$NON-NLS-1$ + for (int i = 0; i < osTokens.length; ++i) { + osList.add(osTokens[i].trim()); + } + } + + // Get the comma-separated list of valid Architectures + String arch = element.getAttribute(ARCH_LIST); + if (arch != null) { + archList = new ArrayList(); + String[] archTokens = arch.split(","); //$NON-NLS-1$ + for (int j = 0; j < archTokens.length; ++j) { + archList.add(archTokens[j].trim()); + } + } + + // Get the isToolchainSupported configuration element + String managedIsToolChainSupported = element.getAttribute(IS_TOOL_CHAIN_SUPPORTED); + if (managedIsToolChainSupported != null && element instanceof DefaultManagedConfigElement) { + managedIsToolChainSupportedElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); + } + + // Get the environmentVariableSupplier configuration element + String environmentVariableSupplier = element.getAttribute(CONFIGURATION_ENVIRONMENT_SUPPLIER); + if(environmentVariableSupplier != null && element instanceof DefaultManagedConfigElement){ + environmentVariableSupplierElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); + } + + // Get the configurationMacroSupplier configuration element + String buildMacroSupplier = element.getAttribute(CONFIGURATION_MACRO_SUPPLIER); + if(buildMacroSupplier != null && element instanceof DefaultManagedConfigElement){ + buildMacroSupplierElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); + } + + } + + + /* (non-Javadoc) + * Initialize the tool-chain information from the XML element + * specified in the argument + * + * @param element An XML element containing the tool-chain information + */ + protected void loadFromProject(Element element) { + + // id + setId(element.getAttribute(IBuildObject.ID)); + + // name + if (element.hasAttribute(IBuildObject.NAME)) { + setName(element.getAttribute(IBuildObject.NAME)); + } + + // version + setVersion(getVersionFromId()); + + // superClass + superClassId = element.getAttribute(IProjectType.SUPERCLASS); + if (superClassId != null && superClassId.length() > 0) { + setSuperClassInternal( ManagedBuildManager.getExtensionToolChain(superClassId) ); + // Check for migration support + checkForMigrationSupport(); + } + + // Get the unused children, if any + if (element.hasAttribute(IProjectType.UNUSED_CHILDREN)) { + unusedChildren = element.getAttribute(IProjectType.UNUSED_CHILDREN); + } + + // isAbstract + if (element.hasAttribute(IProjectType.IS_ABSTRACT)) { + String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); + if (isAbs != null){ + isAbstract = new Boolean("true".equals(isAbs)); //$NON-NLS-1$ + } + } + + // Get the semicolon separated list of IDs of the error parsers + if (element.hasAttribute(ERROR_PARSERS)) { + errorParserIds = element.getAttribute(ERROR_PARSERS); + } + + // Get the semicolon separated list of IDs of the secondary outputs + if (element.hasAttribute(SECONDARY_OUTPUTS)) { + secondaryOutputIds = element.getAttribute(SECONDARY_OUTPUTS); + } + + // Get the target tool id + if (element.hasAttribute(TARGET_TOOL)) { + targetToolIds = element.getAttribute(TARGET_TOOL); + } + + // Get the scanner config discovery profile id + if (element.hasAttribute(SCANNER_CONFIG_PROFILE_ID)) { + scannerConfigDiscoveryProfileId = element.getAttribute(SCANNER_CONFIG_PROFILE_ID); + } + + // Get the 'versionSupported' attribute + if (element.hasAttribute(VERSIONS_SUPPORTED)) { + versionsSupported = element.getAttribute(VERSIONS_SUPPORTED); + } + + // Get the 'convertToId' id + if (element.hasAttribute(CONVERT_TO_ID)) { + convertToId = element.getAttribute(CONVERT_TO_ID); + } + + // Get the comma-separated list of valid OS + if (element.hasAttribute(OS_LIST)) { + String os = element.getAttribute(OS_LIST); + if (os != null) { + osList = new ArrayList(); + String[] osTokens = os.split(","); //$NON-NLS-1$ + for (int i = 0; i < osTokens.length; ++i) { + osList.add(osTokens[i].trim()); + } + } + } + + // Get the comma-separated list of valid Architectures + if (element.hasAttribute(ARCH_LIST)) { + String arch = element.getAttribute(ARCH_LIST); + if (arch != null) { + archList = new ArrayList(); + String[] archTokens = arch.split(","); //$NON-NLS-1$ + for (int j = 0; j < archTokens.length; ++j) { + archList.add(archTokens[j].trim()); + } + } + } + } + + /** + * Persist the tool-chain to the project file. + * + * @param doc + * @param element + */ + public void serialize(Document doc, Element element) { + try { + if (getSuperClass() != null) + element.setAttribute(IProjectType.SUPERCLASS, getSuperClass().getId()); + + element.setAttribute(IBuildObject.ID, id); + + if (name != null) { + element.setAttribute(IBuildObject.NAME, name); + } + + if (unusedChildren != null) { + element.setAttribute(IProjectType.UNUSED_CHILDREN, unusedChildren); + } + + if (isAbstract != null) { + element.setAttribute(IProjectType.IS_ABSTRACT, isAbstract.toString()); + } + + if (errorParserIds != null) { + element.setAttribute(ERROR_PARSERS, errorParserIds); + } + + if (secondaryOutputIds != null) { + element.setAttribute(SECONDARY_OUTPUTS, secondaryOutputIds); + } + + if (targetToolIds != null) { + element.setAttribute(TARGET_TOOL, targetToolIds); + } + + if (scannerConfigDiscoveryProfileId != null) { + element.setAttribute(SCANNER_CONFIG_PROFILE_ID, scannerConfigDiscoveryProfileId); + } + + // versionsSupported + if (versionsSupported != null) { + element.setAttribute(VERSIONS_SUPPORTED, versionsSupported); + } + + // convertToId + if (convertToId != null) { + element.setAttribute(CONVERT_TO_ID, convertToId); + } + + if (osList != null) { + Iterator osIter = osList.listIterator(); + String listValue = EMPTY_STRING; + while (osIter.hasNext()) { + String current = (String) osIter.next(); + listValue += current; + if ((osIter.hasNext())) { + listValue += ","; //$NON-NLS-1$ + } + } + element.setAttribute(OS_LIST, listValue); + } + + if (archList != null) { + Iterator archIter = archList.listIterator(); + String listValue = EMPTY_STRING; + while (archIter.hasNext()) { + String current = (String) archIter.next(); + listValue += current; + if ((archIter.hasNext())) { + listValue += ","; //$NON-NLS-1$ + } + } + element.setAttribute(ARCH_LIST, listValue); + } + + // Serialize elements from my super class + super.serialize(doc, element); + + // Serialize my children + if (targetPlatform != null) { + Element targetPlatformElement = doc.createElement(ITargetPlatform.TARGET_PLATFORM_ELEMENT_NAME); + element.appendChild(targetPlatformElement); + targetPlatform.serialize(doc, targetPlatformElement); + } + if (builder != null) { + Element builderElement = doc.createElement(IBuilder.BUILDER_ELEMENT_NAME); + element.appendChild(builderElement); + builder.serialize(doc, builderElement); + } + List toolElements = getToolList(); + Iterator iter = toolElements.listIterator(); + while (iter.hasNext()) { + Tool tool = (Tool) iter.next(); + Element toolElement = doc.createElement(ITool.TOOL_ELEMENT_NAME); + element.appendChild(toolElement); + tool.serialize(doc, toolElement); + } + + // Note: isToolChainSupported cannot be specified in a project file because + // an IConfigurationElement is needed to load it! + if (managedIsToolChainSupportedElement != null) { + // TODO: issue warning? + } + + // Note: environmentVariableSupplier cannot be specified in a project file because + // an IConfigurationElement is needed to load it! + if(environmentVariableSupplierElement != null) { + // TODO: issue warning? + } + + // Note: buildMacroSupplier cannot be specified in a project file because + // an IConfigurationElement is needed to load it! + if(buildMacroSupplierElement != null) { + // TODO: issue warning? + } + + //serialize user-defined macros + if(userDefinedMacros != null){ + Element macrosElement = doc.createElement(StorableMacros.MACROS_ELEMENT_NAME); + element.appendChild(macrosElement); + userDefinedMacros.serialize(doc,macrosElement); + } + + if(userDefinedEnvironment != null) + EnvironmentVariableProvider.fUserSupplier.storeEnvironment(getParent(),true); + + // I am clean now + isDirty = false; + } catch (Exception e) { + // TODO: issue an error message + } +} + + /* + * P A R E N T A N D C H I L D H A N D L I N G + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#getConfiguration() + */ + public IConfiguration getParent() { + return parent; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#createTargetPlatform(ITargetPlatform, String, String, boolean) + */ + public ITargetPlatform createTargetPlatform(ITargetPlatform superClass, String id, String name, boolean isExtensionElement) { + targetPlatform = new TargetPlatform(this, superClass, id, name, isExtensionElement); + setDirty(true); + return (ITargetPlatform)targetPlatform; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#getTargetPlatform() + */ + public ITargetPlatform getTargetPlatform() { + if (targetPlatform == null) { + if (getSuperClass() != null) { + return getSuperClass().getTargetPlatform(); + } + } + return (ITargetPlatform)targetPlatform; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#removeLocalTargetPlatform() + */ + public void removeLocalTargetPlatform() { + if (targetPlatform == null) return; + targetPlatform = null; + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#createBuilder(IBuilder, String, String, boolean) + */ + public IBuilder createBuilder(IBuilder superClass, String id, String name, boolean isExtensionElement) { + builder = new Builder(this, superClass, id, name, isExtensionElement); + setDirty(true); + return (IBuilder)builder; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#getBuilder() + */ + public IBuilder getBuilder() { + if (builder == null) { + if (getSuperClass() != null) { + return getSuperClass().getBuilder(); + } + } + return (IBuilder)builder; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#removeLocalBuilder() + */ + public void removeLocalBuilder() { + if (builder == null) return; + builder = null; + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#createTool(ITool, String, String, boolean) + */ + public ITool createTool(ITool superClass, String id, String name, boolean isExtensionElement) { + Tool tool = new Tool(this, superClass, id, name, isExtensionElement); + addTool(tool); + setDirty(true); + return (ITool)tool; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#getTools() + */ + public ITool[] getTools() { + ITool[] tools = null; + // Merge our tools with our superclass' tools + if (getSuperClass() != null) { + tools = getSuperClass().getTools(); + } + // Our tools take precedence + if (tools != null) { + Iterator iter = getToolList().listIterator(); + while (iter.hasNext()) { + Tool tool = (Tool)iter.next(); + int j; + for (j = 0; j < tools.length; j++) { + if (tool.getSuperClass() != null // Remove assumption that ALL tools must have superclasses + && tool.getSuperClass().getId().equals(tools[j].getId())) { + tools[j] = tool; + break; + } + } + // No Match? Insert it (may be re-ordered) + if (j == tools.length) { + ITool[] newTools = new ITool[tools.length + 1]; + for (int k = 0; k < tools.length; k++) { + newTools[k] = tools[k]; + } + newTools[j] = tool; + tools = newTools; + } + } + } else { + tools = new ITool[getToolList().size()]; + Iterator iter = getToolList().listIterator(); + int i = 0; + while (iter.hasNext()) { + Tool tool = (Tool)iter.next(); + tools[i++] = (ITool)tool; + } + } + return tools; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getTool(java.lang.String) + */ + public ITool getTool(String id) { + Tool tool = (Tool)getToolMap().get(id); + return (ITool)tool; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getToolsBySuperClassId(java.lang.String) + */ + public ITool[] getToolsBySuperClassId(String id) { + List retTools = new ArrayList(); + if (id != null) { + // Look for a tool with this ID, or the tool(s) with a superclass with this id + ITool[] tools = getTools(); + for (int i = 0; i < tools.length; i++) { + ITool targetTool = tools[i]; + ITool tool = targetTool; + do { + if (id.equals(tool.getId())) { + retTools.add(targetTool); + break; + } + tool = tool.getSuperClass(); + } while (tool != null); + } + } + return (ITool[])retTools.toArray( new ITool[retTools.size()]); + } + + /* (non-Javadoc) + * Safe accessor for the list of tools. + * + * @return List containing the tools + */ + public List getToolList() { + if (toolList == null) { + toolList = new ArrayList(); + } + return toolList; + } + + /* (non-Javadoc) + * Safe accessor for the map of tool ids to tools + * + * @return + */ + private Map getToolMap() { + if (toolMap == null) { + toolMap = new HashMap(); + } + return toolMap; + } + + /* (non-Javadoc) + * Adds the Tool to the Tool-chain list and map + * + * @param Tool + */ + public void addTool(Tool tool) { + getToolList().add(tool); + getToolMap().put(tool.getId(), tool); + } + + /* + * M O D E L A T T R I B U T E A C C E S S O R S + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getSuperClass() + */ + public IToolChain getSuperClass() { + return (IToolChain)superClass; + } + + /* (non-Javadoc) + * Access function to set the superclass element that is defined in + * the base class. + */ + private void setSuperClassInternal(IToolChain superClass) { + this.superClass = superClass; + } + + public void setSuperClass(IToolChain superClass) { + if ( this.superClass != superClass ) { + this.superClass = superClass; + if ( this.superClass == null) { + superClassId = null; + } else { + superClassId = this.superClass.getId(); + } + + if(!isExtensionElement()) + setDirty(true); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#getName() + */ + public String getName() { + return (name == null && getSuperClass() != null) ? getSuperClass().getName() : name; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#isAbstract() + */ + public boolean isAbstract() { + if (isAbstract != null) { + return isAbstract.booleanValue(); + } else { + return false; // Note: no inheritance from superClass + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IToolChain#getUnusedChildren() + */ + public String getUnusedChildren() { + if (unusedChildren != null) { + return unusedChildren; + } else + return EMPTY_STRING; // Note: no inheritance from superClass + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getErrorParserIds() + */ + public String getErrorParserIds() { + String ids = errorParserIds; + if (ids == null) { + // If I have a superClass, ask it + if (getSuperClass() != null) { + ids = getSuperClass().getErrorParserIds(); + } + } + if (ids == null) { + // Collect the error parsers from my children + ids = builder.getErrorParserIds(); + ITool[] tools = getTools(); + for (int i = 0; i < tools.length; i++) { + ITool tool = tools[i]; + String toolIds = tool.getErrorParserIds(); + if (toolIds != null && toolIds.length() > 0) { + if (ids != null) { + ids += ";"; //$NON-NLS-1$ + ids += toolIds; + } else { + ids = toolIds; + } + } + } + } + return ids; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getSecondaryOutputs() + */ + public IOutputType[] getSecondaryOutputs() { + IOutputType[] types = null; + String ids = secondaryOutputIds; + if (ids == null) { + if (getSuperClass() != null) { + return getSuperClass().getSecondaryOutputs(); + } + else { + return new IOutputType[0]; + } + } + StringTokenizer tok = new StringTokenizer(ids, ";"); //$NON-NLS-1$ + types = new IOutputType[tok.countTokens()]; + ITool[] tools = getTools(); + int i = 0; + while (tok.hasMoreElements()) { + String id = tok.nextToken(); + for (int j=0; j 0) { + if (ids != null) { + ids += ";"; //$NON-NLS-1$ + ids += toolIds; + } else { + ids = toolIds; + } + } + } + } + return ids; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getErrorParserList() + */ + public String[] getErrorParserList() { + String parserIDs = getErrorParserIds(); + String[] errorParsers; + if (parserIDs != null) { + // Check for an empty string + if (parserIDs.length() == 0) { + errorParsers = new String[0]; + } else { + StringTokenizer tok = new StringTokenizer(parserIDs, ";"); //$NON-NLS-1$ + List list = new ArrayList(tok.countTokens()); + while (tok.hasMoreElements()) { + list.add(tok.nextToken()); + } + String[] strArr = {""}; //$NON-NLS-1$ + errorParsers = (String[]) list.toArray(strArr); + } + } else { + errorParsers = new String[0]; + } + return errorParsers; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getArchList() + */ + public String[] getArchList() { + if (archList == null) { + // Ask superClass for its list + if (getSuperClass() != null) { + return getSuperClass().getArchList(); + } else { + // I have no superClass and no defined list + return new String[] {"all"}; //$NON-NLS-1$ + } + } + return (String[]) archList.toArray(new String[archList.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getOSList() + */ + public String[] getOSList() { + if (osList == null) { + // Ask superClass for its list + if (getSuperClass() != null) { + return getSuperClass().getOSList(); + } else { + // I have no superClass and no defined filter list + return new String[] {"all"}; //$NON-NLS-1$ + } + } + return (String[]) osList.toArray(new String[osList.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setIsAbstract(boolean) + */ + public void setIsAbstract(boolean b) { + isAbstract = new Boolean(b); + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setErrorParserIds(String) + */ + public void setErrorParserIds(String ids) { + String currentIds = getErrorParserIds(); + if (ids == null && currentIds == null) return; + if (currentIds == null || ids == null || !(currentIds.equals(ids))) { + errorParserIds = ids; + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setSecondaryOutputs() + */ + public void setSecondaryOutputs(String newIds) { + if (secondaryOutputIds == null && newIds == null) return; + if (secondaryOutputIds == null || newIds == null || !newIds.equals(secondaryOutputIds)) { + secondaryOutputIds = newIds; + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setTargetToolIds() + */ + public void setTargetToolIds(String newIds) { + if (targetToolIds == null && newIds == null) return; + if (targetToolIds == null || newIds == null || !newIds.equals(targetToolIds)) { + targetToolIds = newIds; + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setOSList(String[]) + */ + public void setOSList(String[] OSs) { + if (osList == null) { + osList = new ArrayList(); + } else { + osList.clear(); + } + for (int i = 0; i < OSs.length; i++) { + osList.add(OSs[i]); + } + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setArchList(String[]) + */ + public void setArchList(String[] archs) { + if (archList == null) { + archList = new ArrayList(); + } else { + archList.clear(); + } + for (int i = 0; i < archs.length; i++) { + archList.add(archs[i]); + } + setDirty(true); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getScannerConfigDiscoveryProfileId() + */ + public String getScannerConfigDiscoveryProfileId() { + if (scannerConfigDiscoveryProfileId == null) { + if (getSuperClass() != null) { + return getSuperClass().getScannerConfigDiscoveryProfileId(); + } + } + return scannerConfigDiscoveryProfileId; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setScannerConfigDiscoveryProfileId(java.lang.String) + */ + public void setScannerConfigDiscoveryProfileId(String profileId) { + if (scannerConfigDiscoveryProfileId == null && profileId == null) return; + if (scannerConfigDiscoveryProfileId == null || + !scannerConfigDiscoveryProfileId.equals(profileId)) { + scannerConfigDiscoveryProfileId = profileId; + setDirty(true); + } + } + + /* + * O B J E C T S T A T E M A I N T E N A N C E + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#isExtensionElement() + */ + public boolean isExtensionElement() { + return isExtensionToolChain; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#isDirty() + */ + public boolean isDirty() { + // This shouldn't be called for an extension tool-chain + if (isExtensionToolChain) return false; + + // If I need saving, just say yes + if (isDirty) return true; + + //check whether the tool-chain - specific macros are dirty + if(userDefinedMacros != null && userDefinedMacros.isDirty()) + return true; + + if(userDefinedEnvironment != null && userDefinedEnvironment.isDirty()) + return true; + + if(builder != null && builder.isDirty()) + return true; + + // Otherwise see if any tools need saving + Iterator iter = getToolList().listIterator(); + while (iter.hasNext()) { + Tool toolChild = (Tool) iter.next(); + if (toolChild.isDirty()) return true; + } + + // Otherwise see if any options need saving + if (super.isDirty()) { + return true; + } + + return isDirty; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setDirty(boolean) + */ + public void setDirty(boolean isDirty) { + this.isDirty = isDirty; + // Propagate "false" to options + super.setDirty(isDirty); + // Propagate "false" to the children + if (!isDirty) { + Iterator iter = getToolList().listIterator(); + while (iter.hasNext()) { + Tool toolChild = (Tool) iter.next(); + toolChild.setDirty(false); + } + } + } + + /* (non-Javadoc) + * Resolve the element IDs to interface references + */ + public void resolveReferences() { + if (!resolved) { + resolved = true; + // Resolve superClass + if (superClassId != null && superClassId.length() > 0) { + setSuperClassInternal(ManagedBuildManager.getExtensionToolChain(superClassId)); + if (getSuperClass() == null) { + // Report error + ManagedBuildManager.OutputResolveError( + "superClass", //$NON-NLS-1$ + superClassId, + "toolChain", //$NON-NLS-1$ + getId()); + } + } + // Resolve HoldsOptions + super.resolveReferences(); + // Call resolveReferences on our children + if (targetPlatform != null) { + targetPlatform.resolveReferences(); + } + if (builder != null) { + builder.resolveReferences(); + } + Iterator iter = getToolList().listIterator(); + while (iter.hasNext()) { + Tool toolChild = (Tool) iter.next(); + toolChild.resolveReferences(); + } + } + } + + /* (non-Javadoc) + * Normalize the list of output extensions,for all tools in the toolchain by populating the list + * with an empty string for those tools which have no explicit output extension (as defined in the + * manifest file. In a post 2.1 manifest, all tools must have a specifed output extension, even + * if it is "") + */ + public void normalizeOutputExtensions(){ + ITool[] tools = getTools(); + if (tools != null) { + for (int i = 0; i < tools.length; i++) { + ITool tool = tools[i]; + String[] extensions = tool.getOutputsAttribute(); + if (extensions == null) { + tool.setOutputsAttribute(""); //$NON-NLS-1$ + continue; + } + if (extensions.length == 0){ + tool.setOutputsAttribute(""); //$NON-NLS-1$ + continue; + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getConvertToId() + */ + public String getConvertToId() { + if (convertToId == null) { + // If I have a superClass, ask it + if (getSuperClass() != null) { + return getSuperClass().getConvertToId(); + } else { + return EMPTY_STRING; + } + } + return convertToId; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setConvertToId(String) + */ + public void setConvertToId(String convertToId) { + if (convertToId == null && this.convertToId == null) return; + if (convertToId == null || this.convertToId == null || !convertToId.equals(this.convertToId)) { + this.convertToId = convertToId; + setDirty(true); + } + return; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getVersionsSupported() + */ + public String getVersionsSupported() { + if (versionsSupported == null) { + // If I have a superClass, ask it + if (getSuperClass() != null) { + return getSuperClass().getVersionsSupported(); + } else { + return EMPTY_STRING; + } + } + return versionsSupported; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#setVersionsSupported(String) + */ + public void setVersionsSupported(String versionsSupported) { + if (versionsSupported == null && this.versionsSupported == null) return; + if (versionsSupported == null || this.versionsSupported == null || !versionsSupported.equals(this.versionsSupported)) { + this.versionsSupported = versionsSupported; + setDirty(true); + } + return; + } + + private IConfigurationElement getIsToolChainSupportedElement(){ + if (managedIsToolChainSupportedElement == null) { + if (superClass != null && superClass instanceof ToolChain) { + return ((ToolChain)superClass).getIsToolChainSupportedElement(); + } + } + return managedIsToolChainSupportedElement; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#isSupported() + */ + public boolean isSupported(){ + if (managedIsToolChainSupported == null) { + IConfigurationElement element = getIsToolChainSupportedElement(); + if (element != null) { + try { + if (element.getAttribute(IS_TOOL_CHAIN_SUPPORTED) != null) { + managedIsToolChainSupported = (IManagedIsToolChainSupported) element.createExecutableExtension(IS_TOOL_CHAIN_SUPPORTED); + } + } catch (CoreException e) {} + } + } + + if(managedIsToolChainSupported != null) + return managedIsToolChainSupported.isSupported(this,null,null); + return true; + } + + /** + * Returns the plugin.xml element of the configurationEnvironmentSupplier extension or null if none. + * + * @return IConfigurationElement + */ + public IConfigurationElement getEnvironmentVariableSupplierElement(){ + if (environmentVariableSupplierElement == null) { + if (getSuperClass() != null && getSuperClass() instanceof ToolChain) { + return ((ToolChain)getSuperClass()).getEnvironmentVariableSupplierElement(); + } + } + return environmentVariableSupplierElement; + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getEnvironmentVariableSupplier() + */ + public IConfigurationEnvironmentVariableSupplier getEnvironmentVariableSupplier(){ + if (environmentVariableSupplier != null) { + return environmentVariableSupplier; + } + IConfigurationElement element = getEnvironmentVariableSupplierElement(); + if (element != null) { + try { + if (element.getAttribute(CONFIGURATION_ENVIRONMENT_SUPPLIER) != null) { + environmentVariableSupplier = (IConfigurationEnvironmentVariableSupplier) element.createExecutableExtension(CONFIGURATION_ENVIRONMENT_SUPPLIER); + return environmentVariableSupplier; + } + } catch (CoreException e) {} + } + return null; + } + + /* + * this method is called by the UserDefinedMacroSupplier to obtain user-defined + * macros available for this tool-chain + */ + public StorableMacros getUserDefinedMacros(){ + if(isExtensionToolChain) + return null; + + if(userDefinedMacros == null) + userDefinedMacros = new StorableMacros(); + return userDefinedMacros; + } + + public StorableEnvironment getUserDefinedEnvironment(){ + if(isExtensionToolChain) + return null; + + return userDefinedEnvironment; + } + + public void setUserDefinedEnvironment(StorableEnvironment env){ + if(!isExtensionToolChain) + userDefinedEnvironment = env; + } + + + /** + * Returns the plugin.xml element of the configurationMacroSupplier extension or null if none. + * + * @return IConfigurationElement + */ + public IConfigurationElement getBuildMacroSupplierElement(){ + if (buildMacroSupplierElement == null) { + if (superClass != null && superClass instanceof ToolChain) { + return ((ToolChain)superClass).getBuildMacroSupplierElement(); + } + } + return buildMacroSupplierElement; + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getBuildMacroSupplier() + */ + public IConfigurationBuildMacroSupplier getBuildMacroSupplier(){ + if (buildMacroSupplier != null) { + return buildMacroSupplier; + } + IConfigurationElement element = getBuildMacroSupplierElement(); + if (element != null) { + try { + if (element.getAttribute(CONFIGURATION_MACRO_SUPPLIER) != null) { + buildMacroSupplier = (IConfigurationBuildMacroSupplier) element.createExecutableExtension(CONFIGURATION_MACRO_SUPPLIER); + return buildMacroSupplier; + } + } catch (CoreException e) {} + } + return null; + } + + /* + * This function checks for migration support for the toolchain, while + * loading. If migration support is needed, looks for the available + * converters and adds them to the list. + */ + + public void checkForMigrationSupport() { + + boolean isExists = false; + + if (getSuperClass() == null) { + // If 'getSuperClass()' is null, then there is no toolchain available in + // plugin manifest file with the 'id' & version. + // Look for the 'versionsSupported' attribute + String high = (String) ManagedBuildManager + .getExtensionToolChainMap().lastKey(); + + SortedMap subMap = null; + if (superClassId.compareTo(high) <= 0) { + subMap = ManagedBuildManager.getExtensionToolChainMap().subMap( + superClassId, high + "\0"); //$NON-NLS-1$ + } else { + // It means there are no entries in the map for the given id. + // make the project is invalid + IConfiguration parentConfig = getParent(); + IManagedProject managedProject = parentConfig.getManagedProject(); + if (managedProject != null) { + managedProject.setValid(false); + } + return; + } + + // for each element in the 'subMap', + // check the 'versionsSupported' attribute whether the given + // toolChain version is supported + + String baseId = ManagedBuildManager.getIdFromIdAndVersion(superClassId); + String version = getVersionFromId().toString(); + + IToolChain[] toolChainElements = (IToolChain[]) subMap.values().toArray(); + + for (int i = 0; i < toolChainElements.length; i++) { + IToolChain toolChainElement = toolChainElements[i]; + + if (ManagedBuildManager.getIdFromIdAndVersion( + toolChainElement.getId()).compareTo(baseId) > 0) + break; + + // First check if both base ids are equal + if (ManagedBuildManager.getIdFromIdAndVersion( + toolChainElement.getId()).equals(baseId)) { + + // Check if 'versionsSupported' attribute is available' + String versionsSupported = toolChainElement.getVersionsSupported(); + + if ((versionsSupported != null) + && (!versionsSupported.equals(""))) { //$NON-NLS-1$ + String[] tmpVersions = versionsSupported.split(","); //$NON-NLS-1$ + + for (int j = 0; j < tmpVersions.length; j++) { + if (new PluginVersionIdentifier(version).equals(new PluginVersionIdentifier(tmpVersions[j]))) { + // version is supported. + // Do the automatic conversion without + // prompting the user. + // Get the supported version + String supportedVersion = ManagedBuildManager.getVersionFromIdAndVersion( + toolChainElement.getId()); + setId(ManagedBuildManager.getIdFromIdAndVersion(getId()) + + "_" + supportedVersion); //$NON-NLS-1$ + + // If control comes here means that 'superClass' is null + // So, set the superClass to this toolChain element + setSuperClassInternal(toolChainElement); + superClassId = getSuperClass().getId(); + isExists = true; + break; + } + } + if(isExists) + break; // break the outer for loop if 'isExists' is true + } + } + } + } + + if (getSuperClass() != null) { + // If 'getSuperClass()' is not null, look for 'convertToId' attribute in plugin + // manifest file for this toolchain. + String convertToId = getSuperClass().getConvertToId(); + if ((convertToId == null) || (convertToId.equals(""))) { //$NON-NLS-1$ + // It means there is no 'convertToId' attribute available and + // the version is still actively + // supported by the tool integrator. So do nothing, just return + return; + } else { + // In case the 'convertToId' attribute is available, + // it means that Tool integrator currently does not support this + // version of toolchain. + // Look for the converters available for this toolchain version. + + getConverter(convertToId); + } + + } else { + // make the project is invalid + // + IConfiguration parentConfig = getParent(); + IManagedProject managedProject = parentConfig.getManagedProject(); + if (managedProject != null) { + managedProject.setValid(false); + } + } + return; + } + + private void getConverter(String convertToId) { + + String fromId = null; + String toId = null; + + // Get the Converter Extension Point + IExtensionPoint extensionPoint = Platform.getExtensionRegistry() + .getExtensionPoint("org.eclipse.cdt.managedbuilder.core", //$NON-NLS-1$ + "projectConverter"); //$NON-NLS-1$ + if (extensionPoint != null) { + // Get the extensions + IExtension[] extensions = extensionPoint.getExtensions(); + for (int i = 0; i < extensions.length; i++) { + // Get the configuration elements of each extension + IConfigurationElement[] configElements = extensions[i] + .getConfigurationElements(); + for (int j = 0; j < configElements.length; j++) { + + IConfigurationElement element = configElements[j]; + + if (element.getName().equals("converter")) { //$NON-NLS-1$ + + fromId = element.getAttribute("fromId"); //$NON-NLS-1$ + toId = element.getAttribute("toId"); //$NON-NLS-1$ + // Check whether the current converter can be used for + // the selected toolchain + + if (fromId.equals(getSuperClass().getId()) + && toId.equals(convertToId)) { + // If it matches + String mbsVersion = element + .getAttribute("mbsVersion"); //$NON-NLS-1$ + PluginVersionIdentifier currentMbsVersion = ManagedBuildManager + .getBuildInfoVersion(); + + // set the converter element based on the MbsVersion + if (currentMbsVersion + .isGreaterThan(new PluginVersionIdentifier( + mbsVersion))) { + previousMbsVersionConversionElement = element; + } else { + currentMbsVersionConversionElement = element; + } + return; + } + } + } + } + } + + // If control comes here, it means 'Tool Integrator' specified + // 'convertToId' attribute in toolchain definition file, but + // has not provided any converter. + // So, make the project is invalid + + IConfiguration parentConfig = getParent(); + IManagedProject managedProject = parentConfig.getManagedProject(); + if (managedProject != null) { + managedProject.setValid(false); + } + } + + + public IConfigurationElement getPreviousMbsVersionConversionElement() { + return previousMbsVersionConversionElement; + } + + public IConfigurationElement getCurrentMbsVersionConversionElement() { + return currentMbsVersionConversionElement; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.core.BuildObject#updateManagedBuildRevision(java.lang.String) + */ + public void updateManagedBuildRevision(String revision){ + super.updateManagedBuildRevision(revision); + + for(Iterator iter = getToolList().iterator(); iter.hasNext();){ + ((Tool)iter.next()).updateManagedBuildRevision(revision); + } + + if(builder != null) + builder.updateManagedBuildRevision(revision); + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java index d5df38aa97d..34feff3a9cd 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java @@ -1,1251 +1,1254 @@ -/******************************************************************************* - * Copyright (c) 2003, 2005 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.internal.core; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.cdt.managedbuilder.core.BuildException; -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IConfigurationV2; -import org.eclipse.cdt.managedbuilder.core.IHoldsOptions; -import org.eclipse.cdt.managedbuilder.core.IInputType; -import org.eclipse.cdt.managedbuilder.core.IEnvVarBuildPath; -import org.eclipse.cdt.managedbuilder.core.IOptionApplicability; -import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; -import org.eclipse.cdt.managedbuilder.core.IOption; -import org.eclipse.cdt.managedbuilder.core.IOptionCategory; -import org.eclipse.cdt.managedbuilder.core.IOutputType; -import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.IToolChain; -import org.eclipse.cdt.managedbuilder.core.IToolReference; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.PluginVersionIdentifier; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -public class ToolReference implements IToolReference { - private static final String DEFAULT_SEPARATOR = ","; //$NON-NLS-1$ - - private String command; - private boolean isDirty = false; - private List optionReferences; - private IBuildObject owner; - private String outputExtensions; - private String outputFlag; - private String outputPrefix; - protected ITool parent; - private boolean resolved = true; - private String versionsSupported; - private String convertToId; - - /** - * Create a new tool reference based on information contained in - * a project file. - * - * @param owner The ConfigurationV2 the receiver will be added to. - * @param element The element defined in the project file containing build information - * for the receiver. - */ - public ToolReference(BuildObject owner, Element element) { - this.owner = owner; - - if (owner instanceof ConfigurationV2) { - if (parent == null) { - Target parentTarget = (Target) ((ConfigurationV2)owner).getTarget(); - try { - parent = ((Target)parentTarget.getParent()).getTool(element.getAttribute(ID)); - } catch (NullPointerException e) { - parent = null; - } - } - ((ConfigurationV2)owner).addToolReference(this); - } else if (owner instanceof Target) { - if (parent == null) { - try { - parent = ((Target)((Target)owner).getParent()).getTool(element.getAttribute(ID)); - } catch (NullPointerException e) { - parent = null; - } - } - ((Target)owner).addToolReference(this); - } - - // Get the overridden tool command (if any) - if (element.hasAttribute(ITool.COMMAND)) { - command = element.getAttribute(ITool.COMMAND); - } - - // Get the overridden output prefix (if any) - if (element.hasAttribute(ITool.OUTPUT_PREFIX)) { - outputPrefix = element.getAttribute(ITool.OUTPUT_PREFIX); - } - - // Get the output extensions the reference produces - if (element.hasAttribute(ITool.OUTPUTS)) { - outputExtensions = element.getAttribute(ITool.OUTPUTS); - } - // Get the flag to control output - if (element.hasAttribute(ITool.OUTPUT_FLAG)) - outputFlag = element.getAttribute(ITool.OUTPUT_FLAG); - - NodeList configElements = element.getChildNodes(); - for (int i = 0; i < configElements.getLength(); ++i) { - Node configElement = configElements.item(i); - if (configElement.getNodeName().equals(ITool.OPTION_REF)) { - new OptionReference(this, (Element)configElement); - } - } - } - - /** - * Created tool reference from an extension defined in a plugin manifest. - * - * @param owner The BuildObject the receiver will be added to. - * @param element The element containing build information for the reference. - */ - public ToolReference(BuildObject owner, IManagedConfigElement element) { - // setup for resolving - ManagedBuildManager.putConfigElement(this, element); - resolved = false; - - this.owner = owner; - - // hook me up - if (owner instanceof ConfigurationV2) { - ((ConfigurationV2)owner).addToolReference(this); - } else if (owner instanceof Target) { - ((Target)owner).addToolReference(this); - } - - // Get the overridden tool command (if any) - command = element.getAttribute(ITool.COMMAND); - - // Get the overridden output prefix, if any - outputPrefix = element.getAttribute(ITool.OUTPUT_PREFIX); - - // Get the overridden output extensions (if any) - String output = element.getAttribute(ITool.OUTPUTS); - if (output != null) { - outputExtensions = output; - } - - // Get the flag to control output - outputFlag = element.getAttribute(ITool.OUTPUT_FLAG); - - IManagedConfigElement[] toolElements = element.getChildren(); - for (int m = 0; m < toolElements.length; ++m) { - IManagedConfigElement toolElement = toolElements[m]; - if (toolElement.getName().equals(ITool.OPTION_REF)) { - new OptionReference(this, toolElement); - } - } - } - - /** - * Created a tool reference on the fly based on an existing tool or tool reference. - * - * @param owner The BuildObject the receiver will be added to. - * @param tool The ITooltool the reference will be based on. - */ - public ToolReference(BuildObject owner, ITool tool) { - this.owner = owner; - if (tool instanceof ToolReference) { - parent = ((ToolReference)tool).getTool(); - } else { - parent = tool; - } - command = tool.getToolCommand(); - outputFlag = tool.getOutputFlag(); - outputPrefix = tool.getOutputPrefix(); - String[] extensions = tool.getOutputsAttribute(); - outputExtensions = new String(); - if (extensions != null) { - for (int index = 0; index < extensions.length; ++index) { - if (extensions[index] == null) continue; - outputExtensions += extensions[index]; - if (index < extensions.length - 1) { - outputExtensions += DEFAULT_SEPARATOR; - } - } - } - - // Create a copy of the option references of the parent in the receiver - if (tool instanceof ToolReference) { - List parentRefs = ((ToolReference)tool).getOptionReferenceList(); - Iterator iter = parentRefs.iterator(); - while (iter.hasNext()) { - IOption parent = (IOption)iter.next(); - OptionReference clone = createOptionReference(parent); - try { - switch (parent.getValueType()) { - case IOption.BOOLEAN: - clone.setValue(parent.getBooleanValue()); - break; - case IOption.STRING: - clone.setValue(parent.getStringValue()); - case IOption.ENUMERATED: - clone.setValue(parent.getSelectedEnum()); - break; - default: - clone.setValue(parent.getStringListValue()); - break; - } - } catch (BuildException e) { - // Likely a mismatch between the value and option type - continue; - } - } - } - - if (owner instanceof ConfigurationV2) { - ((ConfigurationV2)owner).addToolReference(this); - } else if (owner instanceof Target) { - ((Target)owner).addToolReference(this); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolReference#references(org.eclipse.cdt.managedbuilder.core.ITool) - */ - public boolean references(ITool target) { - if (equals(target)) { - // we are the target - return true; - } else if (parent == null) { - // basic sanity before proceeding - return false; - } else if (parent instanceof IToolReference) { - // check the reference we are overriding - return ((IToolReference)parent).references(target); - } else if (target instanceof IToolReference) { - return parent.equals(((IToolReference)target).getTool()); - } else { - // the real reference - return parent.equals(target); - } - } - - public void resolveReferences() { - if (!resolved) { - resolved = true; - IManagedConfigElement element = ManagedBuildManager.getConfigElement(this); - // resolve my parent - if (owner instanceof ConfigurationV2) { - Target target = (Target) ((ConfigurationV2)owner).getTarget(); - parent = target.getTool(element.getAttribute(ID)); - } else if (owner instanceof Target) { - parent = ((Target)owner).getTool(element.getAttribute(ID)); - } - // recursively resolve my parent - if (parent instanceof Tool) { - ((Tool)parent).resolveReferences(); - } else if (parent instanceof ToolReference) { - ((ToolReference)parent).resolveReferences(); - } - - Iterator it = getOptionReferenceList().iterator(); - while (it.hasNext()) { - OptionReference optRef = (OptionReference)it.next(); - optRef.resolveReferences(); - } - } - } - - /** - * Adds the option reference specified in the argument to the receiver. - * - * @param optionRef - */ - public void addOptionReference(OptionReference optionRef) { - getOptionReferenceList().add(optionRef); - isDirty = true; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#buildsFileType(java.lang.String) - */ - public boolean buildsFileType(String extension) { - if (parent == null) { - // bad reference - return false; - } - return parent.buildsFileType(extension); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#buildsFileType(java.lang.String) - */ - public boolean isInputFileType(String extension) { - if (parent == null) { - // bad reference - return false; - } - return parent.isInputFileType(extension); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolReference#createOptionReference(org.eclipse.cdt.managedbuilder.core.IOption) - */ - public OptionReference createOptionReference(IOption option) { - // Check if the option reference already exists - OptionReference ref = getOptionReference(option); - // It is possible that the search will return an option reference - // that is supplied by another element of the build model, not the caller. - // For example, if the search is starated by a configuration and the target - // the caller belongs to has an option reference for the option, it - // will be returned. While this is correct behaviour for a search, the - // caller will need to create a clone for itself, so make sure the tool - // reference of the search result is owned by the caller - if (ref == null || !ref.getToolReference().owner.equals(this.owner)) { - ref = new OptionReference(this, option); - } - return ref; - } - - /* (non-Javadoc) - * @return - */ - protected List getAllOptionRefs() { - // First get all the option references this tool reference contains - if (owner instanceof ConfigurationV2) { - return ((ConfigurationV2)owner).getOptionReferences(parent); - } else if (owner instanceof Target) { - return ((Target)owner).getOptionReferences(parent); - } else { - // this shouldn't happen - return null; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IBuildObject#getId() - */ - public String getId() { - if (parent == null) { - // bad reference - return new String(); - } - return parent.getId(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IBuildObject#getBaseId() - */ - public String getBaseId() { - if (parent == null) { - // bad reference - return new String(); - } - return parent.getBaseId(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getInputExtensions() - */ - public List getInputExtensions() { - String[] exts = getPrimaryInputExtensions(); - List extList = new ArrayList(); - for (int i=0; i 0) { - buf.append(boolCmd + WHITE_SPACE); - } - break; - - case IOption.ENUMERATED : - String enumVal = option.getEnumCommand(option.getSelectedEnum()); - if (enumVal.length() > 0) { - buf.append(enumVal + WHITE_SPACE); - } - break; - - case IOption.STRING : - String strCmd = option.getCommand(); - String val = option.getStringValue(); - if (val.length() > 0) { - if (strCmd != null) buf.append(strCmd); - buf.append(val + WHITE_SPACE); - } - break; - - case IOption.STRING_LIST : - String cmd = option.getCommand(); - String[] list = option.getStringListValue(); - for (int j = 0; j < list.length; j++) { - String temp = list[j]; - if (cmd != null) buf.append(cmd); - buf.append(temp + WHITE_SPACE); - } - break; - - case IOption.INCLUDE_PATH : - String incCmd = option.getCommand(); - String[] paths = option.getIncludePaths(); - for (int j = 0; j < paths.length; j++) { - String temp = paths[j]; - buf.append(incCmd + temp + WHITE_SPACE); - } - break; - - case IOption.PREPROCESSOR_SYMBOLS : - String defCmd = option.getCommand(); - String[] symbols = option.getDefinedSymbols(); - for (int j = 0; j < symbols.length; j++) { - String temp = symbols[j]; - buf.append(defCmd + temp + WHITE_SPACE); - } - break; - - default : - break; - } - } - } - - return buf.toString().trim(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getTopOptionCategory() - */ - public IOptionCategory getTopOptionCategory() { - try { - return parent.getTopOptionCategory(); - } catch (NullPointerException e) { - return null; - } - } - - /* (non-Javadoc) - * Answers an option reference that overrides the option, or null - * - * @param option - * @return OptionReference - */ - private OptionReference getOptionReference(IOption option) { - // Get all the option references for this option - Iterator iter = getAllOptionRefs().listIterator(); - while (iter.hasNext()) { - OptionReference optionRef = (OptionReference) iter.next(); - if (optionRef.references(option)) - return optionRef; - } - - return null; - } - - /* (non-Javadoc) - * - * @param id - * @return - */ - private OptionReference getOptionReference(String id) { - Iterator it = getOptionReferenceList().iterator(); - while (it.hasNext()) { - OptionReference current = (OptionReference)it.next(); - if (current.getId().equals(id)) { - return current; - } - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolReference#getOptionReferenceList() - */ - public List getOptionReferenceList() { - if (optionReferences == null) { - optionReferences = new ArrayList(); - } - return optionReferences; - } - - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getOptions() - */ - public IOption[] getOptions() { - IOption[] options = parent.getOptions(); - - // Replace with our references - for (int i = 0; i < options.length; ++i) { - OptionReference ref = getOptionReference(options[i]); - if (ref != null) - options[i] = ref; - } - - return options; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputExtensions() - */ - public String[] getOutputExtensions() { - if (outputExtensions == null){ - if (parent != null) { - return parent.getOutputsAttribute(); - } else { - return new String[0]; - } - } - return outputExtensions.split(DEFAULT_SEPARATOR); - } - - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputExtension(java.lang.String) - */ - public String getOutputExtension(String inputExtension) { - if (parent == null) { - // bad reference - return new String(); - } - return parent.getOutputExtension(inputExtension); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputFlag() - */ - public String getOutputFlag() { - if (outputFlag == null) { - if (parent != null) { - return parent.getOutputFlag(); - } else { - // We never should be here - return new String(); - } - } - return outputFlag; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputPrefix() - */ - public String getOutputPrefix() { - if (outputPrefix == null) { - if (parent != null) { - return parent.getOutputPrefix(); - } - return new String(); // bad reference - } - return outputPrefix; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolReference#isDirty() - */ - public boolean isDirty() { - return isDirty; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#isHeaderFile(java.lang.String) - */ - public boolean isHeaderFile(String ext) { - if (parent == null) { - // bad reference - return false; - } - return parent.isHeaderFile(ext); - } - - /** - * Answers true if the owner of the receiver matches - * the argument. - * - * @param config - * @return - */ - public boolean ownedByConfiguration(IConfigurationV2 config) { - if (owner instanceof ConfigurationV2) { - return ((IConfigurationV2)owner).equals(config); - } - return false; - } - - /** - * Persist receiver to project file. - * - * @param doc The persistent store for the reference information. - * @param element The root element in the store the receiver must use - * to persist settings. - */ - public void serialize(Document doc, Element element) { - if (parent == null) return; // This is a bad reference - element.setAttribute(ITool.ID, parent.getId()); - - // Output the command - if (command != null) { - element.setAttribute(ITool.COMMAND, getToolCommand()); - } - - // Save output prefix - if (outputPrefix != null) { - element.setAttribute(ITool.OUTPUT_PREFIX, getOutputPrefix()); - } - - // Save the output flag - if (outputFlag != null) { - element.setAttribute(ITool.OUTPUT_FLAG, getOutputFlag()); - } - - // Save the outputs - if (outputExtensions != null) { - element.setAttribute(ITool.OUTPUTS, outputExtensions); - } - - // Output the option references - Iterator iter = getOptionReferenceList().listIterator(); - while (iter.hasNext()) { - OptionReference optionRef = (OptionReference) iter.next(); - Element optionRefElement = doc.createElement(ITool.OPTION_REF); - element.appendChild(optionRefElement); - optionRef.serialize(doc, optionRefElement); - } - - // Set the reference to clean - isDirty = false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolReference#setDirty(boolean) - */ - public void setDirty(boolean isDirty) { - // Override the local flag - this.isDirty = isDirty; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolReference#setToolCommand(java.lang.String) - */ - public boolean setToolCommand(String cmd) { - if (cmd != null && !cmd.equals(command)) { - command = cmd; - isDirty = true; - return true; - } else { - return false; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setOutputFlag(java.lang.String) - */ - public void setOutputFlag(String flag) { - if (flag == null) return; - if (outputFlag == null || !(flag.equals(outputFlag))) { - outputFlag = flag; - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setOutputPrefix(java.lang.String) - */ - public void setOutputPrefix(String prefix) { - if (prefix == null) return; - if (outputPrefix == null || !(prefix.equals(outputPrefix))) { - outputPrefix = prefix; - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setOutputExtensions(java.lang.String) - */ - public void setOutputExtensions(String ext) { - if (ext == null) return; - if (outputExtensions == null || !(ext.equals(outputExtensions))) { - outputExtensions = ext; - isDirty = true; - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setParent(IBuildObject) - */ - public void setToolParent(IBuildObject newParent) { - if (parent == null) { - // bad reference - return; - } - // Set the parent in the parent of this ToolRefernce, the tool - ((Tool)parent).setToolParent(newParent); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getParent() - */ - public IBuildObject getParent() { - return owner; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getCommandLinePattern() - */ - public String getCommandLinePattern() { - if( parent == null ) return new String(); - return parent.getCommandLinePattern(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getCommandLineGenerator() - */ - public IManagedCommandLineGenerator getCommandLineGenerator() { - if( parent == null ) return null; - return parent.getCommandLineGenerator(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getDependencyGenerator() - */ - public IManagedDependencyGenerator getDependencyGenerator() { - if( parent == null ) return null; - return parent.getDependencyGenerator(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getCommandFlags() - */ - public String[] getCommandFlags() throws BuildException { - if( parent == null ) return null; - return parent.getToolCommandFlags(null, null); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getToolCommandFlags(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) - */ - public String[] getToolCommandFlags(IPath inputFileLocation, IPath outputFileLocation) throws BuildException{ - return getCommandFlags(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getToolCommandFlagsString(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) - */ - public String getToolCommandFlagsString(IPath inputFileLocation, IPath outputFileLocation) throws BuildException{ - return getToolFlags(); - - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - public String toString() { - String answer = new String(); - if (parent != null) { - answer += "Reference to " + parent.getName(); //$NON-NLS-1$ - } - - if (answer.length() > 0) { - return answer; - } else { - return super.toString(); - } - } - - /* - * The following methods are here in order to implement the new ITool methods. - * They should never be called. - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getSuperClass() - */ - public ITool getSuperClass() { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#isAbstract() - */ - public boolean isAbstract() { - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getUnusedChildren() - */ - public String getUnusedChildren() { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getErrorParserList() - */ - public String[] getErrorParserList() { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getErrorParserIds() - */ - public String getErrorParserIds() { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setErrorParserIds() - */ - public void setErrorParserIds(String ids) { - } - - public List getInterfaceExtensions() { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#isExtensionElement() - */ - public boolean isExtensionElement() { - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#createOption() - */ - public IOption createOption(IOption superClass, String Id, String name, boolean b) { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IHoldsOptions#createOptions() - */ - public void createOptions(IHoldsOptions options) { - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#removeOption() - */ - public void removeOption(IOption o) { - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.IOptionCategory#getChildCategories() - */ - public IOptionCategory[] getChildCategories() { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setIsAbstract(boolean) - */ - public void setIsAbstract(boolean b) { - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getCommandLinePattern() - */ - public void setCommandLinePattern(String pattern) { - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#setCommandLineGenerator(IConfigurationElement) - */ - public void setCommandLineGeneratorElement(IConfigurationElement element) { - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getCommandLineGenerator() - */ - public IConfigurationElement getDependencyGeneratorElement() { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#setCommandLineGenerator(IConfigurationElement) - */ - public void setDependencyGeneratorElement(IConfigurationElement element) { - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getCommandLineGeneratorElement() - */ - public IConfigurationElement getCommandLineGeneratorElement() { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getAdvancedInputCategory() - */ - public boolean getAdvancedInputCategory() { - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#setAdvancedInputCategory() - */ - public void setAdvancedInputCategory(boolean display) { - } - - public IInputType createInputType(IInputType superClass, String Id, String name, boolean isExtensionElement) { - return null; - } - - public IOutputType createOutputType(IOutputType superClass, String Id, String name, boolean isExtensionElement) { - return null; - } - - public String getAnnouncement() { - return null; - } - - public IInputType getInputTypeById(String id) { - return null; - } - - public IInputType[] getInputTypes() { - return null; - } - - public IOutputType getOutputTypeById(String id) { - return null; - } - - public IOutputType[] getOutputTypes() { - return null; - } - - public void removeInputType(IInputType type) { - } - - public void removeOutputType(IOutputType type) { - } - - public void setAnnouncement(String announcement) { - } - - public String getDefaultInputExtension() { - return null; - } - - public String[] getAllInputExtensions() { - return null; - } - - public String[] getPrimaryInputExtensions() { - return null; - } - - public IInputType getInputType(String inputExtension) { - return null; - } - - public String[] getOutputsAttribute() { - return null; - } - - public IOutputType getOutputType(String outputExtension) { - return null; - } - - public void setOutputsAttribute(String extensions) { - } - - public String[] getAllOutputExtensions() { - return null; - } - - public String[] getAllDependencyExtensions() { - return null; - } - - public IInputType getPrimaryInputType() { - return null; - } - - public IOutputType getPrimaryOutputType() { - return null; - } - - public IPath[] getAdditionalDependencies() { - return null; - } - - public IPath[] getAdditionalResources() { - return null; - } - - public IConfigurationElement getDependencyGeneratorElementForExtension(String sourceExt) { - return null; - } - - public IManagedDependencyGenerator getDependencyGeneratorForExtension(String sourceExt) { - return null; - } - - public boolean getCustomBuildStep() { - return false; - } - - public void setCustomBuildStep(boolean customBuildStep) { - } - - public IOption getOptionBySuperClassId(String id) { - return null; - } - - public IOptionCategory getOptionCategory(String id) { - // return null as class is deprecated - return null; - } - - public void addOptionCategory(IOptionCategory category) { - } - - /* - * The following methods are added to allow the converter from ToolReference -> Tool - * to retrieve the actual value of attributes. These routines do not go to the - * referenced Tool for a value if the ToolReference does not have a value. - */ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolReference#getRawOutputExtensions() - */ - public String getRawOutputExtensions() { - return outputExtensions; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolReference#getRawOutputFlag() - */ - public String getRawOutputFlag() { - return outputFlag; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolReference#getRawOutputPrefix() - */ - public String getRawOutputPrefix() { - return outputPrefix; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.IToolReference#getRawToolCommand() - */ - public String getRawToolCommand() { - return command; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getConvertToId() - */ - public String getConvertToId() { - if (convertToId == null) { - // If I have a superClass, ask it - if (parent != null) { - return parent.getConvertToId(); - } else { - return new String(); - } - } - return convertToId; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setConvertToId(String) - */ - public void setConvertToId(String convertToId) { - if (convertToId == null && this.convertToId == null) return; - if (convertToId == null || this.convertToId == null || !convertToId.equals(this.convertToId)) { - this.convertToId = convertToId; - setDirty(true); - } - return; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#getVersionsSupported() - */ - public String getVersionsSupported() { - if (versionsSupported == null) { - // If I have a superClass, ask it - if (parent != null) { - return parent.getVersionsSupported(); - } else { - return new String(); - } - } - return versionsSupported; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.core.ITool#setVersionsSupported(String) - */ - public void setVersionsSupported(String versionsSupported) { - if (versionsSupported == null && this.versionsSupported == null) return; - if (versionsSupported == null || this.versionsSupported == null || !versionsSupported.equals(this.versionsSupported)) { - this.versionsSupported = versionsSupported; - setDirty(true); - } - return; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getEnvVarBuildPaths() - */ - public IEnvVarBuildPath[] getEnvVarBuildPaths(){ - return null; - } - - public PluginVersionIdentifier getVersion() { - return null; - } - - public void setVersion(PluginVersionIdentifier version) { - // TODO Auto-generated method stub - } - - public String getManagedBuildRevision() { - return null; - } - - public IOption getOptionToSet(IOption option, boolean adjustExtension){ - return null; - } -} +/******************************************************************************* + * Copyright (c) 2003, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.core; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IConfigurationV2; +import org.eclipse.cdt.managedbuilder.core.IHoldsOptions; +import org.eclipse.cdt.managedbuilder.core.IInputType; +import org.eclipse.cdt.managedbuilder.core.IEnvVarBuildPath; +import org.eclipse.cdt.managedbuilder.core.IOptionApplicability; +import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; +import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.cdt.managedbuilder.core.IOptionCategory; +import org.eclipse.cdt.managedbuilder.core.IOutputType; +import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.core.IToolReference; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.PluginVersionIdentifier; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class ToolReference implements IToolReference { + private static final String DEFAULT_SEPARATOR = ","; //$NON-NLS-1$ + + private String command; + private boolean isDirty = false; + private List optionReferences; + private IBuildObject owner; + private String outputExtensions; + private String outputFlag; + private String outputPrefix; + protected ITool parent; + private boolean resolved = true; + private String versionsSupported; + private String convertToId; + + /** + * Create a new tool reference based on information contained in + * a project file. + * + * @param owner The ConfigurationV2 the receiver will be added to. + * @param element The element defined in the project file containing build information + * for the receiver. + */ + public ToolReference(BuildObject owner, Element element) { + this.owner = owner; + + if (owner instanceof ConfigurationV2) { + if (parent == null) { + Target parentTarget = (Target) ((ConfigurationV2)owner).getTarget(); + try { + parent = ((Target)parentTarget.getParent()).getTool(element.getAttribute(ID)); + } catch (NullPointerException e) { + parent = null; + } + } + ((ConfigurationV2)owner).addToolReference(this); + } else if (owner instanceof Target) { + if (parent == null) { + try { + parent = ((Target)((Target)owner).getParent()).getTool(element.getAttribute(ID)); + } catch (NullPointerException e) { + parent = null; + } + } + ((Target)owner).addToolReference(this); + } + + // Get the overridden tool command (if any) + if (element.hasAttribute(ITool.COMMAND)) { + command = element.getAttribute(ITool.COMMAND); + } + + // Get the overridden output prefix (if any) + if (element.hasAttribute(ITool.OUTPUT_PREFIX)) { + outputPrefix = element.getAttribute(ITool.OUTPUT_PREFIX); + } + + // Get the output extensions the reference produces + if (element.hasAttribute(ITool.OUTPUTS)) { + outputExtensions = element.getAttribute(ITool.OUTPUTS); + } + // Get the flag to control output + if (element.hasAttribute(ITool.OUTPUT_FLAG)) + outputFlag = element.getAttribute(ITool.OUTPUT_FLAG); + + NodeList configElements = element.getChildNodes(); + for (int i = 0; i < configElements.getLength(); ++i) { + Node configElement = configElements.item(i); + if (configElement.getNodeName().equals(ITool.OPTION_REF)) { + new OptionReference(this, (Element)configElement); + } + } + } + + /** + * Created tool reference from an extension defined in a plugin manifest. + * + * @param owner The BuildObject the receiver will be added to. + * @param element The element containing build information for the reference. + */ + public ToolReference(BuildObject owner, IManagedConfigElement element) { + // setup for resolving + ManagedBuildManager.putConfigElement(this, element); + resolved = false; + + this.owner = owner; + + // hook me up + if (owner instanceof ConfigurationV2) { + ((ConfigurationV2)owner).addToolReference(this); + } else if (owner instanceof Target) { + ((Target)owner).addToolReference(this); + } + + // Get the overridden tool command (if any) + command = element.getAttribute(ITool.COMMAND); + + // Get the overridden output prefix, if any + outputPrefix = element.getAttribute(ITool.OUTPUT_PREFIX); + + // Get the overridden output extensions (if any) + String output = element.getAttribute(ITool.OUTPUTS); + if (output != null) { + outputExtensions = output; + } + + // Get the flag to control output + outputFlag = element.getAttribute(ITool.OUTPUT_FLAG); + + IManagedConfigElement[] toolElements = element.getChildren(); + for (int m = 0; m < toolElements.length; ++m) { + IManagedConfigElement toolElement = toolElements[m]; + if (toolElement.getName().equals(ITool.OPTION_REF)) { + new OptionReference(this, toolElement); + } + } + } + + /** + * Created a tool reference on the fly based on an existing tool or tool reference. + * + * @param owner The BuildObject the receiver will be added to. + * @param tool The ITooltool the reference will be based on. + */ + public ToolReference(BuildObject owner, ITool tool) { + this.owner = owner; + if (tool instanceof ToolReference) { + parent = ((ToolReference)tool).getTool(); + } else { + parent = tool; + } + command = tool.getToolCommand(); + outputFlag = tool.getOutputFlag(); + outputPrefix = tool.getOutputPrefix(); + String[] extensions = tool.getOutputsAttribute(); + outputExtensions = new String(); + if (extensions != null) { + for (int index = 0; index < extensions.length; ++index) { + if (extensions[index] == null) continue; + outputExtensions += extensions[index]; + if (index < extensions.length - 1) { + outputExtensions += DEFAULT_SEPARATOR; + } + } + } + + // Create a copy of the option references of the parent in the receiver + if (tool instanceof ToolReference) { + List parentRefs = ((ToolReference)tool).getOptionReferenceList(); + Iterator iter = parentRefs.iterator(); + while (iter.hasNext()) { + IOption parent = (IOption)iter.next(); + OptionReference clone = createOptionReference(parent); + try { + switch (parent.getValueType()) { + case IOption.BOOLEAN: + clone.setValue(parent.getBooleanValue()); + break; + case IOption.STRING: + clone.setValue(parent.getStringValue()); + case IOption.ENUMERATED: + clone.setValue(parent.getSelectedEnum()); + break; + default: + clone.setValue(parent.getStringListValue()); + break; + } + } catch (BuildException e) { + // Likely a mismatch between the value and option type + continue; + } + } + } + + if (owner instanceof ConfigurationV2) { + ((ConfigurationV2)owner).addToolReference(this); + } else if (owner instanceof Target) { + ((Target)owner).addToolReference(this); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolReference#references(org.eclipse.cdt.managedbuilder.core.ITool) + */ + public boolean references(ITool target) { + if (equals(target)) { + // we are the target + return true; + } else if (parent == null) { + // basic sanity before proceeding + return false; + } else if (parent instanceof IToolReference) { + // check the reference we are overriding + return ((IToolReference)parent).references(target); + } else if (target instanceof IToolReference) { + return parent.equals(((IToolReference)target).getTool()); + } else { + // the real reference + return parent.equals(target); + } + } + + public void resolveReferences() { + if (!resolved) { + resolved = true; + IManagedConfigElement element = ManagedBuildManager.getConfigElement(this); + // resolve my parent + if (owner instanceof ConfigurationV2) { + Target target = (Target) ((ConfigurationV2)owner).getTarget(); + parent = target.getTool(element.getAttribute(ID)); + } else if (owner instanceof Target) { + parent = ((Target)owner).getTool(element.getAttribute(ID)); + } + // recursively resolve my parent + if (parent instanceof Tool) { + ((Tool)parent).resolveReferences(); + } else if (parent instanceof ToolReference) { + ((ToolReference)parent).resolveReferences(); + } + + Iterator it = getOptionReferenceList().iterator(); + while (it.hasNext()) { + OptionReference optRef = (OptionReference)it.next(); + optRef.resolveReferences(); + } + } + } + + /** + * Adds the option reference specified in the argument to the receiver. + * + * @param optionRef + */ + public void addOptionReference(OptionReference optionRef) { + getOptionReferenceList().add(optionRef); + isDirty = true; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#buildsFileType(java.lang.String) + */ + public boolean buildsFileType(String extension) { + if (parent == null) { + // bad reference + return false; + } + return parent.buildsFileType(extension); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#buildsFileType(java.lang.String) + */ + public boolean isInputFileType(String extension) { + if (parent == null) { + // bad reference + return false; + } + return parent.isInputFileType(extension); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolReference#createOptionReference(org.eclipse.cdt.managedbuilder.core.IOption) + */ + public OptionReference createOptionReference(IOption option) { + // Check if the option reference already exists + OptionReference ref = getOptionReference(option); + // It is possible that the search will return an option reference + // that is supplied by another element of the build model, not the caller. + // For example, if the search is starated by a configuration and the target + // the caller belongs to has an option reference for the option, it + // will be returned. While this is correct behaviour for a search, the + // caller will need to create a clone for itself, so make sure the tool + // reference of the search result is owned by the caller + if (ref == null || !ref.getToolReference().owner.equals(this.owner)) { + ref = new OptionReference(this, option); + } + return ref; + } + + /* (non-Javadoc) + * @return + */ + protected List getAllOptionRefs() { + // First get all the option references this tool reference contains + if (owner instanceof ConfigurationV2) { + return ((ConfigurationV2)owner).getOptionReferences(parent); + } else if (owner instanceof Target) { + return ((Target)owner).getOptionReferences(parent); + } else { + // this shouldn't happen + return null; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IBuildObject#getId() + */ + public String getId() { + if (parent == null) { + // bad reference + return new String(); + } + return parent.getId(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IBuildObject#getBaseId() + */ + public String getBaseId() { + if (parent == null) { + // bad reference + return new String(); + } + return parent.getBaseId(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getInputExtensions() + */ + public List getInputExtensions() { + String[] exts = getPrimaryInputExtensions(); + List extList = new ArrayList(); + for (int i=0; i 0) { + buf.append(boolCmd + WHITE_SPACE); + } + break; + + case IOption.ENUMERATED : + String enumVal = option.getEnumCommand(option.getSelectedEnum()); + if (enumVal.length() > 0) { + buf.append(enumVal + WHITE_SPACE); + } + break; + + case IOption.STRING : + String strCmd = option.getCommand(); + String val = option.getStringValue(); + if (val.length() > 0) { + if (strCmd != null) buf.append(strCmd); + buf.append(val + WHITE_SPACE); + } + break; + + case IOption.STRING_LIST : + String cmd = option.getCommand(); + String[] list = option.getStringListValue(); + for (int j = 0; j < list.length; j++) { + String temp = list[j]; + if (cmd != null) buf.append(cmd); + buf.append(temp + WHITE_SPACE); + } + break; + + case IOption.INCLUDE_PATH : + String incCmd = option.getCommand(); + String[] paths = option.getIncludePaths(); + for (int j = 0; j < paths.length; j++) { + String temp = paths[j]; + buf.append(incCmd + temp + WHITE_SPACE); + } + break; + + case IOption.PREPROCESSOR_SYMBOLS : + String defCmd = option.getCommand(); + String[] symbols = option.getDefinedSymbols(); + for (int j = 0; j < symbols.length; j++) { + String temp = symbols[j]; + buf.append(defCmd + temp + WHITE_SPACE); + } + break; + + default : + break; + } + } + } + + return buf.toString().trim(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getTopOptionCategory() + */ + public IOptionCategory getTopOptionCategory() { + try { + return parent.getTopOptionCategory(); + } catch (NullPointerException e) { + return null; + } + } + + /* (non-Javadoc) + * Answers an option reference that overrides the option, or null + * + * @param option + * @return OptionReference + */ + private OptionReference getOptionReference(IOption option) { + // Get all the option references for this option + Iterator iter = getAllOptionRefs().listIterator(); + while (iter.hasNext()) { + OptionReference optionRef = (OptionReference) iter.next(); + if (optionRef.references(option)) + return optionRef; + } + + return null; + } + + /* (non-Javadoc) + * + * @param id + * @return + */ + /* + private OptionReference getOptionReference(String id) { + Iterator it = getOptionReferenceList().iterator(); + while (it.hasNext()) { + OptionReference current = (OptionReference)it.next(); + if (current.getId().equals(id)) { + return current; + } + } + return null; + } + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolReference#getOptionReferenceList() + */ + public List getOptionReferenceList() { + if (optionReferences == null) { + optionReferences = new ArrayList(); + } + return optionReferences; + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getOptions() + */ + public IOption[] getOptions() { + IOption[] options = parent.getOptions(); + + // Replace with our references + for (int i = 0; i < options.length; ++i) { + OptionReference ref = getOptionReference(options[i]); + if (ref != null) + options[i] = ref; + } + + return options; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputExtensions() + */ + public String[] getOutputExtensions() { + if (outputExtensions == null){ + if (parent != null) { + return parent.getOutputsAttribute(); + } else { + return new String[0]; + } + } + return outputExtensions.split(DEFAULT_SEPARATOR); + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputExtension(java.lang.String) + */ + public String getOutputExtension(String inputExtension) { + if (parent == null) { + // bad reference + return new String(); + } + return parent.getOutputExtension(inputExtension); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputFlag() + */ + public String getOutputFlag() { + if (outputFlag == null) { + if (parent != null) { + return parent.getOutputFlag(); + } else { + // We never should be here + return new String(); + } + } + return outputFlag; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getOutputPrefix() + */ + public String getOutputPrefix() { + if (outputPrefix == null) { + if (parent != null) { + return parent.getOutputPrefix(); + } + return new String(); // bad reference + } + return outputPrefix; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolReference#isDirty() + */ + public boolean isDirty() { + return isDirty; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#isHeaderFile(java.lang.String) + */ + public boolean isHeaderFile(String ext) { + if (parent == null) { + // bad reference + return false; + } + return parent.isHeaderFile(ext); + } + + /** + * Answers true if the owner of the receiver matches + * the argument. + * + * @param config + * @return + */ + public boolean ownedByConfiguration(IConfigurationV2 config) { + if (owner instanceof ConfigurationV2) { + return ((IConfigurationV2)owner).equals(config); + } + return false; + } + + /** + * Persist receiver to project file. + * + * @param doc The persistent store for the reference information. + * @param element The root element in the store the receiver must use + * to persist settings. + */ + public void serialize(Document doc, Element element) { + if (parent == null) return; // This is a bad reference + element.setAttribute(ITool.ID, parent.getId()); + + // Output the command + if (command != null) { + element.setAttribute(ITool.COMMAND, getToolCommand()); + } + + // Save output prefix + if (outputPrefix != null) { + element.setAttribute(ITool.OUTPUT_PREFIX, getOutputPrefix()); + } + + // Save the output flag + if (outputFlag != null) { + element.setAttribute(ITool.OUTPUT_FLAG, getOutputFlag()); + } + + // Save the outputs + if (outputExtensions != null) { + element.setAttribute(ITool.OUTPUTS, outputExtensions); + } + + // Output the option references + Iterator iter = getOptionReferenceList().listIterator(); + while (iter.hasNext()) { + OptionReference optionRef = (OptionReference) iter.next(); + Element optionRefElement = doc.createElement(ITool.OPTION_REF); + element.appendChild(optionRefElement); + optionRef.serialize(doc, optionRefElement); + } + + // Set the reference to clean + isDirty = false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolReference#setDirty(boolean) + */ + public void setDirty(boolean isDirty) { + // Override the local flag + this.isDirty = isDirty; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolReference#setToolCommand(java.lang.String) + */ + public boolean setToolCommand(String cmd) { + if (cmd != null && !cmd.equals(command)) { + command = cmd; + isDirty = true; + return true; + } else { + return false; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setOutputFlag(java.lang.String) + */ + public void setOutputFlag(String flag) { + if (flag == null) return; + if (outputFlag == null || !(flag.equals(outputFlag))) { + outputFlag = flag; + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setOutputPrefix(java.lang.String) + */ + public void setOutputPrefix(String prefix) { + if (prefix == null) return; + if (outputPrefix == null || !(prefix.equals(outputPrefix))) { + outputPrefix = prefix; + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setOutputExtensions(java.lang.String) + */ + public void setOutputExtensions(String ext) { + if (ext == null) return; + if (outputExtensions == null || !(ext.equals(outputExtensions))) { + outputExtensions = ext; + isDirty = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setParent(IBuildObject) + */ + public void setToolParent(IBuildObject newParent) { + if (parent == null) { + // bad reference + return; + } + // Set the parent in the parent of this ToolRefernce, the tool + ((Tool)parent).setToolParent(newParent); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getParent() + */ + public IBuildObject getParent() { + return owner; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getCommandLinePattern() + */ + public String getCommandLinePattern() { + if( parent == null ) return new String(); + return parent.getCommandLinePattern(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getCommandLineGenerator() + */ + public IManagedCommandLineGenerator getCommandLineGenerator() { + if( parent == null ) return null; + return parent.getCommandLineGenerator(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getDependencyGenerator() + */ + public IManagedDependencyGenerator getDependencyGenerator() { + if( parent == null ) return null; + return parent.getDependencyGenerator(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getCommandFlags() + */ + public String[] getCommandFlags() throws BuildException { + if( parent == null ) return null; + return parent.getToolCommandFlags(null, null); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getToolCommandFlags(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) + */ + public String[] getToolCommandFlags(IPath inputFileLocation, IPath outputFileLocation) throws BuildException{ + return getCommandFlags(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getToolCommandFlagsString(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) + */ + public String getToolCommandFlagsString(IPath inputFileLocation, IPath outputFileLocation) throws BuildException{ + return getToolFlags(); + + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + String answer = new String(); + if (parent != null) { + answer += "Reference to " + parent.getName(); //$NON-NLS-1$ + } + + if (answer.length() > 0) { + return answer; + } else { + return super.toString(); + } + } + + /* + * The following methods are here in order to implement the new ITool methods. + * They should never be called. + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getSuperClass() + */ + public ITool getSuperClass() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#isAbstract() + */ + public boolean isAbstract() { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getUnusedChildren() + */ + public String getUnusedChildren() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getErrorParserList() + */ + public String[] getErrorParserList() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getErrorParserIds() + */ + public String getErrorParserIds() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setErrorParserIds() + */ + public void setErrorParserIds(String ids) { + } + + public List getInterfaceExtensions() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#isExtensionElement() + */ + public boolean isExtensionElement() { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#createOption() + */ + public IOption createOption(IOption superClass, String Id, String name, boolean b) { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IHoldsOptions#createOptions() + */ + public void createOptions(IHoldsOptions options) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#removeOption() + */ + public void removeOption(IOption o) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.IOptionCategory#getChildCategories() + */ + public IOptionCategory[] getChildCategories() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setIsAbstract(boolean) + */ + public void setIsAbstract(boolean b) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getCommandLinePattern() + */ + public void setCommandLinePattern(String pattern) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#setCommandLineGenerator(IConfigurationElement) + */ + public void setCommandLineGeneratorElement(IConfigurationElement element) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getCommandLineGenerator() + */ + public IConfigurationElement getDependencyGeneratorElement() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#setCommandLineGenerator(IConfigurationElement) + */ + public void setDependencyGeneratorElement(IConfigurationElement element) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getCommandLineGeneratorElement() + */ + public IConfigurationElement getCommandLineGeneratorElement() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getAdvancedInputCategory() + */ + public boolean getAdvancedInputCategory() { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#setAdvancedInputCategory() + */ + public void setAdvancedInputCategory(boolean display) { + } + + public IInputType createInputType(IInputType superClass, String Id, String name, boolean isExtensionElement) { + return null; + } + + public IOutputType createOutputType(IOutputType superClass, String Id, String name, boolean isExtensionElement) { + return null; + } + + public String getAnnouncement() { + return null; + } + + public IInputType getInputTypeById(String id) { + return null; + } + + public IInputType[] getInputTypes() { + return null; + } + + public IOutputType getOutputTypeById(String id) { + return null; + } + + public IOutputType[] getOutputTypes() { + return null; + } + + public void removeInputType(IInputType type) { + } + + public void removeOutputType(IOutputType type) { + } + + public void setAnnouncement(String announcement) { + } + + public String getDefaultInputExtension() { + return null; + } + + public String[] getAllInputExtensions() { + return null; + } + + public String[] getPrimaryInputExtensions() { + return null; + } + + public IInputType getInputType(String inputExtension) { + return null; + } + + public String[] getOutputsAttribute() { + return null; + } + + public IOutputType getOutputType(String outputExtension) { + return null; + } + + public void setOutputsAttribute(String extensions) { + } + + public String[] getAllOutputExtensions() { + return null; + } + + public String[] getAllDependencyExtensions() { + return null; + } + + public IInputType getPrimaryInputType() { + return null; + } + + public IOutputType getPrimaryOutputType() { + return null; + } + + public IPath[] getAdditionalDependencies() { + return null; + } + + public IPath[] getAdditionalResources() { + return null; + } + + public IConfigurationElement getDependencyGeneratorElementForExtension(String sourceExt) { + return null; + } + + public IManagedDependencyGeneratorType getDependencyGeneratorForExtension(String sourceExt) { + return null; + } + + public boolean getCustomBuildStep() { + return false; + } + + public void setCustomBuildStep(boolean customBuildStep) { + } + + public IOption getOptionBySuperClassId(String id) { + return null; + } + + public IOptionCategory getOptionCategory(String id) { + // return null as class is deprecated + return null; + } + + public void addOptionCategory(IOptionCategory category) { + } + + /* + * The following methods are added to allow the converter from ToolReference -> Tool + * to retrieve the actual value of attributes. These routines do not go to the + * referenced Tool for a value if the ToolReference does not have a value. + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolReference#getRawOutputExtensions() + */ + public String getRawOutputExtensions() { + return outputExtensions; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolReference#getRawOutputFlag() + */ + public String getRawOutputFlag() { + return outputFlag; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolReference#getRawOutputPrefix() + */ + public String getRawOutputPrefix() { + return outputPrefix; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolReference#getRawToolCommand() + */ + public String getRawToolCommand() { + return command; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getConvertToId() + */ + public String getConvertToId() { + if (convertToId == null) { + // If I have a superClass, ask it + if (parent != null) { + return parent.getConvertToId(); + } else { + return new String(); + } + } + return convertToId; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setConvertToId(String) + */ + public void setConvertToId(String convertToId) { + if (convertToId == null && this.convertToId == null) return; + if (convertToId == null || this.convertToId == null || !convertToId.equals(this.convertToId)) { + this.convertToId = convertToId; + setDirty(true); + } + return; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getVersionsSupported() + */ + public String getVersionsSupported() { + if (versionsSupported == null) { + // If I have a superClass, ask it + if (parent != null) { + return parent.getVersionsSupported(); + } else { + return new String(); + } + } + return versionsSupported; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#setVersionsSupported(String) + */ + public void setVersionsSupported(String versionsSupported) { + if (versionsSupported == null && this.versionsSupported == null) return; + if (versionsSupported == null || this.versionsSupported == null || !versionsSupported.equals(this.versionsSupported)) { + this.versionsSupported = versionsSupported; + setDirty(true); + } + return; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getEnvVarBuildPaths() + */ + public IEnvVarBuildPath[] getEnvVarBuildPaths(){ + return null; + } + + public PluginVersionIdentifier getVersion() { + return null; + } + + public void setVersion(PluginVersionIdentifier version) { + // TODO Auto-generated method stub + } + + public String getManagedBuildRevision() { + return null; + } + + public IOption getOptionToSet(IOption option, boolean adjustExtension){ + return null; + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyCalculator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyCalculator.java new file mode 100755 index 00000000000..71775b26b28 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyCalculator.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2006 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.makegen; + +import org.eclipse.core.runtime.IPath; + +/** + * @since 3.1 + * + * A Tool dependency calculator may implement this interface or + * IManagedDependencyCommands or IManagedDependencyPreBuild. + * An object implementing the interface is returned from a call to + * IManagedDependencyGenerator2.getDependencySourceInfo. + * + * Discussion of Dependency Calculation: + * + * There are two major, and multiple minor, modes of dependency calculation + * supported by the MBS. The major modes are: + * + * 1. The build file generator invokes tool integrator provided methods + * that calculate all dependencies using whatever method the tool + * integrator wants. The build file generator then adds the dependencies + * to the build file using the appropriate build file syntax. + * This type of dependency calculator implements the + * IManagedDependencyCalculator interface defined in this module. + * + * One minor mode of this mode is to use a dependency calculator provided + * by a language integration (e.g. C, C++ or Fortran) that uses the + * language's parsing support to return information regarding source file + * dependencies. An example of this is using the C/C++ Indexer to + * compute dependencies. + * + * 2. The build file generator and the tool-chain cooperate in creating and + * using separate "dependency" files. In this case, dependency calculation + * is done at "build time", rather than at "build file generation time" as + * in mode #1. This currently supports the GNU concept of using .d files + * in GNU make. See the IManagedDependencyCommands and + * IManagedDependencyPreBuild interfaces for more information. + * + */ + +public interface IManagedDependencyCalculator extends IManagedDependencyInfo { + + /** + * Returns the list of source file specific dependencies. + * + * The paths can be either relative to the project directory, or absolute + * in the file system. + * + * @return IPath[] + */ + public IPath[] getDependencies(); + + /** + * Returns the list of source file specific additional targets that the + * source file creates. Most source files will return null. An example + * of where additional targets should be returned is for a Fortran 90 + * source file that creates one or more Fortran Modules. + * + * Note that these output files that are dependencies to other invocations + * of the same tool can be specified here, or as another output type + * of the tool. If the output file can be used as the input of a different + * tool, then use the output type mechanism. + * + * The paths can be either relative to the top build directory, or absolute + * in the file system. + * + * @return IPath[] + */ + public IPath[] getAdditionalTargets(); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyCommands.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyCommands.java new file mode 100755 index 00000000000..3e451e6a5eb --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyCommands.java @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright (c) 2006 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.makegen; + +import org.eclipse.core.runtime.IPath; + +/** + * @since 3.1 + * + * A Tool dependency calculator may implement this interface or + * IManagedDependencyCalculator or IManagedDependencyPreBuild. + * An object implementing the interface is returned from a call to + * IManagedDependencyGenerator2.getDependencySourceInfo. + * + * Discussion of Dependency Calculation: + * + * There are two major, and multiple minor, modes of dependency calculation + * supported by the MBS. The major modes are: + * + * 1. The build file generator invokes tool integrator provided methods + * that calculate all dependencies using whatever method the tool + * integrator wants. The build file generator then adds the dependencies + * to the build file using the appropriate build file syntax. + * See the IManagedDependencyCalculator interface for more information. + * + * 2. The build file generator and the tool-chain cooperate in creating and + * using separate "dependency" files. The build file generator calls + * the dependency calculator to get the dependency file names and to get + * commands that need to be added to the build file. In this case, + * dependency calculation is done at "build time", rather than at + * "build file generation time" as in mode #1. This currently + * supports the GNU concept of using .d files in GNU make. + * + * There are multiple ways that these separate dependency files can + * be created by the tool-chain and used by the builder. + * + * a. In some cases (e.g., Fortran 90 using modules) the dependency files + * must be created/updated prior to invoking the build of the project + * artifact (e.g., an application). In this case, the dependency + * generation step must occur separately before the main build. + * See the IManagedDependencyPreBuild interface for more information. + * + * b. In other cases (e.g., C/C++) the dependency files can be created as + * a side effect of the main build. This implies that the up to date + * dependency files are not required for the current build, but for + * the next build. C/C++ builds can be treated in this manner as is + * described in the following link: + * http://sourceware.org/automake/automake.html#Dependency-Tracking-Evolution + * + * Use the IManagedDependencyCommands interface defined in this file + * for this mode. + * + * Two sub-scenarios of this mode are to: + * + * Create dependency files in the same invocation of the tool that + * creates the tool's build artifact - by adding additional options + * to the tool invocation command line. + * + * Create dependency files in a separate invocation of the tool, or + * by the invocation of another tool. + * + * MBS can also help in the generation of the dependency files. Prior to + * CDT 3.1, MBS and gcc cooperated in generating dependency files using the + * following steps: + * + * 1. Gcc is invoked to perform the compilation that generates the object + * file. + * + * 2. An "echo" command creates the .d file, adding the name of the .d + * file to the beginning of the newly created .d file. Note that this + * causes problems with some implementations of "echo" that don't + * work exactly the way that we want (e.g., it doesn't support the -n + * switch). + + * 3. Gcc is invoked again with the appropriate additional command line + * options to append its dependency file information to the .d file + * that was created by "echo". + * + * 4. Steps 1 - 3 are invoked in the make file. Step 4 occurs after the + * make invocation has finished. In step 4, MBS code post-processes + * the .d files to add a dummy dependency for each header file, for + * the reason explained in the link above. + * + * This mode is no longer used by the default gcc implementation, but can + * still be used by selecting the DefaultGCCDependencyCalculator. + * + * + * Note for GNU make: these separate dependency files are "include"d by + * a main makefile. Therefore, if the dependency files are required to + * be up to date before the main build begins, they must be updated by + * a separate invocation of make. Also, the configuration "clean" step + * must be invoked by a separate invocation of make. This is so that + * we can exclude the dependency files for a "make clean" invocation + * using syntax like: + * + * ifneq ($(MAKECMDGOALS), clean) + * -include $(DEPS) + * endif + * + * Otherwise, because GNU make attempts to re-make make files, we + * can end up with out of date or missing dependency files being + * re-generated and then immediately "clean"ed. + */ + +public interface IManagedDependencyCommands extends IManagedDependencyInfo { + + /** + * Returns the list of generated dependency files. + * + * The paths can be either relative to the top build directory, or absolute + * in the file system. + * + * @return IPath[] + */ + public IPath[] getDependencyFiles(); + + /** + * Returns the command lines to be invoked before the normal tool invocation + * to calculate dependencies. + * + * @return String[] This can be null or an empty array if no dependency + * generation command needs to be invoked before the normal + * tool invocation. + */ + public String[] getPreToolDependencyCommands(); + + /** + * Returns the command line options to be used to calculate dependencies. + * The options are added to the normal tool invocation. + * + * @return String[] This can be null or an empty array if no additional + * arguments need to be added to the tool invocation. + * SHOULD THIS RETURN AN IOption[]? + */ + public String[] getDependencyCommandOptions(); + // IMPLEMENTATION NOTE: This should be called from addRuleFromSource for both resconfig & non-resconfig + + /** + * Returns the command lines to be invoked after the normal tool invocation + * to calculate dependencies. + * + * @return String[] This can be null or an empty array if no dependency + * generation commands needs to be invoked after the normal + * tool invocation + */ + public String[] getPostToolDependencyCommands(); + + /** + * Returns true if the command lines and/or options returned by this interface + * are not specific to the particular source file, but are only specific to, + * at most, the configuration and tool. If the build context is a resource + * configuration, this method should return false if any of the command lines + * and/or options are different than if the build context were the parent + * configuration. This can be used by the build file generator in helping + * to determine if a "pattern" (generic) rule can be used. + * + * @return boolean + */ + public boolean areCommandsGeneric(); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGenerator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGenerator.java index c096e9887fa..5511d473dfe 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGenerator.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGenerator.java @@ -1,35 +1,27 @@ -/******************************************************************************* - * Copyright (c) 2004, 2005 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.makegen; - -import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; - -/** - * @since 2.0 - * - * TODO: These methods should take IPath's rather than IResource's, - * because an output file from one tool can be used as an - * input file to another, and it can be generated outside of the - * project directory. - * This will require a new interface. -*/ -public interface IManagedDependencyGenerator { - public int TYPE_NODEPS = 0; - public int TYPE_COMMAND = 1; - public int TYPE_INDEXER = 2; - public int TYPE_EXTERNAL = 3; - - public IResource[] findDependencies(IResource resource, IProject project); - public int getCalculatorType(); - public String getDependencyCommand(IResource resource, IManagedBuildInfo info); -} +/******************************************************************************* + * Copyright (c) 2004, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.makegen; + +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; + +/** + * @since 2.0 + * @deprecated 3.1 + * + * Use IManagedDependencyGenerator2 instead. +*/ +public interface IManagedDependencyGenerator extends IManagedDependencyGeneratorType { + + public IResource[] findDependencies(IResource resource, IProject project); + public String getDependencyCommand(IResource resource, IManagedBuildInfo info); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGenerator2.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGenerator2.java index b9b1c9c75da..3d16344053c 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGenerator2.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGenerator2.java @@ -1,89 +1,114 @@ -/******************************************************************************* - * Copyright (c) 2005 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation of IManagedDependencyGenerator - * Intel - Initial API and implementation of IManagedDependencyGenerator2 - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.makegen; - -import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; -import org.eclipse.core.runtime.IPath; -import org.eclipse.cdt.managedbuilder.core.ITool; - -/** - * @since NOT YET - * This interface is PROPOSED and not yet used. - * - * A Tool dependency calculator must implement this interface. This interface - * replaces IManagedDependencyGenerator which is deprecated. - * - * Note: The IPath arguments to the methods below can be either relative to - * the project directory, or absolute in the file system. - */ -public interface IManagedDependencyGenerator2 { - /** - * Constants returned by getCalculatorType - */ - public int TYPE_NODEPS = 0; - public int TYPE_COMMAND = 1; - public int TYPE_INDEXER = 2; - public int TYPE_EXTERNAL = 3; - - /** - * Returns the type of dependency generator that is implemented. - * - * TYPE_NODEPS indicates a NULL dependency generator - * TYPE_COMMAND indicates that a command line will be returned to be - * used to calculate dependencies. This currently supports compilers - * that generate .d files. - * TYPE_INDEXER indicates that the CDT indexer should be used to - * calculate the dependencies. - * TYPE_EXTERNAL indicates that a custom dependency calculator is - * implemented. - * - * @return int - */ - public int getCalculatorType(); - - /** - * Returns the list of dependencies for this source file. - * The paths can be either relative to the project directory, or absolute - * in the file system. - * - * @param source The source file for which dependencies should be calculated - * @param info The IManagedBuildInfo of the project - * @param tool The tool associated with the source file - * @param topBuildDirectory The top build directory of the project. This is - * the working directory for the tool. - * @return IPath[] - */ - public IPath[] findDependencies( - IPath source, - IManagedBuildInfo info, - ITool tool, - IPath topBuildDirectory); - - /** - * - * Returns the command line to be used to calculate dependencies. - * This currently supports compilers that generate .d files - * - * @param source The source file for which dependencies should be calculated - * @param info The IManagedBuildInfo of the project - * @param tool The tool associated with the source file - * @param topBuildDirectory The top build directory of the project. This is - * the working directory for the tool. - * - * @return String - */ - public String getDependencyCommand( - IPath source, - IManagedBuildInfo info, - ITool tool, - IPath topBuildDirectory); -} +/******************************************************************************* + * Copyright (c) 2005, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation of IManagedDependencyGenerator + * Intel - Initial API and implementation of IManagedDependencyGenerator2 + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.makegen; + +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.core.runtime.IPath; +import org.eclipse.cdt.managedbuilder.core.ITool; + +/** + * @since 3.1 + * + * A Tool dependency calculator must implement this interface. This interface + * replaces IManagedDependencyGenerator which is deprecated. + * + * Discussion of Dependency Calculation: + * + * There are two major, and multiple minor, modes of dependency calculation + * supported by the MBS. The major modes are: + * + * 1. The build file generator invokes tool integrator provided methods + * that calculate all dependencies using whatever method the tool + * integrator wants. The build file generator then adds the dependencies + * to the build file using the appropriate build file syntax. + * This is a TYPE_CUSTOM dependency calculator as defined below. + * See the IManagedDependencyCalculator interface for more information. + * + * 2. The build file generator and the tool-chain cooperate in creating and + * using separate "dependency" files. In this case, dependency calculation + * is done at "build time", rather than at "build file generation time" as + * in mode #1. This currently supports the GNU concept of using .d files + * in GNU make. + * This is either a TYPE_BUILD_COMMANDS dependency calculator or a + * TYPE_PREBUILD_COMMANDS dependency calculator as defined below. + * See the IManagedDependencyCommands and IManagedDependencyPreBuild + * interfaces for more information. + * + */ + +public interface IManagedDependencyGenerator2 extends IManagedDependencyGeneratorType { + + /** + * Returns an instance of IManagedDependencyInfo for this source file. + * IManagedDependencyCalculator, IManagedDependencyCommands + * and IManagedDependencyPreBuild are all derived from + * IManagedDependencyInfo, and any one of the three can be returned. + * This is called when getCalculatorType returns TYPE_BUILD_COMMANDS, + * TYPE_CUSTOM or TYPE_PREBUILD_COMMANDS. + * + * @param source The source file for which dependencies should be calculated + * The IPath can be either relative to the project directory, or absolute in the file system. + * @param buildContext The IConfiguration or IResourceConfiguration that + * contains the context in which the source file will be built + * @param tool The tool associated with the source file + * @param topBuildDirectory The top build directory of the configuration. This is + * the working directory for the tool. This IPath is relative to the project directory. + * @return IManagedDependencyInfo + */ + public IManagedDependencyInfo getDependencySourceInfo( + IPath source, + IBuildObject buildContext, + ITool tool, + IPath topBuildDirectory); + + /** + * Returns the file extension used by dependency files created + * by this dependency generator. + * This is called when getCalculatorType returns TYPE_BUILD_COMMANDS or + * TYPE_PREBUILD_COMMANDS. + * + * @param buildContext The IConfiguration that contains the context of the build + * @param tool The tool associated with the dependency generator. + * + * @return String + */ + public String getDependencyFileExtension( + IConfiguration buildContext, + ITool tool); + + /** + * Called to allow the dependency calculator to post-process dependency files. + * This method is called after the build has completed for at least every + * dependency file that has changed, and possibly for those that have not + * changed as well. It may also be called with dependency files created by + * another tool. This method should be able to recognize dependency files + * that don't belong to it, or that it has already post-processed. + * This is called when getCalculatorType returns TYPE_BUILD_COMMANDS or + * TYPE_PREBUILD_COMMANDS. + * + * @param dependencyFile The dependency file + * The IPath can be either relative to the top build directory, or absolute in the file system. + * @param buildContext The IConfiguration that contains the context of the build + * @param tool The tool associated with the dependency generator. Note that this is + * not necessarily the tool that created the dependency file + * @param topBuildDirectory The top build directory of the project. This is + * the working directory for the tool. + * + * @return boolean True if the method modified the dependency (e.g., .d) file + */ + public boolean postProcessDependencyFile( + IPath dependencyFile, + IConfiguration buildContext, + ITool tool, + IPath topBuildDirectory); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGeneratorType.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGeneratorType.java new file mode 100755 index 00000000000..bca6f078f11 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyGeneratorType.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2006 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.makegen; + +/** + * @since 3.1 + * + * IManagedDependencyGenerator (deprecated) and IManagedDependencyGenerator2 + * extend this interface. + * + * Discussion of Dependency Calculation: + * + * There are two major, and multiple minor, modes of dependency calculation + * supported by the MBS. The major modes are: + * + * 1. The build file generator invokes tool integrator provided methods + * that calculate all dependencies using whatever method the tool + * integrator wants. The build file generator then adds the dependencies + * to the build file using the appropriate build file syntax. + * This is a TYPE_CUSTOM dependency calculator as defined below. + * See the IManagedDependencyCalculator interface for more information. + * + * 2. The build file generator and the tool-chain cooperate in creating and + * using separate "dependency" files. In this case, dependency calculation + * is done at "build time", rather than at "build file generation time" as + * in mode #1. This currently supports the GNU concept of using .d files + * in GNU make. + * This is either a TYPE_BUILD_COMMANDS dependency calculator or a + * TYPE_PREBUILD_COMMANDS dependency calculator as defined below. + * See the IManagedDependencyCommands and IManagedDependencyPreBuild + * interfaces for more information. + * + */ + +public interface IManagedDependencyGeneratorType { + /** + * Constants returned by getCalculatorType + */ + public int TYPE_NODEPS = 0; // Deprecated - use TYPE_NODEPENDENCIES + public int TYPE_COMMAND = 1; // Deprecated - use TYPE_BUILD_COMMANDS + public int TYPE_INDEXER = 2; // Deprecated - use TYPE_CUSTOM + public int TYPE_EXTERNAL = 3; // Deprecated - use TYPE_CUSTOM + public int TYPE_OLD_TYPE_LIMIT = 3; + + // Use these types + public int TYPE_NODEPENDENCIES = 4; + public int TYPE_BUILD_COMMANDS = 5; + public int TYPE_PREBUILD_COMMANDS = 6; + public int TYPE_CUSTOM = 7; + + /** + * Returns the type of dependency generator that is implemented. + * + * TYPE_NODEPENDENCIES indicates that no dependency generator is + * supplied or needed. + * TYPE_CUSTOM indicates that a custom, "build file generation time" + * dependency calculator is implemented. Note that the dependency + * calculator will be called when the makefile is generated, and + * for every source file that is built by this tool in the build + * file, not just for those that have changed since the last build + * file generation. + * TYPE_BUILD_COMMANDS indicates that command lines or options will + * be returned to be used to calculate dependencies. These + * commands/options are added to the build file to perform dependency + * calculation at "build time". This currently supports + * compilers/tools that generate .d files either as a + * side-effect of tool invocation, or as a separate step that is + * invoked immediately before or after the tool invocation. + * TYPE_PREBUILD_COMMANDS indicates that a separate build step is + * invoked, prior to the the normal build steps, to update the + * dependency information. These commands are added to the build + * file to perform dependency calculation at "build time". Note + * that this step will be invoked every time a build is done in + * order to determine if dependency files need to be re-generated. + * + * @return int + */ + public int getCalculatorType(); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyInfo.java new file mode 100755 index 00000000000..849bbd774c2 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyInfo.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2006 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.makegen; + +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.core.runtime.IPath; + +/** + * @since 3.1 + * + * This interface is the base interface for IManagedDependencyCalculator, + * IManagedDependencyCommands and IManagedDependencyPreBuild. See these + * interfaces and IManagedDependencyGenerator2 for more information on + * writing a dependency calculator. + * + * The methods below simply return the arguments passed to the + * IManagedDependencyGenerator2.getDependency*Info call that created the + * IManagedDependencyInfo instance. + * + */ +public interface IManagedDependencyInfo { + public IPath getSource(); + public IBuildObject getBuildContext(); + public ITool getTool(); + public IPath getTopBuildDirectory(); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyPreBuild.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyPreBuild.java new file mode 100755 index 00000000000..83ef41a83da --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/IManagedDependencyPreBuild.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright (c) 2006 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.makegen; + +import org.eclipse.core.runtime.IPath; + +/** + * @since 3.1 + * + * A Tool dependency calculator may implement this interface or + * IManagedDependencyCalculator or IManagedDependencyCommands. + * An object implementing the interface is returned from a call to + * IManagedDependencyGenerator2.getDependencySourceInfo. + * + * Discussion of Dependency Calculation: + * + * There are two major, and multiple minor, modes of dependency calculation + * supported by the MBS. The major modes are: + * + * 1. The build file generator invokes tool integrator provided methods + * that calculate all dependencies using whatever method the tool + * integrator wants. The build file generator then adds the dependencies + * to the build file using the appropriate build file syntax. + * See the IManagedDependencyCalculator interface for more information. + * + * 2. The build file generator and the tool-chain cooperate in creating and + * using separate "dependency" files. The build file generator calls + * the dependency calculator to get the dependency file names and to get + * commands that need to be added to the build file. In this case, + * dependency calculation is done at "build time", rather than at + * "build file generation time" as in mode #1. This currently + * supports the GNU concept of using .d files in GNU make. + * + * There are multiple ways that these separate dependency files can + * be created by the tool-chain and used by the builder. + * + * a. In some cases (e.g., Fortran 90 using modules) the dependency files + * must be created/updated prior to invoking the build of the project + * artifact (e.g., an application). In this case, the dependency + * generation step must occur separately before the main build. + * Use the IManagedDependencyPreBuild interface defined in this file + * for this mode. + * + * b. In other cases (e.g., C/C++) the dependency files can be created as + * a side effect of the main build. This implies that the up to date + * dependency files are not required for the current build, but for + * the next build. C/C++ builds can be treated in this manner as is + * described in the following link: + * http://sourceware.org/automake/automake.html#Dependency-Tracking-Evolution + * + * See the IManagedDependencyCommands interface for more information. + * + * + * Note for GNU make: these separate dependency files are "include"d by + * a main makefile. Make performs special processing on make files: + * + * "To this end, after reading in all makefiles, make will consider + * each as a goal target and attempt to update it. If a makefile has a + * rule which says how to update it (found either in that very + * makefile or in another one)..., it will be updated if necessary. + * After all makefiles have been checked, if any have actually been + * changed, make starts with a clean slate and reads all the makefiles + * over again." + * + * We can use this to ensure that the dependency files are up to date + * by adding rules to the make file for generating the dependency files. + * These rules are returned by the call to getDependencyCommands. + * However, this has a significant problem when we don’t want to build + * the build target, but only want to “clean” the configuration, + * for example. If we invoke make just to clean the configuration, + * make will still update the dependency files if necessary, thereby + * re-generating the dependency files only to immediately delete them. + * The workaround suggested by the make documentation is to check for + * an invocation using the “clean” target, and to not include the + * dependency files it that case. For example, + * + * ifneq ($(MAKECMDGOALS),clean) + * include $(DEPS) + * endif + * + * The restriction with this is that it only works if “clean” is the only + * target specified on the make command line. Therefore, the build + * "clean" step must be invoked separately. + */ + +public interface IManagedDependencyPreBuild extends IManagedDependencyInfo { + + /** + * Returns the list of generated dependency files. + * + * The paths can be either relative to the top build directory, or absolute + * in the file system. + * + * @return IPath[] + */ + public IPath[] getDependencyFiles(); + + /** + * Returns the name to be used in the build file to identify the separate + * build step. Note that this name should be unique to the tool since + * multiple tools in a tool-chain may be using this method of + * dependency calculation. + * + * @return String + */ + public String getBuildStepName(); + + /** + * Returns the command line(s) to be invoked in the separate + * dependencies pre-build step. + * + * @return String[] + */ + public String[] getDependencyCommands(); + + /** + * Returns true if the command lines returned by this interface + * are not specific to the particular source file, but are only specific to, + * at most, the configuration and tool. If the build context is a resource + * configuration, this method should return false if any of the command lines + * are different than if the build context were the parent configuration. + * This can be used by the build file generator in helping to determine if + * a "pattern" (generic) rule can be used. + * + * @return boolean + */ + public boolean areCommandsGeneric(); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator.java index a016899a7ad..900502650da 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator.java @@ -1,300 +1,300 @@ -/******************************************************************************* - * Copyright (c) 2004, 2005 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.makegen.gnu; - -import org.eclipse.cdt.managedbuilder.core.BuildException; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; -import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; -import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo; -import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; -import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; -import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; -import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Path; - -/** - * @since 2.0 - */ -public class DefaultGCCDependencyCalculator implements IManagedDependencyGenerator { - - private static final String EMPTY_STRING = new String(); - private static final String[] EMPTY_STRING_ARRAY = new String[0]; - public final String WHITESPACE = " "; //$NON-NLS-1$ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#findDependencies(org.eclipse.core.resources.IResource) - */ - public IResource[] findDependencies(IResource resource, IProject project) { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getCalculatorType() - */ - public int getCalculatorType() { - return TYPE_COMMAND; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getDependencyCommand() - */ - public String getDependencyCommand(IResource resource, IManagedBuildInfo info) { - /* - * For a given input, /., return a string containing - * echo -n $(@:%.=%.d) '/' >> $(@:%.=%.d) && \ - * -P -MM -MG $< >> $(@:%.=%.d) - * - */ - StringBuffer buffer = new StringBuffer(); - - // Get what we need to create the dependency generation command - IConfiguration config = info.getDefaultConfiguration(); - - // We need to check whether we have any resource specific build information. - IResourceConfiguration resConfig = null; - if( config != null ) resConfig = config.getResourceConfiguration(resource.getFullPath().toString()); - - String inputExtension = resource.getFileExtension(); - String outputExtension = info.getOutputExtension(inputExtension); - - // Work out the build-relative path for the output files - IContainer resourceLocation = resource.getParent(); - String relativePath = new String(); - if (resourceLocation != null) { - relativePath += resourceLocation.getProjectRelativePath().toString(); - } - if (relativePath.length() > 0) { - relativePath += IManagedBuilderMakefileGenerator.SEPARATOR; - } - - // Calculate the dependency rule - // /$(@:%.=%.d) - String depRule = "'$(@:%." + //$NON-NLS-1$ - outputExtension + - "=%." + //$NON-NLS-1$ - IManagedBuilderMakefileGenerator.DEP_EXT + - ")'"; //$NON-NLS-1$ - - // Add the rule that will actually create the right format for the dep - buffer.append(IManagedBuilderMakefileGenerator.TAB + - IManagedBuilderMakefileGenerator.ECHO + - IManagedBuilderMakefileGenerator.WHITESPACE + - "-n" + //$NON-NLS-1$ - IManagedBuilderMakefileGenerator.WHITESPACE + - depRule + - IManagedBuilderMakefileGenerator.WHITESPACE + - "$(dir $@)" + //$NON-NLS-1$ - IManagedBuilderMakefileGenerator.WHITESPACE + - ">" + //$NON-NLS-1$ - IManagedBuilderMakefileGenerator.WHITESPACE + - depRule + - IManagedBuilderMakefileGenerator.WHITESPACE + - IManagedBuilderMakefileGenerator.LOGICAL_AND + - IManagedBuilderMakefileGenerator.WHITESPACE + - IManagedBuilderMakefileGenerator.LINEBREAK); - - // Add the line that will do the work to calculate dependencies - IManagedCommandLineInfo cmdLInfo = null; - String buildCmd = null; - String[] inputs= new String[1]; inputs[0] = IManagedBuilderMakefileGenerator.IN_MACRO; - String outflag = ""; //$NON-NLS-1$ - String outputPrefix = ""; //$NON-NLS-1$ - String outputFile = ""; //$NON-NLS-1$ - ITool[] tools; - if( resConfig != null && (tools = resConfig.getToolsToInvoke()) != null && tools.length > 0) { - ITool tool = tools[0]; - String cmd = tool.getToolCommand(); - //try to resolve the build macros in the tool command - try { - String resolvedCommand = null; - - // does the resource have spaces in its name? - if (resource.getProjectRelativePath().toString().indexOf(" ") != -1) { - // use fully qualified strings - resolvedCommand = ManagedBuildManager - .getBuildMacroProvider() - .resolveValueToMakefileFormat( - cmd, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(resource.getLocation(), - null, null, tool)); - } else { - // use builder variables - resolvedCommand = ManagedBuildManager - .getBuildMacroProvider() - .resolveValueToMakefileFormat( - cmd, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(resource.getLocation(), - null, null, tool)); - } - - if((resolvedCommand = resolvedCommand.trim()).length() > 0) - cmd = resolvedCommand; - - } catch (BuildMacroException e){ - } - - String[] toolFlags = null; - try { - toolFlags = tool.getToolCommandFlags(resource.getLocation(),null); - } catch( BuildException ex ) { - // TODO add some routines to catch this - toolFlags = EMPTY_STRING_ARRAY; - } - String[] flags = new String[toolFlags.length + 4]; - flags[0] = "-MM"; //$NON-NLS-1$ - flags[1] = "-MG"; //$NON-NLS-1$ - flags[2] = "-P"; //$NON-NLS-1$ - flags[3] = "-w"; //$NON-NLS-1$ - for (int i=0; i 0) - buildCmd = resolvedCommand; - - } catch (BuildMacroException e){ - } - - - } else { - ITool tool = null; - tools = config.getFilteredTools(); - for (int index = 0; index < tools.length; index++) { - ITool tmp = tools[index]; - if (tmp.buildsFileType(inputExtension)) { - tool = tmp; - break; - } - } - String cmd = tool != null ? tool.getToolCommand() : null; - - //try to resolve the build macros in the tool command - try{ - String resolvedCommand = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(cmd, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(resource.getLocation(),null,null,tool)); - if((resolvedCommand = resolvedCommand.trim()).length() > 0) - cmd = resolvedCommand; - - } catch (BuildMacroException e){ - } - - String buildFlags = "-MM -MG -P -w " + info.getToolFlagsForSource(inputExtension, resource.getLocation(), null); //$NON-NLS-1$ - String[] flags = buildFlags.split( "\\s" ); //$NON-NLS-1$ - cmdLInfo = info.generateToolCommandLineInfo( inputExtension, flags, outflag, outputPrefix, - outputFile, inputs, resource.getLocation(), null); - // The command to build - if( cmdLInfo == null ) buildCmd = - cmd + - IManagedBuilderMakefileGenerator.WHITESPACE + - "-MM -MG -P -w " + //$NON-NLS-1$ - buildFlags + - IManagedBuilderMakefileGenerator.WHITESPACE + - IManagedBuilderMakefileGenerator.IN_MACRO; - else { - buildCmd = cmdLInfo.getCommandLine(); - } - - // resolve any remaining macros in the command after it has been - // generated - try { - String resolvedCommand = null; - - // does the resource have spaces in its name? - if (resource.getProjectRelativePath().toString().indexOf(" ") != -1) { - // use fully qualified strings - resolvedCommand = ManagedBuildManager - .getBuildMacroProvider() - .resolveValueToMakefileFormat( - buildCmd, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(resource.getLocation(), - null, null, tool)); - } else { - // use builder variables - resolvedCommand = ManagedBuildManager - .getBuildMacroProvider() - .resolveValueToMakefileFormat( - buildCmd, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(resource.getLocation(), - null, null, tool)); - } - if ((resolvedCommand = resolvedCommand.trim()).length() > 0) - buildCmd = resolvedCommand; - - } catch (BuildMacroException e) { - } - } - - buffer.append(IManagedBuilderMakefileGenerator.TAB + - buildCmd + - IManagedBuilderMakefileGenerator.WHITESPACE + - ">>" + //$NON-NLS-1$ - IManagedBuilderMakefileGenerator.WHITESPACE + depRule ); - - return buffer.toString(); - } - -} +/******************************************************************************* + * Copyright (c) 2004, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.makegen.gnu; + +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; +import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo; +import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +/** + * @since 2.0 + */ +public class DefaultGCCDependencyCalculator implements IManagedDependencyGenerator { + + private static final String EMPTY_STRING = new String(); + private static final String[] EMPTY_STRING_ARRAY = new String[0]; + public final String WHITESPACE = " "; //$NON-NLS-1$ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#findDependencies(org.eclipse.core.resources.IResource) + */ + public IResource[] findDependencies(IResource resource, IProject project) { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getCalculatorType() + */ + public int getCalculatorType() { + return TYPE_COMMAND; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getDependencyCommand() + */ + public String getDependencyCommand(IResource resource, IManagedBuildInfo info) { + /* + * For a given input, /., return a string containing + * echo -n $(@:%.=%.d) '/' >> $(@:%.=%.d) && \ + * -P -MM -MG $< >> $(@:%.=%.d) + * + */ + StringBuffer buffer = new StringBuffer(); + + // Get what we need to create the dependency generation command + IConfiguration config = info.getDefaultConfiguration(); + + // We need to check whether we have any resource specific build information. + IResourceConfiguration resConfig = null; + if( config != null ) resConfig = config.getResourceConfiguration(resource.getFullPath().toString()); + + String inputExtension = resource.getFileExtension(); + String outputExtension = info.getOutputExtension(inputExtension); + + // Work out the build-relative path for the output files + IContainer resourceLocation = resource.getParent(); + String relativePath = new String(); + if (resourceLocation != null) { + relativePath += resourceLocation.getProjectRelativePath().toString(); + } + if (relativePath.length() > 0) { + relativePath += IManagedBuilderMakefileGenerator.SEPARATOR; + } + + // Calculate the dependency rule + // /$(@:%.=%.d) + String depRule = "'$(@:%." + //$NON-NLS-1$ + outputExtension + + "=%." + //$NON-NLS-1$ + IManagedBuilderMakefileGenerator.DEP_EXT + + ")'"; //$NON-NLS-1$ + + // Add the rule that will actually create the right format for the dep + buffer.append(IManagedBuilderMakefileGenerator.TAB + + IManagedBuilderMakefileGenerator.ECHO + + IManagedBuilderMakefileGenerator.WHITESPACE + + "-n" + //$NON-NLS-1$ + IManagedBuilderMakefileGenerator.WHITESPACE + + depRule + + IManagedBuilderMakefileGenerator.WHITESPACE + + "$(dir $@)" + //$NON-NLS-1$ + IManagedBuilderMakefileGenerator.WHITESPACE + + ">" + //$NON-NLS-1$ + IManagedBuilderMakefileGenerator.WHITESPACE + + depRule + + IManagedBuilderMakefileGenerator.WHITESPACE + + IManagedBuilderMakefileGenerator.LOGICAL_AND + + IManagedBuilderMakefileGenerator.WHITESPACE + + IManagedBuilderMakefileGenerator.LINEBREAK); + + // Add the line that will do the work to calculate dependencies + IManagedCommandLineInfo cmdLInfo = null; + String buildCmd = null; + String[] inputs= new String[1]; inputs[0] = IManagedBuilderMakefileGenerator.IN_MACRO; + String outflag = ""; //$NON-NLS-1$ + String outputPrefix = ""; //$NON-NLS-1$ + String outputFile = ""; //$NON-NLS-1$ + ITool[] tools; + if( resConfig != null && (tools = resConfig.getToolsToInvoke()) != null && tools.length > 0) { + ITool tool = tools[0]; + String cmd = tool.getToolCommand(); + //try to resolve the build macros in the tool command + try { + String resolvedCommand = null; + + // does the resource have spaces in its name? + if (resource.getProjectRelativePath().toString().indexOf(" ") != -1) { + // use fully qualified strings + resolvedCommand = ManagedBuildManager + .getBuildMacroProvider() + .resolveValueToMakefileFormat( + cmd, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(resource.getLocation(), + null, null, tool)); + } else { + // use builder variables + resolvedCommand = ManagedBuildManager + .getBuildMacroProvider() + .resolveValueToMakefileFormat( + cmd, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(resource.getLocation(), + null, null, tool)); + } + + if((resolvedCommand = resolvedCommand.trim()).length() > 0) + cmd = resolvedCommand; + + } catch (BuildMacroException e){ + } + + String[] toolFlags = null; + try { + toolFlags = tool.getToolCommandFlags(resource.getLocation(),null); + } catch( BuildException ex ) { + // TODO add some routines to catch this + toolFlags = EMPTY_STRING_ARRAY; + } + String[] flags = new String[toolFlags.length + 4]; + flags[0] = "-MM"; //$NON-NLS-1$ + flags[1] = "-MG"; //$NON-NLS-1$ + flags[2] = "-P"; //$NON-NLS-1$ + flags[3] = "-w"; //$NON-NLS-1$ + for (int i=0; i 0) + buildCmd = resolvedCommand; + + } catch (BuildMacroException e){ + } + + + } else { + ITool tool = null; + tools = config.getFilteredTools(); + for (int index = 0; index < tools.length; index++) { + ITool tmp = tools[index]; + if (tmp.buildsFileType(inputExtension)) { + tool = tmp; + break; + } + } + String cmd = tool != null ? tool.getToolCommand() : null; + + //try to resolve the build macros in the tool command + try{ + String resolvedCommand = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(cmd, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(resource.getLocation(),null,null,tool)); + if((resolvedCommand = resolvedCommand.trim()).length() > 0) + cmd = resolvedCommand; + + } catch (BuildMacroException e){ + } + + String buildFlags = "-MM -MG -P -w " + info.getToolFlagsForSource(inputExtension, resource.getLocation(), null); //$NON-NLS-1$ + String[] flags = buildFlags.split( "\\s" ); //$NON-NLS-1$ + cmdLInfo = info.generateToolCommandLineInfo( inputExtension, flags, outflag, outputPrefix, + outputFile, inputs, resource.getLocation(), null); + // The command to build + if( cmdLInfo == null ) buildCmd = + cmd + + IManagedBuilderMakefileGenerator.WHITESPACE + + "-MM -MG -P -w " + //$NON-NLS-1$ + buildFlags + + IManagedBuilderMakefileGenerator.WHITESPACE + + IManagedBuilderMakefileGenerator.IN_MACRO; + else { + buildCmd = cmdLInfo.getCommandLine(); + } + + // resolve any remaining macros in the command after it has been + // generated + try { + String resolvedCommand = null; + + // does the resource have spaces in its name? + if (resource.getProjectRelativePath().toString().indexOf(" ") != -1) { + // use fully qualified strings + resolvedCommand = ManagedBuildManager + .getBuildMacroProvider() + .resolveValueToMakefileFormat( + buildCmd, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(resource.getLocation(), + null, null, tool)); + } else { + // use builder variables + resolvedCommand = ManagedBuildManager + .getBuildMacroProvider() + .resolveValueToMakefileFormat( + buildCmd, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(resource.getLocation(), + null, null, tool)); + } + if ((resolvedCommand = resolvedCommand.trim()).length() > 0) + buildCmd = resolvedCommand; + + } catch (BuildMacroException e) { + } + } + + buffer.append(IManagedBuilderMakefileGenerator.TAB + + buildCmd + + IManagedBuilderMakefileGenerator.WHITESPACE + + ">>" + //$NON-NLS-1$ + IManagedBuilderMakefileGenerator.WHITESPACE + depRule ); + + return buffer.toString(); + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator2.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator2.java new file mode 100755 index 00000000000..2c259de6052 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator2.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2006 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.makegen.gnu; + +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyPreBuild; +import org.eclipse.core.runtime.IPath; + +/** + * This dependency calculator uses the GCC -MMD -MF -MP -MQ options in order to + * generate .d files as a side effect of compilation. + * See bugzilla 108715 for the discussion of dependency management that led to + * the creation of this dependency calculator. Note also that this technique + * exhibits the failure modes discussed in comment #5. + * + * This dependency calculator uses the class DefaultGCCDependencyCalculator2Commands + * which implements the per-source command information + * + * @since 3.1 + */ + +public class DefaultGCCDependencyCalculator2 implements + IManagedDependencyGenerator2 { + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType#getCalculatorType() + */ + public int getCalculatorType() { + return TYPE_BUILD_COMMANDS; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#getDependencyFileExtension(org.eclipse.cdt.managedbuilder.core.IConfiguration, org.eclipse.cdt.managedbuilder.core.ITool) + */ + public String getDependencyFileExtension(IConfiguration buildContext, ITool tool) { + return IManagedBuilderMakefileGenerator.DEP_EXT; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#getDependencySourceInfo(org.eclipse.core.runtime.IPath, org.eclipse.cdt.managedbuilder.core.IBuildObject, org.eclipse.cdt.managedbuilder.core.ITool, org.eclipse.core.runtime.IPath) + */ + public IManagedDependencyInfo getDependencySourceInfo(IPath source, IBuildObject buildContext, ITool tool, IPath topBuildDirectory) { + return new DefaultGCCDependencyCalculator2Commands(source, buildContext, tool, topBuildDirectory); + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#postProcessDependencyFile(org.eclipse.core.runtime.IPath, org.eclipse.cdt.managedbuilder.core.IConfiguration, org.eclipse.cdt.managedbuilder.core.ITool, org.eclipse.core.runtime.IPath) + */ + public boolean postProcessDependencyFile(IPath dependencyFile, IConfiguration buildContext, ITool tool, IPath topBuildDirectory) { + // Nothing + return false; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator2Commands.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator2Commands.java new file mode 100755 index 00000000000..9e86b5885a7 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator2Commands.java @@ -0,0 +1,203 @@ +/******************************************************************************* + * Copyright (c) 2006 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.makegen.gnu; + +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; +import org.eclipse.cdt.managedbuilder.internal.macros.MacroResolver; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.resources.IProject;; + +/** + * This dependency calculator uses the GCC -MMD -MF -MP -MQ options in order to + * generate .d files as a side effect of compilation. + * See bugzilla 108715 for the discussion of dependency management that led to + * the creation of this dependency calculator. Note also that this technique + * exhibits the failure modes discussed in comment #5. + * + * This class is used with DefaultGCCDependencyCalculator2. + * + * @since 3.1 + */ + +public class DefaultGCCDependencyCalculator2Commands implements + IManagedDependencyCommands { + + // Member variables set by the constructor + IPath source; + IBuildObject buildContext; + ITool tool; + IPath topBuildDirectory; + + // Other Member variables + IProject project; + IPath sourceLocation; + IPath outputLocation; + boolean needExplicitRuleForFile; + Boolean genericCommands = null; + + /** + * Constructor + * + * @param source The source file for which dependencies should be calculated + * The IPath can be either relative to the project directory, or absolute in the file system. + * @param buildContext The IConfiguration or IResourceConfiguration that + * contains the context in which the source file will be built + * @param tool The tool associated with the source file + * @param topBuildDirectory The top build directory of the configuration. This is + * the working directory for the tool. This IPath is relative to the project directory. + */ + public DefaultGCCDependencyCalculator2Commands(IPath source, IBuildObject buildContext, ITool tool, IPath topBuildDirectory) { + this.source = source; + this.buildContext = buildContext; + this.tool = tool; + this.topBuildDirectory = topBuildDirectory; + + // Compute the project + if (buildContext instanceof IConfiguration) { + IConfiguration config = (IConfiguration)buildContext; + project = (IProject)config.getOwner(); + } else if (buildContext instanceof IResourceConfiguration) { + IResourceConfiguration resConfig = (IResourceConfiguration)buildContext; + project = (IProject)resConfig.getOwner(); + } + + sourceLocation = (source.isAbsolute() ? source : project.getLocation().append(source)); + outputLocation = project.getLocation().append(topBuildDirectory).append(getDependencyFiles()[0]); + + // A separate rule is needed for the resource in the case where explicit file-specific macros + // are referenced, or if the resource contains special characters in its path (e.g., whitespace) + needExplicitRuleForFile = GnuMakefileGenerator.containsSpecialCharacters(sourceLocation.toString()) || + MacroResolver.getReferencedExplitFileMacros(tool).length > 0 + || MacroResolver.getReferencedExplitFileMacros( + tool.getToolCommand(), + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(sourceLocation, outputLocation, + null, tool)).length > 0; + + if (needExplicitRuleForFile) genericCommands = new Boolean(false); + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#areCommandsGeneric() + */ + public boolean areCommandsGeneric() { + if (genericCommands == null) genericCommands = new Boolean(true); + return genericCommands.booleanValue(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#getDependencyCommandOptions() + */ + public String[] getDependencyCommandOptions() { + + String[] options = new String[4]; + // -MMD + options[0] = "-MMD"; //$NON-NLS-1$ + // -MP + options[1] = "-MP"; //$NON-NLS-1$ + // -MF$(@:%.o=%.d) + options[2] = "-MF\"$(@:%.o=%.d)\""; //$NON-NLS-1$ + //options[2] = "-MF\"${OutputDirRelPath}${OutputFileBaseName}.d\""; //$NON-NLS-1$ + if( buildContext instanceof IResourceConfiguration || needExplicitRuleForFile ) { + IPath outPath = getDependencyFiles()[0]; + // -MT"dependecy-file-name" + String optTxt = "-MT\""; //$NON-NLS-1$ + optTxt += GnuMakefileGenerator.escapeWhitespaces(outPath.toString()) + "\""; //$NON-NLS-1$ + options[3] = optTxt; + } else { + // -MT"$(@:%.o=%.d) %.o" + options[3] = "-MT\"$(@:%.o=%.d)\""; //$NON-NLS-1$ + //options[3] = "-MT\"${OutputDirRelPath}${OutputFileBaseName}.d\""; //$NON-NLS-1$ + } + + return options; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#getDependencyFiles() + */ + public IPath[] getDependencyFiles() { + // The source file is project relative and the dependency file is top build directory relative + // Remove the source extension and add the dependency extension + IPath depFilePath = source.removeFileExtension().addFileExtension(IManagedBuilderMakefileGenerator.DEP_EXT); + // Remember that the source folder hierarchy and the build output folder hierarchy are the same + // but if this is a generated resource, then it may already be under the top build directory + if (!depFilePath.isAbsolute()) { + if (topBuildDirectory.isPrefixOf(depFilePath)) { + depFilePath = depFilePath.removeFirstSegments(1); + } + } + IPath[] paths = new IPath[1]; + paths[0] = depFilePath; + return paths; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#getPostToolDependencyCommands() + */ + public String[] getPostToolDependencyCommands() { + // Nothing + return null; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands#getPreToolDependencyCommands() + */ + public String[] getPreToolDependencyCommands() { + // Nothing + return null; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getBuildContext() + */ + public IBuildObject getBuildContext() { + return buildContext; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getSource() + */ + public IPath getSource() { + return source; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getTool() + */ + public ITool getTool() { + return tool; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getTopBuildDirectory() + */ + public IPath getTopBuildDirectory() { + return topBuildDirectory; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculatorPreBuild.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculatorPreBuild.java new file mode 100755 index 00000000000..c5c3797a5dc --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculatorPreBuild.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2006 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.makegen.gnu; + +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyPreBuild; +import org.eclipse.core.runtime.IPath; + + +/** + * This dependency calculator uses the GCC -MM -MF -MP -MQ options in order to + * generate .d files as separate step prior to the source compilations. + * + * This dependency calculator uses the class DefaultGCCDependencyCalculatorPreBuildCommands + * which implements the per-source command information + * + * @since 3.1 + */ + +public class DefaultGCCDependencyCalculatorPreBuild implements + IManagedDependencyGenerator2 { + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType#getCalculatorType() + */ + public int getCalculatorType() { + return TYPE_PREBUILD_COMMANDS; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#getDependencyFileExtension(org.eclipse.cdt.managedbuilder.core.IConfiguration, org.eclipse.cdt.managedbuilder.core.ITool) + */ + public String getDependencyFileExtension(IConfiguration buildContext, ITool tool) { + return IManagedBuilderMakefileGenerator.DEP_EXT; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#getDependencySourceInfo(org.eclipse.core.runtime.IPath, org.eclipse.cdt.managedbuilder.core.IBuildObject, org.eclipse.cdt.managedbuilder.core.ITool, org.eclipse.core.runtime.IPath) + */ + public IManagedDependencyInfo getDependencySourceInfo(IPath source, IBuildObject buildContext, ITool tool, IPath topBuildDirectory) { + return new DefaultGCCDependencyCalculatorPreBuildCommands(source, buildContext, tool, topBuildDirectory); + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2#postProcessDependencyFile(org.eclipse.core.runtime.IPath, org.eclipse.cdt.managedbuilder.core.IConfiguration, org.eclipse.cdt.managedbuilder.core.ITool, org.eclipse.core.runtime.IPath) + */ + public boolean postProcessDependencyFile(IPath dependencyFile, IConfiguration buildContext, ITool tool, IPath topBuildDirectory) { + // Nothing + return false; + } + +} + diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculatorPreBuildCommands.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculatorPreBuildCommands.java new file mode 100755 index 00000000000..ed42b74995d --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculatorPreBuildCommands.java @@ -0,0 +1,308 @@ +/******************************************************************************* + * Copyright (c) 2006 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.makegen.gnu; + +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; +import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo; +import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; +import org.eclipse.cdt.managedbuilder.internal.macros.MacroResolver; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyPreBuild; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.resources.IProject; +import java.util.Vector; + +/** + * This dependency calculator uses the GCC -MM -MF -MP -MT options in order to + * generate .d files as separate step prior to the source compilations. + * + * This dependency calculator uses the class DefaultGCCDependencyCalculatorPreBuildCommands + * which implements the per-source command information + * + * This class is used with DefaultGCCDependencyCalculatorPreBuild. + * + * @since 3.1 + */ + +public class DefaultGCCDependencyCalculatorPreBuildCommands implements IManagedDependencyPreBuild { + + private static final String EMPTY_STRING = new String(); + + // Member variables set by the constructor + IPath source; + IBuildObject buildContext; + ITool tool; + IPath topBuildDirectory; + + // Other Member variables + IProject project; + IPath sourceLocation; + IPath outputLocation; + boolean needExplicitRuleForFile; + Boolean genericCommands = null; + + /** + * Constructor + * + * @param source The source file for which dependencies should be calculated + * The IPath can be either relative to the project directory, or absolute in the file system. + * @param buildContext The IConfiguration or IResourceConfiguration that + * contains the context in which the source file will be built + * @param tool The tool associated with the source file + * @param topBuildDirectory The top build directory of the configuration. This is + * the working directory for the tool. This IPath is relative to the project directory. + */ + public DefaultGCCDependencyCalculatorPreBuildCommands(IPath source, IBuildObject buildContext, ITool tool, IPath topBuildDirectory) { + this.source = source; + this.buildContext = buildContext; + this.tool = tool; + this.topBuildDirectory = topBuildDirectory; + + // Compute the project + if (buildContext instanceof IConfiguration) { + IConfiguration config = (IConfiguration)buildContext; + project = (IProject)config.getOwner(); + } else if (buildContext instanceof IResourceConfiguration) { + IResourceConfiguration resConfig = (IResourceConfiguration)buildContext; + project = (IProject)resConfig.getOwner(); + } + + sourceLocation = (source.isAbsolute() ? source : project.getLocation().append(source)); + outputLocation = project.getLocation().append(topBuildDirectory).append(getDependencyFiles()[0]); + + // A separate rule is needed for the resource in the case where explicit file-specific macros + // are referenced, or if the resource contains special characters in its path (e.g., whitespace) + needExplicitRuleForFile = GnuMakefileGenerator.containsSpecialCharacters(sourceLocation.toString()) || + MacroResolver.getReferencedExplitFileMacros(tool).length > 0 + || MacroResolver.getReferencedExplitFileMacros( + tool.getToolCommand(), + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(sourceLocation, outputLocation, + null, tool)).length > 0; + + if (needExplicitRuleForFile) genericCommands = new Boolean(false); + } + + public boolean areCommandsGeneric() { + if (genericCommands != null) return genericCommands.booleanValue(); + // If the context is a Configuration, yes + if (buildContext instanceof IConfiguration) { + genericCommands = new Boolean(true); + return true; + } + // If the context is a Resource Configuration, determine if it overrides any + // of its parent configuration's options that would affect dependency file + // generation. + // TODO + genericCommands = new Boolean(false); + return false; + } + + public String getBuildStepName() { + return new String("GCC_DEPENDS"); //$NON-NLS-1$ + } + + public String[] getDependencyCommands() { + + String[] commands = new String[1]; + String depCmd = EMPTY_STRING; + + // Get and resolve the command + String cmd = tool.getToolCommand(); + try { + String resolvedCommand = null; + if (!needExplicitRuleForFile) { + resolvedCommand = ManagedBuildManager.getBuildMacroProvider() + .resolveValueToMakefileFormat( + cmd, + EMPTY_STRING, + IManagedBuilderMakefileGenerator.WHITESPACE, + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(sourceLocation, + outputLocation, null, tool)); + } else { + // if we need an explicit rule then don't use any builder + // variables, resolve everything + // to explicit strings + resolvedCommand = ManagedBuildManager.getBuildMacroProvider() + .resolveValue( + cmd, + EMPTY_STRING, + IManagedBuilderMakefileGenerator.WHITESPACE, + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(sourceLocation, + outputLocation, null, tool)); + } + + if ((resolvedCommand = resolvedCommand.trim()).length() > 0) + cmd = resolvedCommand; + + } catch (BuildMacroException e) { + } + + IManagedCommandLineInfo cmdLInfo = null; + + // Set up the command line options that will generate the dependency file + Vector options = new Vector(); + // -w + options.add("-w"); //$NON-NLS-1$ + // -MM + options.add("-MM"); //$NON-NLS-1$ + // -MP + options.add("-MP"); //$NON-NLS-1$ + + String optTxt; + + if( buildContext instanceof IResourceConfiguration || needExplicitRuleForFile ) { + IPath outPath = getDependencyFiles()[0]; + // -MT"dependecy-file-name" + optTxt = "-MT\""; //$NON-NLS-1$ + optTxt += GnuMakefileGenerator.escapeWhitespaces(outPath.toString()) + "\""; //$NON-NLS-1$ + options.add(optTxt); + // -MT"object-file-filename" + optTxt = "-MT\""; //$NON-NLS-1$ + GnuMakefileGenerator.escapeWhitespaces((outPath.removeFileExtension()).toString()); + String outExt = tool.getOutputExtension(source.getFileExtension()); + if (outExt != null) optTxt += "." + outExt; //$NON-NLS-1$ + optTxt += "\""; //$NON-NLS-1$ + options.add(optTxt); + } else { + // -MT"$@" + options.add("-MT\"$@\""); //$NON-NLS-1$ + // -MT'$(@:%.d=%.o)' + optTxt = "-MT\"$(@:%.d=%.o)\""; //$NON-NLS-1$ + //optTxt = "-MT\"${OutputDirRelPath}${OutputFileBaseName}"; + //if (outExt != null) optTxt += "." + outExt; + //optTxt += "\""; //$NON-NLS-1$ + options.add(optTxt); + } + + // Save the -I, -D, -U options and discard the rest + try { + String[] allFlags = tool.getToolCommandFlags(sourceLocation, outputLocation); + for (int i=0; i 0) + depCmd = resolvedCommand; + + } catch (BuildMacroException e) { + } + } + + commands[0] = depCmd; + return commands; + } + + public IPath[] getDependencyFiles() { + // The source file is project relative and the dependency file is top build directory relative + // Remove the source extension and add the dependency extension + IPath depFilePath = source.removeFileExtension().addFileExtension(IManagedBuilderMakefileGenerator.DEP_EXT); + // Remember that the source folder hierarchy and the build output folder hierarchy are the same + // but if this is a generated resource, then it may already be under the top build directory + if (!depFilePath.isAbsolute()) { + if (topBuildDirectory.isPrefixOf(depFilePath)) { + depFilePath = depFilePath.removeFirstSegments(1); + } + } + IPath[] paths = new IPath[1]; + paths[0] = depFilePath; + return paths; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getBuildContext() + */ + public IBuildObject getBuildContext() { + return buildContext; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getSource() + */ + public IPath getSource() { + return source; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getTool() + */ + public ITool getTool() { + return tool; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo#getTopBuildDirectory() + */ + public IPath getTopBuildDirectory() { + return topBuildDirectory; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuDependencyGroupInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuDependencyGroupInfo.java new file mode 100755 index 00000000000..bbfa734237f --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuDependencyGroupInfo.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2006 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.makegen.gnu; + +import java.util.ArrayList; + +/** + * + * This class contains the desciption of a group of generated dependency files, + * e.g., .d files created by compilations + * + */ + +public class GnuDependencyGroupInfo { + + // Member Variables + String groupBuildVar; + boolean conditionallyInclude; + ArrayList groupFiles; + + // Constructor + public GnuDependencyGroupInfo(String groupName, boolean bConditionallyInclude) { + groupBuildVar = groupName; + conditionallyInclude = bConditionallyInclude; + // Note: not yet needed + groupFiles = null; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java index 2f7ab27e7ed..93622212f8c 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java @@ -1,3927 +1,4299 @@ -/******************************************************************************* - * Copyright (c) 2003, 2005 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Rational Software - Initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.makegen.gnu; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; // Note: We use LinkedHashMap instead of HashMap - // only to keep the generation of makefiles constant - // for our test set. Make itself doesn't care - // about the order. -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.Vector; - -import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.internal.core.model.Util; -import org.eclipse.cdt.managedbuilder.core.BuildException; -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IInputType; -import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; -import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; -import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo; -import org.eclipse.cdt.managedbuilder.core.IManagedOutputNameProvider; -import org.eclipse.cdt.managedbuilder.core.IOption; -import org.eclipse.cdt.managedbuilder.core.IOutputType; -import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.IToolChain; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; -import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages; -import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; -import org.eclipse.cdt.managedbuilder.internal.macros.MacroResolver; -import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; -import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; -import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; -import org.eclipse.core.resources.IContainer; -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; -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; - -/** - * This is a specialized makefile generator that takes advantage of the - * extensions present in Gnu Make. - * - * @since 1.2 - */ - -public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { - - /** - * This class walks the delta supplied by the build system to determine - * what resources have been changed. The logic is very simple. If a - * buildable resource (non-header) has been added or removed, the directories - * in which they are located are "dirty" so the makefile fragments for them - * have to be regenerated. - *

- * The actual dependencies are recalculated as a result of the build step - * itself. We are relying on make to do the right things when confronted - * with a dependency on a moved header file. That said, make will treat - * the missing header file in a dependency rule as a target it has to build - * unless told otherwise. These dummy targets are added to the makefile - * to avoid a missing target error. - */ - public class ResourceDeltaVisitor implements IResourceDeltaVisitor { - private GnuMakefileGenerator generator; - private IManagedBuildInfo info; - - /** - * The constructor - */ - public ResourceDeltaVisitor(GnuMakefileGenerator 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: - if (!generator.isGeneratedResource(resource)) { - // This is a source file so just add its container - if (info.buildsFileType(ext)) { - generator.appendModifiedSubdirectory(resource); - } - } - break; - case IResourceDelta.REMOVED: - // we get this notification if a resource is moved too - if (!generator.isGeneratedResource(resource)) { - // This is a source file so just add its container - if (info.buildsFileType(ext)) { - generator.appendDeletedFile(resource); - generator.appendModifiedSubdirectory(resource); - } - } - break; - default: - keepLooking = true; - break; - } - } - if (resource.getType() == IResource.FOLDER) { - // I only care about delete event - switch (delta.getKind()) { - case IResourceDelta.REMOVED: - if (!generator.isGeneratedResource(resource)) { - generator.appendDeletedSubdirectory((IContainer)resource); - } - default: - break; - } - } - if (resource.getType() == IResource.PROJECT) { - // If there is a zero-length delta, something the project depends on has changed so just call make - IResourceDelta[] children = delta.getAffectedChildren(); - if (children != null && children.length > 0) { - keepLooking = true; - } - } else { - // If the resource is part of the generated directory structure don't recurse - if (!generator.isGeneratedResource(resource)) { - keepLooking = true; - } - } - - return keepLooking; - } - } - - - - /** - * This class is used to recursively walk the project and determine which - * modules contribute buildable source files. - */ - protected class ResourceProxyVisitor implements IResourceProxyVisitor { - private GnuMakefileGenerator generator; - private IManagedBuildInfo info; - - /** - * Constructs a new resource proxy visitor to quickly visit project - * resources. - */ - public ResourceProxyVisitor(GnuMakefileGenerator generator, IManagedBuildInfo info) { - this.generator = generator; - this.info = info; - } - - /* (non-Javadoc) - * @see org.eclipse.core.resources.IResourceProxyVisitor#visit(org.eclipse.core.resources.IResourceProxy) - */ - public boolean visit(IResourceProxy proxy) throws CoreException { - // No point in proceeding, is there - if (generator == null) { - return false; - } - - // Is this a resource we should even consider - if (proxy.getType() == IResource.FILE) { - // If this resource has a Resource Configuration and is not excluded or - // if it has a file extension that one of the tools builds, add the sudirectory to the list - IResource resource = proxy.requestResource(); - boolean willBuild = false; - IResourceConfiguration resConfig = config.getResourceConfiguration(resource.getFullPath().toString()); - if (resConfig != null) willBuild = true; - if (!willBuild) { - String ext = resource.getFileExtension(); - if (info.buildsFileType(ext) && - // If this file resource is a generated resource, then it is uninteresting - !generator.isGeneratedResource(resource)) { - willBuild = true; - } - } - if (willBuild) { - if ((resConfig == null) || (!(resConfig.isExcluded()))) { - generator.appendBuildSubdirectory(resource); - } - } - return false; - } - - // Recurse into subdirectories - return true; - } - - } - - // String constants for makefile contents and messages - private static final String COMMENT = "MakefileGenerator.comment"; //$NON-NLS-1$ - //private static final String AUTO_DEP = COMMENT + ".autodeps"; //$NON-NLS-1$ - //private static final String MESSAGE = "ManagedMakeBuilder.message"; //$NON-NLS-1$ - //private static final String BUILD_ERROR = MESSAGE + ".error"; //$NON-NLS-1$ - - //private static final String DEP_INCL = COMMENT + ".module.dep.includes"; //$NON-NLS-1$ - private static final String HEADER = COMMENT + ".header"; //$NON-NLS-1$ - - protected static final String MESSAGE_FINISH_BUILD = ManagedMakeMessages.getResourceString("MakefileGenerator.message.finish.build"); //$NON-NLS-1$ - protected static final String MESSAGE_FINISH_FILE = ManagedMakeMessages.getResourceString("MakefileGenerator.message.finish.file"); //$NON-NLS-1$ - protected static final String MESSAGE_START_BUILD = ManagedMakeMessages.getResourceString("MakefileGenerator.message.start.build"); //$NON-NLS-1$ - protected static final String MESSAGE_START_FILE = ManagedMakeMessages.getResourceString("MakefileGenerator.message.start.file"); //$NON-NLS-1$ - protected static final String MESSAGE_NO_TARGET_TOOL = ManagedMakeMessages.getResourceString("MakefileGenerator.message.no.target"); //$NON-NLS-1$ - //private static final String MOD_INCL = COMMENT + ".module.make.includes"; //$NON-NLS-1$ - private static final String MOD_LIST = COMMENT + ".module.list"; //$NON-NLS-1$ - private static final String MOD_VARS = COMMENT + ".module.variables"; //$NON-NLS-1$ - private static final String MOD_RULES = COMMENT + ".build.rule"; //$NON-NLS-1$ - private static final String BUILD_TOP = COMMENT + ".build.toprules"; //$NON-NLS-1$ - private static final String ALL_TARGET = COMMENT + ".build.alltarget"; //$NON-NLS-1$ - private static final String MAINBUILD_TARGET = COMMENT + ".build.mainbuildtarget"; //$NON-NLS-1$ - private static final String BUILD_TARGETS = COMMENT + ".build.toptargets"; //$NON-NLS-1$ - private static final String SRC_LISTS = COMMENT + ".source.list"; //$NON-NLS-1$ - - private static final String EMPTY_STRING = new String(); - private static final String[] EMPTY_STRING_ARRAY = new String[0]; - - private static final String OBJS_MACRO = "OBJS"; //$NON-NLS-1$ - private static final String DEPS_MACRO = "DEPS"; //$NON-NLS-1$ - private static final String MACRO_ADDITION_ADDPREFIX_HEADER = "${addprefix "; //$NON-NLS-1$ - private static final String MACRO_ADDITION_ADDPREFIX_SUFFIX = "," + WHITESPACE + LINEBREAK; //$NON-NLS-1$ - private static final String MACRO_ADDITION_PREFIX_SUFFIX = "+=" + WHITESPACE + LINEBREAK; //$NON-NLS-1$ - private static final String PREBUILD = "pre-build"; //$NON-NLS-1$ - private static final String MAINBUILD = "main-build"; //$NON-NLS-1$ - private static final String POSTBUILD = "post-build"; //$NON-NLS-1$ - private static final String SECONDARY_OUTPUTS = "secondary-outputs"; //$NON-NLS-1$ - - // Enumerations - public static final int - PROJECT_RELATIVE = 1, - PROJECT_SUBDIR_RELATIVE = 2, - ABSOLUTE = 3; - - // Local variables needed by generator - private String buildTargetName; - private String buildTargetExt; - private IConfiguration config; - private ITool[] buildTools; - private boolean[] buildToolsUsed; - private ManagedBuildGnuToolInfo[] gnuToolInfos; - private Vector deletedFileList; - private Vector deletedDirList; - private Vector dependencyMakefiles; - private IManagedBuildInfo info; - private Vector invalidDirList; - private Vector modifiedList; - private IProgressMonitor monitor; - private IProject project; - private IResource[] projectResources; - private Vector ruleList; - private Vector depLineList; - private Vector subdirList; - private IPath topBuildDir; - private Set outputExtensionsSet; - // Maps of macro names (String) to values (List) - private HashMap buildSrcVars = new HashMap(); - private HashMap buildOutVars = new HashMap(); - private LinkedHashMap topBuildOutVars = new LinkedHashMap(); - - public GnuMakefileGenerator() { - super(); - } - - - /************************************************************************* - * IManagedBuilderMakefileGenerator M E T H O D S - ************************************************************************/ - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator#initialize() - * - * @param project - * @param info - * @param monitor - */ - public void initialize(IProject project, IManagedBuildInfo info, IProgressMonitor monitor) { - // Save the project so we can get path and member information - this.project = project; - try { - projectResources = project.members(); - } catch (CoreException e) { - projectResources = null; - } - // Save the monitor reference for reporting back to the user - this.monitor = monitor; - // Get the build info for the project - this.info = info; - // Get the name of the build target - buildTargetName = info.getBuildArtifactName(); - // Get its extension - buildTargetExt = info.getBuildArtifactExtension(); - - try{ - //try to resolve the build macros in the target extension - buildTargetExt = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( - buildTargetExt, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_CONFIGURATION, - info.getDefaultConfiguration()); - } catch (BuildMacroException e){ - } - - try{ - //try to resolve the build macros in the target name - String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( - buildTargetName, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_CONFIGURATION, - info.getDefaultConfiguration()); - if((resolved = resolved.trim()).length() > 0) - buildTargetName = resolved; - } catch (BuildMacroException e){ - } - - - if (buildTargetExt == null) { - buildTargetExt = new String(); - } - // Cache the build tools - config = info.getDefaultConfiguration(); - buildTools = config.getFilteredTools(); - buildToolsUsed = new boolean[buildTools.length]; - for (int i=0; i 0) { - inBuffer.append(readBuffer); - n = in.read(readBuffer); - } - 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; - } - - // Try to determine if this file already has dummy targets defined. - // If so, we will only add the comment. - String[] bufferLines = inBufferString.split("[\\r\\n]"); //$NON-NLS-1$ - for (int i=0; i 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 we are doing an incremental build, only update the files that do not have a comment - String firstToken; - try { - firstToken = (String) deps.get(0); - } catch (ArrayIndexOutOfBoundsException e) { - // This makes no sense so bail - return; - } - - // Put the generated comments in the output buffer - if (!firstToken.startsWith(COMMENT_SYMBOL)) { - outBuffer = addDefaultHeader(); - } else { - outBuffer = new StringBuffer(); - } - - // Some echo implementations misbehave and put the -n and newline in the output - if (firstToken.startsWith("-n")) { //$NON-NLS-1$ - - // Now let's parse: - // Win32 outputs -n '/.d /' - // POSIX outputs -n /.d / - // Get the dep file name - String secondToken; - try { - secondToken = (String) deps.get(1); - } catch (ArrayIndexOutOfBoundsException e) { - secondToken = new String(); - } - if (secondToken.startsWith("'")) { //$NON-NLS-1$ - // This is the Win32 implementation of echo (MinGW without MSYS) - outBuffer.append(secondToken.substring(1) + WHITESPACE); - } else { - outBuffer.append(secondToken + WHITESPACE); - } - - // The relative path to the build goal comes next - String thirdToken; - try { - thirdToken = (String) deps.get(2); - } catch (ArrayIndexOutOfBoundsException e) { - thirdToken = new String(); - } - int lastIndex = thirdToken.lastIndexOf("'"); //$NON-NLS-1$ - if (lastIndex != -1) { - if (lastIndex == 0) { - outBuffer.append(WHITESPACE); - } else { - outBuffer.append(thirdToken.substring(0, lastIndex - 1)); - } - } else { - outBuffer.append(thirdToken); - } - - // Followed by the target output by the compiler plus ':' - // If we see any empty tokens here, assume they are the result of - // a line feed output by "echo" and skip them - String fourthToken; - int nToken = 3; - try { - do { - fourthToken = (String) deps.get(nToken++); - } while (fourthToken.length() == 0); - - } catch (ArrayIndexOutOfBoundsException e) { - fourthToken = new String(); - } - outBuffer.append(fourthToken + WHITESPACE); - - // Followed by the actual dependencies - try { - Iterator iter = deps.listIterator(nToken); - while (iter.hasNext()) { - String nextElement = (String)iter.next(); - if (nextElement.endsWith("\\")) { //$NON-NLS-1$ - outBuffer.append(nextElement + NEWLINE + WHITESPACE); - } else { - outBuffer.append(nextElement + WHITESPACE); - } - } - } catch (IndexOutOfBoundsException e) { - } - - } else { - outBuffer.append(inBuffer); - } - - outBuffer.append(NEWLINE); - save = true; - - // Dummy targets to add to the makefile - 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 - * : - */ - outBuffer.append(dummy + COLON + NEWLINE + NEWLINE); - } - } - - // Write them out to the makefile - if (save) { - Util.save(outBuffer, makefile); - } - } - - /* (non-javadoc) - * This method generates a "fragment" make file (subdir.mk). - * One of these is generated for each project directory/subdirectory - * that contains source files. - * - * @param module - * @throws CoreException - */ - protected void populateFragmentMakefile(IContainer module) throws CoreException { - // Calculate the new directory relative to the build output - IPath moduleRelativePath = module.getProjectRelativePath(); - IPath buildRoot = getBuildWorkingDir(); - if (buildRoot == null) { - return; - } - - IPath moduleOutputPath = buildRoot.append(moduleRelativePath); - updateMonitor(ManagedMakeMessages.getFormattedString("MakefileGenerator.message.gen.source.makefile", moduleOutputPath.toString())); //$NON-NLS-1$ - - // Now create the directory - IPath moduleOutputDir = createDirectory(moduleOutputPath.toString()); - - // Create a module makefile - IFile modMakefile = createFile(moduleOutputDir.append(MODFILE_NAME)); - StringBuffer makeBuf = new StringBuffer(); - makeBuf.append(addFragmentMakefileHeader()); - makeBuf.append(addSources(module)); - - // Save the files - Util.save(makeBuf, modMakefile); - } - - /* (non-Javadoc) - * The makefile generator generates a Macro for each type of output, other than final artifact, - * created by the build. - * - * @param fileHandle The file that should be populated with the output - * @throws CoreException - */ - protected void populateObjectsMakefile(IFile fileHandle) throws CoreException { - - // Master list of "object" dependencies, i.e. dependencies between input files and output files. - StringBuffer macroBuffer = new StringBuffer(); - List valueList; - macroBuffer.append(addDefaultHeader()); - - // Map of macro names (String) to its definition (List of Strings) - HashMap outputMacros = new HashMap(); - - // Add the predefined LIBS, USER_OBJS, & DEPS macros - - // Add the libraries this project depends on - valueList = new ArrayList(); - String[] libs = info.getLibsForConfiguration(buildTargetExt); - for (int i = 0; i < libs.length; i++) { - String string = libs[i]; - valueList.add(string); - } - outputMacros.put("LIBS", valueList); //$NON-NLS-1$ - - // Add the extra user-specified objects - valueList = new ArrayList(); - String[] userObjs = info.getUserObjectsForConfiguration(buildTargetExt); - for (int i = 0; i < userObjs.length; i++) { - String string = userObjs[i]; - valueList.add(string); - } - outputMacros.put("USER_OBJS", valueList); //$NON-NLS-1$ - - // Write every macro to the file - Iterator iterator = outputMacros.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry)iterator.next(); - macroBuffer.append((String)entry.getKey() + " :="); //$NON-NLS-1$ - valueList = (List)entry.getValue(); - Iterator valueIter = valueList.iterator(); - while (valueIter.hasNext()) { - macroBuffer.append(WHITESPACE + (String)valueIter.next()); - } - if (iterator.hasNext()) macroBuffer.append(NEWLINE + NEWLINE); - } - - // For now, just save the buffer that was populated when the rules were created - Util.save(macroBuffer, fileHandle); - - } - - /* (non-Javadoc) - * @param fileHandle - * @throws CoreException - */ - protected void populateSourcesMakefile(IFile fileHandle) throws CoreException { - // Add the comment - StringBuffer buffer = addDefaultHeader(); - - // Determine the set of macros - HashSet handledInputExtensions = new HashSet(); - String buildMacro; - for (int i=0; iStringBuffer containing all of the required targets to - * properly build the project. - * - * @param outputVarsAdditionsList list to add needed build output variables to - * @param rebuild - * @return StringBuffer - */ - private StringBuffer addTargets(List outputVarsAdditionsList, boolean rebuild) { - StringBuffer buffer = new StringBuffer(); - - IConfiguration config = info.getDefaultConfiguration(); - - // Assemble the information needed to generate the targets - String prebuildStep = info.getPrebuildStep(); - try{ - //try to resolve the build macros in the prebuild step - prebuildStep = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( - prebuildStep, - EMPTY_STRING, - WHITESPACE, - IBuildMacroProvider.CONTEXT_CONFIGURATION, - config); - } catch (BuildMacroException e){ - } - prebuildStep = prebuildStep.trim(); // Remove leading and trailing whitespace (and control characters) - - String postbuildStep = info.getPostbuildStep(); - try{ - //try to resolve the build macros in the postbuild step - postbuildStep = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( - postbuildStep, - EMPTY_STRING, - WHITESPACE, - IBuildMacroProvider.CONTEXT_CONFIGURATION, - config); - - } catch (BuildMacroException e){ - } - postbuildStep = postbuildStep.trim(); // Remove leading and trailing whitespace (and control characters) - String preannouncebuildStep = info.getPreannouncebuildStep(); - String postannouncebuildStep = info.getPostannouncebuildStep(); - String targets = rebuild ? "clean all" : "all"; //$NON-NLS-1$ //$NON-NLS-2$ - - ITool targetTool = config.getTargetTool(); - if (targetTool == null) { - targetTool = info.getToolFromOutputExtension(buildTargetExt); - } - - // Get all the projects the build target depends on - IProject[] refdProjects = null; - try { - refdProjects = project.getReferencedProjects(); - } catch (CoreException e) { - // There are 2 exceptions; the project does not exist or it is not open - // and neither conditions apply if we are building for it .... - } - - // If a prebuild step exists, redefine the all target to be - // all: {pre-build} main-build - // and then reset the "traditional" all target to main-build - // This will allow something meaningful to happen if the generated - // makefile is - // extracted and run standalone via "make all" - // - String defaultTarget = "all:"; //$NON-NLS-1$ - if (prebuildStep.length() > 0) { - - // Add the comment for the "All" target - buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(ALL_TARGET) + NEWLINE); - - buffer.append(defaultTarget + WHITESPACE); - buffer.append(PREBUILD + WHITESPACE); - - // Reset defaultTarget for now and for subsequent use, below - defaultTarget = MAINBUILD; - buffer.append(defaultTarget); - - // Update the defaultTarget, main-build, by adding a colon, which is - // needed below - defaultTarget = defaultTarget.concat(COLON); - buffer.append(NEWLINE + NEWLINE); - - // Add the comment for the "main-build" target - buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(MAINBUILD_TARGET) + NEWLINE); - } - else - // Add the comment for the "All" target - buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(ALL_TARGET) + NEWLINE); - - // Write out the all target first in case someone just runs make - // all: or mainbuild: - - String outputPrefix = EMPTY_STRING; - if (targetTool != null) { - outputPrefix = targetTool.getOutputPrefix(); - } - buffer.append(defaultTarget + WHITESPACE + outputPrefix + buildTargetName); - if (buildTargetExt.length() > 0) { - buffer.append(DOT + buildTargetExt); - } - - // Add the Secondary Outputs to the all target, if any - IOutputType[] secondaryOutputs = config.getToolChain().getSecondaryOutputs(); - if (secondaryOutputs.length > 0) { - buffer.append(WHITESPACE + SECONDARY_OUTPUTS); - } - - buffer.append(NEWLINE + NEWLINE); - - /* - * The build target may depend on other projects in the workspace. These - * are captured in the deps target: deps: ; - * $(MAKE) [clean all | all]> - */ - Vector managedProjectOutputs = new Vector(refdProjects.length); - if (refdProjects.length > 0) { - boolean addDeps = true; - if (refdProjects != null) { - for (int i = 0; i < refdProjects.length; i++) { - IProject dep = refdProjects[i]; - if (!dep.exists()) continue; - if (addDeps) { - buffer.append("dependents:" + NEWLINE); //$NON-NLS-1$ - addDeps = false; - } - String buildDir = dep.getLocation().toString(); - String depTargets = targets; - if (ManagedBuildManager.manages(dep)) { - // Add the current configuration to the makefile path - IManagedBuildInfo depInfo = ManagedBuildManager.getBuildInfo(dep); - buildDir += SEPARATOR + depInfo.getConfigurationName(); - - // Extract the build artifact to add to the dependency list - String depTarget = depInfo.getBuildArtifactName(); - String depExt = depInfo.getBuildArtifactExtension(); - - try{ - //try to resolve the build macros in the artifact extension - depExt = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( - depExt, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_CONFIGURATION, - info.getDefaultConfiguration()); - } catch (BuildMacroException e){ - } - - try{ - //try to resolve the build macros in the artifact name - String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( - depTarget, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_CONFIGURATION, - info.getDefaultConfiguration()); - if((resolved = resolved.trim()).length() > 0) - depTarget = resolved; - } catch (BuildMacroException e){ - } - - String depPrefix = depInfo.getOutputPrefix(depExt); - if (depInfo.needsRebuild()) { - depTargets = "clean all"; //$NON-NLS-1$ - } - String dependency = buildDir + SEPARATOR + depPrefix + depTarget; - if (depExt.length() > 0) { - dependency += DOT + depExt; - } - dependency = escapeWhitespaces(dependency); - managedProjectOutputs.add(dependency); - } - buffer.append(TAB + "-cd" + WHITESPACE + escapeWhitespaces(buildDir) + WHITESPACE + LOGICAL_AND + WHITESPACE + "$(MAKE) " + depTargets + NEWLINE); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - buffer.append(NEWLINE); - } - - // Add the targets tool rules - buffer.append(addTargetsRules(targetTool, - outputVarsAdditionsList, managedProjectOutputs, (postbuildStep.length() > 0))); - - // Add the prebuild step target, if specified - if (prebuildStep.length() > 0) { - buffer.append(PREBUILD + COLON + NEWLINE); - if (preannouncebuildStep.length() > 0) { - buffer.append(TAB + DASH + AT + ECHO + WHITESPACE - + SINGLE_QUOTE + preannouncebuildStep + SINGLE_QUOTE - + NEWLINE); - } - buffer.append(TAB + DASH + prebuildStep + NEWLINE); - buffer.append(TAB + DASH + AT + ECHO + WHITESPACE + SINGLE_QUOTE - + WHITESPACE + SINGLE_QUOTE + NEWLINE + NEWLINE); - } - - // Add the postbuild step, if specified - if (postbuildStep.length() > 0) { - buffer.append(POSTBUILD + COLON + NEWLINE); - if (postannouncebuildStep.length() > 0) { - buffer.append(TAB + DASH + AT + ECHO + WHITESPACE - + SINGLE_QUOTE + postannouncebuildStep + SINGLE_QUOTE - + NEWLINE); - } - buffer.append(TAB + DASH + postbuildStep + NEWLINE); - buffer.append(TAB + DASH + AT + ECHO + WHITESPACE + SINGLE_QUOTE - + WHITESPACE + SINGLE_QUOTE + NEWLINE + NEWLINE); - } - - // Add the Secondary Outputs target, if needed - if (secondaryOutputs.length > 0) { - buffer.append(SECONDARY_OUTPUTS + COLON); - Vector outs2 = calculateSecondaryOutputs(secondaryOutputs); - for (int i=0; i 0) { - buffer.append(WHITESPACE + MAINBUILD + WHITESPACE + PREBUILD); - } - if (postbuildStep.length() > 0) { - buffer.append(WHITESPACE + POSTBUILD); - } - buffer.append(NEWLINE); - Iterator refIter = managedProjectOutputs.listIterator(); - while(refIter.hasNext()) { - buffer.append((String)refIter.next() + COLON + NEWLINE); - } - buffer.append(NEWLINE); - - // Include makefile.targets supplemental makefile - buffer.append("-include " + ROOT + SEPARATOR + MAKEFILE_TARGETS + NEWLINE); //$NON-NLS-1$ - - return buffer; - } - - /* (non-javadoc) - * Returns the targets rules. The targets make file (top makefile) contains: - * 1 the rule for the final target tool - * 2 the rules for all of the tools that use multipleOfType in their primary input type - * 3 the rules for all tools that use the output of #2 tools - * - * @param outputVarsAdditionsList list to add needed build output variables to - * @param managedProjectOutputs Other projects in the workspace that this project depends upon - * @return StringBuffer - */ - private StringBuffer addTargetsRules(ITool targetTool, - List outputVarsAdditionsList, Vector managedProjectOutputs, boolean postbuildStep) { - StringBuffer buffer = new StringBuffer(); - // Add the comment - buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(BUILD_TOP) + NEWLINE); - - // Get the target tool and generate the rule - if (targetTool != null) { - if (addRuleForTool(targetTool, buffer, true, buildTargetName, buildTargetExt, - outputVarsAdditionsList, managedProjectOutputs, postbuildStep)) { - // Mark the target tool as processed - for (int i=0; i 0) { - buffer.append(DOT + buildTargetExt); - } - buffer.append(NEWLINE); - buffer.append(TAB + DASH + AT + ECHO + WHITESPACE + SINGLE_QUOTE - + WHITESPACE + SINGLE_QUOTE + NEWLINE + NEWLINE); - - return buffer; - } - - /* (non-Javadoc) - * Create the rule - * - * @param tool - * @param buffer Buffer to add makefile rules to - * @param bTargetTool True if this is the target tool - * @param targetName If this is the "targetTool", the target file name, else null - * @param targetName If this is the "targetTool", the target file extension, else null - * @param outputVarsAdditionsList list to add needed build output variables to - * @param managedProjectOutputs Other projects in the workspace that this project depends upon - * @param bPostBuildStep Emit post-build step invocation - */ - protected boolean addRuleForTool(ITool tool, StringBuffer buffer, boolean bTargetTool, String targetName, String targetExt, - List outputVarsAdditionsList, Vector managedProjectOutputs, boolean bEmitPostBuildStepCall) { - - // Get the tool's inputs and outputs - Vector inputs = new Vector(); - Vector dependencies = new Vector(); - Vector outputs = new Vector(); - Vector enumeratedPrimaryOutputs = new Vector(); - Vector enumeratedSecondaryOutputs = new Vector(); - Vector outputVariables = new Vector(); - String outputPrefix = EMPTY_STRING; - - if (!getToolInputsOutputs(tool, inputs, dependencies, outputs, - enumeratedPrimaryOutputs, enumeratedSecondaryOutputs, - outputVariables, bTargetTool, managedProjectOutputs)) { - return false; - } - - // If we have no primary output, make all of the secondary outputs the primary output - if (enumeratedPrimaryOutputs.size() == 0) { - enumeratedPrimaryOutputs = enumeratedSecondaryOutputs; - enumeratedSecondaryOutputs.clear(); - } - - // Add the output variables for this tool to our list - outputVarsAdditionsList.addAll(outputVariables); - - // Create the build rule - String buildRule = EMPTY_STRING; - String outflag = tool.getOutputFlag(); - - String primaryOutputs = EMPTY_STRING; - boolean first = true; - for (int i=0; i 0) - command = resolvedCommand; - - } catch (BuildMacroException e){ - } - String[] cmdInputs = (String[])inputs.toArray(new String[inputs.size()]); - IManagedCommandLineGenerator gen = tool.getCommandLineGenerator(); - IManagedCommandLineInfo cmdLInfo = gen.generateCommandLineInfo( tool, command, - flags, outflag, outputPrefix, primaryOutputs, cmdInputs, tool.getCommandLinePattern() ); - - // The command to build - String buildCmd = null; - if( cmdLInfo == null ) { - String toolFlags; - try { - toolFlags = tool.getToolCommandFlagsString(null,null); - } catch( BuildException ex ) { - // TODO report error - toolFlags = EMPTY_STRING; - } - buildCmd = command + WHITESPACE + toolFlags + WHITESPACE + outflag + WHITESPACE + outputPrefix + primaryOutputs + WHITESPACE + IN_MACRO; - } - else buildCmd = cmdLInfo.getCommandLine(); - - // resolve any remaining macros in the command after it has been - // generated - try { - String resolvedCommand = ManagedBuildManager - .getBuildMacroProvider().resolveValueToMakefileFormat( - buildCmd, - EMPTY_STRING, - WHITESPACE, - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(null, null, null, tool)); - if ((resolvedCommand = resolvedCommand.trim()).length() > 0) - buildCmd = resolvedCommand; - - } catch (BuildMacroException e) { - } - - - buffer.append(TAB + AT + ECHO + WHITESPACE + buildCmd + NEWLINE); - buffer.append(TAB + AT + buildCmd); - - // TODO - // NOTE WELL: Dependency file generation is not handled for this type of Tool - - // Echo finished message - buffer.append(NEWLINE); - if (bTargetTool) { - buffer.append(TAB + AT + ECHO + WHITESPACE + SINGLE_QUOTE + MESSAGE_FINISH_BUILD + WHITESPACE + OUT_MACRO + SINGLE_QUOTE + NEWLINE); - } else { - buffer.append(TAB + AT + ECHO + WHITESPACE + SINGLE_QUOTE + MESSAGE_FINISH_FILE + WHITESPACE + OUT_MACRO + SINGLE_QUOTE + NEWLINE); - } - buffer.append(TAB + AT + ECHO + WHITESPACE + SINGLE_QUOTE + WHITESPACE + SINGLE_QUOTE + NEWLINE); - - // If there is a post build step, then add a recursive invocation of MAKE to invoke it after the main build - // Note that $(MAKE) will instantiate in the recusive invocation to the make command that was used to invoke - // the makefile originally - if (bEmitPostBuildStepCall) { - buffer.append(TAB + MAKE + WHITESPACE + NO_PRINT_DIR + WHITESPACE + POSTBUILD + NEWLINE + NEWLINE); - } - else { - // Just emit a blank line - buffer.append(NEWLINE); - } - } - - // If we have secondary outputs, output dependency rules without commands - if (enumeratedSecondaryOutputs.size() > 0) { - String primaryOutput = (String)enumeratedPrimaryOutputs.get(0); - for (int i=0; i 0) { - for (int j=0; j 0) { - for (int j=0; jStringBuffer containing the comment(s) - * for a fragment makefile (subdir.mk). - */ - protected StringBuffer addFragmentMakefileHeader() { - return addDefaultHeader(); - } - - /* (non-javadoc) - * Returns a StringBuffer containing makefile text for all of the sources - * contributed by a container (project directory/subdirectory) to the fragement makefile - * - * @param module project resource directory/subdirectory - * @return StringBuffer generated text for the fragement makefile - */ - protected StringBuffer addSources(IContainer module) throws CoreException { - // Calculate the new directory relative to the build output - IPath moduleRelativePath = module.getProjectRelativePath(); - String relativePath = moduleRelativePath.toString(); - relativePath += relativePath.length() == 0 ? "" : SEPARATOR; //$NON-NLS-1$ - - // For build macros in the configuration, create a map which will map them - // to a string which holds its list of sources. - LinkedHashMap buildVarToRuleStringMap = new LinkedHashMap(); - - // Add statements that add the source files in this folder, - // and generated source files, and generated dependency files - // to the build macros - Iterator iterator = buildSrcVars.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry)iterator.next(); - String macroName = (String)entry.getKey(); - addMacroAdditionPrefix(buildVarToRuleStringMap, macroName, null, false); - } - iterator = buildOutVars.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry)iterator.next(); - String macroName = (String)entry.getKey(); - addMacroAdditionPrefix(buildVarToRuleStringMap, macroName, "./" + relativePath, false); //$NON-NLS-1$ - } - - // Create an entry for the DEPS macro - addMacroAdditionPrefix(buildVarToRuleStringMap, DEPS_MACRO, "./" + relativePath, false); //$NON-NLS-1$ - - // String buffers - StringBuffer buffer = new StringBuffer(); // Return buffer - StringBuffer ruleBuffer = new StringBuffer(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(MOD_RULES) + NEWLINE); - - // Visit the resources in this folder and add each one to a sources macro, and generate a build rule, if appropriate - IResource[] resources = module.members(); - - IResourceConfiguration resConfig; - IFolder folder = project.getFolder(info.getConfigurationName()); - - for (int i = 0; i < resources.length; i++) { - IResource resource = resources[i]; - if (resource.getType() == IResource.FILE) { - // Check whether this resource is excluded from build - resConfig = config.getResourceConfiguration(resource.getFullPath().toString()); - if( (resConfig != null) && (resConfig.isExcluded()) ) - continue; - addFragmentMakefileEntriesForSource(buildVarToRuleStringMap, ruleBuffer, - folder, relativePath, resource, resource.getLocation(), resConfig, null, false); - } - } - - // Write out the macro addition entries to the buffer - buffer.append(writeAdditionMacros(buildVarToRuleStringMap)); - return buffer.append(ruleBuffer + NEWLINE); - } - - /* (non-Javadoc - * Adds the entries for a particular source file to the fragment makefile - * - * @param buildVarToRuleStringMap map of build variable names to the list of files assigned to the variable - * @param ruleBuffer buffer to add generated nmakefile text to - * @param folder the top level build output directory - * @param relativePath build output directory relative path of the current output directory - * @param resource the source file for this invocation of the tool - this may be null for a generated output - * @param sourceLocation the full path of the source - * @param resConfig the IResourceConfiguration associated with this file or null - * @param varName the build variable to add this invocation's outputs to - * if null, use the file extension to find the name - * @param generatedSource if true, this file was generated by another tool in the tool-chain - */ - protected void addFragmentMakefileEntriesForSource (LinkedHashMap buildVarToRuleStringMap, StringBuffer ruleBuffer, - IFolder folder, String relativePath, IResource resource, IPath sourceLocation, IResourceConfiguration resConfig, - String varName, boolean generatedSource) { - - // Determine which tool, if any, builds files with this extension - String ext = sourceLocation.getFileExtension(); - ITool tool = null; - - // Use the tool from the resource configuration if there is one - if (resConfig != null) { - ITool[] tools = resConfig.getToolsToInvoke(); - if (tools != null && tools.length > 0) { - tool = tools[0]; - } - } - for (int j=0; j 0) { - addMacroAdditionFile( - buildVarToRuleStringMap, - DEPS_MACRO, - "./" + (relativePath.equals("") ? relativePath : relativePath + "/") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - + generatedDepFile.toString()); - } - - // If the generated outputs of this tool are input to another tool, - // 1. add the output to the appropriate macro - // 2. If the tool does not have multipleOfType input, generate the rule. - - IOutputType outType = tool.getPrimaryOutputType(); - String buildVariable = null; - if (outType != null) { - if (tool.getCustomBuildStep()) { - // TODO: This is somewhat of a hack since a custom build step - // tool does not currently define a build variable - if (generatedOutputs.size() > 0) { - IPath firstOutput = (IPath)generatedOutputs.get(0); - String firstExt = firstOutput.getFileExtension(); - for (int j=0; j 0) { - buildVariable = bV; - break; - } - } - } - } - } else { - buildVariable = outType.getBuildVariable(); - } - } else { - // For support of pre-CDT 3.0 integrations. - buildVariable = OBJS_MACRO; - } - - for (int k=0; k 0) { - if (isSecondaryOutputVar(secondaryOutputs, varName)) { - addMacroAdditionFile(buildVarToRuleStringMap, varName, relativePath, sourceLocation, generatedSource); - } - } - } - } - } - - /* (non-Javadoc) - * Adds the source file to the appropriate build variable - * - * @param buildVarToRuleStringMap map of build variable names to the list of files assigned to the variable - * @param ext the file extension of the file - * @param varName the build variable to add this invocation's outputs to - * if null, use the file extension to find the name - * @param relativePath build output directory relative path of the current output directory - * @param sourceLocation the full path of the source - * @param generatedSource if true, this file was generated by another tool in the tool-chain - */ - protected void addToBuildVar (LinkedHashMap buildVarToRuleStringMap, String ext, - String varName, String relativePath, IPath sourceLocation, boolean generatedSource) { - List varList = null; - if (varName == null) { - // Get the proper source build variable based upon the extension - varName = getSourceMacroName(ext).toString(); - varList = (List)buildSrcVars.get(varName); - } else { - varList = (List)buildOutVars.get(varName); - } - // Add the resource to the list of all resources associated with a variable. - // Do not allow duplicates - there is no reason to and it can be 'bad' - - // e.g., having the same object in the OBJS list can cause duplicate symbol errors from the linker - if ((varList != null) && !(varList.contains(sourceLocation))) { - // Since we don't know how these files will be used, we store them using a "location" - // path rather than a relative path - varList.add(sourceLocation); - if (!buildVarToRuleStringMap.containsKey(varName)) { - // TODO - is this an error? - } else { - // Add the resource name to the makefile line that adds resources to the build variable - addMacroAdditionFile(buildVarToRuleStringMap, varName, relativePath, sourceLocation, generatedSource); - } - } - } - - /* (non-Javadoc) - * Create a rule for this source file. We create a pattern rule if possible. - * - * This is an example of a pattern rule: - * - * /%.: ..//%. - * @echo 'Building file: $<' - * @echo 'Invoking tool xxx' - * @echo $@ $< - * @ $@ $< && \ - * echo -n $(@:%.o=%.d) ' /' >> $(@:%.o=%.d) && \ - * -P -MM -MG $< >> $(@:%.o=%.d) - * @echo 'Finished building: $<' - * @echo ' ' - * - * Note that the macros all come from the build model and are - * resolved to a real command before writing to the module - * makefile, so a real command might look something like: - * source1/%.o: ../source1/%.cpp - * @echo 'Building file: $<' - * @echo 'Invoking tool xxx' - * @echo g++ -g -O2 -c -I/cygdrive/c/eclipse/workspace/Project/headers -o$@ $< - * @ g++ -g -O2 -c -I/cygdrive/c/eclipse/workspace/Project/headers -o$@ $< && \ - * echo -n $(@:%.o=%.d) ' source1/' >> $(@:%.o=%.d) && \ - * g++ -P -MM -MG -g -O2 -c -I/cygdrive/c/eclipse/workspace/Project/headers $< >> $(@:%.o=%.d) - * @echo 'Finished building: $<' - * @echo ' ' - * - * @param relativePath build output directory relative path of the current output directory - * @param buffer buffer to populate with the build rule - * @param resource the source file for this invocation of the tool - * @param generatedSource true if the resource is a generated output - * @param sourceLocation the full path of the source - * @param resConfig the IResourceConfiguration associated with this file or null - * @param generatedDepFile passed in as an empty string; append the dependency file name - * to it if one is generated by the rule - * @param enumeratedOutputs vector of the filenames that are the output of this rule - */ - protected void addRuleForSource(String relativePath, StringBuffer buffer, IResource resource, - IPath sourceLocation, IResourceConfiguration resConfig, - boolean generatedSource, StringBuffer generatedDepFile, Vector enumeratedOutputs) { - - String fileName = sourceLocation.removeFileExtension().lastSegment(); - String inputExtension = sourceLocation.getFileExtension(); - String outputExtension = info.getOutputExtension(inputExtension); - - ITool tool = null; - if( resConfig != null) { - ITool[] tools = resConfig.getToolsToInvoke(); - if (tools != null && tools.length > 0) { - tool = tools[0]; - } - } - if (tool == null) { - tool = info.getToolFromInputExtension(inputExtension); - } - - // Get the dependency generator associated with this tool and file extension - IManagedDependencyGenerator depGen = tool.getDependencyGeneratorForExtension(inputExtension); - boolean doDepGen = (depGen != null && depGen.getCalculatorType() == IManagedDependencyGenerator.TYPE_COMMAND); - - // If the tool creates a dependency file, add it to the list - if (doDepGen) { - String depFile = relativePath + fileName + DOT + DEP_EXT; - getDependencyMakefiles().add(depFile); - generatedDepFile.append(fileName + DOT + DEP_EXT); - } - - // Figure out the output paths - String OptDotExt = EMPTY_STRING; - if (outputExtension != null && outputExtension.length() > 0) - OptDotExt = DOT + outputExtension; - - Vector ruleOutputs = new Vector(); - Vector enumeratedPrimaryOutputs = new Vector(); - Vector enumeratedSecondaryOutputs = new Vector(); - calculateOutputsForSource(tool, relativePath, resource, sourceLocation, ruleOutputs, enumeratedPrimaryOutputs, enumeratedSecondaryOutputs); - enumeratedOutputs.addAll(enumeratedPrimaryOutputs); - enumeratedOutputs.addAll(enumeratedSecondaryOutputs); - String primaryOutputName = null; - if (enumeratedPrimaryOutputs.size() > 0) { - primaryOutputName = escapeWhitespaces(((IPath)enumeratedPrimaryOutputs.get(0)).toString()); - } else { - primaryOutputName = escapeWhitespaces(relativePath + fileName + OptDotExt); - } - String otherPrimaryOutputs = EMPTY_STRING; - for (int i=1; i 0 - || MacroResolver.getReferencedExplitFileMacros(tool - .getToolCommand(), IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(sourceLocation, outputLocation, - null, tool)).length > 0; - //get and resolve command - String cmd = tool.getToolCommand(); - - try { - String resolvedCommand = null; - if (!needExplicitRuleForFile) { - resolvedCommand = ManagedBuildManager.getBuildMacroProvider() - .resolveValueToMakefileFormat( - cmd, - EMPTY_STRING, - WHITESPACE, - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(sourceLocation, - outputLocation, null, tool)); - } else { - // if we need an explicit rule then don't use any builder - // variables, resolve everything - // to explicit strings - resolvedCommand = ManagedBuildManager.getBuildMacroProvider() - .resolveValue( - cmd, - EMPTY_STRING, - WHITESPACE, - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(sourceLocation, - outputLocation, null, tool)); - } - - if ((resolvedCommand = resolvedCommand.trim()).length() > 0) - cmd = resolvedCommand; - - } catch (BuildMacroException e) { - } - - - String defaultOutputName = EMPTY_STRING; - String primaryDependencyName = EMPTY_STRING; - String home = (generatedSource)? DOT : ROOT; - String resourcePath = null; - boolean patternRule = true; - //boolean isItLinked = false; - //if (resource.isLinked()) { NOTE: we don't use this since children of linked resources return false - if(!sourceLocation.toString().startsWith(projectLocation)) { - // it IS linked, so use the actual location - //isItLinked = true; - resourcePath = sourceLocation.toString(); - // Need a hardcoded rule, not a pattern rule, as a linked file - // can reside in any path - defaultOutputName = escapeWhitespaces(relativePath + fileName + OptDotExt); - primaryDependencyName = escapeWhitespaces(resourcePath); - patternRule = false; - } else { - // use the relative path (not really needed to store per se but in the future someone may want this) - resourcePath = relativePath; - // The rule and command to add to the makefile - if( resConfig != null || needExplicitRuleForFile) { - // Need a hardcoded rule, not a pattern rule - defaultOutputName = escapeWhitespaces(resourcePath + fileName + OptDotExt); - primaryDependencyName = escapeWhitespaces(home + SEPARATOR + resourcePath + fileName + DOT + inputExtension); - patternRule = false; - } else { - defaultOutputName = relativePath + WILDCARD + OptDotExt; - primaryDependencyName = home + SEPARATOR + resourcePath + WILDCARD + DOT + inputExtension; - } - } // end fix for PR 70491 - - // If we still think that we are using a pattern rule, make sure that at least one of the rule - // outputs contains a %. - if (patternRule) { - patternRule = false; - for (int i=0; i= 0) { //$NON-NLS-1$ - patternRule = true; - break; - } - } - if (!patternRule) { - // Need to reset the primary dependency to be a filename rather than a pattern - primaryDependencyName = escapeWhitespaces(home + SEPARATOR + resourcePath + fileName + DOT + inputExtension); - } - } - - // Begin building the rule for this source file - String buildRule = EMPTY_STRING; - if (patternRule) { - if (ruleOutputs.size() == 0) { - buildRule = defaultOutputName; - } else { - boolean first = true; - for (int i=0; i= 0) { //$NON-NLS-1$ - if (first) { - first = false; - } else { - buildRule += WHITESPACE; - } - buildRule += ruleOutput; - } - } - } - } else { - buildRule += primaryOutputName; - } - - buildRule += COLON + WHITESPACE + primaryDependencyName; - - // Other additional inputs - // Get any additional dependencies specified for the tool in other InputType elements and AdditionalInput elements - IPath[] addlDepPaths = tool.getAdditionalDependencies(); - for (int i=0; i 0) - buildCmd = resolvedCommand; - - } catch (BuildMacroException e) { - } - - - buffer.append(TAB + AT + ECHO + WHITESPACE + buildCmd + NEWLINE); - buffer.append(TAB + AT + buildCmd); - } else { - buffer.append(TAB + AT + ECHO + WHITESPACE + SINGLE_QUOTE + tool.getAnnouncement() + SINGLE_QUOTE + NEWLINE); - outflag = info.getOutputFlag(outputExtension); - outputPrefix = info.getOutputPrefix(outputExtension); - // Other additional inputs - // Get any additional dependencies specified for the tool in other InputType elements and AdditionalInput elements - IPath[] addlInputPaths = getAdditionalResourcesForSource(tool); - for (int i=0; i 0) - buildCmd = resolvedCommand; - - } catch (BuildMacroException e) { - } - - - buffer.append(TAB + AT + ECHO + WHITESPACE + buildCmd + NEWLINE); - buffer.append(TAB + AT + buildCmd); - } - - // Determine if there are any dependencies to calculate - // TODO: Note that there is an assumption built into this method that if the build rule is the same - // for a set of resources, the dependency command will also be the same. That is, this method - // will not reach this code if the build rule is the same (see above). - if (doDepGen && depGen.getCalculatorType() == IManagedDependencyGenerator.TYPE_COMMAND) { - buffer.append(WHITESPACE + LOGICAL_AND + WHITESPACE + LINEBREAK); - // Get the dependency rule out of the generator - String depCmd = depGen.getDependencyCommand(resource, info); - - // Resolve any macros in the dep command after it has been generated. - // Note: do not trim the result because it will strip out necessary tab characters. - try { - if (!needExplicitRuleForFile) { - depCmd = ManagedBuildManager.getBuildMacroProvider() - .resolveValueToMakefileFormat( - depCmd, - EMPTY_STRING, - WHITESPACE, - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(sourceLocation, - outputLocation, null, - tool)); - } - - else { - depCmd = ManagedBuildManager.getBuildMacroProvider() - .resolveValue( - depCmd, - EMPTY_STRING, - WHITESPACE, - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(sourceLocation, - outputLocation, null, - tool)); - } - - } catch (BuildMacroException e) { - } - - buffer.append(depCmd); - } - - // Echo finished message - buffer.append(NEWLINE); - buffer.append(TAB + AT + ECHO + WHITESPACE + SINGLE_QUOTE + MESSAGE_FINISH_FILE + WHITESPACE + IN_MACRO + SINGLE_QUOTE + NEWLINE); - buffer.append(TAB + AT + ECHO + WHITESPACE + SINGLE_QUOTE + WHITESPACE + SINGLE_QUOTE + NEWLINE + NEWLINE); - } - - // Determine if there are calculated dependencies - String calculatedDependencies = null; - boolean addedDepLines = false; - String depLine; - if (depGen != null && depGen.getCalculatorType() != IManagedDependencyGenerator.TYPE_COMMAND) { - Vector addlDepsVector = calculateDependenciesForSource(depGen, tool, relativePath, resource); - if (addlDepsVector != null && addlDepsVector.size() > 0) { - calculatedDependencies = new String(); - for (int i=0; i 0) { - allRes.add(Path.fromOSString("$(" + type.getBuildVariable() + ")")); //$NON-NLS-1$ //$NON-NLS-2$ - } else { - // Use file extensions - String[] typeExts = type.getSourceExtensions(tool); - for (int j=0; j 0) b = true; - if (toolParent instanceof IToolChain) { - IConfiguration config = ((IToolChain)toolParent).getParent(); - if (config != null) { - ManagedBuildManager.setOption(config, tool, assignToOption, b); - } - } else if (toolParent instanceof IResourceConfiguration) { - ManagedBuildManager.setOption(((IResourceConfiguration)toolParent), tool, assignToOption, b); - } - } else if (optType == IOption.ENUMERATED) { - if (allRes.size() > 0) { - String s = allRes.get(0).toString(); - if (toolParent instanceof IToolChain) { - IConfiguration config = ((IToolChain)toolParent).getParent(); - if (config != null) { - ManagedBuildManager.setOption(config, tool, assignToOption, s); - } - } else if (toolParent instanceof IResourceConfiguration) { - ManagedBuildManager.setOption(((IResourceConfiguration)toolParent), tool, assignToOption, s); - } - } - } - allRes.clear(); - } - } catch( BuildException ex ) { - } - } - } - } - return (IPath[])allRes.toArray(new IPath[allRes.size()]); - } - - - /* (non-Javadoc) - * Returns the output IPaths for this invocation of the tool with the specified source file - /* - * The priorities for determining the names of the outputs of a tool are: - * 1. If the tool is the build target and primary output, use artifact name & extension - - * This case does not apply here... - * 2. If an option is specified, use the value of the option - * 3. If a nameProvider is specified, call it - * 4. If outputNames is specified, use it - * 5. Use the name pattern to generate a transformation macro - * so that the source names can be transformed into the target names - * using the built-in string substitution functions of make. - * - * @param tool - * @param relativePath build output directory relative path of the current output directory - * @param resource - * @param ruleOutputs Vector of rule IPaths that are relative to the build directory - * @param enumeratedPrimaryOutputs Vector of IPaths of primary outputs - * that are relative to the build directory - * @param enumeratedSecondaryOutputs Vector of IPaths of secondary outputs - * that are relative to the build directory - */ - protected void calculateOutputsForSource(ITool tool, String relativePath, IResource resource, - IPath sourceLocation, Vector ruleOutputs, Vector enumeratedPrimaryOutputs, Vector enumeratedSecondaryOutputs) { - String inExt = sourceLocation.getFileExtension(); - String outExt = tool.getOutputExtension(inExt); - - IOutputType[] outTypes = tool.getOutputTypes(); - if (outTypes != null && outTypes.length > 0) { - for (int i=0; i 0) { - for (int j=0; j 0) - outputName = resolved; - } catch (BuildMacroException e){ - } - - IPath outPath = Path.fromOSString(outputName); - // If only a file name is specified, add the relative path of this output directory - if (outPath.segmentCount() == 1) { - outPath = Path.fromOSString(relativePath + (String)outputList.get(j)); - } - if (primaryOutput) { - ruleOutputs.add(j, outPath); - enumeratedPrimaryOutputs.add(j, resolvePercent(outPath, sourceLocation)); - } else { - ruleOutputs.add(outPath); - enumeratedSecondaryOutputs.add(resolvePercent(outPath, sourceLocation)); - } - } - } catch( BuildException ex ) {} - } else - // 3. If a nameProvider is specified, call it - if (nameProvider != null) { - IPath[] inPaths = new IPath[1]; - inPaths[0] = sourceLocation; - IPath[] outPaths = nameProvider.getOutputNames(tool, inPaths); - for (int j=0; j 0) - outputName = resolved; - } catch (BuildMacroException e) { - } - - // If only a file name is specified, add the relative path of this output directory - if (outPath.segmentCount() == 1) { - outPath = Path.fromOSString(relativePath + outPath.toString()); - } - if (primaryOutput) { - ruleOutputs.add(j, outPath); - enumeratedPrimaryOutputs.add(j, resolvePercent(outPath, sourceLocation)); - } else { - ruleOutputs.add(outPath); - enumeratedSecondaryOutputs.add(resolvePercent(outPath, sourceLocation)); - } - } - } else - // 4. If outputNames is specified, use it - if (outputNames != null) { - for (int j = 0; j < outputNames.length; j++) { - String outputName = outputNames[j]; - try{ - //try to resolve the build macros in the output names - String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( - outputName, - "", //$NON-NLS-1$ - " ", //$NON-NLS-1$ - IBuildMacroProvider.CONTEXT_FILE, - new FileContextData(sourceLocation, null, option, tool)); - if((resolved = resolved.trim()).length() > 0) - outputName = resolved; - } catch (BuildMacroException e){ - } - - IPath outPath = Path.fromOSString(outputName); - // If only a file name is specified, add the relative path of this output directory - if (outPath.segmentCount() == 1) { - outPath = Path.fromOSString(relativePath + outPath.toString()); - } - if (primaryOutput) { - ruleOutputs.add(j, outPath); - enumeratedPrimaryOutputs.add(j, resolvePercent(outPath, sourceLocation)); - } else { - ruleOutputs.add(outPath); - enumeratedSecondaryOutputs.add(resolvePercent(outPath, sourceLocation)); - } - } - } else { - // 5. Use the name pattern to generate a transformation macro - // so that the source names can be transformed into the target names - // using the built-in string substitution functions of make. - if (multOfType) { - // This case is not handled - a nameProvider or outputNames must be specified - // TODO - report error - } else { - String namePattern = type.getNamePattern(); - IPath namePatternPath = null; - if (namePattern == null || namePattern.length() == 0) { - namePattern = relativePath + outputPrefix + IManagedBuilderMakefileGenerator.WILDCARD; - if (outExt != null && outExt.length() > 0) { - namePattern += DOT + outExt; - } - namePatternPath = Path.fromOSString(namePattern); - } - else { - if (outputPrefix.length() > 0) { - namePattern = outputPrefix + namePattern; - } - namePatternPath = Path.fromOSString(namePattern); - // If only a file name is specified, add the relative path of this output directory - if (namePatternPath.segmentCount() == 1) { - namePatternPath = Path.fromOSString(relativePath + namePatternPath.toString()); - } - } - - if (primaryOutput) { - ruleOutputs.add(0, namePatternPath); - enumeratedPrimaryOutputs.add(0, resolvePercent(namePatternPath, sourceLocation)); - } else { - ruleOutputs.add(namePatternPath); - enumeratedSecondaryOutputs.add(resolvePercent(namePatternPath, sourceLocation)); - } - } - } - } - } else { - // For support of pre-CDT 3.0 integrations. - // NOTE WELL: This only supports the case of a single "target tool" - // that consumes exactly all of the object files, $OBJS, produced - // by other tools in the build and produces a single output. - // In this case, the output file name is the input file name with - // the output extension. - - //if (!ignorePrimary) { - String outPrefix = tool.getOutputPrefix(); - IPath outPath = Path.fromOSString(relativePath + outPrefix + WILDCARD); - outPath = outPath.addFileExtension(outExt); - ruleOutputs.add(0, outPath); - enumeratedPrimaryOutputs.add(0, resolvePercent(outPath, sourceLocation)); - //} - } - } - - /* (non-Javadoc) - * If the path contains a %, returns the path resolved using the resource name - * - */ - protected IPath resolvePercent(IPath outPath, IPath sourceLocation) { - // Get the input file name - String fileName = sourceLocation.removeFileExtension().lastSegment(); - // Replace the % with the file name - String outName = outPath.toOSString().replaceAll("%", fileName); //$NON-NLS-1$ - return Path.fromOSString(outName); - } - - /* (non-Javadoc) - * Returns the dependency IPaths for this invocation of the tool with the specified source file - * - * @param depGen the dependency calculator - * @param tool tool used to build the source file - * @param relativePath build output directory relative path of the current output directory - * @param resource source file to scan for dependencies - * @return Vector of IPaths that are relative to the build directory - */ - protected Vector calculateDependenciesForSource(IManagedDependencyGenerator depGen, ITool tool, String relativePath, IResource resource) { - Vector deps = new Vector(); - int type = depGen.getCalculatorType(); - - switch (type) { - - case IManagedDependencyGenerator.TYPE_INDEXER: - case IManagedDependencyGenerator.TYPE_EXTERNAL: - IResource[] res = depGen.findDependencies(resource, project); - if (res != null) { - for (int i=0; iSet containing all of the output extensions - */ - public Set getOutputExtensions() { - if (outputExtensionsSet == null) { - // The set of output extensions which will be produced by this tool. - // It is presumed that this set is not very large (likely < 10) so - // a HashSet should provide good performance. - outputExtensionsSet = new HashSet(); - - // For each tool for the target, lookup the kinds of sources it outputs - // and add that to our list of output extensions. - for (int i=0; i - * ##### ....... ##### - */ - protected StringBuffer addDefaultHeader() { - StringBuffer buffer = new StringBuffer(); - outputCommentLine(buffer); - buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(HEADER) + NEWLINE); - outputCommentLine(buffer); - buffer.append(NEWLINE); - return buffer; - } - - /* (non-Javadoc) - * Put COLS_PER_LINE comment charaters in the argument. - */ - protected void outputCommentLine(StringBuffer buffer) { - for (int i = 0; i < COLS_PER_LINE; i++) { - buffer.append(COMMENT_SYMBOL); - } - buffer.append(NEWLINE); - } - - protected boolean containsSpecialCharacters(String path) - { - return path.matches(".*(\\s|[\\{\\}\\(\\)\\$\\@%=;]).*"); - } - - /* (non-Javadoc) - * Answers the argument with all whitespaces replaced with an escape sequence. - * - * @param path - */ - protected String escapeWhitespaces(String path) { - // Escape the spaces in the path/filename if it has any - String[] segments = path.split("\\s"); //$NON-NLS-1$ - if (segments.length > 1) { - StringBuffer escapedPath = new StringBuffer(); - for (int index = 0; index < segments.length; ++index) { - escapedPath.append(segments[index]); - if (index + 1 < segments.length) { - escapedPath.append("\\ "); //$NON-NLS-1$ - } - } - return escapedPath.toString().trim(); - } else { - return path; - } - } - - /* (non-Javadoc) - * Adds a macro addition prefix to a map of macro names to entries. - * Entry prefixes look like: - * C_SRCS += \ - * ${addprefix $(ROOT)/, \ - */ - // TODO fix comment - protected void addMacroAdditionPrefix(LinkedHashMap map, String macroName, String relativePath, boolean addPrefix) { - // there is no entry in the map, so create a buffer for this macro - StringBuffer tempBuffer = new StringBuffer(); - tempBuffer.append(macroName + WHITESPACE + MACRO_ADDITION_PREFIX_SUFFIX); - if (addPrefix) { - tempBuffer.append(MACRO_ADDITION_ADDPREFIX_HEADER + relativePath + MACRO_ADDITION_ADDPREFIX_SUFFIX); - } - - // have to store the buffer in String form as StringBuffer is not a sublcass of Object - map.put(macroName, tempBuffer.toString()); - } - - /* (non-Javadoc) - * Adds a file to an entry in a map of macro names to entries. - * File additions look like: - * example.c, \ - */ - protected void addMacroAdditionFile(HashMap map, String macroName, String filename) { - StringBuffer buffer = new StringBuffer(); - buffer.append(map.get(macroName)); - - // escape whitespace in the filename - filename = escapeWhitespaces(filename); - - buffer.append(filename + WHITESPACE + LINEBREAK); - // re-insert string in the map - map.put(macroName, buffer.toString()); - } - - /* (non-Javadoc) - * Adds a file to an entry in a map of macro names to entries. - * File additions look like: - * example.c, \ - */ - protected void addMacroAdditionFile(HashMap map, String macroName, - String relativePath, IPath sourceLocation, boolean generatedSource) { - // Add the source file path to the makefile line that adds source files to the build variable - String srcName; - IPath projectLocation = project.getLocation(); - IPath dirLocation = projectLocation; - if (generatedSource) { - dirLocation = dirLocation.append(getBuildWorkingDir()); - } - if (dirLocation.isPrefixOf(sourceLocation)) { - IPath srcPath = sourceLocation.removeFirstSegments(dirLocation.segmentCount()).setDevice(null); - if (generatedSource) { - srcName = "./" + srcPath.toString(); //$NON-NLS-1$ - } else { - srcName = ROOT + "/" + srcPath.toString(); //$NON-NLS-1$ - } - } else { - if (generatedSource && !sourceLocation.isAbsolute()) { - srcName = "./" + relativePath + sourceLocation.lastSegment().toString(); //$NON-NLS-1$ - } else { - // TODO: Should we use relative paths when possible (e.g., see MbsMacroSupplier.calculateRelPath) - srcName = sourceLocation.toString(); - } - } - addMacroAdditionFile(map, macroName, srcName); - } - - /* (non-Javadoc) - * Adds file(s) to an entry in a map of macro names to entries. - * File additions look like: - * example.c, \ - */ - public void addMacroAdditionFiles(HashMap map, String macroName, Vector filenames) { - StringBuffer buffer = new StringBuffer(); - buffer.append(map.get(macroName)); - for (int i=0; i 0) { - buffer.append(filename + WHITESPACE + LINEBREAK); - } - } - // re-insert string in the map - map.put(macroName, buffer.toString()); - } - - /* (non-Javadoc) - * Write all macro addition entries in a map to the buffer - */ - protected StringBuffer writeAdditionMacros(LinkedHashMap map) { - StringBuffer buffer = new StringBuffer(); - // Add the comment - buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(MOD_VARS) + NEWLINE); - - Collection bufferCollection = map.values(); - Iterator collectionIterator = bufferCollection.iterator(); - while(collectionIterator.hasNext()) - { - String macroString = collectionIterator.next().toString(); - // Check if we added any files to the rule - // Currently, we do this by comparing the end of the rule buffer to MACRO_ADDITION_PREFIX_SUFFIX - if (!(macroString.endsWith(MACRO_ADDITION_PREFIX_SUFFIX))) { - StringBuffer currentBuffer = new StringBuffer(); - - // Remove the final "/" - if (macroString.endsWith(LINEBREAK)) { - macroString = macroString.substring(0, (macroString - .length() - 2)) - + NEWLINE; - } - currentBuffer.append(macroString); - - currentBuffer.append(NEWLINE); - - // append the contents of the buffer to the master buffer for - // the whole file - buffer.append(currentBuffer); - } - } - return buffer.append(NEWLINE); - } - - /* (non-Javadoc) - * Write all macro addition entries in a map to the buffer - */ - protected StringBuffer writeTopAdditionMacros(List varList, HashMap varMap) { - StringBuffer buffer = new StringBuffer(); - // Add the comment - buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(MOD_VARS) + NEWLINE); - - for (int i=0; i 0) - name = resolved; - } catch (BuildMacroException e){ - } - - gnuToolInfos[i] = new ManagedBuildGnuToolInfo(project, buildTools[i], true, - name, ext); - } else { - gnuToolInfos[i] = new ManagedBuildGnuToolInfo(project, buildTools[i], false, null, null); - } - doneState[i] = 0; - } - - // Initialize the build output variable to file additions map - LinkedHashMap map = getTopBuildOutputVars(); - Iterator iterator = buildOutVars.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry)iterator.next(); - String macroName = (String)entry.getKey(); - addMacroAdditionPrefix(map, macroName, "", false); //$NON-NLS-1$ - } - - // Set of input extensions for which macros have been created so far - HashSet handledDepsInputExtensions = new HashSet(); - HashSet handledOutsInputExtensions = new HashSet(); - - while (!done) { - int[] testState = new int[doneState.length]; - for (int i=0; iOperationCanceledException. - * - * @see org.eclipse.core.runtime.OperationCanceledException#OperationCanceledException() - */ - protected void checkCancel() { - if (monitor != null && monitor.isCanceled()) { - throw new OperationCanceledException(); - } - } - - /* (non-Javadoc) - * Return or create the folder needed for the build output. If we are - * creating the folder, set the derived bit to true so the CM system - * ignores the contents. If the resource exists, respect the existing - * derived setting. - * - * @param string - * @return IPath - */ - private IPath createDirectory(String dirName) throws CoreException { - // Create or get the handle for the build directory - IFolder folder = project.getFolder(dirName); - if (!folder.exists()) { - // Make sure that parent folders exist - IPath parentPath = (new Path(dirName)).removeLastSegments(1); - // Assume that the parent exists if the path is empty - if (!parentPath.isEmpty()) { - IFolder parent = project.getFolder(parentPath); - if (!parent.exists()) { - createDirectory(parentPath.toString()); - } - } - - // Now make the requested folder - try { - folder.create(true, true, null); - } - catch (CoreException e) { - if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED) - folder.refreshLocal(IResource.DEPTH_ZERO, null); - else - throw e; - } - - // Make sure the folder is marked as derived so it is not added to CM - if (!folder.isDerived()) { - folder.setDerived(true); - } - } - - return folder.getFullPath(); - } - - /* (non-Javadoc) - * Return or create the makefile needed for the build. If we are creating - * the resource, set the derived bit to true so the CM system ignores - * the contents. If the resource exists, respect the existing derived - * setting. - * - * @param makefilePath - * @return IFile - */ - private IFile createFile(IPath makefilePath) throws CoreException { - // Create or get the handle for the makefile - IWorkspaceRoot root = CCorePlugin.getWorkspace().getRoot(); - IFile newFile = root.getFileForLocation(makefilePath); - if (newFile == null) { - newFile = root.getFile(makefilePath); - } - // Create the file if it does not exist - ByteArrayInputStream contents = new ByteArrayInputStream(new byte[0]); - try { - newFile.create(contents, false, new SubProgressMonitor(monitor, 1)); - // Make sure the new file is marked as derived - if (!newFile.isDerived()) { - newFile.setDerived(true); - } - - } - catch (CoreException e) { - // If the file already existed locally, just refresh to get contents - if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED) - newFile.refreshLocal(IResource.DEPTH_ZERO, null); - else - throw e; - } - - return newFile; - } - - /** - * @param deletedFile - */ - private void deleteBuildTarget(IResource deletedFile) { - // Get the project relative path of the file - String fileName = getFileName(deletedFile); - String srcExtension = deletedFile.getFileExtension(); - String targetExtension = info.getOutputExtension(srcExtension); - if (targetExtension != "") //$NON-NLS-1$ - fileName += DOT + targetExtension; - IPath projectRelativePath = deletedFile.getProjectRelativePath().removeLastSegments(1); - IPath targetFilePath = getBuildWorkingDir().append(projectRelativePath).append(fileName); - IResource depFile = project.findMember(targetFilePath); - if (depFile != null && depFile.exists()) { - try { - depFile.delete(true, new SubProgressMonitor(monitor, 1)); - } catch (CoreException e) { - // This had better be allowed during a build - - } - } - } - - /** - * @param deletedFile - */ - private void deleteDepFile(IResource deletedFile) { - // Get the project relative path of the file - String fileName = getFileName(deletedFile); - fileName += DOT + DEP_EXT; - IPath projectRelativePath = deletedFile.getProjectRelativePath().removeLastSegments(1); - IPath depFilePath = getBuildWorkingDir().append(projectRelativePath).append(fileName); - IResource depFile = project.findMember(depFilePath); - if (depFile != null && depFile.exists()) { - try { - depFile.delete(true, new SubProgressMonitor(monitor, 1)); - } catch (CoreException e) { - // This had better be allowed during a build - - } - } - } - - /** - * @return Returns the deletedDirList. - */ - private Vector getDeletedDirList() { - if (deletedDirList == null) { - deletedDirList = new Vector(); - } - return deletedDirList; - } - - /* (non-Javadoc) - * @return - */ - private Vector getDeletedFileList() { - if (deletedFileList == null) { - deletedFileList = new Vector(); - } - return deletedFileList; - } - - /* (non-Javadoc) - * @return - */ - private Vector getDependencyMakefiles() { - if (dependencyMakefiles == null) { - dependencyMakefiles = new Vector(); - } - return dependencyMakefiles; - } - - /* (non-Javadoc) - * Strips off the file extension from the argument and returns - * the name component in a String - * - * @param file - * @return - */ - private String getFileName(IResource file) { - String answer = new String(); - String lastSegment = file.getName(); - int extensionSeparator = lastSegment.lastIndexOf(DOT); - if (extensionSeparator != -1) { - answer = lastSegment.substring(0, extensionSeparator); - } - 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; - } - - /* (non-javadoc) - * - * @return Vector - */ - private Vector getModifiedList() { - if (modifiedList == null) { - modifiedList = new Vector(); - } - return modifiedList; - } - - /* (non-javadoc) - * Answers the list of subdirectories contributing source code to the build - * - * @return List - */ - private Vector getSubdirList() { - if (subdirList == null) { - subdirList = new Vector(); - } - return subdirList; - } - - /* (non-Javadoc) - * @param subDir - */ - private void removeGeneratedDirectory(IContainer subDir) { - try { - // The source directory isn't empty - if (subDir.exists() && subDir.members().length > 0) return; - } catch (CoreException e) { - // The resource doesn't exist so we should delete the output folder - } - - // Figure out what the generated directory name is and delete it - IPath moduleRelativePath = subDir.getProjectRelativePath(); - IPath buildRoot = getBuildWorkingDir(); - if (buildRoot == null) { - return; - } - IPath moduleOutputPath = buildRoot.append(moduleRelativePath); - IFolder folder = project.getFolder(moduleOutputPath); - if (folder.exists()) { - try { - folder.delete(true, new SubProgressMonitor(monitor, 1)); - } catch (CoreException e) { - // TODO Log this - } - } - } - - /* (non-Javadoc) - * @param msg - */ - protected void updateMonitor(String msg) { - if (monitor!= null && !monitor.isCanceled()) { - monitor.subTask(msg); - monitor.worked(1); - } - } - - /** - * Return the configuration's top build directory - */ - public IPath getTopBuildDir() { - return project.getLocation().append(getBuildWorkingDir()); - } - -} +/******************************************************************************* + * Copyright (c) 2003, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation + * ARM Ltd. - Minor changes to echo commands + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.makegen.gnu; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; // Note: We use LinkedHashMap instead of HashMap + // only to keep the generation of makefiles constant + // for our test set. Make itself doesn't care + // about the order. +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Vector; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.internal.core.model.Util; +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IInputType; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; +import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedOutputNameProvider; +import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.cdt.managedbuilder.core.IOutputType; +import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; +import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages; +import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; +import org.eclipse.cdt.managedbuilder.internal.macros.MacroResolver; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator2; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyInfo; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCommands; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyCalculator; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyPreBuild; +import org.eclipse.core.resources.IContainer; +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; +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; + +/** + * This is a specialized makefile generator that takes advantage of the + * extensions present in Gnu Make. + * + * @since 1.2 + */ + +public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { + + /** + * This class walks the delta supplied by the build system to determine + * what resources have been changed. The logic is very simple. If a + * buildable resource (non-header) has been added or removed, the directories + * in which they are located are "dirty" so the makefile fragments for them + * have to be regenerated. + *

+ * The actual dependencies are recalculated as a result of the build step + * itself. We are relying on make to do the right things when confronted + * with a dependency on a moved header file. That said, make will treat + * the missing header file in a dependency rule as a target it has to build + * unless told otherwise. These dummy targets are added to the makefile + * to avoid a missing target error. + */ + public class ResourceDeltaVisitor implements IResourceDeltaVisitor { + private GnuMakefileGenerator generator; + private IManagedBuildInfo info; + + /** + * The constructor + */ + public ResourceDeltaVisitor(GnuMakefileGenerator 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: + if (!generator.isGeneratedResource(resource)) { + // This is a source file so just add its container + if (info.buildsFileType(ext)) { + generator.appendModifiedSubdirectory(resource); + } + } + break; + case IResourceDelta.REMOVED: + // we get this notification if a resource is moved too + if (!generator.isGeneratedResource(resource)) { + // This is a source file so just add its container + if (info.buildsFileType(ext)) { + generator.appendDeletedFile(resource); + generator.appendModifiedSubdirectory(resource); + } + } + break; + default: + keepLooking = true; + break; + } + } + if (resource.getType() == IResource.FOLDER) { + // I only care about delete event + switch (delta.getKind()) { + case IResourceDelta.REMOVED: + if (!generator.isGeneratedResource(resource)) { + generator.appendDeletedSubdirectory((IContainer)resource); + } + default: + break; + } + } + if (resource.getType() == IResource.PROJECT) { + // If there is a zero-length delta, something the project depends on has changed so just call make + IResourceDelta[] children = delta.getAffectedChildren(); + if (children != null && children.length > 0) { + keepLooking = true; + } + } else { + // If the resource is part of the generated directory structure don't recurse + if (!generator.isGeneratedResource(resource)) { + keepLooking = true; + } + } + + return keepLooking; + } + } + + + + /** + * This class is used to recursively walk the project and determine which + * modules contribute buildable source files. + */ + protected class ResourceProxyVisitor implements IResourceProxyVisitor { + private GnuMakefileGenerator generator; + private IManagedBuildInfo info; + + /** + * Constructs a new resource proxy visitor to quickly visit project + * resources. + */ + public ResourceProxyVisitor(GnuMakefileGenerator generator, IManagedBuildInfo info) { + this.generator = generator; + this.info = info; + } + + /* (non-Javadoc) + * @see org.eclipse.core.resources.IResourceProxyVisitor#visit(org.eclipse.core.resources.IResourceProxy) + */ + public boolean visit(IResourceProxy proxy) throws CoreException { + // No point in proceeding, is there + if (generator == null) { + return false; + } + + // Is this a resource we should even consider + if (proxy.getType() == IResource.FILE) { + // If this resource has a Resource Configuration and is not excluded or + // if it has a file extension that one of the tools builds, add the sudirectory to the list + IResource resource = proxy.requestResource(); + boolean willBuild = false; + IResourceConfiguration resConfig = config.getResourceConfiguration(resource.getFullPath().toString()); + if (resConfig != null) willBuild = true; + if (!willBuild) { + String ext = resource.getFileExtension(); + if (info.buildsFileType(ext) && + // If this file resource is a generated resource, then it is uninteresting + !generator.isGeneratedResource(resource)) { + willBuild = true; + } + } + if (willBuild) { + if ((resConfig == null) || (!(resConfig.isExcluded()))) { + generator.appendBuildSubdirectory(resource); + } + } + return false; + } + + // Recurse into subdirectories + return true; + } + + } + + // String constants for makefile contents and messages + private static final String COMMENT = "MakefileGenerator.comment"; //$NON-NLS-1$ + //private static final String AUTO_DEP = COMMENT + ".autodeps"; //$NON-NLS-1$ + //private static final String MESSAGE = "ManagedMakeBuilder.message"; //$NON-NLS-1$ + //private static final String BUILD_ERROR = MESSAGE + ".error"; //$NON-NLS-1$ + + //private static final String DEP_INCL = COMMENT + ".module.dep.includes"; //$NON-NLS-1$ + private static final String HEADER = COMMENT + ".header"; //$NON-NLS-1$ + + protected static final String MESSAGE_FINISH_BUILD = ManagedMakeMessages.getResourceString("MakefileGenerator.message.finish.build"); //$NON-NLS-1$ + protected static final String MESSAGE_FINISH_FILE = ManagedMakeMessages.getResourceString("MakefileGenerator.message.finish.file"); //$NON-NLS-1$ + protected static final String MESSAGE_START_BUILD = ManagedMakeMessages.getResourceString("MakefileGenerator.message.start.build"); //$NON-NLS-1$ + protected static final String MESSAGE_START_FILE = ManagedMakeMessages.getResourceString("MakefileGenerator.message.start.file"); //$NON-NLS-1$ + protected static final String MESSAGE_START_DEPENDENCY = ManagedMakeMessages.getResourceString("MakefileGenerator.message.start.dependency"); //$NON-NLS-1$ + protected static final String MESSAGE_NO_TARGET_TOOL = ManagedMakeMessages.getResourceString("MakefileGenerator.message.no.target"); //$NON-NLS-1$ + //private static final String MOD_INCL = COMMENT + ".module.make.includes"; //$NON-NLS-1$ + private static final String MOD_LIST = COMMENT + ".module.list"; //$NON-NLS-1$ + private static final String MOD_VARS = COMMENT + ".module.variables"; //$NON-NLS-1$ + private static final String MOD_RULES = COMMENT + ".build.rule"; //$NON-NLS-1$ + private static final String BUILD_TOP = COMMENT + ".build.toprules"; //$NON-NLS-1$ + private static final String ALL_TARGET = COMMENT + ".build.alltarget"; //$NON-NLS-1$ + private static final String MAINBUILD_TARGET = COMMENT + ".build.mainbuildtarget"; //$NON-NLS-1$ + private static final String BUILD_TARGETS = COMMENT + ".build.toptargets"; //$NON-NLS-1$ + private static final String SRC_LISTS = COMMENT + ".source.list"; //$NON-NLS-1$ + + private static final String EMPTY_STRING = new String(); + private static final String[] EMPTY_STRING_ARRAY = new String[0]; + + private static final String OBJS_MACRO = "OBJS"; //$NON-NLS-1$ + private static final String MACRO_ADDITION_ADDPREFIX_HEADER = "${addprefix "; //$NON-NLS-1$ + private static final String MACRO_ADDITION_ADDPREFIX_SUFFIX = "," + WHITESPACE + LINEBREAK; //$NON-NLS-1$ + private static final String MACRO_ADDITION_PREFIX_SUFFIX = "+=" + WHITESPACE + LINEBREAK; //$NON-NLS-1$ + private static final String PREBUILD = "pre-build"; //$NON-NLS-1$ + private static final String MAINBUILD = "main-build"; //$NON-NLS-1$ + private static final String POSTBUILD = "post-build"; //$NON-NLS-1$ + private static final String SECONDARY_OUTPUTS = "secondary-outputs"; //$NON-NLS-1$ + + // Enumerations + public static final int + PROJECT_RELATIVE = 1, + PROJECT_SUBDIR_RELATIVE = 2, + ABSOLUTE = 3; + + // Local variables needed by generator + private String buildTargetName; + private String buildTargetExt; + private IConfiguration config; + private ITool[] buildTools; + private boolean[] buildToolsUsed; + private ManagedBuildGnuToolInfo[] gnuToolInfos; + private Vector deletedFileList; + private Vector deletedDirList; + private IManagedBuildInfo info; + private Vector invalidDirList; + private Vector modifiedList; + private IProgressMonitor monitor; + private IProject project; + private IResource[] projectResources; + private Vector ruleList; + private Vector depLineList; // String's of additional dependency lines + private Vector depRuleList; // String's of rules for generating dependency files + private Vector subdirList; + private IPath topBuildDir; // Build directory - relative to the workspace + private Set outputExtensionsSet; + // Maps of macro names (String) to values (List) + private HashMap buildSrcVars = new HashMap(); // Map of source file build variable names + // to a List of source file Path's + private HashMap buildOutVars = new HashMap(); // Map of output file build variable names + // to a List of output file Path's + private HashMap buildDepVars = new HashMap(); // Map of dependency file build variable names + // to a List of GnuDependencyGroupInfo objects + private LinkedHashMap topBuildOutVars = new LinkedHashMap(); + // Dependency file variables + private Vector dependencyMakefiles; // IPath's - relative to the top build directory or absolute + + + public GnuMakefileGenerator() { + super(); + } + + + /************************************************************************* + * IManagedBuilderMakefileGenerator M E T H O D S + ************************************************************************/ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator#initialize() + * + * @param project + * @param info + * @param monitor + */ + public void initialize(IProject project, IManagedBuildInfo info, IProgressMonitor monitor) { + // Save the project so we can get path and member information + this.project = project; + try { + projectResources = project.members(); + } catch (CoreException e) { + projectResources = null; + } + // Save the monitor reference for reporting back to the user + this.monitor = monitor; + // Get the build info for the project + this.info = info; + // Get the name of the build target + buildTargetName = info.getBuildArtifactName(); + // Get its extension + buildTargetExt = info.getBuildArtifactExtension(); + + try{ + //try to resolve the build macros in the target extension + buildTargetExt = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + buildTargetExt, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + info.getDefaultConfiguration()); + } catch (BuildMacroException e){ + } + + try{ + //try to resolve the build macros in the target name + String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + buildTargetName, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + info.getDefaultConfiguration()); + if((resolved = resolved.trim()).length() > 0) + buildTargetName = resolved; + } catch (BuildMacroException e){ + } + + + if (buildTargetExt == null) { + buildTargetExt = new String(); + } + // Cache the build tools + config = info.getDefaultConfiguration(); + buildTools = config.getFilteredTools(); + buildToolsUsed = new boolean[buildTools.length]; + for (int i=0; i 0) { + inBuffer.append(readBuffer); + n = in.read(readBuffer); + } + 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; + } + + // Try to determine if this file already has dummy targets defined. + // If so, we will only add the comment. + String[] bufferLines = inBufferString.split("[\\r\\n]"); //$NON-NLS-1$ + for (int i=0; i 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 we are doing an incremental build, only update the files that do not have a comment + String firstToken; + try { + firstToken = (String) deps.get(0); + } catch (ArrayIndexOutOfBoundsException e) { + // This makes no sense so bail + return; + } + + // Put the generated comments in the output buffer + if (!firstToken.startsWith(COMMENT_SYMBOL)) { + outBuffer = addDefaultHeader(); + } else { + outBuffer = new StringBuffer(); + } + + // Some echo implementations misbehave and put the -n and newline in the output + if (firstToken.startsWith("-n")) { //$NON-NLS-1$ + + // Now let's parse: + // Win32 outputs -n '/.d /' + // POSIX outputs -n /.d / + // Get the dep file name + String secondToken; + try { + secondToken = (String) deps.get(1); + } catch (ArrayIndexOutOfBoundsException e) { + secondToken = new String(); + } + if (secondToken.startsWith("'")) { //$NON-NLS-1$ + // This is the Win32 implementation of echo (MinGW without MSYS) + outBuffer.append(secondToken.substring(1) + WHITESPACE); + } else { + outBuffer.append(secondToken + WHITESPACE); + } + + // The relative path to the build goal comes next + String thirdToken; + try { + thirdToken = (String) deps.get(2); + } catch (ArrayIndexOutOfBoundsException e) { + thirdToken = new String(); + } + int lastIndex = thirdToken.lastIndexOf("'"); //$NON-NLS-1$ + if (lastIndex != -1) { + if (lastIndex == 0) { + outBuffer.append(WHITESPACE); + } else { + outBuffer.append(thirdToken.substring(0, lastIndex - 1)); + } + } else { + outBuffer.append(thirdToken); + } + + // Followed by the target output by the compiler plus ':' + // If we see any empty tokens here, assume they are the result of + // a line feed output by "echo" and skip them + String fourthToken; + int nToken = 3; + try { + do { + fourthToken = (String) deps.get(nToken++); + } while (fourthToken.length() == 0); + + } catch (ArrayIndexOutOfBoundsException e) { + fourthToken = new String(); + } + outBuffer.append(fourthToken + WHITESPACE); + + // Followed by the actual dependencies + try { + Iterator iter = deps.listIterator(nToken); + while (iter.hasNext()) { + String nextElement = (String)iter.next(); + if (nextElement.endsWith("\\")) { //$NON-NLS-1$ + outBuffer.append(nextElement + NEWLINE + WHITESPACE); + } else { + outBuffer.append(nextElement + WHITESPACE); + } + } + } catch (IndexOutOfBoundsException e) { + } + + } else { + outBuffer.append(inBuffer); + } + + outBuffer.append(NEWLINE); + save = true; + + // Dummy targets to add to the makefile + 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 + * : + */ + outBuffer.append(dummy + COLON + NEWLINE + NEWLINE); + } + } + + // Write them out to the makefile + if (save) { + Util.save(outBuffer, makefile); + } + } + + /* (non-javadoc) + * This method generates a "fragment" make file (subdir.mk). + * One of these is generated for each project directory/subdirectory + * that contains source files. + * + * @param module + * @throws CoreException + */ + protected void populateFragmentMakefile(IContainer module) throws CoreException { + // Calculate the new directory relative to the build output + IPath moduleRelativePath = module.getProjectRelativePath(); + IPath buildRoot = getBuildWorkingDir(); + if (buildRoot == null) { + return; + } + + IPath moduleOutputPath = buildRoot.append(moduleRelativePath); + updateMonitor(ManagedMakeMessages.getFormattedString("MakefileGenerator.message.gen.source.makefile", moduleOutputPath.toString())); //$NON-NLS-1$ + + // Now create the directory + IPath moduleOutputDir = createDirectory(moduleOutputPath.toString()); + + // Create a module makefile + IFile modMakefile = createFile(moduleOutputDir.append(MODFILE_NAME)); + StringBuffer makeBuf = new StringBuffer(); + makeBuf.append(addFragmentMakefileHeader()); + makeBuf.append(addSources(module)); + + // Save the files + Util.save(makeBuf, modMakefile); + } + + /* (non-Javadoc) + * The makefile generator generates a Macro for each type of output, other than final artifact, + * created by the build. + * + * @param fileHandle The file that should be populated with the output + * @throws CoreException + */ + protected void populateObjectsMakefile(IFile fileHandle) throws CoreException { + + // Master list of "object" dependencies, i.e. dependencies between input files and output files. + StringBuffer macroBuffer = new StringBuffer(); + List valueList; + macroBuffer.append(addDefaultHeader()); + + // Map of macro names (String) to its definition (List of Strings) + HashMap outputMacros = new HashMap(); + + // Add the predefined LIBS, USER_OBJS macros + + // Add the libraries this project depends on + valueList = new ArrayList(); + String[] libs = info.getLibsForConfiguration(buildTargetExt); + for (int i = 0; i < libs.length; i++) { + String string = libs[i]; + valueList.add(string); + } + outputMacros.put("LIBS", valueList); //$NON-NLS-1$ + + // Add the extra user-specified objects + valueList = new ArrayList(); + String[] userObjs = info.getUserObjectsForConfiguration(buildTargetExt); + for (int i = 0; i < userObjs.length; i++) { + String string = userObjs[i]; + valueList.add(string); + } + outputMacros.put("USER_OBJS", valueList); //$NON-NLS-1$ + + // Write every macro to the file + Iterator iterator = outputMacros.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = (Map.Entry)iterator.next(); + macroBuffer.append((String)entry.getKey() + " :="); //$NON-NLS-1$ + valueList = (List)entry.getValue(); + Iterator valueIter = valueList.iterator(); + while (valueIter.hasNext()) { + macroBuffer.append(WHITESPACE + (String)valueIter.next()); + } + if (iterator.hasNext()) macroBuffer.append(NEWLINE + NEWLINE); + } + + // For now, just save the buffer that was populated when the rules were created + Util.save(macroBuffer, fileHandle); + + } + + /* (non-Javadoc) + * @param fileHandle + * @throws CoreException + */ + protected void populateSourcesMakefile(IFile fileHandle) throws CoreException { + // Add the comment + StringBuffer buffer = addDefaultHeader(); + + // Determine the set of macros + HashSet handledInputExtensions = new HashSet(); + String buildMacro; + for (int i=0; iStringBuffer containing all of the required targets to + * properly build the project. + * + * @param outputVarsAdditionsList list to add needed build output variables to + * @param rebuild + * @return StringBuffer + */ + private StringBuffer addTargets(List outputVarsAdditionsList, boolean rebuild) { + StringBuffer buffer = new StringBuffer(); + + IConfiguration config = info.getDefaultConfiguration(); + + // Assemble the information needed to generate the targets + String prebuildStep = info.getPrebuildStep(); + try{ + //try to resolve the build macros in the prebuild step + prebuildStep = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + prebuildStep, + EMPTY_STRING, + WHITESPACE, + IBuildMacroProvider.CONTEXT_CONFIGURATION, + config); + } catch (BuildMacroException e){ + } + prebuildStep = prebuildStep.trim(); // Remove leading and trailing whitespace (and control characters) + + String postbuildStep = info.getPostbuildStep(); + try{ + //try to resolve the build macros in the postbuild step + postbuildStep = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + postbuildStep, + EMPTY_STRING, + WHITESPACE, + IBuildMacroProvider.CONTEXT_CONFIGURATION, + config); + + } catch (BuildMacroException e){ + } + postbuildStep = postbuildStep.trim(); // Remove leading and trailing whitespace (and control characters) + String preannouncebuildStep = info.getPreannouncebuildStep(); + String postannouncebuildStep = info.getPostannouncebuildStep(); + String targets = rebuild ? "clean all" : "all"; //$NON-NLS-1$ //$NON-NLS-2$ + + ITool targetTool = config.getTargetTool(); + if (targetTool == null) { + targetTool = info.getToolFromOutputExtension(buildTargetExt); + } + + // Get all the projects the build target depends on + IProject[] refdProjects = null; + try { + refdProjects = project.getReferencedProjects(); + } catch (CoreException e) { + // There are 2 exceptions; the project does not exist or it is not open + // and neither conditions apply if we are building for it .... + } + + // If a prebuild step exists, redefine the all target to be + // all: {pre-build} main-build + // and then reset the "traditional" all target to main-build + // This will allow something meaningful to happen if the generated + // makefile is + // extracted and run standalone via "make all" + // + String defaultTarget = "all:"; //$NON-NLS-1$ + if (prebuildStep.length() > 0) { + + // Add the comment for the "All" target + buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(ALL_TARGET) + NEWLINE); + + buffer.append(defaultTarget + WHITESPACE); + buffer.append(PREBUILD + WHITESPACE); + + // Reset defaultTarget for now and for subsequent use, below + defaultTarget = MAINBUILD; + buffer.append(defaultTarget); + + // Update the defaultTarget, main-build, by adding a colon, which is + // needed below + defaultTarget = defaultTarget.concat(COLON); + buffer.append(NEWLINE + NEWLINE); + + // Add the comment for the "main-build" target + buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(MAINBUILD_TARGET) + NEWLINE); + } + else + // Add the comment for the "All" target + buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(ALL_TARGET) + NEWLINE); + + // Write out the all target first in case someone just runs make + // all: or mainbuild: + + String outputPrefix = EMPTY_STRING; + if (targetTool != null) { + outputPrefix = targetTool.getOutputPrefix(); + } + buffer.append(defaultTarget + WHITESPACE + outputPrefix + buildTargetName); + if (buildTargetExt.length() > 0) { + buffer.append(DOT + buildTargetExt); + } + + // Add the Secondary Outputs to the all target, if any + IOutputType[] secondaryOutputs = config.getToolChain().getSecondaryOutputs(); + if (secondaryOutputs.length > 0) { + buffer.append(WHITESPACE + SECONDARY_OUTPUTS); + } + + buffer.append(NEWLINE + NEWLINE); + + /* + * The build target may depend on other projects in the workspace. These + * are captured in the deps target: deps: ; + * $(MAKE) [clean all | all]> + */ + Vector managedProjectOutputs = new Vector(refdProjects.length); + if (refdProjects.length > 0) { + boolean addDeps = true; + if (refdProjects != null) { + for (int i = 0; i < refdProjects.length; i++) { + IProject dep = refdProjects[i]; + if (!dep.exists()) continue; + if (addDeps) { + buffer.append("dependents:" + NEWLINE); //$NON-NLS-1$ + addDeps = false; + } + String buildDir = dep.getLocation().toString(); + String depTargets = targets; + if (ManagedBuildManager.manages(dep)) { + // Add the current configuration to the makefile path + IManagedBuildInfo depInfo = ManagedBuildManager.getBuildInfo(dep); + buildDir += SEPARATOR + depInfo.getConfigurationName(); + + // Extract the build artifact to add to the dependency list + String depTarget = depInfo.getBuildArtifactName(); + String depExt = depInfo.getBuildArtifactExtension(); + + try{ + //try to resolve the build macros in the artifact extension + depExt = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + depExt, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + info.getDefaultConfiguration()); + } catch (BuildMacroException e){ + } + + try{ + //try to resolve the build macros in the artifact name + String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + depTarget, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + info.getDefaultConfiguration()); + if((resolved = resolved.trim()).length() > 0) + depTarget = resolved; + } catch (BuildMacroException e){ + } + + String depPrefix = depInfo.getOutputPrefix(depExt); + if (depInfo.needsRebuild()) { + depTargets = "clean all"; //$NON-NLS-1$ + } + String dependency = buildDir + SEPARATOR + depPrefix + depTarget; + if (depExt.length() > 0) { + dependency += DOT + depExt; + } + dependency = escapeWhitespaces(dependency); + managedProjectOutputs.add(dependency); + } + buffer.append(TAB + "-cd" + WHITESPACE + escapeWhitespaces(buildDir) + WHITESPACE + LOGICAL_AND + WHITESPACE + "$(MAKE) " + depTargets + NEWLINE); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + buffer.append(NEWLINE); + } + + // Add the targets tool rules + buffer.append(addTargetsRules(targetTool, + outputVarsAdditionsList, managedProjectOutputs, (postbuildStep.length() > 0))); + + // Add the prebuild step target, if specified + if (prebuildStep.length() > 0) { + buffer.append(PREBUILD + COLON + NEWLINE); + if (preannouncebuildStep.length() > 0) { + buffer.append(TAB + DASH + AT + escapedEcho(preannouncebuildStep)); + } + buffer.append(TAB + DASH + prebuildStep + NEWLINE); + buffer.append(TAB + DASH + AT + ECHO_BLANK_LINE + NEWLINE); + } + + // Add the postbuild step, if specified + if (postbuildStep.length() > 0) { + buffer.append(POSTBUILD + COLON + NEWLINE); + if (postannouncebuildStep.length() > 0) { + buffer.append(TAB + DASH + AT + escapedEcho(postannouncebuildStep)); + } + buffer.append(TAB + DASH + postbuildStep + NEWLINE); + buffer.append(TAB + DASH + AT + ECHO_BLANK_LINE + NEWLINE); + } + + // Add the Secondary Outputs target, if needed + if (secondaryOutputs.length > 0) { + buffer.append(SECONDARY_OUTPUTS + COLON); + Vector outs2 = calculateSecondaryOutputs(secondaryOutputs); + for (int i=0; i 0) { + buffer.append(WHITESPACE + MAINBUILD + WHITESPACE + PREBUILD); + } + if (postbuildStep.length() > 0) { + buffer.append(WHITESPACE + POSTBUILD); + } + buffer.append(NEWLINE); + Iterator refIter = managedProjectOutputs.listIterator(); + while(refIter.hasNext()) { + buffer.append((String)refIter.next() + COLON + NEWLINE); + } + buffer.append(NEWLINE); + + // Include makefile.targets supplemental makefile + buffer.append("-include " + ROOT + SEPARATOR + MAKEFILE_TARGETS + NEWLINE); //$NON-NLS-1$ + + return buffer; + } + + /** + * prepend all instanced of '\' or '"' with a backslash + * + * @param string + * @return + */ + public static String escapedEcho(String string) { + String escapedString = string.replaceAll("(['\"\\\\])", "\\\\$1"); + return ECHO + WHITESPACE + escapedString + NEWLINE; + } + + public static String ECHO_BLANK_LINE = ECHO + WHITESPACE + SINGLE_QUOTE + WHITESPACE + SINGLE_QUOTE + NEWLINE; + + + /* (non-javadoc) + * Returns the targets rules. The targets make file (top makefile) contains: + * 1 the rule for the final target tool + * 2 the rules for all of the tools that use multipleOfType in their primary input type + * 3 the rules for all tools that use the output of #2 tools + * + * @param outputVarsAdditionsList list to add needed build output variables to + * @param managedProjectOutputs Other projects in the workspace that this project depends upon + * @return StringBuffer + */ + private StringBuffer addTargetsRules(ITool targetTool, + List outputVarsAdditionsList, Vector managedProjectOutputs, boolean postbuildStep) { + StringBuffer buffer = new StringBuffer(); + // Add the comment + buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(BUILD_TOP) + NEWLINE); + + // Get the target tool and generate the rule + if (targetTool != null) { + if (addRuleForTool(targetTool, buffer, true, buildTargetName, buildTargetExt, + outputVarsAdditionsList, managedProjectOutputs, postbuildStep)) { + // Mark the target tool as processed + for (int i=0; i 0) { + buffer.append(DOT + buildTargetExt); + } + buffer.append(NEWLINE); + buffer.append(TAB + DASH + AT + ECHO_BLANK_LINE + NEWLINE); + + return buffer; + } + + /* (non-Javadoc) + * Create the rule + * + * @param tool + * @param buffer Buffer to add makefile rules to + * @param bTargetTool True if this is the target tool + * @param targetName If this is the "targetTool", the target file name, else null + * @param targetName If this is the "targetTool", the target file extension, else null + * @param outputVarsAdditionsList list to add needed build output variables to + * @param managedProjectOutputs Other projects in the workspace that this project depends upon + * @param bPostBuildStep Emit post-build step invocation + */ + protected boolean addRuleForTool(ITool tool, StringBuffer buffer, boolean bTargetTool, String targetName, String targetExt, + List outputVarsAdditionsList, Vector managedProjectOutputs, boolean bEmitPostBuildStepCall) { + + // Get the tool's inputs and outputs + Vector inputs = new Vector(); + Vector dependencies = new Vector(); + Vector outputs = new Vector(); + Vector enumeratedPrimaryOutputs = new Vector(); + Vector enumeratedSecondaryOutputs = new Vector(); + Vector outputVariables = new Vector(); + Vector additionalTargets = new Vector(); + String outputPrefix = EMPTY_STRING; + + if (!getToolInputsOutputs(tool, inputs, dependencies, outputs, + enumeratedPrimaryOutputs, enumeratedSecondaryOutputs, + outputVariables, additionalTargets, bTargetTool, managedProjectOutputs)) { + return false; + } + + // If we have no primary output, make all of the secondary outputs the primary output + if (enumeratedPrimaryOutputs.size() == 0) { + enumeratedPrimaryOutputs = enumeratedSecondaryOutputs; + enumeratedSecondaryOutputs.clear(); + } + + // Add the output variables for this tool to our list + outputVarsAdditionsList.addAll(outputVariables); + + // Create the build rule + String buildRule = EMPTY_STRING; + String outflag = tool.getOutputFlag(); + + String primaryOutputs = EMPTY_STRING; + boolean first = true; + for (int i=0; i 0) + command = resolvedCommand; + + } catch (BuildMacroException e){ + } + String[] cmdInputs = (String[])inputs.toArray(new String[inputs.size()]); + IManagedCommandLineGenerator gen = tool.getCommandLineGenerator(); + IManagedCommandLineInfo cmdLInfo = gen.generateCommandLineInfo( tool, command, + flags, outflag, outputPrefix, primaryOutputs, cmdInputs, tool.getCommandLinePattern() ); + + // The command to build + String buildCmd = null; + if( cmdLInfo == null ) { + String toolFlags; + try { + toolFlags = tool.getToolCommandFlagsString(null,null); + } catch( BuildException ex ) { + // TODO report error + toolFlags = EMPTY_STRING; + } + buildCmd = command + WHITESPACE + toolFlags + WHITESPACE + outflag + WHITESPACE + outputPrefix + primaryOutputs + WHITESPACE + IN_MACRO; + } + else buildCmd = cmdLInfo.getCommandLine(); + + // resolve any remaining macros in the command after it has been + // generated + try { + String resolvedCommand = ManagedBuildManager + .getBuildMacroProvider().resolveValueToMakefileFormat( + buildCmd, + EMPTY_STRING, + WHITESPACE, + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(null, null, null, tool)); + if ((resolvedCommand = resolvedCommand.trim()).length() > 0) + buildCmd = resolvedCommand; + + } catch (BuildMacroException e) { + } + + + buffer.append(TAB + AT + escapedEcho(buildCmd)); + buffer.append(TAB + AT + buildCmd); + + // TODO + // NOTE WELL: Dependency file generation is not handled for this type of Tool + + // Echo finished message + buffer.append(NEWLINE); + buffer.append(TAB + AT + escapedEcho((bTargetTool ? MESSAGE_FINISH_BUILD : MESSAGE_FINISH_FILE) + WHITESPACE + OUT_MACRO)); + buffer.append(TAB + AT + ECHO_BLANK_LINE); + + // If there is a post build step, then add a recursive invocation of MAKE to invoke it after the main build + // Note that $(MAKE) will instantiate in the recusive invocation to the make command that was used to invoke + // the makefile originally + if (bEmitPostBuildStepCall) { + buffer.append(TAB + MAKE + WHITESPACE + NO_PRINT_DIR + WHITESPACE + POSTBUILD + NEWLINE + NEWLINE); + } + else { + // Just emit a blank line + buffer.append(NEWLINE); + } + } + + // If we have secondary outputs, output dependency rules without commands + if (enumeratedSecondaryOutputs.size() > 0 || additionalTargets.size() > 0) { + String primaryOutput = (String)enumeratedPrimaryOutputs.get(0); + Vector addlOutputs = new Vector(); + addlOutputs.addAll(enumeratedSecondaryOutputs); + addlOutputs.addAll(additionalTargets); + for (int i=0; i 0) { + for (int j=0; j 0) { + for (int j=0; jStringBuffer containing the comment(s) + * for a fragment makefile (subdir.mk). + */ + protected StringBuffer addFragmentMakefileHeader() { + return addDefaultHeader(); + } + + /* (non-javadoc) + * Returns a StringBuffer containing makefile text for all of the sources + * contributed by a container (project directory/subdirectory) to the fragement makefile + * + * @param module project resource directory/subdirectory + * @return StringBuffer generated text for the fragement makefile + */ + protected StringBuffer addSources(IContainer module) throws CoreException { + // Calculate the new directory relative to the build output + IPath moduleRelativePath = module.getProjectRelativePath(); + String relativePath = moduleRelativePath.toString(); + relativePath += relativePath.length() == 0 ? "" : SEPARATOR; //$NON-NLS-1$ + + // For build macros in the configuration, create a map which will map them + // to a string which holds its list of sources. + LinkedHashMap buildVarToRuleStringMap = new LinkedHashMap(); + + // Add statements that add the source files in this folder, + // and generated source files, and generated dependency files + // to the build macros + Iterator iterator = buildSrcVars.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = (Map.Entry)iterator.next(); + String macroName = (String)entry.getKey(); + addMacroAdditionPrefix(buildVarToRuleStringMap, macroName, null, false); + } + iterator = buildOutVars.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = (Map.Entry)iterator.next(); + String macroName = (String)entry.getKey(); + addMacroAdditionPrefix(buildVarToRuleStringMap, macroName, "./" + relativePath, false); //$NON-NLS-1$ + } + + // String buffers + StringBuffer buffer = new StringBuffer(); // Return buffer + StringBuffer ruleBuffer = new StringBuffer(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(MOD_RULES) + NEWLINE); + + // Visit the resources in this folder and add each one to a sources macro, and generate a build rule, if appropriate + IResource[] resources = module.members(); + + IResourceConfiguration resConfig; + IFolder folder = project.getFolder(info.getConfigurationName()); + + for (int i = 0; i < resources.length; i++) { + IResource resource = resources[i]; + if (resource.getType() == IResource.FILE) { + // Check whether this resource is excluded from build + resConfig = config.getResourceConfiguration(resource.getFullPath().toString()); + if( (resConfig != null) && (resConfig.isExcluded()) ) + continue; + addFragmentMakefileEntriesForSource(buildVarToRuleStringMap, ruleBuffer, + folder, relativePath, resource, resource.getLocation(), resConfig, null, false); + } + } + + // Write out the macro addition entries to the buffer + buffer.append(writeAdditionMacros(buildVarToRuleStringMap)); + return buffer.append(ruleBuffer + NEWLINE); + } + + /* (non-Javadoc + * Adds the entries for a particular source file to the fragment makefile + * + * @param buildVarToRuleStringMap map of build variable names to the list of files assigned to the variable + * @param ruleBuffer buffer to add generated nmakefile text to + * @param folder the top level build output directory + * @param relativePath build output directory relative path of the current output directory + * @param resource the source file for this invocation of the tool - this may be null for a generated output + * @param sourceLocation the full path of the source + * @param resConfig the IResourceConfiguration associated with this file or null + * @param varName the build variable to add this invocation's outputs to + * if null, use the file extension to find the name + * @param generatedSource if true, this file was generated by another tool in the tool-chain + */ + protected void addFragmentMakefileEntriesForSource (LinkedHashMap buildVarToRuleStringMap, StringBuffer ruleBuffer, + IFolder folder, String relativePath, IResource resource, IPath sourceLocation, IResourceConfiguration resConfig, + String varName, boolean generatedSource) { + + // Determine which tool, if any, builds files with this extension + String ext = sourceLocation.getFileExtension(); + ITool tool = null; + + // Use the tool from the resource configuration if there is one + if (resConfig != null) { + ITool[] tools = resConfig.getToolsToInvoke(); + if (tools != null && tools.length > 0) { + tool = tools[0]; + } + } + for (int j=0; j 0) { + for (int k=0; k 0) { + IPath firstOutput = (IPath)generatedOutputs.get(0); + String firstExt = firstOutput.getFileExtension(); + for (int j=0; j 0) { + buildVariable = bV; + break; + } + } + } + } + } else { + buildVariable = outType.getBuildVariable(); + } + } else { + // For support of pre-CDT 3.0 integrations. + buildVariable = OBJS_MACRO; + } + + for (int k=0; k 0) { + if (isSecondaryOutputVar(secondaryOutputs, varName)) { + addMacroAdditionFile(buildVarToRuleStringMap, varName, relativePath, sourceLocation, generatedSource); + } + } + } + } + } + + /* (non-Javadoc) + * Adds the source file to the appropriate build variable + * + * @param buildVarToRuleStringMap map of build variable names to the list of files assigned to the variable + * @param ext the file extension of the file + * @param varName the build variable to add this invocation's outputs to + * if null, use the file extension to find the name + * @param relativePath build output directory relative path of the current output directory + * @param sourceLocation the full path of the source + * @param generatedSource if true, this file was generated by another tool in the tool-chain + */ + protected void addToBuildVar (LinkedHashMap buildVarToRuleStringMap, String ext, + String varName, String relativePath, IPath sourceLocation, boolean generatedSource) { + List varList = null; + if (varName == null) { + // Get the proper source build variable based upon the extension + varName = getSourceMacroName(ext).toString(); + varList = (List)buildSrcVars.get(varName); + } else { + varList = (List)buildOutVars.get(varName); + } + // Add the resource to the list of all resources associated with a variable. + // Do not allow duplicates - there is no reason to and it can be 'bad' - + // e.g., having the same object in the OBJS list can cause duplicate symbol errors from the linker + if ((varList != null) && !(varList.contains(sourceLocation))) { + // Since we don't know how these files will be used, we store them using a "location" + // path rather than a relative path + varList.add(sourceLocation); + if (!buildVarToRuleStringMap.containsKey(varName)) { + // TODO - is this an error? + } else { + // Add the resource name to the makefile line that adds resources to the build variable + addMacroAdditionFile(buildVarToRuleStringMap, varName, relativePath, sourceLocation, generatedSource); + } + } + } + + /* (non-Javadoc) + * Create a rule for this source file. We create a pattern rule if possible. + * + * This is an example of a pattern rule: + * + * /%.: ..//%. + * @echo Building file: $< + * @echo Invoking tool xxx + * @echo $@ $< + * @ $@ $< && \ + * echo -n $(@:%.o=%.d) ' /' >> $(@:%.o=%.d) && \ + * -P -MM -MG $< >> $(@:%.o=%.d) + * @echo Finished building: $< + * @echo ' ' + * + * Note that the macros all come from the build model and are + * resolved to a real command before writing to the module + * makefile, so a real command might look something like: + * source1/%.o: ../source1/%.cpp + * @echo Building file: $< + * @echo Invoking tool xxx + * @echo g++ -g -O2 -c -I/cygdrive/c/eclipse/workspace/Project/headers -o$@ $< + * @ g++ -g -O2 -c -I/cygdrive/c/eclipse/workspace/Project/headers -o$@ $< && \ + * echo -n $(@:%.o=%.d) ' source1/' >> $(@:%.o=%.d) && \ + * g++ -P -MM -MG -g -O2 -c -I/cygdrive/c/eclipse/workspace/Project/headers $< >> $(@:%.o=%.d) + * @echo Finished building: $< + * @echo ' ' + * + * @param relativePath top build output directory relative path of the current output directory + * @param buffer buffer to populate with the build rule + * @param resource the source file for this invocation of the tool + * @param sourceLocation the full path of the source + * @param resConfig the IResourceConfiguration associated with this file or null + * @param generatedSource true if the resource is a generated output + * @param generatedDepFile build directory relative paths of the dependency files generated by the rule + * @param enumeratedOutputs vector of the filenames that are the output of this rule + */ + protected void addRuleForSource(String relativePath, StringBuffer buffer, IResource resource, + IPath sourceLocation, IResourceConfiguration resConfig, + boolean generatedSource, Vector generatedDepFiles, Vector enumeratedOutputs) { + + String fileName = sourceLocation.removeFileExtension().lastSegment(); + String inputExtension = sourceLocation.getFileExtension(); + String outputExtension = info.getOutputExtension(inputExtension); + + ITool tool = null; + if( resConfig != null) { + ITool[] tools = resConfig.getToolsToInvoke(); + if (tools != null && tools.length > 0) { + tool = tools[0]; + } + } + if (tool == null) { + tool = info.getToolFromInputExtension(inputExtension); + } + + // Get the dependency generator information for this tool and file extension + IManagedDependencyGenerator oldDepGen = null; // This interface is deprecated but still supported + IManagedDependencyGenerator2 depGen = null; // This is the recommended interface + IManagedDependencyInfo depInfo = null; + IManagedDependencyCommands depCommands = null; + IManagedDependencyPreBuild depPreBuild = null; + IPath[] depFiles = null; + boolean doDepGen = false; + { + IManagedDependencyGeneratorType t = tool.getDependencyGeneratorForExtension(inputExtension); + if (t != null) { + int calcType = t.getCalculatorType(); + if (calcType <= IManagedDependencyGeneratorType.TYPE_OLD_TYPE_LIMIT) { + oldDepGen = (IManagedDependencyGenerator)t; + doDepGen = (calcType == IManagedDependencyGeneratorType.TYPE_COMMAND); + if (doDepGen) { + IPath depFile = Path.fromOSString(relativePath + fileName + DOT + DEP_EXT); + getDependencyMakefiles().add(depFile); + generatedDepFiles.add(depFile); + } + } else { + depGen = (IManagedDependencyGenerator2)t; + doDepGen = (calcType == IManagedDependencyGeneratorType.TYPE_BUILD_COMMANDS); + IBuildObject buildContext = (resConfig != null) ? (IBuildObject)resConfig : (IBuildObject)config; + depInfo = depGen.getDependencySourceInfo(resource.getProjectRelativePath(), buildContext, tool, getBuildWorkingDir()); + if (calcType == IManagedDependencyGeneratorType.TYPE_BUILD_COMMANDS) { + depCommands = (IManagedDependencyCommands)depInfo; + depFiles = depCommands.getDependencyFiles(); + } else if (calcType == IManagedDependencyGeneratorType.TYPE_PREBUILD_COMMANDS) { + depPreBuild = (IManagedDependencyPreBuild)depInfo; + depFiles = depPreBuild.getDependencyFiles(); + } + if (depFiles != null) { + for (int i=0; i 0) + optDotExt = DOT + outputExtension; + + Vector ruleOutputs = new Vector(); + Vector enumeratedPrimaryOutputs = new Vector(); // IPaths relative to the top build directory + Vector enumeratedSecondaryOutputs = new Vector(); // IPaths relative to the top build directory + calculateOutputsForSource(tool, relativePath, resource, sourceLocation, ruleOutputs, enumeratedPrimaryOutputs, enumeratedSecondaryOutputs); + enumeratedOutputs.addAll(enumeratedPrimaryOutputs); + enumeratedOutputs.addAll(enumeratedSecondaryOutputs); + String primaryOutputName = null; + if (enumeratedPrimaryOutputs.size() > 0) { + primaryOutputName = escapeWhitespaces(((IPath)enumeratedPrimaryOutputs.get(0)).toString()); + } else { + primaryOutputName = escapeWhitespaces(relativePath + fileName + optDotExt); + } + String otherPrimaryOutputs = EMPTY_STRING; + for (int i=1; i 0 + || MacroResolver.getReferencedExplitFileMacros(tool + .getToolCommand(), IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(sourceLocation, outputLocation, + null, tool)).length > 0; + + // Get and resolve the command + String cmd = tool.getToolCommand(); + + try { + String resolvedCommand = null; + if (!needExplicitRuleForFile) { + resolvedCommand = ManagedBuildManager.getBuildMacroProvider() + .resolveValueToMakefileFormat( + cmd, + EMPTY_STRING, + WHITESPACE, + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(sourceLocation, + outputLocation, null, tool)); + } else { + // if we need an explicit rule then don't use any builder + // variables, resolve everything + // to explicit strings + resolvedCommand = ManagedBuildManager.getBuildMacroProvider() + .resolveValue( + cmd, + EMPTY_STRING, + WHITESPACE, + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(sourceLocation, + outputLocation, null, tool)); + } + + if ((resolvedCommand = resolvedCommand.trim()).length() > 0) + cmd = resolvedCommand; + + } catch (BuildMacroException e) { + } + + String defaultOutputName = EMPTY_STRING; + String primaryDependencyName = EMPTY_STRING; + String patternPrimaryDependencyName = EMPTY_STRING; + String home = (generatedSource)? DOT : ROOT; + String resourcePath = null; + boolean patternRule = true; + boolean isItLinked = false; + //if (resource.isLinked()) { NOTE: we don't use this since children of linked resources return false + if(!sourceLocation.toString().startsWith(projectLocation)) { + // it IS linked, so use the actual location + isItLinked = true; + resourcePath = sourceLocation.toString(); + // Need a hardcoded rule, not a pattern rule, as a linked file + // can reside in any path + defaultOutputName = escapeWhitespaces(relativePath + fileName + optDotExt); + primaryDependencyName = escapeWhitespaces(resourcePath); + patternRule = false; + } else { + // Use the relative path (not really needed to store per se but in the future someone may want this) + resourcePath = relativePath; + // The rule and command to add to the makefile + if( resConfig != null || needExplicitRuleForFile) { + // Need a hardcoded rule, not a pattern rule + defaultOutputName = escapeWhitespaces(resourcePath + fileName + optDotExt); + patternRule = false; + } else { + defaultOutputName = relativePath + WILDCARD + optDotExt; + } + primaryDependencyName = escapeWhitespaces(home + SEPARATOR + resourcePath + fileName + DOT + inputExtension); + patternPrimaryDependencyName = home + SEPARATOR + resourcePath + WILDCARD + DOT + inputExtension; + } // end fix for PR 70491 + + // If the tool specifies a dependency calculator of TYPE_BUILD_COMMANDS, ask whether + // the dependency commands are "generic" (i.e., we can use a pattern rule) + boolean needExplicitDependencyCommands = false; + if (depCommands != null) { + needExplicitDependencyCommands = !depCommands.areCommandsGeneric(); + } + + // If we still think that we are using a pattern rule, check a few more things + if (patternRule) { + patternRule = false; + // Make sure that at least one of the rule outputs contains a %. + for (int i=0; i= 0) { //$NON-NLS-1$ + patternRule = true; + break; + } + } + if (patternRule) { + patternRule = !needExplicitDependencyCommands; + } + } + + // Begin building the rule for this source file + String buildRule = EMPTY_STRING; + + if (patternRule) { + if (ruleOutputs.size() == 0) { + buildRule += defaultOutputName; + } else { + boolean first = true; + for (int i=0; i= 0) { //$NON-NLS-1$ + if (first) { + first = false; + } else { + buildRule += WHITESPACE; + } + buildRule += ruleOutput; + } + } + } + } else { + buildRule += primaryOutputName; + } + + String buildRuleDependencies = primaryDependencyName; + String patternBuildRuleDependencies = patternPrimaryDependencyName; + + // Other additional inputs + // Get any additional dependencies specified for the tool in other InputType elements and AdditionalInput elements + IPath[] addlDepPaths = tool.getAdditionalDependencies(); + for (int i=0; i 0) { + for (int i=0; i 0) + buildCmd = resolvedCommand; + + } catch (BuildMacroException e) { + } + + buffer.append(TAB + AT + escapedEcho(buildCmd)); + buffer.append(TAB + AT + buildCmd); + + // Determine if there are any dependencies to calculate + if (doDepGen) { + // Get the dependency rule out of the generator + String[] depCmds = null; + if (oldDepGen != null) { + depCmds = new String[1]; + depCmds[0] = oldDepGen.getDependencyCommand(resource, info); + } else { + if (depCommands != null) { + depCmds = depCommands.getPostToolDependencyCommands(); + } + } + + if (depCmds != null) { + for (int i=0; i 0) { + calculatedDependencies = new String(); + for (int i=0; i 1) { + // Starting with 1 is intentional in order to skip the primary output + for (int i=1; i 0) depLine += WHITESPACE; + if (patternRule) { + optDotExt = EMPTY_STRING; + String depExt = depFiles[i].getFileExtension(); + if (depExt != null && depExt.length() > 0) + optDotExt = DOT + depExt; + depLine += escapeWhitespaces(relativePath + WILDCARD + optDotExt); + } else { + depLine += escapeWhitespaces((depFiles[i]).toString()); + } + } + depLine += COLON + WHITESPACE + (patternRule ? patternBuildRuleDependencies : buildRuleDependencies); + if (!getDepRuleList().contains(depLine)) { + getDepRuleList().add(depLine); + addedDepLines = true; + buffer.append(depLine + NEWLINE); + buffer.append(TAB + AT + escapedEcho(MESSAGE_START_DEPENDENCY + WHITESPACE + OUT_MACRO)); + for (int i=0; i 0) { + int flagsLen = flags.length; + String[] flagsCopy = new String[flags.length + depOptions.length]; + for (int i=0; i 0) { + allRes.add(Path.fromOSString("$(" + type.getBuildVariable() + ")")); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + // Use file extensions + String[] typeExts = type.getSourceExtensions(tool); + for (int j=0; j 0) b = true; + if (toolParent instanceof IToolChain) { + IConfiguration config = ((IToolChain)toolParent).getParent(); + if (config != null) { + ManagedBuildManager.setOption(config, tool, assignToOption, b); + } + } else if (toolParent instanceof IResourceConfiguration) { + ManagedBuildManager.setOption(((IResourceConfiguration)toolParent), tool, assignToOption, b); + } + } else if (optType == IOption.ENUMERATED) { + if (allRes.size() > 0) { + String s = allRes.get(0).toString(); + if (toolParent instanceof IToolChain) { + IConfiguration config = ((IToolChain)toolParent).getParent(); + if (config != null) { + ManagedBuildManager.setOption(config, tool, assignToOption, s); + } + } else if (toolParent instanceof IResourceConfiguration) { + ManagedBuildManager.setOption(((IResourceConfiguration)toolParent), tool, assignToOption, s); + } + } + } + allRes.clear(); + } + } catch( BuildException ex ) { + } + } + } + } + return (IPath[])allRes.toArray(new IPath[allRes.size()]); + } + + + /* (non-Javadoc) + * Returns the output IPaths for this invocation of the tool with the specified source file + /* + * The priorities for determining the names of the outputs of a tool are: + * 1. If the tool is the build target and primary output, use artifact name & extension - + * This case does not apply here... + * 2. If an option is specified, use the value of the option + * 3. If a nameProvider is specified, call it + * 4. If outputNames is specified, use it + * 5. Use the name pattern to generate a transformation macro + * so that the source names can be transformed into the target names + * using the built-in string substitution functions of make. + * + * @param tool + * @param relativePath build output directory relative path of the current output directory + * @param resource + * @param ruleOutputs Vector of rule IPaths that are relative to the build directory + * @param enumeratedPrimaryOutputs Vector of IPaths of primary outputs + * that are relative to the build directory + * @param enumeratedSecondaryOutputs Vector of IPaths of secondary outputs + * that are relative to the build directory + */ + protected void calculateOutputsForSource(ITool tool, String relativePath, IResource resource, + IPath sourceLocation, Vector ruleOutputs, Vector enumeratedPrimaryOutputs, Vector enumeratedSecondaryOutputs) { + String inExt = sourceLocation.getFileExtension(); + String outExt = tool.getOutputExtension(inExt); + + IOutputType[] outTypes = tool.getOutputTypes(); + if (outTypes != null && outTypes.length > 0) { + for (int i=0; i 0) { + for (int j=0; j 0) + outputName = resolved; + } catch (BuildMacroException e){ + } + + IPath outPath = Path.fromOSString(outputName); + // If only a file name is specified, add the relative path of this output directory + if (outPath.segmentCount() == 1) { + outPath = Path.fromOSString(relativePath + (String)outputList.get(j)); + } + if (primaryOutput) { + ruleOutputs.add(j, outPath); + enumeratedPrimaryOutputs.add(j, resolvePercent(outPath, sourceLocation)); + } else { + ruleOutputs.add(outPath); + enumeratedSecondaryOutputs.add(resolvePercent(outPath, sourceLocation)); + } + } + } catch( BuildException ex ) {} + } else + // 3. If a nameProvider is specified, call it + if (nameProvider != null) { + IPath[] inPaths = new IPath[1]; + inPaths[0] = sourceLocation; + IPath[] outPaths = nameProvider.getOutputNames(tool, inPaths); + for (int j=0; j 0) + outputName = resolved; + } catch (BuildMacroException e) { + } + + // If only a file name is specified, add the relative path of this output directory + if (outPath.segmentCount() == 1) { + outPath = Path.fromOSString(relativePath + outPath.toString()); + } + if (primaryOutput) { + ruleOutputs.add(j, outPath); + enumeratedPrimaryOutputs.add(j, resolvePercent(outPath, sourceLocation)); + } else { + ruleOutputs.add(outPath); + enumeratedSecondaryOutputs.add(resolvePercent(outPath, sourceLocation)); + } + } + } else + // 4. If outputNames is specified, use it + if (outputNames != null) { + for (int j = 0; j < outputNames.length; j++) { + String outputName = outputNames[j]; + try{ + //try to resolve the build macros in the output names + String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + outputName, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(sourceLocation, null, option, tool)); + if((resolved = resolved.trim()).length() > 0) + outputName = resolved; + } catch (BuildMacroException e){ + } + + IPath outPath = Path.fromOSString(outputName); + // If only a file name is specified, add the relative path of this output directory + if (outPath.segmentCount() == 1) { + outPath = Path.fromOSString(relativePath + outPath.toString()); + } + if (primaryOutput) { + ruleOutputs.add(j, outPath); + enumeratedPrimaryOutputs.add(j, resolvePercent(outPath, sourceLocation)); + } else { + ruleOutputs.add(outPath); + enumeratedSecondaryOutputs.add(resolvePercent(outPath, sourceLocation)); + } + } + } else { + // 5. Use the name pattern to generate a transformation macro + // so that the source names can be transformed into the target names + // using the built-in string substitution functions of make. + if (multOfType) { + // This case is not handled - a nameProvider or outputNames must be specified + // TODO - report error + } else { + String namePattern = type.getNamePattern(); + IPath namePatternPath = null; + if (namePattern == null || namePattern.length() == 0) { + namePattern = relativePath + outputPrefix + IManagedBuilderMakefileGenerator.WILDCARD; + if (outExt != null && outExt.length() > 0) { + namePattern += DOT + outExt; + } + namePatternPath = Path.fromOSString(namePattern); + } + else { + if (outputPrefix.length() > 0) { + namePattern = outputPrefix + namePattern; + } + namePatternPath = Path.fromOSString(namePattern); + // If only a file name is specified, add the relative path of this output directory + if (namePatternPath.segmentCount() == 1) { + namePatternPath = Path.fromOSString(relativePath + namePatternPath.toString()); + } + } + + if (primaryOutput) { + ruleOutputs.add(0, namePatternPath); + enumeratedPrimaryOutputs.add(0, resolvePercent(namePatternPath, sourceLocation)); + } else { + ruleOutputs.add(namePatternPath); + enumeratedSecondaryOutputs.add(resolvePercent(namePatternPath, sourceLocation)); + } + } + } + } + } else { + // For support of pre-CDT 3.0 integrations. + // NOTE WELL: This only supports the case of a single "target tool" + // that consumes exactly all of the object files, $OBJS, produced + // by other tools in the build and produces a single output. + // In this case, the output file name is the input file name with + // the output extension. + + //if (!ignorePrimary) { + String outPrefix = tool.getOutputPrefix(); + IPath outPath = Path.fromOSString(relativePath + outPrefix + WILDCARD); + outPath = outPath.addFileExtension(outExt); + ruleOutputs.add(0, outPath); + enumeratedPrimaryOutputs.add(0, resolvePercent(outPath, sourceLocation)); + //} + } + } + + /* (non-Javadoc) + * If the path contains a %, returns the path resolved using the resource name + * + */ + protected IPath resolvePercent(IPath outPath, IPath sourceLocation) { + // Get the input file name + String fileName = sourceLocation.removeFileExtension().lastSegment(); + // Replace the % with the file name + String outName = outPath.toOSString().replaceAll("%", fileName); //$NON-NLS-1$ + return Path.fromOSString(outName); + } + + /* (non-Javadoc) + * Returns the dependency IPaths for this invocation of the tool with the specified source file + * + * @param depGen the dependency calculator + * @param tool tool used to build the source file + * @param relativePath build output directory relative path of the current output directory + * @param resource source file to scan for dependencies + * @return Vector of IPaths that are relative to the build directory + */ + protected IPath[] oldCalculateDependenciesForSource(IManagedDependencyGenerator depGen, ITool tool, String relativePath, IResource resource) { + Vector deps = new Vector(); + int type = depGen.getCalculatorType(); + + switch (type) { + + case IManagedDependencyGeneratorType.TYPE_INDEXER: + case IManagedDependencyGeneratorType.TYPE_EXTERNAL: + IResource[] res = depGen.findDependencies(resource, project); + if (res != null) { + for (int i=0; iIPaths relative to the build directory + * + * @param depCalculator the dependency calculator + * @return IPath[] that are relative to the build directory + */ + protected IPath[] calculateDependenciesForSource(IManagedDependencyCalculator depCalculator) { + IPath[] addlDeps = depCalculator.getDependencies(); + if (addlDeps != null) { + for (int i=0; iSet containing all of the output extensions + */ + public Set getOutputExtensions() { + if (outputExtensionsSet == null) { + // The set of output extensions which will be produced by this tool. + // It is presumed that this set is not very large (likely < 10) so + // a HashSet should provide good performance. + outputExtensionsSet = new HashSet(); + + // For each tool for the target, lookup the kinds of sources it outputs + // and add that to our list of output extensions. + for (int i=0; i + * ##### ....... ##### + */ + protected StringBuffer addDefaultHeader() { + StringBuffer buffer = new StringBuffer(); + outputCommentLine(buffer); + buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(HEADER) + NEWLINE); + outputCommentLine(buffer); + buffer.append(NEWLINE); + return buffer; + } + + /* (non-Javadoc) + * Put COLS_PER_LINE comment charaters in the argument. + */ + protected void outputCommentLine(StringBuffer buffer) { + for (int i = 0; i < COLS_PER_LINE; i++) { + buffer.append(COMMENT_SYMBOL); + } + buffer.append(NEWLINE); + } + + static public boolean containsSpecialCharacters(String path) + { + return path.matches(".*(\\s|[\\{\\}\\(\\)\\$\\@%=;]).*"); + } + + /* (non-Javadoc) + * Answers the argument with all whitespaces replaced with an escape sequence. + * + * @param path + */ + public static String escapeWhitespaces(String path) { + // Escape the spaces in the path/filename if it has any + String[] segments = path.split("\\s"); //$NON-NLS-1$ + if (segments.length > 1) { + StringBuffer escapedPath = new StringBuffer(); + for (int index = 0; index < segments.length; ++index) { + escapedPath.append(segments[index]); + if (index + 1 < segments.length) { + escapedPath.append("\\ "); //$NON-NLS-1$ + } + } + return escapedPath.toString().trim(); + } else { + return path; + } + } + + /* (non-Javadoc) + * Adds a macro addition prefix to a map of macro names to entries. + * Entry prefixes look like: + * C_SRCS += \ + * ${addprefix $(ROOT)/, \ + */ + // TODO fix comment + protected void addMacroAdditionPrefix(LinkedHashMap map, String macroName, String relativePath, boolean addPrefix) { + // there is no entry in the map, so create a buffer for this macro + StringBuffer tempBuffer = new StringBuffer(); + tempBuffer.append(macroName + WHITESPACE + MACRO_ADDITION_PREFIX_SUFFIX); + if (addPrefix) { + tempBuffer.append(MACRO_ADDITION_ADDPREFIX_HEADER + relativePath + MACRO_ADDITION_ADDPREFIX_SUFFIX); + } + + // have to store the buffer in String form as StringBuffer is not a sublcass of Object + map.put(macroName, tempBuffer.toString()); + } + + /* (non-Javadoc) + * Adds a file to an entry in a map of macro names to entries. + * File additions look like: + * example.c, \ + */ + protected void addMacroAdditionFile(HashMap map, String macroName, String filename) { + StringBuffer buffer = new StringBuffer(); + buffer.append(map.get(macroName)); + + // escape whitespace in the filename + filename = escapeWhitespaces(filename); + + buffer.append(filename + WHITESPACE + LINEBREAK); + // re-insert string in the map + map.put(macroName, buffer.toString()); + } + + /* (non-Javadoc) + * Adds a file to an entry in a map of macro names to entries. + * File additions look like: + * example.c, \ + */ + protected void addMacroAdditionFile(HashMap map, String macroName, + String relativePath, IPath sourceLocation, boolean generatedSource) { + // Add the source file path to the makefile line that adds source files to the build variable + String srcName; + IPath projectLocation = project.getLocation(); + IPath dirLocation = projectLocation; + if (generatedSource) { + dirLocation = dirLocation.append(getBuildWorkingDir()); + } + if (dirLocation.isPrefixOf(sourceLocation)) { + IPath srcPath = sourceLocation.removeFirstSegments(dirLocation.segmentCount()).setDevice(null); + if (generatedSource) { + srcName = "./" + srcPath.toString(); //$NON-NLS-1$ + } else { + srcName = ROOT + "/" + srcPath.toString(); //$NON-NLS-1$ + } + } else { + if (generatedSource && !sourceLocation.isAbsolute()) { + srcName = "./" + relativePath + sourceLocation.lastSegment().toString(); //$NON-NLS-1$ + } else { + // TODO: Should we use relative paths when possible (e.g., see MbsMacroSupplier.calculateRelPath) + srcName = sourceLocation.toString(); + } + } + addMacroAdditionFile(map, macroName, srcName); + } + + /* (non-Javadoc) + * Adds file(s) to an entry in a map of macro names to entries. + * File additions look like: + * example.c, \ + */ + public void addMacroAdditionFiles(HashMap map, String macroName, Vector filenames) { + StringBuffer buffer = new StringBuffer(); + buffer.append(map.get(macroName)); + for (int i=0; i 0) { + buffer.append(filename + WHITESPACE + LINEBREAK); + } + } + // re-insert string in the map + map.put(macroName, buffer.toString()); + } + + /* (non-Javadoc) + * Write all macro addition entries in a map to the buffer + */ + protected StringBuffer writeAdditionMacros(LinkedHashMap map) { + StringBuffer buffer = new StringBuffer(); + // Add the comment + buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(MOD_VARS) + NEWLINE); + + Collection bufferCollection = map.values(); + Iterator collectionIterator = bufferCollection.iterator(); + while(collectionIterator.hasNext()) + { + String macroString = collectionIterator.next().toString(); + // Check if we added any files to the rule + // Currently, we do this by comparing the end of the rule buffer to MACRO_ADDITION_PREFIX_SUFFIX + if (!(macroString.endsWith(MACRO_ADDITION_PREFIX_SUFFIX))) { + StringBuffer currentBuffer = new StringBuffer(); + + // Remove the final "/" + if (macroString.endsWith(LINEBREAK)) { + macroString = macroString.substring(0, (macroString + .length() - 2)) + + NEWLINE; + } + currentBuffer.append(macroString); + + currentBuffer.append(NEWLINE); + + // append the contents of the buffer to the master buffer for + // the whole file + buffer.append(currentBuffer); + } + } + return buffer.append(NEWLINE); + } + + /* (non-Javadoc) + * Write all macro addition entries in a map to the buffer + */ + protected StringBuffer writeTopAdditionMacros(List varList, HashMap varMap) { + StringBuffer buffer = new StringBuffer(); + // Add the comment + buffer.append(COMMENT_SYMBOL + WHITESPACE + ManagedMakeMessages.getResourceString(MOD_VARS) + NEWLINE); + + for (int i=0; i 0) + name = resolved; + } catch (BuildMacroException e){ + } + + gnuToolInfos[i] = new ManagedBuildGnuToolInfo(project, buildTools[i], true, + name, ext); + } else { + gnuToolInfos[i] = new ManagedBuildGnuToolInfo(project, buildTools[i], false, null, null); + } + doneState[i] = 0; + } + + // Initialize the build output variable to file additions map + LinkedHashMap map = getTopBuildOutputVars(); + Iterator iterator = buildOutVars.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = (Map.Entry)iterator.next(); + String macroName = (String)entry.getKey(); + addMacroAdditionPrefix(map, macroName, "", false); //$NON-NLS-1$ + } + + // Set of input extensions for which macros have been created so far + HashSet handledDepsInputExtensions = new HashSet(); + HashSet handledOutsInputExtensions = new HashSet(); + + while (!done) { + int[] testState = new int[doneState.length]; + for (int i=0; iOperationCanceledException. + * + * @see org.eclipse.core.runtime.OperationCanceledException#OperationCanceledException() + */ + protected void checkCancel() { + if (monitor != null && monitor.isCanceled()) { + throw new OperationCanceledException(); + } + } + + /* (non-Javadoc) + * Return or create the folder needed for the build output. If we are + * creating the folder, set the derived bit to true so the CM system + * ignores the contents. If the resource exists, respect the existing + * derived setting. + * + * @param string + * @return IPath + */ + private IPath createDirectory(String dirName) throws CoreException { + // Create or get the handle for the build directory + IFolder folder = project.getFolder(dirName); + if (!folder.exists()) { + // Make sure that parent folders exist + IPath parentPath = (new Path(dirName)).removeLastSegments(1); + // Assume that the parent exists if the path is empty + if (!parentPath.isEmpty()) { + IFolder parent = project.getFolder(parentPath); + if (!parent.exists()) { + createDirectory(parentPath.toString()); + } + } + + // Now make the requested folder + try { + folder.create(true, true, null); + } + catch (CoreException e) { + if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED) + folder.refreshLocal(IResource.DEPTH_ZERO, null); + else + throw e; + } + + // Make sure the folder is marked as derived so it is not added to CM + if (!folder.isDerived()) { + folder.setDerived(true); + } + } + + return folder.getFullPath(); + } + + /* (non-Javadoc) + * Return or create the makefile needed for the build. If we are creating + * the resource, set the derived bit to true so the CM system ignores + * the contents. If the resource exists, respect the existing derived + * setting. + * + * @param makefilePath + * @return IFile + */ + private IFile createFile(IPath makefilePath) throws CoreException { + // Create or get the handle for the makefile + IWorkspaceRoot root = CCorePlugin.getWorkspace().getRoot(); + IFile newFile = root.getFileForLocation(makefilePath); + if (newFile == null) { + newFile = root.getFile(makefilePath); + } + // Create the file if it does not exist + ByteArrayInputStream contents = new ByteArrayInputStream(new byte[0]); + try { + newFile.create(contents, false, new SubProgressMonitor(monitor, 1)); + // Make sure the new file is marked as derived + if (!newFile.isDerived()) { + newFile.setDerived(true); + } + + } + catch (CoreException e) { + // If the file already existed locally, just refresh to get contents + if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED) + newFile.refreshLocal(IResource.DEPTH_ZERO, null); + else + throw e; + } + + return newFile; + } + + /** + * @param deletedFile + */ + private void deleteBuildTarget(IResource deletedFile) { + // Get the project relative path of the file + String fileName = getFileName(deletedFile); + String srcExtension = deletedFile.getFileExtension(); + String targetExtension = info.getOutputExtension(srcExtension); + if (targetExtension != "") //$NON-NLS-1$ + fileName += DOT + targetExtension; + IPath projectRelativePath = deletedFile.getProjectRelativePath().removeLastSegments(1); + IPath targetFilePath = getBuildWorkingDir().append(projectRelativePath).append(fileName); + IResource depFile = project.findMember(targetFilePath); + if (depFile != null && depFile.exists()) { + try { + depFile.delete(true, new SubProgressMonitor(monitor, 1)); + } catch (CoreException e) { + // This had better be allowed during a build + + } + } + } + + /** + * @param deletedFile + */ + private void deleteDepFile(IResource deletedFile) { + // Calculate the top build directory relative paths of the dependency files + IPath[] depFilePaths = null; + ITool tool = null; + IManagedDependencyGeneratorType depType = null; + String sourceExtension = deletedFile.getFileExtension(); + ITool[] tools = config.getFilteredTools(); + for (int index = 0; index < tools.length; ++index) { + if (tools[index].buildsFileType(sourceExtension)) { + tool = tools[index]; + depType = tool.getDependencyGeneratorForExtension(sourceExtension); + break; + } + } + if (depType != null) { + int calcType = depType.getCalculatorType(); + if (calcType == IManagedDependencyGeneratorType.TYPE_COMMAND) { + depFilePaths = new IPath[1]; + IPath absolutePath = deletedFile.getLocation(); + depFilePaths[0] = ManagedBuildManager.calculateRelativePath(getTopBuildDir(), absolutePath); + depFilePaths[0] = depFilePaths[0].removeFileExtension().addFileExtension(DEP_EXT); + } else if (calcType == IManagedDependencyGeneratorType.TYPE_BUILD_COMMANDS || + calcType == IManagedDependencyGeneratorType.TYPE_PREBUILD_COMMANDS) { + IManagedDependencyGenerator2 depGen = (IManagedDependencyGenerator2)depType; + IManagedDependencyInfo depInfo = depGen.getDependencySourceInfo( + deletedFile.getProjectRelativePath(), config, tool, getBuildWorkingDir()); + if (depInfo != null) { + if (calcType == IManagedDependencyGeneratorType.TYPE_BUILD_COMMANDS) { + IManagedDependencyCommands depCommands = (IManagedDependencyCommands)depInfo; + depFilePaths = depCommands.getDependencyFiles(); + } else if (calcType == IManagedDependencyGeneratorType.TYPE_PREBUILD_COMMANDS) { + IManagedDependencyPreBuild depPreBuild = (IManagedDependencyPreBuild)depInfo; + depFilePaths = depPreBuild.getDependencyFiles(); + } + } + } + } + + // Delete the files if they exist + if (depFilePaths != null) { + for (int i=0; iString + * + * @param file + * @return + */ + private String getFileName(IResource file) { + String answer = new String(); + String lastSegment = file.getName(); + int extensionSeparator = lastSegment.lastIndexOf(DOT); + if (extensionSeparator != -1) { + answer = lastSegment.substring(0, extensionSeparator); + } + 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; + } + + /* (non-javadoc) + * + * @return Vector + */ + private Vector getModifiedList() { + if (modifiedList == null) { + modifiedList = new Vector(); + } + return modifiedList; + } + + /* (non-javadoc) + * Answers the list of subdirectories (IContainer's) contributing source code to the build + * + * @return List + */ + private Vector getSubdirList() { + if (subdirList == null) { + subdirList = new Vector(); + } + return subdirList; + } + + /* (non-Javadoc) + * @param subDir + */ + private void removeGeneratedDirectory(IContainer subDir) { + try { + // The source directory isn't empty + if (subDir.exists() && subDir.members().length > 0) return; + } catch (CoreException e) { + // The resource doesn't exist so we should delete the output folder + } + + // Figure out what the generated directory name is and delete it + IPath moduleRelativePath = subDir.getProjectRelativePath(); + IPath buildRoot = getBuildWorkingDir(); + if (buildRoot == null) { + return; + } + IPath moduleOutputPath = buildRoot.append(moduleRelativePath); + IFolder folder = project.getFolder(moduleOutputPath); + if (folder.exists()) { + try { + folder.delete(true, new SubProgressMonitor(monitor, 1)); + } catch (CoreException e) { + // TODO Log this + } + } + } + + /* (non-Javadoc) + * @param msg + */ + protected void updateMonitor(String msg) { + if (monitor!= null && !monitor.isCanceled()) { + monitor.subTask(msg); + monitor.worked(1); + } + } + + /** + * Return the configuration's top build directory as an absolute path + */ + public IPath getTopBuildDir() { + return project.getLocation().append(getBuildWorkingDir()); + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/IManagedBuildGnuToolInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/IManagedBuildGnuToolInfo.java index b120ad40ac2..09f7f160232 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/IManagedBuildGnuToolInfo.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/IManagedBuildGnuToolInfo.java @@ -1,112 +1,122 @@ -/******************************************************************************* - * Copyright (c) 2005 Intel Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Intel Corporation - Initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.makegen.gnu; - -import java.util.Vector; - -/** - * This interface returns information about a Tool's inputs - * and outputs while a Gnu makefile is being generated. - */ -public interface IManagedBuildGnuToolInfo { - public final String DOT = "."; //$NON-NLS-1$ - - /** - * Returns true if the tool's inputs have been calculated, - * else false. - * - * @return boolean - */ - public boolean areInputsCalculated(); - - /** - * Returns the tool's inputs in command line format. This will use - * variables rather than actual file names as appropriate. - * - * @return Vector - */ - public Vector getCommandInputs(); - - /** - * Returns the raw list of tool's input file names. - * - * @return Vector - */ - public Vector getEnumeratedInputs(); - - /** - * Returns true if the tool's outputs have been calculated, - * else false. - * - * @return boolean - */ - public boolean areOutputsCalculated(); - - /** - * Returns the tool's outputs in command line format. This will use - * variables rather than actual file names as appropriate. - * - * @return Vector - */ - public Vector getCommandOutputs(); - - /** - * Returns the raw list of tool's primary output file names. - * - * @return Vector - */ - public Vector getEnumeratedPrimaryOutputs(); - - /** - * Returns the raw list of tool's secondary output file names. - * - * @return Vector - */ - public Vector getEnumeratedSecondaryOutputs(); - - /** - * Returns the raw list of tool's output variable names. - * - * @return Vector - */ - public Vector getOutputVariables(); - - /** - * Returns true if the tool's dependencies have been calculated, - * else false. - * - * @return boolean - */ - public boolean areDependenciesCalculated(); - - /** - * Returns the tool's dependencies in command line format. This will use - * variables rather than actual file names as appropriate. - * - * @return Vector - */ - public Vector getCommandDependencies(); - - /** - * Returns the raw list of tool's input dependencies. - * - * @return Vector - */ - //public Vector getEnumeratedDependencies(); - - /** - * Returns true if this is the target tool - * else false. - * - * @return boolean - */ - public boolean isTargetTool(); -} +/******************************************************************************* + * Copyright (c) 2005, 2006 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.makegen.gnu; + +import java.util.Vector; + +/** + * This interface returns information about a Tool's inputs + * and outputs while a Gnu makefile is being generated. + */ +public interface IManagedBuildGnuToolInfo { + public final String DOT = "."; //$NON-NLS-1$ + + /** + * Returns true if the tool's inputs have been calculated, + * else false. + * + * @return boolean + */ + public boolean areInputsCalculated(); + + /** + * Returns the tool's inputs in command line format. This will use + * variables rather than actual file names as appropriate. + * + * @return Vector + */ + public Vector getCommandInputs(); + + /** + * Returns the raw list of tool's input file names. + * + * @return Vector + */ + public Vector getEnumeratedInputs(); + + /** + * Returns true if the tool's outputs have been calculated, + * else false. + * + * @return boolean + */ + public boolean areOutputsCalculated(); + + /** + * Returns the tool's outputs in command line format. This will use + * variables rather than actual file names as appropriate. + * + * @return Vector + */ + public Vector getCommandOutputs(); + + /** + * Returns the raw list of tool's primary output file names. + * + * @return Vector + */ + public Vector getEnumeratedPrimaryOutputs(); + + /** + * Returns the raw list of tool's secondary output file names. + * + * @return Vector + */ + public Vector getEnumeratedSecondaryOutputs(); + + /** + * Returns the raw list of tool's output variable names. + * + * @return Vector + */ + public Vector getOutputVariables(); + + /** + * Returns true if the tool's dependencies have been calculated, + * else false. + * + * @return boolean + */ + public boolean areDependenciesCalculated(); + + /** + * Returns the tool's dependencies in command line format. This will use + * variables rather than actual file names as appropriate. + * Dependencies are top build directory relative. + * + * @return Vector + */ + public Vector getCommandDependencies(); + + /** + * Returns the tool's additional targets as determined by the + * dependency calculator. + * Additional targets are top build directory relative + * + * @return Vector + */ + public Vector getAdditionalTargets(); + + /** + * Returns the raw list of tool's input dependencies. + * + * @return Vector + */ + //public Vector getEnumeratedDependencies(); + + /** + * Returns true if this is the target tool + * else false. + * + * @return boolean + */ + public boolean isTargetTool(); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java index de423f774de..ca0d780621a 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java @@ -1,980 +1,996 @@ -/******************************************************************************* - * Copyright (c) 2005 Intel Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Intel Corporation - Initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.makegen.gnu; - -import java.util.Iterator; -import java.util.List; -import java.util.Arrays; -import java.util.ArrayList; -import java.util.Vector; -import java.util.Map; -import java.util.HashMap; -import java.util.HashSet; - -import org.eclipse.cdt.managedbuilder.core.IAdditionalInput; -import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IInputType; -import org.eclipse.cdt.managedbuilder.core.IOutputType; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.IOption; -import org.eclipse.cdt.managedbuilder.core.IManagedOutputNameProvider; -import org.eclipse.cdt.managedbuilder.core.BuildException; -import org.eclipse.cdt.managedbuilder.core.IToolChain; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; -import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; -import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; -import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages; -import org.eclipse.cdt.managedbuilder.internal.core.Tool; -import org.eclipse.cdt.managedbuilder.internal.macros.OptionContextData; -import org.eclipse.cdt.managedbuilder.makegen.gnu.GnuMakefileGenerator; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Path; - -/** - * This class represents information about a Tool's inputs - * and outputs while a Gnu makefile is being generated. - */ -public class ManagedBuildGnuToolInfo implements IManagedBuildGnuToolInfo { - - //private static final String EMPTY_STRING = new String(); - //private static final String OBJS_MACRO = "OBJS"; //$NON-NLS-1$ - private static final String DEPS_MACRO = "DEPS"; //$NON-NLS-1$ - - /* - * Members - */ - private IProject project; - private Tool tool; - private boolean bIsTargetTool; - private String targetName; - private String targetExt; - private boolean inputsCalculated = false; - private boolean outputsCalculated = false; - private boolean outputVariablesCalculated = false; - private boolean dependenciesCalculated = false; - private Vector commandInputs = new Vector(); - private Vector enumeratedInputs = new Vector(); - private Vector commandOutputs = new Vector(); - private Vector enumeratedPrimaryOutputs = new Vector(); - private Vector enumeratedSecondaryOutputs = new Vector(); - private Vector outputVariables = new Vector(); - private Vector commandDependencies = new Vector(); - //private Vector enumeratedDependencies = new Vector(); - // Map of macro names (String) to values (List) - - /* - * Constructor - */ - public ManagedBuildGnuToolInfo(IProject project, ITool tool, boolean targetTool, String name, String ext) { - this.project = project; - this.tool = (Tool)tool; - bIsTargetTool = targetTool; - if (bIsTargetTool) { - targetName = name; - targetExt = ext; - } - } - - /* - * IManagedBuildGnuToolInfo Methods - */ - public boolean areInputsCalculated() { - return inputsCalculated; - } - - // Command inputs are top build directory relative - public Vector getCommandInputs() { - return commandInputs; - } - - // Enumerated inputs are project relative - public Vector getEnumeratedInputs() { - return enumeratedInputs; - } - - public boolean areOutputsCalculated() { - return outputsCalculated; - } - - // Command outputs are top build directory relative - public Vector getCommandOutputs() { - return commandOutputs; - } - - public Vector getEnumeratedPrimaryOutputs() { - return enumeratedPrimaryOutputs; - } - - public Vector getEnumeratedSecondaryOutputs() { - return enumeratedSecondaryOutputs; - } - - public Vector getOutputVariables() { - return outputVariables; - } - - public boolean areOutputVariablesCalculated() { - return outputVariablesCalculated; - } - - public boolean areDependenciesCalculated() { - return dependenciesCalculated; - } - - public Vector getCommandDependencies() { - return commandDependencies; - } - - //public Vector getEnumeratedDependencies() { - // return enumeratedDependencies; - //} - - public boolean isTargetTool() { - return bIsTargetTool; - } - - /* - * Other Methods - */ - - public boolean calculateInputs(GnuMakefileGenerator makeGen, IConfiguration config, IResource[] projResources, boolean lastChance) { - // Get the inputs for this tool invocation - // Note that command inputs that are also dependencies are also added to the command dependencies list - - /* The priorities for determining the names of the inputs of a tool are: - * 1. If an option is specified, use the value of the option. - * 2. If a build variable is specified, use the files that have been added to the build variable as - * the output(s) of other build steps. - * 3. Use the file extensions and the resources in the project - */ - boolean done = true; - Vector myCommandInputs = new Vector(); // Inputs for the tool command line - Vector myCommandDependencies = new Vector(); // Dependencies for the make rule - Vector myEnumeratedInputs = new Vector(); // Complete list of individual inputs - - IInputType[] inTypes = tool.getInputTypes(); - if (inTypes != null && inTypes.length > 0) { - for (int i=0; i 0) - inputName = resolved; - } catch (BuildMacroException e) { - } - - if (primaryInput) { - itCommandDependencies.add(j, inputName); - } else { - itCommandDependencies.add(inputName); - } - // NO - itCommandInputs.add(inputName); - // NO - itEnumeratedInputs.add(inputName); - } - } catch( BuildException ex ) { - } - - } else { - - // Build Variable? - if (variable.length() > 0) { - String cmdVariable = variable = "$(" + variable + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - itCommandInputs.add(cmdVariable); - if (primaryInput) { - itCommandDependencies.add(0, cmdVariable); - } else { - itCommandDependencies.add(cmdVariable); - } - // If there is an output variable with the same name, get - // the files associated with it. - List outMacroList = makeGen.getBuildVariableList(variable, GnuMakefileGenerator.PROJECT_RELATIVE, - null, true); - if (outMacroList != null) { - itEnumeratedInputs.addAll(outMacroList); - } else { - // If "last chance", then calculate using file extensions below - if (lastChance) { - useFileExts = true; - } else { - done = false; - break; - } - } - } - - // Use file extensions - if (variable.length() == 0 || useFileExts) { - //if (type.getMultipleOfType()) { - // Calculate EnumeratedInputs using the file extensions and the resources in the project - // Note: This is only correct for tools with multipleOfType == true, but for other tools - // it gives us an input resource for generating default names - // Determine the set of source input macros to use - HashSet handledInputExtensions = new HashSet(); - String[] exts = type.getSourceExtensions(tool); - if (projResources != null) { - for (int j=0; j 0) { - ManagedBuildManager.setOption(config, tool, assignToOption, true); - } else { - ManagedBuildManager.setOption(config, tool, assignToOption, false); - } - } else if (optType == IOption.ENUMERATED) { - if (itCommandInputs.size() > 0) { - ManagedBuildManager.setOption(config, tool, assignToOption, (String)itCommandInputs.firstElement()); - } - } - itCommandInputs.removeAllElements(); - //itEnumeratedInputs.removeAllElements(); - } catch( BuildException ex ) { - } - } - - myCommandInputs.addAll(itCommandInputs); - myCommandDependencies.addAll(itCommandDependencies); - myEnumeratedInputs.addAll(itEnumeratedInputs); - } - } else { - // For support of pre-CDT 3.0 integrations. - if (bIsTargetTool) { - // NOTE WELL: This only supports the case of a single "target tool" - // with the following characteristics: - // 1. The tool consumes exactly all of the object files produced - // by other tools in the build and produces a single output - // 2. The target name comes from the configuration artifact name - // The rule looks like: - // .: $(OBJS) - myCommandInputs.add("$(OBJS)"); //$NON-NLS-1$ - myCommandInputs.add("$(USER_OBJS)"); //$NON-NLS-1$ - myCommandInputs.add("$(LIBS)"); //$NON-NLS-1$ - } else { - // Rule will be generated by addRuleForSource - } - } - - if (done) { - commandInputs.addAll(myCommandInputs); - commandDependencies.addAll(0, myCommandDependencies); - enumeratedInputs.addAll(myEnumeratedInputs); - inputsCalculated = true; - return true; - } - - return false; - } - - /* - * The priorities for determining the names of the outputs of a tool are: - * 1. If the tool is the build target and primary output, use artifact name & extension - * 2. If an option is specified, use the value of the option - * 3. If a nameProvider is specified, call it - * 4. If outputNames is specified, use it - * 5. Use the name pattern to generate a transformation macro - * so that the source names can be transformed into the target names - * using the built-in string substitution functions of make. - * - * NOTE: If an option is not specified and this is not the primary output type, the outputs - * from the type are not added to the command line - */ - public boolean calculateOutputs(GnuMakefileGenerator makeGen, IConfiguration config, HashSet handledInputExtensions, boolean lastChance) { - - boolean done = true; - Vector myCommandOutputs = new Vector(); - Vector myEnumeratedPrimaryOutputs = new Vector(); - Vector myEnumeratedSecondaryOutputs = new Vector(); - HashMap myOutputMacros = new HashMap(); - // The next two fields are used together - Vector myBuildVars = new Vector(); - Vector myBuildVarsValues = new Vector(); - - // Get the outputs for this tool invocation - IOutputType[] outTypes = tool.getOutputTypes(); - if (outTypes != null && outTypes.length > 0) { - for (int i=0; i 0) { - outputName += (DOT + targetExt); - } - myCommandOutputs.add(outputName); - typeEnumeratedOutputs.add(outputName); - // But this doesn't use any output macro... - } else - // 2. If an option is specified, use the value of the option - if (option != null) { - try { - List outputs = new ArrayList(); - int optType = option.getValueType(); - if (optType == IOption.STRING) { - outputs.add(outputPrefix + option.getStringValue()); - } else if ( - optType == IOption.STRING_LIST || - optType == IOption.LIBRARIES || - optType == IOption.OBJECTS) { - outputs = (List)option.getValue(); - // Add outputPrefix to each if necessary - if (outputPrefix.length() > 0) { - for (int j=0; j 0) - outputs.set(j, resolved); - } catch (BuildMacroException e){ - } - } - - // NO - myCommandOutputs.addAll(outputs); - typeEnumeratedOutputs.addAll(outputs); - if (variable.length() > 0) { - List outputPaths = new ArrayList(); - for (int j=0; j 0) { - outputName = resolved; - outNames[j] = Path.fromOSString(resolved); - } - } catch (BuildMacroException e){ - } - - if (primaryOutput) { - myCommandOutputs.add(outputName); - } - typeEnumeratedOutputs.add(outputName); - } - } - } - if (variable.length() > 0 && outNames != null) { - if (myOutputMacros.containsKey(variable)) { - List currList = (List)myOutputMacros.get(variable); - currList.addAll(Arrays.asList(outNames)); - myOutputMacros.put(variable, currList); - } else { - myOutputMacros.put(variable, Arrays.asList(outNames)); - } - } - } else - // 4. If outputNames is specified, use it - if (outputNames != null) { - if (outputNames.length > 0) { - for (int j=0; j 0) - outputNames[j] = resolved; - } catch (BuildMacroException e){ - } - } - List namesList = Arrays.asList(outputNames); - if (primaryOutput) { - myCommandOutputs.addAll(namesList); - } - typeEnumeratedOutputs.addAll(namesList); - if (variable.length() > 0) { - List outputPaths = new ArrayList(); - for (int j=0; jmake. - if (multOfType) { - // This case is not handled - a nameProvider or outputNames must be specified - List errList = new ArrayList(); - errList.add(ManagedMakeMessages.getResourceString("MakefileGenerator.error.no.nameprovider")); //$NON-NLS-1$ - myCommandOutputs.add(errList); - } else { - String namePattern = type.getNamePattern(); - if (namePattern == null || namePattern.length() == 0) { - namePattern = outputPrefix + IManagedBuilderMakefileGenerator.WILDCARD; - String outExt = (type.getOutputExtensions(tool))[0]; - if (outExt != null && outExt.length() > 0) { - namePattern += DOT + outExt; - } - } - else if (outputPrefix.length() > 0) { - namePattern = outputPrefix + namePattern; - } - - // Calculate the output name - // The inputs must have been calculated before we can do this - if (!inputsCalculated) { - done = false; - } else { - Vector inputs = getEnumeratedInputs(); - String fileName; - if (inputs.size() > 0) { - // Get the input file name - fileName = (Path.fromOSString((String)inputs.get(0))).removeFileExtension().lastSegment(); - // Check if this is a build macro. If so, use the raw macro name. - if (fileName.startsWith("$(") && fileName.endsWith(")")) { //$NON-NLS-1$ //$NON-NLS-2$ - fileName = fileName.substring(2,fileName.length()-1); - } - } else { - fileName = "default"; //$NON-NLS-1$ - } - // Replace the % with the file name - if (primaryOutput) { - myCommandOutputs.add(namePattern.replaceAll("%", fileName)); //$NON-NLS-1$ - } - typeEnumeratedOutputs.add(namePattern.replaceAll("%", fileName)); //$NON-NLS-1$ - if (variable.length() > 0) { - List outputs = new ArrayList(); - outputs.add(Path.fromOSString(fileName)); - if (myOutputMacros.containsKey(variable)) { - List currList = (List)myOutputMacros.get(variable); - currList.addAll(outputs); - myOutputMacros.put(variable, currList); - } else { - myOutputMacros.put(variable, outputs); - } - } - } - } - } - if (variable.length() > 0) { - myBuildVars.add(variable); - myBuildVarsValues.add(typeEnumeratedOutputs); - } - if (primaryOutput) { - myEnumeratedPrimaryOutputs.addAll(typeEnumeratedOutputs); - } else { - myEnumeratedSecondaryOutputs.addAll(typeEnumeratedOutputs); - } - } - } else { - if (bIsTargetTool) { - String outputPrefix = tool.getOutputPrefix(); - String outputName = outputPrefix + targetName; - if (targetExt.length() > 0) { - outputName += (DOT + targetExt); - } - myCommandOutputs.add(outputName); - myEnumeratedPrimaryOutputs.add(outputName); - } else { - // For support of pre-CDT 3.0 integrations. - // NOTE WELL: This only supports the case of a single "target tool" - // that consumes exactly all of the object files, $OBJS, produced - // by other tools in the build and produces a single output - } - } - - // Add the output macros of this tool to the buildOutVars map - Iterator iterator = myOutputMacros.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry)iterator.next(); - String macroName = (String)entry.getKey(); - List newMacroValue = (List)entry.getValue(); - HashMap map = makeGen.getBuildOutputVars(); - if (map.containsKey(macroName)) { - List macroValue = (List)map.get(macroName); - macroValue.addAll(newMacroValue); - map.put(macroName, macroValue); - } else { - map.put(macroName, newMacroValue); - } - } - outputVariablesCalculated = true; - - if (done) { - commandOutputs.addAll(myCommandOutputs); - enumeratedPrimaryOutputs.addAll(myEnumeratedPrimaryOutputs); - enumeratedSecondaryOutputs.addAll(myEnumeratedSecondaryOutputs); - outputVariables.addAll(myOutputMacros.keySet()); - outputsCalculated = true; - for (int i=0; i 0) { - for (int i=0; i 0) { - for (int j=0; j.: $(OBJS) - myCommandDependencies.add("$(OBJS)"); //$NON-NLS-1$ - myCommandDependencies.add("$(USER_OBJS)"); //$NON-NLS-1$ - } else { - String[] extensionsList = tool.getAllInputExtensions(); - - // Handle dependencies from the dependencyCalculator - IManagedDependencyGenerator depGen = tool.getDependencyGenerator(); - if (depGen != null) { - int calcType = depGen.getCalculatorType(); - switch (calcType) { - case IManagedDependencyGenerator.TYPE_COMMAND: - // iterate over all extensions that the tool knows how to handle - for (int i=0; i 0) { + for (int i=0; i 0) + inputName = resolved; + } catch (BuildMacroException e) { + } + + if (primaryInput) { + itCommandDependencies.add(j, inputName); + } else { + itCommandDependencies.add(inputName); + } + // NO - itCommandInputs.add(inputName); + // NO - itEnumeratedInputs.add(inputName); + } + } catch( BuildException ex ) { + } + + } else { + + // Build Variable? + if (variable.length() > 0) { + String cmdVariable = variable = "$(" + variable + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + itCommandInputs.add(cmdVariable); + if (primaryInput) { + itCommandDependencies.add(0, cmdVariable); + } else { + itCommandDependencies.add(cmdVariable); + } + // If there is an output variable with the same name, get + // the files associated with it. + List outMacroList = makeGen.getBuildVariableList(variable, GnuMakefileGenerator.PROJECT_RELATIVE, + null, true); + if (outMacroList != null) { + itEnumeratedInputs.addAll(outMacroList); + } else { + // If "last chance", then calculate using file extensions below + if (lastChance) { + useFileExts = true; + } else { + done = false; + break; + } + } + } + + // Use file extensions + if (variable.length() == 0 || useFileExts) { + //if (type.getMultipleOfType()) { + // Calculate EnumeratedInputs using the file extensions and the resources in the project + // Note: This is only correct for tools with multipleOfType == true, but for other tools + // it gives us an input resource for generating default names + // Determine the set of source input macros to use + HashSet handledInputExtensions = new HashSet(); + String[] exts = type.getSourceExtensions(tool); + if (projResources != null) { + for (int j=0; j 0) { + ManagedBuildManager.setOption(config, tool, assignToOption, true); + } else { + ManagedBuildManager.setOption(config, tool, assignToOption, false); + } + } else if (optType == IOption.ENUMERATED) { + if (itCommandInputs.size() > 0) { + ManagedBuildManager.setOption(config, tool, assignToOption, (String)itCommandInputs.firstElement()); + } + } + itCommandInputs.removeAllElements(); + //itEnumeratedInputs.removeAllElements(); + } catch( BuildException ex ) { + } + } + + myCommandInputs.addAll(itCommandInputs); + myCommandDependencies.addAll(itCommandDependencies); + myEnumeratedInputs.addAll(itEnumeratedInputs); + } + } else { + // For support of pre-CDT 3.0 integrations. + if (bIsTargetTool) { + // NOTE WELL: This only supports the case of a single "target tool" + // with the following characteristics: + // 1. The tool consumes exactly all of the object files produced + // by other tools in the build and produces a single output + // 2. The target name comes from the configuration artifact name + // The rule looks like: + // .: $(OBJS) + myCommandInputs.add("$(OBJS)"); //$NON-NLS-1$ + myCommandInputs.add("$(USER_OBJS)"); //$NON-NLS-1$ + myCommandInputs.add("$(LIBS)"); //$NON-NLS-1$ + } else { + // Rule will be generated by addRuleForSource + } + } + + if (done) { + commandInputs.addAll(myCommandInputs); + commandDependencies.addAll(0, myCommandDependencies); + enumeratedInputs.addAll(myEnumeratedInputs); + inputsCalculated = true; + return true; + } + + return false; + } + + /* + * The priorities for determining the names of the outputs of a tool are: + * 1. If the tool is the build target and primary output, use artifact name & extension + * 2. If an option is specified, use the value of the option + * 3. If a nameProvider is specified, call it + * 4. If outputNames is specified, use it + * 5. Use the name pattern to generate a transformation macro + * so that the source names can be transformed into the target names + * using the built-in string substitution functions of make. + * + * NOTE: If an option is not specified and this is not the primary output type, the outputs + * from the type are not added to the command line + */ + public boolean calculateOutputs(GnuMakefileGenerator makeGen, IConfiguration config, HashSet handledInputExtensions, boolean lastChance) { + + boolean done = true; + Vector myCommandOutputs = new Vector(); + Vector myEnumeratedPrimaryOutputs = new Vector(); + Vector myEnumeratedSecondaryOutputs = new Vector(); + HashMap myOutputMacros = new HashMap(); + // The next two fields are used together + Vector myBuildVars = new Vector(); + Vector myBuildVarsValues = new Vector(); + + // Get the outputs for this tool invocation + IOutputType[] outTypes = tool.getOutputTypes(); + if (outTypes != null && outTypes.length > 0) { + for (int i=0; i 0) { + outputName += (DOT + targetExt); + } + myCommandOutputs.add(outputName); + typeEnumeratedOutputs.add(outputName); + // But this doesn't use any output macro... + } else + // 2. If an option is specified, use the value of the option + if (option != null) { + try { + List outputs = new ArrayList(); + int optType = option.getValueType(); + if (optType == IOption.STRING) { + outputs.add(outputPrefix + option.getStringValue()); + } else if ( + optType == IOption.STRING_LIST || + optType == IOption.LIBRARIES || + optType == IOption.OBJECTS) { + outputs = (List)option.getValue(); + // Add outputPrefix to each if necessary + if (outputPrefix.length() > 0) { + for (int j=0; j 0) + outputs.set(j, resolved); + } catch (BuildMacroException e){ + } + } + + // NO - myCommandOutputs.addAll(outputs); + typeEnumeratedOutputs.addAll(outputs); + if (variable.length() > 0) { + List outputPaths = new ArrayList(); + for (int j=0; j 0) { + outputName = resolved; + outNames[j] = Path.fromOSString(resolved); + } + } catch (BuildMacroException e){ + } + + if (primaryOutput) { + myCommandOutputs.add(outputName); + } + typeEnumeratedOutputs.add(outputName); + } + } + } + if (variable.length() > 0 && outNames != null) { + if (myOutputMacros.containsKey(variable)) { + List currList = (List)myOutputMacros.get(variable); + currList.addAll(Arrays.asList(outNames)); + myOutputMacros.put(variable, currList); + } else { + myOutputMacros.put(variable, Arrays.asList(outNames)); + } + } + } else + // 4. If outputNames is specified, use it + if (outputNames != null) { + if (outputNames.length > 0) { + for (int j=0; j 0) + outputNames[j] = resolved; + } catch (BuildMacroException e){ + } + } + List namesList = Arrays.asList(outputNames); + if (primaryOutput) { + myCommandOutputs.addAll(namesList); + } + typeEnumeratedOutputs.addAll(namesList); + if (variable.length() > 0) { + List outputPaths = new ArrayList(); + for (int j=0; jmake. + if (multOfType) { + // This case is not handled - a nameProvider or outputNames must be specified + List errList = new ArrayList(); + errList.add(ManagedMakeMessages.getResourceString("MakefileGenerator.error.no.nameprovider")); //$NON-NLS-1$ + myCommandOutputs.add(errList); + } else { + String namePattern = type.getNamePattern(); + if (namePattern == null || namePattern.length() == 0) { + namePattern = outputPrefix + IManagedBuilderMakefileGenerator.WILDCARD; + String outExt = (type.getOutputExtensions(tool))[0]; + if (outExt != null && outExt.length() > 0) { + namePattern += DOT + outExt; + } + } + else if (outputPrefix.length() > 0) { + namePattern = outputPrefix + namePattern; + } + + // Calculate the output name + // The inputs must have been calculated before we can do this + if (!inputsCalculated) { + done = false; + } else { + Vector inputs = getEnumeratedInputs(); + String fileName; + if (inputs.size() > 0) { + // Get the input file name + fileName = (Path.fromOSString((String)inputs.get(0))).removeFileExtension().lastSegment(); + // Check if this is a build macro. If so, use the raw macro name. + if (fileName.startsWith("$(") && fileName.endsWith(")")) { //$NON-NLS-1$ //$NON-NLS-2$ + fileName = fileName.substring(2,fileName.length()-1); + } + } else { + fileName = "default"; //$NON-NLS-1$ + } + // Replace the % with the file name + if (primaryOutput) { + myCommandOutputs.add(namePattern.replaceAll("%", fileName)); //$NON-NLS-1$ + } + typeEnumeratedOutputs.add(namePattern.replaceAll("%", fileName)); //$NON-NLS-1$ + if (variable.length() > 0) { + List outputs = new ArrayList(); + outputs.add(Path.fromOSString(fileName)); + if (myOutputMacros.containsKey(variable)) { + List currList = (List)myOutputMacros.get(variable); + currList.addAll(outputs); + myOutputMacros.put(variable, currList); + } else { + myOutputMacros.put(variable, outputs); + } + } + } + } + } + if (variable.length() > 0) { + myBuildVars.add(variable); + myBuildVarsValues.add(typeEnumeratedOutputs); + } + if (primaryOutput) { + myEnumeratedPrimaryOutputs.addAll(typeEnumeratedOutputs); + } else { + myEnumeratedSecondaryOutputs.addAll(typeEnumeratedOutputs); + } + } + } else { + if (bIsTargetTool) { + String outputPrefix = tool.getOutputPrefix(); + String outputName = outputPrefix + targetName; + if (targetExt.length() > 0) { + outputName += (DOT + targetExt); + } + myCommandOutputs.add(outputName); + myEnumeratedPrimaryOutputs.add(outputName); + } else { + // For support of pre-CDT 3.0 integrations. + // NOTE WELL: This only supports the case of a single "target tool" + // that consumes exactly all of the object files, $OBJS, produced + // by other tools in the build and produces a single output + } + } + + // Add the output macros of this tool to the buildOutVars map + Iterator iterator = myOutputMacros.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = (Map.Entry)iterator.next(); + String macroName = (String)entry.getKey(); + List newMacroValue = (List)entry.getValue(); + HashMap map = makeGen.getBuildOutputVars(); + if (map.containsKey(macroName)) { + List macroValue = (List)map.get(macroName); + macroValue.addAll(newMacroValue); + map.put(macroName, macroValue); + } else { + map.put(macroName, newMacroValue); + } + } + outputVariablesCalculated = true; + + if (done) { + commandOutputs.addAll(myCommandOutputs); + enumeratedPrimaryOutputs.addAll(myEnumeratedPrimaryOutputs); + enumeratedSecondaryOutputs.addAll(myEnumeratedSecondaryOutputs); + outputVariables.addAll(myOutputMacros.keySet()); + outputsCalculated = true; + for (int i=0; i 0) depExt = xt; + } + String depsMacroEntry = calculateSourceMacro(makeGen, extensionName, depExt, + IManagedBuilderMakefileGenerator.WILDCARD); + + List depsList = new ArrayList(); + depsList.add(Path.fromOSString(depsMacroEntry)); + String depsMacro = makeGen.getDepMacroName(extensionName).toString(); + if (myOutputMacros.containsKey(depsMacro)) { + List currList = (List)myOutputMacros.get(depsMacro); + currList.addAll(depsList); + myOutputMacros.put(depsMacro, currList); + } else { + myOutputMacros.put(depsMacro, depsList); + } + } + } + break; + + case IManagedDependencyGeneratorType.TYPE_INDEXER: + case IManagedDependencyGeneratorType.TYPE_EXTERNAL: + case IManagedDependencyGeneratorType.TYPE_CUSTOM: + // The inputs must have been calculated before we can do this + if (!inputsCalculated) { + done = false; + } else { + Vector inputs = getEnumeratedInputs(); + + if (calcType == IManagedDependencyGeneratorType.TYPE_CUSTOM) { + IManagedDependencyGenerator2 depGen2 = (IManagedDependencyGenerator2)depGen; + IManagedDependencyInfo depInfo = null; + for (int i=0; i 0) { + for (int i=0; i 0) { + for (int j=0; j.: $(OBJS) + myCommandDependencies.add("$(OBJS)"); //$NON-NLS-1$ + myCommandDependencies.add("$(USER_OBJS)"); //$NON-NLS-1$ + } else { + // Handle dependencies from the dependencyCalculator + IManagedDependencyGeneratorType depGen = tool.getDependencyGenerator(); + String[] extensionsList = tool.getAllInputExtensions(); + if (depGen != null) { + done = callDependencyCalculator (makeGen, config, handledInputExtensions, + depGen, extensionsList, myCommandDependencies, myOutputMacros, + myAdditionalTargets, done); + } + + } + } + + // Add the output macros of this tool to the buildOutVars map + Iterator iterator = myOutputMacros.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = (Map.Entry)iterator.next(); + String macroName = (String)entry.getKey(); + List newMacroValue = (List)entry.getValue(); + HashMap map = makeGen.getBuildOutputVars(); + if (map.containsKey(macroName)) { + List macroValue = (List)map.get(macroName); + macroValue.addAll(newMacroValue); + map.put(macroName, macroValue); + } else { + map.put(macroName, newMacroValue); + } + } + + if (done) { + commandDependencies.addAll(myCommandDependencies); + additionalTargets.addAll(myAdditionalTargets); + //enumeratedDependencies.addAll(myEnumeratedDependencies); + dependenciesCalculated = true; + return true; + } + + return false; + } + + + /* + * Calculate the source macro for the given extension + */ + protected String calculateSourceMacro(GnuMakefileGenerator makeGen, String srcExtensionName, String outExtensionName, String wildcard) { + StringBuffer macroName = makeGen.getSourceMacroName(srcExtensionName); + String OptDotExt = ""; //$NON-NLS-1$ + if (outExtensionName != null) { + OptDotExt = DOT + outExtensionName; + } else + if (tool.getOutputExtension(srcExtensionName) != "") //$NON-NLS-1$ + OptDotExt = DOT + tool.getOutputExtension(srcExtensionName); + + // create rule of the form + // OBJS = $(macroName1: ../%.input1=%.output1) ... $(macroNameN: ../%.inputN=%.outputN) + StringBuffer objectsBuffer = new StringBuffer(); + objectsBuffer.append(IManagedBuilderMakefileGenerator.WHITESPACE + "$(" + macroName + //$NON-NLS-1$ + IManagedBuilderMakefileGenerator.COLON + IManagedBuilderMakefileGenerator.ROOT + //$NON-NLS-1$ + IManagedBuilderMakefileGenerator.SEPARATOR + IManagedBuilderMakefileGenerator.WILDCARD + + DOT + srcExtensionName + "=" + wildcard + OptDotExt + ")" ); //$NON-NLS-1$ //$NON-NLS-2$ + return objectsBuffer.toString(); + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/internal/DefaultIndexerDependencyCalculator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/internal/DefaultIndexerDependencyCalculator.java index 33355861e54..f1ccd65b145 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/internal/DefaultIndexerDependencyCalculator.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/internal/DefaultIndexerDependencyCalculator.java @@ -1,87 +1,87 @@ -/******************************************************************************* - * Copyright (c) 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.managedbuilder.makegen.internal; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.search.ICSearchConstants; -import org.eclipse.cdt.core.search.ICSearchScope; -import org.eclipse.cdt.core.search.SearchEngine; -import org.eclipse.cdt.internal.core.search.PathCollector; -import org.eclipse.cdt.internal.core.search.PatternSearchJob; -import org.eclipse.cdt.internal.core.search.indexing.IndexManager; -import org.eclipse.cdt.internal.core.search.matching.CSearchPattern; -import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; -import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspaceRoot; - -/** - * @since 2.0 - */ -public class DefaultIndexerDependencyCalculator implements IManagedDependencyGenerator { - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#findDependencies(org.eclipse.core.resources.IResource) - */ - public IResource[] findDependencies(IResource resource, IProject project) { - 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, 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 (project != null) { - root = 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()]); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getCalculatorType() - */ - public int getCalculatorType() { - // Tell the - return TYPE_INDEXER; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getDependencyCommand() - */ - public String getDependencyCommand(IResource resource, IManagedBuildInfo info) { - // There is no command - return null; - } -} +/******************************************************************************* + * Copyright (c) 2004, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.makegen.internal; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.search.ICSearchConstants; +import org.eclipse.cdt.core.search.ICSearchScope; +import org.eclipse.cdt.core.search.SearchEngine; +import org.eclipse.cdt.internal.core.search.PathCollector; +import org.eclipse.cdt.internal.core.search.PatternSearchJob; +import org.eclipse.cdt.internal.core.search.indexing.IndexManager; +import org.eclipse.cdt.internal.core.search.matching.CSearchPattern; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRoot; + +/** + * @since 2.0 + */ +public class DefaultIndexerDependencyCalculator implements IManagedDependencyGenerator { + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#findDependencies(org.eclipse.core.resources.IResource) + */ + public IResource[] findDependencies(IResource resource, IProject project) { + 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, 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 (project != null) { + root = 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()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getCalculatorType() + */ + public int getCalculatorType() { + // Tell the + return TYPE_EXTERNAL; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getDependencyCommand() + */ + public String getDependencyCommand(IResource resource, IManagedBuildInfo info) { + // There is no command + return null; + } +} -- cgit v1.2.3