/******************************************************************************* * Copyright (c) 2004, 2007 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.scannerconfig; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.Vector; import org.eclipse.cdt.build.internal.core.scannerconfig2.CfgScannerConfigProfileManager; import org.eclipse.cdt.core.model.CoreModel; 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.make.core.scannerconfig.IExternalScannerInfoProvider; import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2; import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector; import org.eclipse.cdt.make.core.scannerconfig.InfoContext; import org.eclipse.cdt.make.internal.core.scannerconfig2.SCProfileInstance; import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfileManager; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; import org.eclipse.cdt.managedbuilder.core.ITarget; 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.internal.core.ManagedBuildInfo; import org.eclipse.cdt.managedbuilder.scannerconfig.IManagedScannerInfoCollector; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; /** * Implements a specialized path container for managed build projects. It will * either start the dynamic path collector specified for a target in the tool * manifest, or it will attempt to discover the built-in values specified in * the manifest. * * @since 2.0 */ public class ManagedBuildCPathEntryContainer implements IPathEntryContainer { // Managed make per project scanner configuration discovery profile public static final String MM_PP_DISCOVERY_PROFILE_ID = ManagedBuilderCorePlugin.getUniqueIdentifier() + ".GCCManagedMakePerProjectProfile"; //$NON-NLS-1$ private static final String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$ private static final String ERROR_HEADER = "PathEntryContainer error ["; //$NON-NLS-1$ private static final String TRACE_FOOTER = "]: "; //$NON-NLS-1$ private static final String TRACE_HEADER = "PathEntryContainer trace ["; //$NON-NLS-1$ private ITarget defaultTarget; private Vector<IPathEntry> entries; private IProject project; private ManagedBuildInfo info; public static boolean VERBOSE = false; 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); } } /** * Creates a new path container for the managed build project. */ public ManagedBuildCPathEntryContainer(IProject project) { super(); this.project = project; entries = new Vector<IPathEntry>(); } protected void addDefinedSymbols(Map<String, String> definedSymbols) { // Add a new macro entry for each defined symbol Set<String> macros = definedSymbols.keySet(); for (String macro : macros) { boolean add = true; String value = definedSymbols.get(macro); // Make sure the current entries do not contain a duplicate for (IPathEntry entry : entries) { if (entry.getEntryKind() == IPathEntry.CDT_MACRO) { if (((IMacroEntry)entry).getMacroName().equals(macro) && ((IMacroEntry)entry).getMacroValue().equals(value)) { add = false; break; } } } if (add) { entries.add(CoreModel.newMacroEntry(Path.EMPTY, macro, value)); } } } protected void addIncludePaths(List<String> paths) { // A little checking is needed to avoid adding duplicates for (String path : paths) { IPathEntry entry = CoreModel.newIncludeEntry(Path.EMPTY, Path.EMPTY, new Path(path), true); if (!entries.contains(entry)) { entries.add(entry); } } } protected void calculateEntriesDynamically(final IProject project, SCProfileInstance profileInstance, final IScannerInfoCollector collector) { // TODO Get the provider from the toolchain specification final IScannerConfigBuilderInfo2 buildInfo = ScannerConfigProfileManager. createScannerConfigBuildInfo2(ManagedBuilderCorePlugin.getDefault().getPluginPreferences(), profileInstance.getProfile().getId(), false); List<String> providerIds = buildInfo.getProviderIdList(); for (final String providerId : providerIds) { final IExternalScannerInfoProvider esiProvider = profileInstance.createExternalScannerInfoProvider(providerId); // Set the arguments for the provider ISafeRunnable runnable = new ISafeRunnable() { public void run() { IProgressMonitor monitor = new NullProgressMonitor(); IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project); IConfiguration config = info.getDefaultConfiguration(); IBuildEnvironmentVariable[] vars = ManagedBuildManager.getEnvironmentVariableProvider().getVariables(config, true, true); Properties env = new Properties(); if (vars != null) for (int i = 0; i < vars.length; ++i) env.put(vars[i].getName(), vars[i].getValue()); esiProvider.invokeProvider(monitor, project, providerId, buildInfo, collector/*, env*/); } public void handleException(Throwable exception) { if (exception instanceof OperationCanceledException) { throw (OperationCanceledException) exception; } } }; Platform.run(runnable); } } /* (non-Javadoc) * @see org.eclipse.cdt.core.model.IPathEntryContainer#getPathEntries() */ public IPathEntry[] getPathEntries() { info = (ManagedBuildInfo) ManagedBuildManager.getBuildInfo(project); if (info == null) { ManagedBuildCPathEntryContainer.outputError(project.getName(), "Build information is null"); //$NON-NLS-1$ return entries.toArray(new IPathEntry[entries.size()]); } IConfiguration defaultConfig = info.getDefaultConfiguration(); if (defaultConfig == null) { // The build information has not been loaded yet ManagedBuildCPathEntryContainer.outputError(project.getName(), "Build information has not been loaded yet"); //$NON-NLS-1$ return entries.toArray(new IPathEntry[entries.size()]); } // get the associated scanner config discovery profile id String scdProfileId = ManagedBuildManager.getScannerInfoProfileId(defaultConfig); IScannerInfoCollector collector = null; SCProfileInstance profileInstance = null; if (scdProfileId != null) { // See if we can load a dynamic resolver //FIXME: InfoContext context = CfgScannerConfigProfileManager.createDefaultContext(project); profileInstance = ScannerConfigProfileManager.getInstance(). getSCProfileInstance(project, context, scdProfileId); collector = profileInstance.createScannerInfoCollector(); } synchronized(this) { if (collector instanceof IManagedScannerInfoCollector) { IManagedScannerInfoCollector mCollector = (IManagedScannerInfoCollector) collector; mCollector.setProject(project); ManagedBuildCPathEntryContainer.outputTrace(project.getName(), "Path entries collected dynamically"); //$NON-NLS-1$ calculateEntriesDynamically((IProject)info.getOwner(), profileInstance, collector); addEntries(info.getManagedBuildValues()); addIncludePaths(mCollector.getIncludePaths()); addDefinedSymbols(mCollector.getDefinedSymbols()); } else { // If none supplied, use the built-ins if (defaultConfig != null) { addEntries(info.getManagedBuildValues()); addEntries(info.getManagedBuildBuiltIns()); ManagedBuildCPathEntryContainer.outputTrace(project.getName(), "Path entries set using built-in definitions from " + defaultConfig.getName()); //$NON-NLS-1$ } else { ManagedBuildCPathEntryContainer.outputError(project.getName(), "Configuration is null"); //$NON-NLS-1$ return entries.toArray(new IPathEntry[entries.size()]); } } return entries.toArray(new IPathEntry[entries.size()]); } // end synchronized } /* (non-Javadoc) * @see org.eclipse.cdt.core.model.IPathEntryContainer#getDescription() */ public String getDescription() { return "CDT Managed Build Project"; //$NON-NLS-1$ } /* (non-Javadoc) * @see org.eclipse.cdt.core.model.IPathEntryContainer#getPath() */ public IPath getPath() { return new Path("org.eclipse.cdt.managedbuilder.MANAGED_CONTAINER"); //$NON-NLS-1$ } private void addEntries(IPathEntry[] values) { if (values == null) return; for (int i=0; i<values.length; i++) { if (values[i] == null) continue; if (!entries.contains(values[i])) { entries.add(values[i]); } } } }