On 1/26/06, Rich Johnson
On Jan 26, 2006, at 11:58 AM, Noel Yap wrote:
Hmm, I've been thinking about this problem but from a different perspective.
First, some definitions: - patch release: the new component is link and load compatible with the old one; clients might need to relink or reload - minor release: the new component is compile compatible with the old one; clients might need to recompile - major release: the new component isn't compatible with the old one; clients might need to modify code
Given the above, a mapping can be made of changes to source to one of the above. I suppose if a component developer follows the above, one could write a class that could easily figure out whether or not a certain M.m.p update is backwards compatible with another.
Also, what really counts are changes to header files. More specifically, changes to published header files (ie header files that are installed so as to be usable by other components).
I LIKE the crispness of your functional definitions. They suggest that there may exist an algorithm determining the ''order'' of a change: - Any change in the interface base class is _at least_ a minor release. - Any change in an implementation derived class is _at most_ a patch release. - Any change in the semantics of the base class interface is _at least_ a major release. - Version stamp can probably be generated by configuration control (i.e. CVS); - Version stamp can probably be used as a _signature_ of the module's interface.
This is exactly my intention. The rub is that automatically generating the release numbers requires a very good C++ parser.
FWIW, a "compiler compatibility" is probably required when dealing with separately compiled modules.
You're right. I hadn't considered that. I'll add it to my list of caveats. Oh, wait, it just occurred to me that I would take care of this by encoding architecture, compiler, and compiler flags into the installation directory name.
Applying the definitions to dynamically loaded libraries where we're _always_ relinking; we come up with: - if patch release; accept - if minor release; reject (you _might_ scoot by with some changes; but why risk it?) - if major release; reject - if compiler incompatible; reject (of course).
The last two are synonymous under my scheme.
Dynamically loaded modules could supply a ''well known'' C function to access their version stamp (or otherwise determine compatibility) prior to instantiating any dynamically allocated objects.
Hmm, I had assumed, probably incorrectly, that components would be installed within a directory whose name encodes the release number. For example, /my/component/1.0/{include,lib}. OTOH, deployment is really orthogonal to this issue. Having a "reflective" function within the component would help in, IMO, messy deployments (eg installing everything in /usr/local).
Now you've got me thinking....
Good. Now there're at least two people I know thinking about this my way :-) Noel