#! /bin/sh
#
# Simple script to build shared libraries
#
#
# Load the mpich configuration data
if [ -s ../util/mpichlib.conf ] ; then 
    . ../util/mpichlib.conf
fi
#
kind=""
nolink=0
islocal=0
created_shared=0
Verbose=echo
setecho=0
GetPathSpec="no"
# OtherLibs contains any additional information, such as additional libraries,
# that are needed to create a shared library.  Currently used only for gcc.
OtherLibs=""
for arg in "$@" ; do
    case $arg in
	-lib=*) lib=`echo A$arg | sed -e 's/A-lib=//g'`
	SHLIBS="$SHLIBS $lib"
	;;
	-obj=*) objs=`echo A$arg | sed -e 's/A-obj=//g'`
	;;
	# exceptobjs are the files NOT to include in the shared library
	-exceptobjs=*) except_objs=`echo A$arg | sed -e 's/A-exceptobjs=//g'`
	;;
	-kind=*) kind=`echo A$arg | sed -e 's/A-kind=//g'`
	;;
	-suffix=*) slsuffix=`echo A$arg | sed -e 's/A-suffix=//g'`
	;;
	-cc=*) CC=`echo A$arg | sed -e 's/A-cc=//g'`
	;;
	-clinker=*) CLINKER=`echo A$arg | sed -e 's/A-clinker=//g'`
	;;
	-echo) set -x ;;
	-noecho) set +x ; setecho=0 ;;
	-local) nolink=1 ; islocal=1 ;;
	-link) nolink=0 ;;
	-verbose) Verbose=echo ;;
	-noverbose) Verbose=true ;;
	-getpathspec) GetPathSpec="yes" ;;
	*)
	echo "Unrecognized option $arg"
	exit 1
	;;	
    esac
done
#
# This allows us to turn echo on by default, but suppress EVERYTHING
# with -noecho
if [ "$SHELL_ECHO" = "on" -o $setecho = 1 ] ; then 
    set -x 
fi
#
# This is the default
if [ "$kind" = "ignore" ] ; then
    exit 0
fi

if [ "$GetPathSpec" = "yes" ] ; then
    # Return only the path leader used for specifying the location of a
    # shared library
    # This should follow the libtool rules (libdir_flag_spec, libdir_separator,
    # etc.).  It should return quoted strings with ${shlibname}.  See the
    # ltconfig program, which contains all of this info.
    # Note that these sometimes need the linker spec line (${wl} in ltconfig,
    # often either empty or -Wl,).
    case $kind in 
        gcc) echo "-Wl,-rpath -Wl," ;;
	freebsd|solaris) echo "-R" ;;
        rs6000|aix|aix-4) echo "-L" ;; # ???
        irix|irix64|irixn32|sgi) echo "-rpath " ;;
	osf) echo "-shared -rpath " ;;
	*) echo "" ;;
    esac
    exit 0
fi

#
# Put other system-dependent option output here
#
# Actually build the library
if [ -z "$slsuffix" ] ; then
    slsuffix=so.1.0
    req_slsuffix=so
fi
if [ -z "$req_slsuffix" ] ; then
    req_slsuffix=$slsuffix
fi
if [ -z "$AR" ] ; then
    AR=ar
fi
if [ -z "$LD" ] ; then
    LD="ld"
fi
if [ -z "$CLINKER" ] ; then
    if [ -n "$CC" ] ; then
        CLINKER=$CC
    else
	echo "No C linker or C compiler specified!"
	exit 1
    fi
fi
if [ -z "$SHLIBS" ] ; then
    echo "No libraries specified!"
    exit 1
fi
#
# Check that there are libraries 
foundlib=0
for libname in $SHLIBS ; do
   libnamelocal=`basename $libname`
   if [ -s $libnamelocal ] ; then 
       foundlib=1
       break
   fi
done
if [ -n "$objs" ] ; then
    foundlib=1
    for file in $objs ; do
        if [ ! -s $file ] ; then
	    foundlib=0
	    break
	fi
    done
fi
if [ $foundlib = 0 ] ; then
    if [ -n "$objs" ] ; then
        echo "Could not find $objs"
    else
        echo "Could not find $SHLIBS"
    fi
    exit 1
fi
if [ ! -d shared ] ; then 
    mkdir shared
    created_shared=1
fi
#
# Note on except_objs:
# It is NOT an error to fail to find these files; if they aren't present,
# they are ignored.
case $kind in
    gcc)
    # Include any other libraries needed to link with in case they are
    # needed to resolve any symbols.  This is needed for Scyld and should
    # be harmless in general.
    OtherLibs="$BASE_LIB_LIST"
    for libname in $SHLIBS ; do
        $Verbose "Making a shared library of $libname"
        rm -rf .tmp
        mkdir .tmp

	if [ -z "$objs" ] ; then
            cd .tmp
            $AR x ../$libname
	    if [ -n "$except_objs" ] ; then
	        rm -f $except_objs
	    fi
            #$CLINKER -shared -Wl,-soname,$libbase.$slsuffix \
	    #	-o ../shared/$libbase.$slsuffix *.o
	else
	    cp $objs .tmp
	    cd .tmp
	fi
        libbase=`basename $libname .a`
	# The -h name sets the name of the object; this is necessary to 
	# ensure that the dynamic linker can find the proper shared library.
        $CLINKER -shared -Wl,-h,$libbase.$slsuffix -o ../shared/$libbase.$slsuffix *.o $OtherLibs 
        cd ..
        # Make a link in the library directory to the shared library in the
        # shared directory.
	if [ $islocal = 1 ] ; then
	    mv shared/$libbase.$slsuffix .
  	    if [ $slsuffix != $req_slsuffix -a $nolink = 0 ] ; then
	        rm -f $libbase.$req_slsuffix
	        ln -s $libbase.$slsuffix $libbase.$req_slsuffix
	    fi
	else
  	    if [ $slsuffix != $req_slsuffix -a $nolink = 0 ] ; then
	        rm -f shared/$libbase.$req_slsuffix
	        (cd shared ; \
                 ln -s ../$libbase.$slsuffix $libbase.$req_slsuffix )
            fi
	fi
        rm -rf .tmp
    done
    ;;
    solaris|solaris64)
    for libname in $SHLIBS ; do
        $Verbose "Making a shared library of $libname"
        rm -rf .tmp
        mkdir .tmp
	if [ -z "$objs" ] ; then
            cd .tmp
            $AR x ../$libname
	    if [ -n "$except_objs" ] ; then
	        rm -f $except_objs
	    fi
        else
	    cp $objs .tmp
	    cd .tmp
	fi
        # Note that we may need LD_LIBRARY_PATH_64 (!) for 64 bit builds
	libbase=`basename $libname .a`
        if $LD -G -h $libbase.$slsuffix -o ../shared/$libbase.$slsuffix *.o ; then
	    :
	else
	    # Exit if we fail to build the library
	    exit 1
	fi
        cd ..
	if [ $islocal = 1 ] ; then
	    mv shared/$libbase.$slsuffix .
  	    if [ $slsuffix != $req_slsuffix  -a $nolink = 0 ] ; then
	        rm -f $libbase.$req_slsuffix
	        ln -s $libbase.$slsuffix $libbase.$req_slsuffix
            fi
	else
  	    if [ $slsuffix != $req_slsuffix  -a $nolink = 0 ] ; then
	        rm -f shared/$libbase.$req_slsuffix
	        ( cd shared ; ln -s $libbase.$slsuffix $libbase.$req_slsuffix )
            fi
        fi
        rm -rf .tmp
    done
    ;;

    rs6000|aix|aix-4)
    # Untested
    for libname in $SHLIBS ; do
        $Verbose "Making a shared library of $libname"
        rm -rf .tmp
        mkdir .tmp
	if [ -z "$objs" ] ; then
            cd .tmp
            ar x ../$libname
	    if [ -n "$except_objs" ] ; then
	        rm -f $except_objs
	    fi
	else
	    cp $objs .tmp
	    cd .tmp
	fi
        # Another alternative is to export everything.  The following
        # has been suggested:
        # ld -o ../shared/$libbase.so *.o -bexpall -bnoentry -G
	libbase=`basename $libname .a`
        nm -g -p *.o | awk '{ if ($2 == "T") { print $1 ; }}' | \
	    sed -e 's/^\.//g' >  $libbase.exp
        # xlC doesn't work with this!
        # cc misses the iargc/getarg libraries
        if xlf -r -o ../shared/$libbase.so *.o -bE:$libbase.exp -bM:SRE -bnoentry ; then
	    :
	else
	    exit 1
        fi
        # create new shared file name
        newfile="${libbase}shared.a"
        /bin/rm -f $newfile
        ar qv $newfile ../shared/$libbase.so
        /bin/rm -f *.o
        cd ..
        /bin/rm -rf .tmp
    done
    ;;

    irix|irix64|sgi)
    for libname in $SHLIBS ; do
        $Verbose "Making a shared library of $libname"
        rm -rf .tmp
        mkdir .tmp
	if [ -z "$objs" ] ; then
            cd .tmp
            $AR x ../$libname
	    if [ -n "$except_objs" ] ; then
	        rm -f $except_objs
	    fi
        else
	    cp $objs .tmp
	    cd .tmp
	fi
	libbase=`basename $libname .a`
        if $CLINKER -elf -no_library_replacement -shared -rdata_shared -all \
	    -o ../shared/$libbase.$slsuffix *.o ; then
	    :
	else
	    exit 1
        fi
        cd ..
	if [ $islocal = 1 ] ; then
	    mv shared/$libbase.$slsuffix .
  	    if [ $slsuffix != $req_slsuffix  -a $nolink = 0 ] ; then
	        rm -f $libbase.$req_slsuffix
	        ln -s $libbase.$slsuffix $libbase.$req_slsuffix
            fi
	else
  	    if [ $slsuffix != $req_slsuffix  -a $nolink = 0 ] ; then
	        rm -f shared/$libbase.$req_slsuffix
	        ( cd shared ; ln -s $libbase.$slsuffix $libbase.$req_slsuffix )
            fi
        fi
        rm -rf .tmp
    done
    ;;

    hpux*)
    echo "HPUX is not supported"
    # From libtools' ltconfig, we might try (except for hpux9)
    # ld -b +h libmpich.so +b $installdir -o libmpich $objs ...
    # Note that libtool notes that shared libraries need to have 
    # permissions 555 (chmod 555 $lib)
    ;;

    osf)
    for libname in $SHLIBS ; do
        $Verbose "Making a shared library of $libname"
        rm -rf .tmp
        mkdir .tmp
	if [ -z "$objs" ] ; then
            cd .tmp
            $AR x ../$libname
	    if [ -n "$except_objs" ] ; then
	        rm -f $except_objs
	    fi
        else
	    cp $objs .tmp
	    cd .tmp
	fi
	libbase=`basename $libname .a`
        if $CLINKER -shared  -Wl,-expect_unresolved -Wl,\* \
	    -Wl,-msym \
	    -o ../shared/$libbase.$slsuffix *.o ; then
	    :
	else
	    exit 1
        fi
        cd ..
	if [ $islocal = 1 ] ; then
	    mv shared/$libbase.$slsuffix .
  	    if [ $slsuffix != $req_slsuffix  -a $nolink = 0 ] ; then
	        rm -f $libbase.$req_slsuffix
	        ln -s $libbase.$slsuffix $libbase.$req_slsuffix
            fi
	else
  	    if [ $slsuffix != $req_slsuffix  -a $nolink = 0 ] ; then
	        rm -f shared/$libbase.$req_slsuffix
	        ( cd shared ; ln -s $libbase.$slsuffix $libbase.$req_slsuffix )
            fi
        fi
        rm -rf .tmp
    done
    ;;
    
    *)	
    if [ -z "$kind" ] ; then
        echo "Shared library type not specified"
    else
        echo "Unknown shared library type $kind"
    fi 
    exit 1
    ;;
esac
# Remove the shared directory if local and we created it
if [ $islocal = 1 -a $created_shared = 1 ] ; then
   rm -rf shared
fi


