summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus 2011-11-21 21:16:33 (EST)
committer Alena Laskavaia2011-11-21 21:16:33 (EST)
commitf3c8eaaf302399dc0212c86a3b6f799889d422c0 (patch)
tree3f8927da285fecd1a8cdf038a09ebc7efc6ca5d8
parent1e3fc49c454408e87ee1ea6206afd2d6c3771c2d (diff)
downloadorg.eclipse.cdt-f3c8eaaf302399dc0212c86a3b6f799889d422c0.zip
org.eclipse.cdt-f3c8eaaf302399dc0212c86a3b6f799889d422c0.tar.gz
org.eclipse.cdt-f3c8eaaf302399dc0212c86a3b6f799889d422c0.tar.bz2
Bug 210248 - [Internal Builder]does not rebuild a dependent project in
case of a reference library project change
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core.tests/resources/depLibsProjects/tapp.zipbin0 -> 4514 bytes
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core.tests/resources/depLibsProjects/tlib.zipbin0 -> 3091 bytes
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core.tests/resources/depLibsProjects/tobjs.zipbin0 -> 3603 bytes
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core.tests/suite/org/eclipse/cdt/managedbuilder/tests/suite/AllManagedBuildTests.java2
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildDependencyLibsTests.java285
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/AdditionalInput.java332
-rw-r--r--build/org.eclipse.cdt.managedbuilder.gnu.ui/plugin.xml10
7 files changed, 622 insertions, 7 deletions
diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/resources/depLibsProjects/tapp.zip b/build/org.eclipse.cdt.managedbuilder.core.tests/resources/depLibsProjects/tapp.zip
new file mode 100644
index 0000000..56f8888
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.core.tests/resources/depLibsProjects/tapp.zip
Binary files differ
diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/resources/depLibsProjects/tlib.zip b/build/org.eclipse.cdt.managedbuilder.core.tests/resources/depLibsProjects/tlib.zip
new file mode 100644
index 0000000..2167f3f
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.core.tests/resources/depLibsProjects/tlib.zip
Binary files differ
diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/resources/depLibsProjects/tobjs.zip b/build/org.eclipse.cdt.managedbuilder.core.tests/resources/depLibsProjects/tobjs.zip
new file mode 100644
index 0000000..3fe31c0
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.core.tests/resources/depLibsProjects/tobjs.zip
Binary files differ
diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/suite/org/eclipse/cdt/managedbuilder/tests/suite/AllManagedBuildTests.java b/build/org.eclipse.cdt.managedbuilder.core.tests/suite/org/eclipse/cdt/managedbuilder/tests/suite/AllManagedBuildTests.java
index 65fdaad..d90c1e4 100644
--- a/build/org.eclipse.cdt.managedbuilder.core.tests/suite/org/eclipse/cdt/managedbuilder/tests/suite/AllManagedBuildTests.java
+++ b/build/org.eclipse.cdt.managedbuilder.core.tests/suite/org/eclipse/cdt/managedbuilder/tests/suite/AllManagedBuildTests.java
@@ -26,6 +26,7 @@ import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildCoreTests;
import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildCoreTests20;
import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildCoreTests_SharedToolOptions;
import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildDependencyCalculatorTests;
+import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildDependencyLibsTests;
import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildEnvironmentTests;
import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildMacrosTests;
import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildTCSupportedTest;
@@ -61,6 +62,7 @@ public class AllManagedBuildTests {
suite.addTestSuite(GCCSpecsConsoleParserTest.class);
// managedbuilder.core.tests
+ suite.addTest(ManagedBuildDependencyLibsTests.suite());
suite.addTest(ManagedBuildCoreTests20.suite());
suite.addTest(ManagedBuildCoreTests.suite());
suite.addTest(ManagedProjectUpdateTests.suite());
diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildDependencyLibsTests.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildDependencyLibsTests.java
new file mode 100644
index 0000000..05b0320
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildDependencyLibsTests.java
@@ -0,0 +1,285 @@
+package org.eclipse.cdt.managedbuilder.core.tests;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.settings.model.ICProjectDescription;
+import org.eclipse.cdt.managedbuilder.core.IBuilder;
+import org.eclipse.cdt.managedbuilder.core.IConfiguration;
+import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
+import org.eclipse.cdt.managedbuilder.core.IToolChain;
+import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
+import org.eclipse.cdt.managedbuilder.internal.core.FolderInfo;
+import org.eclipse.cdt.managedbuilder.tcmodification.IConfigurationModification;
+import org.eclipse.cdt.managedbuilder.tcmodification.IToolChainModificationManager;
+import org.eclipse.cdt.managedbuilder.testplugin.ManagedBuildTestHelper;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceDescription;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+
+public class ManagedBuildDependencyLibsTests extends TestCase {
+ private static final String PROJ_PATH = "depLibsProjects";
+ private static final String MESSAGE_TAIL = " (see .log file for more details).";
+
+ private IProject fTapp, fTlib, fTobjs;
+
+ private IToolChain[] allToolChains;
+
+ public ManagedBuildDependencyLibsTests(String name) {
+ super(name);
+ // TODO Auto-generated constructor stub
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite(ManagedBuildDependencyLibsTests.class.getName());
+
+ suite.addTest(new ManagedBuildDependencyLibsTests("testDepLibs"));
+ suite.addTest(new ManagedBuildDependencyLibsTests("testDepUObjs"));
+ return suite;
+ }
+
+ private void buildProject(IProject curProject) {
+
+ IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(curProject);
+ try {
+ IProject[] referencedProjects = curProject.getReferencedProjects();
+ for(int i = 0; i < referencedProjects.length; ++i)
+ buildProject(referencedProjects[i]);
+
+ // Build the project in order to generate the makefiles
+ curProject.build(IncrementalProjectBuilder.INCREMENTAL_BUILD,new NullProgressMonitor());
+ }
+ catch(CoreException e){
+ fail(e.getStatus().getMessage());
+ }
+ catch(OperationCanceledException e){
+ fail("the project \"" + curProject.getName() + "\" build was cancelled, exception message: " + e.getMessage());
+ }
+
+
+ }
+
+
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ allToolChains = ManagedBuildManager.
+ getRealToolChains();
+ IWorkspaceDescription wsDescription = ResourcesPlugin.getWorkspace().getDescription();
+ wsDescription.setAutoBuilding(false);
+ ResourcesPlugin.getWorkspace().setDescription(wsDescription);
+ assertNotNull("Cannot create tapp project",
+ fTapp = ManagedBuildTestHelper.loadProject("tapp", PROJ_PATH));
+ assertNotNull("Cannot create tlib project",
+ fTlib = ManagedBuildTestHelper.loadProject("tlib", PROJ_PATH));
+ assertNotNull("Cannot create tobjs project",
+ fTobjs = ManagedBuildTestHelper.loadProject("tobjs", PROJ_PATH));
+ IProjectDescription projDescription = fTapp.getDescription();
+ projDescription.setReferencedProjects(new IProject[]
+ {fTlib, fTobjs});
+ fTapp.setDescription(projDescription, new NullProgressMonitor());
+ IToolChain toolChain = setToolChain(fTapp, null);
+ assertNotNull("No compatible tool chain.", toolChain);
+ setToolChain(fTlib, toolChain);
+ setToolChain(fTobjs, toolChain);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ ManagedBuildTestHelper.removeProject(fTapp.getName());
+ ManagedBuildTestHelper.removeProject(fTlib.getName());
+ ManagedBuildTestHelper.removeProject(fTobjs.getName());
+ }
+
+ private void deleteFiles(IFolder dir, String pattern, IProgressMonitor monitor) {
+ List<IFile> files = new ArrayList<IFile>();
+ findFiles(dir, pattern, files);
+ for(Iterator<IFile> i = files.iterator(); i.hasNext(); ) {
+ IFile file = i.next();
+ try {
+ file.delete(true, monitor);
+ } catch (CoreException e) {
+ e.printStackTrace();
+ fail("Error deleting file " + file.getFullPath().toString() + '.' + MESSAGE_TAIL);
+ }
+ }
+ }
+
+ private void findFiles(IResource dir, String pattern, List<IFile> files) {
+ IResource resource = null;
+ try {
+ IResource[] members;
+ if(dir instanceof IContainer)
+ members = ((IContainer)dir).members(IFolder.INCLUDE_PHANTOMS);
+ else
+ if(dir instanceof IFolder)
+ members = ((IFolder)dir).members(IFolder.INCLUDE_PHANTOMS);
+ else // Not possible
+ return;
+ for(int i = 0; i < members.length; ++i) {
+ resource = members[i];
+ if(resource.getType() == IResource.FOLDER)
+ findFiles((IFolder)resource, pattern, files);
+ else {
+ if(resource.getName().matches(pattern))
+ files.add((IFile)resource);
+ }
+ }
+ } catch (CoreException e) {
+ e.printStackTrace();
+ fail("Error while collecting files." + MESSAGE_TAIL);
+ }
+ }
+
+ private IToolChain setToolChain(IProject project, IToolChain setTo) {
+ try {
+ IConfiguration cfg = getProjectConfiguration(project);
+ IToolChain currentToolChain = cfg.getToolChain();
+
+ IToolChainModificationManager mngr =
+ ManagedBuildManager.getToolChainModificationManager();
+ IConfigurationModification cfgM =
+ (IConfigurationModification)mngr.
+ createModification(cfg.getRootFolderInfo());
+ FolderInfo folderInfo = (FolderInfo)cfg.getRootFolderInfo();
+
+ if(setTo == null) {
+ for(int i = 0; i < allToolChains.length; ++i) {
+ // If predefined tool chain supported, leave it alone
+ if(allToolChains[i].equals(currentToolChain))
+ return currentToolChain;
+ // In the same loop try to find compatible tool chain
+ if(setTo == null) {
+ IBuilder builder = allToolChains[i].getBuilder();
+ if(cfg.isBuilderCompatible(builder) &&
+ folderInfo.isToolChainCompatible(allToolChains[i]))
+ setTo = allToolChains[i];
+ }
+ }
+ }
+ if(null != setTo) {
+ cfgM.setToolChain(setTo);
+ assertEquals(setTo, cfgM.getToolChain());
+ assertEquals(setTo.getBuilder(), cfgM.getBuilder());
+ }
+ } catch (CoreException e) {
+ e.printStackTrace();
+ fail("Error. " + MESSAGE_TAIL);
+ }
+ return setTo;
+ }
+
+ private IConfiguration getProjectConfiguration(IProject project) throws CoreException {
+ ICProjectDescription cProjDescription = CoreModel.getDefault().
+ createProjectDescription(project, true);
+ return ManagedBuildManager.
+ getConfigurationForDescription(
+ cProjDescription.getConfigurations()[0]);
+
+ }
+
+ private void rebuildArtefact(IProject project) {
+// deleteFiles(getProjectFolder(project),
+// getArtefactFullName(project),
+// new NullProgressMonitor());
+ try {
+ project.build(IncrementalProjectBuilder.CLEAN_BUILD, new NullProgressMonitor());
+ } catch (CoreException e) {
+ e.printStackTrace();
+ fail("Cannot clean project " + fTapp.getName() + '.' + MESSAGE_TAIL);
+ }
+ buildProject(project);
+ }
+
+ private long getArtifactTimeStamp(IProject project) {
+ List<IFile> files = new ArrayList<IFile>();
+ findFiles(project, getArtefactFullName(project), files);
+ if(files.size() == 0) // File not exists
+ return 0;
+ IFile artefact = files.iterator().next();
+ return artefact.getModificationStamp();
+ }
+
+ private String getArtefactFullName(IProject project) {
+ IConfiguration cfg = null;
+ try {
+ cfg = getProjectConfiguration(project);
+ } catch (CoreException e) {
+ e.printStackTrace();
+ fail("Error. " + MESSAGE_TAIL);
+ }
+ String name = cfg.getArtifactName();
+ String ext = cfg.getArtifactExtension();
+ if((null != ext) && (ext.length() > 0)) {
+ name += '.';
+ name += ext;
+ }
+ return name;
+ }
+
+
+ public void testDepLibs() {
+ buildProject(fTapp);
+ long timeStamp = getArtifactTimeStamp(fTapp);
+ if(timeStamp == 0) {
+ fail("Cannot build project " + fTapp.getName());
+ }
+ try { // To be sure that in case of build the time should be changed
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ // Do nothing
+ }
+ // Check if no build any more
+ buildProject(fTapp);
+ if(timeStamp != getArtifactTimeStamp(fTapp)) {
+ fail("Error. This time it should be nothing to build");
+ }
+ rebuildArtefact(fTlib);
+ buildProject(fTapp);
+ if(timeStamp == getArtifactTimeStamp(fTapp)) {
+ fail("Error. This time it should build application.");
+ }
+ }
+
+ public void testDepUObjs() {
+ buildProject(fTapp);
+ long timeStamp = getArtifactTimeStamp(fTapp);
+ if(timeStamp == 0) {
+ fail("Cannot build project " + fTapp.getName());
+ }
+ try { // To be sure that in case of build the time should be changed
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ // Do nothing
+ }
+ // Check if no build any more
+ buildProject(fTapp);
+ if(timeStamp != getArtifactTimeStamp(fTapp)) {
+ fail("Error. This time it should be nothing to build");
+ }
+// deleteFiles(getProjectFolder(fTobjs), "*.o", new NullProgressMonitor());
+ rebuildArtefact(fTobjs);
+ buildProject(fTapp);
+ if(timeStamp == getArtifactTimeStamp(fTapp)) {
+ fail("Error. This time it should build application.");
+ }
+ }
+} \ No newline at end of file
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/AdditionalInput.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/AdditionalInput.java
index 15fe519..89d8fed 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/AdditionalInput.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/AdditionalInput.java
@@ -11,17 +11,51 @@
*******************************************************************************/
package org.eclipse.cdt.managedbuilder.internal.core;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.cdt.core.cdtvariables.CdtVariableException;
import org.eclipse.cdt.core.settings.model.ICStorageElement;
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
import org.eclipse.cdt.internal.core.SafeStringInterner;
+import org.eclipse.cdt.managedbuilder.core.BuildException;
import org.eclipse.cdt.managedbuilder.core.IAdditionalInput;
+import org.eclipse.cdt.managedbuilder.core.IBuildObject;
+import org.eclipse.cdt.managedbuilder.core.IBuilder;
+import org.eclipse.cdt.managedbuilder.core.IConfiguration;
+import org.eclipse.cdt.managedbuilder.core.IFileInfo;
import org.eclipse.cdt.managedbuilder.core.IInputType;
import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement;
+import org.eclipse.cdt.managedbuilder.core.IOption;
+import org.eclipse.cdt.managedbuilder.core.IOutputType;
+import org.eclipse.cdt.managedbuilder.core.ITool;
+import org.eclipse.cdt.managedbuilder.core.IToolChain;
+import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
+import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
+import org.eclipse.cdt.managedbuilder.internal.macros.BuildMacroProvider;
+import org.eclipse.cdt.managedbuilder.internal.macros.IMacroContextInfo;
+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.utils.cdtvariables.CdtVariableResolver;
+import org.eclipse.cdt.utils.cdtvariables.SupplierBasedCdtVariableSubstitutor;
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
public class AdditionalInput implements IAdditionalInput {
private static final String EMPTY_STRING = new String();
+ private static final String BUILD_VARIABLE_STATIC_LIB = "ARCHIVES"; //$NON-NLS-1$
+ private static final String BUILD_VARIABLE_SHARED_LIB = "LIBRARIES"; //$NON-NLS-1$
+
+ private String[] expandedNames;
+
// Superclass
// Parent and children
private IInputType fParent;
@@ -289,8 +323,302 @@ public class AdditionalInput implements IAdditionalInput {
}
}
- public boolean needsRebuild(){
- return fRebuildState;
+ public boolean needsRebuild() {
+ // This shouldn't be called for an extension AdditionalInput
+ if (fIsExtensionAdditionalInput)
+ return false;
+ if (fRebuildState)
+ return fRebuildState;
+ if (fKind.intValue() == IAdditionalInput.KIND_ADDITIONAL_DEPENDENCY
+ || fKind.intValue() == IAdditionalInput.KIND_ADDITIONAL_INPUT_DEPENDENCY) {
+ IToolChain toolChain = getToolChain();
+ if (!toolChain.isExtensionElement()) {
+ long artifactTimeStamp = getArtifactTimeStamp(toolChain);
+ if (0 != artifactTimeStamp) {
+ String[] paths = getPaths();
+ for (int i = 0; i < paths.length; ++i) {
+ if (paths[i].length() == 0)
+ continue;
+ if (dependencyChanged(paths[i], artifactTimeStamp))
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ private long getArtifactTimeStamp(IToolChain toolChain) {
+ IBuilder builder = toolChain.getBuilder();
+ IConfiguration configuration = toolChain.getParent();
+ URI buildLocationURI = ManagedBuildManager.getBuildLocationURI(configuration, builder);
+ if (buildLocationURI != null) {
+ if (!buildLocationURI.toString().endsWith("/")) { //$NON-NLS-1$
+ // ensure that it's a directory URI
+ buildLocationURI = URI.create(buildLocationURI.toString() + "/"); //$NON-NLS-1$
+ }
+
+ String artifactName = configuration.getArtifactName();
+ String artifactExt = configuration.getArtifactExtension();
+ String artifactPref = configuration.getOutputPrefix(artifactExt);
+ if (artifactName.length() > 0) {
+ if (artifactExt.length() > 0)
+ artifactName += "." + artifactExt; //$NON-NLS-1$
+ if (artifactPref.length() > 0)
+ artifactName = artifactPref + artifactName;
+ try {
+ artifactName = ManagedBuildManager.getBuildMacroProvider().resolveValue(artifactName, "", //$NON-NLS-1$
+ " ", IBuildMacroProvider.CONTEXT_CONFIGURATION, configuration); //$NON-NLS-1$
+ } catch (BuildMacroException e) {
+ }
+
+ URI buildArtifactURI = buildLocationURI.resolve(artifactName);
+
+ try {
+ IFileStore artifact = EFS.getStore(buildArtifactURI);
+ org.eclipse.core.filesystem.IFileInfo info = (artifact == null) ? null : artifact.fetchInfo();
+ if ((info != null) && info.exists()) {
+ return info.getLastModified();
+ }
+ } catch (CoreException e) {
+ // if we can't even inquire about it, then assume it doesn't exist
+ }
+ }
+ }
+ return 0;
+ }
+
+ private boolean dependencyChanged(String sPath, long artefactTimeStamp) {
+ try {
+ IToolChain toolChain = getToolChain();
+ IConfiguration configuration = toolChain.getParent();
+ if (fIsDirty || (null == expandedNames)) {
+ if ("$(LIBS)".equals(sPath)) //$NON-NLS-1$
+ expandedNames = getDepLibs();
+ else if ("$(USER_OBJS)".equals(sPath)) //$NON-NLS-1$
+ expandedNames = getDepObjs(configuration);
+ else {
+ expandedNames = getDepFiles(sPath);
+ }
+ }
+ for (int j = 0; j < expandedNames.length; ++j) {
+ if (expandedNames[j] != null) {
+ IFileStore file = getEFSFile(expandedNames[j]);
+ org.eclipse.core.filesystem.IFileInfo info = (file == null) ? null : file.fetchInfo();
+ if ((info != null) && info.exists() && (info.getLastModified() > artefactTimeStamp)) {
+ return true;
+ }
+ }
+ }
+ } catch (Exception e) {
+ // we'll have to assume that the dependency didn't change if we couldn't get its timestamp
+ ManagedBuilderCorePlugin.log(e);
+ }
+ return false;
+ }
+
+ private IToolChain getToolChain() {
+ IBuildObject bo = fParent.getParent().getParent();
+ IToolChain tCh = null;
+ if (bo instanceof IToolChain) {
+ tCh = ((IToolChain) bo);
+ } else if (bo instanceof IFileInfo) {
+ tCh = ((ResourceConfiguration) bo).getBaseToolChain();
+ }
+ return tCh;
+ }
+
+ private String[] getDepLibs() throws CoreException, BuildException, CdtVariableException {
+ IOption[] options = fParent.getParent().getOptions();
+ String[] libNames = null;
+ List<String> libPaths = null;
+ for (int i = 0; i < options.length; ++i) {
+ int type = options[i].getValueType();
+ if (type == IOption.LIBRARIES) {
+ libNames = options[i].getLibraries();
+ } else if (type == IOption.LIBRARY_PATHS) {
+ if (null == libPaths)
+ libPaths = new ArrayList<String>();
+ libPaths.addAll(Arrays.asList(restoreLibraryPaths(options[i])));
+ }
+ }
+
+ if ((libNames != null) && (libPaths != null)) {
+ IToolChain toolChain = getToolChain();
+ for (int i = 0; i < libNames.length; ++i) {
+ URI uri = findLibrary(toolChain, libNames[i], libPaths);
+ libNames[i] = (uri == null) ? null : uri.toString();
+ }
+ return libNames;
+ }
+ return new String[0];
+ }
+
+ private String[] restoreLibraryPaths(IOption option) throws BuildException, CdtVariableException {
+ @SuppressWarnings("unchecked")
+ List<String> libPaths = (List<String>) option.getValue();
+ String[] dirs = libPaths.toArray(new String[libPaths.size()]);
+ dirs = substituteEnvVars(option, dirs);
+ return dirs;
+ }
+
+ private URI findLibrary(IToolChain toolChain, final String libName, List<String> dirs) throws CoreException {
+ final String libSO = getDynamicLibPrefix(toolChain) + libName + '.'
+ + getDynamicLibExtension(toolChain);
+ final String libA = getStaticLibPrefix(toolChain) + libName + '.' + getStaticLibExtension(toolChain);
+
+ class LibFilter {
+ public boolean accept(String name) {
+ if (equals(libA, name))
+ return true;
+ if (!startsWith(name, libSO))
+ return false;
+ if (libSO.length() == name.length())
+ return true; // we don't necessarily have a version extension
+ if (name.charAt(libSO.length()) != '.')
+ return false;
+ String ext = libName.substring(libSO.length() + 1);
+ try {
+ Integer.parseInt(ext);
+ return true;
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ }
+
+ boolean equals(String a, String b) {
+ return a.equals(b);
+ }
+
+ boolean startsWith(String string, String prefix) {
+ return string.startsWith(prefix);
+ }
+
+ }
+ class CaseInsensitiveLibFilter extends LibFilter {
+ @Override
+ boolean equals(String a, String b) {
+ return a.equalsIgnoreCase(b);
+ }
+
+ @Override
+ boolean startsWith(String string, String prefix) {
+ return string.toLowerCase().startsWith(prefix.toLowerCase());
+ }
+ }
+
+ for (Iterator<String> i = dirs.iterator(); i.hasNext();) {
+ IFileStore dir = getEFSFile(i.next());
+ LibFilter filter = dir.getFileSystem().isCaseSensitive() ? new LibFilter() : new CaseInsensitiveLibFilter();
+ for (IFileStore child : dir.childStores(EFS.NONE, null)) {
+ if (filter.accept(child.getName())) {
+ return child.toURI();
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Gets an EFS file-store for the specified path or URI, which may be a local filesystem path or may be a more abstract URI.
+ *
+ * @param pathOrURI a local filesystem path or URI
+ *
+ * @return the file store, if one could be determined
+ */
+ private static IFileStore getEFSFile(String pathOrURI) {
+ IFileStore result;
+
+ try {
+ // try it as a URI
+ result = EFS.getStore(URI.create(pathOrURI));
+ } catch (Exception e) {
+ // most likely, the path is not a URI, so assume a local file and try again
+ result = EFS.getLocalFileSystem().getStore(new Path(pathOrURI));
+ }
+
+ return result;
+ }
+
+ private String[] substituteEnvVars(IOption option, String[] paths) throws CdtVariableException {
+ BuildMacroProvider provider = (BuildMacroProvider) ManagedBuildManager.getBuildMacroProvider();
+ IMacroContextInfo info = provider.getMacroContextInfo(IBuildMacroProvider.CONTEXT_OPTION,
+ new OptionContextData(option, fParent));
+ String delimiter = ManagedBuildManager.getEnvironmentVariableProvider().getDefaultDelimiter();
+ String inexVal = " "; //$NON-NLS-1$
+ SupplierBasedCdtVariableSubstitutor subst = provider.getMacroSubstitutor(info, inexVal, delimiter);
+
+ String[] newPaths = CdtVariableResolver.resolveStringListValues(paths, subst, false);
+ for (int i = 0; i < newPaths.length; ++i) {
+ String newPath = newPaths[i];
+ int len = newPath.length();
+ if ((len > 1) && (newPath.charAt(0) == '\"') && (newPath.charAt(len - 1) == '\"'))
+ newPaths[i] = newPaths[i].substring(1, len - 1);
+ }
+ return newPaths;
+ }
+
+ private static String getStaticLibPrefix(IToolChain toolChain) {
+ IOutputType type = findOutputType(toolChain, BUILD_VARIABLE_STATIC_LIB);
+ if (null == type)
+ return "lib"; //$NON-NLS-1$
+ return type.getOutputPrefix();
+ }
+
+ private static String getStaticLibExtension(IToolChain toolChain) {
+ IOutputType type = findOutputType(toolChain, BUILD_VARIABLE_STATIC_LIB);
+ if (null == type || type.getOutputExtensionsAttribute().length == 0) {
+ return "a"; //$NON-NLS-1$
+ }
+ return type.getOutputExtensionsAttribute()[0];
+ }
+
+ private static String getDynamicLibPrefix(IToolChain toolChain) {
+ IOutputType type = findOutputType(toolChain, BUILD_VARIABLE_SHARED_LIB);
+ if (null == type)
+ return "lib"; //$NON-NLS-1$
+ return type.getOutputPrefix();
+ }
+
+ private static String getDynamicLibExtension(IToolChain toolChain) {
+ IOutputType type = findOutputType(toolChain, BUILD_VARIABLE_SHARED_LIB);
+ if (null == type || type.getOutputExtensionsAttribute().length == 0) {
+ return "so"; //$NON-NLS-1$
+ }
+ return type.getOutputExtensionsAttribute()[0];
+ }
+
+ public static IOutputType findOutputType(IToolChain toolChain, String buildVariable) {
+ // if we're determining whether to re-build an executable, then it won't have an output
+ // type for shared libraries from which we can get a filename extension or prefix.
+ // We have to scan the extension toolchain
+ toolChain = ManagedBuildManager.getExtensionToolChain(toolChain);
+ ITool[] tools = toolChain.getTools();
+ for (int i = 0; i < tools.length; ++i) {
+ IOutputType[] oTypes = tools[i].getOutputTypes();
+ for (int j = 0; j < oTypes.length; ++j) {
+ if (buildVariable.equals(oTypes[j].getBuildVariable()))
+ return oTypes[j];
+ }
+ }
+ return null;
+ }
+
+ private String[] getDepObjs(IConfiguration configuration) throws BuildException, CdtVariableException {
+ IOption[] options = fParent.getParent().getOptions();
+ String[] userObjs = null;
+ for (int i = 0; i < options.length; ++i) {
+ int type = options[i].getValueType();
+ if (type == IOption.OBJECTS) {
+ userObjs = options[i].getUserObjects();
+ return substituteEnvVars(options[i], userObjs);
+ }
+ }
+ return new String[0];
+ }
+
+ private String[] getDepFiles(String sPath) {
+ return new String[0];
}
public void setRebuildState(boolean rebuild){
diff --git a/build/org.eclipse.cdt.managedbuilder.gnu.ui/plugin.xml b/build/org.eclipse.cdt.managedbuilder.gnu.ui/plugin.xml
index ddc4c31..3fce76a 100644
--- a/build/org.eclipse.cdt.managedbuilder.gnu.ui/plugin.xml
+++ b/build/org.eclipse.cdt.managedbuilder.gnu.ui/plugin.xml
@@ -176,7 +176,7 @@
</additionalInput>
<additionalInput
paths="$(LIBS)"
- kind="additionalinput">
+ kind="additionalinputdependency">
</additionalInput>
</inputType>
<outputType
@@ -377,7 +377,7 @@
</additionalInput>
<additionalInput
paths="$(LIBS)"
- kind="additionalinput">
+ kind="additionalinputdependency">
</additionalInput>
</inputType>
<outputType
@@ -458,7 +458,7 @@
</additionalInput>
<additionalInput
paths="$(LIBS)"
- kind="additionalinput">
+ kind="additionalinputdependency">
</additionalInput>
</inputType>
<outputType
@@ -746,7 +746,7 @@
</additionalInput>
<additionalInput
paths="$(LIBS)"
- kind="additionalinput">
+ kind="additionalinputdependency">
</additionalInput>
</inputType>
<outputType
@@ -911,7 +911,7 @@
</additionalInput>
<additionalInput
paths="$(LIBS)"
- kind="additionalinput">
+ kind="additionalinputdependency">
</additionalInput>
</inputType>
<outputType