Automatically Increment Build Version Number in Firmware

Go To Last Post
26 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello all,

We are using a version number of the format major.minor.build. An example might be 1.5.234.

I would like the makefile to automatically increment the build number and then compile it into the hex file so it can be sent out the serial port.

I googled various combinations of the following words: make gcc increment build version

I searched the AVR forums using those words.

I also looked in the WinAVR user manuals.

As anyone implemented a version number like this? Does anyone have a good link I can review? Is there a better tool to use then make?

Thank you,
Jeff

Jeff Dombach, JLD Systems
"We do the stuff behind the buttons!"
Your source for embedded solutions with a 100% Guarantee.
http://www.jldsystems.com
Phone 717.892.1100

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you using any version control software. Eg. for Subversion there is a utility that will report the Subversion revision for the thing being built. Does not fit into your current scheme, but thought I mention it anyway... (Can't recall the utility name right now, but will dig if you're interested).

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here's a link to a forum post / article that might get you going. It currently does not include the build number - just the major / minor numbers but a build number could be added. As Johan pointed out, it is based on a source control system. It integrates with AVR GCC either within the Studio framework or standalone from a DOS command line.

Dave

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You got some good advice if you are using a version control system. And, if you are not using a VCS, you should consider using one.

Assuming that the you don't want to use the automatic revision numbers from CVS or Subversion that be automatically updated when you make a commit to the VCS, I think you'll have to roll your own system.

In general, make can automate the process. But, you'll need a simple filter program than can parse your source file containing the current version and ouput a new version of the source file with the version number incremented. In general, this isn't too hard. Mostly people would use a tool like perl, sed, or awk to create this filter.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The client was originally using subversion, however we did not implement build versions into the make and the subversion server is no longer functioning.

We currently backup the source directory to an offsite server daily (I know it's not VCS, but it's what I have).

I would like to know how to implement the CVS version numbers and if possible a stand alone.

Thanks,
Jeff

Jeff Dombach, JLD Systems
"We do the stuff behind the buttons!"
Your source for embedded solutions with a 100% Guarantee.
http://www.jldsystems.com
Phone 717.892.1100

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jldsystems wrote:
I would like to know how to implement the CVS version numbers and if possible a stand alone.
Jeff, if you want CVS version number, you typically need a CVS server. But, CVS is built on top of the older RCS tools which you can use to create version numbers as you check in and out files. RCS tools might be okay for you as you are asking for a "stand alone" system and RCS does not use a centralized server. I'm fairly certain RCS is in the cygwin tools. You'll need to read the RCS documentation to learn how to use those tools.

While I still recommend a version control system for all of its other benefits, if you really want complete control over the numbering, the guideline I already outlined for you using a filter program has some merit.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Buildnumber creation without a central database like a VCS is rather fragile. Consider using a timestamp instead. Here is a quick hack for generating one on Unix with make:

# Do not name this rule timestamp.c, although
# it creates timestamp.c
# The timestamp contains an SCCS ID marker
# for what(1) (the @(#)) and an RCS keyword
# marker for ident(1) (the $Build: ... $)
timestamp:
         date '+static char const timestamp[] = "@(#) $$Build: '$$LOGNAME'@'$$(hostname)' %F %H:%M:%S.%N %z $$";' > timestamp.c

# create timestamp.c
timestamp.c: timestamp
.PHONY: timestamp

# some houskeeping
clean::
        -rm -f timestamp.c

If you really want to work with automatic build number counting and no central repository, you could start working from this:

#
# Initial creation of counter. Should better
# be done manually, not in this makefile.
#
counter:
        echo "0" > $@

#
# Increment counter and write buildnum.c
# Do not name this rule buildnum.c although it creates buildnum.c
# TODO: Add file locking for concurrent builds
#
buildnum: counter
        read LASTNUM < counter;         \
        NEWNUM=$$(($$LASTNUM + 1));             \
        echo "const int buildnum = $$NEWNUM;" > buildnum.c; \
        echo "$$NEWNUM" > counter

buildnum.c: buildnum
.PHONY: buildnum
clean::
        -rm -f buildnum.c

I consider the above buildnum.c creation not good enough for production. You would have to have some protection for the "counter" file. Erasing it is just too easy. You would also have to have a separate build procedure for all the dirty builds a developer does during the day, and an official build which leaves the developer's desk and is e.g. given to QA.

For the above reasons I prefer the simple timestamp.

Stealing Proteus doesn't make you an engineer.

Last Edited: Fri. Dec 21, 2007 - 01:21 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jeff,

somewhere I found the following idea that is based on the Makefile and the Bash as shell behind:
Makefile....

include buildnum
NEW_BUILDNUMBER = $(shell echo $$(( $(BUILDNUMBER) + 1 )))

Whatever you do with "NWE_BUILDNUMBER" is up to you but at one location you need to add the following (I do it at linking):

%.elf: $(OBJ)
	@echo
	@echo $(MSG_LINKING) $@
	@echo "# Automatically generated file - do not edit" > buildnum
	@echo "BUILDNUMBER=$(NEW_BUILDNUMBER)" >> buildnum
	$(CC) $(ALL_CFLAGS) $^  --output $@ $(LDFLAGS)

HTH
Knut

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Personally I just build a string in the code with __DATE__ and __TIME__ then have the makefile 'touch' that file so it is built every time. This makes for unique version numbers (unless you can get two builds done in one second!) and is also helpfully documenting. When a problem occurs in some version you can look back to your email traffic of that date/time for chatter about when the build was released, what issues it fixed, etc, etc (of course the "release notes" you always methodically update have this too - don't they? ;))

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you everyone, you all provided the excellent high quality feedback that has made AVR Freaks a great resource for all of us.

I am going explore each of these ideas in depth.

Thank you again!

Jeff Dombach, JLD Systems
"We do the stuff behind the buttons!"
Your source for embedded solutions with a 100% Guarantee.
http://www.jldsystems.com
Phone 717.892.1100

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's probably obvious but I actually have the "version" date/time built into the help screen for my program's terminal interface which uses:

const uint8_t help[] PROGMEM = { 
"\
Program version "__DATE__" "__TIME__"\r\n\n\
1 - toggle LED1\r\n\
2 - toggle LED2\r\n\
3 - toggle LED3\r\n\
....
Y - play fast PWM with 8bit data (fPWM=31,250Hz)\r\n\
"
};

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jldsystems wrote:
Hello all,

We are using a version number of the format major.minor.build. An example might be 1.5.234.

I would like the makefile to automatically increment the build number and then compile it into the hex file so it can be sent out the serial port.

I googled various combinations of the following words: make gcc increment build version

I searched the AVR forums using those words.

I also looked in the WinAVR user manuals.

As anyone implemented a version number like this? Does anyone have a good link I can review? Is there a better tool to use then make?

Thank you,
Jeff

I am curious as to how you finally implemented this? We have the same issue and it would be nice if I could do this with a click through Studio.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When I do timestamping, I make it part of the link step:

fred.elf: $(fred_deps)
        avr-gcc -o linktime.o -c $(CFLAGS) $(SRC)/linktime.c
        avr-gcc -o $@ $(LDFLAGS) linktime.o $^ $(LDLIBS)

That way there is no need to touch linktime.c and
consecutive makes will not cause consecutive links.
Replace the linktime.c step with something that compiles revision.c and updates it.
Awk shouldn't have too hard a time updating this:

#include 
char revision[] PROGMEM ="3.2."
"0"
;

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
It's probably obvious but I actually have the "version" date/time built into the help screen for my program's terminal interface which uses:

const uint8_t help[] PROGMEM = { 
"\
Program version "__DATE__" "__TIME__"\r\n\n\
1 - toggle LED1\r\n\
2 - toggle LED2\r\n\
3 - toggle LED3\r\n\
....
Y - play fast PWM with 8bit data (fPWM=31,250Hz)\r\n\
"
};

Does this work without any special things needed in a make file?
It seems so easy and is something I have been looking for a long time ago, but stopped then (yes I have been stupid by not asking it here) as I could not find anything close to this.

I use As6 and the internal make file. As I consider myself a dummy I do not want to run into makefile problems. I already have enough issues keeping my code nice, clean and in working order for that matter.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

meslomp wrote:
Does this work without any special things needed in a make file?
Yes. __DATE__ and __TIME__ are provided by the compiler.

http://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Stefan,

thanks for the info (and cliff ofcoarse also) this makes me a happy man. this will save me editting in the future.

regards

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just for future reference. The example I quoted above is a little "confused". It's possibly simpler to use this as an example:

const char version[] = {
"Program version " __DATE__ " " __TIME__ "\n"
};

That generated:

	.section	.rodata.version,"a",@progbits
	.type	version, @object
	.size	version, 38
version:
	.string	"Program version May 31 2013 10:35:26\n"

Add PROGMEM or __flash to personal taste.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

meslomp wrote:
clawson wrote:
It's probably obvious but I actually have the "version" date/time built into the help screen for my program's terminal interface which uses:

const uint8_t help[] PROGMEM = { 
"\
Program version "__DATE__" "__TIME__"\r\n\n\
1 - toggle LED1\r\n\
2 - toggle LED2\r\n\
3 - toggle LED3\r\n\
....
Y - play fast PWM with 8bit data (fPWM=31,250Hz)\r\n\
"
};

Does this work without any special things needed in a make file?

One needs to make sure that it is recompiled for every build.
That is why I put such things in the link step.

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

One needs to make sure that it is recompiled for every build.

That's why I added a command to "touch" the .c where this was located at the start of each build ;-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Quote:

One needs to make sure that it is recompiled for every build.

That's why I added a command to "touch" the .c where this was located at the start of each build ;-)
Where do you put the touch?
Will it cause a redundant build?

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Where do you put the touch?

Makefile.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
clawson wrote:
Quote:

One needs to make sure that it is recompiled for every build.

That's why I added a command to "touch" the .c where this was located at the start of each build ;-)
Where do you put the touch?
Will it cause a redundant build?
clawson wrote:
Quote:

Where do you put the touch?

Makefile.
Where in the make file?
Will it cause a redundant build?

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Will it cause a redundant build?

Not sure what you mean by a "redundant build". If nothing else has changed but you "make" then yes the file will be touched, compiled and cause a link but I'm not sure I see why this actually matters?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Quote:

Will it cause a redundant build?

Not sure what you mean by a "redundant build". If nothing else has changed but you "make" then yes the file will be touched, compiled and cause a link but I'm not sure I see why this actually matters?
It just seems untidy, uncompact and unnecessary.
fred.elf: $(fred_deps)
        $(MAKE) --always-make datetime.o
        $(LD) $(LDFLAGS) -o $@ $^ datetime.o $(LDLIBS)

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why would you "make" if you haven't actually edited anything?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Why would you "make" if you haven't actually edited anything?
I wouldn't.
Not everyone is pefect.

Moderation in all things. -- ancient proverb