![]() |
Dependent version checkingThis memo is a proposal for a mechanism that allows cooperating components to divulge their own versioning information and compare that to their import requirements. In order for this to be effective, all cooperating component libraries have to include certain capabilities (defined below). This mechanism's goal is to provide definitive proof that the product environment (made up of one or more shared libraries) is consistent within itself. It does not provide static checking that might cause ungraceful termination of an application. Nor does it provide early detection of inconsistencies such that might be used to drive selective loading of shared libraries. Version informationSoftware components can be identified generically by name (regrettably I don't know anything better than ASCII). For simplicity the version of the software component may also be identified by an ASCII string. The string's content is not significant since (as will be described later) only the component presenting the version string need understand its makeup.Discovering a component's identity and versionA component will advertise it identity and version through use of static defines in a well-know header. Using NSPR as an example, these constants might show up in a header named prvrsion.h and look like:#define PR_NAME "NSPR 2.0" #define PR_VERSION "199770530"Note: It would be expected that the name of the component ("NSPR 2.0" in this example) would not change for the lifetime of the product. Along with these two constants, each component must provide a function capable of returning a boolean answer indicating that available library is compatible with the expectations of the caller. That function has a signature as follows: typedef PRBool (*version_check)(const char *imported_version);The importer would literally code this call as (using NSPR as an example):
if (!PR_VersionCheck(PR_VERSION))
{
...version check fails...
}
At the time a version check routine is called the code should evaluate
the string passed in as the argument with the version the library is exporting.
This string will contain the literal value that was defined by environment
in which the importing component was built. The called function will compare
the string to the value known to it, which represents the value captured
at its build time. During the execution of the version check function is
the opportunity for the called component to verify its dependencies as
well. The answer returned will be the logical union of all the responses.
Caution: Circular dependencies could be a problem. Version Embedding SpecificationIntroductionA complicated product or suite of products can require a huge number of shared libraries. Over time, each of these libraries is patched numerous times. One of the most pressing questions when debugging a field escalation is "What versions of the libraries are installed?". Often, problems can be attributed to wrong installed versions, incompatible versions, etc. So, what remains is how to answer the question "What libraries are installed?". This specification proposes a mechanism for answering that question.BackgroundWindows NT long ago addressed this issue by the use of standardized version resources embedded in libraries. The NT installer uses these version numbers when making decisions as to whether or not to overwrite libraries. This proposal allows for similar capabilities on a wider variety of platforms.MechanismWe define a C structure to contain version information. We then define a well-known function that all libraries should expose. We also define a naming convention for the instances of the structure to aid in locating them in a core file.Version structureThe structure we use is listed below. The first field is intended to allow future extensions to this specification. Version 2 of the body is listed below. If the version is not 2, no statement is made about the contents of the body at this time. Time is expressed in the format exposed by NSPR's PRTime. Special builds are intended for non-RTM builds. This could be a private patch, a prototyped change, etc. If special is true, the specialString should be set. All strings are optional, and should be set to NULL if not utilized.#include <prtypes.h>
typedef struct {
PRInt32 version;
PRTime buildTime;
char * buildTimeString;
PRUint8 vMajor;
PRUint8 vMinor;
PRUint8 vPatch;
PRBool beta;
PRBool debug;
PRBool special;
char * filename;
char * description;
char * security;
char * copyright;
char * comment;
char * specialString;
} PRVersionDescription;
The PRVersionDescription does use NSPR's typing and type semantics, though is not dependent on NSPR 2.0. There are, however, utilities available for accessing the information defined by the structure, and they do utilize features of the runtime. Some caution should be taken regarding this apparent circular dependency.
InterfaceAll components supporting the version protocol must expose a C function named libVersionPoint.All components should also expose their PRVersionDescription structure using the following naming convention.const PRVersionDescription *libVersionPoint(void); Take the filename field from the structure. Convert non-alphanumeric characters to "_". Prepend "PRVersionDescription_". Use this as the name.So, for libfoo.so, the name would be PRVersionDescription_libfoo_so. If the filename field is not set, take PR_Now() and
print it using PR_snprintf(). Append this to "PRVersionDescription_".
The first form is the preferred form.
Last updated: Wed Jul 23 16:28:40 PDT 1998
|
|||||||||||||||||||||||||||||||
|
Copyright © 1998-2000 The Mozilla Organization.
Last modified July 24, 1998. |
|||||||||||||||||||||||||||||||