Visual c++ 生成后事件始终在MSBUILD VS2013中运行

Visual c++ 生成后事件始终在MSBUILD VS2013中运行,visual-c++,msbuild,visual-studio-2013,Visual C++,Msbuild,Visual Studio 2013,这是非常重要的,除了在我为VS2013修复了MSBUILD之后,MSBUILD上存在的问题。生成后事件正在运行,即使编译器和链接器认为项目是最新的 关于如何防止生成后事件在此运行,您有什么想法吗 1>Project "D:\XXX\XXX\XXX\XXX.vcxproj" on node 1 (default targets). 1>InitializeBuildStatus: Creating ".\..\XXX\XXX\XXX\XXX.39DEE505.tlog\unsuc

这是非常重要的,除了在我为VS2013修复了MSBUILD之后,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).

此功能是.Net项目的MsBuild中内置的(在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>

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

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

假的
仅当链接器实际执行时,才会执行生成后事件

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