Aug 26, 2010

property and item in msbuild

In msbuild, there are two way to save variable information, they are property and item. Here is an example how to define properties and items.


<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
  </PropertyGroup>
  <!--reference items-->
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core">
      <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
    <Reference Include="System.Xml.Linq">
      <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
    <Reference Include="System.Data.DataSetExtensions">
      <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
  </ItemGroup>


 <PropertyGroup>
   <Pfile>Program.cs;Msbuild.xml</Pfile>
 </PropertyGroup>


But they have different usage. Normally property defines a single variable, if you redefine it, the old value will be overwritten, but Property can be also used as item list, if you want. For Item, it is a list, so you can define an item multiple times, each definition will add one item into the the list.
You can also pass property from the msbuild command line, like the following


MSBuild MyApp.csproj /t:Clean
                     /p:Configuration=Debug;TargetFrameworkVersion=v3.5

It is also different in the way to reference property and items. Here is an example how they are referenced.




 <Message Text="Pfile:@(MyFile->'%(FullPath)')" />

<!--Referencing a property -->
<Message Text="SchemaVersion: $(SchemaVersion)" />

<!-- Referenceing an item's metadata FullPath
 <Message Text="MyFile.FullPath: @(MyFile->'%(FullPath)')" />

<!--Referencing an item -->
 <Message Text="Reference Items: @(Reference)" />

<!--Referencing an item's medata data -->
 <Message Text="Reference Items: @(Reference->'%(RequiredTargetFramework)')" />





We can use three wildcard elements(?, *, **) to defined items, for example


<ItemGroup>
<MyFile Include="Program.cs;Msbuild.xml" />
<MyFile Include="*.doc" />
<MyFile Include="src\**\*.doc" />
<MyFile Include="**\*.cs" />
</ItemGroup>

After an property is defined, it can be also referenced in a new definition.


<ItemGroup> <AppConfigFileDestination Include="$(OutDir)$(TargetFileName).config"/>
</ItemGroup>

There are some special property and item medtadata. For property we call it reserved property, for more information see http://msdn.microsoft.com/en-us/library/ms164309.aspx. For item, we call it well-known item metadata, for more information see http://msdn.microsoft.com/en-us/library/ms164313.aspx


The "$" can also work with enviroment variables.


<Target Name="PrintSystemPath"> <Message Text="Path: $(Path)"/>
</Target>