引用目标中 ItemGroup 的元数据定义内众所周知的项目元数据

发布于 2025-01-04 14:10:46 字数 1500 浏览 8 评论 0原文

这是一个 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) 众所周知的元数据引用的行为不同是否在目标内部?

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

Here's an MSBuild script:

<?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>

The output I would expect from it is:

  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

But the result is:

  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

Why is the behavior of the %(FileName)%(Extension) well-known metadata reference is different when an ItemGroup is inside a target?

Is it possible to get the "outside a target" behavior inside a target?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

§普罗旺斯的薰衣草 2025-01-11 14:10:46

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

编辑:

如果(如下面的评论所述)每个item 的 %(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 诡计 技巧 #70, 71

This will give the output you desire. Though it may not be the correct approach in the general case, it does avoid the batching that occurs with "File4" by making the custom metadata a part of the item definition that is calculated:

<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>

edit:

If (as your comment below says) each item has a different value for %(Dest), you just need to make the final value calculated:

<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>

Excerpted from MSBuild Trickery tricks #70, 71

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文