From: Gordon Matzigkeit Date: Tue, 1 Apr 1997 18:29:23 +0000 (+0000) Subject: Initial revision X-Git-Tag: release-1-0a~51 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=87b8075bc962d6fde11fef24bc1fb3e8a4d38e6b;p=thirdparty%2Flibtool.git Initial revision --- diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 000000000..f6d579284 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,46 @@ +## Process Makefile.am with automake to create Makefile.in. +## Gordon Matzigkeit , 1996 +AUTOMAKE_OPTIONS = gnits +SUBDIRS = doc + +EXTRA_DIST = libtool.m4 libtoolize.in ltconfig.in ltmain.sh.in +CLEANFILES = libtool libtoolize ltconfig ltmain.sh + +# Files in the demo subdirectory that go in the distribution. +demo_distfiles = Makefile.in Makefile.am aclocal.m4 configure configure.in \ + foo.c foo.h hello.c libinfo main.c + +# These are required by libtoolize. +pkgdata_SCRIPTS = config.guess config.sub ltconfig +pkgdata_DATA = ltmain.sh + +# This macro files should be visible to Automake's aclocal. +aclocaldir = @aclocaldir@ +aclocal_DATA = libtool.m4 + +# The standalone libtool script, and the libtool distributor. +bin_SCRIPTS = libtool libtoolize + +libtool: ltconfig + ./ltconfig --srcdir=$(srcdir) $(pkgdatadir)/ltmain.sh + +libtoolize: libtoolize.in + CONFIG_FILES=libtoolize CONFIG_HEADERS= $(top_builddir)/config.status + chmod +x libtoolize + +ltconfig: ltconfig.in + CONFIG_FILES=ltconfig CONFIG_HEADERS= $(top_builddir)/config.status + chmod +x ltconfig + +ltmain.sh: ltmain.sh.in + CONFIG_FILES=ltmain.sh CONFIG_HEADERS= $(top_builddir)/config.status + +# Distribute the demo subdirectory. +dist-hook: + mkdir $(distdir)/demo + @for file in $(demo_distfiles); do \ + d=$(srcdir)/demo; \ + test -f $(distdir)/demo/$$file \ + || ln $$d/$$file $(distdir)/demo/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/demo/$$file; \ + done diff --git a/NEWS b/NEWS new file mode 100644 index 000000000..7655c7af6 --- /dev/null +++ b/NEWS @@ -0,0 +1,67 @@ +New in 0.6a: +* Total rewrite of libtool, along with a new model for library building. +* Updated documentation for the new paradigm. +* Proper handling of broken system linkers, such as the ones on AIX + and HP-UX. +* configure mode is now a separate program, `ltconfig' +* Libtool only supports `compile', `link', and `install' modes, via + the `--mode' command line option. +* Automatic mode guessing, based on the command line. + +New in 0.6: (never released) +* Optimization to cut `libtool archive' execution time by a factor of 5. +* New AM_REPLACE_FUNCS macro to generate LTLIBOBJS as well as LIBOBJS. + From Karl Berry. +* Renamed ABOUT-LIBS to ABOUT-LIBTOOL. From Karl Berry. +* Include the generated libtool script in the distribution. +* Quote metacharacters in arguments to `libtool compile'. +* Bug fixes. +* Removed `link' and `install-progs' modes because they cannot be + correctly implemented. See (libtool)Linking Against Pseudo-Libraries. + +New in 0.5: +* Disabled install-progs until next version, when it will be correctly + implemented. +* Clearer library versioning documentation. See (libtool)Versioning. +* Renamed gm_PROG_LIBTOOL to AM_PROG_LIBTOOL +* Libtool now creates pseudo-objects named foo.lo and pseudo-archives named + libfoo.la instead of foo.o and libfoo.a. See the documentation. +* libtool compile doesn't interfere with user CFLAGS if they don't + conflict with the current objtype. From Karl Berry. +* Created new libinfo helper script. +* libversion.in files are obsolete -- libtool uses libinfo to read the + new LIBINFO files. +* Libtool is better at finding its config file and helper scripts. +* Support for *-*-gnu* + +New in 0.4: +* Bug fixes and new regression tests +* On unsupported configurations, ``libtool configure'' demotes OBJTYPES to + `standard' instead of aborting +* Added new object type, `t', for tcov(1) support +* Support for *-*-aix3*, *-*-aix4*, *-*-hpux10*, *-*-osf3*, and *-*-solaris2* + +New in 0.3: +* Bug fixes and new regression tests +* Added new uninstall-libs mode +* Added a host argument to configure mode +* Fixed debugging/hyper-optimizing flags conflict (from Karl Berry) +* Support for --no-whole-archive when needed by GNU ld (from Ulrich Drepper) +* Implementation of --enable-linktype, --enable-profile, --enable-shared, + --enable-static in gm_PROG_LIBTOOL macro +* New `libtoolize' program (modeled after GNU gettext's `gettextize') to help + conversion to libtool +* New ABOUT-LIBS document for inclusion with libtool-supported packages + +New in 0.2: +* Support for *-*-linux +* Better checking for GNU ld +* Reimplemented the config file so that it corresponds more closely to the + variables listed in (libtool)Porting Libtool. +* Reimplemented the shared library version scheme. See (libtool)Versioning. +* Replaced `--config-file' and `--version-file' options with `--confdir' +* Added new install-libs and install-progs modes + +New in 0.1: +* First release of libtool +* Support for: *-*-freebsd*, *-*-netbsd*, *-*-sunos4*, *-*-ultrix4* diff --git a/README b/README new file mode 100644 index 000000000..c4787576c --- /dev/null +++ b/README @@ -0,0 +1,20 @@ +This is GNU libtool, a generic library support script. Libtool hides +the complexity of generating special library types (such as shared +libraries) behind a consistent interface. + +To use libtool, add the new generic library building commands to your +Makefile, Makefile.in, or Makefile.am. See the documentation for +details. + +Libtool supports building static libraries on all platforms. + +Shared library support has been implemented for these platforms: + NetBSD 1.x (*-*-netbsd*) + +See the file NEWS for a description of recent changes to libtool. + +See the file INSTALL for instructions on how to build and install libtool. + +If you have any suggestions or bug reports, or you wish to port libtool +to a new platform, please send electronic mail to Gord Matzigkeit +. diff --git a/THANKS b/THANKS new file mode 100644 index 000000000..c511209b9 --- /dev/null +++ b/THANKS @@ -0,0 +1,11 @@ +Libtool would not be what it is today without the invaluable help of +these people: + +Joel Cannon +Karl Berry +Mimi Burbank +Oliver Guntermann +Thomas Esser +Tom Tromey +Ulrich Drepper +Volker Kuhlmann diff --git a/TODO b/TODO new file mode 100644 index 000000000..8b7eebfa0 --- /dev/null +++ b/TODO @@ -0,0 +1,17 @@ +* Find link_static_flag for every C compiler, currently at least +native cc's for AIX, HP-UX, OSF/1. + +* Configure test for a library-stripping program (strip -x on NetBSD) + +* Implement fuller support for profiled libraries (libNAME_p), and +resolve naming difficulties for debuggable libraries (libNAME_g on +Linux at least), old system 5 shared libraries (libNAME_s), etc. + +* We should use the C compiler rather than the linker to create shared +libraries, if at all possible. This just involves looking up the $wl +values for system compilers. + +* What should be done about the difference between -fpic and -fPIC? + +* GCC docs imply that all rs6000 code is PIC. If that is true, then +implement it. diff --git a/configure.in b/configure.in new file mode 100644 index 000000000..a15777d90 --- /dev/null +++ b/configure.in @@ -0,0 +1,9 @@ +AC_INIT(ltmain.sh.in) +AM_INIT_AUTOMAKE(libtool, 0.6a) + +pkgdatadir='${datadir}/libtool' +AC_SUBST(pkgdatadir) +aclocaldir='${datadir}/aclocal' +AC_SUBST(aclocaldir) + +AC_OUTPUT([Makefile doc/Makefile]) diff --git a/demo/Makefile.am b/demo/Makefile.am new file mode 100644 index 000000000..c1dedc874 --- /dev/null +++ b/demo/Makefile.am @@ -0,0 +1,20 @@ +# A brief demonstration of using Automake with Libtool. +AUTOMAKE_OPTIONS = foreign + +EXTRA_DIST = libinfo + +# Build a libtool library, libhell.la for installation in libdir. +lib_PROGRAMS = libhell.la +libhell_la_SOURCES = hello.c foo.c +libhell_la_LDFLAGS = -version-file $(srcdir)/libinfo -rpath $(libdir) + +include_HEADERS = foo.h + +# Build hell from main.c and libhell.la +bin_PROGRAMS = hell +hell_SOURCES = main.c +hell_LDADD = libhell.la + +# Regenerate the acinclude.m4 from the parent, if it doesn't exist. +$(top_srcdir)/acinclude.m4: + ln -s $(top_srcdir)/../libtool.m4 $(top_srcdir)/acinclude.m4 diff --git a/demo/foo.c b/demo/foo.c new file mode 100644 index 000000000..248b24eb6 --- /dev/null +++ b/demo/foo.c @@ -0,0 +1,29 @@ +/* foo.c -- trivial test function for libfoo + Copyright (C) 1996 Free Software Foundation, Inc. + This file is part of GNU Libtool. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Written by Gordon Matzigkeit */ +#include "foo.h" + +static char *package = PACKAGE; +static char *version = VERSION; + +int +foo () +{ + return FOO_RET; +} diff --git a/doc/libtool.texi b/doc/libtool.texi new file mode 100644 index 000000000..5f831343b --- /dev/null +++ b/doc/libtool.texi @@ -0,0 +1,1356 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header +@setfilename libtool.info +@settitle libtool +@setchapternewpage off +@c %**end of header +@syncodeindex vr cp +@synindex pg cp + +@include version.texi +@set MAINT Gord Matzigkeit + +@ifinfo +@format +START-INFO-DIR-ENTRY +* Libtool: (libtool). Generic shared library support script. +END-INFO-DIR-ENTRY +@end format +@end ifinfo + +@ifinfo +This file documents the Libtool library support script. + +Copyright (C) 1996 Free Software Foundation, Inc. + +Permission is granted to make and distribute verbatim copies of this +manual provided the copyright notice and this permission notice are +preserved on all copies. + +@ignore +Permission is granted to process this file through TeX and print the +results, provided the printed document carries copying permission notice +identical to this one except for the removal of this paragraph + + +@end ignore +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that this permission notice may be stated in a translation +approved by the Foundation. +@end ifinfo + + +@titlepage +@title GNU Libtool +@subtitle For version @value{VERSION}, @value{UPDATED} +@c copyright page +@page +@vskip 0pt plus 1filll +Copyright @copyright{} 1996 Free Software Foundation, Inc. +@sp 2 +This is the second edition of the GNU Libtool documentation,@* +and is consistent with GNU Libtool @value{VERSION}.@* +@sp 2 +Published by the Free Software Foundation @* +675 Massachusetts Avenue, @* +Cambridge, MA 02139 USA @* + +Permission is granted to make and distribute verbatim copies of this +manual provided the copyright notice and this permission notice are +preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that this permission notice may be stated in a translation +approved by the Free Software Foundation. +@end titlepage + +@ifinfo +@node Top, Introduction, (dir), (dir) +@comment node-name, next, previous, up +@top Shared library support for GNU + +This file documents GNU libtool, a script that allows package developers +to provide generic shared library support. This edition documents +version @value{VERSION}. + +@menu +* Introduction:: What the heck is libtool? +* Libtool Paradigm:: How libtool's view of libraries is different. +* Using Libtool:: Example of using libtool to build libraries. +* Invoking @file{libtool}:: Running the @file{libtool} script. +* Integrating Libtool:: Using libtool in your own packages. +* Versioning:: Using library interface versions. +* Library Tips:: Tips for library interface design. +* Modifying:: Changing the libtool script. +* Index:: Index of concepts, variables, and programs. + + --- The Detailed Node Listing --- + +Introduction + +* Motivation:: Why does GNU need a libtool? +* Issues:: The problems that need to be addressed. +* Other Implementations:: How other people have solved these issues. +* Postmortem:: Learning from past difficulties. + +Using Libtool + +* Creating Object Files:: Compiling object files for libraries. +* Linking Libraries:: +* Linking Executables:: Linking object files against libtool libraries. +* Installing Libraries:: Making libraries available to users. +* Installing Executables:: Making programs available to users. +* Static Libraries:: When shared libraries are not wanted. + +Invoking @file{libtool} + +* Compile Mode:: Creating library object files. +* Link Mode:: Generating executables and libraries. +* Install Mode:: Making libraries and executables public. +* Finish Mode:: Completing a library installation. +* Uninstall Mode:: Removing executables and libraries. + +Integrating Libtool with Your Own Packages + +* Makefile Rules:: Writing Makefile rules for libtool. +* Using Automake:: Automatically supporting libtool. +* Configuring:: Configuring libtool for a host system. +* Distributing:: What files to distribute with your package. + +Including Libtool with Your Package + +* Invoking @file{libtoolize}:: @file{libtoolize} command line options. + +Library Interface Versions + +* Interfaces:: What are library interfaces? +* Libtool Versioning:: Libtool's versioning system. +* Version Files:: How libtool tracks library versions. +* Updating @file{libinfo}:: Keeping a library version file up-to-date. +@end menu + +@end ifinfo + +@node Introduction, Libtool Paradigm, Top, Top +@comment node-name, next, previous, up +@chapter Introduction + +In the past, if a source code package developer wanted to take advantage +of the power of shared libraries, he needed to write custom support code +for each platform his package ran on. He also had to design a +configuration interface so that the user could choose what sort of +libraries were built. + +GNU libtool simplifies the developer's job by encapsulating both the +platform-specific dependencies, and the user interface, in a single +script. GNU libtool is designed so that the complete functionality of +each host type is available via a generic interface, but nasty quirks +are hidden from the programmer. + +GNU libtool's consistent interface is reassuring@dots{} users don't need +to read obscure documentation in order to have their favorite source +package build shared libraries. They just run your package +@file{configure} script (or equivalent), and libtool does all the dirty +work. + +There are several examples throughout this document. All assume the +same environment: we want to build a library, @file{libfoo}, in a +generic way. + +@file{libfoo} could be a shared library, a static library, or +both@dots{} whatever is available on the host system, as long as libtool +has been ported to it. + +This chapter explains the original design philosophy of libtool. Feel +free to skip to the next chapter, unless you are interested in history, +or want to write code to extend libtool in a consistent way. + +@menu +* Motivation:: Why does GNU need a libtool? +* Issues:: The problems that need to be addressed. +* Other Implementations:: How other people have solved these issues. +* Postmortem:: Learning from past difficulties. +@end menu + +@node Motivation, Issues, Introduction, Introduction +@comment node-name, next, previous, up +@section Motivation for Writing Libtool + +@cindex Motivation for writing libtool +@cindex Design philosophy +Since early 1995, several different GNU developers have recognized the +importance of having shared library support for their packages. The +primary motivation for such a change is to encourage modularity and +reuse of code (both conceptually and physically) in GNU programs. + +Such a demand means that the way libraries are built in GNU packages +needs to be general, to allow for any library type the user might want. +The problem is compounded by the absence of a standard procedure for +creating shared libraries on different platforms. + +The following sections outline the major issues facing shared library +support in GNU, how some developers have overcome these issues, and how +I propose that shared library support should be standardized with +libtool. + +@cindex Specifications for libtool +@cindex Libtool specifications +The following specifications were used in developing and evaluating this +system: + +@enumerate +@item +The system must be as elegant as possible. + +@item +The system must be fully integrated with the GNU Autoconf and Automake +utilities, so that it will be easy for GNU maintainers to use. However, +the system must not require these tools, so that it can be used by +non-GNU packages. + +@item +Portablility to other (non-GNU) architectures and tools is desirable. +@end enumerate + +@node Issues, Other Implementations, Motivation, Introduction +@comment node-name, next, previous, up +@section Implementation Issues + +@cindex Tricky design issues +@cindex Design issues +The following issues need to be addressed in any reusable shared library +system, specifically libtool: + +@enumerate +@item +The user should be able to control what sort of libraries are built. + +@item +It can be tricky to run dynamically linked programs whose libraries have +not yet been installed. @var{LD_LIBRARY_PATH} must be set properly (if +it is supported), or the program fails. + +@item +The system must operate consistently even on hosts which don't support +shared libraries. + +@item +The commands required to build shared libraries may differ wildly from +host to host. These need to be guessed and tested at configure time in +a consistent way. + +@item +Some operating systems do not support shared object version numbers, and +it is not obvious with which suffix a shared object should be installed. +This makes it difficult for Makefile rules, since they generally assume +that filenames are the same from host to host. + +@item +Programmers need to be aware of what assumptions they are allowed to +make. Library names will need to be carefully chosen (to avoid name +clashes), binary compatibility needs to be accounted for, + +@item +The system needs a simple library version number abstraction, so that +shared libraries can be upgraded in place. The programmer should be +informed how to design the interfaces to the library to maximize binary +compatibility. + +@item +The install Makefile target should warn the user to set +@var{LD_LIBRARY_PATH} (or equivalent) or run @kbd{ldconfig}, if +required. +@end enumerate + +@node Other Implementations, Postmortem, Issues, Introduction +@comment node-name, next, previous, up +@section Other Implementations + +I have investigated several different implementations of building shared +libraries as part of a freeware package. At first, I made notes on the +features of each of these packages for comparison purposes. + +Now it is clear that none of these packages have documented the details +of shared library systems that libtool requires. So, other packages +have been more or less abandoned as influences. + +@node Postmortem, , Other Implementations, Introduction +@comment node-name, next, previous, up +@section A Postmortem Analysis of Other Implementations + +@cindex Other implementations, flaws in +@cindex Reuseability of library systems +In all fairness, each of the implementations that I examined do the job +that they were intended to do, for a number of different host systems. +However, none of these solutions seem to function well as a generalized, +reuseable component. + +@cindex Complexity of library systems +Most were too complex for me to use (much less modify) without +understanding exactly what the implementation does, and they were +generally not documented. + +I think the main problem is that different vendors have different views +of what libraries are, and none of the packages I examined seemed to be +confident enough to settle on a single paradigm that just @emph{works}. + +Ideally, libtool would be a standard that would be implemented as series +of extensions and modifications to existing library systems to make them +work consistently. However, I don't have the time or power to convince +operating system developers to mend their evil ways, and I want to build +shared libraries right now, even on buggy, broken, confused operating +systems. + +For this reason, I have designed libtool as an independent shell script. +It isolates the problems and inconsistencies in library building that +plague Makefile writers by wrapping the compiler suite on different +platforms with a consistent, powerful interface. + +I hope that libtool will be useful to and used by the GNU community, and +that the lessons I've learned in writing it will be taken up and +implemented by designers of library systems. + +@node Libtool Paradigm, Using Libtool, Introduction, Top +@comment node-name, next, previous, up +@chapter The Libtool Paradigm + +At first, libtool was designed to support an arbitrary number of library +object types. After porting libtool to more platforms, the author +discovered a new (at least for him) paradigm of what libraries and +programs are. + +In summary: ``libraries are programs with multiple entry points, and +more formally defined interfaces.'' + +Version 0.7 of libtool was a complete redesign and rewrite of libtool to +reflect this new paradigm. So far, it has proved to be successful: +libtool is simpler and more functional than before. + +The best way to introduce the libtool paradigm is to contrast it with +the paradigm of existing library systems, with examples from each. It +is a new way of thinking, so it may take a little time to absorb, but +when you understand it the world gets simpler. + +@node Using Libtool, Invoking @file{libtool}, Libtool Paradigm, Top +@comment node-name, next, previous, up +@chapter Using Libtool + +It makes little sense to talk about using libtool in your own packages +until you have seen how it makes your life simpler. The examples in +this chapter introduce the main features of libtool by comparing the +standard library building procedure to libtool's operation on two +different platforms: + +@table @asis +@item `a23' +An Ultrix 4.2 platform with only static libraries. + +@item `burger' +A NetBSD/i386 1.2 platform with shared libraries. +@end table + +You can follow these examples on your own platform, using the +pre-configured (@pxref{Configuring}) libtool script that was installed +with the libtool distribution. + +Source files for the following examples are taken from the @file{demo} +subdirectory of the libtool distribution. Assume that we are building a +library, @file{libhello}, out of the files @file{foo.c} and +@file{hello.c}. + +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:: +* Linking Executables:: Linking object files against libtool libraries. +* 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, Linking Libraries, Using Libtool, Using Libtool +@comment node-name, next, previous, up +@section Creating Object Files + +To create an object file from a source file, the compiler is invoked +with the `-c' flag (and any other desired flags): + +@example +burger$ @kbd{gcc -g -O -c main.c} +burger$ +@end example + +The above compiler command produces an object file, @file{main.o}, from +the source file @file{main.c}. + +For most library systems, creating object files that become part of a +static library is as simple as creating object files that are linked to +form an executable: + +@example +burger$ @kbd{gcc -g -O -c foo.c} +burger$ @kbd{gcc -g -O -c hello.c} +burger$ +@end example + +Shared libraries, however, may only be built from +@dfn{position-independant code} (PIC). So, special flags must be passed +to the compiler to tell it to generate PIC rather than the standard +position-dependant code. + +Since this is a library implementation detail, libtool hides the +complexity of PIC compiler flags by using separate library object files +(which end in `.lo' instead of `.o'). On systems without shared +libraries (or without special PIC compiler flags), these library object +files 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 as an +argument: + +@example +a23$ libtool gcc -g -O -c foo.c +gcc -g -O -c foo.c -o foo.lo +a23$ libtool gcc -g -O -c hello.c +gcc -g -O -c hello.c -o hello.lo +a23$ +@end example + +On shared library systems, libtool automatically inserts the PIC +generation flags into the compilation command: + +@example +burger$ @kbd{libtool gcc -g -O -c foo.c} +gcc -g -O -c -fPIC -DPIC foo.c -o foo.lo +burger$ @kbd{libtool gcc -g -O -c hello.c} +gcc -g -O -c -fPIC -DPIC hello.c -o hello.lo +burger$ +@end example + +@node Linking Libraries, Linking Executables, Creating Object Files, Using Libtool +@comment node-name, next, previous, up +@section Linking Libraries + +Without libtool, the programmer would invoke the @file{ar} command to +create a static library: + +@example +burger$ @kbd{ar cru libhello.a hello.o foo.o} +burger$ +@end example + +But of course, that would be too simple, so many systems require that +you run the @file{ranlib} command on the resulting library (to give it +better karma, or something): + +@example +burger$ @kbd{ranlib libhello.a} +burger$ +@end example + +It seems more natural to use the C compiler for this task, given +libtool's ``libraries are programs'' approach. So, on platforms without +shared libraries, libtool simply acts as a wrapper for the system +@file{ar} (and possibly @file{ranlib}) commands. + +Again, the libtool library name differs from the standard name (it has a +`.la' suffix instead of a `.a' suffix). The arguments to libtool are +the same ones you would use to produce an executable named +@file{libhello.la} with your compiler: + +@example +burger$ @kbd{libtool gcc -g -O -o libhello.la foo.o hello.o} +libtool: cannot build libtool library `libhello.la' from non-libtool objects +burger$ +@end example + +Aha! Libtool caught a common error@dots{} trying to build a library +from standard objects instead of library objects.@footnote{The converse, +however, is perfectly legal. Library objects can do anything that +standard objects can do@dots{} it makes sense to link them directly into +programs.} This doesn't matter much for static libraries, but on shared +library systems, it is of great importance. + +So, let's try again, this time with the library object files: + +@example +a23$ @kbd{libtool gcc -g -O -o libhello.la foo.lo hello.lo} +libtool: you must specify an installation directory with `-rpath' +a23$ +@end example + +Argh. Another complication in building shared libraries is that we need +to specify the path to the directory in which they (eventually) will be +installed. So, we try again, with an @code{rpath} setting of +@file{/usr/local/lib}: + +@example +a23$ @kbd{libtool gcc -g -O -o libhello.la foo.lo hello.lo -rpath /usr/local/lib} +mkdir LIBS +ar cru LIBS/libhello.a foo.lo hello.lo +ranlib LIBS/libhello.a +creating libhello.la +a23$ +@end example + +Now, let's try the same trick on the shared library platform: + +@example +burger$ @kbd{libtool gcc -g -O -o libhello.la foo.lo hello.lo -rpath /usr/local/lib} +mkdir LIBS +ld -Bshareable -o LIBS/libhello.so.0.0 foo.lo hello.lo +ar cru LIBS/libhello.a foo.lo hello.lo +ranlib LIBS/libhello.a +creating libhello.la +burger$ +@end example + +Now that's significantly cooler@dots{} libtool just ran an obscure +@file{ld} command to create a shared library, as well as the static +library. + +Note how libtool creates extra files in the @file{LIBS} subdirectory, +rather than the current directory. This feature is to make it easier to +clean up the build directory, and to help ensure that other programs +fail horribly if you accidentally forget to use libtool when you should. + +@node Linking Executables, Installing Libraries, Linking Libraries, Using Libtool +@comment node-name, next, previous, up +@section Linking Executables + +If you choose at this point to @dfn{install} the library (put it in a +permanent location) before linking executables against it, then you +don't need to use libtool to do the linking. + +Some system linkers insist on encoding the full directory name of each +shared library in the resulting executable. Libtool has to work around +this misfeature by special magic to ensure that only permanent directory +names are put into installed executables. + +The importance of this bug must not be overlooked: it won't cause +programs to crash in obvious ways. It creates a security hole, +and possibly even worse, if you are modifying the library source code +after you have installed the package, you will change the behaviour of +the installed programs! + +So, if you want to link programs against the library before you install +it, you must use libtool to do the linking. + +Here's the old way of linking against an uninstalled library: + +@example +burger$ @kbd{gcc -g -O -o hell.old main.o libhello.a} +burger$ +@end example + +This is libtool's way: + +@example +a23$ @kbd{libtool gcc -g -O -o hell main.o libhello.la} +gcc -g -O -o hell main.o ./LIBS/libhello.a +a23$ +@end example + +That looks too simple to be true. All libtool did was transform +@file{libhello.la} to @file{./LIBS/libhello.a}, but remember that +`a23' has no shared libraries. + +On `burger' the situation is different: + +@example +burger$ @kbd{libtool gcc -g -O -o hell main.o libhello.la} +gcc -g -O -o LIBS/hell main.o -L./LIBS -R/usr/local/lib -lhello +creating hell +burger$ +@end example + +Notice that the executable, @file{hell} was actually created in the +@file{LIBS} subdirectory. Then, a wrapper script was created in the +current directory. + +On NetBSD 1.2, libtool encodes the installation directory of +@file{libhello}, @file{/usr/local/lib}, by using the @code{-R} compiler +flag. Then, the wrapper script guarantees that the executable finds the +correct shared library (the one in @file{./LIBS}) until it is properly +installed. + +Let's compare the two different programs: + +@example +burger$ @kbd{time ./hell.old} +Welcome to GNU Hell! +** This is not GNU Hello. There is no built-in mail reader. ** + 0.21 real 0.02 user 0.08 sys +burger$ @kbd{time ./hell} +Welcome to GNU Hell! +** This is not GNU Hello. There is no built-in mail reader. ** + 0.63 real 0.09 user 0.59 sys +burger$ +@end example + +The wrapper script takes significantly longer to execute, but at least +the results are correct, even though the shared library hasn't been +installed yet. + +So, what about all the space savings that shared libraries are supposed +to yield? + +@example +burger$ @kbd{ls -l hell.old libhello.a} +-rwxr-xr-x 1 gord gord 15481 Nov 14 12:11 hell.old +-rw-r--r-- 1 gord gord 4274 Nov 13 18:02 libhello.a +burger$ @kbd{ls -l LIBS/hell LIBS/libhello.*} +-rwxr-xr-x 1 gord gord 11602 Nov 14 12:10 LIBS/hell +-rw-r--r-- 1 gord gord 4352 Nov 13 18:44 LIBS/libhello.a +-rwxr-xr-x 1 gord gord 12205 Nov 13 18:44 LIBS/libhello.so.0.0 +burger$ +@end example + +Well, that sucks. Maybe I should just scrap this project and take up +basket weaving. + +Actually, it just proves an important point: shared libraries incur +overhead because of their (relative) complexity. In this situation, the +price of being dynamic is eight kilobytes, and the payoff is about four +kilobytes. So, having a shared @file{libhello} won't be an advantage +until we link it against at least a few more programs. + +@node Installing Libraries, Installing Executables, Linking Executables, Using Libtool +@comment node-name, next, previous, up +@section Installing Libraries + +Installing libraries on a non-libtool system is quite +straightforward@dots{} just copy them into place:@footnote{Don't +accidentally strip the libraries, though, or they will be unusable.} + +@example +burger$ @kbd{su} +Password: ******** +burger# @kbd{cp libhello.a /usr/local/lib/libhello.a} +burger# +@end example + +Oops, don't forget the @file{ranlib} command: + +@example +burger# @kbd{ranlib /usr/local/lib/libhello.a} +burger# +@end example + +Libtool installation is quite simple, as well. Just use the +@file{install} or @file{cp} command that you normally would: + +@example +a23# @kbd{libtool cp libhello.la /usr/local/lib/libhello.la} +cp libhello.la /local/lib/libhello.la +cp LIBS/libhello.a /local/lib/libhello.a +ranlib /local/lib/libhello.a +a23# +@end example + +Note that the libtool library @file{libhello.la} is also installed, for +informational purposes. + +Here is the shared library example: + +@example +burger# libtool install -c libhello.la /usr/local/lib/libhello.la +install -c LIBS/libhello.so.0.0 /usr/local/lib/libhello.so.0.0 +install -c libhello.la /usr/local/lib/libhello.la +install -c LIBS/libhello.a /usr/local/lib/libhello.a +ranlib /usr/local/lib/libhello.a +burger# +@end example + +It is safe to specify the @samp{-s} (strip symbols) flag to the install +program (if you use a BSD-compatible install) when installing libraries. +Libtool will either ignore the @samp{-s} flag, or will run a program +that will strip only debugging and compiler symbols from the library. + +Once the libraries have been put in place, there may be some additional +configuration that you need to do before using them. First, you must +make sure that where the library is installed actually agrees with the +@samp{-rpath} flag you used to build it. + +Then, running @samp{libtool -n --finish @var{libdir}} can give you +further hints on what to do: + +@example +burger# @kbd{libtool -n --finish /usr/local/lib} +ldconfig -m /usr/local/lib +To link against installed libraries in LIBDIR, users may have to: + - add LIBDIR to their `LD_LIBRARY_PATH' environment variable + - use the `-LLIBDIR' linker flag +burger# +@end example + +After you have completed these steps, you can go on to begin using the +installed libraries. You may also install any executables that depend +on libraries you created. + +@node Installing Executables, Static Libraries, Installing Libraries, Using Libtool +@comment node-name, next, previous, up +@section Installing Executables + +If you used libtool to link any executables against uninstalled libtool +libraries (@pxref{Linking Executables}), you need to use libtool to +install the executables after the libraries have been installed +(@pxref{Installing Libraries}). + +So, for our Ultrix example, we would run: + +@example +a23# libtool install -c hell /usr/local/bin/hell +install -c hell /usr/local/bin/hell +a23# +@end example + +On shared library systems, libtool just ignores the wrapper script and +installs the correct binary: + +@example +burger# libtool install -c hell /usr/local/bin/hell +install -c LIBS/hell /usr/local/bin/hell +burger# +@end example + +@node Static Libraries, , Installing Executables, Using Libtool +@comment node-name, next, previous, up +@section Linking Static Libraries + +Sometimes it is desirable to create a static archive that can never be +shared. The most frequent case is when you have a ``convenience +library'' that is a collection of unrelated object files without a +really nice interface. + +Why return to @file{ar} and @file{ranlib} silliness when you've had a +taste of libtool? libtool works consistently with standard object +files, static libraries, and programs created without libtool's help. + +So, to create a static library: + +@enumerate 1 +@item +Compile the object files with or without using libtool. It doesn't +matter whether these objects are PIC (end with the `.lo' suffix) or not. + +@item +Link the files in the same way you would a libtool library, but use a +`.a' suffix (instead of `.la'): + +@example +burger$ @kbd{libtool gcc -o libfoo.a main.o foo.lo hello.lo} +rm -f libfoo.a +ar cru libfoo.a main.o foo.lo hello.lo +ranlib libfoo.a +burger$ +@end example + +@item +If you want to install the library (but you probably don't), then you +can use libtool to do it, too: + +@example +burger$ @kbd{libtool ./install-sh -c libfoo.a /local/lib/libfoo.a} +./install-sh -c libfoo.a /local/lib/libfoo.a +ranlib /local/lib/libfoo.a +burger$ +@end example +@end enumerate + +Another common situation where static linking is desirable is in +creating a standalone binary. Use libtool to do the linking and add the +@samp{-static} flag. + +@node Invoking @file{libtool}, Integrating Libtool, Using Libtool, Top +@comment node-name, next, previous, up +@chapter Invoking @file{libtool} + +The @file{libtool} program has the following synopsis: + +@example +libtool [@var{option}]@dots{} [@var{mode-arg}]... +@end example + +@noindent +and accepts the following options: + +@table @samp +@item -n +@itemx --dry-run +Don't create, modify, or delete any files, just show what commands would +be executed by libtool. + +@item --finish +Same as @samp{--mode=finish}. + +@item --help +Display a help message and exit. If @samp{--mode=@var{mode}} is +specified, then detailed help for operation mode @var{mode} is +displayed. + +@item --mode=@var{mode} +Use operation mode @var{mode}. By default, the operation mode is +inferred from the contents of @var{mode-args}. + +If @var{mode} is specified, it must be one of the following: + +@table @samp +@item compile +Compile a source file into a libtool object. + +@item finish +Complete the installation of libtool libraries on the system. + +@item install +Install libraries or executables. + +@item link +Create a library or an executable. + +@item uninstall +Delete libraries or executables. +@end table + +@item --version +Print libtool version information and exit. +@end table + +@menu +* Compile Mode:: Creating library object files. +* Link Mode:: Generating executables and libraries. +* Install Mode:: Making libraries and executables public. +* Finish Mode:: Completing a library installation. +* Uninstall Mode:: Removing executables and libraries. +@end menu + +@node Compile Mode, Link Mode, Invoking @file{libtool}, Invoking @file{libtool} +@comment node-name, next, previous, up +@section Compile Mode + +For @samp{compile} mode, @var{mode-args} is a compiler command to be +used in creating a `standard' object file. These arguments should begin +with the name of the C compiler, and contain the @samp{-c} compiler flag +so that only an object file is created. + +Libtool determines the name of the output file by removing the directory +component from the source file name, then substituting the C source code +suffix `.c' with the library object suffix, `.lo'. + +If shared libraries are being built, any necessary PIC generation flags +are substituted into the compilation command. + +@node Link Mode, Install Mode, Compile Mode, Invoking @file{libtool} +@comment node-name, next, previous, up +@section Link Mode + +@samp{link} mode links together object files (including library +objects) to form another library or to create an executable program. + +@var{mode-args} consist of a command using the C compiler to create an +output file (with the @samp{-o} flag) from several object files. + +The following components of @var{mode-args} are treated specially: + +@table @samp +@item -L@var{libdir} +Search @var{libdir} for required libraries that have already been +installed. + +@item -l@var{name} +@var{output-file} requires the installed library @file{lib@var{name}}. + +@item -o @var{output-file} +Create @var{output-file} from the specified objects and libraries. + +@item -rpath @var{libdir} +If @var{output-file} is a library, it will eventually be installed in +@var{libdir}. + +@item -static +If @var{output-file} is a program, then do not link it against any +shared libraries. If @var{output-file} is a library, then only create a +static library. + +@item -version-file @var{verfile} +If @var{output-file} is a library, then search for library versioning +information in @var{verfile}. +@end table + +If the @var{output-file} ends in `.la', then a libtool library is +created, which must be build only from library objects (`.lo' files). +The @samp{-rpath} option is required. In the current implementation, +libtool libraries may not depend on other uninstalled libtool +libraries. + +If the @var{output-file} ends in `.a', then a standard library is +created using @file{ar} and possibly @file{ranlib}. + +Otherwise, an executable program is created. + +@node Install Mode, Finish Mode, Link Mode, Invoking @file{libtool} +@comment node-name, next, previous, up +@section Install Mode + +In @samp{install} mode, libtool interprets @var{mode-args} as an +installation command beginning with @file{cp}, or a BSD-compatible +@file{install} program. + +The rest of the @var{mode-args} are interpreted as arguments to that +command. + +The command is run, and any necessary unprivileged post-installation +commands are also completed. + +@node Finish Mode, Uninstall Mode, Install Mode, Invoking @file{libtool} +@comment node-name, next, previous, up +@section Finish Mode + +@samp{finish} mode helps system administrators install libtool +libraries so that they can be located and linked into user programs. + +Each @var{mode-arg} is interpreted as the name of a library directory. +Running this command may require superuser privileges, so the +@samp{--dry-run} option may be useful. + +@node Uninstall Mode, , Finish Mode, Invoking @file{libtool} +@comment node-name, next, previous, up +@section Uninstall Mode + +This mode deletes installed libraries (and other files). + +The first @var{mode-arg} is the name of the program to use to delete +files (typically @file{/bin/rm}). + +The remaning @var{mode-args} are either flags for the deletion program +(beginning with a `-'), or the names of files to delete. + +@node Integrating Libtool, Versioning, Invoking @file{libtool}, Top +@comment node-name, next, previous, up +@chapter Integrating Libtool with Your Own Packages + +This chapter describes how to integrate libtool with your packages so +that your users can install hassle-free shared libraries. + +@menu +* Makefile Rules:: Writing Makefile rules for libtool. +* Using Automake:: Automatically supporting libtool. +* Configuring:: Configuring libtool for a host system. +* Distributing:: What files to distribute with your package. +@end menu + +@node Makefile Rules, Using Automake, Integrating Libtool, Integrating Libtool +@comment node-name, next, previous, up +@section Writing Makefile Rules for Libtool + +Libtool is fully integrated with Automake (@pxref{Top, , The Automake +Manual, automake.info, The Automake Manual}), starting with Automake +version 1.2. + +If you want to use libtool in a regular @file{Makefile} (or +@file{Makefile.in}), you are on your own. If you're not using Automake +1.2, and you don't know how to incorporate libtool into your package you +need to do one of the following: + +@enumerate 1 +@item +Download Automake (version 1.2 or later) from your nearest GNU mirror, +install it, and start using it. + +@item +Learn how to write Makefile rules by hand. They're sometimes complex, +but if you're clever enough to write rules for compiling your old +libraries, then you should be able to easily figure out new rules for +libtool libraries (hint: examine the @file{Makefile.in} in the +@file{demo} subdirectory of the libtool distribution@dots{} note +especially that it was generated automatically from the +@file{Makefile.am} by Automake). +@end enumerate + +@node Using Automake, Configuring, Makefile Rules, Integrating Libtool +@comment node-name, next, previous, up +@section Using Automake with Libtool + +Libtool library support fits conveniently into Automake's understanding +of what a @samp{PROGRAM} is. + +Here are some samples from the Automake @file{Makefile.am} in the +libtool distribution's @file{demo} subdirectory. + +First, to link a program against a libtool library, just use the +@samp{program_LDADD} variable: + +@example +# Build hell from main.c and libhell.la +bin_PROGRAMS = hell +hell_SOURCES = main.c +hell_LDADD = libhell.la +@end example + +You may use the @samp{program_LDFLAGS} variable to stuff in any flags +you want to pass to libtool while linking @samp{program}, such as +@samp{-static}. + +Building a libtool library is almost as trivial@dots{} note the use of +@samp{libhell_la_LDFLAGS} to pass the @samp{-version-file} +(@pxref{Versioning}) and @samp{-rpath} options to libtool: + +@example +# Build a libtool library, libhell.la for installation in libdir. +lib_PROGRAMS = libhell.la +libhell_la_SOURCES = hello.c foo.c +libhell_la_LDFLAGS = -version-file $(srcdir)/libinfo -rpath $(libdir) +@end example + +@node Configuring, Distributing, Using Automake, Integrating Libtool +@comment node-name, next, previous, up +@section Configuring Libtool + +FIXME +Description of what it means to configure libtool. ltconfig synopsis +description of AM_PROG_LIBTOOL, how to add to aclocal + +@node Distributing, , Configuring, Integrating Libtool +@comment node-name, next, previous, up +@section Including Libtool with Your Package + +In order to use libtool, you need to include the following files with +your package: + +@table @file +@item config.guess +Attempt to guess a canonical system name. + +@item config.sub +Canonical system name validation subroutine script. + +@item ltconfig +Generate a libtool script for a given system. + +@item ltmain.sh +A generic script implementing basic libtool functionality. +@end table + +Note that the libtool script itself should @emph{not} be included with +your package. @xref{Configuring}. + +Rather than coping these files into your package manually, you should +use the @file{libtoolize} program. + +@menu +* Invoking @file{libtoolize}:: @file{libtoolize} command line options. +@end menu + +@node Invoking @file{libtoolize}, , Distributing, Distributing +@comment node-name, next, previous, up +@subsection Invoking @file{libtoolize} + +The @file{libtoolize} program provides a standard way to add libtool +support to your package. In the future, it may implement better usage +checking, or other features to make libtool even easier to use. + +The @file{libtoolize} program has the following synopsis: + +@example +libtoolize [@var{option}]@dots{} +@end example + +@noindent +and accepts the following options: + +@table @samp +@item --automake +Work silently, and assume that Automake libtool support is used. + +@samp{libtoolize --automake} is used by Automake to add libtool files to +your package, when @samp{AM_PROG_LIBTOOL} appears in your +@file{configure.in}. + +@item --copy +@itemx -c +Copy files from the libtool data directory rather than creating +symlinks. + +@item --force +@itemx -f +Replace existing libtool files. By default, @file{libtoolize} won't +overwrite existing files. + +@item --help +Display a help message and exit. + +@item --version +Print @file{libtoolize} version information and exit. +@end table + +@file{libtoolize} displays hints for adding libtool support to your +package, as well. + +@node Versioning, Library Tips, Integrating Libtool, Top +@comment node-name, next, previous, up +@chapter Library Interface Versions + +The most difficult issue introduced by shared libraries is that of +creating and resolving runtime dependencies. Dependencies on programs +and libraries are often described in terms of a single name, such as +@file{sed}. So, I may say ``libtool depends on sed,'' and that is good +enough for most purposes. + +However, when an interface changes regularly, we need to be more +specific: ``Gnus 5.1 requires Emacs 19.28 or above.'' Here, the +description of an interface consists of a name, and a ``version +number.'' + +Even that sort of description is not accurate enough for some purposes. +What if Emacs 20 changes enough to break Gnus 5.1? + +The same problem exists in shared libraries: we require a formal version +system to describe the sorts of dependencies that programs have on +shared libraries, so that the dynamic linker can guarantee that programs +are linked only against libraries that provide the interface they +require. + +@menu +* Interfaces:: What are library interfaces? +* Libtool Versioning:: Libtool's versioning system. +* Version Files:: How libtool tracks library versions. +* Updating @file{libinfo}:: Keeping a library version file up-to-date. +@end menu + +@node Interfaces, Libtool Versioning, Versioning, Versioning +@comment node-name, next, previous, up +@section What Are Library Interfaces? + +Interfaces for libraries may be any of the following (and more): + +@itemize @bullet +@item +global variables (names and types) + +@item +global functions (arguments types and number, return types, and function names) + +@item +standard input, standard output, standard error, and file formats + +@item +sockets, pipes, and other inter-process communication protocols +@end itemize + +Note that static functions do not count as interfaces, because they are +not directly available to the user of the library. + +@node Libtool Versioning, Version Files, Interfaces, Versioning +@comment node-name, next, previous, up +@section Libtool's Versioning System + +Libtool has its own formal versioning system. It is not as flexible as +some, but it is definitely the simplest of the more powerful versioning +systems. + +Think of a library as exporting several sets of interfaces, arbitrarily +represented by integers. When a program is linked against a library, it +may use any subset of all those interfaces. + +Libtool's description of the interfaces that a program uses is very +simple: it encodes the least and the greatest interface numbers in the +resulting binary (@var{first-interface}, @var{last-interface}). + +Then, the dynamic linker is guaranteed that if a library supports +@emph{every} interface number between @var{first-interface} and +@var{last-interface}, then the program can be relinked against that +library. + +Note that this can cause problems because libtool's compatibility +requirements are actually stricter than is necessary. + +Say @file{libfoo} supports interfaces 5, 16, 17, 18, and 19, and that +libtool is used to link @file{test} against @file{libfoo}. + +Libtool encodes the numbers 5 and 19 in @file{test}, and the dynamic +linker will only link @file{test} against libraries that support +@emph{every} interface between 5 and 19. So, the dynamic linker refuses +to link @file{test} against @file{libfoo}! + +In order to eliminate this problem, libtool only allows libraries to +declare consecutive interface numbers. So, @file{libfoo} can declare at +most that it supports interfaces 16 through 19. Then, the dynamic +linker will link @file{test} against @file{libfoo}. + +So, libtool library versions are described by three integers: + +@table @var +@item current +The most recent interface number that this library implements. + +@item age +The difference between the oldest and newest interfaces that this +library implements. In other words, the library implements all the +interface numbers in the range from number @code{@var{current} - +@var{age}} to @code{@var{current}}. + +@item revision +The implementation number of the @var{current} interface. +@end table + +If two libraries have identical @var{current} and @var{age} numbers, +then the dynamic linker chooses the library with the greater +@var{revision} number. + +@node Version Files, Updating @file{libinfo}, Libtool Versioning, Versioning +@comment node-name, next, previous, up +@section Version Files + +By default, libtool creates libraries with @var{current}, @var{age}, and +@var{revision} all set to 0. + +If you want to use libtool's versioning system, then you must specify a +file that contains version information for the library you are creating, +using the @samp{-version-file} flag during link mode (@pxref{Link +Mode}). + +By convention, the name of the version file is @file{libinfo}, though it +can be any file you want. + +Here are the contents of the @file{libinfo} file from the @file{demo} +subdirectory of the libtool distribution: + +@example +# libinfo - used by libtool for library version information +# +# Comments begin with a hash sign. +# +# Each non-comment line has the following format: +# libNAME CURRENT AGE REVISION +libhell 3 1 12 +@end example + +So, this file tells libtool that @file{libhello} supports interfaces 2 +and 3, and that it should be used instead of libraries with revisions +less than 12. + +@node Updating @file{libinfo}, , Version Files, Versioning +@comment node-name, next, previous, up +@section Updating the @file{libinfo} File + +Here are a set of rules to help you update your library version file: + +@enumerate 1 +@item +Start with a version file that contains only: + +@example +libNAME 0 0 0 +@end example + +@noindent +for each libtool library @file{lib@var{name}}. + +@item +Update the version file only immediately before a public release of your +software. More frequent updates are unnecessary, and only guarantee +that the current interface number gets larger faster. + +@item +If the library source code has changed at all since the last update, +then increment @var{revision}. + +@item +If any interfaces have been added, removed, or changed since the last +update, increment @var{current}, and set @var{revision} to 0. + +@item +If any interfaces have been added since the last public release, then +increment @var{age}. + +@item +If any interfaces have been removed since the last public release, then +set @var{age} to 0. +@end enumerate + +@emph{NEVER} try to set library version numbers so that they correspond +to the release of the package that you are making. This is an abuse +that only fosters misunderstanding of the purpose of library versions, +and you would be better off not using a @file{libinfo} file at all. + +@node Library Tips, Modifying, Versioning, Top +@comment node-name, next, previous, up +@chapter Tips for Interface Design + +Writing a good library interface takes a lot of practice and thorough +understanding of the problem that the library is intended to solve. + +If you design a good interface, it won't have to change often, you won't +have to keep updating documentation, and users won't have to keep +relearning how to use the library. + +Here is a brief list of tips for library interface design, which may +help you in your exploits: + +@table @asis +@item Plan ahead +Try to make every interface truly minimal, so that you won't need to +delete entry points very often. + +@item Avoid interface changes +Some people love redesigning and changing entry points just for the heck +of it (note: @emph{renaming} a function is considered changing an entry +point). Don't be one of those people. If you must redesign an +interface, then leave compatibility functions behind so that users don't +need to rewrite their code. + +@item Use opaque data types +The fewer data type definitions a library user has access to, the +better. If possible, design your functions to accept a generic pointer +(which you can cast to an internal data type), and provide access +functions rather than allowing the user to directly manipulate the data. +That way, you have the freedom to change the data structures without +changing the interface. + +This is essentially the same thing as using abstract data types and +inheritance in an object-oriented system. + +@item Use header files +If you are careful to document each of your library's global functions +and variables in header files, and include them in your source files, +then the compiler will let you know if you make any interface changes by +accident. + +@item Use the @code{static} keyword whenever possible +The fewer global functions your library has, the more flexibility you'll +have in changing them. Static functions and variables may change forms +as often as you like@dots{} your users cannot access them, so they +aren't interface changes. +@end table + +@node Modifying, Index, Library Tips, Top +@comment node-name, next, previous, up +@chapter Modifying Libtool + +FIXME +Description of libtool script contents, the interface between ltconfig +and libtool + +@node Index, , Modifying, Top +@comment node-name, next, previous, up +@unnumbered Index + +@printindex cp + +@c summarycontents +@contents +@bye diff --git a/libtoolize.in b/libtoolize.in new file mode 100644 index 000000000..5231354d1 --- /dev/null +++ b/libtoolize.in @@ -0,0 +1,171 @@ +#! /bin/sh +# libtoolize - Prepare a package to use libtool. +# @configure_input@ +# Copyright (C) 1996 Free Software Foundation, Inc. +# Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# The name of this program. +progname=`echo "$0" | sed 's%^.*/%%'` + +# Constants. +PROGRAM=libtoolize +PACKAGE=@PACKAGE@ +VERSION=@VERSION@ + +# Directory names. +prefix=@prefix@ +datadir=@datadir@ +pkgdatadir=@pkgdatadir@ +aclocaldir=@aclocaldir@ + +libtool_m4="$aclocaldir/libtool.m4" + +help="Try \`$progname --help' for more information." +rm="rm -f" +ln_s="ln -s" +cp="cp -f" + +# Global variables. +automake= +copy= +force= +status=0 + +for arg +do + case "$arg" in + --help) + cat <&2 + echo "$help" 1>&2 + exit 1 + ;; + + *) + echo "$progname: too many arguments" 1>&2 + echo "$help" 1>&2 + exit 1 + ;; + esac +done + +if test -f configure.in; then : +else + echo "$progname: \`configure.in' does not exist" 1>&2 + echo "$help" 1>&2 + exit 1 +fi + +files=`cd $pkgdatadir && ls` +if test -z "$files"; then + echo "$progname: cannot \`cd' to \`$pkgdatadir'" 1>&2 + exit 1 +fi + +if test -z "$automake"; then + if egrep AM_PROG_LIBTOOL configure.in >/dev/null 2>&1; then : + else + echo "Remember to add \`AM_PROG_LIBTOOL' to \`configure.in'." + fi + + if egrep AC_PROG_RANLIB configure.in >/dev/null 2>&1; then + echo "Using \`AC_PROG_RANLIB' is rendered obsolete by \`AM_PROG_LIBTOOL'" + fi + + if egrep '^AC_DEFUN\(AM_PROG_LIBTOOL' aclocal.m4 >/dev/null 2>&1; then + # Check the version number on libtool.m4 and the one used in aclocal.m4. + instserial=`grep '^# serial ' $libtool_m4 | grep 'AM_PROG_LIBTOOL' | sed -e 's/^# serial \([0-9][0-9]*\).*$/\1/; q'` + + if test -z "$instserial"; then + echo "$progname: warning: no serial number on \`$libtool_m4'" 1>&2 + else + # If the local macro has no serial number, we assume it's ancient. + localserial=`grep '^# serial ' aclocal.m4 | grep 'AM_PROG_LIBTOOL' | sed -e 's/^# serial \([0-9][0-9]*\).*$/\1/; q'` + + test -z "$localserial" && localserial=0 + + if test "$localserial" -lt "$instserial"; then + echo "You should update \`aclocal.m4' with the contents of \`$libtool_m4'" + elif test "$localserial" -gt "$instserial"; then + echo "$progname: \`$libtool_m4' has serial number $instserial, less than $localserial found in \`aclocal.m4'" 1>&2 + fi + fi + else + echo "Add the contents of \`$libtool_m4' to \`aclocal.m4'." + fi +fi + +for file in $files; do + if test -f "$file" && test -z "$force"; then + test -z "$automake" && echo "$progname: \`$file' exists: use \`--force' to overwrite" 1>&2 + continue + fi + + $rm $file + if test -n "$ln_s" && $ln_s $pkgdatadir/$file $file; then : + elif $cp $pkgdatadir/$file $file; then : + else + echo "$progname: cannot copy \`$pkgdatadir/$file' to \`$file'" 1>&2 + status=1 + fi +done + +exit $status + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/ltconfig.in b/ltconfig.in new file mode 100755 index 000000000..004f801e5 --- /dev/null +++ b/ltconfig.in @@ -0,0 +1,738 @@ +#! /bin/sh + +# ltconfig - Create a system-specific libtool. +# @configure_input@ +# Copyright (C) 1996, Free Software Foundation, Inc. +# Gordon Matzigkeit , 1996 +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A lot of this script is taken from autoconf-2.10. + +# The name of this program. +progname=`echo "$0" | sed 's%^.*/%%'` + +# Constants: +PROGRAM=ltconfig +PACKAGE=@PACKAGE@ +VERSION=@VERSION@ +rm="rm -f" + +help="Try \`$progname --help' for more information." + +# Global variables: +enable_shared=yes +enable_static=yes +ltmain=NONE +silent= +srcdir= +ac_config_guess= +ac_config_sub= +host=NONE +nonopt=NONE +verify_host=yes +with_gcc=no + +old_CC="$CC" +old_CFLAGS="$CFLAGS" +old_LD="$LD" +old_RANLIB="$RANLIB" + +# Parse the command line options. +args= +prev= +for option +do + case "$option" in + -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + eval "$prev=\$option" + prev= + continue + fi + + case "$option" in + --help) cat <&2 + echo "$help" 1>&2 + exit 1 + ;; + + *) + if test "$ltmain" = NONE; then + ltmain="$option" + elif test "$host" = NONE; then + if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then + echo "$progname: warning \`$option' is not a valid host type" 1>&2 + fi + host="$option" + else + echo "$progname: too many arguments" 1>&2 + echo "$help" 1>&2 + exit 1 + fi ;; + esac +done + +if test "$ltmain" = NONE; then + echo "$progname: you must specify a LTMAIN file" 1>&2 + echo "$help" 1>&2 + exit 1 +fi + +if test -e "$ltmain"; then : +else + echo "$progname: warning: \`$ltmain' does not exist" 1>&2 +fi + +# Quote any args containing shell metacharacters. +ltconfig_args= +for arg +do + case "$arg" in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ltconfig_args="$ltconfig_args '$arg'" ;; + *) ltconfig_args="$ltconfig_args $arg" ;; + esac +done + +# A relevant subset of AC_INIT. + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 5 compiler messages saved in config.log +# 6 checking for... messages and results +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>>./config.log + +# NLS nuisances. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LANG+set}" = set; then LANG=C; export LANG; fi + +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + +if test -z "$srcdir"; then + # Assume the source directory is the same one as the path to ltmain.sh. + srcdir=`echo "$ltmain" | sed 's%/[^/]*$%%'` + test "$srcdir" = "$ltmain" && srcdir=. +fi + +if test "$verify_host" = yes; then + # Check for config.guess and config.sub. + ac_aux_dir= + for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/config.guess; then + ac_aux_dir=$ac_dir + break + fi + done + if test -z "$ac_aux_dir"; then + echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2 + echo "$help" 1>&2 + exit 1 + fi + ac_config_guess=$ac_aux_dir/config.guess + ac_config_sub=$ac_aux_dir/config.sub + + # Make sure we can run config.sub. + if $ac_config_sub sun4 >/dev/null 2>&1; then : + else + echo "$progname: cannot run $ac_config_sub" 1>&2 + echo "$help" 1>&2 + exit 1 + fi + + echo $ac_n "checking host system type""... $ac_c" 1>&6 + + host_alias=$host + case "$host_alias" in + NONE) + if host_alias=`$ac_config_guess`; then : + else + echo "$progname: cannot guess host type; you must specify one" 1>&2 + echo "$help" 1>&2 + exit 1 + fi ;; + esac + host=`$ac_config_sub $host_alias` + echo "$ac_t""$host" 1>&6 + +elif test "$host" = NONE; then + echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2 + echo "$help" 1>&2 + exit 1 +else + host_alias=$host +fi + +host_cpu=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'` + +# Check to see if we are using GCC. +if test "$with_gcc" = no; then + # If CC is not set, then try to find GCC or a usable CC. + if test -z "$CC"; then + echo $ac_n "checking for gcc... $ac_c" 1>&6 + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:" + for dir in $PATH; do + IFS="$save_ifs" + test -z "$dir" && dir=. + if test -f $dir/gcc; then + CC="gcc" + break + fi + done + IFS="$save_ifs" + + if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 + else + echo "$ac_t""no" 1>&6 + fi + fi + + # Not "gcc", so try "cc", rejecting "/usr/ucb/cc". + if test -z "$CC"; then + echo $ac_n "checking for cc... $ac_c" 1>&6 + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:" + cc_rejected=no + for dir in $PATH; do + test -z "$dir" && dir=. + if test -f $dir/cc; then + if test "$dir/cc" = "/usr/ucb/cc"; then + cc_rejected=yes + continue + fi + CC="cc" + break + fi + done + IFS="$save_ifs" + if test $cc_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same name, so the bogon will be chosen + # first if we set CC to just the name; use the full file name. + shift + set dummy "$dir/cc" "$@" + shift + CC="$@" + fi + fi + + if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 + else + echo "$ac_t""no" 1>&6 + fi + + if test -z "$CC"; then + echo "$progname: error: no acceptable cc found in \$PATH" 1>&2 + exit 1 + fi + fi + + # Now see if the compiler is really GCC. + with_gcc=no + echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6 + + trap "$rm conftest.c; exit 1" 1 2 15 + $rm conftest.c + cat > conftest.c </dev/null 2>&1; then : + with_gcc=yes + fi + $rm conftest.c + echo $ac_t "$with_gcc" 1>&6 +fi + +echo $ac_n "checking PIC compiler flags... $ac_c" 1>&6 +compile_flags= +profile_flag_pattern= +wl= +link_static_flag= + +if test "$with_gcc" = yes; then + compile_flags='-fPIC -DPIC' + profile_flag_pattern='-pg?' + wl='-Wl,' + link_static_flag='-static' + case "$host" in + *-*-aix3* | *-*-aix4*) + # Yippee! All AIX code is position-independent. + compile_flags='-DPIC' + ;; + esac +else + # PORTME Check for PIC flags for the system compiler. + case "$host" in + *-*-aix3* | *-*-aix4*) + compile_flags='-DPIC' + ;; + + *-*-hpux10*) + compile_flags='+Z -DPIC' + ;; + + *-*-osf3*) + # Yippee! Another system with position-independant code by default. + compile_flags='-DPIC' + ;; + + *-*-solaris2*) + compile_flags='-KPIC -DPIC' + link_static_flag='-Bstatic' + ;; + + *-*-sunos4*) + compile_flags='-PIC -DPIC' + link_static_flag='-Bstatic' + ;; + + *) + can_build_shared=no + ;; + esac +fi + +if test -n "$compile_flags"; then + echo $ac_t "$compile_flags" 1>&6 + compile_flags=" $compile_flags" +else + echo $ac_t none 1>&6 +fi + +echo $ac_n "checking static linking compiler flag... $ac_c" 1>&6 +if test -n "$link_static_flag"; then + echo $ac_t "$link_static_flag" 1>&6 +else + echo $ac_t none 1>&6 +fi + +# See if we're really using GNU ld. +test -z "$LD" && LD="ld" +with_gnu_ld=no +linker="$LD" +echo $ac_n "checking if $LD is GNU ld... $ac_c" 1>&6 +if $LD --version 2>&1 | egrep 'with BFD' > /dev/null; then + with_gnu_ld=yes + linker="GNU ld" +fi +echo $ac_t "$with_gnu_ld" 1>&6 + +# See if the linker supports building shared libraries. +echo $ac_n "checking if $linker supports shared libraries... $ac_c" 1>&6 + +archive_cmds= +link_rpath_flag= +hardcode_minus_L=no +hardcode_shlibpath_var=no + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # See if GNU ld supports shared libraries. + + case "$host" in + *-*-sunos4*) + ld_shlibs=yes + ;; + + *) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + ld_shlibs=yes + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = yes; then + archive_cmds='$cc -shared ${wl}-soname $wl$soname -o $lib$libobjs$deplibs' + link_rpath_flag='${wl}-rpath $wl$libdir' + fi +else + # PORTME fill in a description of your system's linker (not GNU ld) + case "$host" in + *-*-aix3*) + archive_cmds='$rm $lib.exp;/ucb/nm$libobjs | egrep " D " | sed "s/^.* //" > $lib.exp;$LD -o $lib.o$libobjs -bE:$lib.exp -T512 -H512 -bM:SRE -lc$deplibs;ar cru $lib $lib.o' + hardcode_shlibpath_var=yes + hardcode_minus_L=yes + ;; + + *-*-aix4*) + archive_cmds='$rm $lib.exp;/bin/nm -B$libobjs | egrep " D " | sed "s/^.* //" > $lib.exp;$cc -o $lib.o$libobjs ${wl}-bE:$lib.exp ${wl}-bM:SRE ${wl}-bnoentry$deplibs;ar cru $lib $lib.o' + hardcode_shlibpath_var=yes + hardcode_minus_L=yes + ;; + + *-*-freebsd*) + archive_cmds='$LD -Bshareable -o $lib$libobjs$deplibs' + hardcode_minus_L=yes + link_rpath_flag='-L$libdir' + ;; + + *-*-hpux10*) + archive_cmds='$LD -b +h $soname +s +b $libdir -o $lib$libobjs$deplibs' + link_rpath_flag='${wl}+b ${wl}$libdir' + hardcode_minus_L=yes + hardcode_shlibpath_var=yes + ;; + + *-*-netbsd*) + # Tested with NetBSD 1.2 ld + archive_cmds='$LD -Bshareable -o $lib$libobjs$deplibs' + link_rpath_flag='-R$libdir' + ;; + + *-*-osf3*) + archive_cmds='$LD -shared -o $lib -rpath $libdir -soname $soname -set_version $verstring$libobjs -lc$deplibs' + link_rpath_flag='${wl}-rpath ${wl}$libdir' + ;; + + *-*-solaris2*) + archive_cmds='$LD -G -z text -h $soname -o $lib$libobjs$deplibs' + link_rpath_flag='-R$libdir' + ;; + + *-*-sunos4*) + objs2shlib='$LD -assert pure-text -Bstatic -o $lib$libobjs$deplibs' + link_rpath_flag='-L$libdir' + hardcode_minus_L=yes + ;; + + *) + ld_shlibs=no + can_build_shared=no + ;; + esac +fi +echo $ac_t "$ld_shlibs" 1>&6 + +if test "$hardcode_shlibpath_var" = yes && test "$hardcode_minus_L" = yes; then + echo "$progname: warning: $LD needlessly hardcodes library paths into binaries" 1>&2 + echo "$PACKAGE will compensate by relinking binaries at install time." 1>&2 +fi + +# PORTME Fill in your ld.so characteristics +can_build_shared=yes +lib_names= +soname_spec= +postinstall_cmds= +finish_cmds= +shlibpath_var=LD_LIBRARY_PATH +version_type=none +dynamic_linker="$host_os ld.so" + +echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6 +case "$host" in +*-*-aix3* | *-*-aix4*) + # Shared libraries and static libraries currently use the same namespace. + test "$enable_shared" = no || enable_static=no + + version_type=solaris # But only for show... AIX has no versioning. + lib_names='$libname.so.$versuffix $libname.a' + shlibpath_var=LIBPATH + ;; + +*-*-freebsd*) + version_type=sunos + lib_names='$libname.so.$versuffix $libname.so' + finish_cmds='ldconfig -m $libdir' + ;; + +*-*-gnu*) + version_type=sunos + lib_names='$libname.so.$versuffix' + ;; + +*-*-hpux10*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + dynamic_linker="$host_os dld.sl" + version_type=hpux + shlibpath_var=SHLIB_PATH + lib_names='$libname.sl.$versuffix $libname.sl.$major $libname.sl' + soname_spec='$libname.sl.$major' + postinstall='chmod 555 $lib' + ;; + +# No shared lib support for linuxoldld or linuxaout. +*-*-linuxoldld* | *-*-linuxaout*) + dynamic_linker=no + can_build_shared=no + ;; + +*-*-linux*) + version_type=solaris + lib_names='$libname.so.$versuffix $libname.so.$major $libname.so' + finish_cmds='ldconfig $libdir' + ;; + +*-*-netbsd*) + version_type=sunos + lib_names='$libname.so.$versuffix' + finish_cmds='ldconfig -m $libdir' + ;; + +*-*-osf3*) + version_type=osf + soname_spec='$libname.so' + lib_names='$libname.so.$versuffix $libname.so' + ;; + +*-*-solaris2*) + version_type=solaris + lib_names='$libname.so.$versuffix' + ;; + +*-*-sunos4*) + version_type=sunos + lib_names='$libname.so.$versuffix' + finish_cmds='ldconfig $libdir' + ;; + +*) + dynamic_linker=no + can_build_shared=no + ;; +esac +echo "$ac_t""$dynamic_linker" + + +# Report the consequences. +echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6 + +echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6 +test "$can_build_shared" = "no" && enable_shared=no +echo "$ac_t""$enable_shared" 1>&6 + +# All known linkers require a `.a' archive for static linking. +enable_static=yes + +# Determine commands to create old-style static archives. +old_archive_cmds='ar cru $oldlib$oldobjs' +old_postinstall_cmds='' + +# If RANLIB is not set, then run the test. +if test -z "$RANLIB"; then + result=no + + echo $ac_n "checking for ranlib... $ac_c" 1>&6 + if test "$result" = no; then + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:" + for dir in $PATH; do + test -z "$dir" && dir=. + if test -f $dir/ranlib; then + RANLIB="ranlib" + result="ranlib" + break + fi + done + IFS="$save_ifs" + fi + + echo $ac_t "$result" 1>&6 +fi + +if test -n "$RANLIB"; then + old_archive_cmds="$old_archive_cmds;\$RANLIB \$oldlib" + old_postinstall_cmds='$RANLIB $oldlib' +fi + +ofile=libtool +trap "rm -fr $ofile; exit 1" 1 2 15 +echo creating $ofile +rm -fr $ofile +cat < $ofile +#! /bin/sh + +# libtool - Provide generalized library-building support services. +# See ABOUT-LIBS for more information. +# +# Generated automatically by $PROGRAM - GNU $PACKAGE $VERSION +# This program was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# CC="$old_CC" CFLAGS="$old_CFLAGS" LD="$old_LD" RANLIB="$old_RANLIB" \\ +# $0$ltconfig_args +# +# Compiler and other test output produced by $progname, useful for +# debugging $progname, is in ./config.log if it exists. + +# The version of $progname that generated this script. +LTCONFIG_VERSION="$VERSION" + +# The host system. +host_alias="$host_alias" +host="$host" + +# The linker used to build libraries. +LD='$LD' + +# How to pass a linker flag through the compiler. +wl='$wl' + +# Whether or not to build libtool libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build old-style libraries. +build_old_libs=$enable_static + +# Additional compiler flags for building library objects. +compile_flags='$compile_flags' + +# Compiler flag to prevent dynamic linking. +link_static_flag='$link_static_flag' + +# Pattern to match compiler flags for creating libNAME_p libraries: +profile_flag_pattern='$profile_flag_pattern' + +# Library versioning type. +version_type=$version_type + +# List of archive names. First name is the real one, the rest are links. +lib_names='$lib_names' + +# The coded name of the library, if different from the real name. +soname_spec='$soname_spec' + +# Commands used to build and install an old-style archive. +RANLIB='$RANLIB' +old_archive_cmds='$old_archive_cmds' +old_postinstall_cmds='$old_postinstall_cmds' + +# Commands used to build and install a shared archive. +archive_cmds='$archive_cmds' +postinstall_cmds='$postinstall_cmds' + +# Commands used to finish a libtool library installation in a directory. +finish_cmds='$finish_cmds' + +# The flag that specifies a runtime search path when linking. +link_rpath_flag='$link_rpath_flag' + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L + +EOF + +# Detect if we are using a relative or absolute path to ltmain.sh. +case "$ltmain" in +/*) cat <> $ofile +# Execute the libtool backend. +. $ltmain +EOF2 + ;; +*) cat <> $ofile +# Find the path to this script. +thisdir=\`echo "\$0" | sed -e 's%/[^/]*%%'\` +test "X\$0" = "X\$thisdir" && thisdir=. + +# Execute the libtool backend. +. \$thisdir/$ltmain +EOF3 + ;; +esac + +echo 'exit 1' >> $ofile + +chmod +x $ofile +exit 0 + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/ltmain.sh.in b/ltmain.sh.in new file mode 100644 index 000000000..003b9f025 --- /dev/null +++ b/ltmain.sh.in @@ -0,0 +1,1262 @@ +# ltmain.sh - Provide generalized library-building support services. +# @configure_input@ +# Copyright (C) 1996 Free Software Foundation, Inc. +# Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# The name of this program. +progname=`echo "$0" | sed 's%^.*/%%'` + +# Constants. +PROGRAM=ltmain.sh +PACKAGE=@PACKAGE@ +VERSION=@VERSION@ + +default_mode=NONE +help="Try \`$progname --help' for more information." +ln_s="ln -s" +magic="%%%MAGIC variable%%%" +mkdir="mkdir" +objdir=.libs +rm="rm -f" + +if test "$LTCONFIG_VERSION" != "$VERSION"; then + echo "$progname: ltconfig version \`$LTCONFIG_VERSION' does not match $PROGRAM version \`$VERSION'" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show=echo +show_help= + +# Parse our command line options once, thoroughly. +while test -n "$1" +do + arg="$1" + shift + + case "$arg" in + -*=*) optarg=`echo "$arg" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + eval "$prev=\$arg" + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case "$arg" in + --help) + show_help=yes + ;; + + --version) + echo "$PROGRAM - GNU $PACKAGE $VERSION" + exit 0 + ;; + + --dry-run | -n) + run=: + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + -*) + echo "$progname: unrecognized option \`$arg'" 1>&2 + echo "$help" 1>&2 + exit 1 + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + + +if test -n "$prevopt"; then + echo "$progname: option \`$prevopt' requires an argument" 1>&2 + echo "$help" + exit 1 +fi + + +if test -z "$show_help"; then + + # Infer the operation mode. + if test "$mode" = NONE; then + case "$nonopt" in + *cc) + if echo " $@ " | egrep "[ ]-c[ ]" > /dev/null 2>&1; then + mode=compile + else + mode=link + fi + ;; + *install*|cp) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # Just use the default operation mode. + if test "$mode" = NONE; then + if test -n "$nonopt"; then + echo "$progname: warning: cannot infer operation mode from \`$nonopt $@'" 1>&2 + else + echo "$progname: warning: cannot infer operation mode from no MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # These modes are in order of execution frequency so that they run quickly. + case "$mode" in + # libtool compile mode + compile) + # Get the compilation command and the source file. + base_compile="$nonopt" + lastarg= + srcfile= + + for arg + do + # Quote any args containing shell metacharacters. + case "$arg" in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*|*\"*) + quote_arg="'$arg'" ;; + *) quote_arg="$arg" ;; + esac + + base_compile="$base_compile$lastarg" + srcfile="$quote_arg" + lastarg=" $srcfile" + done + + # Get the name of the library object. + libobj=`echo "$srcfile" | sed -e 's%^.*/%%' -e 's/\.c$/.lo/'` + case $libobj in + *.lo) ;; + *) + echo "$progname: cannot determine name of library object from \`$srcfile'" + exit 1 + ;; + esac + + if test -z "$base_compile"; then + echo "$progname: you must specify a compilation command" 1>&2 + echo "$help" 1>&2 + exit 1 + fi + + # Delete any old library object. + $run $rm $libobj + + # Only use the compile flags if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + base_compile="$base_compile$compile_flags" + fi + + $show "$base_compile $srcfile -o $libobj" + eval "$run $base_compile $srcfile -o $libobj" + + # Exit with the status of the compile command. + exit $? + ;; + + # libtool link mode + link) + # Go through the arguments, transforming them on the way. + cc="$nonopt" + args="$cc" + compile_command="$cc" + finalize_command="$cc" + deplibs= + libdir= + libobjs= + link_against_libtool_libs= + link_static= + ltlibs= + objs= + output= + prev= + prevarg= + temp_rpath= + vfile= + + + # Maybe set the library names to libNAME_p.a if we are doing profiling. + if echo " $@ " | egrep "[ ]$profile_flag_pattern[ ]" > /dev/null 2>&1; then + suffix=p + else + suffix= + fi + + for arg + do + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case "$prev" in + output) + compile_command="$compile_command $objdir/$arg" + finalize_command="$finalize_command $objdir/$arg"T + args="$args $arg" + ;; + esac + + eval "$prev=\$arg" + prev= + + continue + fi + + # The finalize and compile arguments. + farg="$arg" + carg="$arg" + + case "$arg" in + -L*) + deplibs="$deplibs $arg" + dir=`echo "$arg" | sed 's%^-L\(.*\)$%\1%'` + case "$dir" in + /*) + ;; + *) + echo "$progname: \`-L$dir' cannot specify a relative directory" 1>&2 + exit 1 + ;; + esac + ;; + + -l*) deplibs="$deplibs $arg" ;; + + -o) prev=output ;; + + -rpath) prev=libdir ;; + + -static) + build_libtool_libs=no + farg="$link_static_flag" + carg="$farg" + ;; + + -version-file) prev=vfile ;; + + -*) cc="$cc $arg" ;; # Some other compiler flag. + + *.o) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A library object. + libobjs="$libobjs $arg" + ;; + + *.la) + # A libtool-controlled library. + dir=`echo "$arg" | sed 's%/[^/]*$%%'` + test "$dir" = "$arg" && dir=. + file=`echo "$arg" | sed 's%^.*/%%'` + + case "$file" in + lib?*.la) + link_against_libtool_libs="$link_against_libtool_libs $arg" + if test "$build_libtool_libs" = yes; then + # Specify the library as -lNAME. + carg="-l`echo "$file" | sed 's/lib\(..*\)\.la$/\1/'`" + farg="$carg" + + if test -n "$shlibpath_var"; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + "* $dir *") ;; + *) temp_rpath="$temp_rpath $dir" ;; + esac + fi + + if test -n "$link_rpath_flag"; then + # Check to see that this really is a libtool archive. + if egrep "^# Generated by $PROGRAM" $arg >/dev/null 2>&1; then : + else + echo "$progname: \`$arg' is not a valid libtool archive" 1>&2 + exit 1 + fi + + libdir= + . $file + + if test -z "$libdir"; then + echo "$progname: \`$arg' contains no -rpath information" 1>&2 + exit 1 + fi + + carg="`eval echo \"$link_rpath_flag\"` $carg" + farg="$carg" + fi + + if test "$hardcode_minus_L" != yes; then + # Just give the right -L directory flag. + carg="-L$dir/$objdir $carg" + + elif test "$hardcode_shlibpath_var" = yes; then + # Give an absolute path to the library. + dir=`cd $dir && pwd` + case "$dir" in + /*) carg="-L`cd $dir && pwd`/$objdir $arg" ;; + *) + echo "$progname: cannot determine absolute pathname of \`$dir'" 1>&2 + exit 1 + ;; + esac + fi + else + # Transform directly to old archives if we don't build new libraries. + carg="$dir/$objdir/`echo "$file" | sed 's/\.la$/.a/'`" + farg="$carg" + fi + ;; + *) + echo "$progname: improperly formed library name \`$arg' (not libNAME.la)" 1>&2 + echo "$help" + exit 1 + ;; + esac + ;; + esac + + args="$args $arg" + + compile_command="$compile_command $carg" + finalize_command="$finalize_command $farg" + prevarg="$arg" + done + + if test -n "$prev"; then + echo "$progname: the \`$prevarg' option requires an argument" + echo "$help" 1>&2 + exit 1 + fi + + oldobjs= + oldlib= + case "$output" in + "") + echo "$progname: you must specify an output file" 1>&2 + echo "$help" 1>&2 + exit 1 + ;; + + */*) + echo "$progname: output file \`$output' must have no directory components" 1>&2 + exit 1 + ;; + + *.a) + # Old archive. + build_old_libs=yes + ;; + + lib?*.la) + libname=`echo "$output" | sed 's/\.la$//'` + + if test -n "$objs"; then + echo "$progname: cannot build libtool library \`$output' from non-libtool objects" + exit 1 + fi + + # How the heck do we write a wrapper for a shared library? + if test -n "$link_against_libtool_libs"; then + echo "$progname: libtool libraries may not depend on uninstalled libraries" 1>&2 + exit 1 + fi + + # FIXME - screen out invalid options (such as link_static) + + if test -z "$libdir"; then + echo "$progname: you must specify an installation directory with \`-rpath'" 1>&2 + exit 1 + fi + + if test -z "$vfile"; then + # Default version line: 0 0 0 + current=0 + age=0 + revision=0 + + elif test -r "$vfile"; then + # Get version information + line=`egrep "^$libname[ ]" "$vfile"` + set dummy $line + + if test -z "$2"; then + echo "$progname: no version information for \`$libname' in \`$vfile'" 1>&2 + exit 1 + fi + + current="$3" + age="$4" + revision="$5" + + if test -z "$revision"; then + echo "$progname: \`$vfile' must specify a CURRENT, AGE, and REVISION for \`$libname'" 1>&2 + exit 1 + fi + + if test "$age" -gt "$current"; then + echo "$progname: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + echo "\`$vfile' contains invalid version information for \`$libname'" 1>&2 + exit 1 + fi + else + echo "$progname: version file \`$vfile' is not readable" 1>&2 + exit 1 + fi + + # Calculate the version variables. + version_vars="version_type current age revision" + case "$version_type" in + none) ;; + + hpux) + version_vars="$version_vars major versuffix" + major="$current" + versuffix="$current.$revision" + ;; + + osf) + version_vars="$version_vars versuffix verstring" + versuffix="$current.$age.$revision" + verstring="$versuffix" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test $loop != 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + solaris) + version_vars="$version_vars major versuffix" + major=`expr $current - $age` + verstring="$major.$age.$revision" + ;; + + sunos) + version_vars="$version_vars versuffix" + versuffix="$current.$revision" + ;; + + *) + echo "$progname: unknown library version type \`$version_type'" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 + ;; + esac + + # Maybe add a suffix. + test -n "$suffix" && libname=$libname"_$suffix" + + if test "$build_libtool_libs" = yes; then + # Get the real and link names of the library. + library_names=`eval echo \"$lib_names\"` + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname"; then + soname=`eval echo \"$soname_spec\"` + else + soname="$realname" + fi + + lib="$objdir/$realname" + linknames= + for link + do + linknames="$linknames $objdir/$link" + done + + # Create the output directory, or remove our outputs if we need to. + if test -d $objdir; then + $show "$rm $objdir/$libname.*" + $run $rm $objdir/$libname.* + else + $show "$mkdir $objdir" + $run $mkdir $objdir || exit $? + fi + + # Do each of the archive commands. + cmds=`eval echo \"$archive_cmds\"` + IFS=${IFS= }; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run $cmd || exit $? + done + IFS="$save_ifs" + + # Create links to the real library. + for link in $linknames; do + $show "$ln_s $realname $link" + $run $ln_s $realname $link || exit $? + done + fi + ;; + + *.la) + echo "$progname: improperly formed library name \`$arg' (not libNAME.la)" 1>&2 + echo "$help" + exit 1 + ;; + + *) + if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then + # We have no uninstalled library dependencies, so finalize right now. + $show "$finalize_command" + $run $finalize_command + exit $? + fi + + # Create the binary in the object directory, then wrap it. + if test -d $objdir; then : + else + $show "$mkdir $objdir" + $run $mkdir $objdir || exit $? + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case "$dir" in + /*) + # Absolute path. + rpath="$rpath:$dir/$objdir" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath:\$thisdir/$dir/$objdir" + ;; + esac + done + + # Strip the ugly leading colon. + rpath=`echo "$rpath" | sed 's/^://'` + + # Prettify the rpath for the link command. + linkrpath=`echo "$rpath" | sed 's%\$thisdir/%%g'` + fi + + # Delete the old output file. + $run $rm $output + + if test "$hardcode_minus_L" != yes; then + # Things are fine, the world is a beautiful place. + $show "$compile_command" + + elif test "$hardcode_shlibpath_var" != yes; then + # We just need to export the shlibpath for the link command. + $show "$shlibpath_var=$linkrpath $compile_command" + eval "export $shlibpath_var=$linkrpath" + + else + # AGH! Flame the AIX and HP-UX people for me, will ya? + echo "$progname: warning: using a buggy hardcoding system linker" 1>&2 + echo "$progname: relinking will be required before \`$output' can be installed" 1>&2 + + $show "$compile_command" + fi + + $run $compile_command || exit $? + + # Now create the wrapper script. + echo "creating $output" + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + $rm $output + trap "$rm $output; exit 1" 1 2 15 + + cat > $output <> $output <>$output <&2 + echo "This script is just a wrapper for \$program." 1>&2 + echo "See the $PACKAGE documentation for more information." 1>&2 + exit 1 + fi +fi +EOF + chmod +x $output + fi + exit 0 + ;; + esac + + + # See if we need to build an old-fashioned archive. + if test "$build_old_libs" = "yes"; then + case "$output" in + *.la) + # Now set the variables for building old libraries. + oldlib="$objdir/$libname.a" + oldobjs="$libobjs" + ;; + *) + oldlib="$output" + oldobjs="$objs$libobjs" + $show "$rm $oldlib" + $run $rm $oldlib + ;; + esac + cmds=`eval echo \"$old_archive_cmds\"` + + # Do each command in the archive commands. + IFS=${IFS= }; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run $cmd || exit $? + done + IFS="$save_ifs" + fi + + # Now create the libtool archive. + case "$output" in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.a" + + echo "creating $output" + + # Only create the output if not a dry run. + if test -z "$run"; then + cat > $output <&2 + echo "$help" 1>&2 + exit 1 + fi + + if test -n "$prev"; then + echo "$progname: the \`$prev' option requires an argument" 1>&2 + echo "$help" 1>&2 + exit 1 + fi + + if test -z "$files"; then + if test -z "$dest"; then + echo "$progname: no file or destination specified" 1>&2 + else + echo "$progname: you must specify a destination" 1>&2 + fi + echo "$help" 1>&2 + exit 1 + fi + + # Strip any trailing slash from the destination. + dest=`echo "$dest" | sed 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test -n "$isdir"; then + destdir="$dest" + else + destdir=`echo "$dest" | sed 's%/[^/]*$%%'` + fi + case "$destdir" in + /*) ;; + *) + echo "$progname: $destdir must be an absolute directory name" 1>&2 + echo "$help" 1>&2 + exit 1 + esac + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case "$file" in + *.a) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if egrep "^# Generated by $PROGRAM" $file >/dev/null 2>&1; then : + else + echo "$progname: \`$file' is not a valid libtool archive" 1>&2 + echo "$help" 1>&2 + exit 1 + fi + + library_names= + old_library= + . $file + + # Add the libdir to current_libdirs if it is the destination. + if test "$destdir" = "$libdir"; then + case "$current_libdirs " in + "* $libdir *") ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + "* $libdir *") ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir="`echo "$file" | sed 's%/[^/]*$%%'`/" + test "$dir" = "$file/" && dir= + dir="$dir$objdir" + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + # FIXME support stripping libraries + if test -n "$stripme"; then + echo "$progname: will not strip libraries (yet)" 1>&2 + fi + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$realname $destdir/$realname" + $run $install_prog $dir/$realname $destdir/$realname || exit $? + + if test -n "$1"; then + # Delete the old symlinks. + $show "$rm $@" + $run $rm $@ + + # ... and create new ones. + for linkname; do + $show "$ln_s $realname $destdir/$linkname" + $run $ln_s $realname $destdir/$linkname + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + cmds=`eval echo \"$postinstall_cmds\"` + IFS=${IFS= }; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run $cmd || exit $? + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`echo "$file" | sed 's%^.*/%%'` + $show "$install_prog $file $destdir/$name" + $run $install_prog $file $destdir/$name || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *) + # Do a test to see if this is really a libtool program. + if egrep "^# Generated by $PROGRAM" $file >/dev/null 2>&1; then + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + link_against_libtool_libs= + finalize_command= + + # If there is no pathname component, then add one. + case "$file" in + */*) . $file ;; + *) . ./$file ;; + esac + + # Check the variables that should have been set. + if test -z "$link_against_libtool_libs" || test -z "$finalize_command"; then + echo "$progname: invalid libtool wrapper script \`$file'" + exit 1 + fi + + for lib in $link_against_libtool_libs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + . $lib + fi + libfile="$libdir/`echo "$lib" | sed 's%^.*/%%g'`" + if test -z "$libdir"; then + echo "$progname: warning: \`$lib' contains no libdir information" + elif test -f "$libfile"; then : + else + echo "$progname: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + fi + done + + if test "$hardcode_minus_L" = yes && test "$hardcode_shlibpath_var" = yes; then + echo "$progname: warning: relinking \`$file' on behalf of your buggy system linker" + $show "$finalize_command" + if $run $finalize_command; then : + else + echo "$progname: error: relink \`$file' with the above command before installing it" 1>&2 + continue + fi + file="$objdir/$file"T + else + # Install the binary that we compiled earlier. + dir=`echo "$file" | sed 's%/[^/]*$%%'` + if test "$file" = "$dir"; then + file="$objdir/$file" + else + file="$dir/$objdir/`echo "$file" | sed 's%^.*/%%'`" + fi + fi + fi + + $show "$install_prog$stripme $file $dest" + $run $install_prog$stripme $file $dest || exit $? + ;; + esac + done + + # Install any profiled libraries, too. + newfiles= + for file in $staticlibs; do + newfiles="$newfiles $file" + pfile=`echo "$file" | sed 's/\.a$/_p.a/'` + test -f "$pfile" && newfiles="$newfiles $pfile" + done + staticlibs="$newfiles" + + for file in $staticlibs; do + name=`echo "$file" | sed 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + # FIXME support stripping libraries + if test -n "$stripme"; then + echo "$progname: will not strip libraries (yet)" 1>&2 + fi + + $show "$install_prog $file $oldlib" + $run $install_prog $file $oldlib || exit $? + + # Do each command in the postinstall commands. + cmds=`eval echo \"$old_postinstall_cmds\"` + IFS=${IFS= }; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run $cmd || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + echo "$progname: warning: remember to run \`$progname --finish$future_libdirs'" + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs="-n $current_libdirs" + exec $0 --finish$current_libdirs + exit 1 + fi + + exit 0 + ;; + + # libtool finish mode + finish) + libdirs="$nonopt" + + if test -n "$finish_cmds" && test -n "$libdirs"; then + for dir; do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + # Do each command in the postinstall commands. + cmds=`eval echo \"$finish_cmds\"` + IFS=${IFS= }; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run $cmd + done + IFS="$save_ifs" + done + fi + + echo "To link against installed libraries in LIBDIR, users may have to:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to their \`$shlibpath_var' environment variable" + fi + echo " - use the \`-LLIBDIR' linker flag" + exit 0 + ;; + + # libtool uninstall mode + uninstall) + rm="$nonopt" + files= + + for arg + do + case "$arg" in + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + echo "$progname: you must specify an RM program" 1>&2 + echo "$help" 1>&2 + exit 1 + fi + + for file in $files; do + dir=`echo "$file" | sed -e 's%/[^/]*$%%'` + test "$dir" = "$file" && dir=. + name=`echo "$file" | sed -e 's%^.*/%%'` + + case "$name" in + lib*.la) + # Possibly a libtool archive, so verify it. + if egrep "^# Generated by $PROGRAM" $file >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + $show "$rm $dir/$n" + $run $rm $dir/$n + done + + # Delete the old-fashioned archive. + if test -n "$old_library"; then + $show "$rm $dir/$old_library" + $run $rm $dir/$old_library + fi + fi + ;; + esac + + $show "$rm $file" + $run $rm $file + done + exit 0 + ;; + + NONE) + echo "$progname: you must specify a MODE" 1>&2 + echo "$help" 1>&2 + exit 1 + ;; + esac + + echo "$progname: invalid operation mode \`$mode'" 1>&2 + echo "$help" 1>&2 + exit 1 +fi # test -z "$show_help" + +# We need to display help for each of the modes. +case "$mode" in +NONE) cat <&2 + echo "$help" 1>&2 + exit 1 + ;; +esac + +case "$mode" in +archive|compile) + echo + echo "Try \`$progname --help' for more information about other modes." + ;; +esac + +exit 0 + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/tests/ChangeLog b/tests/ChangeLog new file mode 100644 index 000000000..d01ba479d --- /dev/null +++ b/tests/ChangeLog @@ -0,0 +1,8 @@ +Mon Dec 2 16:31:10 1996 Gordon Matzigkeit + + * demo.test: Try compiling the ../demo subdirectory, with no + special options. + + * test-e.test: Check that we haven't used `test -e' anywhere in + our portable shell scripts. + diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 000000000..85d5d0b20 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,7 @@ +## Process this file with automake to create Makefile.in + +AUTOMAKE_OPTIONS = gnits + +TESTS = demo.test test-e.test + +EXTRA_DIST = defs $(TESTS)