tags:

views:

261

answers:

3

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.

+2  A: 

Maybe you could create a string with the version like this:

char* library_version = { "Version: 1.3.6" };

and to be able to check it from the shell just use:

strings library.a | grep Version | cut -d " " -f 2
Puppe
You would, of course, make that `const char library_version[] = "1.3.6";` to save the space for the pointer. And you would declare the variable in the library's header (or in a header distributed with the library).
Jonathan Leffler
please recheck my question - it was updated
Pirks
Added info for checking the version from a shell
Puppe
+2  A: 

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):

#define MYLIB_MAJOR_VERSION 1
#define MYLIB_MINOR_VERSION 2
#define MYLIB_REVISION 3
#define MYLIB_VERSION "1.2.3"
#define MYLIB_VERSION_CHECK(maj, min) ((maj==MYLIB_MAJOR_VERSION) && (min<=MYLIB_MINOR_VERSION))

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:

if (! MYLIB_VERSION_CHECK(1, 2)) {
    fprintf(stderr, "ERROR: incompatible library version\n");
    exit(-1);
}

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:

struct {
    const char* string;
    const unsigned major;
    const unsigned minor;
    const unsigned revision;
} mylib_version = {
    MYLIB_VERSION, MYLIB_MAJOR_VERSION, MYLIB_MINOR_VERSION, MYLIB_REVISION
};

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.

jheddings
The only issue with the MYLIB_VERSION_CHECK that I see is that it is evaluated at compile-time, and a good optimizer will remove the check if everything is OK, and will unconditionally call printf() - you meant fprintf(stderr, ...), didn't you? - and exit(). I think it would be better to call a function that embedded the logic rather than use a constant expression.
Jonathan Leffler
Yeah, good points here... I later edited my post to include embedding the information in the library for this reason. Thanks for the clarification.
jheddings
please recheck my question - it was updated
Pirks
+1  A: 

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:

ar t libmylib.a | grep 'version_' | sed -e 's/^version_//'

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.

jheddings