libfoo.so.major.minor.
When you link a program, the linker ld embeds that information
in the created binary. You can see it with ldd.
Later, when you run that program, the dynamic linker
ld.so uses that information to find the right dynamic library:
The rules for shared libraries are quite simple.
Sometimes, it happens that a library is written as several files, and that internal functions happen to be visible to communicate between those files. Those function names traditionally begin with an underscore, and are not part of the API proper.
Note that the library naming scheme is ubiquitous on OpenBSD platforms, whether they be ELF or a.out.
gcc -shared -fpic|-fPIC -o libfoo.so.4.5 obj1 obj2
Trying to rename the library after the fact to adjust the version number does not work: ELF libraries use some extra magic to set the library internal name, so you must link it with the correct version the first time.
On the other hand, remember that you can override Makefile variables from
the command line, by using MAKE_FLAGS in the port's Makefile.
This is quite valuable in, for instance, libtool-based ports, which provide
one such version variable for each library they create.
The best way to handle libtool-based ports is to set
USE_LIBTOOL=Yes. This activates the ports tree version of libtool,
which handles most details automatically:
SHARED_LIBS and automatically
replaces version numbers.
${WRKBUILD}/shared_libs.log which can be directly
included in the port's Makefile.
ld uses -L flags
to set up paths to look for libraries. It stops looking as soon as
it finds a library that matches its requirements.
ld.so uses the information cached
through ldconfig to find the required library.
qt.1.45 and qt.2.31.
Since both ports can be installed simultaneously, to make sure a given
program will link against qt.1, that library is provided as
/usr/local/lib/qt/libqt.so.1.45, and programs will be linked
using ld -o program program.o -L/usr/local/lib/qt -lqt.
Similarly, a program that links with qt.2 will use the
/usr/local/lib/qt2/libqt.so.2.31 file with
ld -o program program.o -L/usr/local/lib/qt2 -lqt.
To solve those libraries at run-time, a link called
/usr/local/lib/libqt.so.1.45 and a link called
/usr/local/lib/libqt.so.2.31 have been provided. This is
enough to satisfy ld.so.
It is an error to link a program using qt1 with
ld -o program program.o -L/usr/local/lib -lqt.
This code assumes the qt.2.31 is not installed, which is
a wrong assumption.
Such tricks are only necessary in the rare cases of very pervasive
libraries where a transition period between major versions must be
provided. In general, it is enough to make sure the library appears in
/usr/local/lib.
make lib-depends-check to verify a port does mention all
libraries it requires. You just separate library specs with commas like
this:
LIB_DEPENDS=gtk.1.2,gdk.1.2::x11/gtk+.
It is not an error to specify static libraries on a LIB_DEPENDS line as
well. LIB_DEPENDS are fully evaluated at package build time: the resulting
package will have library dependency information embedded as lines for
ld.so that hold the actual major.minor number that was used
for building, and nothing for static libraries.
You must provide RUN_DEPENDS as well if a port requires anything beyond a library proper. This will allow the port to build correctly on architectures that do not support shared libraries.
In fact, providing LIB_DEPENDS lines for static libraries is a good idea: this will simplify port update if a given dependency goes from a static library to a shared library.
LIB_DEPENDS lines must specify the same paths that are used for
ld. For instance, the standard qt2 depends fragment says:
LIB_DEPENDS+=lib/qt2/qt.2::x11/qt2, so that the lib
depends line will be solved correctly. This allows the dependency checking
code to do the right thing when multiple versions of the same library
are encountered.