mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Merge remote-tracking branch 'cdt/master' into sd90
This commit is contained in:
commit
99b341c407
6 changed files with 634 additions and 2 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -27,6 +27,7 @@ import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildCoreTests;
|
||||||
import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildCoreTests20;
|
import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildCoreTests20;
|
||||||
import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildCoreTests_SharedToolOptions;
|
import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildCoreTests_SharedToolOptions;
|
||||||
import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildDependencyCalculatorTests;
|
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.ManagedBuildEnvironmentTests;
|
||||||
import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildMacrosTests;
|
import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildMacrosTests;
|
||||||
import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildTCSupportedTest;
|
import org.eclipse.cdt.managedbuilder.core.tests.ManagedBuildTCSupportedTest;
|
||||||
|
@ -63,6 +64,7 @@ public class AllManagedBuildTests {
|
||||||
suite.addTestSuite(GCCBuiltinSpecsDetectorTest.class);
|
suite.addTestSuite(GCCBuiltinSpecsDetectorTest.class);
|
||||||
|
|
||||||
// managedbuilder.core.tests
|
// managedbuilder.core.tests
|
||||||
|
suite.addTest(ManagedBuildDependencyLibsTests.suite());
|
||||||
suite.addTest(ManagedBuildCoreTests20.suite());
|
suite.addTest(ManagedBuildCoreTests20.suite());
|
||||||
suite.addTest(ManagedBuildCoreTests.suite());
|
suite.addTest(ManagedBuildCoreTests.suite());
|
||||||
suite.addTest(ManagedProjectUpdateTests.suite());
|
suite.addTest(ManagedProjectUpdateTests.suite());
|
||||||
|
|
|
@ -0,0 +1,294 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2011 QNX Software Systems 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:
|
||||||
|
* QNX Software Systems - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,17 +11,51 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.managedbuilder.internal.core;
|
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.ICStorageElement;
|
||||||
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
|
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
|
||||||
import org.eclipse.cdt.internal.core.SafeStringInterner;
|
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.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.IInputType;
|
||||||
import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement;
|
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 {
|
public class AdditionalInput implements IAdditionalInput {
|
||||||
|
|
||||||
private static final String EMPTY_STRING = new String();
|
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
|
// Superclass
|
||||||
// Parent and children
|
// Parent and children
|
||||||
private IInputType fParent;
|
private IInputType fParent;
|
||||||
|
@ -295,9 +329,311 @@ public class AdditionalInput implements IAdditionalInput {
|
||||||
fResolved = true;
|
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
|
||||||
|
|| isLibrariesInput()) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean needsRebuild(){
|
private boolean isLibrariesInput() {
|
||||||
return fRebuildState;
|
// libraries are of the "additionalinput" kind, not "additionalinputdependency" because otherwise the
|
||||||
|
// external make builder would generate makefiles with $(LIBS) in the dependency list, resulting in
|
||||||
|
// failure to build dependency -lxyz etc.
|
||||||
|
return (fKind.intValue() == IAdditionalInput.KIND_ADDITIONAL_INPUT && Arrays.asList(getPaths()).contains("$(LIBS)")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
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){
|
public void setRebuildState(boolean rebuild){
|
||||||
|
|
Loading…
Add table
Reference in a new issue