Newsgroups: comp.parallel.pvm
From: drake@interoz.com (Richard Drake)
Subject: make utility for PVM programs across non-shared file systems
Organization: CMDS News machine
Date: Tue, 23 Apr 1996 21:47:10 GMT
Message-ID: <4ljmad$frp@server.cntfl.com>


#                           pvmake
#
#   To compile a program for use with PVM, duplicate copies of
# the source code must be compiled on the various machines
# comprising the virtual machine.  If the machines
# do not share a file system, the code must be copied to all
# the machines and then compiled separately.  
# The pvmake script does this automatically from a single
# terminal (window).  This allows the programmer to do the
# editing on a single terminal as is done with serial programming.
#   pvmake copies only the necessary files
# needed to update your program on all machines in a hostfile list.
# It copies them to the same directory under the $HOME directory
# on each machine.  Then it executes aimk on each of the machines.
# pvmake utilizes aimk together with a Makefile.aimk to determine
# your program dependencies.
#   Note: If the machine which is executing pvmake is in the hostfile
# list, files are copied to themselves and aimk is executed twice.
#   Caution: pvmake uses the condition of the source code on the
# machine executing pvmake to determine which files to copy.  If
# aimk, for instance, was run on the current machine before pvmake,
# it will not copy all necessary files in order to update the code
# on the other machines. (In this case, use -a or -A option.)
#
# USAGE:
#           pvmake [-aAcnh] [hostfile] [target1 target2 ...]
#
#   The targets are the same targets used with aimk (or make), in
# fact, these arguments are just passed to aimk.
#
# OPTIONS:
#           -a   pvmake copies all files in the dependency list
#                as dictated by Makefile.aimk
#
#           -A   copies all files in the current directory except
#                *.o, executables, and directories.
#
#           -c   performs a dry run to check what pvmake will do
#                without actually doing it.
#
#           -n   copies files but does not execute aimk.
#
#           -h   pvmake looks for the file "hostfile" in the
#                current directory with the list of machines
#                to copy to.  The -h option specifies a different
#                hostfile file name.
#
# AUTHOR:
#           Richard Drake
#           drake@interoz.com
# DATES:
#           written: 4/96
#
#========================================================

# get options
all=0
ALL=0
check=0
noaimk=0
hfile=""
while getopts aAcnh: op
do
  case $op in
    a) all=1 ;;
    A) ALL=1 ;;
    c) check=1 ;;
    n) noaimk=1 ;;
    h) hfile=$OPTARG ;;
  esac
done
shift `expr $OPTIND - 1`



# if hfile is null, set hostfile to "hostfile"
test ! -n "$hfile" && hfile=hostfile

# get remote hosts list
hosts=`cat $hfile`

# check the connection to remote hosts and build list of connectables
bld=""
for host in $hosts
do
  rsh $host 'date > /dev/null'
  if [ $? -ne 0 ]
  then
    echo "(could not execute rsh on $host)"
  else
    bld="$bld $host"
  fi
done
hosts=$bld



# if there is at least one host ...
if [ -n "$hosts" ]
then

# get current subdirectory under login name on this machine
  subCWD=`echo $PWD $LOGNAME | awk '{ i = index($1,$2)
                                      n = length($2)
                                      print substr($1,i+n+1) }'`

  dest=""
  for host in $hosts
  do

#   get home directory of remote machine
    rhome=`rsh $host 'echo $HOME'`
#   form the remote directory to copy files to
    rdir=$rhome/$subCWD

#   create directory on remote machine if not already there
    echo Duplicating $subCWD to $host:$rdir
    [ $check -eq 0 ] && rsh $host mkdir -p $rdir

#   build destination host:directory list
    dest="$dest $host:$rdir"

  done



# execute a nonexecuting aimk to get a (lousy) list of files to copy
  if [ $all -eq 1 ]
  then
#   "all" option was invoked so get list of all dependencies
    aimake=`aimk -P $*`
  else
#   just get list of files that need to be copied
    aimake=`aimk -nds $*`
  fi

# make sure the current ai makefile is included on list
  aimake="$aimake Makefile.aimk"
# if "all" option is invoked, include FORTRAN pvm header file
  [ $all -eq 1 ] && aimake="$aimake fpvm3.h"

# if ALL option is invoked, put all files on aimake list
  [ $ALL -eq 1 ] && aimake=`ls`

  olist=`ls *.o`

  for file in `ls`
  do

#   flag for text file or not
    textfile=0

#   test for directory
    test -d $file && textfile=1

#   test for executable
    test -x $file && textfile=1

#   test for .o file
    for ofile in $olist
    do
      if [ $file = $ofile ] 
      then
        textfile=1
        break
      fi
    done

#   if $file is a textfile, ...
    if [ $textfile -eq 0 ]
    then
#     see if $file is contained in the aimake list somewhere
      temp=`echo $aimake | grep $file`
      if [ -n "$temp" ]
      then
#       copy $file to all machines
        for to in $dest
        do
          echo rcp $file to $to
          [ $check -eq 0 ] && rcp $file $to
        done
      fi
    fi
  done

# if "noaimk" option is not specified, ...
  if [ $noaimk -eq 0 ]
  then
#   execute aimk on machine executing pvmake
    echo
    echo $PWD';' aimk $*
    [ $check -eq 0 ] && aimk $*
#   execute aimk on all machines in hostfile
    for host in $hosts
    do
#     look for $host in destination list to get the remote directory
      for dd in $dest
      do
        temp=`echo $dd | grep $host`
        if [ -n "$temp" ]
        then
#         extract remote directory (without the host name attatched)
          dir=`echo $dd | awk '{ i = index($1,":")
                                 print substr($1,i+1) }'`
          echo
          echo $host:$dir';' aimk $*
          [ $check -eq 0 ] && rsh $host "cd $dir; aimk $*"
          break
        fi
      done
    done
  fi
fi


