首页 > 解决方案 > 在每次构建之前运行自定义工具,即使它是最新的

问题描述

我想将 的输出嵌入git describe --dirty --always --tags到我的程序中,以轻松区分同一可执行文件的不同版本。为此,我生成了一个包含所述命令输出的源文件。

由于该命令会生成一个字符串,dirty如果我的工作树中有任何尚未提交的已修改文件以结尾,我无法真正定义何时重新生成我的源文件的触发器(例如,如本答案中所示)。为了解决这个问题,我编写了一个批处理脚本,它比较现有源文件的内容和 git 命令的输出,并仅在必要时重新生成源文件。

我现在的问题是我需要在每次构建之前运行这个批处理脚本,即使 msbuild 认为项目是最新的。我尝试使用预构建事件,但如果项目是最新的,则不会触发它。我还尝试了一个自定义构建步骤并将一个不存在的文件配置为输出(这也是一个可接受的答案)。这会导致我的批处理脚本始终执行,但它也会导致为项目执行代码生成,即使我生成的源文件没有更改。

4>------ Build started: Project: TestProject, Configuration: Release Win32 ------
4>  Current git Version is 9.6-13-g2c753a1727-dirty
4>  Include with version number is up-to-date
4>  Generating code
4>  0 of 9106 functions ( 0.0%) were compiled, the rest were copied from previous compilation.
4>    0 functions were new in current compilation
4>    0 functions had inline decision re-evaluated but remain unchanged
4>  Finished generating code
4>  TestProject.vcxproj -> C:\bin\TestProject.exe
4>  TestProject.vcxproj -> C:\bin\TestProject.pdb (Full PDB)

我尝试将Execute Before设置为ClCompile。这可能是原因吗?我也尝试了其他一些,但效果相同。

如果我生成的源文件已更新,我怎样才能始终运行我的批处理脚本但使项目只生成一个新的可执行文件?

标签: visual-studiobuildmsbuildversioncode-generation

解决方案


如果我生成的源文件已更新,我怎样才能始终运行我的批处理脚本但使项目只生成一个新的可执行文件?

尝试添加<DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>PropertyGroup

  <PropertyGroup Label="Globals">
     ...
    <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
  </PropertyGroup>

然后 VS 将始终运行项目,如果输出xx.exe是最新的且xx.cpp文件没有更改,则目标实际上ClCmpile不会创建新的.xx.exe

更新:

我创建了一个新的简单 C++ 项目,设置它release的模式,并添加DisableFastUpToDateCheck属性。现在 vs 将始终构建项目。

我都使用pre-build eventandcustom target which execute before ClCompile来执行命令git describe --dirty --always --tags

现在我的 msbuild 输出日志详细程度是minimal.

1.构建项目:

在此处输入图像描述

2.对源文件不做任何更改,再次构建项目:

在此处输入图像描述

3.做与#2相同的动作。和同样的结果。

4.添加注释xx.cpp(不影响代码),构建项目:

在此处输入图像描述

5.当您尝试获取有关构建过程中发生的情况的详细信息时,Msbuild 项目构建输出详细信息是一个很好的工具。对我来说,我总是将其设置为Detailed. 对于这个问题,如果我们将其设置为,Normal我们可以找到:

在此处输入图像描述

在我看来:

  1. 当我在代码中更改某些内容时,消息是1 of 10 functions (10.0%) were compiled, the rest were copied from previous compilation.并且在比较#1和#4之后,我们可以得出结论,当它显示时0 of xxx functions were compiled,它实际上并没有花费时间生成代码,所以它不会影响你的构建过程的时间。

  2. 有关它创建新可执行文件的原因,请参阅此文档。在 vs 中,大多数目标都有其输入和输出。与 ClCompile 目标一样,xx.h 文件和 xx.cpp 文件是它的输入。此目标是否会执行不取决于输出文件是否早于输入。

    例如:当我在 xx.cpp 中添加注释时,代码实际上并没有改变。但是现在 xx.cpp 比早期版本的输出 xx.exe 更新。然后这一次构建引擎将执行 ClCompile 和 Link 目标以创建新的 xx.exe。代码生成是链接目标的一部分,由于代码本身没有变化,它将显示 0of xxx functions were compiled表示它不会真正生成,尽管这次将创建新的 xx.exe。

  3. 所以在正常情况下,DisableFastUpToDateCheck像#2 和#3 这样的情况确实有效。根据你上面分享的图片,你必须做一些不改变源文件中的代码内容(编译了0个函数)但更新输入文件的修改日期的事情。

在此处输入图像描述


推荐阅读