1

I have a makefile used by GNU Make 3.81 running on windows and with each build I pass to the compiler a define giving a version number. The version number is obtained from a file and incremented at the start of the makefile using a perl script with the -get option. The resulting program can then display the build version. The trouble I have is that the version number is updated even if the build fails. But this is fixed by running the perl script again, with the -dec option, to decrement the version number if an error occurs. Simplified contents of the makefile:

objects:= pov1.obj
ouf:= pov1
versionFile:= povVersion.txt
VERSION:=$(shell perl ../../../perl/uscripts/bump.pl -get -f $(versionFile))
CXX:= cl 
CXXFLAGS:= -c -EHsc -std:c++17 -D$(addprefix VER=,\"$(VERSION)\")

target:=$(addsuffix .exe, $(ouf))

%.obj : %.cpp
    $(CXX) $(CXXFLAGS) $< -Fo$@ || perl ../../../perl/uscripts/bump.pl -dec -f $(versionFile)
     
$(target) : $(objects)
    $(LINKER) $(LDFLAGS) $(objects) /OUT:$(target) || perl ../../../perl/uscripts/bump.pl -dec -f $(versionFile)

Although this seems to work if I accidently run the make when up-to-date the version number is updated despite no build taking place. How can I run the perl script decrement in the event that the make detects up-to-date or, make the first run of the perl script dependent on an update being required?

Maybe there is a better way to get build version numbers into the program?

Edit to reflect answer given by dash-o, my simplified make file now contains this:

objects:= pov1.obj
ouf:= pov1
versionFile:= povVersion.txt
VERSION:=$(shell perl ../../../perl/uscripts/bump.pl -inc -dry -f $(versionFile)) #versionFile is not updated until link actually completes
CXX:= cl 
CXXFLAGS:= -c -EHsc -std:c++17 -D$(addprefix VER=,\"$(VERSION)\")

target:=$(addsuffix .exe, $(ouf))

%.obj : %.cpp
    $(CXX) $(CXXFLAGS) $< -Fo$@
     
$(target) : $(objects)
    $(LINKER) $(LDFLAGS) $(objects) /OUT:$(target)
    perl ../../../perl/uscripts/bump.pl -inc -f $(versionFile) #update versionFile here

In my C++ main file pov1.cpp I have

#ifdef VER
std::string version{VER};
#else
std::string version{"version not set"};
#endif

which allows access in the program to the version number. The perl script is here

stegzzz
  • 407
  • 4
  • 9
  • Simply increment only if you need to build and not before. No need to work around by decrement on whatever... – Klaus Jan 03 '21 at 17:09
  • Use date-time as the build number, as in say `20210103121050`. Then it's no longer a problem that two consecutive builds are assigned non-sequential numbers. – Igor Tandetnik Jan 03 '21 at 17:11
  • @Klaus, thanks, yes that seems the best way "make the first run of the perl script dependent on an update being required", but how do I do this? – stegzzz Jan 03 '21 at 17:13
  • @stegzzz Create a 1st level dependency to `$(versionfile)` e.g. `%.obj : $(versionfile) %.cpp` (and another rule to call the script of course). – πάντα ῥεῖ Jan 03 '21 at 17:47
  • This seems like the perfect situation for this little trick: http://make.mad-scientist.net/deferred-simple-variable-expansion/ – MadScientist Jan 03 '21 at 18:45

1 Answers1

2

The current solution bumps the version number (stored in the file) at the start of the build, and rolling it back on failure. However, this may fail in variety of situation, when the scripts does not reach the link time.

As an alternative, consider a different solution:

  • New version number will be calculated at the start of the build, but the version number will NOT be updated in the file.
  • If the build (linking) is completed successfully, the new version number is committed to the file

    # The '-get' should return N+1, and should NOT update the file
VERSION:=$(shell perl ../../../perl/uscripts/bump.pl -get -f $(versionFile))

$(target) : $(objects)
    $(LINKER) $(LDFLAGS) $(objects) /OUT:$(target)
    # Commit the new version number, only if build is success
    echo $(VERSION) > $(versionFile)
dash-o
  • 13,723
  • 1
  • 10
  • 37