📄 libtool.texi
字号:
@node Postmortem@section A postmortem analysis of other implementations@cindex other implementations, flaws in@cindex reusability of library systemsIn all fairness, each of the implementations that were examined do thejob that they were intended to do, for a number of different hostsystems. However, none of these solutions seem to function well as ageneralized, reusable component.@cindex complexity of library systemsMost were too complex to use (much less modify) without understandingexactly what the implementation does, and they were generally notdocumented.The main difficulty is that different vendors have different views ofwhat libraries are, and none of the packages which were examined seemedto be confident enough to settle on a single paradigm that just@emph{works}.Ideally, libtool would be a standard that would be implemented as seriesof extensions and modifications to existing library systems to make themwork consistently. However, it is not an easy task to convinceoperating system developers to mend their evil ways, and people want tobuild shared libraries right now, even on buggy, broken, confusedoperating systems.For this reason, libtool was designed as an independent shell script.It isolates the problems and inconsistencies in library building thatplague @file{Makefile} writers by wrapping the compiler suite ondifferent platforms with a consistent, powerful interface.With luck, libtool will be useful to and used by the GNU community, andthat the lessons that were learned in writing it will be taken up bydesigners of future library systems.@node Libtool paradigm@chapter The libtool paradigmAt first, libtool was designed to support an arbitrary number of libraryobject types. After libtool was ported to more platforms, a newparadigm gradually developed for describing the relationship betweenlibraries and programs.@cindex definition of libraries@cindex libraries, definition ofIn summary, ``libraries are programs with multiple entry points, andmore formally defined interfaces.''Version 0.7 of libtool was a complete redesign and rewrite of libtool toreflect this new paradigm. So far, it has proved to be successful:libtool is simpler and more useful than before.The best way to introduce the libtool paradigm is to contrast it withthe paradigm of existing library systems, with examples from each. Itis a new way of thinking, so it may take a little time to absorb, butwhen you understand it, the world becomes simpler.@node Using libtool@chapter Using libtool@cindex examples of using libtool@cindex libtool examplesIt makes little sense to talk about using libtool in your own packagesuntil you have seen how it makes your life simpler. The examples inthis chapter introduce the main features of libtool by comparing thestandard library building procedure to libtool's operation on twodifferent platforms:@table @samp@item a23An Ultrix 4.2 platform with only static libraries.@item burgerA NetBSD/i386 1.2 platform with shared libraries.@end tableYou can follow these examples on your own platform, using thepreconfigured libtool script that was installed with libtool(@pxref{Configuring}).Source files for the following examples are taken from the @file{demo}subdirectory of the libtool distribution. Assume that we are building alibrary, @file{libhello}, out of the files @file{foo.c} and@file{hello.c}.Note that the @file{foo.c} source file uses the @code{cos} math libraryfunction, which is usually found in the standalone math library, and notthe C library (@pxref{Trig Functions, , Trigonometric Functions, libc,The GNU C Library Reference Manual}). So, we need to add @kbd{-lm} tothe end of the link line whenever we link @file{foo.o} or @file{foo.lo}into an executable or a library (@pxref{Inter-library dependencies}).The same rule applies whenever you use functions that don't appear inthe standard C library@dots{} you need to add the appropriate@kbd{-l@var{name}} flag to the end of the link line when you linkagainst those objects.After we have built that library, we want to create a program by linking@file{main.o} against @file{libhello}.@menu* Creating object files:: Compiling object files for libraries.* Linking libraries:: Creating libraries from object files.* Linking executables:: Linking object files against libtool libraries.* Debugging executables:: Running GDB on libtool-generated programs.* Installing libraries:: Making libraries available to users.* Installing executables:: Making programs available to users.* Static libraries:: When shared libraries are not wanted.@end menu@node Creating object files@section Creating object files@cindex compiling object files@cindex object files, compilingTo create an object file from a source file, the compiler is invokedwith the `-c' flag (and any other desired flags):@exampleburger$ @kbd{gcc -g -O -c main.c}burger$@end exampleThe above compiler command produces an object file, @file{main.o}, fromthe source file @file{main.c}.For most library systems, creating object files that become part of astatic library is as simple as creating object files that are linked toform an executable:@exampleburger$ @kbd{gcc -g -O -c foo.c}burger$ @kbd{gcc -g -O -c hello.c}burger$@end example@cindex position-independent code@cindex PIC (position-independent code)Shared libraries, however, may only be built from@dfn{position-independent code} (PIC). So, special flags must be passedto the compiler to tell it to generate PIC rather than the standardposition-dependent code.@cindex library object file@cindex @samp{.lo} files@cindex object files, librarySince this is a library implementation detail, libtool hides thecomplexity of PIC compiler flags by using separate library object files(which end in @samp{.lo} instead of @samp{.o}). On systems without sharedlibraries (or without special PIC compiler flags), these library objectfiles are identical to ``standard'' object files.To create library object files for @file{foo.c} and @file{hello.c},simply invoke libtool with the standard compilation command asarguments (@pxref{Compile mode}):@examplea23$ @kbd{libtool --mode=compile gcc -g -O -c foo.c}gcc -g -O -c foo.cecho timestamp > foo.loa23$ @kbd{libtool --mode=compile gcc -g -O -c hello.c}gcc -g -O -c hello.cecho timestamp > hello.loa23$@end exampleNote that libtool creates two files for each invocation. The @samp{.lo}file is a library object, which may be built into a shared library, andthe @samp{.o} file is a standard object file. On @samp{a23}, thelibrary objects are just timestamps, because only static libraries aresupported.On shared library systems, libtool automatically inserts the PICgeneration flags into the compilation command, so that the libraryobject and the standard object differ:@exampleburger$ @kbd{libtool --mode=compile gcc -g -O -c foo.c}gcc -g -O -c -fPIC -DPIC foo.cmv -f foo.o foo.logcc -g -O -c foo.c >/dev/null 2>&1burger$ @kbd{libtool --mode=compile gcc -g -O -c hello.c}gcc -g -O -c -fPIC -DPIC hello.cmv -f hello.o hello.logcc -g -O -c hello.c >/dev/null 2>&1burger$@end exampleNotice that the second run of GCC has its output discarded. This isdone so that compiler warnings aren't annoyingly duplicated.@node Linking libraries@section Linking libraries@pindex arWithout libtool, the programmer would invoke the @code{ar} command tocreate a static library:@exampleburger$ @kbd{ar cru libhello.a hello.o foo.o}burger$@end example@pindex ranlibBut of course, that would be too simple, so many systems require thatyou run the @code{ranlib} command on the resulting library (to give itbetter karma, or something):@exampleburger$ @kbd{ranlib libhello.a}burger$@end exampleIt seems more natural to use the C compiler for this task, givenlibtool's ``libraries are programs'' approach. So, on platforms withoutshared libraries, libtool simply acts as a wrapper for the system@code{ar} (and possibly @code{ranlib}) commands.@cindex libtool libraries@cindex @samp{.la} filesAgain, the libtool library name differs from the standard name (it has a@samp{.la} suffix instead of a @samp{.a} suffix). The arguments to libtool arethe same ones you would use to produce an executable named@file{libhello.la} with your compiler (@pxref{Link mode}):@examplea23$ @kbd{libtool --mode=link gcc -g -O -o libhello.la foo.o hello.o}libtool: cannot build libtool library `libhello.la' from non-libtool \ objectsa23$@end exampleAha! Libtool caught a common error@dots{} trying to build a libraryfrom standard objects instead of library objects. This doesn't matterfor static libraries, but on shared library systems, it is of greatimportance.So, let's try again, this time with the library object files. Rememberalso that we need to add @kbd{-lm} to the link command line because@file{foo.c} uses the @code{cos} math library function (@pxref{Usinglibtool}).Another complication in building shared libraries is that we need tospecify the path to the directory in which they (eventually) will beinstalled (in this case, @file{/usr/local/lib})@footnote{If you don'tspecify an @code{rpath}, then libtool builds a libtool conveniencearchive, not a shared library (@pxref{Static libraries}).}:@examplea23$ @kbd{libtool --mode=link gcc -g -O -o libhello.la foo.lo hello.lo \ -rpath /usr/local/lib -lm}mkdir @value{objdir}ar cru @value{objdir}/libhello.a foo.o hello.oranlib @value{objdir}/libhello.acreating libhello.laa23$@end exampleNow, let's try the same trick on the shared library platform:@exampleburger$ @kbd{libtool --mode=link gcc -g -O -o libhello.la foo.lo hello.lo \ -rpath /usr/local/lib -lm}mkdir @value{objdir}ld -Bshareable -o @value{objdir}/libhello.so.0.0 foo.lo hello.lo -lmar cru @value{objdir}/libhello.a foo.o hello.oranlib @value{objdir}/libhello.acreating libhello.laburger$@end exampleNow that's significantly cooler@dots{} libtool just ran an obscure@code{ld} command to create a shared library, as well as the staticlibrary.@cindex @file{@value{objdir}} subdirectoryNote how libtool creates extra files in the @file{@value{objdir}}subdirectory, rather than the current directory. This feature is tomake it easier to clean up the build directory, and to help ensure thatother programs fail horribly if you accidentally forget to use libtoolwhen you should.@node Linking executables@section Linking executables@cindex linking against installed librariesIf you choose at this point to @dfn{install} the library (put it in apermanent location) before linking executables against it, then youdon't need to use libtool to do the linking. Simply use the appropriate@samp{-L} and @samp{-l} flags to specify the library's location.@cindex buggy system linkersSome system linkers insist on encoding the full directory name of eachshared library in the resulting executable. Libtool has to work aroundthis misfeature by special magic to ensure that only permanent directorynames are put into installed executables.@cindex security problems with buggy linkers@cindex bugs, subtle ones caused by buggy linkersThe importance of this bug must not be overlooked: it won't causeprograms to crash in obvious ways. It creates a security hole,and possibly even worse, if you are modifying the library source codeafter you have installed the package, you will change the behaviour ofthe installed programs!So, if you want to link programs against the library before you installit, you must use libtool to do the linking.@cindex linking against uninstalled librariesHere's the old way of linking against an uninstalled library:@exampleburger$ @kbd{gcc -g -O -o hell.old main.o libhello.a -lm}burger$@end exampleLibtool's way is almost the same@footnote{However, you should avoid using@samp{-L} or @samp{-l} flags to link against an uninstalled libtoollibrary. Just specify the relative path to the @samp{.la} file, such as@file{../intl/libintl.la}. This is a design decision to eliminate anyambiguity when linking against uninstalled shared libraries.}(@pxref{Link mode}):@examplea23$ @kbd{libtool --mode=link gcc -g -O -o hell main.o libhello.la -lm}gcc -g -O -o hell main.o ./@value{objdir}/libhello.a -lma23$@end exampleThat looks too simple to be true. All libtool did was transform@file{libhello.la} to @file{./@value{objdir}/libhello.a}, but rememberthat @samp{a23} has no shared libraries.On @samp{burger} the situation is different:@exampleburger$ @kbd{libtool --mode=link gcc -g -O -o hell main.o libhello.la -lm}gcc -g -O -o @value{objdir}/hell main.o -L./@value{objdir} -R/usr/local/lib -lhello -lmcreating hellburger$@end example@cindex linking with installed libtool libraries
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -