0

I want to embed the output of git describe --dirty --always --tags into my program to easily differentiate different versions of the same executable. To do so I generate a source file containing the output of said command.

Since the command produces a string that ends with dirty if there are any modified files in my worktree that are not yet committed I cannot really define a trigger when to re-generate my source file (e.g. as show in this answer). To solve this problem I wrote a batch script which compares the content of the existing source file and the output of the git command and re-generates the source file only if necessary.

My problem now is that I need to run this batch script before each build, even if msbuild considers the project up-to-date. I tried to use a Pre-Build Event but it is not triggered if the project is up-to-date. I also tried a Custom Build Step and configured a non-existing file as output (this is also an accepted answer here). This causes my batch script to always execute but it also causes code generation being executed for the project even if my generated source file did not change.

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)

I tried it with Execute Before set to ClCompile. Might this be the cause? I also tried some others but with the same effect.

How can I always run my batch script but make the project only produce a new executable if my generated source file was updated?

sigy
  • 2,408
  • 1
  • 24
  • 55

1 Answers1

0

How can I always run my batch script but make the project only produce a new executable if my generated source file was updated?

Try adding <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck> into PropertyGroup:

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

Then VS will always run the project, and if the output xx.exe is up-to-date with no changes to xx.cpp files, the ClCmpile target won't actually create new xx.exe.

Update:

I create a new simple C++ project, set it release mode, and add the DisableFastUpToDateCheck property. Now the vs will always build the project.

I both use the pre-build event and custom target which execute before ClCompile to execute the command git describe --dirty --always --tags.

Now my msbuild output log verbosity is minimal.

1.Build the project:

enter image description here

2.Change nothing to source file,build the project again:

enter image description here

3.Do the same action like #2. And same result.

4.Add a comment the xx.cpp(Not affect the code), build the project:

enter image description here

5.Msbuild project build output verbosity is a good tool when you try to get details about what happen in the build process. For me, I always set it to Detailed. For this issue, if we set it to Normal we can find:

enter image description here

In my opinion:

  1. When I change something in code, the message is 1 of 10 functions (10.0%) were compiled, the rest were copied from previous compilation. And after comparing #1 and #4, we can conclude when it shows 0 of xxx functions were compiled, it actually not spend time generating code, so it won't affect time of your build process.

  2. For the reason why it creates new executable, please see this document. In vs, most of the targets have their inputs and outputs. Like ClCompile target, xx.h files and xx.cpp files are its inputs. Whether this target will execute doesn't depend on if the output files are earlier than inputs.

    For example: When I add a comment in xx.cpp, code actually not change. But since now the xx.cpp is newer than output xx.exe from earlier build. Then this time the build engine will execute ClCompile and Link target to create new xx.exe. And code generation is part of Link target, since no changes to code itself, it will show 0 of xxx functions were compiled to indicate it won't really generate though this time new xx.exe will be created.

  3. So in normal situation the DisableFastUpToDateCheck do work for this situation like #2 and #3. According to the pic you shared above, you must do something which not change the code content(0 functions were compiled) in source files but update the modified date of input files.

enter image description here

Community
  • 1
  • 1
LoLance
  • 25,666
  • 1
  • 39
  • 73
  • It has no effect. It still executes the code generation step even if nothing changed. – sigy Aug 22 '19 at 11:40
  • @sigy Hi friend, see my update to do some trouble-shooting to locate the issue.(See #2,#3, it should work) Hope it makes some help :) – LoLance Aug 23 '19 at 03:26