7.2. Shared libraries - libtool

NetBSD supports many different machines, with different object formats like a.out and ELF, and varying abilities to do shared library and dynamic loading at all. To accompany this, varying commands and options have to be passed to the compiler, linker etc. to get the Right Thing, which can be pretty annoying especially if you don't have all the machines at your hand to test things. The libtool package (pkgsrc/devel/libtool) can help here, as it just "knows" how to build both static and dynamic libraries from a set our source files, thus being platform independent.

Here's how to use libtool in a package in six simple steps:

  1. Add USE_LIBTOOL=yes to the package Makefile.

  2. For library objects, use ``${LIBTOOL} --mode=compile ${CC}'' in place of ``${CC}''. You could even add it to the definition of CC, if only libraries are being built in a given Makefile. This one command will build both PIC and non-PIC library objects, so you need not have separate shared and non-shared library rules.

  3. For the linking of the library, remove any ``ar'', ``ranlib'', and ``ld -Bshareable'' commands, and use instead:

    	${LIBTOOL} --mode=link cc -o ${.TARGET:.a=.la} ${OBJS:.o=.lo} -rpath ${PREFIX}/lib -version-info major:minor
         

    Note that the library is changed to have a .la extension, and the objects are changed to have a .lo extension. Change the OBJS variable as necessary. This automatically creates all of the .a, .so.major.minor, and ELF symlinks (if necessary) in the build directory.

  4. When linking programs that depend on these libraries before they are installed, preface the ``cc'' or ``ld'' line with "${LIBTOOL} --mode=link", and it will find the correct libraries (static or shared), but please be aware that libtool will not allow you to specify a relative path in -L (such as -L../somelib), because it is trying to force you to change that argument to be the .la file. For example

    	${LIBTOOL} --mode=link ${CC} -o someprog -L../somelib -lsomelib
         
    won't work; it needs to be changed to:
    	${LIBTOOL} --mode=link ${CC} -o someprog ../somelib/somelib.la
         
    and it will DTRT with the libraries. If you must use a relative path with -L, and you are not going to run this program before installing it, you can omit the use of libtool during link and install of this program if you add the subdirectory .libs in your ``-L'' command:
    	${CC} -o someprog -L../somelib/.libs -lsomelib
         

  5. When installing libraries, preface the ``install'' or ``cp'' command with "${LIBTOOL} --mode=install", and change the library name to .la. For example:

    	${LIBTOOL} --mode=install ${BSD_INSTALL_DATA} ${SOMELIB:.a=.la} ${PREFIX}/lib
         

    This will install the static .a, shared library, any needed symlinks, and run ``ldconfig''.

  6. In your PLIST, include the .a, .la, and .so.major.minor files. Don't include the ELF symlink files (.so.major, .so); those are added automatically.

Do not use pkglibtool! Previously, the package system used its own version of libtool from pkgtools. However, over time, this version became outdated and is now deprecated. You may see some definitions of USE_PKGLIBTOOL in existing packages that still use this outdated version of libtool. Please do not use this definition in new packages!