From a3dd98987aac6bbe923499647d75c6e1f135f654 Mon Sep 17 00:00:00 2001 From: Christian W. Damus Date: Mon, 21 Nov 2011 21:56:38 -0500 Subject: Bug 210248 - [Internal Builder]does not rebuild a dependent project in case of a reference library project change Conflicts: build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/AdditionalInput.java --- .../resources/depLibsProjects/tapp.zip | Bin 0 -> 4514 bytes .../resources/depLibsProjects/tlib.zip | Bin 0 -> 3091 bytes .../resources/depLibsProjects/tobjs.zip | Bin 0 -> 3603 bytes .../tests/suite/AllManagedBuildTests.java | 2 + .../tests/ManagedBuildDependencyLibsTests.java | 285 ++++++++++++++++++ .../internal/core/AdditionalInput.java | 332 ++++++++++++++++++++- .../plugin.xml | 10 +- 7 files changed, 622 insertions(+), 7 deletions(-) create mode 100644 build/org.eclipse.cdt.managedbuilder.core.tests/resources/depLibsProjects/tapp.zip create mode 100644 build/org.eclipse.cdt.managedbuilder.core.tests/resources/depLibsProjects/tlib.zip create mode 100644 build/org.eclipse.cdt.managedbuilder.core.tests/resources/depLibsProjects/tobjs.zip create mode 100644 build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildDependencyLibsTests.java (limited to 'build') 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 00000000000..56f88881c1a Binary files /dev/null and b/build/org.eclipse.cdt.managedbuilder.core.tests/resources/depLibsProjects/tapp.zip 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 00000000000..2167f3f9024 Binary files /dev/null and b/build/org.eclipse.cdt.managedbuilder.core.tests/resources/depLibsProjects/tlib.zip 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 00000000000..3fe31c0ee4c Binary files /dev/null and b/build/org.eclipse.cdt.managedbuilder.core.tests/resources/depLibsProjects/tobjs.zip 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 65fdaadca1d..d90c1e4adde 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 00000000000..05b0320ddec --- /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 files = new ArrayList(); + findFiles(dir, pattern, files); + for(Iterator 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 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 files = new ArrayList(); + 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 b0ba81b5e2c..01c05fd9479 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; @@ -295,9 +329,303 @@ public class AdditionalInput implements IAdditionalInput { fResolved = true; } } + + 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 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(); + 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 libPaths = (List) 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 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 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]; + } - public boolean needsRebuild(){ - return fRebuildState; + 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 ddc4c317689..3fce76a186d 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 @@ + kind="additionalinputdependency"> + kind="additionalinputdependency"> + kind="additionalinputdependency"> + kind="additionalinputdependency"> + kind="additionalinputdependency">