Code revision inserted into binary

03 Feb 2012

Hi all,

I'd like to have an automatic way of inserting version numbers into the compiled code.

Perhaps the commit level (+1 for every commit) and compile level (+1 for every compile of that commit level).

Feel free to ignore this if it's already possible through clever use of C and/or whatnot, I'm new to this C thing.

/Hugo

05 Feb 2012

+1

I'd like this too. If it is already possible a pointer to how to do this would be great.

TIA.

11 Jul 2014

I agree that this would be very desirable!

11 Jul 2014

I too agree. This isn't the first thread asking for this.

The closest thing available that I'm aware of are the standard DATE and TIME macros, and obviously these are not traceable like a revision number. I could rebuild a project weeks later and create an "old" version - other than the date stamp, and it is difficult to prove.

For lack of a better solution, I often do this:

const char * PROG_INFO = "My Apps Name: " __DATE__ ", " __TIME__;

Then I emit it to the USB serial port and/or to a connected display.

But like you, I wish the build environment slipped in something like:

-D=REV_MAJOR=58
-D=REV_SERIAL=26658a56112a
-D=REV_STATUS=SYNCED (or REV_STATUS=CHANGED)

With this, it would be reasonably traceable to a specific version, or at least to identify the version it was derived from. With this, not just the program, but each library can be identified.

23 Sep 2014

Can we please get this in the feature request list? When using mbed for anything more than a hobby project this is critical....

I agree with David's suggestion, how about this:

- REV_MAJOR = "45\0\0"
- REV_HASH="26658a56112a"
- REV_DATE="2014-01-01 12:00:00"

Or when modified:

- REV_MAJOR = "45+\0"
- REV_HASH="UNCOMMITED\0\0"
- REV_DATE="2014-01-01 12:00:00"

Note the zero padding to prevent stuff from shifting around in the binary when the value changes. It would also be really nice if this would (optionally) generate a binary with the following name:

<ProjectName>_REV_26658a56112a.bin

22 Oct 2014

Ping... Anyone? :-/

21 Dec 2014

+1

At this time I would be happy with just the revision for my committed code ("REVISION", with space or + for uncommitted). In the long run to support tracing where new bugs cropped up then add: - version of the compiler itself - revision of each linked library, maybe as defined value in an autogenerated header file when library is compiled/committed?

29 Dec 2014

PING! This seems pretty trivial to implement.... Mbed wants to profile themselves as a platform for prototyping that scales well into production. Proper version and release management is CRITICAL for production.

12 Jan 2015

Hi guys,

Can you use our build system timestamp to mark your builds?

-DMBED_BUILD_TIMESTAMP=1406208182.13

Adding this functionality requires actually some hassle.

  • You need to always rebuild file with "version".
  • Few question also arises:
  • HASH: hash of what?
  • COMMIT: how we can detect you did commit in your project?
  • COMPILE ? REVISION counter: how to make sure your compilation counter is consistent the same across your project? Example: We both are on the same team. I compile and build, you also. And your compilation counter should be at least +1 bigger than mine.

I can say forcing mbed SDK workspace tools build API to produce binary with make containing for example compilation date is not a problem at all. E.g. my_project_20150112_091253.bin -> 12/01/2015 09:12:53 (local machine time).

I think those problems can be solved but some limitations would be applied.

/Przemek

12 Jan 2015

Hi Przemek,

The HASH would be the git commit hash:

/media/uploads/jaerts/hash.png

I'm not sure how the revision number worked when multiple people are working on the same project, but I think it would still be useful to have as an indicator (especially when only 1 person is working on it). The HASH is obviously the true unique indicator.

The timestamp is somewhat handy, but makes it difficult to track it back to a state of the code repository.

Thanks for looking into this.

Regards, Joris

12 Jan 2015

@joris, git SHA is a good candidate. The build scripts might be replaced by another tool, which should take care of this. So if you need immediate solution, feel free to add this to the tool scripts.

12 Jan 2015

For hash I propose calling:

$ git rev-parse HEAD
70391ec98521fe7b7297c492000df12c2fa2984b

or

$ git rev-parse --short HEAD
70391ec

I think second one will work well with file name, e.g. project_70391ec.bin

12 Jan 2015

+1 for short :-)

I believe guys here refer to have a revision also in the sources?

12 Jan 2015

Yes, so what I propose is that we add new switch to build api tools (build.py, make.py, singletest.py) so people can inject stamp from command line and add to -D section something like this:

build.py -t ARM -m LPC1768 --HASH=`git rev-parse HEAD`

to produce project_<GIT_HASH>.bin

build.py -t ARM -m LPC1768 --HASH=`date.exe +"%Y_%m_%d" /T`

to produce project_<WINDOWS_DATE>.bin

We can use HASH to add new -D option for compilation (people can use -c option to always rebuild to get fresh HASH in compilation.

12 Jan 2015

A) Is the mbed compiler version control based on git? i.e. can you retrieve the same versions directly with git as you can with the mbed compiler or projects on the mbed website? It would be best if a consistent version method existed between any git/github back end, and the online mbed compiler version control.

If using git/github then maybe there is a $Revision:$ feature that already exists for version info insertion in source files? (CVS had, I expect git has something)

'==========

B) Basically versions of anything that would affect the output hex file's contents. This is required for reliability/history/debugging of projects going to production.

  • Dates are a bonus, but file's date can change when moved between systems so a version/revision is required for tracking.
    • Build UTC Date/Time available today: <<code>> __DATE__ __TIME__ <</code>> == [ Jan 12 2015 18:04:48 ]
  1. A revision of the sources (This is the primary)
    • OptionA: a revision.h automatically generated when project committed, and automatically added to project.
    • OptionB: a string that is automatically replaced in a source file when committed/retrieved (like $ProjectRevision:$),
      • This should be the Project's/Library's overall commit revision
      • Option: A separate $FileRevision:$ would be a bonus showing when that particular file was last updated
      • Need $ProjectRevision:$ type as trying to determine the latest Revision from a bunch of $FileRevision:$ would be messy
      • If the file is modified in compiler and uncommitted, the revision should change to something like "0" (==unknown) or "r23m" (==revision 23 modified).
    • OptionC: A predefine that returns the currently checked out revision of the Project (i.e. "23" or "r23")
      • Bonus if something appended indicating modified from the committed version (i.e. "23m" or "r23m")
  2. A revision for each library (Future?).
    • If the project version changes when library is updated then may not need the library revision visible outside the compiler, as the revision of the library can be seen when open the project in the mbed compiler.
    • If library can be updated without project commit then libraries may need a standard function to retrieve their own commit version to avoid conflict with other revision.h in project and other libs), as including the library's autogenerated revision.h would have definition conflicts with project's own revision.h.
  3. A version for the mbed compiler generated during compile (Future or existing?)
    • bonus if also a version for compiler used during commit (could help debug if a project stops working correctly between last commit and now).
    • Available today: <<code>>__VERSION__ <</code>> == [ 4.2 (EDG g++ mode) ]
12 Jan 2015

Paul, Thank you for your description, this looks like a big feature . That you want is a big change in online compiler, what we can give is similar functionality for off-line tools.

/Przemek

12 Jan 2015

I wouldn't expect all of that, just wishful. but a way to get the project revision would be quite useful.

FYI, predefines available today that work with the mbed online compiler:

<<block>>
ARM Compiler Predefines:   [Output of predefine in square brackets]
   __DATE__ (Compile UTC)  [Jan 11 2015]
   __TIME__  (Compile UTC) [20:01:15]
   __arm__                 [1]   
   __ARMCC_VERSION         [5030117]=[P:major V:minor bbbb:build]
   __VERSION__(gnu)        [4.2 (EDG g++ mode)]
   __OPTIMISE_LEVEL        [3]   
   __OPTIMISE_TIME         [1]
   __MODULE__              [main.cpp] 
   __FILE__                [/src/main.cpp] 
   __BASE_FILE__           [/src/main.cpp]
   __FUNCTION__            [main] 
   __PRETTY_FUNCTION__     [int main()]
<</block>>
12 Jan 2015

Imho this doesnt have to bee that complicated. If we could start with putting the git SHA in a predefine and ideally the filename, that would be a great start. The rest is all nice to have.

12 Jan 2015

@joris, the filename? Please provide details, might help to envision ;)

13 Jan 2015

I think this is what Joris means (correct me if I'm wrong)

current file download

test_app_LPC812.bin


To be replaced with the following and ejected from the online IDE.

new hash naming

-D BUILD_HASH  // created as a pre-compilation step and available to the program at compile time
and...
hash_program-name_target.bin (or hex :D)


and I think HASH is refering to the mercurial hash for a given program, not submodule or libaray

13 Jan 2015

I think it is better to not put the hash in the front of the file name: Then the old versions in your download folder get placed everywhere, file name - target name first is imo best, and then you can put whatever you want at the end of the file name.

13 Jan 2015

@Erik, Agree.

@Sam, yes for a given program. Thanks for a code snippet ;)

we are getting closer to a final proposal , good work guys. This would be applied in the online enviroment here on mbed (= mercurial), initially at least.

13 Jan 2015

Yes I was referring to inserting the short mercurial hash in the filename and a magic variable:

__APP_SHA_SHORT__                ["d9f7121\0"] 
__APP_SHA__                      ["d9f7121e8ebd4d1f789dab9f8214ada2h480b9cf\0"]

Binary name: MyApp_d9f7121.hex

We also need to identify when building source from a repository that has working changes:

__APP_SHA_SHORT__                ["d9f7121+"] 
__APP_SHA__                      ["d9f7121e8ebd4d1f789dab9f8214ada2h480b9cf+"]

Binary name: MyApp_d9f7121+.hex

(Note the 0 padding to keep the strings to the same length)

13 Jan 2015

I have been following this thread with interest.

I am using a "manual" version reporting system based on some of the concepts and utilities from the original Unix sccs tool.

I include a tag string in the main.cpp file and also in the main file of each library:

#define VERSION "0.28"
static const char sccsid[] = "@(#) * "__FILE__" "VERSION" "__DATE__" "__TIME__" ";

I output the tag string in main.cpp to the debug terminal on startup.

If I want to see what my .bin file contains, I use the OS X "what" utility. It works on both source and binary files. For example (the what commands are on lines 3 and 39):

Pauls-Mac-mini:PG230_test paul$ pwd
/Users/paul/Projects/LPCXpresso/PG230_test
Pauls-Mac-mini:PG230_test paul$ what *.cpp */*.cpp
main.cpp
	 * 
BurstSPI/BurstSPI_KL25Z.cpp
BurstSPI/BurstSPI_LPC1768.cpp
DogLCD/DogEffects.cpp
DogLCD/DogGraphics.cpp
DogLCD/DogImage.cpp
DogLCD/DogLCD.cpp
DogLCD/DogText.cpp
DogLCD/font5x7.cpp
Editor/Editor.cpp
	 * 
Editor/editFixed.cpp
Editor/editInteger.cpp
Editor/editList.cpp
Editor/editPassword.cpp
Editor/editText.cpp
Editor/editTimeDate.cpp
Fonts/TahomaBold14px.cpp
Fonts/TahomaBold18px.cpp
Fonts/font6x12.cpp
Fonts/font7x9.cpp
Fonts/font8x7.cpp
Fonts/symbols11.cpp
Fonts/symbols16x8.cpp
Keypad/Keypad.cpp
PwmSound/PwmSound.cpp
PwmSound/play.cpp
SDFileSystem/SDFileSystem.cpp
Semaphore/Semaphore.cpp
UITools/UITools.cpp
UITools/dialogues.cpp
UITools/menu.cpp
UITools/notifications.cpp
Pauls-Mac-mini:PG230_test paul$ cd debug
Pauls-Mac-mini:debug paul$ what *.bin
PG230_test.bin
	 * ../Editor/Editor.cpp 0.25 Jan  3 2015 09:40:31 
	 * ../main.cpp 0.28 Jan  3 2015 09:47:48 
Pauls-Mac-mini:debug paul$ 

I use the * in the tag string to indicate those source files that contain a tag string.

The "what" utility is included in OS X (I am running Mountain Lion). It is available for Linux as part of the cssc package. Google "cssc linux" for details.

Will your proposals result in a VERSION or _VERSION_ macro that I can include in my tag strings? If so, I will be very happy.

Paul

15 Sep 2016

Just curious if the revision or hash has been added in. I have been able to print out the information per Paul's method using:

#define VERSION "0.28"
static const char sccsid[] = "@(#) * "__FILE__" "VERSION" "__DATE__" "__TIME__" ";

It would be nice if the revision number such as 72:72e45f0 or 72:72e45f0+ could also be accessible for printing in log files to help with debugging etc. As Paul mentions and does this can be done manually, but it seems like it would be easy enough to make this information accessible as the DATE and TIME are.