Mercurial > octave
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