2 # This purports to allow distributions to be built with shared libraries.
4 # I wrote it for Kpathsea and friends, but I don't think there's
5 # anything TeX-specific in here.
7 # There is a much fancier libtool project underway by
8 # <gord@enci.ucalgary.ca>, but I did not want to wait for that to be
9 # completed, stable, and portable before releasing Web2c. The ideas are
10 # based on Gord's Libtool, though, and you may find its documentation
11 # interesting/useful reading.
13 # Porting this to other systems shouldn't be too hard, mostly because I
14 # don't try to take advantage of all the fancy features offered by some
15 # os's (like multiple version compatibility, encoding directory paths in
16 # the binary, etc.) See the configure mode. I can send you the
17 # hello,world Makefile I used for testing if you want it.
19 rcs_version='$Id: klibtool,v 1.11 2002/11/11 09:43:05 olaf Exp $'
21 maint=tex-k@mail.tug.org
22 help="Usage: $0 [OPTION]... MODE [ARG]...
23 Help for building and linking with shared libraries.
25 Modes: Environment variables used:
26 configure [HOSTTYPE] RANLIB, LIBTOOL_OBJTYPES
27 compile CC SOURCEFILE ARG...
28 archive AR ARFLAGS LIBNAME ARG...
30 install-lib DIR LIBNAME... INSTALL_DATA
31 install-prog DIR PROGNAME... INSTALL_PROGRAM
46 bug_report="$0: Please report this bug to $maint.
47 Please mention this is Klibtool version $version ($rcs_version),
48 and your hardware/operating system (`uname -a`, at least).
50 Running this same command ($0 $*) with --verbose and including the
51 resulting output would be nice, but is not required."
59 # Yes, this option parsing is imperfect, e.g., -xcruddy will be
60 # recognized as --config-dir. I don't think it's worth the trouble to
61 # program correctly until somebody besides me uses this.
62 while test $# -gt 0; do
64 configure|compile|archive|link|install-lib|install-prog|version)
66 --source-dir) # --source-dir
67 shift; source_dir=$1;;
69 shift; config_dir=$1;;
70 -n|-*d*) # -n, --dry-run
73 echo "$help"; exit 0;;
74 -*q|-*s) # --quiet, --silent
76 -v|-*verb*) # --verbose
78 -*version) # --version
79 echo "$0 version $version ($rcs_version)"; exit 0;;
81 echo "$0: Unknown option \`$1'. Try --help for info." >&2; exit 1;;
83 echo "$0: Unknown mode \`$1'. Try --help for info." >&2; exit 1;;
88 # Read all the arguments. Peel off the mode.
92 # Read the configuration file unless we're configuring.
94 if test $mode != configure; then
95 # Read configuration file. If we have it in the current directory, or
96 # the user told us where it is, great. More likely, though, it's only
97 # in the directory with the library that we're eventually going to
98 # link with. We have no way of knowing what that is, so let's use the
99 # location of this script itself as the default if not in `.', `..',
101 test -z "$config_dir" && config_dir=$KLIBTOOL_CONFIG_DIR
102 if test -z "$config_dir"; then
103 if test -r ./klibtool.config; then
105 elif test -r ../klibtool.config; then
107 elif test -r ../../klibtool.config; then
110 dir=`echo $0 | sed 's,/[^/]*$,,'`
111 test -r $dir/klibtool.config && config_dir=$dir
114 if test -z "$config_dir"; then
115 echo "$0: Cannot find klibtool.config in . or .. or $dir," >&2
116 echo "$0: and no --config-dir option specified" >&2
117 echo "$0: or KLIBTOOL_CONFIG_DIR environment variable set." >&2
121 . $config_dir/klibtool.config
123 if test -z "$LIBTOOL_OBJTYPES"; then
124 echo "$0: Impossibly empty LIBTOOL_OBJTYPES!" >&2
125 echo "$bug_report" >&2
128 # Copy the valid object type names from LIBTOOL_OBJTYPES into objtypes.
129 $verbose "$0: checking LIBTOOL_OBJTYPES = $LIBTOOL_OBJTYPES."
131 for ot in `echo $LIBTOOL_OBJTYPES | tr : " "`; do
134 if $shared_support; then
135 objtypes=$objtypes:$ot
137 echo "$0: Shared libraries not supported on this system." >&2
141 objtypes=$objtypes:$ot;;
142 "") true;; # don't worry about empty object types.
144 echo "$0: Ignoring unknown libtool object type $objtype." >&2;;
147 # Remove the extra trailing colon from our list-building.
148 objtypes=`echo $objtypes | sed 's/^://'`
149 if test -z $objtypes; then
150 # If they just took the default, we started with STATIC and so
152 echo "$0: No valid object types in $LIBTOOL_OBJTYPES, quitting." >&2
155 $verbose "$0: final objtypes = $objtypes."
162 # I wish we had subroutines so we could make this readable, but shell
163 # functions aren't portable enough, even nowadays.
165 $verbose "$0: mode = $mode."
169 #
\f configure mode: [HOSTTYPE]
171 # If no config dir specified, use the script location.
172 if test -z "$config_dir"; then
173 if echo $0 | grep / >/dev/null; then
174 config_dir=`echo $0 | sed 's,/[^/]*$,,'`
176 config_dir=. # $0 is just the script name, no directory part.
179 if test -z "$source_dir"; then
180 source_dir=$config_dir
182 config_file=$config_dir/klibtool.config
183 config_tmp=$config_dir/klt$$.tmp
184 $verbose "$0: writing to config_file = $config_file."
186 # If no specified HOSTTYPE, guess it.
187 if test $# -eq 0; then
188 config_guess=$source_dir/config.guess
189 if test ! -r $config_guess; then
190 echo "$0: config.guess not in $source_dir." >&2
191 echo "$0: Either specify a host type or get the scripts." >&2
194 host_alias=`$config_guess`
197 || echo "$0: Using $1 as host alias, ignoring other arguments ($*)." >&2
201 # Convert the original host type to canonical form.
202 config_sub=$source_dir/config.sub
203 if test ! -r $config_sub; then
204 echo "$0: config.sub missing from $source_dir; it's required." >&2
207 host_type=`$config_sub $host_alias`
208 if test -z "$host_type"; then
209 echo "$0: $host_alias not a recognizable host type." >&2
213 # Define defaults, to be overridden in the system-specific cases.
214 config_vars="LIBTOOL_OBJTYPES shared_support shared_ext libpath_var CC
215 args_STATIC_compile args_SHARED_compile
216 args_STATIC_archive STATIC_ranlib args_SHARED_archive
219 for v in $config_vars; do
220 # Preserve existing value of a couple variables.
222 LIBTOOL_OBJTYPES|CC) true;;
226 test -z "$LIBTOOL_OBJTYPES" && LIBTOOL_OBJTYPES=STATIC
228 libpath_var=LD_LIBRARY_PATH
229 STATIC_ranlib=$RANLIB
231 # The compiler. If the user set CC, take that, else use gcc if we
232 # can find it, else use cc. Up to the user to avoid /usr/ucb/cc.
233 if test -z "$CC"; then
234 for dir in `echo $PATH | tr : ' '`; do
235 test -z "$dir" && dir=.
236 if test -f $dir/gcc; then
239 elif test -f $dir/gcc.exe; then
245 test -z "$CC" && CC=cc
247 # But the real question is not the name of the command, it's whether
248 # it is GNU C. We only distinguish gcc and system cc. We have to
249 # assume that they use the same compiler at `klibtool compile' time
250 # as we determine here; the whole point is that we don't want to do
251 # this check before compiling every file (for speed).
254 echo "#ifdef __GNUC__"
258 if eval "$CC -E conftest.c" | grep yes >/dev/null 2>&1; then
260 args_SHARED_compile=-fPIC # should we have an option for -fpic?
261 args_SHARED_archive=-shared
267 # Override defaults for this system.
271 SHARED_postinstall='ldconfig $libdir'
276 if test $compiler = cc; then # /opt/SUNWspro/cc, that is.
277 args_SHARED_compile=-KPIC
278 args_SHARED_archive="-G -z text" # Perhaps should have -h.
284 if test $compiler = cc; then # /opt/ccs/bin/cc, that is.
285 args_SHARED_compile=-KPIC
286 args_SHARED_archive="-G -z text"
293 SHARED_postinstall='ldconfig $libdir'
294 if test $compiler = cc; then
295 args_SHARED_compile=-PIC
296 prog_SHARED_archive=ld
297 args_SHARED_archive="-assert pure-text" # gord has -Bstatic?
301 *-*-irix5*|*-*-irix6*)
306 *-*-*djgpp* | *-*-*go32* | *-*-msdos*)
308 libpath_var=LIBRARY_PATH
313 SHARED_postinstall='ldconfig -m $libdir'
317 if test $compiler = gcc; then
319 args_SHARED_archive='-shared -fPIC'
325 STATIC_postinstall='$STATIC_ranlib $libdir/$lib_basename'
329 echo "$0: $host_type not explicitly supported, using defaults." >&2
333 # Finally, we'll be creating something.
337 for v in $config_vars; do
338 config_line=$v=\'`eval echo '$'$v`\'
339 $verbose "$0: writing config line $config_line."
340 echo $config_line >>$config_tmp
343 # Check if this changed anything.
344 if cmp -s $config_file $config_tmp 2>/dev/null; then
345 $verbose "$0: $config_file is unchanged"
349 mv $config_tmp $config_file
354 #
\f compile mode: CC SOURCEFILE [ARG]...
356 compiler=$1; shift # must assume it's what configure found
358 objname=`basename $sourcefile | sed 's/\.[^./]*$//'`.o
359 $verbose "$0: object basename for source file $sourcefile = $objname."
361 for ot in `echo $objtypes | tr : " "`; do
362 # Snarf arguments for this object type.
363 ot_args=`eval echo '$'args_${ot}_${mode}`
364 $verbose "$0: args_${ot}_${mode} = $ot_args."
366 # Have to output into a subdirectory of current directory (not
367 # source directory, which might be read-only).
368 output_arg="-o $ot/$objname"
369 if test ! -d $ot; then
374 # Construct and run the cmd.
375 cmd="$compiler ""$@"" $ot_args $output_arg"
379 test $status -eq 0 || break
380 done # end of objtypes loop for compile mode
381 test $status -eq 0 && date >./"`echo $objname | sed 's/o$/lo/'`"
388 cmdname=$1; shift # the archiver
389 for ot in `echo $objtypes | tr : " "`; do
392 if test $ot = SHARED; then
393 # Can't generally use ar to make a shared library.
396 ot_args=`eval echo '$'args_SHARED_archive`
397 ot_prog=`eval echo '$'prog_SHARED_archive`
398 test -z "$ot_prog" && ot_prog=$CC
399 cmdname="$ot_prog $ot_args -o"
400 $verbose "$0: replaced $old_ar with $cmdname."
403 # Now transform remaining arguments (presumably filenames).
406 *.l[ao]) # Remove the `l' from a .la or .lo filename.
407 newarg=`echo $arg | sed 's/l\(.\)$/\1/'`
408 $verbose "$0: transformed arg $arg to $newarg."
409 # First .la file is the output library.
410 if test -z "$libname" && echo $newarg | grep '\.a$'>/dev/null; then
411 if test $ot = SHARED; then
412 $verbose "$0: running $0 version $newarg."
413 verstring=`$0 version $newarg`
414 $verbose "$0: got version $verstring."
415 libname=`echo $newarg | sed 's/\.a$/\.'$shared_ext$verstring/`
419 if echo $libname | grep / >/dev/null; then
420 lib_dir=`echo $libname | sed 's,/[^/]*$,,'`
424 lib_basename=`basename $libname`
425 lib_base=`echo $lib_basename | sed 's/[.0-9]*$//'`
427 # We might have to run a command after making the library.
429 if test $ot = SHARED; then
430 # If it supports shared libraries, it supports symlinks.
431 # Although this is unnecessary on (e.g.) SunOS, it
432 # doesn't hurt, and it is necessary on (e.g.) Solaris.
433 post="&& rm -f $lib_base && ln -s $lib_basename $lib_base"
434 elif test $ot = STATIC; then
435 ranlib=`eval echo '$'${ot}_ranlib`
436 $verbose "${ot}_ranlib = $ranlib."
437 test -n "$ranlib" && post="&& $ranlib $lib_basename"
440 $verbose "$0: output library dir = $lib_dir."
441 $verbose "$0: output library basename = $lib_basename."
442 $verbose "$0: output library base = $lib_base."
450 if test -z "$libname"; then
451 # FIXME: should check that the .la file was second arg.
452 echo "$0 archive: .la (libtool archive) argument missing." >&2
456 # Remove old archive file because we recommend `ar q', not `r',
457 # and the user can't necessarily know the library name. We remove
458 # both $lib_base and $lib_base* because on MS-DOS the latter may not
460 cmd="cd $lib_dir/$ot && rm -f $lib_base $lib_base* && $cmdname $args $post"
462 $chicken eval "($cmd)"
464 test $status -eq 0 || break
466 # If making both objtypes, need original arguments next time through.
467 if test $ot = SHARED; then
470 true # Don't think we failed to make the library just because
471 # the last objtype was not SHARED.
473 done # end of objtypes loop for archive mode
475 # Create the .la file we claimed that we would.
476 test $status -eq 0 && date >./"`echo $libname | sed 's/\.[^/]*$/.la/'`"
483 cmdname=$1; shift # the linker
484 # Do links using the first object type.
485 linktype=`echo $objtypes | sed 's/:.*//'`
486 $verbose "$0: linktype = $linktype."
487 if test -z "$linktype"; then
488 echo "$0: Impossibly empty linktype?!" >&2
492 # Need to know the output name if we generate the wrapper.
493 looking_for_output=false
498 if $looking_for_output; then
499 real_output_name=$arg
500 arg=$real_output_name.exe
501 looking_for_output=false
505 test $linktype = SHARED && looking_for_output=true
507 *.l[ao]) # Find .la files in the linktype subdir
508 # of the given directory, e.g., if the user says
509 # ../foo/libfoo.la, transform into
510 # ../foo/$linktype/libfoo.{a,so...}. We do the same for
511 # libtool archive, although it's not as often necessary.
512 newarg=`echo $arg | sed -e 's,\([^/]*\)$,'$linktype'/\1,' \
514 if test $linktype = SHARED \
515 && echo $newarg | grep '\.a$' >/dev/null; then
516 # If shared, transform dir/foo.la into -Ldir -lfoo.
517 dir=`echo $newarg | sed 's,/[^/]*$,,'`
518 lib=`echo $newarg | sed -e 's,.*/\([^/]*\),\1,' \
519 -e 's/^lib//' -e 's/\.a$//'`
520 newarg="-L$dir -l$lib"
521 # Remember we will need this directory in LD_LIBRARY_PATH.
522 if echo $dir | grep -v '^/' >/dev/null; then
525 # Maybe had previous directories.
526 test -n "$libpath" && libpath=$libpath:
529 $verbose "$0: transformed .la arg $arg to $newarg."
532 *.lo) # .lo files have no directory stripping or suffix changing.
533 newarg=`echo $arg | sed -e 's,\([^/]*\)$,'$linktype'/\1,' \
535 $verbose "$0: transformed .lo arg $arg to $newarg."
542 # Set up to generate wrapper shell script if shared.
543 if test $linktype = SHARED; then
544 if $looking_for_output; then
545 echo "$0 link: -o requires an argument." >&2
548 if test -z "$real_output_name"; then
549 # If they didn't give -o at all, default to a.out.
550 real_output_name=a.out
551 args="$args -o $real_output_name.exe"
561 if test $status -eq 0 && test -n "$real_output_name"; then
562 $verbose "$0: creating wrapper $real_output_name."
563 # We created the binary, so create the wrapper script.
564 # Use as short a temporary suffix as we can to minimize the chance
565 # of collisions on deficient systems.
566 rm -f ${real_output_name} ${real_output_name}T
568 libpath_var_val='$'$libpath_var
570 echo "# Generated `date` by $0."
571 echo "# Do not install this wrapper script."
572 echo "# It's only here to enable running $real_output_name"
573 echo "# before it's installed. (Use $0 install-progs to install it.)"
575 echo "if test -z \"$libpath_var_val\"; then"
576 echo " $libpath_var=\"$libpath\""
578 echo " $libpath_var=\"$libpath:$libpath_var_val\""
580 echo "export $libpath_var"
582 echo "thisdir=\`echo $""0 | sed 's%/[^/]*$%%'\`"
583 echo 'test "x$thisdir" = "x$0" && thisdir=.'
585 echo "exec \$thisdir/$real_output_name.exe \"\$@\""
586 ) >${real_output_name}T
587 chmod +x ${real_output_name}T
588 mv ${real_output_name}T ${real_output_name}
594 #
\f install-lib mode: DIR LIBNAME...
596 if test $# -lt 2; then
597 echo "$0 install-lib: Need directory and at least one library." >&2
601 if test ! -d $libdir; then
602 echo "$0 install-lib: $1 not a directory." >&2
605 for arg in "$@"; do # for each library...
606 # Always having a directory part simplifies the code below.
607 echo $arg | grep / >/dev/null || arg="./$arg"
608 for ot in `echo $objtypes | tr : " "`; do # for each object type...
610 SHARED) # needs shared extension and version number.
611 verstring=`$0 version $arg`
612 libname=`echo $arg | sed 's/\.la$/\.'$shared_ext$verstring/`
614 STATIC) # just get rid of the `l'.
615 libname=`echo $arg | sed 's/l\(.\)$/\1/'`
618 echo "$0: Impossible object type $ot!" >&2
619 echo "$bug_report" >&2
622 # Have to insert the object type directory.
623 libname=`echo $libname | sed 's,\(/[^/]*\)$,/'$ot'\1,'`
624 lib_basename=`basename $libname`
625 $verbose "$0: library name = $libname."
626 $verbose "$0: installation name = $libdir/$lib_basename."
627 cmd="${INSTALL_DATA-cp} $libname $libdir/$lib_basename"
629 if test $ot = SHARED; then
630 # Link libfoo.so to libfoo.so.1.2.3.
631 lib_base=`echo $lib_basename | sed 's/[.0-9]*$//'`
632 $verbose "$0: linking $libdir/$lib_base to $lib_basename"
633 (cd $libdir && rm -f $lib_base && ln -s $lib_basename $lib_base)
637 postinstall=`eval echo '$'${ot}_postinstall`
638 test -n "$postinstall" && cmd="$cmd && $postinstall"
646 #
\f install-prog mode: DIR PROGNAME...
648 if test $# -lt 2; then
649 echo "$0 install-prog: Need directory and at least one program." >&2
653 if test ! -d $dir; then
654 echo "$0 install-prog: $1 not a directory." >&2
657 # The program got linked using the first object type, so
658 # installation of the program will proceed accordingly.
659 linktype=`echo $objtypes | sed 's/:.*//'`
660 $verbose "$0: linktype = $linktype."
661 if test -z "$linktype"; then
662 echo "$0: Impossibly empty linktype?!" >&2
665 if test $linktype = SHARED; then
666 # Install the binary, not the wrapper script.
671 for arg in "$@"; do # for each program...
672 # FIXME: On SunOS, AIX, and HP-UX, relink to avoid hardwired libdirs.
673 cmd="${INSTALL_PROGRAM-cp} $arg$suffix $dir/$arg"
682 if test $# -ne 1; then
683 echo "$0 version: Exactly one argument needed, not $# ($*)." >&2
686 # Strip directory name, `lib' prefix, and any .suffix.
687 dir=`echo $1 | sed 's,/[^/]*$,,'`
688 test "x$dir" = "x$1" && dir=.
689 libname=`basename $1 | sed -e 's,^lib,,' -e s',\..*$,,'`
690 verfile=$dir/klibtool.version
691 if test ! -r $verfile; then
692 echo "$0 version: No file $verfile for $libname version info." >&2
693 echo "$0 version: Original argument was $1." >&2
696 $verbose "$0: dir = $dir, libname = $libname."
697 version=`awk '$1 == "'$libname'" { print "." $2 "." $3 "." $4 }' $verfile`
698 $verbose "$0: version for $libname = $version."
705 echo "$0: Impossible mode \`$mode'!" >&2
706 echo "$bug_report" >&2