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.
Libtool-based ports are handled automatically by the in-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 that 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 or
make port-lib-depends-check
to verify a port does mention all
libraries it requires.
You just write them in LIB_DEPENDS/WANTLIB like this:
LIB_DEPENDS += x11/gtk+
WANTLIB += gtk.>=1.2,gdk.>=1.2
It is not an error to specify static libraries on a WANTLIB line as
well. WANTLIB 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 even 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.
WANTLIB lines must specify the same paths that are used for
ld. With the same example as above, a standard qt2 depends
fragment would say
WANTLIB += lib/qt2/qt.=2.
This allows the dependency checking code to do the right thing when
multiple versions of the same library are encountered.