visual-c++ - 构建后事件始终在 MSBUILD VS2013 中运行

标签 visual-c++ msbuild visual-studio-2013

这很similar to this question ,除了问题,除了在我为 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).

最佳答案

此功能内置于 .Net 项目的 MsBuild 中(在 Microsoft.Common.Targets 中搜索 PostBuildEvent,另见 here),这里是一个简化版本。原则是您在构建之前获得输出文件的时间戳,在构建之后获得另一个时间戳,然后比较它们。如果它们相同,显然没有真正构建。这个逻辑有很多可能的插入点,在这里我只是选择了应该做得很好的链接阶段:

<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 来添加要检查的文件。项目组。

现在剩下的就是禁用 PostBuildEvent。 MsBuild 已经有一个机制,因为 postbuild 事件调用取决于名为 PostBuildEventUseInBuild 的属性。 ,因此如果未修改输出文件,我们将其设置为 false:
<Target Name="DisablePostBuildEvent" AfterTargets="GetTimeStampAfterLink">
  <PropertyGroup>
    <PostBuildEventUseInBuild Condition='"$(OutputFilesModified)' != 'True'">false</PostBuildEventUseInBuild>
  </PropertyGroup>
</Target>

关于visual-c++ - 构建后事件始终在 MSBUILD VS2013 中运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22542820/

相关文章:

c++ - 在 vc++ 中获取事件进程名

visual-studio-2015 - 错误 "The OutputPath property is not set for project"VS 2015

c++ - 如何自动矢量化基于范围的 for 循环?

c# - 在构建事件中所做的更改不会在 clickonce 发布时持续存在

c# - .net core 3.1 Azure Devops Pipeline 在 nuget 恢复上失败

c++ - 检测图像上标记的最佳方法是什么?打开简历

c++ - 在 pdfium 中创建一个 dll

c++ - 进程内通信 WinRT(消息替换)

visual-c++ - CComboBox 只接受 VC++ 中的数字?

c++ - 对于不同版本的 Microsoft Visual C++,已编译的 .lib 文件是否可以互换?