【问题标题】:Post-build event always runs in MSBUILD VS2013构建后事件始终在 MSBUILD VS2013 中运行
【发布时间】:2014-03-20 19:08:36
【问题描述】:

这很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).

【问题讨论】:

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


    【解决方案1】:

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

    您可以将此代码直接插入到您的项目文件中,但最好将其保存在一个单独的文件中,这样您就可以通过将其导入到任何您想要的位置来重复使用 if 用于其他项目。您也可以通过添加到ProjectOutputFiles ItemGroup 来添加要检查的文件。

    现在剩下的就是禁用 PostBuildEvent。 MsBuild 已经有一个机制,因为 postbuild 事件调用取决于名为 PostBuildEventUseInBuild 的属性,所以如果输出文件未被修改,我们将其设置为 false:

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

    【讨论】:

      【解决方案2】:

      stjin 的回答稍微简单一些:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-22
        • 1970-01-01
        • 2015-05-06
        • 2023-03-29
        • 2015-05-09
        • 2016-08-11
        相关资源
        最近更新 更多