1. libtool wrappers

When building programs with the help of libtool, your targets in the build directory consist of shell scripts, instead of the final ELF executable files. These shell scripts are designed to workaround some limitations present when working with shared objects in different operating systems.

The most important problem is that, if one of the executable files is referencing a library that was just built, and is not installed in the system already, you have to tell the dynamic loader where said library has to be found — this is even more important when you are building a new version of a library that is already installed on the system. While some operating systems look on the executable's directory for libraries to load, most Unix systems do not, so to point the loader to the new libraries, you have to either use the rpath feature, or you have to set some special environment variables, the name and semantics of which depend on the operating system itself.

Both methods have advantages and disadvantages: rpath has the least overhead during building, but it can (generally) only be set at build time by the link editor, and, since it shouldn't be present on the final, installed executable, usually requires relinking all of the files before installation, which is time-consuming.

On the other hand, using the script approach causes headaches with most debuggers (even though there is a designed libtool --mode=debug command): when using the wrapper script, your output file becomes, as said above, a POSIX sh script, while the actual linked executable file is generated within the .libs directory. For instance if your target is called foo, the actual executable will be .libs/lt-foo.

Obviously, the wrapper/launcher script adds some overhead over the startup of the files themselves; since sometimes you're building test programs that are executed many times on the same build process, libtool provides you with a system to disable the wrapper scripts and instead optimise the output to be executed in place. This is done by providing the -no-install flag to the LDFLAGS list.

Example 3.1. building a test program optimised for in-place execution

check_PROGRAMS = test1
test1_SOURCES = test1.c
test1_LDADD = libmylib.la
test1_LDFLAGS = -no-install

When using -no-install, libtool tells the linker to set the rpath for the output file to the full path of the .libs directory, instead of using a wrapper script to set up the LD_LIBRARY_PATH. This, in turn, eases the debugging phase, as tools such as gdb can be used directly.

While the -no-install option could be very useful when building a work-copy of a project to be tested, and especially debugged, some non-GCC compilers, as well as GCC 4.6 and later, throw an error when they are given unrecognized command-line flags, making it impossible nowadays to pass the flag down to ./configure to build a non-wrapper copy of a project.