How can I store a version number in a static library (file.a) and later check for its version in Linux?
P.S. I need possibility to check version of file any time without any special executable using only by shell utilities.
How can I store a version number in a static library (file.a) and later check for its version in Linux?
P.S. I need possibility to check version of file any time without any special executable using only by shell utilities.
If you are using gcc, you can use the #ident directive
To get the version just use one of the following:
This will allow you to compile the version into the library with the capability of later stripping it out using
strip -R .comment your_file
or completely omit it by passing-fno-ident
(This will also omit the compiler version comments from the compiled objects)Creating a new answer based on your edit... Just to avoid confusion :)
If you are looking for a non-code way to solve the problem, you could try this. It's (yet again) an alternative to the
strings
approach defined by Puppe.Maybe you could just touch a file called
version_1.2.3
and add it to the archive. Then, you could determine the version by looking for the version file using the ar command:I'm not sure if that will get you what you need, but there is no standard method for embedding metadata like this in an archive. Maybe you'll find other information you want to store in this "metafile" for the archive.
Several times
man 1 ident
has been mentioned, so here are details about using that method.ident
is a command that comes with the RCS (Revision Control System), but might also be available if you are using CVS (Concurrent Versions System), or Subversion.You would use it like this (cloned from the man page):
and f.c is compiled into f.o, then the command
will output
If your
f.o
were added to a static libraryf.a
thenident f.a
should show a similar output. If you have several similarly built[a-z].o
in youraz.a
you should find all their strings in theaz.a
file.CAVEAT: Just because they are in the .a file doesn't mean they will be included in your program file. Unless the program references them the linker sees no need to include them. So you usually have to have a method in each module to return the string, and the app needs to call that method. There are ways to convince most linkers that it is a required symbol without actually referencing it, but it depends on the linker, and is beyond the scope of this answer.
If instead you are familiar with the SCCS (Source Code Control System) then you would use
man 1 what
instead, and it would look like this (done with macros to show the flexibility available):and f.c is compiled into f.o, then the command
will output
PS: both
ident
andwhat
are commands that come with specific centralized source control systems. If you are using a distributed source control system (like git) the entire concept may not make sense. For some ideas usinggit
see this thread: Moving from CVS to git: $Id:$ equivalent? though the hash isn't the same as a version number. :)Maybe you could create a string with the version like this:
and to be able to check it from the shell just use:
In addition to providing a static string as mentioned by Puppe, it is common practice to provide a macro to retrieve the version check for compatibility. For example, you could have the following macros (declared in a header file to be used with your library):
Notice with the
MYLIB_CHECK_VERSION
macro, I'm assuming you want a specific major rev and a minor rev greater than or equal to your desired version. Change as required for your application.Then use it from a calling application, something like:
This approach will cause the version information to come from the included header file. Additionally, it will be optimized at compile time for the calling application. With a little more work, you can extract it from the library itself. Read on...
You can also use this information to create a static string stored inside your library, as mentioned by Puppe. Place something like this inside your library:
This will create a struct called
mylib_version
in your library. You can use this to do further verifications by creating functions inside your library and accessing those from a calling application, etc.