【问题标题】:Referencing well-known item metadata inside metadata definition in an ItemGroup in a target在目标中的 ItemGroup 的元数据定义中引用众所周知的项目元数据
【发布时间】:2012-02-10 16:13:09
【问题描述】:

这是一个 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) 知名元数据引用的行为会有所不同?

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

【问题讨论】:

    标签: msbuild metadata target msbuild-4.0 itemgroup


    【解决方案1】:

    这将提供您想要的输出。虽然在一般情况下它可能不是正确的方法,但它确实通过将自定义元数据作为计算的项目定义的一部分来避免使用“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

    【讨论】:

    • 对我来说,这种方法的问题是“dest\”部分会因项目而异,因此不能将相同的定义应用于组中的所有项目。
    • 好吧,试试上面的第二种方法。注意使用Dest vs. _Dest
    • 这帮助我完成了一项完全不同的任务,谢谢。另外,对于书的链接,我要买它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多