生成后事件始终在MSBUILD VS2013中运行 [英] Post-build event always runs in MSBUILD VS2013

查看:130
本文介绍了生成后事件始终在MSBUILD VS2013中运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这与该问题非常类似,除了除了我在VS2013修复它之后,MSBUILD上存在该问题以外的其他问题.即使编译器和链接器认为项目是最新的,构建后事件也正在运行.

This is very similar to this question, except for the problem except the problem exists on MSBUILD after I fix it for VS2013. The post-build event is running even though the compiler and linker think the project is up-to-date.

是否有任何关于如何防止构建后事件在此处运行的想法?

Any thoughts on how to prevent the post-build event from running here?

1>Project "D:\XXX\XXX\XXX\XXX.vcxproj" on node 1 (default targets).

1>InitializeBuildStatus:
  Creating ".\..\XXX\XXX\XXX\XXX.39DEE505.tlog\unsuccessfulbuild" because "AlwaysCreate" was specified.\

ClCompile:
  All outputs are up-to-date.
  All outputs are up-to-date.
ResourceCompile:
  All outputs are up-to-date.
Link:
  All outputs are up-to-date.
  WpnSiteOverlayManager.vcxproj -> D:\XXX\XXX\XXX\XXX\..\bin\Release\XXX.dll
PostBuildEvent:
  "..\..\..\Components\DevTools\Build\BuildCommand.exe" /p "..\..\..\Products" "D:\XXX
  ....
  buildcommand completed successfully
FinalizeBuildStatus:
  Deleting file ".\..\intermediate\release\XXX\XXX.39DEE505.tlog\unsuccessfulbuild".
  Touching ".\..\intermediate\release\XXX\XXX.39DEE505.tlog\XXX.lastbuildstate".
1>Done Building Project "D:\XXX\XXX\XXX\XXX.vcxproj" (default targets).

推荐答案

此功能内置在MsBuild for .Net项目中(在Microsoft.Common.Targets中搜索PostBuildEvent,另请参见

This functionality is built-in in MsBuild for .Net projects (search for PostBuildEvent in Microsoft.Common.Targets, also see here), here is a simplified version. The principle is you get a timestamp of your output file(s) before the build, and another one after the build, then compare them. If they are the same, obviously nothing was really built. There's a miriad of possible insertion points for this logic, here I just picked the link stage which should do just fine:

<Target Name="GetTimeStampBeforeLink" BeforeTargets="Link">
  <ItemGroup>
    <ProjectOutputFiles Include="$(TargetPath)" />
  </ItemGroup>
  <PropertyGroup>
    <OutputTimeStampBeforeLink>%(ProjectOutputFiles.ModifiedTime)</OutputTimeStampBeforeLink>
  </PropertyGroup>
</Target>

<Target Name="GetTimeStampAfterLink" AfterTargets="Link">
  <PropertyGroup>
    <OutputTimeStampAfterLink>%(ProjectOutputFiles.ModifiedTime)</OutputTimeStampAfterLink>
    <OutputFilesModified Condition="'$(OutputTimeStampBeforeLink)' != '$(OutputTimeStampAfterLink)'">True</OutputFilesModified>
  </PropertyGroup>
</Target>

您可以将此代码直接插入到您的项目文件中,但是更好的主意是将其保存在单独的文件中,以便通过将其导入到任何其他位置来将其重用于其他项目.您也可以通过添加到ProjectOutputFiles ItemGroup中来添加要检查的文件.

You can insert this code right into your projectfile, but a better idea is to save it in a seperate file so you can reuse if for other projects by importing it wherever you want it. Also you can add files to check by adding to the ProjectOutputFiles ItemGroup.

现在剩下的就是禁用PostBuildEvent. MsBuild已经有了一种机制,因为构建后事件的调用取决于名为PostBuildEventUseInBuild的属性,因此如果未修改输出文件,则将其设置为false:

Now all is left is disabling the PostBuildEvent. MsBuild already has a mechanism for that since postbuild event invokation is conditional on a propery named PostBuildEventUseInBuild, so we set this to false if output files are not modified:

<Target Name="DisablePostBuildEvent" AfterTargets="GetTimeStampAfterLink">
  <PropertyGroup>
    <PostBuildEventUseInBuild Condition='"$(OutputFilesModified)' != 'True'">false</PostBuildEventUseInBuild>
  </PropertyGroup>
</Target>

这篇关于生成后事件始终在MSBUILD VS2013中运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆