我在MSBuild中有一个后期构建目标来复制一些构建输出.
这是作为对AfterBuild
目标的依赖关系(公开Microsoft.CSharp.targets
):
如果构建实际上没有重新构建,有没有办法避免文件被复制?
例如,当MSBuild依赖关系分析声明项目不需要构建因为它的源文件都没有更新时,它不会构建,但仍然执行我的复制目标.有什么方法可以防止这种情况吗?
我只是用谷歌搜索了这个年代的答案.我找到了一种方法,通过从核心目标中窃取一个想法来更轻松地做到这一点.覆盖BeforeBuild和AfterBuild,并执行以下操作:
%(IntermediateAssembly.ModifiedTime)
由于您要覆盖AfterBuild目标,因此它将始终在构建发生后执行.这是重建或正常构建的情况.如果要在重建(而不是构建)之后执行某些操作,则应该扩展Rebuild目标的依赖项属性.因此,在重建发生后注入目标的情况下,项目文件应如下所示:
$(RebuildDependsOn); InstallUtil; CopyPostBuildFiles
此方法扩展了Rebuild目标用于声明其所依赖的目标的属性.我在文章Inside MSBuild中详细介绍了这一点,请参阅扩展构建过程一节.
如果您可以指定哪些文件将" 触发 "更新发生,那么AfterBuild目标可能会实现您要完成的任务.换句话说,您可以在目标中指定一组"输入",并将一组"输出"指定为两个文件.如果所有输出都是在所有输入之后创建的,则目标将被考虑为最新并跳过.这个概念被称为增量构建,我在文章MSBuild最佳实践第2部分中介绍了它.另外,我在我的书"Microsoft Build Engine内部:使用MSBuild和Team Foundation Build"中详细说明了这一点.
编辑:添加BuildDependsOn示例
如果希望目标仅在实际构建文件时执行,而不是仅在执行重建目标时执行.然后,您应该创建您的项目,如下所示:
$(BuildDependsOn); CustomAfterBuild;
我刚刚复制了Microsoft.CSharp.targets中的CoreCompile目标的输入和输出(我假设你在这里使用C#)并将其粘贴在这里.这意味着只要执行CoreCompile目标,就会跳过目标.此外,由于我扩展了BuildDependsOn,我们知道无论何时构建项目,MSBuild都会尝试执行它.
如何在编译目标中使用输入和输出目标的属性呢?
CopiedFilesDirectory
您可以在CopyPostBuildFiles和InstallUtil上使用它,也可以直接在AfterBuild上使用它.
有关目标输入输出的更多信息,请参阅此页面