| || |
When partitioning the functionality of your project into libraries, and particularly loadable modules, it easy to inadvertantly rely on modern shared library features such as back-linking or dependent library loading . If you do accidentally use any of these features, you probably won't find out about it until someone first tries to use your project on an older or less featureful host.
I have already used the `-module' and `-avoid-version' libtool linking options when compiling the libltdl module in the last section, the others are useful to know also. All of these are used with the `link' mode of
libtool ( `libtool --mode=link' ):
- This option tells
libtool that the target is a dynamically loadable module (as opposed to a conventional shared library) and as such need not have the `lib' prefix.
- When linking a dynamic module, this option can be used instead of the `-version- info ' option, so that the module is not subject to the usual shared library version number suffixes.
- This is an extremely important option when you are aiming for maximum portability. It declares that all of the symbols required by the target are resolved at link time. Some shared library architectures do not allow undefined symbols by default (Tru64 Unix), and others do not allow them at all (AIX). By using this switch, and ensuring that all symbols really are resolved at link time, your libraries will work on even these platforms. See section 11.2.1 Creating Libtool Libraries with Automake.
- Almost the opposite of `-no-undefined' , this option will compile the target so that the symbols it exports can be used to satisfy unresolved symbols in subsequently loaded modules. Not all shared library architectures support this feature, and many that do support it, do so by default regardless of whether this option is supplied. If you rely on this feature, then you should use this option, in the knowledge that you project will not work correctly on architectures that have no support for the feature. For maximum portability, you should neither rely on this feature nor use the `-export-dynamic' option -- but, on the occasions you do need the feature, this option is necessary to ensure that the linker is called correctly.
When you have the option to do so, I recommend that you design your project so that each of the libraries and modules is self contained, except for minimal number of dependent libraries, arranged in a directional graph shaped like a tree. That is, by relying on back-linking, or mutual or cyclic dependencies you reduce the portability of your project. In the diagrams below, an arrow indicates that the compilation object relies on symbols from the objects that it points to:
| || |
main .---> main main .----+----, .----+----, .----+----, v v v v v v liba libb liba libb liba<-----libb ^ v v v libc libc libc-------' Tree: good Backlinking: bad Cyclic: bad