Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add MSBuild batched task output as item metadata

I have a list of projects in my MSBuild file:

<ItemGroup>
    <SubProject Include="**\*.csproj" />
</ItemGroup>

And now, I would like to set, on each project, its TargetPath in a metadata property for each project.

I already know how to extract the target path for each project, and put it on a separate items list:

<Target Name="ExtractTargetPaths">
    <MSBuild Projects="%(SubProject.Identity)" Targets="GetTargetPath">
        <Output TaskParameter="TargetOutputs" ItemName="SubProjectTargetPath" />
    </MSBuild>
</Target>

However, I would like to be able to access that "SubProjectTargetPath" as metadata on the SubProject items instead of having a separate list of items.

That is, instead of writing e.g. this:

<SomeTask Parameter="%(SubProjectTargetPath.Identity)" />

I would be able to write something like:

<SomeTask Parameter="%(SubProject.TargetPath)" />
like image 740
Jean Hominal Avatar asked Jul 04 '12 11:07

Jean Hominal


1 Answers

OK, I have found one solution, which is to use target batching, with a temporary property:

<ItemGroup>
    <SubProject Include="**\*.csproj" />
</ItemGroup>

<Target Name="UpdateSubProjectMetadata" Outputs="%(SubProject.Identity)">
    <!-- Retrieves the Target DLL path and puts it in the temporary property "_TempTargetPath" -->
    <MSBuild Projects="%(SubProject.Identity)" Targets="GetTargetPath">
        <Output TaskParameter="TargetOutputs" PropertyName="_TempTargetPath" />
    </MSBuild>

    <!-- Set the metadata item for TestProject to the value of the temporary property -->
    <ItemGroup>
        <SubProject Condition="'%(SubProject.Identity)' == '%(Identity)'" >
            <TargetPath>$(_TempTargetPath)</TargetPath>
        </SubProject>
    </ItemGroup>
    <!-- Clear the temporary property -->
    <PropertyGroup>
        <_TempTargetPath></_TempTargetPath>
    </PropertyGroup>
</Target>

Once that target has run, TargetPath is available on every metadata item.

Implementation note: The above code is only tested for MSBuild 4.0 - I think it works as is on MSBuild 3.5, and users of previous versions would use the <CreateItem> and <CreateProperty> tasks instead of putting <PropertyGroup> and <ItemGroup>.

like image 167
Jean Hominal Avatar answered Sep 27 '22 16:09

Jean Hominal