#
# $Id: buildsubs,v 1.14 1999/07/26 19:05:33 hanche Exp $
#

# Simple build routines.  Construct a wrapper script which sources
# this file after setting enough of the variables listed below.
#
# Invoke the wrapper script with either no arguments (build on all
# architectures) or with a list of architectures as arguments.
#
# Set enough of these in the wrapper shell script:
#
# appname=(no default)
# version=(no default)
# buildtype=(X|GNU|make|pm, the latter assumes config already done)
# confcmd=(can be null, in which case we use confstring or default under GNU)
# confstring=(can be null, in which case we just do --prefix=$prefix)
# prefix=(can be null, in which case we use confstring)
# maketargets=(target(s) to use instead of the default empty string)
# installtargets=(target(s) to use instead of "install", defaulted for GNU&X)
# linkdownfirst=(non-null -> list of apps to link down before compiling)
# linkupafter=(non-null -> list of apps to link up after installing)
# linkupthis=(non-null => slash-separated list of (app ver store) to link
#             up before compiling)
# postpostinstcmds=(can be null)
# rsh=(rsh|ssh, defaults to ssh -x)
# nice=(defaults to "nice -15")
# timeout=(defaults to 20) (was 10)
#

perlintpath=/store/etc/internal

hostdir=$HOME/etc

# Mapping from Perl5 pm to store arch
pmabya=$perlintpath/etc/pm-a-by-a

if test -r $hostdir/master.conf; then
	. $hostdir/master.conf
else
	echo "Unable to read $hostdir/master.conf"
	exit 1
fi

# which perl to run
perl=${perl:-"perl"}

# which tar to run.  We need GNU tar
tar=${tar:-"tar"}

# which make to run.  We want GNU make
make=${make:-"make"}

# Edit buildhosts to add/change
buildhosts=${buildhosts:-"$hostdir/buildhosts"}

hosts=`sed 's/#.*//' < $buildhosts`

# default as appropriate
rsh=${rsh:-"ssh -x"}
confstring=${confstring:-"--prefix=${prefix:-/store}"}
nice=${nice:-"nice -15"}
#timeout=${timeout:-"10"}
#timeout=10 er for kort for enkelte bokser. -roart
timeout=${timeout:-"25"}

# Always link down the compiling app before installing and up after
if test "X$linkdownfirst" = X; then
	linkdownfirst="$appname"
else
	linkdownfirst="$appname $linkdownfirst"
fi
if test "X$linkupafter" = X; then
	linkupafter="$appname"
else
	linkupafter="$appname $linkdownfirst"
fi

do_master () {

  cd $mastertree/$appname

  echo ...shadowing
  $perl $perlintpath/shadow.pl -m $masterstore -s $masterstore -a $appname \
		-v $version -A $masterarch

  cd src-$version-$masterarch

  if [ "$linkdownfirst" ]; then
     for a in $linkdownfirst; do
       # Find out if and to what store the application is linked up,
       # it might be something else than $masterstore.
       linkedupto=""
       f=/store/etc/appinfo/$a/info
       if [ -f $f ]; then
         x=`cat /store/etc/appinfo/$a/info`
         linkedupto=`set x $x; test "$3" = linkedup && echo $4`
       fi
       if [ "$linkedupto" ]; then
         echo ...$a was linked up to $linkedupto on $masterstore, linking down
         (set -x;
          $perl $perlintpath/linkdown.pl \
          -a $a -s $linkedupto -l $masterlinktree)
        aq=`echo $a | tr .+- ___`
        eval linkedupto_$aq=$linkedupto
       fi
     done
  fi

  if [ "$linkupthis" ]; then
     echo "$linkupthis" | tr / "\n" |
     while read a v; do
	(set -x
	$perl $perlintpath/linkup.pl -a $a -v $v -s $masterstore -l $masterlinktree)
     done
  fi	


  if [ "$buildtype" = "X" ]; then
    echo ...configuring
    (set -x; $nice xmkmf -a)
  elif [ "$buildtype" = "pm" ]; then
    . $pmabya
    eval PMA=\$PMA_$masterarch
    if [ "$PMA" ]; then
	echo "Perl-module archname = '$PMA'"
    else
	echo Error: No perl-module archname
	exit 1
    fi
    echo ...configuring
    (set -x; $nice $perl Makefile.PL)
  elif [ "$buildtype" = "GNU" ]; then
    echo ...configuring
    if [ "$confcmd" ]; then
      (set -x; eval SARCH=$masterarch $confcmd)
    else
      (set -x; $nice ./configure $confstring)
    fi
  elif [ "$buildtype" = "make" ]; then
    echo "...buildtype 'make': assuming that no configuration is necessary"
  else
    echo "Warning: unknown or unset buildtype '$buildtype'"
  fi

  (set -x; $nice $make $maketargets)

  echo ...installing
  if [ "$buildtype" = "X" ]; then
    targets="install install.man"
  else
    targets="install"
  fi
  if [ "$installtargets" ]; then
    targets="$installtargets"
  fi
  postinstprefix=
  if [ "$directinstall" ]; then
    directinstall="/store/store/$masterstore/$appname/ver-$version"
    postinstprefix="-p $directinstall"
    targets="prefix=$directinstall $targets"
  fi

  if [ "$buildtype" = "pm" ]; then
	rm -f /store/lib/perl5/$PMA/$curperlvers/perllocal.pod
  fi
  (set -x; $nice $make $targets)
  if [ "$buildtype" = "pm" ]; then
	mv /store/lib/perl5/$PMA/$curperlvers/perllocal.pod \
	   /store/lib/perl5/pod/perllocal-$appname.pod
  fi

  echo ...running postinst
  $perl $perlintpath/postinst.pl -a $appname -A $masterarch \
		-s $masterstore -v $version -l $masterlinktree \
		-t $timeout $postinstprefix

  (cd ../ver-$version/lib/perl5 || exit 0
   rm -rf  $PMA@$masterarch
   mv $PMA $PMA@$masterarch
   rm -rf            site_perl/$PMA@$masterarch
   mv site_perl/$PMA site_perl/$PMA@$masterarch
  )

  if [ ! -z "$postpostinstcmds" ]; then
    echo ...running post-postinst commands
    (set -x;
    cd ../ver-$version;
    SARCH=$masterarch eval "$postpostinstcmds" )
  fi

  if [ "$linkupafter" ]; then
    for a in $linkupafter; do
      aq=`echo $a | tr .+- ___`
      eval linkedupto=\$linkedupto_$aq
      if [ "$linkedupto" ]; then
        echo "...app $a now being re-linked up to $linkedupto"
        (set -x;
          $perl $perlintpath/linkup.pl \
          -a $a -s $linkedupto -l $masterlinktree)
      fi
    done
  fi
}


do_slave () {
  slavestore=$1
  slavehost=$2
  slavearch=$3
  slavelinktree=$4

  bashinit=". /store/store/Adm/.bashrc; set -x"

  echo ...making directory
  $rsh -n $slavehost "$bashinit; mkdir /store/store/$slavestore/$appname-c"

  compiledir=/store/store/$slavestore/$appname-c/src-$version-$slavearch
  compiletre=/store/store/$slavestore/$appname-c

  echo ...shadowing
  $rsh -n $slavehost "$bashinit; $perl $perlintpath/shadow.pl \
	-m $masterstore -s $slavestore -a $appname-c -v $version -A $slavearch"

  if [ "$linkdownfirst" ]; then
    for a in $linkdownfirst; do
      # Find out if and to what store the application is linked up,
      # it might be something else than $slavestore.
      x=`$rsh -n $slavehost "$bashinit; cat /store/etc/appinfo/$a/info"`
      linkedupto=`set x $x; test "$3" = linkedup && echo $4`
      if [ "$linkedupto" ]; then
        echo ...$a was linked up to $linkedupto on $slavehost, linking down
        $rsh -n $slavehost "$bashinit; \
          $perl $perlintpath/linkdown.pl \
          -a $a -s $linkedupto -l $slavelinktree"
        aq=`echo $a | tr .+- ___`
        eval linkedupto_$aq=$linkedupto
      fi
    done
  fi

  if [ "$linkupthis" ]; then
     echo "$linkupthis" | tr / "\n" |
     while read a v; do
        $rsh -n $slavehost "(set -x; \
        $perl $perlintpath/linkup.pl -a $a -v $v -s $masterstore -l $slavelinktree)"
     done
  fi

  if [ "$buildtype" = "X" ]; then
    echo ...configuring
    $rsh -n $slavehost "$bashinit; cd $compiledir; $nice xmkmf -a"
  elif [ "$buildtype" = "pm" ]; then
    . $pmabya
    eval PMA=\$PMA_$slavearch
    if [ "$PMA" ]; then
	echo "Perl-module archname = '$PMA'"
    else
	echo Error: No perl-module archname
	exit 1
    fi
    echo ...configuring
    $rsh -n $slavehost "$bashinit; cd $compiledir; $nice $perl Makefile.PL"
  elif [ "$buildtype" = "GNU" ]; then
    echo ...configuring
    GNUarch=`$rsh -n $slavehost "$bashinit; $compiledir/config.guess`
    if [ "$confcmd" ]; then
      $rsh -n $slavehost "$bashinit; cd $compiledir; \
	SARCH=$slavearch $confcmd"
    else
      $rsh -n $slavehost "$bashinit; cd $compiledir; \
	$nice ./configure $confstring"
    fi
  elif [ "$buildtype" = "make" ]; then
    echo "...buildtype 'make': assuming that no configuration is necessary"
  else
    echo "Warning: unknown or unset buildtype '$buildtype'"
  fi

  echo ...compiling
  $rsh -n $slavehost "$bashinit; cd $compiledir; $nice $make $maketargets"

  echo ...installing
  if [ "$buildtype" = "X" ]; then
    targets="install install.man"
  else
    targets="install"
  fi
  if [ "$installtargets" ]; then
    targets="$installtargets"
  fi
  postinstprefix=
  if [ "$directinstall" ]; then
    directinstall="/store/store/$slavestore/$appname-c/ver-$version"
    postinstprefix="-p $directinstall"
    targets="prefix=$directinstall $targets"
  fi

  if [ "$buildtype" = "pm" ]; then
	cmd="rm -f /store/lib/perl5/$PMA/$curperlvers/perllocal.pod"
	cmd="$cmd; cd $compiledir; $nice $make $targets"
	cmd="$cmd; mv /store/lib/perl5/$PMA/$curperlvers/perllocal.pod /store/lib/perl5/pod/perllocal-$appname.pod"
  else
	cmd="cd $compiledir; $nice $make $targets"
  fi

  echo "$rsh -n $slavehost \"$bashinit; $cmd\""
  $rsh -n $slavehost "$bashinit; $cmd"

  echo ...running postinst
  $rsh -n $slavehost "$bashinit; \
	$perl $perlintpath/postinst.pl \
	-a $appname-c -A $slavearch -s $slavestore \
	-v $version -l $slavelinktree -t $timeout $postinstprefix"

  echo ...removing *@$slavearch.old files from ver tree
  $rsh -n $slavehost "$bashinit; \
	cd $compiletre; find ver-$version -name '*@'$slavearch.old \
	    -print -exec rm -f {} ';'"

  apptarfile=V-$appname-c-$version@$slavearch.tar

  repackage=false
  if [ "$postpostinstcmds" ]; then
    echo ...running post-postinst commands
    $rsh -n $slavehost "$bashinit; \
	(set -x; cd $compiletre/ver-$version; \
	export SARCH=$slavearch; export GNUarch=$GNUarch; $postpostinstcmds)"
    repackage=true
  fi
  if [ "$buildtype" = "pm" ]; then
    $rsh -n $slavehost "$bashinit; \
	(set -x; cd $compiletre/ver-$version/lib/perl5 || exit 0; \
	   rm -rf  $PMA@$slavearch
	   mv $PMA $PMA@$slavearch
	   rm -rf            site_perl/$PMA@$slavearch
	   mv site_perl/$PMA site_perl/$PMA@$slavearch)"
    repackage=true
  fi

  if $repackage; then
    echo ...re-packaging arch-specific files
    $rsh -n $slavehost "$bashinit; \
	cd $compiletre; find ver-$version -name '*@*' | \
	    $tar cvfT $apptarfile -";
  fi

  echo ...fetching files to local machine
  echo "$rsh -n $slavehost cat $compiletre/V-$appname-c-$version@$slavearch.tar \
    | $tar -xvpf -"
  $rsh -n $slavehost cat $compiletre/V-$appname-c-$version@$slavearch.tar \
    | $tar -xvpf -

  echo ...removing compiletree from remote machine
  echo "$rsh -n $slavehost $bashinit; rm -rf $compiletre"
  $rsh -n $slavehost "$bashinit; rm -rf $compiletre"

  if [ "$linkupafter" ]; then
    for a in $linkupafter; do
      aq=`echo $a | tr .+- ___`
      eval linkedupto=\$linkedupto_$aq
      if [ "$linkedupto" ]; then
        echo "...app $a now being re-linked up to $linkedupto"
        $rsh -n $slavehost "$bashinit; \
          $perl $perlintpath/linkup.pl \
          -a $a -s $linkedupto -l $slavelinktree"
      fi
    done
  fi

}

onlysome=0
for a in $*; do
    if [ $a = "all" ]; then
	break;
    fi
    eval build_$a=1
    onlysome=1
done

set $hosts
while [ $# -gt 0 ]; do
    store=$1; shift
    host=$1; shift
    arch=$1; shift
    linktree=$1; shift
    curperlvers=$1; shift

    if [ $onlysome = "1" ]; then
	if eval test \"\$build_$arch\" = "1"; then
	    echo doing $arch on $host
	    (
	    if [ $store = $masterstore ]; then
		do_master
	    else
		do_slave $store $host $arch $linktree
	    fi
	    echo ...done ) > out.$arch 2>&1 </dev/null &
	fi
    else
	    echo doing $arch on $host
	    (
	    if [ $store = $masterstore ]; then
		do_master
	    else
		do_slave $store $host $arch $linktree
	    fi
	    echo ...done ) > out.$arch 2>&1 </dev/null &
    fi
done
