在目标中的ItemGroup中引用元数据定义中的已知项元数据

时间:2012-02-10 16:13:10

标签: msbuild metadata target msbuild-4.0 itemgroup

这是一个MSBuild脚本:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="AugmentItemGroup" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
 <ItemGroup> 
   <ItmGrp Include="File1.txt">
       <Dest>dest\%(FileName)%(Extension)</Dest> 
   </ItmGrp>
   <ItmGrp Include="File2.txt">
       <Dest>dest\%(FileName)%(Extension)</Dest> 
   </ItmGrp>
   <ItmGrp Include="File3.txt">
       <Dest>dest\%(FileName)%(Extension)</Dest> 
   </ItmGrp>
  </ItemGroup>

   <Target Name="AugmentItemGroup">
     <ItemGroup>
      <ItmGrp Include="File4.txt">
        <Dest>dest\%(FileName)%(Extension)</Dest> 
      </ItmGrp>          
     </ItemGroup>
     <Message Text="%(ItmGrp.FullPath) to %(ItmGrp.Dest)" />
   </Target>
</Project>

我期望的输出是:

  D:\t\File1.txt to dest\File1.txt
  D:\t\File2.txt to dest\File2.txt
  D:\t\File3.txt to dest\File3.txt
  D:\t\File4.txt to dest\File4.txt

但结果是:

  D:\t\File1.txt to dest\File1.txt
  D:\t\File2.txt to dest\File2.txt
  D:\t\File3.txt to dest\File3.txt
  D:\t\File4.txt to dest\File1.txt
  D:\t\File4.txt to dest\File2.txt
  D:\t\File4.txt to dest\File3.txt

当ItemGroup在目标中时,为什么%(FileName)%(Extension)众所周知的元数据引用的行为不同?

是否有可能在目标中获得“目标外”行为?

1 个答案:

答案 0 :(得分:5)

这将提供您想要的输出。虽然在一般情况下它可能不是正确的方法,但它确实通过使自定义元数据成为计算的项目定义的一部分来避免与“File4”发生的批处理:

<Project
   xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
   DefaultTargets="AugmentItemGroup" 
   ToolsVersion="4.0">  
   <ItemDefinitionGroup>
      <ItmGrp>
         <Dest>dest\%(FileName)%(Extension)</Dest>  
      </ItmGrp>
   </ItemDefinitionGroup>

   <ItemGroup>  
      <ItmGrp Include="File1.txt" />
      <ItmGrp Include="File2.txt" /> 
      <ItmGrp Include="File3.txt" /> 
   </ItemGroup> 

   <Target Name="AugmentItemGroup"> 
      <ItemGroup> 
         <ItmGrp Include="File4.txt" />
      </ItemGroup> 
      <Message Text="%(ItmGrp.FullPath) to %(ItmGrp.Dest)" /> 
   </Target> 
</Project>

编辑:

如果(如下面的评论所述)每个项目的%(Dest)值都不同,则只需要计算最终值:

<Project ...>
    <ItemDefinitionGroup>
       <ItmGrp>
          <_Dest />
       </ItmGrp>
    </ItemDefinitionGroup>

    <ItemGroup>  
       <ItmGrp Include="File1.txt"><Dest>dest1</Dest></ItmGrp>
       <ItmGrp Include="File2.txt"><Dest>dest2</Dest></ItmGrp>
       <ItmGrp Include="File3.txt"><Dest>dest3</Dest></ItmGrp>
    </ItemGroup> 

    <Target Name="AugmentItemGroup"> 
       <ItemGroup> 
          <ItmGrp Include="File4.txt"><Dest>dest4</Dest></ItmGrp>
          <ItmGrp>
             <_Dest>%(Dest)\%(FileName)%(Extension)</_Dest>
          </ItmGrp>
       </ItemGroup> 
       <Message Text="%(ItmGrp.FullPath) to %(ItmGrp._Dest)" /> 
    </Target> 
</Project>

摘自MSBuild Trickery技巧#70,71