Properties and AdditionalProperties metadata for items used in MSBuild task's
Greetings MSBuilders!
Passing properties to projects specifically when you want to pass different sets of properties to different projects listed in the same item has always been challenging. To achieve this is Visual Studio 2005 you would have to break the item according to the properties you wanted to pass it or use batching techniques to batch the MSBuild task and provide different properties to projects based on condition or other proprietary method.
To ease this problem, in Orcas MSBuild we have introduced 2 new reserved metadata “Properties” and “AdditionalProperties” on items which will be used in the Projects attribute of the MSBuild task. This new metadata is only applicable to items passed in the Projects attribute of the MSBuild task. The purpose of this is to provide our customers a flexible way to pass different Properties for different projects being built using the MSBuild task. If you use the Properties attribute of the MSBuild task then it will be applied to all the projects being built using the MSBuild task unless you batch the MSBuild task and conditionally provide different properties for each project in the item list
Properties metadata
For instance if you are building multiple solution files using the MSBuild task where you want certain solution files to be built using the Release configuration and other using the Debug configuration, with 2.0 MSBuild you will need to have multiple instances of MSBuild task where each will build certain sets of project with Release configuration and the other with Debug configuration. Your project file would look similar to the following
(… represents additional solution files)
a.proj
<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" >
<Target Name=”Build”>
<MSBuild Projects=”a1.sln…” Properties=”Configuration=Debug” />
<MSBuild Projects=”a2.sln” Properties=”Configuration=Release” />
</Target>
</Project>
By using the Properties metadata you can simplify the above to use a single MSBuild task by writing the project file as following:
a.proj
<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" >
<ItemGroup>
<ProjectToBuild Include=”a1.sln…”>
<Properties>Configuration=Debug</ Properties >
</ProjectToBuild>
<ProjectToBuild Include=”a2.sln”>
< Properties > Configuration=Release</ Properties >
</ProjectToBuild>
</ItemGroup>
<Target Name=”Build”>
<MSBuild Projects=”@(ProjectToBuild)” />
</Target>
</Project>
OR
<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" >
<ItemGroup>
<ProjectToBuild Include=”a1.sln…” />
<ProjectToBuild Include=”a2.sln”>
< Properties > Configuration=Release</ Properties >
</ProjectToBuild>
</ItemGroup>
<Target Name=”Build”>
<MSBuild Projects=”@(ProjectToBuild)” Properties=”Configuration=Debug”/>
</Target>
</Project>
AdditionalProperties metadata
For instance if you are building multiple solution files using the MSBuild task where you want to build all the solution in Release configuration and some with x86 architecture and some with ia64 architecture, with 2.0 MSBuild you will need to have multiple instances of MSBuild task where each will build certain sets of project with Release configuration and x86 Architecture and the other with Release configuration and ia64 architectre. Your project file would look similar to the following
(… represents additional solution files)
a.proj
<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" >
<Target Name=”Build”>
<MSBuild Projects=”a1.sln…” Properties=”Configuration=Release; Architecture=x86” />
<MSBuild Projects=”a2.sln” Properties=”Configuration=Release; Architecture=ia64” />
</Target>
</Project>
By using the AdditionalProperties metadata you can simplify the above to use a single MSBuild task by writing the project file as following:
a.proj
<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" >
<ItemGroup>
<ProjectToBuild Include=”a1.sln…”>
<AdditionalProperties> Architecture=x86</ AdditionalProperties >
</ProjectToBuild>
<ProjectToBuild Include=”a2.sln”>
< AdditionalProperties > Architecture=ia64</ AdditionalProperties >
</ProjectToBuild>
</ItemGroup>
<Target Name=”Build”>
<MSBuild Projects=”@(ProjectToBuild)” Properties=”Configuration=Release” />
</Target>
</Project>
One of the benefit we get from these new sets of metadata is to be able to consolidate all projects into a single MSBuild task invocation and not have to do any batching or conditional MSBuild tasks. In doing so it also allows us to parallelize all the projects listed (contained in an item) in the Projects attribute if “BuildInParallel=true” attribute is present in the MSBuild task as we can only parallelize projects within a single invocation of MSBuild task. For additional details on build parallelization you can check out the blog post: Building Projects in parallel.
[ Author: Jay Shrestha, MSBuild Software Engineer ]
Comments
Anonymous
August 28, 2007
This is a great feature, but will it only apply to the projects specified in the MSBuild task? The problem I always have is trying to set specific properties for an individual project within a solution I'm compiling with the MSBuild task. (Or getting out the list of the output files for a specific project, for that matter).Anonymous
September 06, 2007
This only applies to projects specified in the MSBuild task. Eventually solutions are converted to msbuild project file before processing them but I cannot think of a way where we can specify this in solution files. As forbeing able to get a list of the output files for a specific project, you can use the target's Output attribute. For instance if you output the output of the compile target then you can use TargetOutputs property of the msbuild task to get that output. If you need an example please let me know and I can help out. Jay Shrestha (Jaysh@microsoft.com)Anonymous
November 11, 2007
Earlier this week, I spent some quality time porting a moderately complicated build over to MSBUILD 3.5,