Stadub Dima
Stadub Dima

Reputation: 858

MSBuild batch task output

I have several solutions (plugins) for a project. For each solution there is a defined range of metadata:

<ItemGroup>
    <Plugins Include="Plugin1\Plugin1.sln">
        <Disabled>false</Disabled>
        <ProjectDirectory>plugin1\</ProjectDirectory>
        <ProjectName>Plugin1</ProjectName>
    </Plugins>
    <Plugins Include="Plugin2\Plugin2.sln">
        <Disabled>true</Disabled>
        <ProjectDirectory>plugin2\</ProjectDirectory>
        <ProjectName>Plugin2</ProjectName>
    </Plugins>
    <Plugins Include="Plugin3\Plugin3.sln">
        <Disabled>false</Disabled>
        <ProjectDirectory>plugin3\</ProjectDirectory>
        <ProjectName>Plugin3</ProjectName>
    </Plugins>
</ItemGroup>

I need to build not Disabled plugins by running its own build script and add the result directory to Plugins metadata for subsequent processing (for example: Copy each plugin build output to its own folder).

But I can't find a way to concatenate it.

Below is my target:

<Target Name="BuildPlugin" Inputs="%(Plugins.Identity)" Outputs="%(Plugins.Identity -> %(PluginOutput.Identity))" Returns="%(PluginOutput.Identity)">
    <MSBuild
        Condition="!%(Disabled)"
        Projects='%(ProjectDirectory)BuildProject.target'
        Targets="Clean;Build;" >

            <Output ItemName="PluginOutput" TaskParameter="TargetOutputs"/>
    </MSBuild>

    <ItemGroup>
        <Plugins Condition="%(ProjectName)=%(Plugins.ProjectName)">
            <PluginOutput>%(PluginOutput.Identity)</PluginOutput>
        </Plugins>
    </ItemGroup>

    <Message Text="%(Plugins.ProjectName) %(PluginOutput.Identity)"  Condition="%(Plugins.Disabled)" />
</Target>

BuildProject.target returns output directories (Ex:Plugin1\Plugin1\bin\Release\)

In this case buuilding fails with next errors:

error MSB4096: item list "PluginOutput" does not define a value for metadata "ProjectName". In order to use this metadata, either qualify it by specifying %(PluginOutput.ProjectName), or ensure that all items in this list define a value for this metadata.

error MSB4113: Specified condition "%(Plugins.Disabled)" evaluates to "" instead of a boolean.

But if remove ItemGroup and condition for Message task

<Target Name="BuildPlugin" Inputs="%(Plugins.Identity)" Outputs="%(Plugins.Identity -> %(PluginOutput.Identity))" Returns="%(PluginOutput.Identity)">
    <MSBuild
        Condition="!%(Disabled)"
        Projects='%(ProjectDirectory)BuildProject.target'
        Targets="Clean;Build;" >

            <Output ItemName="PluginOutput" TaskParameter="TargetOutputs"/>
    </MSBuild>

    <Message Text="%(Plugins.ProjectName) %(PluginOutput.Identity)"  />
</Target>

seems msbuild correctly batches plugins. BuildPlugin target output produced by Message task is:

 BuildPlugin:
   Plugin1
     Plugin1\Plugin1\bin\Release\
 BuildPlugin:
   Plugin2
 BuildPlugin:
   Plugin3
     Plugin3\Plugin3\bin\Release

But in this case I don't have any ability to filter disabled plugins and add plugins output folder to metadata.

Any ideas?

Upvotes: 1

Views: 1022

Answers (2)

Hamid Shahid
Hamid Shahid

Reputation: 4616

The following should work

<Target Name="BuildPlugin" Outputs="%(Plugins.Identity -> %(PluginOutput.Identity))" Returns="%(PluginOutput.Identity)">
    <MSBuild 
        Condition="!%(Plugins.Disabled)"
        Projects='%(Plugins.ProjectDirectory)BuildProject.target'
        Targets="Clean;Build;" >
            <Output ItemName="PluginOutput" TaskParameter="TargetOutputs"/>
    </MSBuild>


    <Message Text="%(Plugins.ProjectName) %(PluginOutput.Identity)" Condition="!%(Plugins.Disabled)"/>
</Target>

Upvotes: 1

MikeR
MikeR

Reputation: 3075

I couldn't test all steps, because of missing BuildProject.target, but this should work:

<Target  Name="BuildPlugin"
     Inputs="%(Plugins.Identity)"
     Outputs="%(Plugins.Identity)\dummy.txt"
     Returns="%(PluginOutput.Identity)">

 <PropertyGroup> <!-- transform Metadata to Properties -->
   <ProjectName>%(Plugins.ProjectName)</ProjectName>
   <PluginDisabled>%(Plugins.Disabled)</PluginDisabled>
 </PropertyGroup>

 <MSBuild
     Condition="'$(PluginDisabled)' != 'true'"
     Projects='%(Plugins.ProjectDirectory)BuildProject.target'
     Targets="Clean;Build;" >
   <Output ItemName="PluginOutput" TaskParameter="TargetOutputs"/>
 </MSBuild>

 <ItemGroup>
    <!-- batching 2 ItemGroups in one task is usually not working or creates side effects-->
   <Plugins Condition="'%(PluginOutput.ProjectName)' == '$(ProjectName)'">
     <PluginOutput>%(PluginOutput.Identity)</PluginOutput>
   </Plugins>
 </ItemGroup>

   <!-- batching 2 ItemGroups in one task is usually not working or creates side effects-->
 <Message Text="$(ProjectName) %(PluginOutput.Identity)"  Condition="$(PluginDisabled)" />
</Target>

Upvotes: 0

Related Questions