Question

How does one flatten an item out into a property?

According to this MSDN page (section Conversions between Strings and Item Lists), it is simply a matter of declaring a property with the item as the value.

But I found actual practice to be completely contrary. When I run this project with MSBuild 4.0, specifying target install ...

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(Project-to-import)" Condition="'$(Project-to-import)' != ''" />

  <ItemGroup>
    <RuntimeProj    Include="C:\TEMP\Design.proj" />
    <DesigntimeProj Include="C:\TEMP\Run.dproj" />
  </ItemGroup>

  <PropertyGroup> <!-- Flatten out the items to properties. -->
    <RuntimeProj>@(RuntimeProj)</RuntimeProj>
     <!-- ^ This bit doesn't work. MS documentation is wrong? -->
    <DesigntimeProj>@(RuntimeProj)</DesigntimeProj>
  </PropertyGroup>

  <Target Name="install">
    <Message Text="Hello world!"/>
    <MSBuild Projects="$(MSBuildProjectFile)" Targets="BuildRunPackage"   
             Properties="Project-to-import=$(RuntimeProj)" />
    <MSBuild Projects="$(MSBuildProjectFile)" Targets="BuildDesignPackage"
             Properties="Project-to-import=$(DesigntimeProj)" />
  </Target>

  <Target Name="BuildRunPackage">
    <CallTarget Targets="Clean" /> 
    <CallTarget Targets="Build" /> 
  </Target>

  <Target Name="BuildDesignPackage">
    <CallTarget Targets="Clean" /> 
    <CallTarget Targets="Make" /> 
    <CallTarget Targets="Register" />
  </Target>
<.Project>

... an error is returned ...

error MSB4012: The expression "Project-to-import=@(RuntimeProj) cannot be used in this context. Item lists cannot be concatenated with other strings where an item list is expected. Use a semicolon to separate multiple item lists.

Was it helpful?

Solution

I’m not absolutely sure but I think you get into evaluation order problem. As far as I aware properties are valuated before Items ( see Property and Item Evaluation Order in http://msdn.microsoft.com/en-us/library/dd997067.aspx) If you can try to move property group from “global” under install target. It should work.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(Project-to-import)" Condition="'$(Project-to-import)' != ''" />

  <ItemGroup>
    <RuntimeProj    Include="C:\TEMP\Design.proj" />
    <DesigntimeProj Include="C:\TEMP\Run.dproj" />
  </ItemGroup>


  <Target Name="install">
    <PropertyGroup> <!-- Flatten out the items to properties. -->
      <RuntimeProj>@(RuntimeProj)</RuntimeProj>
      <DesigntimeProj>@(RuntimeProj)</DesigntimeProj>
    </PropertyGroup>

    <Message Text="Hello world!"/>
    <MSBuild Projects="$(MSBuildProjectFile)" Targets="BuildRunPackage"   
             Properties="Project-to-import=$(RuntimeProj)" />
    <MSBuild Projects="$(MSBuildProjectFile)" Targets="BuildDesignPackage"
             Properties="Project-to-import=$(DesigntimeProj)" />
  </Target>

  <Target Name="BuildRunPackage">
    <CallTarget Targets="Clean" /> 
    <CallTarget Targets="Build" /> 
  </Target>

  <Target Name="BuildDesignPackage">
    <CallTarget Targets="Clean" /> 
    <CallTarget Targets="Make" /> 
    <CallTarget Targets="Register" />
  </Target>
</Project>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top