1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-09 18:56:02 +02:00

Fix for bug 66739 - Created a shared lib project does not set shared flag in configs. There was a gap in the ever-increasingly complex inheritance behaviour of the ToolReferences. The commands supplied by the ToolReferences were being ignored if the configuration supplied its own ToolReferences. Searching is more comprehensive now, the tool reference is creating a copy of itself more thoroughly, and the JUnit tests have been updated to reflect this.

This commit is contained in:
Sean Evoy 2004-06-23 19:21:42 +00:00
parent 3783f1b7be
commit 687d762517
7 changed files with 223 additions and 38 deletions

View file

@ -38,7 +38,7 @@
name="String in Free"
category="indy.cat.free"
valueType="string"
id="org.eclipse.cdt.core.tests.option1">
id="indy.cat.free.string">
</option>
<optionCategory
owner="indy.cat.free"
@ -50,7 +50,7 @@
name="Boolean in Chained"
category="indy.cat.chained"
valueType="boolean"
id="org.eclipse.cdt.core.tests.option2">
id="indy.cat.chained.boolean">
</option>
</tool>
<target
@ -293,7 +293,13 @@
id="test.sub.sub">
<toolReference
id="target.independent.tool">
<optionReference
defaultValue="true"
id="indy.cat.chained.boolean"/>
</toolReference>
<configuration
name="Sub Sub Config"
id="sub.sub.config"/>
</target>
<dynamicElementProvider
name="Test Target Provider"

View file

@ -45,7 +45,9 @@ import org.eclipse.cdt.managedbuilder.core.ITool;
import org.eclipse.cdt.managedbuilder.core.IToolReference;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.core.ManagedCProjectNature;
import org.eclipse.cdt.managedbuilder.internal.core.Option;
import org.eclipse.cdt.managedbuilder.internal.core.OptionReference;
import org.eclipse.cdt.managedbuilder.internal.core.ToolReference;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
@ -1052,6 +1054,24 @@ public class ManagedBuildCoreTests extends TestCase {
}
/*
* The Sub Sub target has a reference to a tool that is defined
* independently from the target itself. This is a common pattern
* for tools that are shared between many targets.
*
* The tool itself is defined as having two option categories, with
* one option in each category. To test that the reference is properly
* inheritted, the target overrides the default value of the boolean
* option.
*
* The test confirms that the basic settings are inheritted through the
* reference, and that the overridden value is used instead of the
* default. It also tests that the command can be overidden through a
* tool reference.
*
* Finally, the string option in the configuration is overridden and the
* test confirms that it contains both the overridden boolean that the
* target provides, and the overridden string that it provides.
*
* @param testSubSub
*/
private void checkSubSubTarget(ITarget target) {
@ -1068,6 +1088,7 @@ public class ManagedBuildCoreTests extends TestCase {
final String chainedOptName = "Boolean in Chained";
final String freeOptValue = "Live free or die";
final String newCmd = "Let the Wookie win";
final String stringOverride = "The future language of slaves";
// Check the inherited clean command
assertEquals("rm -yourworld", target.getCleanCommand());
@ -1079,9 +1100,9 @@ public class ManagedBuildCoreTests extends TestCase {
String[] expectedOSList = {"win32","linux","solaris"};
assertTrue(Arrays.equals(expectedOSList, target.getTargetOSList()));
// Get the 4 configurations
// Get the 5 configurations (3 from test, 1 from test sub and 1 from this)
IConfiguration[] configs = target.getConfigurations();
assertEquals(4, configs.length);
assertEquals(5, configs.length);
// Check the tools. We should have 3 (1 from each parent and the one referenced).
ITool[] tools = target.getTools();
@ -1115,7 +1136,13 @@ public class ManagedBuildCoreTests extends TestCase {
assertEquals(freeOptName, optsInCat[0].getName());
assertEquals(IOption.STRING, optsInCat[0].getValueType());
try {
assertEquals(freeOptValue, optsInCat[0].getStringValue());
// We get the option categories and options from the tool itself, but the
// tool reference will have a set of 0 to n option references that contain
// overridden settings. In this case, the string is inheritted and should
// not be reference
IOption stringOpt = toolRef.getOptionById(optsInCat[0].getId());
assertTrue(stringOpt instanceof Option);
assertEquals(freeOptValue, stringOpt.getStringValue());
} catch (BuildException e1) {
fail("Failed getting string value in subsubtarget :" + e1.getLocalizedMessage());
}
@ -1123,10 +1150,12 @@ public class ManagedBuildCoreTests extends TestCase {
// Do the same for the options in the child cat
IOption[] optsInSubCat = subCategories[0].getOptions(null);
assertEquals(1, optsInSubCat.length);
assertEquals(chainedOptName, optsInSubCat[0].getName());
assertEquals(IOption.BOOLEAN, optsInSubCat[0].getValueType());
IOption booleanRef = toolRef.getOptionById(optsInSubCat[0].getId());
assertTrue(booleanRef instanceof OptionReference);
assertEquals(chainedOptName, booleanRef.getName());
assertEquals(IOption.BOOLEAN, booleanRef.getValueType());
try {
assertFalse(optsInSubCat[0].getBooleanValue());
assertTrue(booleanRef.getBooleanValue());
} catch (BuildException e) {
fail("Failure getting boolean value in subsubtarget: " + e.getLocalizedMessage());
}
@ -1134,6 +1163,57 @@ public class ManagedBuildCoreTests extends TestCase {
// Test that the tool command can be changed through the reference
((IToolReference)toolRef).setToolCommand(newCmd);
assertEquals(toolRef.getToolCommand(), newCmd);
// Muck about with the options in the local config
IConfiguration subSubConfig = target.getConfiguration("sub.sub.config");
assertNotNull(subSubConfig);
ITool[] configTools = subSubConfig.getTools();
// This tool ref is inherited from parent, so it does not belong to the config
ITool configToolRef = configTools[2];
assertNotNull(configToolRef);
assertFalse(((ToolReference)configToolRef).ownedByConfiguration(subSubConfig));
IOption configStringOpt = configToolRef.getOptionById(optsInCat[0].getId());
assertNotNull(configStringOpt);
// Override the string option
try {
subSubConfig.setOption(configStringOpt, stringOverride);
} catch (BuildException e) {
fail("Failure setting string value in subsubconfiguration: " + e.getLocalizedMessage());
}
// Now the config should have a tool ref to the independent tool
configTools = subSubConfig.getTools();
configToolRef = configTools[2];
assertNotNull(configToolRef);
assertTrue(((ToolReference)configToolRef).ownedByConfiguration(subSubConfig));
// Test that the string option is overridden in the configuration
configStringOpt = configToolRef.getOptionById(optsInCat[0].getId());
try {
assertEquals(stringOverride, configStringOpt.getStringValue());
} catch (BuildException e) {
fail("Failure getting string value in subsubconfiguration: " + e.getLocalizedMessage());
}
// The tool should also contain the boolean option set to true
IOption configBoolOpt = configToolRef.getOptionById(optsInSubCat[0].getId());
assertNotNull(configBoolOpt);
try {
assertTrue(configBoolOpt.getBooleanValue());
} catch (BuildException e) {
fail("Failure getting boolean value in subsubconfiguration: " + e.getLocalizedMessage());
}
// Override it in config and retest
try {
subSubConfig.setOption(configBoolOpt, false);
} catch (BuildException e) {
fail("Failure setting boolean value in subsubconfiguration: " + e.getLocalizedMessage());
}
configBoolOpt = configToolRef.getOptionById(optsInSubCat[0].getId());
try {
assertFalse(configBoolOpt.getBooleanValue());
} catch (BuildException e) {
fail("Failure getting boolean value in subsubconfiguration: " + e.getLocalizedMessage());
}
}
/*

View file

@ -73,7 +73,8 @@ public interface ITool extends IBuildObject {
/**
* This is a deprecated method for retrieving an <code>IOption</code> from
* the receiver based on an ID. It is preferred that you use the newer method
* @see org.eclipse.cdt.core.build.managed.ITool#getOption(java.lang.String)
* <code>getOptionById</code>
* @see org.eclipse.cdt.core.build.managed.ITool#getOptionById(java.lang.String)
*
* @param id unique identifier of the option to search for
* @return <code>IOption</code>

View file

@ -104,9 +104,10 @@ public class Configuration extends BuildObject implements IConfiguration {
// Check that the tool and the project match
IProject project = (IProject) target.getOwner();
// Get the tool references from the parent
List parentToolRefs = ((Configuration)parentConfig).getLocalToolReferences();
Iterator iter = parentToolRefs.listIterator();
// Get the tool references from the target and parent
List allToolRefs = new Vector(target.getLocalToolReferences());
allToolRefs.addAll(((Configuration)parentConfig).getLocalToolReferences());
Iterator iter = allToolRefs.listIterator();
while (iter.hasNext()) {
ToolReference toolRef = (ToolReference)iter.next();
@ -231,35 +232,60 @@ public class Configuration extends BuildObject implements IConfiguration {
* @return
*/
private OptionReference createOptionReference(IOption option) {
ToolReference searchRef = null;
ToolReference answer = null;
// The option may already be a reference created to hold user settings
if (option instanceof OptionReference) {
// The option reference belongs to an existing tool reference
OptionReference optionRef = (OptionReference)option;
ToolReference toolRef = optionRef.getToolReference();
searchRef = optionRef.getToolReference();
// That tool reference may belong to a target or to the configuration
if (toolRef.ownedByConfiguration(this))
if (searchRef.ownedByConfiguration(this))
return optionRef;
else {
// Make a copy so the settings can be saved
toolRef = new ToolReference(this, toolRef);
return toolRef.createOptionReference(option);
// All this means is that the tool ref does not belong to the receiver.
// The receiver may also have a reference to the tool
if ((answer = findLocalReference(searchRef)) == null) {
// Otherwise, create one and save the option setting in it
answer = new ToolReference(this, searchRef);
}
return answer.createOptionReference(option);
}
} else {
// Find out if a tool reference already exists
ToolReference toolRef = (ToolReference) getToolReference(option.getTool());
if (toolRef == null) {
toolRef = new ToolReference(this, option.getTool());
searchRef = (ToolReference) getToolReference(option.getTool());
if (searchRef == null) {
answer = new ToolReference(this, option.getTool());
} else {
// The reference may belong to the target
if (!toolRef.ownedByConfiguration(this)) {
toolRef = new ToolReference(this, toolRef);
if (!searchRef.ownedByConfiguration(this)) {
answer = new ToolReference(this, searchRef);
} else {
answer = searchRef;
}
}
return answer.createOptionReference(option);
}
}
return toolRef.createOptionReference(option);
/* (non-Javadoc)
* @param toolRef
* @return
*/
private ToolReference findLocalReference(ToolReference toolRef) {
Iterator iter = getLocalToolReferences().iterator();
while (iter.hasNext()) {
ToolReference ref = (ToolReference)iter.next();
if (toolRef.getTool().equals(ref.getTool())) {
return ref;
}
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.core.IConfiguration#getFilteredTools(org.eclipse.core.resources.IProject)
*/

View file

@ -502,7 +502,7 @@ public class Target extends BuildObject implements ITarget {
*
* @return List
*/
private List getLocalToolReferences() {
protected List getLocalToolReferences() {
if (toolReferences == null) {
toolReferences = new ArrayList();
}

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.managedbuilder.core.IOptionCategory;
import org.eclipse.cdt.managedbuilder.core.ITool;
import org.eclipse.cdt.managedbuilder.core.IToolReference;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@ -149,15 +150,19 @@ public class ToolReference implements IToolReference {
* Created a tool reference on the fly based on an existing tool or tool reference.
*
* @param owner The <code>BuildObject</code> the receiver will be added to.
* @param parent The <code>ITool</code>tool the reference will be based on.
* @param tool The <code>ITool</code>tool the reference will be based on.
*/
public ToolReference(BuildObject owner, ITool parent) {
this.parent = parent;
public ToolReference(BuildObject owner, ITool tool) {
this.owner = owner;
command = parent.getToolCommand();
outputFlag = parent.getOutputFlag();
outputPrefix = parent.getOutputPrefix();
String[] extensions = parent.getOutputExtensions();
if (tool instanceof ToolReference) {
parent = ((ToolReference)tool).getTool();
} else {
parent = tool;
}
command = tool.getToolCommand();
outputFlag = tool.getOutputFlag();
outputPrefix = tool.getOutputPrefix();
String[] extensions = tool.getOutputExtensions();
outputExtensions = new String();
if (extensions != null) {
for (int index = 0; index < extensions.length; ++index) {
@ -169,6 +174,34 @@ public class ToolReference implements IToolReference {
}
}
// Create a copy of the option references of the parent in the receiver
if (tool instanceof ToolReference) {
List parentRefs = ((ToolReference)tool).getOptionReferenceList();
Iterator iter = parentRefs.iterator();
while (iter.hasNext()) {
IOption parent = (IOption)iter.next();
OptionReference clone = createOptionReference(parent);
try {
switch (parent.getValueType()) {
case IOption.BOOLEAN:
clone.setValue(parent.getBooleanValue());
break;
case IOption.STRING:
clone.setValue(parent.getStringValue());
case IOption.ENUMERATED:
clone.setValue(parent.getSelectedEnum());
break;
default:
clone.setValue(parent.getStringListValue());
break;
}
} catch (BuildException e) {
ManagedBuilderCorePlugin.log(e);
continue;
}
}
}
if (owner instanceof Configuration) {
((Configuration)owner).addToolReference(this);
} else if (owner instanceof Target) {
@ -250,7 +283,14 @@ public class ToolReference implements IToolReference {
public OptionReference createOptionReference(IOption option) {
// Check if the option reference already exists
OptionReference ref = getOptionReference(option);
if (ref == null) {
// It is possible that the search will return an option reference
// that is supplied by another element of the build model, not the caller.
// For example, if the search is starated by a configuration and the target
// the caller belongs to has an option reference for the option, it
// will be returned. While this is correct behaviour for a search, the
// caller will need to create a clone for itself, so make sure the tool
// reference of the search result is owned by the caller
if (ref == null || !ref.getToolReference().owner.equals(this.owner)) {
ref = new OptionReference(this, option);
}
return ref;
@ -504,7 +544,6 @@ public class ToolReference implements IToolReference {
public List getOptionReferenceList() {
if (optionReferences == null) {
optionReferences = new ArrayList();
optionReferences.clear();
}
return optionReferences;
}

View file

@ -222,7 +222,7 @@
<option
name="%Option.Posix.Linker.Defname"
category="gnu.c.link.category.shared"
command="-Wl,--output-def,"
command="-Wl,--output-def="
id="gnu.c.link.option.defname"
valueType="string">
</option>
@ -307,7 +307,7 @@
<option
name="%Option.Posix.Linker.XLinker"
category="gnu.cpp.link.category.other"
command="-Xlinker,"
command="-Xlinker "
valueType="stringList"
id="gnu.cpp.link.option.other">
</option>
@ -348,7 +348,7 @@
<option
name="%Option.Posix.Linker.Defname"
category="gnu.cpp.link.category.shared"
command="-Wl,--output-def,"
command="-Wl,--output-def="
valueType="string"
id="gnu.cpp.link.option.defname">
</option>
@ -438,6 +438,27 @@
name="%Option.Posix.UndefSym"
id="gnu.windres.option.preprocessor.undefined.symbols"/>
</tool-->
<!--tool
command="as"
sources="s,S"
outputs="o"
name="%ToolName.assembler.gnu"
outputFlag="-o"
id="cdt.managedbuild.tool.gnu.assembler"
natureFilter="both">
<optionCategory
owner="cdt.managedbuild.tool.gnu.assembler"
name="%OptionCategory.General"
id="gnu.asm.category.general">
</optionCategory>
<option
name="%Option.Posix.Assembler.Flags"
category="gnu.asm.category.general"
valueType="string"
id="gnu.both.asm.option.flags">
</option>
<tool/-->
<target
name="%TargetName.gnu"
id="cdt.managedbuild.target.gnu"
@ -1047,11 +1068,17 @@
outputs="so"
outputPrefix="lib"
id="cdt.managedbuild.tool.gnu.c.linker">
<optionReference
defaultValue="true"
id="gnu.c.link.option.shared"/>
</toolReference>
<toolReference
outputs="so"
outputPrefix="lib"
id="cdt.managedbuild.tool.gnu.cpp.linker">
<optionReference
defaultValue="true"
id="gnu.cpp.link.option.shared"/>
</toolReference>
</target>
<target
@ -1261,10 +1288,16 @@
<toolReference
outputs="dll,a.dll"
id="cdt.managedbuild.tool.gnu.c.linker">
<optionReference
defaultValue="true"
id="gnu.c.link.option.shared"/>
</toolReference>
<toolReference
outputs="dll,a.dll"
id="cdt.managedbuild.tool.gnu.cpp.linker">
<optionReference
defaultValue="true"
id="gnu.cpp.link.option.shared"/>
</toolReference>
</target>
<target