views:

24

answers:

1

Hi guys,

I'm currently trying to use MSBuild to set up a project, and am having some issues with wildcards.

I'm trying to use the following snippet:

<Project ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;
  <ItemGroup>
    <Xsd Include="App_Data\*.xsd">
      <Generator>MSDataSetGenerator</Generator>
      <LastGenOutput>%(Xsd.Filename).Designer.cs</LastGenOutput>
      <SubType>Designer</SubType>
    </Xsd>
    <Xss Include="App_Data\*.xss">
      <DependentUpon>%(Xss.Filename).xsd</DependentUpon>
    </Xss>
    <Xsc Include="App_Data\*.xsc">
      <DependentUpon>%(Xsc.Filename).xsd</DependentUpon>
    </Xsc>
  </ItemGroup>
  <Target Name="PrintMetaData">
    <Message Text="@(Xss->'%(DependentUpon)')"/>
  </Target>
</Project>

using the 3.5 version of MSBuild I get the following output:

".xsd;.xsd;.xsd;.....etc.xsd;"

using the 4.0 version of MSBuild I get the expected result: a list of the filenames.

Does anyone know if this is a known issue with a workaround, or if there's a patch for MSBuild I'm missing?

Thanks!

+1  A: 

I had a quite similar problem. See : http://stackoverflow.com/questions/3629231/scope-and-order-of-evaluation-of-items-in-msbuild .

With MSBuild prior to 4.0 you cannot declare an item and set some of his Metadata by batching over its own well-known metadata at the same time.

Don't also forget that Items outside of Targets are evaluated once, in the beginning of the parsing. Thus, you cannot do batching outside of targets with MSBuild prior to 4.0. So a workaround could be to put your batching part (or the whole declaration in your target) :

<Project ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;
  <ItemGroup>
    <XsdFiles Include="App_Data\*.xsd">
      <Generator>MSDataSetGenerator</Generator>
      <SubType>Designer</SubType>
    </XsdFiles>
    <XssFiles Include="App_Data\*.xss" />
    <XscFiles Include="App_Data\*.xsc" />
  </ItemGroup>
  <Target Name="PrintMetaData">
    <ItemGroup>
      <Xsd Include="@(XsdFiles)">
        <LastGenOutput>%(XsdFiles.Filename).Designer.cs</LastGenOutput>
      </Xsd>
      <Xss Include="@(XssFiles)">
        <DependentUpon>%(XssFiles.Filename).xsd</DependentUpon>
      </Xss>
      <Xsc Include="@(XscFiles)">
        <DependentUpon>%(XscFiles.Filename).xsd</DependentUpon>
      </Xsc>
    </ItemGroup>
    <Message Text="@(Xss->'%(DependentUpon)')"/>
  </Target>
</Project>

If you want to put the whole ItemGroup in your target, don't forget to set the metadata by batching only once your item is declared. You must do this in two steps.

Benjamin Baumann
Spot on, thanks for that! You'd be amazed at how hard it is to find any detailed information about stuff like this in MSBuild, even the books I have access to don't have anything like it.
Ed Woodcock
Items evaluation and scope are a huge pain to understand, above all because like you say the docs are sparse. I haven't access to MsBuild Books but http://www.sedodream.com/ is a very interesting source of information. His book is also very worth reading according to what I heard.
Benjamin Baumann