/p property values are immutable - (sort of)....
Hello there - sorry for the long absence, but we're back and hopefully I'll keep this going again.
So there was a recent forum post about how property values that are specified from the command line are immutable - i.e. it is not straightforward to change them from within the project file. Well, this is mostly true, but there are exceptions.
Let's take an example:
If I've got a property in my project file defined like this,
<PropertyGroup>
<Configuration>Debug</Configuration>
</PropertyGroup>
then, calling msbuild with /p:Configuration=Release will override this value (or alternatively set the value if it is not defined) for all projects that are being built. Properties that we pass in with a /p switch on the command line are known as "Global Properties" and so it will flow down to all projects that are being built - so if you were building a solution file, all projects will get the overridden value of this property.
Now, let's say that you have this defined in your project file:
<PropertyGroup>
<AppPath Condition=" '$(AppPath)' == '' ">bin\debug\</AppPath>
<AppPath Condition=" !HasTrailingSlash('$(AppPath)') ">$(AppPath)\</AppPath>
</PropertyGroup>
What I am doing here is that I am defining a default value for AppPath property if AppPath is not defined. Additionally, I want to set it up so that if someone has specified an AppPath property, then if it does not already have a trailing slash, I'd like to add it. Looks reasonable, correct?
Actually this will not work as you expect - and is something to watch out for. What happens when you specify something with a /p:AppPath=blah\ is that all in-project property definitions for AppPath are ignored (or essentially overridden), and so none of the in-project property definitions take effect - even the ones with the condition. This makes sense if you think about it because otherwise what exactly are we supposed to override? Would that be the first definition of the property? Or should we override only those values of the property that are checking against an empty value? There isn't a clear answer. We override all property definitions and what is passed in is the effective value.
Fortunately, there is a way around this if it causes you grief - but it isn't declarative like PropertyGroup. You have to use the CreateProperty task inside a target where you intend to process the property, like so:
<CreateProperty Value="$(AppPath)\" Condition=" !HasTrailingSlash('$(AppPath)') ">
<Output TaskParameter="Value" PropertyName="AppPath" />
</CreateProperty>
Alternatively (and perhaps as a better approach), you can use a property name like AppPath as the public property you expect to override from th command line, but filter it out into a different property inside your targets that you then use for doing the actual work - like this:
<PropertyGroup>
<_validatedAppPath>$(AppPath)</_validatedAppPath>
<_validatedAppPath Condition=" '$(_validatedAppPath)' == '' ">bin\debug\</_validatedAppPath>
<_validatedAppPath Condition=" !HasTrailingSlash('$(_validatedAppPath)') ">$(_validatedAppPath)\</_validatedAppPath>
</PropertyGroup>
In this case, you validate the /p value and store it in an internal property that is validated, and never directly overridden from the command line.
Hope this helps, and clears some confusion on "strange behavior" if you ever encountered it.
[ Author: Faisal Mohamood ]
Comments
Anonymous
October 05, 2006
The comment has been removedAnonymous
October 05, 2006
Is the "HasTrailingSlash" a new function? I don't see it documented. The only conditon function that is documented is Exists. Having some more functions would be good. Being able to write and inject our own custom functions into conditions would be even better.Anonymous
October 06, 2006
Hi Keith - HasTrailingSlash is not new, and is used quite extensively in Microsoft.common.targets. Sorry that you weren't able to find it in the documentation like "Exists". Yes, we are thinking of more functions, as well as user defined functions. Faisal Mohamood (MSFT)Anonymous
October 06, 2006
Hi James - you make a valid point, and the NAnt approach does make sense. We expect our property / item syntax to get more refined over time as we add features like scoping and visibility to properties and items. Faisal Mohamood (MSFT)Anonymous
June 06, 2007
[url=http://artmam.net/Dir-Chicken_Recipe.htm]fried chicken recipe[/url] An all-time favorite steps out on a world tour of flavors * Chicken salad--once a plain Jane sandwich stuffer--has enormous potential as a sophisticated ...Anonymous
June 07, 2007
A common complaint with Team Build v1 was that it ignored the output paths specified for individual projects