diff kpathsea/klibtool @ 3000:86d3a6fc4c84

[project @ 1997-05-23 03:09:13 by jwe]
author jwe
date Fri, 23 May 1997 03:10:11 +0000
parents
children 1f0b06020e36
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kpathsea/klibtool	Fri May 23 03:10:11 1997 +0000
@@ -0,0 +1,645 @@
+#!/bin/sh
+# This purports to allow distributions to be built with shared libraries.
+# 
+# I wrote it for Kpathsea and friends, but I don't think there's
+# anything TeX-specific in here.
+# 
+# There is a much fancier libtool project underway by
+# <gord@enci.ucalgary.ca>, but I did not want to wait for that to be
+# completed, stable, and portable before releasing Web2c.  The ideas are
+# based on Gord's Libtool, though, and you may find its documentation
+# interesting/useful reading.
+# 
+# Porting this to other systems shouldn't be too hard, mostly because I
+# don't try to take advantage of all the fancy features offered by some
+# os's (like multiple version compatibility, encoding directory paths in
+# the binary, etc.)  See the configure mode.  I can send you the
+# hello,world Makefile I used for testing if you want it.
+# 
+rcs_version='$Id: klibtool,v 1.1 1997-05-23 03:09:13 jwe Exp $'
+version=0.1
+maint=tex-k@mail.tug.org
+help="Usage: $0 [OPTION]... MODE [ARG]...
+Help for building and linking with shared libraries.
+
+Modes:                                 Environment variables used:
+configure [HOSTTYPE]		       RANLIB, LIBTOOL_OBJTYPES
+compile CC SOURCEFILE ARG...
+archive AR ARFLAGS LIBNAME ARG...
+link CC ARG...
+install-lib DIR LIBNAME...             INSTALL_DATA
+install-prog DIR PROGNAME...           INSTALL_PROGRAM
+version
+
+Options:
+    --config-dir DIR
+-n, --dry-run
+    --help
+    --quiet, --silent
+-v, --verbose
+    --version
+
+Email bugs to $maint.
+"
+
+bug_report="$0: Please report this bug to $maint.
+Please mention this is Klibtool version $version ($rcs_version),
+and your hardware/operating system (`uname -a`, at least).
+
+Running this same command ($0 $*) with --verbose and including the
+resulting output would be nice, but is not required."
+
+verbose=:
+chicken=
+show=echo
+config_dir=
+
+# Yes, this option parsing is imperfect, e.g., -xcruddy will be
+# recognized as --config-dir.  I don't think it's worth the trouble to
+# program correctly until somebody besides me uses this.
+while test $# -gt 0; do
+  case "$1" in
+    configure|compile|archive|link|install-lib|install-prog|version)
+      mode=$1; break;;
+    -*c*)         # --config-dir
+      shift; config_dir=$1;;
+    -n|-*d*)      # -n, --dry-run
+      chicken=echo;;
+    -*help)       # --help
+      echo "$help"; exit 0;;
+    -*q|-*s)      # --quiet, --silent
+      show=:; verbose=:;;
+    -v|-*verb*)   # --verbose
+      verbose=echo;;
+    -*version)    # --version
+      echo "$0 version $version ($rcs_version)"; exit 0;;
+    -*)
+      echo "$0: Unknown option \`$1'. Try --help for info." >&2; exit 1;;
+    *)
+      echo "$0: Unknown mode \`$1'. Try --help for info." >&2; exit 1;;
+  esac
+  shift
+done
+
+# Read all the arguments.  Peel off the mode.
+shift
+
+# 
+# Read the configuration file unless we're configuring.
+# 
+if test $mode != configure; then
+  # Read configuration file.  If we have it in the current directory, or
+  # the user told us where it is, great.  More likely, though, it's only
+  # in the directory with the library that we're eventually going to
+  # link with.  We have no way of knowing what that is, so let's use the
+  # location of this script itself as the default.
+  if test -z "$config_dir"; then
+    if test -r ./klibtool.config; then
+      config_dir=.
+    else
+      dir=`echo $0 | sed 's,/[^/]*$,,'`
+      test -r $dir/klibtool.config && config_dir=$dir
+    fi
+  fi
+  if test -z "$config_dir"; then
+    echo "$0: Cannot find klibtool.config in . or $dir," >&2
+    echo "$0: and no --config-dir option specified." >&2
+    exit 1
+  fi
+  # Read the file.
+  . $config_dir/klibtool.config
+
+  if test -z "$LIBTOOL_OBJTYPES"; then
+    echo "$0: Impossibly empty LIBTOOL_OBJTYPES!" >&2
+    echo "$bug_report" >&2
+    exit 1
+  fi
+  # Copy the valid object type names from LIBTOOL_OBJTYPES into objtypes.
+  $verbose "$0: checking LIBTOOL_OBJTYPES = $LIBTOOL_OBJTYPES."
+  objtypes=
+  for ot in `echo $LIBTOOL_OBJTYPES | tr : " "`; do
+    case $ot in
+      SHARED)
+        if $shared_support; then 
+          objtypes=$objtypes:$ot
+        else
+          echo "$0: Shared libraries not supported on this system." >&2
+        fi
+        ;;
+      STATIC)
+        objtypes=$objtypes:$ot;;
+      "") true;; # don't worry about empty object types.
+      *)
+        echo "$0: Ignoring unknown libtool object type $objtype." >&2;;
+     esac
+  done
+  # Remove the extra trailing colon from our list-building.
+  objtypes=`echo $objtypes | sed 's/^://'`
+  if test -z $objtypes; then
+    # If they just took the default, we started with STATIC and so
+    # wouldn't be here.
+    echo "$0: No valid object types in $LIBTOOL_OBJTYPES, quitting." >&2
+    exit 1
+  fi
+  $verbose "$0: final objtypes = $objtypes."
+fi
+
+
+# 
+# Do the deed.
+# 
+# I wish we had subroutines so we could make this readable, but shell
+# functions aren't portable enough, even nowadays.
+# 
+$verbose "$0: mode = $mode."
+case $mode in
+
+
+  # configure mode: [HOSTTYPE]
+  configure)
+    # If no config dir specified, use the script location.
+    if test -z "$config_dir"; then
+      if echo $0 | grep / >/dev/null; then
+        config_dir=`echo $0 | sed 's,/[^/]*$,,'`
+      else
+        config_dir=.  # $0 is just the script name, no directory part.
+      fi
+    fi
+    config_file=$config_dir/klibtool.config
+    $verbose "$0: writing to config_file = $config_file."
+    
+    # If no specified HOSTTYPE, guess it.
+    if test $# -eq 0; then
+      config_guess=$config_dir/config.guess
+      if test ! -r $config_guess; then
+        echo "$0: config.guess not in $config_dir." >&2
+        echo "$0: Either specify a host type or get the scripts." >&2
+        exit 1
+      fi
+      host_alias=`$config_guess`
+    else
+      test $# -eq 1 \
+       || echo "$0: Using $1 as host alias, ignoring other arguments ($*)." >&2
+      host_alias=$1
+    fi
+    
+    # Convert the original host type to canonical form.
+    config_sub=$config_dir/config.sub
+    if test ! -r $config_sub; then
+      echo "$0: config.sub missing from $config_dir; it's required." >&2
+      exit 1
+    fi
+    host_type=`$config_sub $host_alias`
+    if test -z "$host_type"; then
+      echo "$0: $host_alias not a recognizable host type." >&2
+      exit 1
+    fi
+    
+    # Finally, we'll be creating something.
+    rm -f $config_file
+    
+    # Define defaults, to be overridden in the system-specific cases.
+    config_vars="LIBTOOL_OBJTYPES shared_support shared_ext libpath_var CC
+      args_STATIC_compile args_SHARED_compile
+      args_STATIC_archive STATIC_ranlib args_SHARED_archive
+      args_SHARED_link
+      SHARED_postinstall"
+    for v in $config_vars; do
+      # Preserve existing value of a couple variables.
+      case $v in
+        LIBTOOL_OBJTYPES|CC) true;;
+        *) eval $v=;;
+      esac
+    done
+    test -z "$LIBTOOL_OBJTYPES" && LIBTOOL_OBJTYPES=STATIC
+    shared_ext=so
+    libpath_var=LD_LIBRARY_PATH
+    STATIC_ranlib=$RANLIB
+
+    # The compiler.  If the user set CC, take that, else use gcc if we
+    # can find it, else use cc.  Up to the user to avoid /usr/ucb/cc.
+    if test -z "$CC"; then
+      for dir in `echo $PATH | tr : ' '`; do
+        test -z "$dir" && dir=.
+        if test -f $dir/gcc; then
+          CC=gcc
+          break
+        fi
+      done
+    fi
+    test -z "$CC" && CC=cc
+    #
+    # But the real question is not the name of the command, it's whether
+    # it is GNU C.  We only distinguish gcc and system cc.  We have to
+    # assume that they use the same compiler at `klibtool compile' time
+    # as we determine here; the whole point is that we don't want to do
+    # this check before compiling every file (for speed).
+    rm -f conftest.c
+    (
+      echo "#ifdef __GNUC__"
+      echo "yes;"
+      echo "#endif"
+    ) >conftest.c
+    if eval "$CC -E conftest.c" | grep yes >/dev/null 2>&1; then
+      compiler=gcc
+      args_SHARED_compile=-fPIC # should we have an option for -fpic?
+      args_SHARED_archive=-shared
+    else
+      compiler=cc
+    fi
+    rm -f conftest.c
+
+    # Override defaults for this system.
+    case $host_type in
+      *-*-linux*)
+        shared_support=true
+        SHARED_postinstall='ldconfig $libdir'
+        ;;
+        
+      *-*-solaris2*)
+        shared_support=true
+        if test $compiler = cc; then # /opt/SUNWspro/cc, that is.
+          args_SHARED_compile=-KPIC
+          args_SHARED_archive="-G -z text" # Perhaps should have -h.
+        fi
+        ;;
+
+      *-*-sunos4*)
+        shared_support=true
+        STATIC_ranlib=ranlib
+        SHARED_postinstall='ldconfig $libdir'
+        if test $compiler = cc; then
+          args_SHARED_compile=-PIC
+          prog_SHARED_archive=ld
+          args_SHARED_archive="-assert pure-text"    # gord has -Bstatic?
+        fi
+        ;;
+
+      *)
+        echo "$0: $host_type not explicitly supported, using defaults." >&2
+        ;;
+    esac
+
+    # Output values.  
+    for v in $config_vars; do
+      config_line=$v=\'`eval echo '$'$v`\'
+      $verbose "$0: writing config line $config_line."
+      echo $config_line >>$config_file
+    done
+    ;;
+
+
+  # compile mode: CC SOURCEFILE [ARG]...
+  compile)
+    compiler=$1; shift   # must assume it's what configure found
+    sourcefile=$1
+    objname=`basename $sourcefile | sed 's/\.[^./]*$//'`.o
+    $verbose "$0: object basename for source file $sourcefile = $objname."
+    #
+    for ot in `echo $objtypes | tr : " "`; do
+      # Snarf arguments for this object type.
+      ot_args=`eval echo '$'args_${ot}_${mode}`
+      $verbose "$0: args_${ot}_${mode} = $ot_args."
+      
+      # Have to output into a subdirectory of current directory (not
+      # source directory, which might be read-only).
+      output_arg="-o $ot/$objname"
+      if test ! -d $ot; then
+        $show mkdir $ot
+        $chicken mkdir $ot
+      fi
+      
+      # Construct and run the cmd.
+      cmd="$compiler ""$@"" $ot_args $output_arg"
+      $show $cmd
+      $chicken $cmd
+      status=$?
+      test $status -eq 0 || break
+    done # end of objtypes loop for compile mode
+    test $status -eq 0 && date >./"`echo $objname | sed 's/o$/lo/'`"
+    exit $status
+    ;;
+
+
+  # archive mode
+  archive)
+    cmdname=$1; shift             # the archiver
+    for ot in `echo $objtypes | tr : " "`; do
+      libname=
+      args=
+      if test $ot = SHARED; then
+        # Can't generally use ar to make a shared library.
+        old_ar="$cmdname $1"
+        shift
+        ot_args=`eval echo '$'args_SHARED_archive`
+        ot_prog=`eval echo '$'prog_SHARED_archive`
+        test -z "$ot_prog" && ot_prog=$CC
+        cmdname="$ot_prog $ot_args -o"
+        $verbose "$0: replaced $old_ar with $cmdname."
+      fi
+      
+      # Now transform remaining arguments (presumably filenames).
+      for arg in "$@"; do
+        case "$arg" in
+          *.l[ao]) # Remove the `l' from a .la or .lo filename.
+            newarg=`echo $arg | sed 's/l\(.\)$/\1/'`
+            $verbose "$0: transformed arg $arg to $newarg."
+            # First .la file is the output library.
+            if test -z "$libname" && echo $newarg | grep '\.a$'>/dev/null; then
+              if test $ot = SHARED; then
+                $verbose "$0: running $0 version $newarg."
+                verstring=`$0 version $newarg`
+                $verbose "$0: got version $verstring."
+                libname=`echo $newarg | sed 's/\.a$/\.'$shared_ext$verstring/`
+              else
+                libname=$newarg
+              fi
+              if echo $libname | grep / >/dev/null; then
+                lib_dir=`echo $libname | sed 's,/[^/]*$,,'`
+              else
+                lib_dir=.
+              fi
+              lib_basename=`basename $libname`
+              lib_base=`echo $lib_basename | sed 's/[.0-9]*$//'`
+              
+              # We might have to run a command after making the library.
+              post=
+              if test $ot = SHARED; then
+                # If it supports shared libraries, it supports symlinks.
+                # Although this is unnecessary on (e.g.) SunOS, it
+                # doesn't hurt, and it is necessary on (e.g.) Solaris.
+                post="&& ln -s $lib_basename $lib_base"
+              elif test $ot = STATIC; then
+                ranlib=`eval echo '$'${ot}_ranlib`
+                $verbose "${ot}_ranlib = $ranlib."
+                test -n "$ranlib" && post="&& $ranlib $lib_basename"
+              fi
+
+              $verbose "$0: output library dir = $lib_dir."
+              $verbose "$0: output library basename = $lib_basename."
+              $verbose "$0: output library base = $lib_base."
+              newarg=$lib_basename
+            fi
+            arg=$newarg
+            ;;
+        esac
+        args="$args $arg"
+      done
+      if test -z "$libname"; then
+        # FIXME: should check that the .la file was second arg.
+        echo "$0 archive: .la (libtool archive) argument missing." >&2
+        exit 1
+      fi
+      
+      # Remove old archive file because we recommend `ar q', not `r',
+      # and the user can't necessarily know the library name.
+      cmd="cd $lib_dir/$ot && rm -f $lib_base* && $cmdname $args $post"
+      $show $cmd
+      $chicken eval "($cmd)"
+      status=$?
+      test $status -eq 0 || break
+      
+      # If making both objtypes, need original arguments next time through.
+      if test $ot = SHARED; then
+        cmdname=$old_ar
+      else
+        true # Don't think we failed to make the library just because
+             # the last objtype was not SHARED.
+      fi
+    done # end of objtypes loop for archive mode
+    #
+    # Create the .la file we claimed that we would.
+    test $status -eq 0 && date >./"`echo $libname | sed 's/\.[^/]*$/.la/'`"
+    exit $status
+    ;;
+
+
+  # link mode
+  link)
+    cmdname=$1; shift             # the linker
+    # Do links using the first object type.
+    linktype=`echo $objtypes | sed 's/:.*//'`
+    $verbose "$0: linktype = $linktype."
+    if test -z "$linktype"; then
+      echo "$0: Impossibly empty linktype?!" >&2
+      exit 1
+    fi
+    #
+    # Need to know the output name if we generate the wrapper.
+    looking_for_output=false
+    real_output_name=
+    libpath=
+    #
+    for arg in "$@"; do
+      if $looking_for_output; then
+        real_output_name=$arg
+        arg=$real_output_name.exe
+        looking_for_output=false
+      fi
+      case "$arg" in
+        -o)
+          test $linktype = SHARED && looking_for_output=true
+          ;;
+        *.l[ao]) # Find .la files in the linktype subdir
+                 # of the given directory, e.g., if the user says
+                 # ../foo/libfoo.la, transform into
+                 # ../foo/$linktype/libfoo.{a,so...}.  We do the same for
+                 # libtool archive, although it's not as often necessary.
+          newarg=`echo $arg | sed -e 's,\([^/]*\)$,'$linktype'/\1,' \
+                                  -e 's/l\(.\)$/\1/'`
+          if test $linktype = SHARED \
+             && echo $newarg | grep '\.a$' >/dev/null; then
+            # If shared, transform dir/foo.la into -Ldir -lfoo.
+            dir=`echo $newarg | sed 's,/[^/]*$,,'`
+            lib=`echo $newarg | sed -e 's,.*/\([^/]*\),\1,' \
+                                    -e 's/^lib//' -e 's/\.a$//'`
+            newarg="-L$dir -l$lib"
+            # Remember we will need this directory in LD_LIBRARY_PATH.
+            if echo $dir | grep -v '^/' >/dev/null; then
+              dir=`pwd`/$dir
+            fi
+            # Maybe had previous directories.
+            test -n "$libpath" && libpath=$libpath:
+            libpath=$libpath$dir
+          fi
+          $verbose "$0: transformed .la arg $arg to $newarg."
+          arg=$newarg
+          ;;
+        *.lo) # .lo files have no directory stripping or suffix changing.
+          newarg=`echo $arg | sed -e 's,\([^/]*\)$,'$linktype'/\1,' \
+                                  -e 's/l\(.\)$/\1/'`
+          $verbose "$0: transformed .lo arg $arg to $newarg."
+          arg=$newarg
+          ;;
+      esac
+      args="$args $arg"
+    done
+    
+    # Set up to generate wrapper shell script if shared.
+    if test $linktype = SHARED; then
+      if $looking_for_output; then
+        echo "$0 link: -o requires an argument." >&2
+        exit 1
+      fi
+      if test -z "$real_output_name"; then
+        # If they didn't give -o at all, default to a.out.
+        real_output_name=a.out
+        args="$args -o $real_output_name.exe"
+      fi
+    fi
+    
+    # Do the link.
+    cmd="$cmdname $args"
+    $show $cmd
+    $chicken $cmd
+    
+    status=$?
+    if test $status -eq 0 && test -n "$real_output_name"; then
+      $verbose "$0: creating wrapper $real_output_name."
+      # We created the binary, so create the wrapper script.
+      # Use as short a temporary suffix as we can to minimize the chance
+      # of collisions on deficient systems.
+      rm -f ${real_output_name} ${real_output_name}T
+      (
+        libpath_var_val='$'$libpath_var
+        echo "#! /bin/sh"
+        echo "# Generated `date` by $0."
+        echo "# Do not install this wrapper script."
+        echo "# It's only here to enable running $real_output_name"
+        echo "# before it's installed.  (Use $0 install-progs to install it.)"
+        echo
+        echo "if test -z \"$libpath_var_val\"; then"
+        echo "  $libpath_var=\"$libpath\""
+        echo "else"
+        echo "  $libpath_var=\"$libpath:$libpath_var_val\""
+        echo "fi"
+        echo "export $libpath_var"
+        echo
+        echo "thisdir=\`echo $""0 | sed 's%/[^/]*$%%'\`"
+        echo 'test "x$thisdir" = "x$0" && thisdir=.'
+        echo
+        echo "exec \$thisdir/$real_output_name.exe \"\$@\""
+      ) >${real_output_name}T
+      chmod +x ${real_output_name}T
+      mv ${real_output_name}T ${real_output_name}
+    fi
+    exit $status
+    ;;
+
+
+  # install-lib mode: DIR LIBNAME...
+  install-lib)
+    if test $# -lt 2; then
+      echo "$0 install-lib: Need directory and at least one library." >&2
+      exit 1
+    fi
+    libdir=$1; shift
+    if test ! -d $libdir; then
+      echo "$0 install-lib: $1 not a directory." >&2
+      exit 1
+    fi
+    for arg in "$@"; do # for each library...
+      # Always having a directory part simplifies the code below.
+      echo $arg | grep / >/dev/null || arg="./$arg"
+      for ot in `echo $objtypes | tr : " "`; do # for each object type...
+        case $ot in
+          SHARED) # needs shared extension and version number.
+            verstring=`$0 version $arg`
+            libname=`echo $arg | sed 's/\.la$/\.'$shared_ext$verstring/`
+            ;;
+          STATIC) # just get rid of the `l'.
+            libname=`echo $arg | sed 's/l\(.\)$/\1/'`
+            ;;
+          *)
+            echo "$0: Impossible object type $ot!" >&2
+            echo "$bug_report" >&2
+            exit 1;;
+        esac
+        # Have to insert the object type directory.
+        libname=`echo $libname | sed 's,\(/[^/]*\)$,/'$ot'\1,'`
+        lib_basename=`basename $libname`
+        $verbose "$0: library name = $libname."
+        $verbose "$0: installation name = $libdir/$lib_basename."
+        cmd="${INSTALL_DATA-cp} $libname $libdir/$lib_basename"
+        #
+        if test $ot = SHARED; then
+          # Link libfoo.so to libfoo.so.1.2.3.
+          lib_base=`echo $lib_basename | sed 's/[.0-9]*$//'`          
+          $verbose "$0: linking $libdir/$lib_base to $lib_basename"
+          (cd $libdir && ln -s $lib_basename $lib_base)
+        fi
+        #
+        # Run ldconfig, etc.
+        postinstall=`eval echo '$'${ot}_postinstall`
+        test -n "$postinstall" && cmd="$cmd && $postinstall"
+        $show $cmd
+        $chicken eval "$cmd"
+      done
+    done
+    ;;
+
+
+  # install-prog mode: DIR PROGNAME...
+  install-prog)
+    if test $# -lt 2; then
+      echo "$0 install-prog: Need directory and at least one program." >&2
+      exit 1
+    fi
+    dir=$1; shift
+    if test ! -d $dir; then
+      echo "$0 install-prog: $1 not a directory." >&2
+      exit 1
+    fi
+    # The program got linked using the first object type, so
+    # installation of the program will proceed accordingly.
+    linktype=`echo $objtypes | sed 's/:.*//'`
+    $verbose "$0: linktype = $linktype."
+    if test -z "$linktype"; then
+      echo "$0: Impossibly empty linktype?!" >&2
+      exit 1
+    fi
+    if test $linktype = SHARED; then
+      # Install the binary, not the wrapper script.
+      suffix=.exe
+    else
+      suffix=
+    fi
+    for arg in "$@"; do # for each program...
+      # FIXME: On SunOS, AIX, and HP-UX, relink to avoid hardwired libdirs.
+      cmd="${INSTALL_PROGRAM-cp} $arg$suffix $dir/$arg"
+      $show $cmd
+      $chicken $cmd
+    done
+    ;;
+
+
+  # version mode
+  version)
+    if test $# -ne 1; then
+      echo "$0 version: Exactly one argument needed, not $# ($*)." >&2
+      exit 1
+    fi
+    # Strip directory name, `lib' prefix, and any .suffix.
+    dir=`echo $1 | sed 's,/[^/]*$,,'`
+    test "x$dir" = "x$1" && dir=.
+    libname=`basename $1 | sed -e 's,^lib,,' -e s',\..*$,,'`
+    verfile=$dir/klibtool.version
+    if test ! -r $verfile; then
+      echo "$0 version: No file $verfile for $libname version info." >&2
+      echo "$0 version: Original argument was $1." >&2
+      exit 1
+    fi
+    $verbose "$0: dir = $dir, libname = $libname."
+    version=`awk '$1 == "'$libname'" { print "." $2 "." $3 "." $4 }' $verfile`
+    $verbose "$0: version for $libname = $version."
+    echo $version
+    ;;
+    
+  
+  # unknown mode
+  *)
+    echo "$0: Impossible mode \`$mode'!" >&2
+    echo "$bug_report" >&2
+    exit 1
+    ;;
+esac