Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MSBuild script default property best practices explanation

In building an MSBuild script, I need to define a series of properties that are default but can be overridden when running the script. According to the following article, you should use a Conditional to default the property:

http://msdn.microsoft.com/en-us/library/ee240983.aspx

How Microsoft recommends:

<PropertyGroup>
    <MyProperty Condition="'$(MyProperty)' == '' ">Default Value</MyProperty>
</PropertyGroup>

However, this behaves exactly the same way:

<PropertyGroup>
    <MyProperty>Default Value Without Conditional</MyProperty>
</PropertyGroup>

So, if I have this Target and invoke it with either of the above, it has the same behavior:

<Target Name="DefaultsTest">
    <Message Text="$(MyProperty)"></Message>
</Target>

Invocation:

msbuild build.xml /t:DefaultsTest /p:MyProperty="Overridden value"

Please explain the benefits of using the Condition attribute if you are only defaulting the same property that can be overridden from the invocation?

Update:

Here is a full simple config file to demonstrate: defaults.xml

<?xml version="1.0" encoding="utf-8" ?>
<Project DefaultTargets="DefaultsTest" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <MyProperty Condition=" '$(MyProperty)' == '' ">MyProperty with Conditional</MyProperty>
        <MyOtherProperty>MyOtherProperty without Conditional</MyOtherProperty>
    </PropertyGroup>

    <Target Name="DefaultsTest">
        <Message Text="$(MyProperty)"></Message>
        <Message Text="$(MyOtherProperty)"></Message>
    </Target>
</Project>

This can be run simply as msbuild defaults.xml

or

msbuild defaults.xml /p:MyProperty="Changed Value" /p:MyOtherProperty="Changed as well"

like image 802
Keith Morris Avatar asked May 08 '14 14:05

Keith Morris


People also ask

What is the default value of importance property for message task?

Specifies the importance of the message. This parameter can have a value of high , normal or low . The default value is normal .

What are default properties?

A default property is a class or structure property that your code can access without specifying it. When calling code names a class or structure but not a property, and the context allows access to a property, Visual Basic resolves the access to that class or structure's default property if one exists.

What is MSBuild property?

Global propertiesMSBuild lets you set properties on the command line by using the -property (or -p) switch. These global property values override property values that are set in the project file. This includes environment properties, but does not include reserved properties, which cannot be changed.

What is MSBuildProjectExtensionsPath?

The default value of MSBuildProjectExtensionsPath is $(BaseIntermediateOutputPath) , obj/ . NuGet uses this mechanism to refer to build logic delivered with packages; that is, at restore time, it creates {project}.


1 Answers

You correctly noticed, that you can achieve behavior you want with unconditional assignment of property. The following project when built without /p: override on command line will produce Default Value. And when built using command msbuild myproj.proj /t:DefaultsTest /p:MyProperty=NewValue will produce NewValue.

 <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <MyProperty>Default Value</MyProperty>
    </PropertyGroup>
    <Target Name="DefaultsTest">
        <Message Text="MyProperty=$(MyProperty)"></Message>
    </Target>
</Project>

This is because any properties specified on MSBuild command line or provided as a parameter of task will be treated as Global Properties. For global properties, any assignment or modifications, either conditional or unconditional, are simply ignored -- global properties will remain constant throughout lifetime of the project execution.

The only difference in behavior between conditional assignment and unconditional will be if you use TreatAsLocalProperty attribute.

For example, consider the following project:

 <Project TreatAsLocalProperty="Prop1;Prop2" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <Prop1>Prop1 Default Value</Prop1>
        <Prop2 Condition="$(Prop2) == ''">Prop2 Default Value</Prop2>
    </PropertyGroup>
    <Target Name="DefaultsTest">
        <Message Text="Prop1=$(Prop1)"></Message>
        <Message Text="Prop2=$(Prop2)"></Message>
    </Target>
</Project>

Two properties -- Prop1 and Prop2 are both declared as local in the Project element. Prop1 is assigned unconditionally, while Prop2 is assigned using non-empty condition. Executing build command:

msbuild b.proj /t:DefaultsTest /p:Prop1=NewValue1 /p:Prop2=NewValue2

will produce output:

Prop1=Prop1 Default Value
Prop2=NewValue2

This means that in general case (if you are not absoluterly sure if property will be global or local), it is safer to use conditional assignment of the default value, because it works always.

like image 63
seva titov Avatar answered Sep 22 '22 14:09

seva titov