/******************************************************************************* * Copyright (c) 2003, 2016 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 * James Blackburn (Broadcom Corp.) * Dmitry Kozlov (CodeSourcery) - Save build output preferences (bug 294106) * Andrew Gvozdev (Quoin Inc) - Saving build output implemented in different way (bug 306222) *******************************************************************************/ package org.eclipse.cdt.managedbuilder.internal.core; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import java.util.Vector; import org.eclipse.cdt.build.core.scannerconfig.ICfgScannerConfigBuilderInfo2Set; import org.eclipse.cdt.build.internal.core.scannerconfig.CfgDiscoveredPathManager.PathInfoCache; import org.eclipse.cdt.core.ErrorParserManager; import org.eclipse.cdt.core.settings.model.CSourceEntry; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICExternalSetting; import org.eclipse.cdt.core.settings.model.ICLibraryPathEntry; import org.eclipse.cdt.core.settings.model.ICOutputEntry; import org.eclipse.cdt.core.settings.model.ICSettingBase; import org.eclipse.cdt.core.settings.model.ICSettingEntry; import org.eclipse.cdt.core.settings.model.ICSourceEntry; import org.eclipse.cdt.core.settings.model.ICStorageElement; import org.eclipse.cdt.core.settings.model.extension.CBuildData; import org.eclipse.cdt.core.settings.model.extension.CConfigurationData; import org.eclipse.cdt.core.settings.model.util.CDataUtil; import org.eclipse.cdt.core.settings.model.util.LanguageSettingEntriesSerializer; import org.eclipse.cdt.core.settings.model.util.PathSettingsContainer; import org.eclipse.cdt.internal.core.SafeStringInterner; import org.eclipse.cdt.managedbuilder.buildproperties.IBuildProperty; import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyType; import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyValue; import org.eclipse.cdt.managedbuilder.core.BuildException; import org.eclipse.cdt.managedbuilder.core.IBuildObject; import org.eclipse.cdt.managedbuilder.core.IBuildObjectProperties; import org.eclipse.cdt.managedbuilder.core.IBuildPropertiesRestriction; import org.eclipse.cdt.managedbuilder.core.IBuilder; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IFileInfo; import org.eclipse.cdt.managedbuilder.core.IFolderInfo; import org.eclipse.cdt.managedbuilder.core.IHoldsOptions; import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo; 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.IOptionApplicability; import org.eclipse.cdt.managedbuilder.core.IProjectType; import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; import org.eclipse.cdt.managedbuilder.core.IResourceInfo; 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.core.ManagedBuilderCorePlugin; import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier; import org.eclipse.cdt.managedbuilder.internal.dataprovider.BuildConfigurationData; import org.eclipse.cdt.managedbuilder.internal.enablement.OptionEnablementExpression; import org.eclipse.cdt.managedbuilder.internal.macros.BuildMacroProvider; import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; import org.eclipse.cdt.managedbuilder.internal.macros.OptionContextData; import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; import org.eclipse.cdt.managedbuilder.macros.IConfigurationBuildMacroSupplier; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.osgi.util.NLS; import org.osgi.framework.Version; public class Configuration extends BuildObject implements IConfiguration, IBuildPropertiesRestriction, IBuildPropertyChangeListener, IRealBuildObjectAssociation { private static final String EMPTY_STRING = ""; //$NON-NLS-1$ private static final String EMPTY_CFG_ID = "org.eclipse.cdt.build.core.emptycfg"; //$NON-NLS-1$ private static final String LANGUAGE_SETTINGS_PROVIDER_DELIMITER = ";"; //$NON-NLS-1$ private static final String LANGUAGE_SETTINGS_PROVIDER_NEGATION_SIGN = "-"; //$NON-NLS-1$ private static final String $TOOLCHAIN = "${Toolchain}"; //$NON-NLS-1$ // Parent and children private String parentId; private IConfiguration parent; private ProjectType projectType; private ManagedProject managedProject; private String artifactName; private String cleanCommand; private String artifactExtension; private String errorParserIds; private String defaultLanguageSettingsProvidersAttribute; private String[] defaultLanguageSettingsProviderIds; private String prebuildStep; private String postbuildStep; private String preannouncebuildStep; private String postannouncebuildStep; private String description; private ICSourceEntry[] sourceEntries; private BuildObjectProperties buildProperties; private boolean isTest; private SupportedProperties supportedProperties; // Miscellaneous private boolean isExtensionConfig = false; private boolean isDirty = false; private boolean rebuildNeeded = false; private boolean resolved = true; private boolean isTemporary = false; private PathSettingsContainer pathSettings = PathSettingsContainer.createRootContainer(); private ResourceInfoContainer rcInfos = new ResourceInfoContainer(pathSettings, true); private BooleanExpressionApplicabilityCalculator booleanExpressionCalculator; private FolderInfo rootFolderInfo; private BuildConfigurationData fCfgData; private ICConfigurationDescription fCfgDes; // private IScannerConfigBuilderInfo2 scannerCfgBuilderInfo; // private IDiscoveredPathManager.IDiscoveredPathInfo discoveredInfo; // private Boolean isPerResourceDiscovery; private ICfgScannerConfigBuilderInfo2Set cfgScannerInfo; private boolean isPreferenceConfig; private List<IPath> excludeList; //property name for holding the rebuild state private static final String REBUILD_STATE = "rebuildState"; //$NON-NLS-1$ //The resource delta passed to the builder is not always up-to-date //for the given configuration because between two builds of the same configuration //any number of other configuration builds may occur //that is why we need to keep some information regarding what happened //with the resource tree between the two configuration builds // //The trivial approach implemented currently is to hold //the general information of whether some resources were //removed,changed,etc. and detect whether the rebuild is needed //based upon this information // //In the future we might implement some more smart mechanism //for tracking delta, e.g calculate the pre-cinfiguration resource delta, etc. // //property for holding the resource change state private static final String RC_CHANGE_STATE = "rcState"; //$NON-NLS-1$ //resource change state private int resourceChangeState = -1; //Internal Builder state //NOTE: these are temporary properties //In the future we are going present the Internal Builder //as a special Builder object of the tool-chain and implement the internal //builder enabling/disabling as the Builder substitution functionality // // private static final String INTERNAL_BUILDER = "internalBuilder"; //$NON-NLS-1$ //preference key that holds the Internal Builder enable state // private static final String INTERNAL_BUILDER_ENABLED = "enabled"; //$NON-NLS-1$ //preference key that holds the internal builder mode // private static final String INTERNAL_BUILDER_IGNORE_ERR = "ignoreErr"; //$NON-NLS-1$ //preference key that holds the internal builder mode // private static final String INTERNAL_BUILDER_PARALLEL = "parallel"; //$NON-NLS-1$ //preference key that holds the internal builder mode // private static final String INTERNAL_BUILDER_PARALLEL_DEF = "paralleldef"; //$NON-NLS-1$ //preference key that holds the internal builder mode // private static final String INTERNAL_BUILDER_PARALLELNUMBER = "parallelnumber"; //$NON-NLS-1$ //Internal Builder enable state // private boolean internalBuilderEnabled; //Internal Builder mode // private boolean internalBuilderIgnoreErr = true; //Internal Builder parallel mode // private boolean internalBuilderParallel = true; //Internal Builder parallel mode - default jobs # // private boolean internalBuilderParallelDef = true; //Number of parallel threads // private int internalBuilderParallelNumber = 1; // default value /* * 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 <code>ProjectType</code> the configuration will be added to. * @param element The element from the manifest that contains the configuration information. */ 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); } IManagedConfigElement enablements[] = element.getChildren(OptionEnablementExpression.NAME); if(enablements.length > 0) booleanExpressionCalculator = new BooleanExpressionApplicabilityCalculator(enablements); // Load the children IManagedConfigElement[] configElements = element.getChildren(); List<IPath> srcPathList = new ArrayList<IPath>(); excludeList = new ArrayList<IPath>(); for (int l = 0; l < configElements.length; ++l) { IManagedConfigElement configElement = configElements[l]; if (configElement.getName().equals(IToolChain.TOOL_CHAIN_ELEMENT_NAME)) { rootFolderInfo = new FolderInfo(this, configElement, managedBuildRevision, false); addResourceConfiguration(rootFolderInfo); } else if (IFolderInfo.FOLDER_INFO_ELEMENT_NAME.equals(configElement.getName())) { FolderInfo resConfig = new FolderInfo(this, configElement, managedBuildRevision, true); addResourceConfiguration(resConfig); } else if (IFileInfo.FILE_INFO_ELEMENT_NAME.equals(configElement.getName()) || IResourceConfiguration.RESOURCE_CONFIGURATION_ELEMENT_NAME.equals(configElement.getName())) { ResourceConfiguration resConfig = new ResourceConfiguration(this, configElement, managedBuildRevision); addResourceConfiguration(resConfig); } else if (SourcePath.ELEMENT_NAME.equals(configElement.getName())){ SourcePath p = new SourcePath(configElement); if(p.getPath() != null) srcPathList.add(p.getPath()); } else if (configElement.getName().equals(SupportedProperties.SUPPORTED_PROPERTIES)){ loadProperties(configElement); } else if (SOURCE_ENTRIES.equals(configElement.getName())){ List<ICSettingEntry> seList = LanguageSettingEntriesSerializer.loadEntriesList(new ManagedConfigStorageElement(configElement), ICSettingEntry.SOURCE_PATH); sourceEntries = seList.toArray(new ICSourceEntry[seList.size()]); } } sourceEntries = createSourceEntries(sourceEntries, srcPathList, excludeList); excludeList = null; if(rootFolderInfo == null) createRootFolderInfo(); String props = SafeStringInterner.safeIntern(element.getAttribute(BUILD_PROPERTIES)); if(props != null) buildProperties = new BuildObjectProperties(props, this, this); String artType = SafeStringInterner.safeIntern(element.getAttribute(BUILD_ARTEFACT_TYPE)); if(artType != null){ if(buildProperties == null) buildProperties = new BuildObjectProperties(this, this); try { buildProperties.setProperty(ManagedBuildManager.BUILD_ARTEFACT_TYPE_PROPERTY_ID, artType, true); } catch (CoreException e) { ManagedBuilderCorePlugin.log(e); } } if(projectType != null && projectType.buildProperties != null){ if(buildProperties == null){ buildProperties = new BuildObjectProperties(projectType.buildProperties, this, this); } else { IBuildProperty properties[] = projectType.buildProperties.getProperties(); for(int i = 0; i < properties.length; i++){ try { buildProperties.internalSetProperty(properties[i].getPropertyType().getId(), properties[i].getValue().getId()); } catch (CoreException e) { } } } } setDirty(false); } private static ICSourceEntry[] createSourceEntries(ICSourceEntry[] curEntries, List<IPath> pathList, List<IPath> excludeList){ for(int i = 0; i < excludeList.size(); i++){ IPath path = excludeList.get(i); if(path.segmentCount() == 0) excludeList.remove(i); } if(pathList.size() == 0) pathList.add(Path.EMPTY); if(pathList.size() == 1 && pathList.get(0).equals(Path.EMPTY) && excludeList.size() == 0) return curEntries; int pathSize = pathList.size(); Map<IPath, ICSourceEntry> map = new LinkedHashMap<IPath, ICSourceEntry>(); for(int i = 0; i < pathSize; i++){ IPath path = pathList.get(i); ICSourceEntry entry = map.get(path); if(entry == null) entry = new CSourceEntry(path, null, ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED); entry = CDataUtil.addExcludePaths(entry, excludeList, true); if(entry != null) map.put(path, entry); } return map.values().toArray(new ICSourceEntry[map.size()]); } /** * Create a new extension configuration based on one already defined. * * @param projectType The <code>ProjectType</code> the configuration will be added to. * @param parentConfig The <code>IConfiguration</code> 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 constructor 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 inheritance 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 <code>ProjectType</code> the configuration will be added to. * @param parentConfig The <code>IConfiguration</code> 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 <code>Configuration</code> based on the specification stored in the * project file (.cdtbuild). * * @param managedProject The <code>ManagedProject</code> the configuration will be added to. * @param element The XML element that contains the configuration settings. * */ public Configuration(ManagedProject managedProject, ICStorageElement element, String managedBuildRevision, boolean isPreference) { this.managedProject = managedProject; this.isPreferenceConfig = isPreference; isExtensionConfig = false; fCfgData = new BuildConfigurationData(this); setManagedBuildRevision(managedBuildRevision); // Initialize from the XML attributes loadFromProject(element); // Hook me up if(managedProject != null) managedProject.addConfiguration(this); ICStorageElement configElements[] = element.getChildren(); List<IPath> srcPathList = new ArrayList<IPath>(); excludeList = new ArrayList<IPath>(); for (int i = 0; i < configElements.length; ++i) { ICStorageElement configElement = configElements[i]; if (configElement.getName().equals(IToolChain.TOOL_CHAIN_ELEMENT_NAME)) { rootFolderInfo = new FolderInfo(this, configElement, managedBuildRevision, false); addResourceConfiguration(rootFolderInfo); } else if (IFolderInfo.FOLDER_INFO_ELEMENT_NAME.equals(configElement.getName())) { FolderInfo resConfig = new FolderInfo(this, configElement, managedBuildRevision, true); addResourceConfiguration(resConfig); } else if (IFileInfo.FILE_INFO_ELEMENT_NAME.equals(configElement.getName()) || IResourceConfiguration.RESOURCE_CONFIGURATION_ELEMENT_NAME.equals(configElement.getName())) { ResourceConfiguration resConfig = new ResourceConfiguration(this, configElement, managedBuildRevision); addResourceConfiguration(resConfig); } else if (SourcePath.ELEMENT_NAME.equals(configElement.getName())){ SourcePath p = new SourcePath(configElement); if(p.getPath() != null) srcPathList.add(p.getPath()); } else if (SOURCE_ENTRIES.equals(configElement.getName())){ List<ICSettingEntry> seList = LanguageSettingEntriesSerializer.loadEntriesList(configElement, ICSettingEntry.SOURCE_PATH); sourceEntries = seList.toArray(new ICSourceEntry[seList.size()]); } } resolveProjectReferences(true); sourceEntries = createSourceEntries(sourceEntries, srcPathList, excludeList); excludeList = null; PropertyManager mngr = PropertyManager.getInstance(); String rebuild = mngr.getProperty(this, REBUILD_STATE); if(rebuild == null || Boolean.valueOf(rebuild).booleanValue()) rebuildNeeded = true; String rcChangeState = mngr.getProperty(this, RC_CHANGE_STATE); if(rcChangeState == null) resourceChangeState = ~0; else { try { resourceChangeState = Integer.parseInt(rcChangeState); } catch (NumberFormatException e){ resourceChangeState = ~0; } } setDirty(false); // Preferences prefs = getPreferences(INTERNAL_BUILDER); // // internalBuilderEnabled = prefs != null ? // prefs.getBoolean(INTERNAL_BUILDER_ENABLED, false) : false; // internalBuilderIgnoreErr = prefs != null ? // prefs.getBoolean(INTERNAL_BUILDER_IGNORE_ERR, true) : true; } public Configuration(ManagedProject managedProject, ToolChain tCh, String id, String name) { setId(id); setName(name); // this.description = cloneConfig.getDescription(); this.managedProject = managedProject; isExtensionConfig = false; if(tCh == null){ //create configuration based upon the preference config IConfiguration cfg = ManagedBuildManager.getPreferenceConfiguration(false); if(cfg != null) copySettingsFrom((Configuration)cfg, true); } else { Configuration baseCfg = (Configuration)ManagedBuildManager.getExtensionConfiguration(EMPTY_CFG_ID); // this.isTemporary = temporary; fCfgData = new BuildConfigurationData(this); if(baseCfg.buildProperties != null) this.buildProperties = new BuildObjectProperties(baseCfg.buildProperties, this, this); // set managedBuildRevision setManagedBuildRevision(baseCfg.getManagedBuildRevision()); // if(!baseCfg.isExtensionConfig) // cloneChildren = true; // If this constructor is called to clone an existing // configuration, the parent of the cloning config should be stored. parent = baseCfg.isExtensionConfig || baseCfg.getParent() == null ? baseCfg : baseCfg.getParent(); // Copy the remaining attributes projectType = baseCfg.projectType; artifactName = baseCfg.artifactName; cleanCommand = baseCfg.cleanCommand; artifactExtension = baseCfg.artifactExtension; errorParserIds = baseCfg.errorParserIds; prebuildStep = baseCfg.prebuildStep; postbuildStep = baseCfg.postbuildStep; preannouncebuildStep = baseCfg.preannouncebuildStep; postannouncebuildStep = baseCfg.postannouncebuildStep; if(baseCfg.sourceEntries != null) sourceEntries = baseCfg.sourceEntries.clone(); defaultLanguageSettingsProvidersAttribute = baseCfg.defaultLanguageSettingsProvidersAttribute; if(baseCfg.defaultLanguageSettingsProviderIds != null) { defaultLanguageSettingsProviderIds = baseCfg.defaultLanguageSettingsProviderIds.clone(); } // enableInternalBuilder(baseCfg.isInternalBuilderEnabled()); // setInternalBuilderIgnoreErr(baseCfg.getInternalBuilderIgnoreErr()); // setInternalBuilderParallel(baseCfg.getInternalBuilderParallel()); // setParallelDef(baseCfg.getParallelDef()); // setParallelNumber(baseCfg.getParallelNumber()); // internalBuilderEnabled = cloneConfig.internalBuilderEnabled; // internalBuilderIgnoreErr = cloneConfig.internalBuilderIgnoreErr; // Clone the configuration's children // Tool Chain String tcId = ManagedBuildManager.calculateChildId(tCh.getId(), null); IToolChain newChain = createToolChain(tCh, tcId, tCh.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(tCh); // 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. String subId; ITool[] tools = tCh.getTools(); for (int i=0; i<tools.length; i++) { Tool toolChild = (Tool)tools[i]; subId = ManagedBuildManager.calculateChildId(toolChild.getId(),null); newChain.createTool(toolChild, subId, toolChild.getName(), false); } ITargetPlatform tpBase = tCh.getTargetPlatform(); ITargetPlatform extTp = tpBase; for(;extTp != null && !extTp.isExtensionElement();extTp = extTp.getSuperClass()) {} TargetPlatform tp; if(extTp != null){ int nnn = ManagedBuildManager.getRandomNumber(); subId = extTp.getId() + "." + nnn; //$NON-NLS-1$ // subName = tpBase.getName(); tp = new TargetPlatform(newChain, subId, tpBase.getName(), (TargetPlatform)tpBase); } else { subId = ManagedBuildManager.calculateChildId(getId(), null); String subName = EMPTY_STRING; tp = new TargetPlatform((ToolChain)newChain, null, subId, subName, false); } ((ToolChain)newChain).setTargetPlatform(tp); // if(cloneChildren){ //copy expand build macros setting // BuildMacroProvider macroProvider = (BuildMacroProvider)ManagedBuildManager.getBuildMacroProvider(); // macroProvider.expandMacrosInBuildfile(this, // macroProvider.areMacrosExpandedInBuildfile(baseCfg)); //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); // } // Hook me up managedProject.addConfiguration(this); IBuilder builder = getEditableBuilder(); try { builder.setManagedBuildOn(false); } catch (CoreException e) { } propertiesChanged(); } setDirty(true); setRebuildState(true); } public Configuration(ManagedProject managedProject, Configuration cloneConfig, String id, boolean cloneChildren, boolean temporary) { this(managedProject, cloneConfig, id, cloneChildren, temporary, false); } /** * Create a new project, non-extension, configuration based on one already defined. * * @param managedProject The <code>ManagedProject</code> the configuration will be added to. * @param cloneConfig The <code>IConfiguration</code> to copy the settings from. * @param id A unique ID for the new configuration. * @param cloneChildren If <code>true</code>, the configuration's tools are cloned */ public Configuration(ManagedProject managedProject, Configuration cloneConfig, String id, boolean cloneChildren, boolean temporary, boolean isPreferenceConfig) { setId(id); setName(cloneConfig.getName()); this.isPreferenceConfig = isPreferenceConfig; this.managedProject = managedProject; isExtensionConfig = false; this.isTemporary = temporary; copySettingsFrom(cloneConfig, cloneChildren); } private void copySettingsFrom(Configuration cloneConfig, boolean cloneChildren){ fCfgData = new BuildConfigurationData(this); if(cloneConfig.buildProperties != null) { this.buildProperties = new BuildObjectProperties(cloneConfig.buildProperties, this, this); } this.description = cloneConfig.getDescription(); // set managedBuildRevision setManagedBuildRevision(cloneConfig.getManagedBuildRevision()); if(!cloneConfig.isExtensionConfig) cloneChildren = true; // If this constructor is called to clone an existing // configuration, the parent of the cloning config should be stored. parent = cloneConfig.isExtensionConfig || cloneConfig.getParent() == null ? cloneConfig : cloneConfig.getParent(); parentId = parent.getId(); // Copy the remaining attributes projectType = cloneConfig.projectType; artifactName = cloneConfig.artifactName; cleanCommand = cloneConfig.cleanCommand; artifactExtension = cloneConfig.artifactExtension; errorParserIds = cloneConfig.errorParserIds; prebuildStep = cloneConfig.prebuildStep; postbuildStep = cloneConfig.postbuildStep; preannouncebuildStep = cloneConfig.preannouncebuildStep; postannouncebuildStep = cloneConfig.postannouncebuildStep; if(cloneConfig.sourceEntries != null) { sourceEntries = cloneConfig.sourceEntries.clone(); } defaultLanguageSettingsProvidersAttribute = cloneConfig.defaultLanguageSettingsProvidersAttribute; if(cloneConfig.defaultLanguageSettingsProviderIds != null) { defaultLanguageSettingsProviderIds = cloneConfig.defaultLanguageSettingsProviderIds.clone(); } // enableInternalBuilder(cloneConfig.isInternalBuilderEnabled()); // setInternalBuilderIgnoreErr(cloneConfig.getInternalBuilderIgnoreErr()); // setInternalBuilderParallel(cloneConfig.getInternalBuilderParallel()); // setParallelDef(cloneConfig.getParallelDef()); // setParallelNumber(cloneConfig.getParallelNumber()); // internalBuilderEnabled = cloneConfig.internalBuilderEnabled; // internalBuilderIgnoreErr = cloneConfig.internalBuilderIgnoreErr; // Clone the configuration's children // Tool Chain boolean copyIds = cloneConfig.getId().equals(id); String subId; // Resource Configurations Map<IPath, Map<String, String>> toolIdMap = new HashMap<IPath, Map<String, String>>(); IResourceInfo infos[] = cloneConfig.rcInfos.getResourceInfos(); for(int i = 0; i < infos.length; i++){ if(infos[i] instanceof FolderInfo){ FolderInfo folderInfo = (FolderInfo)infos[i]; subId = copyIds ? folderInfo.getId() : ManagedBuildManager.calculateChildId(getId(), folderInfo.getPath().toString()); FolderInfo newFolderInfo = new FolderInfo(this, folderInfo, subId, toolIdMap, cloneChildren); addResourceConfiguration(newFolderInfo); } else { ResourceConfiguration fileInfo = (ResourceConfiguration)infos[i]; subId = copyIds ? fileInfo.getId() : ManagedBuildManager.calculateChildId(getId(), fileInfo.getPath().toString()); ResourceConfiguration newResConfig = new ResourceConfiguration(this, fileInfo, subId, toolIdMap, cloneChildren); addResourceConfiguration(newResConfig); } } resolveProjectReferences(false); if(cloneChildren){ //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); } // Hook me up if(managedProject != null){ managedProject.addConfiguration(this); } if(cloneConfig.isExtensionConfig){ propertiesChanged(); } if(copyIds){ rebuildNeeded = cloneConfig.rebuildNeeded; resourceChangeState = cloneConfig.resourceChangeState; isDirty = cloneConfig.isDirty; } else { if(cloneConfig.isExtensionConfig) exportArtifactInfo(); setDirty(true); setRebuildState(true); } } public void applyToManagedProject(ManagedProject mProj){ managedProject = mProj; isPreferenceConfig = false; isTemporary = false; managedProject.addConfiguration(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 */ /** * Initialize the configuration information from an element in the * manifest file or provided by a dynamicElementProvider * * @param element An obejct implementing IManagedConfigElement */ protected void loadFromManifest(IManagedConfigElement element) { ManagedBuildManager.putConfigElement(this, element); // id setId(SafeStringInterner.safeIntern(element.getAttribute(IBuildObject.ID))); // name name = SafeStringInterner.safeIntern(element.getAttribute(IBuildObject.NAME)); // description description = SafeStringInterner.safeIntern(element.getAttribute(IConfiguration.DESCRIPTION)); // parent parentId = SafeStringInterner.safeIntern(element.getAttribute(IConfiguration.PARENT)); // if (parentID != null) { // // Lookup the parent configuration by ID // parent = ManagedBuildManager.getExtensionConfiguration(parentID); // } // Get the name of the build artifact associated with configuration artifactName = SafeStringInterner.safeIntern(element.getAttribute(ARTIFACT_NAME)); // Get the semicolon separated list of IDs of the error parsers errorParserIds = SafeStringInterner.safeIntern(element.getAttribute(ERROR_PARSERS)); // Get the initial/default language settings providers IDs defaultLanguageSettingsProvidersAttribute = SafeStringInterner.safeIntern(element.getAttribute(LANGUAGE_SETTINGS_PROVIDERS)); // Get the artifact extension artifactExtension = SafeStringInterner.safeIntern(element.getAttribute(EXTENSION)); // Get the clean command cleanCommand = SafeStringInterner.safeIntern(element.getAttribute(CLEAN_COMMAND)); // Get the pre-build and post-build commands prebuildStep = SafeStringInterner.safeIntern(element.getAttribute(PREBUILD_STEP)); postbuildStep = SafeStringInterner.safeIntern(element.getAttribute(POSTBUILD_STEP)); // Get the pre-build and post-build announcements preannouncebuildStep = SafeStringInterner.safeIntern(element.getAttribute(PREANNOUNCEBUILD_STEP)); postannouncebuildStep = SafeStringInterner.safeIntern(element.getAttribute(POSTANNOUNCEBUILD_STEP)); String tmp = element.getAttribute(IS_SYSTEM); if(tmp != null) isTest = Boolean.valueOf(tmp).booleanValue(); } /** * Initialize the configuration information from the XML element * specified in the argument * * @param element An XML element containing the configuration information */ protected void loadFromProject(ICStorageElement element) { // id // note: IDs are unique so no benefit to intern them setId(element.getAttribute(IBuildObject.ID)); // name if (element.getAttribute(IBuildObject.NAME) != null) setName(SafeStringInterner.safeIntern(element.getAttribute(IBuildObject.NAME))); // description if (element.getAttribute(IConfiguration.DESCRIPTION) != null) description = SafeStringInterner.safeIntern(element.getAttribute(IConfiguration.DESCRIPTION)); String props = element.getAttribute(BUILD_PROPERTIES); if(props != null) buildProperties = new BuildObjectProperties(props, this, this); String artType = SafeStringInterner.safeIntern(element.getAttribute(BUILD_ARTEFACT_TYPE)); if(artType != null){ if(buildProperties == null) buildProperties = new BuildObjectProperties(this, this); try { buildProperties.setProperty(ManagedBuildManager.BUILD_ARTEFACT_TYPE_PROPERTY_ID, artType, true); } catch (CoreException e) { ManagedBuilderCorePlugin.log(e); } } if (element.getAttribute(IConfiguration.PARENT) != null) { // See if the parent belongs to the same project if(managedProject != null) parent = managedProject.getConfiguration(element.getAttribute(IConfiguration.PARENT)); // If not, then try the extension configurations if (parent == null) { parent = ManagedBuildManager.getExtensionConfiguration(element.getAttribute(IConfiguration.PARENT)); if (parent==null) { String message = NLS.bind(ManagedMakeMessages.getResourceString("Configuration.orphaned"), getId(), element.getAttribute(IConfiguration.PARENT)); //$NON-NLS-1$ ManagedBuilderCorePlugin.error(message); } } } // Get the name of the build artifact associated with target (usually // in the plugin specification). if (element.getAttribute(ARTIFACT_NAME) != null) { artifactName = SafeStringInterner.safeIntern(element.getAttribute(ARTIFACT_NAME)); } // Get the semicolon separated list of IDs of the error parsers if (element.getAttribute(ERROR_PARSERS) != null) { errorParserIds = SafeStringInterner.safeIntern(element.getAttribute(ERROR_PARSERS)); } // Get the artifact extension if (element.getAttribute(EXTENSION) != null) { artifactExtension = SafeStringInterner.safeIntern(element.getAttribute(EXTENSION)); } // Get the clean command if (element.getAttribute(CLEAN_COMMAND) != null) { cleanCommand = SafeStringInterner.safeIntern(element.getAttribute(CLEAN_COMMAND)); } // Get the pre-build and post-build commands if (element.getAttribute(PREBUILD_STEP) != null) { prebuildStep = SafeStringInterner.safeIntern(element.getAttribute(PREBUILD_STEP)); } if (element.getAttribute(POSTBUILD_STEP) != null) { postbuildStep = SafeStringInterner.safeIntern(element.getAttribute(POSTBUILD_STEP)); } // Get the pre-build and post-build announcements if (element.getAttribute(PREANNOUNCEBUILD_STEP) != null) { preannouncebuildStep = SafeStringInterner.safeIntern(element.getAttribute(PREANNOUNCEBUILD_STEP)); } if (element.getAttribute(POSTANNOUNCEBUILD_STEP) != null) { postannouncebuildStep = SafeStringInterner.safeIntern(element.getAttribute(POSTANNOUNCEBUILD_STEP)); } } /** * Persist this configuration to project file. */ public void serialize(ICStorageElement element) { element.setAttribute(IBuildObject.ID, id); if (name != null) element.setAttribute(IBuildObject.NAME, name); if (description != null) element.setAttribute(IConfiguration.DESCRIPTION, description); if(buildProperties != null){ element.setAttribute(BUILD_PROPERTIES, buildProperties.toString()); IBuildProperty prop = buildProperties.getProperty(ManagedBuildManager.BUILD_ARTEFACT_TYPE_PROPERTY_ID); if(prop != null){ IBuildPropertyValue val = prop.getValue(); element.setAttribute(BUILD_ARTEFACT_TYPE, val.getId()); } } if (parent != null) element.setAttribute(IConfiguration.PARENT, parent.getId()); if (artifactName != null) element.setAttribute(ARTIFACT_NAME, artifactName); if (errorParserIds != null) element.setAttribute(ERROR_PARSERS, errorParserIds); if (artifactExtension != null) element.setAttribute(EXTENSION, artifactExtension); if (cleanCommand != null) element.setAttribute(CLEAN_COMMAND, cleanCommand); if (prebuildStep != null) element.setAttribute(PREBUILD_STEP, prebuildStep); if (postbuildStep != null) element.setAttribute(POSTBUILD_STEP, postbuildStep); if (preannouncebuildStep != null) element.setAttribute(PREANNOUNCEBUILD_STEP, preannouncebuildStep); if (postannouncebuildStep != null) element.setAttribute(POSTANNOUNCEBUILD_STEP, postannouncebuildStep); // Serialize my children IResourceInfo infos[] = rcInfos.getResourceInfos(); for(int i = 0; i < infos.length; i++){ String elementName = infos[i].getKind() == ICSettingBase.SETTING_FILE ? IFileInfo.FILE_INFO_ELEMENT_NAME : IFolderInfo.FOLDER_INFO_ELEMENT_NAME; ICStorageElement resElement = element.createChild(elementName); ((ResourceInfo)infos[i]).serialize(resElement); } PropertyManager.getInstance().serialize(this); if(sourceEntries != null && sourceEntries.length > 0){ ICStorageElement el = element.createChild(SOURCE_ENTRIES); LanguageSettingEntriesSerializer.serializeEntries(sourceEntries, el); } // I am clean now setDirty(false); } /* * P A R E N T A N D C H I L D H A N D L I N G */ @Override public IConfiguration getParent() { return parent; } @Override public IResource getOwner() { if (managedProject != null) return managedProject.getOwner(); else { return null; // Extension configurations don't have an "owner" } } @Override public IProjectType getProjectType() { return projectType; } @Override public IManagedProject getManagedProject() { return managedProject; } @Override public IToolChain createToolChain(IToolChain superClass, String Id, String name, boolean isExtensionElement) { if(rootFolderInfo == null){ createRootFolderInfo(); } return rootFolderInfo.createToolChain(superClass, Id, name, isExtensionElement); } private IFolderInfo createRootFolderInfo(){ String id = ManagedBuildManager.calculateChildId(this.id, null); String name = "/"; //$NON-NLS-1$ rootFolderInfo = new FolderInfo(this, new Path(name), id, name, isExtensionConfig); addResourceConfiguration(rootFolderInfo); return rootFolderInfo; } /* public IFolderInfo createFolderInfo(IPath path, IToolChain superClass, String Id, String name){ } public IFolderInfo createFolderInfo(IPath path, IFolderInfo baseFolderInfo, String Id, String name){ } */ @Override public IToolChain getToolChain() { return rootFolderInfo.getToolChain(); } @Override public IResourceConfiguration[] getResourceConfigurations() { return (IResourceConfiguration[])rcInfos.getResourceInfos(ICSettingBase.SETTING_FILE, IResourceConfiguration.class); } @Override public IResourceConfiguration getResourceConfiguration(String resPath) { return rcInfos.getFileInfo(new Path(resPath).removeFirstSegments(1)); } @Override public ITool[] getFilteredTools() { return rootFolderInfo.getFilteredTools(); } @Override public ITool[] getTools() { return rootFolderInfo.getTools(); } @Override public ITool getTool(String id) { return rootFolderInfo.getTool(id); } @Override public ITool[] getToolsBySuperClassId(String id) { return rootFolderInfo.getToolsBySuperClassId(id); } @Override public ITool getTargetTool() { String[] targetToolIds = rootFolderInfo.getToolChain().getTargetToolList(); if (targetToolIds == null || targetToolIds.length == 0) return null; // For each target tool id, in list order, // look for a tool with this ID, or a tool with a superclass with this id. // Stop when we find a match ITool[] tools = getFilteredTools(); for (int i=0; i<targetToolIds.length; i++) { String targetToolId = targetToolIds[i]; for (int j=0; j<tools.length; j++) { ITool targetTool = tools[j]; ITool tool = targetTool; do { if (targetToolId.equals(tool.getId())) { return targetTool; } tool = tool.getSuperClass(); } while (tool != null); } } return null; } @Override public String getToolCommand(ITool tool) { // TODO: Do we need to verify that the tool is part of the configuration? return tool.getToolCommand(); } @Override public void setToolCommand(ITool tool, String command) { // TODO: Do we need to verify that the tool is part of the configuration? tool.setToolCommand(command); } @Override public IOption setOption(IHoldsOptions holder, IOption option, boolean value) throws BuildException { return getRootFolderInfo().setOption(holder, option, value); } @Override public IOption setOption(IHoldsOptions holder, IOption option, String value) throws BuildException { return getRootFolderInfo().setOption(holder, option, value); } @Override public IOption setOption(IHoldsOptions holder, IOption option, String[] value) throws BuildException { return getRootFolderInfo().setOption(holder, option, value); } /** * Adds the Resource Configuration to the Resource Configuration list and map */ void addResourceConfiguration(IResourceInfo resConfig) { if(resConfig.getPath().segmentCount() == 0) rootFolderInfo = (FolderInfo)resConfig; rcInfos.addResourceInfo(resConfig); isDirty = true; // rebuildNeeded = true; } @Override public void removeResourceConfiguration(IResourceInfo resConfig) { ManagedBuildManager.performValueHandlerEvent(resConfig, IManagedOptionValueHandler.EVENT_CLOSE); ITool tools[] = resConfig.getTools(); rcInfos.removeResourceInfo(resConfig.getPath()); ((ResourceInfo)resConfig).removed(); BuildSettingsUtil.disconnectDepentents(this, tools); isDirty = true; rebuildNeeded = true; } /* * M O D E L A T T R I B U T E A C C E S S O R S */ @Override public String getName() { return (name == null && parent != null) ? parent.getName() : name; } @Override public String getArtifactExtension() { String ext = getArtifactExtensionAttribute(true); return ext != null ? ext : EMPTY_STRING; } public String getArtifactExtensionAttribute(boolean querySuperClass) { if (artifactExtension == null) { // Ask my parent first if (parent != null) { return parent.getArtifactExtension(); } return null; } return artifactExtension; } @Override public String getArtifactName() { if (artifactName == null) { // If I have a parent, ask it if (parent != null) { return parent.getArtifactName(); } else { // I'm it and this is not good! return EMPTY_STRING; } } else { return artifactName; } } @Override public String getBuildArguments() { IToolChain tc = getToolChain(); IBuilder builder = tc.getBuilder(); if (builder != null) { return builder.getArguments(); } return "-k"; //$NON-NLS-1$ } @Override public String getBuildCommand() { IToolChain tc = getToolChain(); IBuilder builder = tc.getBuilder(); if (builder != null) { return builder.getCommand(); } return "make"; //$NON-NLS-1$ } @Override public String getPrebuildStep() { if (prebuildStep == null) { // If I have a parent, ask it if (parent != null) { return parent.getPrebuildStep(); } else { // I'm it return EMPTY_STRING; } } else { return prebuildStep; } } @Override public String getPostbuildStep() { if (postbuildStep == null) { // If I have a parent, ask it if (parent != null) { return parent.getPostbuildStep(); } else { // I'm it return EMPTY_STRING; } } else { return postbuildStep; } } @Override public String getPreannouncebuildStep() { if (preannouncebuildStep == null) { // If I have a parent, ask it if (parent != null) { return parent.getPreannouncebuildStep(); } else { // I'm it return EMPTY_STRING; } } else { return preannouncebuildStep; } } @Override public String getPostannouncebuildStep() { if (postannouncebuildStep == null) { // If I have a parent, ask it if (parent != null) { return parent.getPostannouncebuildStep(); } else { // I'm it return EMPTY_STRING; } } else { return postannouncebuildStep; } } @Override public String getCleanCommand() { // Return the command used to remove files if (cleanCommand == null) { if (parent != null) { return parent.getCleanCommand(); } else { // User forgot to specify it. Guess based on OS. if (Platform.getOS().equals(Platform.OS_WIN32)) { return "del"; //$NON-NLS-1$ } else { return "rm"; //$NON-NLS-1$ } } } else { // This was spec'd in the manifest return cleanCommand; } } @Override public String getDescription() { if (description == null) { // If I have a parent, ask it if (parent != null) { return parent.getDescription(); } else { // I'm it return EMPTY_STRING; } } else { return description; } } @Override public String getErrorParserIds() { if (errorParserIds != null) { return errorParserIds; } // If I have a parent, ask it String errorParsers = null; if (parent != null) { errorParsers = parent.getErrorParserIds(); } // If no error parsers are specified by the configuration, the default // is // the error parsers from the tool-chain //TODO if (errorParsers == null && rootFolderInfo != null) { errorParsers = rootFolderInfo.getErrorParserIds(); } return errorParsers; } public String getErrorParserIdsAttribute() { if (errorParserIds != null) { return errorParserIds; } // If I have a parent, ask it String errorParsers = null; if (parent != null) { errorParsers = ((Configuration)parent).getErrorParserIdsAttribute(); } return errorParsers; } @Override public String[] getErrorParserList() { Set<String> set = contributeErrorParsers(null, true); if(set != null){ String result[] = new String[set.size()]; set.toArray(result); return result; } return ErrorParserManager.getErrorParserAvailableIdsInContext(ErrorParserManager.BUILD_CONTEXT); } public Set<String> contributeErrorParsers(Set<String> set, boolean includeChildren) { String parserIDs = getErrorParserIdsAttribute(); if (parserIDs != null){ if(set == null) set = new LinkedHashSet<String>(); if(parserIDs.length() != 0) { StringTokenizer tok = new StringTokenizer(parserIDs, ";"); //$NON-NLS-1$ while (tok.hasMoreElements()) { set.add(tok.nextToken()); } } } if(includeChildren){ IResourceInfo[] rcInfos = getResourceInfos(); for(int i = 0; i < rcInfos.length; i++){ ResourceInfo rcInfo = (ResourceInfo)rcInfos[i]; set = rcInfo.contributeErrorParsers(set); } } return set; } /** * Get value of attribute {@link IConfiguration#LANGUAGE_SETTINGS_PROVIDERS} * It not defined, it will try to pull the attribute from the parent configuration. */ private String getDefaultLanguageSettingsProvidersAttribute() { if (defaultLanguageSettingsProvidersAttribute == null && parent instanceof Configuration) { defaultLanguageSettingsProvidersAttribute = ((Configuration) parent).getDefaultLanguageSettingsProvidersAttribute(); } return defaultLanguageSettingsProvidersAttribute; } /** * {@inheritDoc} * * This function will try to find default provider Ids specified in this instance. * It none defined, it will try to pull Ids from the parent configuration. */ @Override public String[] getDefaultLanguageSettingsProviderIds() { if (defaultLanguageSettingsProviderIds == null) { defaultLanguageSettingsProvidersAttribute = getDefaultLanguageSettingsProvidersAttribute(); if (defaultLanguageSettingsProvidersAttribute != null) { List<String> ids = new ArrayList<String>(); String[] defaultIds = defaultLanguageSettingsProvidersAttribute.split(LANGUAGE_SETTINGS_PROVIDER_DELIMITER); for (String id : defaultIds) { if (id != null && !id.isEmpty()) { if (id.startsWith(LANGUAGE_SETTINGS_PROVIDER_NEGATION_SIGN)) { id = id.substring(1); ids.remove(id); } else if (!ids.contains(id)) { if (id.contains($TOOLCHAIN)) { IToolChain toolchain = getToolChain(); if (toolchain != null) { String toolchainProvidersIds = toolchain.getDefaultLanguageSettingsProviderIds(); if (toolchainProvidersIds != null) { ids.addAll(Arrays.asList(toolchainProvidersIds.split(LANGUAGE_SETTINGS_PROVIDER_DELIMITER))); } } } else { ids.add(id); } } } } defaultLanguageSettingsProviderIds = ids.toArray(new String[ids.size()]); } else if (parent != null) { defaultLanguageSettingsProviderIds = parent.getDefaultLanguageSettingsProviderIds(); } } return defaultLanguageSettingsProviderIds; } @Override public void setArtifactExtension(String extension) { if (extension == null && artifactExtension == null) return; if (artifactExtension == null || extension == null || !artifactExtension.equals(extension)) { artifactExtension = extension; // rebuildNeeded = true; if(!isExtensionElement()){ ITool tool = calculateTargetTool(); if(tool != null){ tool.setRebuildState(true); } else { setRebuildState(true); } } isDirty = true; // exportArtifactInfo(); } } @Override public void setArtifactName(String name) { if (name == null && artifactName == null) return; if (artifactName == null || name == null || !artifactName.equals(name)) { if (canExportedArtifactInfo()) { // Remove existing exported library, if it exists ICConfigurationDescription des = ManagedBuildManager.getDescriptionForConfiguration(this); ICSettingEntry[] unresolved = new ICSettingEntry[] {CDataUtil.createCLibraryFileEntry(getArtifactName(), 0)}; ICSettingEntry[] libs = CDataUtil.resolveEntries(unresolved, des); if (libs.length > 0) { for (ICExternalSetting setting : des.getExternalSettings()) { Set<ICSettingEntry> entries = new LinkedHashSet<ICSettingEntry>(Arrays.asList(setting.getEntries())); for (ICSettingEntry lib : libs) { if (entries.contains(lib)) { entries.remove(lib); des.removeExternalSetting(setting); des.createExternalSetting(setting.getCompatibleLanguageIds(), setting.getCompatibleContentTypeIds(), setting.getCompatibleExtensions(), entries.toArray(new ICSettingEntry[entries.size()])); } } } } } artifactName = name; if(!isExtensionElement()){ ITool tool = calculateTargetTool(); if(tool != null) { tool.setRebuildState(true); } else { setRebuildState(true); } } // rebuildNeeded = true; isDirty = true; exportArtifactInfo(); } } @Override 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; } } @Override public void setCleanCommand(String command) { if (command == null && cleanCommand == null) return; if (cleanCommand == null || command == null || !cleanCommand.equals(command)) { cleanCommand = command; isDirty = true; } } @Override public void setDescription(String description) { if (description == null && this.description == null) return; if (this.description == null || description == null || !description.equals(this.description)) { this.description = description; isDirty = true; } } @Override public void setBuildArguments(String makeArgs) { IToolChain tc = getToolChain(); IBuilder builder = tc.getBuilder(); if(makeArgs == null){ //resetting the build arguments if(!builder.isExtensionElement()){ builder.setArguments(makeArgs); // rebuildNeeded = true; } }else if(!makeArgs.equals(builder.getArguments())){ if (builder.isExtensionElement()) { String subId = ManagedBuildManager.calculateChildId(builder.getId(), null); String builderName = builder.getName() + "." + getName(); //$NON-NLS-1$ builder = getToolChain().createBuilder(builder, subId, builderName, false); } builder.setArguments(makeArgs); // rebuildNeeded = true; } } @Override public void setBuildCommand(String command) { IToolChain tc = getToolChain(); IBuilder builder = tc.getBuilder(); if(command == null){ //resetting the build command if(!builder.isExtensionElement()){ builder.setCommand(command); // rebuildNeeded = true; } } else if(!command.equals(builder.getCommand())){ if (builder.isExtensionElement()) { String subId = ManagedBuildManager.calculateChildId(builder.getId(), null); String builderName = builder.getName() + "." + getName(); //$NON-NLS-1$ builder = getToolChain().createBuilder(builder, subId, builderName, false); } builder.setCommand(command); // rebuildNeeded = true; } } @Override public void setPrebuildStep(String step) { if (step == null && prebuildStep == null) return; if (prebuildStep == null || step == null || !prebuildStep.equals(step)) { prebuildStep = step; // rebuildNeeded = true; isDirty = true; } } @Override public void setPostbuildStep(String step) { if (step == null && postbuildStep == null) return; if (postbuildStep == null || step == null || !postbuildStep.equals(step)) { postbuildStep = step; // rebuildNeeded = true; isDirty = true; } } @Override public void setPreannouncebuildStep(String announceStep) { if (announceStep == null && preannouncebuildStep == null) return; if (preannouncebuildStep == null || announceStep == null || !preannouncebuildStep.equals(announceStep)) { preannouncebuildStep = announceStep; // rebuildNeeded = true; isDirty = true; } } @Override public void setPostannouncebuildStep(String announceStep) { if (announceStep == null && postannouncebuildStep == null) return; if (postannouncebuildStep == null || announceStep == null || !postannouncebuildStep.equals(announceStep)) { postannouncebuildStep = announceStep; // rebuildNeeded = true; isDirty = true; } } @Override public boolean isSupported(){ IFolderInfo foInfo = getRootFolderInfo(); if(foInfo != null) return foInfo.isSupported(); return false; } @Override public boolean isHeaderFile(String ext) { return getRootFolderInfo().isHeaderFile(ext); } /* * O B J E C T S T A T E M A I N T E N A N C E */ @Override public boolean isExtensionElement() { return isExtensionConfig; } @Override public boolean isDirty() { // This shouldn't be called for an extension configuration if (isExtensionConfig) return false; // If I need saving, just say yes if (isDirty) return true; // Otherwise see if any children need saving IResourceInfo infos[] = rcInfos.getResourceInfos(); for(int i = 0; i < infos.length; i++){ if(infos[i].isDirty()) return true; } return isDirty; } @Override public boolean needsRebuild() { return needsRebuild(true); } @Override public boolean needsFullRebuild() { return needsRebuild(false); } public boolean needsRebuild(boolean checkChildren) { boolean needRebuild = rebuildNeeded || resourceChangesRequireRebuild(); if(needRebuild || !checkChildren) return needRebuild; IResourceInfo infos[] = rcInfos.getResourceInfos(); for(int i = 0; i < infos.length; i++){ if(infos[i].needsRebuild()) return true; } return false; } @Override public void setDirty(boolean isDirty) { // Override the dirty flag this.isDirty = isDirty; // Propagate "false" to the children if (!isDirty) { IResourceInfo infos[] = rcInfos.getResourceInfos(); for(int i = 0; i < infos.length; i++){ infos[i].setDirty(false); } } } @Override public void setRebuildState(boolean rebuild) { if(isExtensionElement() && rebuild) return; if(rebuildNeeded != rebuild){ rebuildNeeded = rebuild; saveRebuildState(); } if(!rebuildNeeded){ setResourceChangeState(0); IResourceInfo infos[] = rcInfos.getResourceInfos(); for(int i = 0; i < infos.length; i++){ infos[i].setRebuildState(false); } } } @Override public boolean hasOverriddenBuildCommand() { IBuilder builder = getToolChain().getBuilder(); if (builder != null) { IBuilder superB = builder.getSuperClass(); if (superB != null) { String command = builder.getCommand(); if (command != null) { String superC = superB.getCommand(); if (superC != null) { if (!command.equals(superC)) { return true; } } } String args = builder.getArguments(); if (args != null) { String superA = superB.getArguments(); if (superA != null) { if (!args.equals(superA)) { return true; } } } } } return false; } public void resolveReferences() { if (!resolved) { resolved = true; // call resolve references on any children ResourceInfo infos[] = (ResourceInfo[])rcInfos.getResourceInfos(ResourceInfo.class); for(int i = 0; i < infos.length; i++){ infos[i].resolveReferences(); } if (parentId != null) { // Lookup the parent configuration by ID parent = ManagedBuildManager.getExtensionConfiguration(parentId); } } } /** * Reset the configuration's, tools', options */ public void reset() { ((FolderInfo)getRootFolderInfo()).resetOptionSettings(); } /** * Create a resource configuration object for the passed-in file */ @Override public IResourceConfiguration createResourceConfiguration(IFile file) { return createFileInfo(file.getFullPath().removeFirstSegments(1)); } @Override public IFileInfo createFileInfo(IPath path){ String resourceName = path.lastSegment(); String id = ManagedBuildManager.calculateChildId(getId(), path.toString()); return createFileInfo(path, id, resourceName); } @Override public IFileInfo createFileInfo(IPath path, String id, String name){ IResourceInfo info = getResourceInfo(path, false); IFileInfo fileInfo = null; if(info instanceof IFileInfo){ fileInfo = (IFileInfo)info; } else if (info instanceof IFolderInfo){ IFolderInfo base = (IFolderInfo)info; fileInfo = createFileInfo(path, base, null, id, name); } return fileInfo; } @Override public IFileInfo createFileInfo(IPath path, IFolderInfo base, ITool baseTool, String id, String name){ if(base.getPath().equals(path)) return null; IFileInfo fileInfo = new ResourceConfiguration((FolderInfo)base, baseTool, id, name, path); addResourceConfiguration(fileInfo); ManagedBuildManager.performValueHandlerEvent(fileInfo, IManagedOptionValueHandler.EVENT_OPEN); return fileInfo; } @Override public IFileInfo createFileInfo(IPath path, IFileInfo base, String id, String name){ if(base.getPath().equals(path)) return null; IFileInfo fileInfo = new ResourceConfiguration((ResourceConfiguration)base, path, id, name); addResourceConfiguration(fileInfo); ManagedBuildManager.performValueHandlerEvent(fileInfo, IManagedOptionValueHandler.EVENT_OPEN); return fileInfo; } @Override public IConfigurationEnvironmentVariableSupplier getEnvironmentVariableSupplier(){ IToolChain toolChain = getToolChain(); if(toolChain != null) return toolChain.getEnvironmentVariableSupplier(); return null; } /** * @return Returns the version. */ @Override public Version getVersion() { if ( version == null) { if ( rootFolderInfo.getToolChain() != null) { return rootFolderInfo.getToolChain().getVersion(); } } return version; } @Override public void setVersion(Version version) { // Do nothing } @Override public IConfigurationBuildMacroSupplier getBuildMacroSupplier(){ IToolChain toolChain = getToolChain(); if(toolChain != null) return toolChain.getBuildMacroSupplier(); return null; } @Override public boolean isTemporary(){ return isTemporary; } @Override public void updateManagedBuildRevision(String revision){ super.updateManagedBuildRevision(revision); ResourceInfo infos[] = (ResourceInfo[])rcInfos.getResourceInfos(ResourceInfo.class); for(int i = 0; i < infos.length; i++){ infos[i].updateManagedBuildRevision(revision); } } public void setParent(IConfiguration parent) { if ( this.parent != parent) { this.parent = parent; if (!isExtensionElement()) setDirty(true); } } @Override public ITool calculateTargetTool(){ ITool tool = getTargetTool(); if(tool == null){ tool = getToolFromOutputExtension(getArtifactExtension()); } if(tool == null){ IConfiguration extCfg; for(extCfg = this; extCfg != null && !extCfg.isExtensionElement(); extCfg = extCfg.getParent()){ } if(extCfg != null){ tool = getToolFromOutputExtension(extCfg.getArtifactExtension()); } } return tool; } @Override public ITool getToolFromOutputExtension(String extension) { return getRootFolderInfo().getToolFromOutputExtension(extension); } @Override public ITool getToolFromInputExtension(String sourceExtension) { return getRootFolderInfo().getToolFromInputExtension(sourceExtension); } /** * The resource delta passed to the builder is not always up-to-date * for the given configuration because between two builds of the same configuration * any number of other configuration builds may occur * that is why we need to keep some information regarding what happened * with the resource tree between the two configuration builds * * The trivial approach implemented currently is to hold * the general information of whether some resources were * removed,changed,etc. and detect whether the rebuild is needed * based upon this information * * This method adds the resource change state for the configuration * specifying the resource change type performed on the project * reported while building another configuration * The method is not exported to the public API since delta handling * mechanism will likely to be changed in the future * * In the future we might implement some more smart mechanism * for tracking delta, e.g calculate the pre-cinfiguration resource delta, etc. * */ public void addResourceChangeState(int state){ setResourceChangeState(state | resourceChangeState); } private void setResourceChangeState(int state){ if(resourceChangeState != state){ resourceChangeState = state; saveResourceChangeState(); } } private boolean resourceChangesRequireRebuild(){ return isInternalBuilderEnabled() ? resourceChangeState != 0 : (resourceChangeState & IResourceDelta.REMOVED) == IResourceDelta.REMOVED; } private void saveRebuildState(){ PropertyManager.getInstance().setProperty(this, REBUILD_STATE, Boolean.toString(rebuildNeeded)); } private void saveResourceChangeState(){ PropertyManager.getInstance().setProperty(this, RC_CHANGE_STATE, Integer.toString(resourceChangeState)); } /* * Internal Builder state API * NOTE: this is a temporary API * In the future we are going present the Internal Builder * as a special Builder object of the tool-chain and implement the internal * builder enabling/disabling as the Builder substitution functionality * */ /* public void setInternalBuilderBoolean(boolean value, String pref) { Preferences prefs = getPreferences(INTERNAL_BUILDER); if(prefs != null){ prefs.putBoolean(pref, value); try { prefs.flush(); } catch (BackingStoreException e) {} } } */ /* public boolean getInternalBuilderBoolean(String pref, boolean defaultValue) { Preferences prefs = getPreferences(INTERNAL_BUILDER); return prefs != null ? prefs.getBoolean(pref, false) : defaultValue; } */ /** * this method is used for enabling/disabling the internal builder * for the given configuration * * @param enable boolean */ public void enableInternalBuilder(boolean enable){ if(enable == isInternalBuilderEnabled()) return; IBuilder builder = getBuilderForInternalBuilderEnablement(enable, true); if(builder != null){ if(enable){ savePrevBuilderId(getBuilder()); } changeBuilder(builder, ManagedBuildManager.calculateChildId(builder.getId(), null), builder.getName(), true); if(enable){ try { setManagedBuildOn(true); } catch (BuildException e) { } } } } public boolean canEnableInternalBuilder(boolean enable){ return getBuilderForInternalBuilderEnablement(enable, true) != null; } private IBuilder getBuilderForInternalBuilderEnablement(boolean enable, boolean checkCompatibility){ IBuilder newBuilder = null; if(enable){ if(supportsBuild(true, false)){ IBuilder b = ManagedBuildManager.getInternalBuilder(); if(b != null){ if(!checkCompatibility || isBuilderCompatible(b)) newBuilder = b; } } } else { String id = getPrevBuilderId(); if(id != null){ IBuilder b = ManagedBuildManager.getExtensionBuilder(id); if(b != null){ if(!checkCompatibility || isBuilderCompatible(b)) newBuilder = b; } } if(newBuilder == null){ for(IToolChain tc = getToolChain(); tc != null; tc = tc.getSuperClass()){ IBuilder b = tc.getBuilder(); if(b.isInternalBuilder()) continue; for(;b != null && !b.isExtensionElement(); b = b.getSuperClass()) {} if(b != null){ if(!checkCompatibility || isBuilderCompatible(b)){ newBuilder = b; break; } } } } // if(newBuilder == null){ // IBuilder builders[] = ManagedBuildManager.getRealBuilders(); // IBuilder tmpB = null; // for(int i = 0; i < builders.length; i++){ // IBuilder b = builders[i]; // if(b.isInternalBuilder()) // continue; // // // if(isBuilderCompatible(b)){ // newBuilder = b; // break; // } else if(!checkCompatibility){ // tmpB = b; // } // } // // if(newBuilder == null){ // if(tmpB != null) // newBuilder = tmpB; // } // } } return newBuilder; } private void savePrevBuilderId(IBuilder builder){ IBuilder b = builder; for(;b != null && !b.isExtensionElement(); b = b.getSuperClass()) {} if(b == null) b = builder; ToolChain tc = (ToolChain)getToolChain(); if(tc != null) tc.setNonInternalBuilderId(b.getId()); } private String getPrevBuilderId(){ ToolChain tc = (ToolChain)getToolChain(); if(tc != null) return tc.getNonInternalBuilderId(); return null; } /** * returns whether the internal builder is enabled * @return boolean */ public boolean isInternalBuilderEnabled(){ return getBuilder().isInternalBuilder(); } /** * * sets the Internal Builder mode * * @param ignore if true, internal builder will ignore * build errors while building, * otherwise it will stop at the first build error */ public void setInternalBuilderIgnoreErr(boolean ignore){ try { getEditableBuilder().setStopOnError(!ignore); } catch (CoreException e) { } } /** * returns the Internal Builder mode * if true, internal builder will ignore build errors while building, * otherwise it will stop at the first build error * * @return boolean */ public boolean getInternalBuilderIgnoreErr(){ return !getBuilder().isStopOnError(); } /** * sets the Internal Builder Parallel mode * @param parallel if true, internal builder will use parallel mode * * @deprecated since CDT 9.0. Use {@link #setParallelDef(boolean)} */ @Deprecated public void setInternalBuilderParallel(boolean parallel){ setParallelDef(parallel); } /** * returns the Internal Builder parallel mode * if true, internal builder will work in parallel mode * otherwise it will use only one thread * @return boolean * * @deprecated since CDT 9.0. Use {@link #getParallelDef()} */ @Deprecated public boolean getInternalBuilderParallel(){ return getParallelDef(); } /** * Set parallel execution mode for the configuration's builder. * @see Builder#setParallelBuildOn(boolean) * * @param parallel - the flag to enable or disable parallel mode. */ public void setParallelDef(boolean parallel){ if(getParallelDef() == parallel) return; try { getEditableBuilder().setParallelBuildOn(parallel); } catch (CoreException e) { ManagedBuilderCorePlugin.log(e); } } /** * Check if the configuration's builder is operating in parallel mode. * @return {@code true} if parallel mode is enabled, {@code false} otherwise. */ public boolean getParallelDef(){ return getBuilder().isParallelBuildOn(); } /** * Sets maximum number of parallel threads/jobs to be used by builder. * * @param jobs - maximum number of jobs or threads. For details how * the number is interpreted see {@link Builder#setParallelizationNum(int)}. */ public void setParallelNumber(int jobs){ try { getEditableBuilder().setParallelizationNum(jobs); } catch (CoreException e) { ManagedBuilderCorePlugin.log(e); } } /** * Returns maximum number of parallel threads/jobs used by the configuration's builder. * @see #setParallelDef(boolean) * * @return - maximum number of parallel threads or jobs used by the builder. */ public int getParallelNumber(){ return getBuilder().getParallelizationNum(); } // private Preferences getPreferences(String name){ // if(isTemporary) // return null; // // IProject project = (IProject)getOwner(); // // if(project == null || !project.exists() || !project.isOpen()) // return null; // // Preferences prefs = new ProjectScope(project).getNode(ManagedBuilderCorePlugin.getUniqueIdentifier()); // if(prefs != null){ // prefs = prefs.node(getId()); // if(prefs != null && name != null) // prefs = prefs.node(name); // } // return prefs; // } @Override public IResourceInfo[] getResourceInfos() { return rcInfos.getResourceInfos(); } @Override public IResourceInfo getResourceInfo(IPath path, boolean exactPath) { return rcInfos.getResourceInfo(path, exactPath); } @Override public IResourceInfo getResourceInfoById(String id) { IResourceInfo infos[] = rcInfos.getResourceInfos(); for(int i = 0; i < infos.length; i++){ if(id.equals(infos[i].getId())) return infos[i]; } return null; } @Override public IFolderInfo getRootFolderInfo() { return rootFolderInfo; } ResourceInfoContainer getRcInfoContainer(IResourceInfo rcInfo){ PathSettingsContainer cr = pathSettings.getChildContainer(rcInfo.getPath(), true, true); return new ResourceInfoContainer(cr, false); } @Override public CConfigurationData getConfigurationData(){ return fCfgData; } @Override public void removeResourceInfo(IPath path) { IResourceInfo info = getResourceInfo(path, true); if(info != null) removeResourceConfiguration(info); } @Override public IFolderInfo createFolderInfo(IPath path) { String resourceName = path.lastSegment(); String id = ManagedBuildManager.calculateChildId(getId(), path.toString()); return createFolderInfo(path, id, resourceName); } @Override public IFolderInfo createFolderInfo(IPath path, String id, String name) { IResourceInfo info = getResourceInfo(path, false); IFolderInfo folderInfo = null; if(info instanceof IFileInfo){ // folderInfo = null; } else if (info instanceof IFolderInfo){ IFolderInfo base = (IFolderInfo)info; folderInfo = createFolderInfo(path, base, id, name); } return folderInfo; } @Override public IFolderInfo createFolderInfo(IPath path, IFolderInfo base, String id, String name) { if(base.getPath().equals(path)) return null; FolderInfo folderInfo = new FolderInfo((FolderInfo)base, id, name, path); addResourceConfiguration(folderInfo); folderInfo.propertiesChanged(); ManagedBuildManager.performValueHandlerEvent(folderInfo, IManagedOptionValueHandler.EVENT_OPEN); return folderInfo; } @Override public ICSourceEntry[] getSourceEntries() { if(sourceEntries == null || sourceEntries.length == 0){ if(parent != null && sourceEntries == null) return parent.getSourceEntries(); return new ICSourceEntry[]{new CSourceEntry(Path.EMPTY, null, ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED)}; } return sourceEntries.clone(); } @Override public void setSourceEntries(ICSourceEntry[] entries) { setSourceEntries(entries, true); } public void setSourceEntries(ICSourceEntry[] entries, boolean setRebuildState) { exportArtifactInfo(); if(Arrays.equals(getSourceEntries(), entries)) return; sourceEntries = entries != null ? (ICSourceEntry[])entries.clone() : null; // for(int i = 0; i < sourcePaths.length; i++){ // sourcePaths[i] = sourcePaths[i].makeRelative(); // } if(setRebuildState){ setDirty(true); setRebuildState(true); } } public void setErrorParserAttribute(String[] ids) { if(ids == null){ errorParserIds = null; } else if(ids.length == 0){ errorParserIds = EMPTY_STRING; } else { StringBuilder buf = new StringBuilder(); buf.append(ids[0]); for(int i = 1; i < ids.length; i++){ buf.append(";").append(ids[i]); //$NON-NLS-1$ } errorParserIds = buf.toString(); } } @Override public void setErrorParserList(String[] ids) { if(ids == null){ //reset resetErrorParsers(); } else { resetErrorParsers(); Set<String> oldSet = contributeErrorParsers(null, true); if(oldSet != null) { oldSet.removeAll(Arrays.asList(ids)); removeErrorParsers(oldSet); } setErrorParserAttribute(ids); } } public void resetErrorParsers(){ errorParserIds = null; IResourceInfo rcInfos[] = getResourceInfos(); for(int i = 0; i < rcInfos.length; i++){ ResourceInfo rcInfo = (ResourceInfo)rcInfos[i]; rcInfo.resetErrorParsers(); } } void removeErrorParsers(Set<String> set){ Set<String> oldSet = contributeErrorParsers(null, false); if(oldSet == null) oldSet = new LinkedHashSet<String>(); oldSet.removeAll(set); setErrorParserAttribute(oldSet.toArray(new String[oldSet.size()])); IResourceInfo rcInfos[] = getResourceInfos(); for(int i = 0; i < rcInfos.length; i++){ ResourceInfo rcInfo = (ResourceInfo)rcInfos[i]; rcInfo.removeErrorParsers(set); } } @Override public CBuildData getBuildData() { return getEditableBuilder().getBuildData(); } @Override public IBuilder getEditableBuilder(){ IToolChain tc = getToolChain(); IBuilder builder = tc.getBuilder(); if(builder.isExtensionElement()){ String subId = ManagedBuildManager.calculateChildId(builder.getId(), null); String builderName = builder.getName() + "." + getName(); //$NON-NLS-1$ builder = getToolChain().createBuilder(builder, subId, builderName, false); } return builder; } @Override public IBuilder getBuilder(){ return getToolChain().getBuilder(); } @Override public String getOutputPrefix(String outputExtension) { // Treat null extensions as empty string String ext = outputExtension == null ? EMPTY_STRING : outputExtension; // Get all the tools for the current config String flags = EMPTY_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; } public ICConfigurationDescription getConfigurationDescription(){ return fCfgDes; } public void setConfigurationDescription(ICConfigurationDescription cfgDes){ fCfgDes = cfgDes; } @Override public IBuildObjectProperties getBuildProperties() { if(buildProperties == null){ BuildObjectProperties parentProps = findBuildProperties(); if(parentProps != null) buildProperties = new BuildObjectProperties(parentProps, this, this); else buildProperties = new BuildObjectProperties(this, this); } return buildProperties; } private BuildObjectProperties findBuildProperties(){ if(buildProperties == null){ if(parent != null){ return ((Configuration)parent).findBuildProperties(); } return null; } return buildProperties; } public boolean supportsType(IBuildPropertyType type) { return supportsType(type.getId()); } public boolean supportsValue(IBuildPropertyType type, IBuildPropertyValue value) { return supportsValue(type.getId(), value.getId()); } @Override public void propertiesChanged() { if(isExtensionConfig) return; BooleanExpressionApplicabilityCalculator calculator = getBooleanExpressionCalculator(); if(calculator != null) calculator.adjustConfiguration(this, false); IResourceInfo infos[] = getResourceInfos(); for(int i = 0; i < infos.length; i++){ ((ResourceInfo)infos[i]).propertiesChanged(); } } public BooleanExpressionApplicabilityCalculator getBooleanExpressionCalculator(){ if(booleanExpressionCalculator == null){ if(parent != null){ return ((Configuration)parent).getBooleanExpressionCalculator(); } } return booleanExpressionCalculator; } @Override public boolean isSystemObject() { if(isTest) return true; if(getProjectType() != null) return getProjectType().isSystemObject(); return false; } @Override public String getOutputExtension(String resourceExtension) { return getRootFolderInfo().getOutputExtension(resourceExtension); } @Override public String getOutputFlag(String outputExt) { // Treat null extension as an empty string String ext = outputExt == null ? EMPTY_STRING : outputExt; // Get all the tools for the current config String flags = EMPTY_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; } @Override 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; } @Override public String[] getUserObjects(String extension) { Vector<String> objs = new Vector<String>(); ITool tool = calculateTargetTool(); 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 objs.toArray(new String[objs.size()]); } @Override public String[] getLibs(String extension) { Vector<String> libs = new Vector<String>(); ITool tool = calculateTargetTool(); 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(this, 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 libs.toArray(new String[libs.size()]); } @Override public boolean buildsFileType(String srcExt) { return getRootFolderInfo().buildsFileType(srcExt); } /** * @return whether this Configuration exports settings to other referenced configurations */ public boolean canExportedArtifactInfo() { if (isExtensionConfig) return false; IBuildObjectProperties props = getBuildProperties(); IBuildProperty prop = props.getProperty(ManagedBuildManager.BUILD_ARTEFACT_TYPE_PROPERTY_ID); if (prop == null) return false; String valueId = prop.getValue().getId(); if(!ManagedBuildManager.BUILD_ARTEFACT_TYPE_PROPERTY_SHAREDLIB.equals(valueId) && !ManagedBuildManager.BUILD_ARTEFACT_TYPE_PROPERTY_STATICLIB.equals(valueId)) return false; ICConfigurationDescription des = ManagedBuildManager.getDescriptionForConfiguration(this); return des != null && !des.isReadOnly(); } /** * Responsible for contributing 'external' settings back to the core for use * by referenced projects. * * In this case it returns Include, Library path & Library File settings * to be used be references for linking the output of this library project */ public void exportArtifactInfo(){ if (!canExportedArtifactInfo()) return; ICConfigurationDescription des = ManagedBuildManager.getDescriptionForConfiguration(this); if(des != null && !des.isReadOnly()){ ICOutputEntry entries[] = getConfigurationData().getBuildData().getOutputDirectories(); IPath path = getOwner().getFullPath(); List<ICSettingEntry> list = new ArrayList<ICSettingEntry>(entries.length + 1); // Add project level include path list.add(CDataUtil.createCIncludePathEntry(path.toString(), ICSettingEntry.VALUE_WORKSPACE_PATH)); // Add Build output path as an exported library path entries = CDataUtil.resolveEntries(entries, des); for(int i = 0; i < entries.length; i++){ ICOutputEntry out = entries[i]; String value = out.getValue(); IPath p = new Path(value); if(!p.isAbsolute()) value = getOwner().getFullPath().append(value).toString(); ICLibraryPathEntry lib = CDataUtil.createCLibraryPathEntry(value, out.getFlags() & (~ICSettingEntry.RESOLVED)); list.add(lib); } // Add 'libs' artifact names themselves ICSettingEntry[] unresolved = new ICSettingEntry[] {CDataUtil.createCLibraryFileEntry(getArtifactName(), 0)}; ICSettingEntry[] libFiles = CDataUtil.resolveEntries(unresolved, des); list.add(libFiles[0]); // Contribute the settings back as 'exported' des.createExternalSetting(null, null, null, list.toArray(new ICSettingEntry[list.size()])); } } @Override public boolean supportsBuild(boolean managed) { return supportsBuild(managed, true); } public boolean supportsBuild(boolean managed, boolean checkBuilder) { IResourceInfo[] rcs = getResourceInfos(); for(int i = 0; i < rcs.length; i++){ if(!rcs[i].supportsBuild(managed)) return false; } if(checkBuilder){ IBuilder builder = getBuilder(); if(builder != null && !builder.supportsBuild(managed)) return false; } return true; } @Override public boolean supportsType(String typeId) { SupportedProperties props = findSupportedProperties(); boolean supports = false; if(props != null){ supports = props.supportsType(typeId); } if(!supports) supports = ((ToolChain)getToolChain()).supportsType(typeId); return supports; } @Override public boolean supportsValue(String typeId, String valueId) { SupportedProperties props = findSupportedProperties(); boolean supports = false; if(props != null){ supports = props.supportsValue(typeId, valueId); } if(!supports) supports = ((ToolChain)getToolChain()).supportsValue(typeId, valueId); return supports; } private SupportedProperties findSupportedProperties(){ if(supportedProperties == null){ if(parent != null){ return ((Configuration)parent).findSupportedProperties(); } } return supportedProperties; } private void loadProperties(IManagedConfigElement el){ supportedProperties = new SupportedProperties(el); } @Override public String[] getRequiredTypeIds() { SupportedProperties props = findSupportedProperties(); List<String> list = new ArrayList<String>(); if(props != null){ list.addAll(Arrays.asList(props.getRequiredTypeIds())); } list.addAll(Arrays.asList(((ToolChain)getToolChain()).getRequiredTypeIds())); return list.toArray(new String[list.size()]); } @Override public String[] getSupportedTypeIds() { SupportedProperties props = findSupportedProperties(); List<String> list = new ArrayList<String>(); if(props != null){ list.addAll(Arrays.asList(props.getSupportedTypeIds())); } list.addAll(Arrays.asList(((ToolChain)getToolChain()).getSupportedTypeIds())); return list.toArray(new String[list.size()]); } @Override public String[] getSupportedValueIds(String typeId) { SupportedProperties props = findSupportedProperties(); List<String> list = new ArrayList<String>(); if(props != null){ list.addAll(Arrays.asList(props.getSupportedValueIds(typeId))); } list.addAll(Arrays.asList(((ToolChain)getToolChain()).getSupportedValueIds(typeId))); return list.toArray(new String[list.size()]); } @Override public boolean requiresType(String typeId) { SupportedProperties props = findSupportedProperties(); boolean requires = false; if(props != null){ requires = props.requiresType(typeId); } if(!requires) requires = ((ToolChain)getToolChain()).requiresType(typeId); return requires; } @Override public boolean isManagedBuildOn() { return getBuilder().isManagedBuildOn(); } @Override public void setManagedBuildOn(boolean on) throws BuildException { try { getEditableBuilder().setManagedBuildOn(on); } catch (CoreException e) { throw new BuildException(e.getLocalizedMessage()); } } @Override public void changeBuilder(IBuilder newBuilder, String id, String name){ changeBuilder(newBuilder, id, name, false); } public void changeBuilder(IBuilder newBuilder, String id, String name, boolean allBuildSettings){ ToolChain tc = (ToolChain)getToolChain(); Builder cur = (Builder)getEditableBuilder(); Builder newCfgBuilder = null; if(newBuilder.getParent() == tc){ newCfgBuilder = (Builder)newBuilder; } else { IBuilder curReal = ManagedBuildManager.getRealBuilder(cur); IBuilder newReal = ManagedBuildManager.getRealBuilder(newBuilder); if(newReal != curReal){ IBuilder extBuilder = newBuilder; for(;extBuilder != null && !extBuilder.isExtensionElement(); extBuilder = extBuilder.getSuperClass()) {} if(extBuilder == null) extBuilder = newBuilder; newCfgBuilder = new Builder(tc, extBuilder, id, name, false); newCfgBuilder.copySettings(cur, allBuildSettings); } } if(newCfgBuilder != null){ tc.setBuilder(newCfgBuilder); } } @Override public boolean isBuilderCompatible(IBuilder builder){ return builder.supportsBuild(isManagedBuildOn()); } ITool findToolById(String id){ IResourceInfo[] rcInfos = getResourceInfos(); ITool tool = null; for(int i = 0; i < rcInfos.length; i++){ ResourceInfo info = (ResourceInfo)rcInfos[i]; tool = info.getToolById(id); if(tool != null) break; } return tool; } void resolveProjectReferences(boolean onLoad){ IResourceInfo[] rcInfos = getResourceInfos(); for(int i = 0; i < rcInfos.length; i++){ ResourceInfo info = (ResourceInfo)rcInfos[i]; info.resolveProjectReferences(onLoad); } } public boolean isPerRcTypeDiscovery(){ ToolChain tc = (ToolChain)getRootFolderInfo().getToolChain(); return tc.isPerRcTypeDiscovery(); } public void setPerRcTypeDiscovery(boolean on){ ToolChain tc = (ToolChain)getRootFolderInfo().getToolChain(); tc.setPerRcTypeDiscovery(on); } // public IScannerConfigBuilderInfo2 getScannerConfigInfo(){ // ToolChain tc = (ToolChain)getRootFolderInfo().getToolChain(); // return tc.getScannerConfigBuilderInfo(); // } // public IScannerConfigBuilderInfo2 setScannerConfigInfo(IScannerConfigBuilderInfo2 info){ // ToolChain tc = (ToolChain)getRootFolderInfo().getToolChain(); // return tc.setScannerConfigBuilderInfo(info); // } public PathInfoCache setDiscoveredPathInfo(PathInfoCache info){ ToolChain tc = (ToolChain)getRootFolderInfo().getToolChain(); return tc.setDiscoveredPathInfo(info); } public PathInfoCache getDiscoveredPathInfo(){ ToolChain tc = (ToolChain)getRootFolderInfo().getToolChain(); return tc.getDiscoveredPathInfo(); } public String getDiscoveryProfileId(){ ToolChain tc = (ToolChain)getRootFolderInfo().getToolChain(); return tc.getScannerConfigDiscoveryProfileId(); } public PathInfoCache clearDiscoveredPathInfo(){ ToolChain tc = (ToolChain)getRootFolderInfo().getToolChain(); return tc.clearDiscoveredPathInfo(); } public ICfgScannerConfigBuilderInfo2Set getCfgScannerConfigInfo(){ return cfgScannerInfo; } public void setCfgScannerConfigInfo(ICfgScannerConfigBuilderInfo2Set info){ cfgScannerInfo = info; } public void clearCachedData(){ cfgScannerInfo = null; } public boolean isPreference(){ return isPreferenceConfig; } @Override public IBuildPropertyValue getBuildArtefactType() { IBuildObjectProperties props = findBuildProperties(); if(props != null){ IBuildProperty prop = props.getProperty(ManagedBuildManager.BUILD_ARTEFACT_TYPE_PROPERTY_ID); if(prop != null) return prop.getValue(); } return null; } @Override public void setBuildArtefactType(String id) throws BuildException { IBuildObjectProperties props = getBuildProperties(); try { props.setProperty(ManagedBuildManager.BUILD_ARTEFACT_TYPE_PROPERTY_ID, id); } catch (CoreException e){ throw new BuildException(e.getLocalizedMessage()); } // May need to update the exports paths & symbols after artifact type change exportArtifactInfo(); } boolean isExcluded(IPath path){ // if(path.segmentCount() == 0) // return false; ICSourceEntry[] entries = getSourceEntries(); return CDataUtil.isExcluded(path, entries); } void setExcluded(IPath path, boolean isFolder, boolean excluded){ // if(path.segmentCount() == 0) // return; if(excludeList == null) { ICSourceEntry[] newEntries = getUpdatedEntries(path, isFolder, excluded); if(newEntries != null) setSourceEntries(newEntries, false); } else{ if(excluded) excludeList.add(path); } } private ICSourceEntry[] getUpdatedEntries(IPath path, boolean isFolder, boolean excluded){ try { ICSourceEntry[] entries = getSourceEntries(); return CDataUtil.setExcluded(path, isFolder, excluded, entries, false); } catch (CoreException e) { ManagedBuilderCorePlugin.log(e); } return null; } boolean canExclude(IPath path, boolean isFolder, boolean excluded){ if(excludeList == null) { ICSourceEntry[] newEntries = getUpdatedEntries(path, isFolder, excluded); return newEntries != null; } else{ if(excluded) excludeList.add(path); return true; } } @Override public IRealBuildObjectAssociation getExtensionObject() { return isExtensionConfig ? this : (Configuration)getParent(); } @Override public IRealBuildObjectAssociation[] getIdenticBuildObjects() { return new Configuration[]{(Configuration)getExtensionObject()}; } @Override public IRealBuildObjectAssociation getRealBuildObject() { return getExtensionObject(); } @Override public IRealBuildObjectAssociation getSuperClassObject() { return (IRealBuildObjectAssociation)getParent(); } @Override public int getType() { return OBJECT_CONFIGURATION; } @Override public boolean isRealBuildObject() { return getRealBuildObject() == this; } @Override public String getUniqueRealName() { return getName(); } @Override public boolean isExtensionBuildObject() { return isExtensionElement(); } }