Here is a quick tip on how to insert the svn revision number in your c/c++ code. This is a simple Makefile trick that will define a preprocessor constant that holds the revision number of your project. It only works if you are using gcc as your compiler, and GNU version of make. You will also need a small utility called svnversion (On ubuntu, it should come with the subversion package).
gcc has a command line option “-D” which will define a preprocessor constant.
So doing:
1 | gcc -DHELLO_THERE ... |
is similar to defining the constant in your code as such:
1 | #define HELLO_THERE |
So we are going to use that trick.
On your make file:
1 2 | SVNDEV := -D'SVN_REV="(shell svnversion -n .)"' CFLAGS := $(SVNDEV) ... |
That was taken from here
Note: in the definition of SVNDEV, notice the dot after svnversion -n. The dot means in the current directory in which your building your code, so if you are issuing the make command outside of the svn’d directory, it won’t work. You will get “export” instead of a revision number.
In Eclipse
In Eclipse, the building directory is different from the src directory and so if you don’t have that directory in svn, you will get “export” instead of a version number. So in eclipse the easiest way I found to do this is to replace the dot with the project_loc variable. You would do this in Project->Properties->C/C++ Build->Setting->Preprocessor( or Symbols in case of C):
1 | 'SVN_REV="$(shell svnversion -n ${project_loc})"' |
After you do all that, you can use SVN_REV as any preprocessor define. So you can print out the version number like this:
1 2 3 | cout << "Version: SVN " << SVN_REV << endl; //or printf ("Version: SVN %sn", SVN_REV); |
NB: SVN_REV is not just a number in c/c++, its a text (const char *).
More info:
http://subversion.tigris.org/faq.html#version-value-in-source (has another way of doing this)
http://svnbook.red-bean.com/en/1.1/re57.html
EDIT:
I found out that putting the SVN_REV define in eclipse’s project build settings slowed down my building process extremely. The reason was that make was running svnversion to evaluate SVN_REV for every file it was compiling. Instead, I found a much better way. If you look at the makefiles that Eclipse CDT generates, it includes a makefile.defs file thats non-existent.
1 2 3 4 5 6 7 8 9 10 11 12 13 | ... ifneq ($(strip $(C_UPPER_DEPS)),) -include $(C_UPPER_DEPS) endif endif -include ../makefile.defs # Add inputs and outputs from these tool invocations to the build variables # All Target all: pre-build main-build ... |
This I believe is left for users to define their own symbols, best place for SVN_REV. This way, SVN_REV is evaluated once. So you would do this in the makefile.defs
1 | SVNREV:='"$(shell svnversion -n ${project_loc})"' |
and set
1 | SVN_REV=$(SVNREV) |
in the projects build settings.
Notice how SVNREV:= has the colon before the equal sign. This tells make to evaluate SVNREV only once. If we used just the equal sign, SVNREV will evaluated for every file defeating the purpose of moving it to makefile.defs.
Moreover, I found a better definition for SVN_REV reading through a project called coreboot (open source bios). This definition finds the file with the latest commit version number
1 | SVNREV:='"$(shell LC_ALL=C svnversion -cn ../ | sed -e "s/.*://" -e "s/\([0-9]*\).*/\1/" | grep "[0-9]" )"' |
Hi,
I found out about SubWCRev. It is part of TortoiseSVN. It make it much easier to get rev information. Of course it only appears to run on windows. On the bright side, it does give the highest SVN number of all your files — so its a bit more sophisticated than the other methods.
Thought you might be interested.
-Stosh
Looks like a good tool even though it doesn’t work on Linux. The same thing (having a template of keywords and an output file) can be accomplished by using a build utility such as “make” or “ant”. I actually have a working version of the ant build, which I can post if you are interested. I will have to look into how to do it using “make” but it shouldn’t be hard.