On 09/12/2021 02.58, miim wrote:
I am not sure if this is a question for this list or for the APR forum, but it seems to me that this forum is more likely to have an answer. To what extent can I expect a module compiled on system A to be portable to system B: -- if both are running the same distribution of linux, though possibly not the same release -- if system A and system B are both running Apache 2.4.x, though possibly not the same release -- if system A has a custom-built Apache and system B has a distribution release of Apache I'm asking because several people don't want to compile their own modules (can't imagine why, it's so easy an Einstein can do it) and asked for ready-to-go kits that they can drop in and go. APR seems to me to be a black box, and if one of my modules calls a reslib that may not be present in another machine or at a different level, it seems to me there's potential problems there; and yet APR being a black box, it is going to be difficult to force static linking against libraries instead of resident libraries if APR intends to go that way.
Linux distributions ship some 3rd-party modules (libapache2-mod-auth-kerb for kerberos authentication for example). I've noticed that there are regular updates of apache-2.4 packages without offering updates for the 3rd-party modules. So in many situations patch version number changes of apache-2.4 do not require rebuilds of the 3rd-party modules.
The apache source API is guaranteed not to change among releases having the same major and minor version numbers.
The immutability of the ABI (binary interface) does not really depend only on apache, but depends on your build tool chain too. For example if your code contained C++, some time ago there was a change in the ABI of C++ objects (std::string, std::list). (Debian/Ubuntu addressed this problem by creating packages with names such as libFOOv5 (note the v5). Slowly all libraries migrated to the new ABI and these names were phased out. So if your distributed your module as a package then it would not have installed because on one distribution it would depend on libFOO and on the other FOO is distributed in libFOOv5.)
Another example: If your module depends on boost or on other header-only C++ library then your binary module will contain the code of the functions and the static data that it uses from boost. Let us assume that you've built it on distribution 1.0 with libboost 1.6 and your code uses an object of class X from libboost. On distribution 2.0 someone builds another module using boost 1.7 and uses the same object of class X. However class X has a different binary layout in boost 1.7 than in boost 1.6. So your module would function correctly as long as it is the only module using libboost that is loaded into apache. As soon as you have two modules using libboost, the runtime linker will load the object of class X symbol twice. It will retain only one instance. As the layout of the retained class X's symbol is incompatible with one of the modules that uses it, the execution will crash.
There are solutions to such situations. You significantly increase the chances of binary compatibility if, when linking your module, you instruct the linker to put absolutely all symbols as hidden (private to the shared object) except the module structure. So the only global symbol of your binary module should be the module structure. (See ld's man page, the --version-script option.) Then the runtime linker, when loading the two shared objects of the two modules using boost, will load two instances of the class X object. They'll have different layouts, each used by its respective module and the crash is avoided. (Run "nm -aC mod_mymodule.so" to see all symbols of your module and consult nm's man page for an explanation of its output. Basically upper-case letters in the second column of the output denote global symbols and lower-case letter denote module-local symbols. Ideally the only globally defined symbol of your binary should look like this: "00000000012192a0 D my_module". Note the upper-case D.)
That said, it is very likely that the module build on one distribution is installable and running correctly on a more recent distribution. The situations in which it does not work are really idiosyncratic.
I think you should not worry at all about APR. It is the least likely to cause a binary incompatibility between distributions. When the ABI of libapr changes it'll be big news.
HTH, Sorin