How to embed version information into shared library and binary?
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.
zer0stimulus
Updated on July 18, 2022Comments
-
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 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 about 3 yearsLooks like
-sox
embeds only compiler version, but not the library version itself. -
Johan Boulé over 2 yearsThe 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 asconst 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
.