MSBuild中的交叉连接项组

时间:2013-04-09 23:08:38

标签: msbuild itemgroup

考虑到这样的事情......

 <?xml version="1.0" encoding="utf-8"?>
    <Project DefaultTargets="test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
        <ItemGroup>
            <ConfigFiles Include="*.config" />

            <DatabaseConfig Include="ABC">
                <Database>DB1</Database>
                <CsString>Database</CsString>
            </DatabaseConfig>

            <DatabaseConfig Include="DEF">
                <Database>DB2</Database>
                <CsString>Logging</CsString>
            </DatabaseConfig>
        </ItemGroup>


        <Target Name="test" >
            <!-- Some sort of join here (or somewhere)... -->
         <Message Text=" %(Combined.ConfigFile) %(Combined.Database) " />
        </Target> 
    </Project>

我希望输出是这样的..(给出两个文件one.config&amp; two.config)

one.config DB1
two.config DB1
one.config DB2
two.config DB2

(顺序并不重要,只是两个ItemGroups的完整笛卡尔积)

2 个答案:

答案 0 :(得分:5)

这似乎是一个整洁的解决方案:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <ConfigFiles Include="*.config" />

        <DatabaseConfig Include="ABC">
            <Database>DB1</Database>
            <CsString>Database</CsString>
        </DatabaseConfig>

        <DatabaseConfig Include="DEF">
            <Database>DB2</Database>
            <CsString>Logging</CsString>
        </DatabaseConfig>
    </ItemGroup>

    <Target Name="test" >
        <ItemGroup>
            <Combined Include="@(DatabaseConfig)">
                <ConfigFile>%(ConfigFiles.Identity)</ConfigFile>
            </Combined> 
        </ItemGroup>
    <Message Text=" %(Combined.ConfigFile) %(Combined.Database) " />
    </Target> 
</Project>

答案 1 :(得分:3)

有一种方法可以对现有示例代码进行最少的更改。您可以combine metadataConfigFiles项目和DatabaseConfig项目转换为新的“合并”项目,然后输出该“合并”项目。

要合并元数据,请将target batching与每个DatabaseConfig项目运行一次的批处理目标一起使用。然后,您可以调用另一个目标来输出组合的元数据以获取您描述的输出。看看我的示例代码扩展,看看如何实现这一目标:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <ItemGroup>
    <ConfigFiles Include="*.config" />

    <DatabaseConfig Include="ABC">
      <Database>DB1</Database>
      <CsString>Database</CsString>
    </DatabaseConfig>

    <DatabaseConfig Include="DEF">
      <Database>DB2</Database>
      <CsString>Logging</CsString>
    </DatabaseConfig>
  </ItemGroup>

  <Target Name="test" DependsOnTargets="test_setup;test_output" >
    <!-- Logic here runs after targets listed in "DependsOnTargets". -->
  </Target>

  <!-- This will run once for each "DatabaseConfig" item. -->
  <Target Name="test_setup" Outputs="%(DatabaseConfig.Identity)">
    <PropertyGroup>
      <!-- Specify the Database for the current DatabaseConfig item -->
      <CurrentDb>%(DatabaseConfig.Database)</CurrentDb>
    </PropertyGroup>
    <ItemGroup>
      <!-- Add a new CombinedOutput item with each run, combining metadata. -->
      <CombinedOutput Include=" %(ConfigFiles.FileName)%(ConfigFiles.Extension) $(CurrentDb) " />
    </ItemGroup>
  </Target>

  <Target Name="test_output">
    <!-- Output the combined metadata from the CombinedOutput items -->
    <Message Text=" %(CombinedOutput.Identity) " />
  </Target>

</Project>

样本中发生了什么:

  1. test目标现在只是用来调用其他两个目标来执行工作:test_setuptest_output
  2. test_setup目标进行批处理并创建新目标 CombinedOutput个项目。
  3. test_output之后调用test_setup目标 输出CombinedOutput项目的元数据。
  4. test_output的输出:

    one.config DB1
    two.config DB1
    one.config DB2
    two.config DB2