Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  <2017 Index 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  <2017
<== Date ==> <== Thread ==>

Subject: Re: exporting module versions
From: Dirk Zimoch <>
To: Mark Rivers <>, "" <>
Date: Thu, 2 Nov 2017 15:58:02 +0100
Hi Mark,

Not that many driver-like modules actually have an API. Only the generic ones like asyn or devLib2 do. And particularly there it is desirable to be a bit more careful with changes. For example not to re-order function tables needlessly should not be too difficult.

In my opinion (and experience) it is not too much work to try to stay backward compatible. In particular compared to debugging situations when compile-time and link-time interfaces (i.e header files and dynamic libraries) don't match. And this does happen in real life.

And it is not only IOCs. The base libraries Com and ca are used by many client programs or programming language interfaces. To find them all and re-build them is a problem as soon as more systems than "my beamline" is affected.

To opt against compatibility sound to me like: "I don't care if other people have problems with my changes." But we are in a community, where other people have to live with our changes.

BTW: This is exactly what I hate with the Linux kernel changes. And this is probably why so many manufactures do not want to provide Linux drivers for their products.


On 02.11.2017 14:32, Mark Rivers wrote:
Hi Dirk,

I agree that ABI compatibility is desirable in theory.  It is essential for things like operating system libraries.  But for EPICS applications a cost/benefit analysis is needed.  I would argue that for the limited number of libraries needed for CA clients (libCom and ca) having ABI compatibility is good, we can replace those libraries without having to relink.

But for IOCs is it worth it?  The main benefit for having ABI compatibility is eliminating the time needed to rebuild the IOC application.  However, on my Linux system rebuilding everything except EPICS base and V4 (i.e. synApps, seq, asyn, stream, areaDetector and over 100 IOCs) takes 113 seconds which is pretty quick.  Not having ABI compatibility does mean that I need to maintain the source code trees so that this rebuild is possible.  But I better do that anyway in case I need to change the configuration of an IOC or add a new one.  The cost of ABI compatibility is to constrain the developer from making the types of internal changes we currently do.  We would also need to make major releases much more frequently which may intimidate or confuse sites who only care about API compatibility.

I would be curious to know how many sites currently try to simply replace libraries (e.g. libCom, ca, asyn, seq) for their IOCs, or would do so if it was better supported, compared to rebuilding from scratch?

In my experience the larger problems are in the lack of ability to deploy binaries across various OS versions.  I can't build an application on my Centos 7 development system and deploy it on RHEL 6.  (I can build an application on Windows 10 and deploy it on XP.  Microsoft does a better job here.)  The C++ compiler runtime ABIs are typically not backward compatible from one release of a compiler to the next.  This is certainly true of Visual Studio, and it is true for certain versions of g++ as well.


From: <> on behalf of Dirk Zimoch <>
Sent: Thursday, November 2, 2017 7:42 AM
Subject: Re: exporting module versions

On 02.11.2017 11:18, Ralph Lange wrote:
Hi Dirk,

On Thu, Nov 2, 2017 at 10:23 AM, Dirk Zimoch <
<>> wrote:

    [...]  I also opt for binary backward compatibility, so that it is
    always possible to replace a dynamic library with a newer version
    without needing to re-build all programs. Forcing a program to link
    only with a very specific library version is, in my opinion, not
    very maintenance friendly.

As you seem to have experience with that: which tools / methodology do
you suggest to detect and track ABI changes in libraries, especially
libraries created from C++ sources?


I don't know any tools to support compatibility checks, but here is what
I try to do:

* Never remove API functions (declaring them depreciated is OK)
* Never change the signature of an existing (extern C) function (
an incompatible way. Signedness change is often OK. Adding const or
volatile where appropriate is also often OK. Changing 32 bit args (like
int) to potentially 64 bit args (e.g. size_t) is only OK if no 64 bit
was supported previously, but that is already ancient history.)
* Never change the semantics of an existing function (e.g. swap src and
dest parameters in some copy function)
* Never remove, re-order, or change size of the fields of a structure
that is used in an API.
* Add new fields only ever at the end of structure passed to API
functions by reference (and then handle cases gracefully where the
fields don't exist).
* Never remove or re-order virtual methods (the same for non-C++
function tables like in asyn).
* Expose as little as possible in the API. Not all functions are API
functions, not all structures/classes are used in the API. Not all
Macros are part of the API. Keep public and private header files
separate. Do not install private headers. This allows to change any non
API function, class, etc. at any time without breaking the API.
* Do not put private fields/methods in API classes. If private members
are needed, inherit from a API base class without private members. APIs
are not private.

As it is often not feasible to be so strictly backward compatible, I
suggest (any use in my software) the following rules:

* A version consists of 3 numbers: major.minor.patch
* Whenever a change is not binary backward compatible, the major number
* Whenever there are new features, the minor number increases.
* Whenever a bug is fixed without a new feature, the patch number
increases. (A bugfix may be incompatible in so far that the
incompatibility was the actual bug that has been fixed.)
* In linking use the major number in the file name to ensure no
incompatible version can be used.
* Do not use the minor number or patch number in linking in order to
allow upgrading the library.

See also how Linux (or GNU) does it: /bin/bash on my computer is linked
to which is a symbolic link to Note that
is is not linked to version 5.7 but only to version 5. This allows to
upgrade the library to 5.8 but not to 6.0 without having to rebuild the

Or: softIoc on my computer is linked to which is a
symbolic link to

I have no idea how to automatically check for backward compatibility
when releasing a new version. I can imagine checking function and
structure/class signatures automatically. But how to check for semantic


exporting module versions Michael Davidsaver
Re: exporting module versions Andrew Johnson
Re: exporting module versions Dirk Zimoch
Re: exporting module versions Ralph Lange
Re: exporting module versions Dirk Zimoch
Re: exporting module versions Mark Rivers

Navigate by Date:
Prev: Re: exporting module versions Torsten Bögershausen
Next: Re: exporting module versions Andrew Johnson
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  <2017
Navigate by Thread:
Prev: Re: exporting module versions Andrew Johnson
Next: RE: exporting module versions Mark Rivers
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  <2017
ANJ, 02 Nov 2017 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·