Property overwrite behaviour
Posted
by jeremyj
on Geeks with Blogs
See other posts from Geeks with Blogs
or by jeremyj
Published on Wed, 22 Aug 2012 14:06:21 GMT
Indexed on
2012/08/27
21:40 UTC
Read the original article
Hit count: 229
Filed under:
I thought it worth sharing about property overwrite behaviour because i found it confusing at first in the hope of preventing some learning pain for the uninitiated with MSBuild :-)
The confusion for me came because of the redundancy of using a Condition statement in a _project_ level property to test that a property has not been previously set. What i mean is that the following two statements are always identical in behaviour, regardless if the property has been supplied on the command line -
<PropertyGroup>
<PropA Condition=" '$(PropA)' == '' ">PropA set at project level</PropA>
</PropertyGroup>
has the same behaviour regardless of command line override as -
<PropertyGroup>
<PropA>PropA set at project level</PropA>
</PropertyGroup>
i.e. the two above property declarations have the same result whether the property is overridden on the command line or not.
To prove this experiment with the following .proj file -
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" >
<PropertyGroup>
<PropA Condition=" '$(PropA)' == '' ">PropA set at project level</PropA>
</PropertyGroup>
<Target Name="Target1">
<Message Text="PropA: $(PropA)"/>
</Target>
<Target Name="Target2">
<PropertyGroup>
<PropA>PropA set in Target2</PropA>
</PropertyGroup>
<Message Text="PropA: $(PropA)"/>
</Target>
<Target Name="Target3">
<PropertyGroup>
<PropA Condition=" '$(PropA)' == '' ">PropA set in Target3</PropA>
</PropertyGroup>
<Message Text="PropA: $(PropA)"/>
</Target>
<Target Name="Target4">
<PropertyGroup>
<PropA Condition=" '$(PropA)' != '' ">PropA set in Target4</PropA>
</PropertyGroup>
<Message Text="PropA: $(PropA)"/>
</Target>
</Project>
Try invoking it using both of the following invocations and observe its output -
1)
>msbuild blog.proj /t:Target1;Target2;Target3;Target4
2)
>msbuild blog.proj /t:Target1;Target2;Target3;Target4 "/p:PropA=PropA set on command line"
Then try those two invocations with the following three variations of specifying PropA at the project level -
1)
<PropertyGroup>
<PropA Condition=" '$(PropA)' == '' ">PropA set at project level</PropA>
</PropertyGroup>
2)
<PropertyGroup>
<PropA>PropA set at project level</PropA>
</PropertyGroup>
3)
<PropertyGroup>
<PropA Condition=" '$(PropA)' != '' ">PropA set at project level</PropA>
</PropertyGroup>
The confusion for me came because of the redundancy of using a Condition statement in a _project_ level property to test that a property has not been previously set. What i mean is that the following two statements are always identical in behaviour, regardless if the property has been supplied on the command line -
<PropertyGroup>
<PropA Condition=" '$(PropA)' == '' ">PropA set at project level</PropA>
</PropertyGroup>
has the same behaviour regardless of command line override as -
<PropertyGroup>
<PropA>PropA set at project level</PropA>
</PropertyGroup>
i.e. the two above property declarations have the same result whether the property is overridden on the command line or not.
To prove this experiment with the following .proj file -
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" >
<PropertyGroup>
<PropA Condition=" '$(PropA)' == '' ">PropA set at project level</PropA>
</PropertyGroup>
<Target Name="Target1">
<Message Text="PropA: $(PropA)"/>
</Target>
<Target Name="Target2">
<PropertyGroup>
<PropA>PropA set in Target2</PropA>
</PropertyGroup>
<Message Text="PropA: $(PropA)"/>
</Target>
<Target Name="Target3">
<PropertyGroup>
<PropA Condition=" '$(PropA)' == '' ">PropA set in Target3</PropA>
</PropertyGroup>
<Message Text="PropA: $(PropA)"/>
</Target>
<Target Name="Target4">
<PropertyGroup>
<PropA Condition=" '$(PropA)' != '' ">PropA set in Target4</PropA>
</PropertyGroup>
<Message Text="PropA: $(PropA)"/>
</Target>
</Project>
Try invoking it using both of the following invocations and observe its output -
1)
>msbuild blog.proj /t:Target1;Target2;Target3;Target4
2)
>msbuild blog.proj /t:Target1;Target2;Target3;Target4 "/p:PropA=PropA set on command line"
Then try those two invocations with the following three variations of specifying PropA at the project level -
1)
<PropertyGroup>
<PropA Condition=" '$(PropA)' == '' ">PropA set at project level</PropA>
</PropertyGroup>
2)
<PropertyGroup>
<PropA>PropA set at project level</PropA>
</PropertyGroup>
3)
<PropertyGroup>
<PropA Condition=" '$(PropA)' != '' ">PropA set at project level</PropA>
</PropertyGroup>
© Geeks with Blogs or respective owner