How to embed version information into shared library and binary?

10,257

Solution 1

One way to do it if using cvs or subversion is to have a special id string formatted specially in your source file. Then add a pre-commit hook to cvs or svn that updates that special variable with the new version of the file when a change is committed. Then, when the binary is built, you can use ident to extract that indformation. For example:

Add something like this to your cpp file:

static char fileid[] = "$Id: fname.cc,v 1.124 2010/07/21 06:38:45 author Exp $";

And running ident (which you can find by installing rcs) on the program should show the info about the files that have an id string in them.

ident program
program:
    $Id: fname.cc,v 1.124 2010/07/21 06:38:45 author Exp $

Note As people have mentioned in the comments this technique is archaic. Having the source control system automatically change your source code is ugly and the fact that source control has improved since the days when cvs was the only option means that you can find a better way to achieve the same goals.

Solution 2

To extend the @sashang answer, while avoiding the "$Id:$" issues mentioned by @cdunn2001, ...

You can add a file "version_info.h" to your project that has only:

#define VERSION_MAJOR "1"
#define VERSION_MINOR "0"
#define VERSION_PATCH "0"
#define VERSION_BUILD "0"

And in your main.c file have the line:

static char version[] = VERSION_MAJOR "." VERSION_MINOR "." VERSION_PATCH "." VERSION_BUILD;
static char timestamp[] = __DATE__ " " __TIME__;

(or however you want to use these values in your program)

Then set up a pre-build step which reads the version_info.h file, bumps the numbers appropriately, and writes it back out again. A daily build would just bump the VERSION_BUILD number, while a more serious release would bump other numbers.

If your makefile lists this on your object's prerequisite list, then the build will recompile what it needs to.

Solution 3

The Intel Fortran and C++ compilers can certainly do this, use the -sox option. So, yes there is a way. I don't know of any widespread convention for embedding such information in a binary and I generally use Emacs in hexl-mode for reading the embedded information, which is quite hackish.

'-sox' also embeds the compiler options used to build an executable, which is very useful.

Share:
10,257
zer0stimulus
Author by

zer0stimulus

Updated on July 18, 2022

Comments

  • zer0stimulus
    zer0stimulus almost 2 years

    On Linux, is there a way to embed version information into an ELF binary? I would like to embed this info at compile time so it can then be extract it using a script later. A hackish way would be to plant something that can be extracted using the strings command. Is there a more conventional method, similar to how Visual Studio plant version info for Windows DLLs (note version tab in DLL properties)?

  • cdunn2001
    cdunn2001 almost 12 years
    ident was once very useful, but embedding $Id$ strings has become unwise in the world of distributed Version Control Systems. It confounds diffs and merges.
  • nt86
    nt86 about 3 years
    Looks like -sox embeds only compiler version, but not the library version itself.
  • Johan Boulé
    Johan Boulé over 2 years
    The address is not the file offset. To obtain the file offset, you need to substract the section address, and add the section file offset. You obtain those values with objdump -h .rodata. The .data section indicates that you didn't declare the constant as const program_version[] = "xxxxxxxxxxxxxxxxxxxx"; otherwise it would be .rodata. For patching, it really needs to be the read-only section. Also, you may want to read the runtime symbol table rather than the debugging table, i.e. use -T and not -t.