【问题标题】:MsBuild Target with multiple Outputs具有多个输出的 MsBuild 目标
【发布时间】:2018-06-18 12:53:11
【问题描述】:

当您有多个输出时,有没有办法克服目标的一对一映射?似乎这应该是可能的,但我不知道怎么做,因为我对 MsBuild 很陌生,我可能错过了一些东西。

以下 msbuild 脚本来自微软的文档。当我有多个备份文件夹时,我应该更改什么?那么列表@(BackupFolders) 我想保留构建的增量行为吗?

<Target Name="Backup" Inputs="@(Compile)"   
    Outputs="@(Compile->'$(BackupFolder)%(Identity).bak')">  
    <Copy SourceFiles="@(Compile)" DestinationFiles=  
        "@(Compile->'$(BackupFolder)%(Identity).bak')" />  
</Target>  

【问题讨论】:

    标签: msbuild msbuild-target msbuild-batching


    【解决方案1】:

    首先,Target 节点上的 Inputs 和 Outputs 属性用于incremental builds。它们需要具有相同数量的条目,以便 msbuild 了解在构建时应该过滤哪些项目。 MSBuild 检查输出是否已经存在并且是最新的,如果是,则从输入列表中过滤匹配的输入项。如果您不关心增量构建,则可以完全跳过此机制。如果输入和输出不匹配(或不存在),msbuild 将始终执行包含所有项目的目标,因为它无法决定哪些项目导致哪些输出。

    其次,这些属性期望的是一个项目列表。这不必是一个列表,它可以是任意列表。因此,像这样扩展您的示例是完全公平的:

    <Target Name="Backup" Inputs="@(Compile);@(Compile2)"   
      Outputs="@(Compile->'$(BackupFolder)%(Identity).bak');@(Compile2->'$(BackupFolder)%(Identity).bak')">  
      <Copy SourceFiles="@(Compile)" DestinationFiles=  
         "@(Compile->'$(BackupFolder)%(Identity).bak')" />  
      <Copy SourceFiles="@(Compile2)" DestinationFiles=  
         "@(Compile2->'$(BackupFolder)%(Identity).bak')" />  
    </Target>
    

    但是您想将相同的项目复制到不同的备份文件夹,对吗?所以应该这样做:

    <Target Name="Backup">  
      <Copy SourceFiles="@(Compile)" DestinationFiles=  
          "@(Compile->'$(BackupFolder)%(Identity).bak')" />  
      <Copy SourceFiles="@(Compile)" DestinationFiles=  
          "@(Compile->'$(BackupFolder2)%(Identity).bak')" />  
    </Target>
    

    如果有两个备份文件夹,一个项目实际上可能已经在一个文件夹中是最新的,但在另一个文件夹中却丢失了。您可以将一个定义为“主”备份文件夹,并告诉 MSBuild 将其用作增量构建的参考。

    编辑:对于两个位置的增量构建,可能最简单的解决方案是组合两个目标,两者都是增量构建:

    <Target Name="Backup" DependsOnTargets="_Backup1;_Backup2">
    </Target>
    
    <Target Name="_Backup1" Inputs="@(Compile)"   
      Outputs="@(Compile->'$(BackupFolder)%(Identity).bak')">  
      <Copy SourceFiles="@(Compile)" DestinationFiles=  
         "@(Compile->'$(BackupFolder)%(Identity).bak')" />    
    </Target>
    
    <Target Name="_Backup2" Inputs="@(Compile)"   
      Outputs="@(Compile->'$(BackupFolder2)%(Identity).bak')">  
      <Copy SourceFiles="@(Compile)" DestinationFiles=  
         "@(Compile->'$(BackupFolder2)%(Identity).bak')" />  
    </Target>
    

    【讨论】:

    • 我想保留增量构建能力。而且我不太确定您的任何一种方法都能实现这一点。我未能描述的问题是该项目应复制到两个目的地。如果它已经在一个副本中,则跳过该副本,然后再做另一个。
    • 对不起,我想得太复杂了。最简单的方法可能是实现两个备份到不同位置的单独目标,并确保两者都被调用。
    猜你喜欢
    • 1970-01-01
    • 2018-12-03
    • 1970-01-01
    • 2012-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-14
    • 1970-01-01
    相关资源
    最近更新 更多