构建后事件始终在MSBUILD VS2013中运行

4

这个问题和这个问题非常相似,只是这里的问题存在于我为VS2013解决了该问题之后在MSBUILD中仍然存在。尽管编译器和链接器认为项目已经是最新的,但后期构建事件仍在运行。

有什么想法可以防止后期构建事件在这里运行吗?

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).
2个回答

5

对stjin答案的一个稍微简单一点的变化:

<Target Name="DisablePostBuildEvent" AfterTargets="Link" BeforeTargets="PostBuildEvent">
  <PropertyGroup>
    <PostBuildEventUseInBuild Condition="'$(LinkSkippedExecution)' == 'True'">false</PostBuildEventUseInBuild>
  </PropertyGroup>
</Target>

只有当链接器实际执行时,才会执行此后构建事件。

5
这个功能在MsBuild中已经内置,适用于.Net项目(在Microsoft.Common.Targets中搜索PostBuildEvent,也可以参见这里)。以下是一个简化版本。原理是在构建之前获取输出文件的时间戳,然后在构建之后再获取一次,最后进行比较。如果它们相同,显然没有真正构建任何内容。这个逻辑可以在很多地方进行插入,这里只选择了链接阶段,应该足够了。
<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来检查文件。
现在剩下的就是禁用PostBuildEvent了。MsBuild已经有了这种机制,因为后建事件调用取决于一个名为PostBuildEventUseInBuild的属性,因此如果输出文件未被修改,我们将其设置为false。
<Target Name="DisablePostBuildEvent" AfterTargets="GetTimeStampAfterLink">
  <PropertyGroup>
    <PostBuildEventUseInBuild Condition='"$(OutputFilesModified)' != 'True'">false</PostBuildEventUseInBuild>
  </PropertyGroup>
</Target>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接