#!/usr/local/bin/bash
#
# obuildtree - create an OMNI build tree
#


###########################################################################
#
# Check that we have GNU make
#

if [ "$GNUMAKE" = "" ]; then
  case `make -v 2>/dev/null` in
  GNU*) ;;
  *)
    echo "The 'make' on your path is not GNU make."
    echo Set the GNUMAKE environment variable to specify the GNU make command.
    exit 1
    ;;
  esac
else
  case `$GNUMAKE -v 2>/dev/null` in
  GNU*) ;;
  *)
    echo "The 'make' in the GNUMAKE environment variable is not GNU make."
    echo Set the GNUMAKE environment variable to specify the GNU make command.
    exit 1
    ;;
  esac
fi


###########################################################################
#
# Unfortunately the built-in "read" doesn't work on NT so we need this.  It
# also expands environment variables in the input string, but this means
# it doesn't cope with double-quotes the input string.
#

myread() {
  if [ "$2" != "" ]; then
    echo -n "> [$2] "
  else
    echo -n "> "
  fi
  result=`head -1`
  if [ "$result" = "" ]; then
    result=$2
  fi
  eval "$1=\"$result\""
}


###########################################################################
#
# Function to get details interactively:
#

interactive() {

#
# Get the base OMNI tree
#

  echo
  echo "Enter the base OMNI tree for this build tree"
  myread baseomnitree $OMNI_TREE

  if [ "$baseomnitree" = "" ]; then
    echo "Error: no base OMNI tree specified"
    exit 1
  fi


#
# Get the platform
#

  getdefaultplatform
  echo
  echo "Enter the platform name from:"
  (cd $baseomnitree/mk/platforms; ls *.mk */*.mk | sed s/\.mk//g)
  myread platform $defaultplatform

  if [ ! -r "$baseomnitree/mk/platforms/$platform.mk" ]; then
    echo
    echo "No such platform \"$platform\""
    echo
    exit 1
  fi


#
# Get the destination
#

  echo
  echo "Enter the destination directory"
  myread dest $platform

  if [ -e "$dest" ]; then
    echo
    echo "Error: \"$dest\" already exists."
    echo
    echo "Remove it ?"
    myread rmexistingdest n
    if [ "$rmexistingdest" != "y" ]; then
      exit 1
    fi
    rm -rf $dest
  fi


#
# Get the export tree
#

  echo
  echo "Does this build tree have an export tree ?"

  current=`pwd`
  if [ `basename $current` = "build" ]; then
    defaultexporttree=`dirname $current`
    myread hasexporttree y
  else
    myread hasexporttree n
  fi


  if [ "$hasexporttree" = "y" ]; then
    echo
    echo "Enter the export tree"
    myread exporttree $defaultexporttree
  fi


#
# Get the import trees
#

  echo

  if [ "$exporttree" = "$baseomnitree" ]; then

    echo "The only import tree will be $exporttree (this is both"
    echo "the export tree & the base OMNI tree)"
    imports="$exporttree"

  else

    if [ "$exporttree" != "" ]; then
      echo "The first import tree will be $exporttree (the export tree)"
    fi

    echo "The final import tree will be $baseomnitree (the base OMNI tree)"

    extraenvimports=`echo $OMNI_IMPORT_TREES | tr ' ' '\n' | \
		     egrep -v '^'$exporttree'$'`
    extraenvimports=`echo $extraenvimports`

    envimports=""
    if [ "$extraenvimports" != "" ]; then
       for import_tree in $extraenvimports; do
          echo "Do you also want to import from $import_tree ?"
          myread use_import_tree y
          if [ "$use_import_tree" = "y" ]; then
            envimports="$envimports $import_tree"
          fi;
       done;
    fi;

    echo "Enter any other import trees in search order"

    import=wob
    while [ "$import" != "" ]; do
      myread import
      intimports="$intimports $import"
    done

    imports="$exporttree $intimports $envimports $baseomnitree"
  fi

    firstimport=`echo $imports | awk '{print$1}'`


#
# Get the source trees
#

  echo
  echo "Does this build tree have any source trees ?"
  myread hassourcetree y

  if [ "$hassourcetree" = "y" ]; then
    echo
    echo "Enter the source trees (relative to $current/$dest)"
    myread source $firstimport/src

    sources=$source

    while [ "$source" != "" ]; do
      myread source
      sources="$sources $source"
    done
  fi

}


###########################################################################
#
# Get default platform
#

getdefaultplatform() {
  if [ -x /usr/local/bin/arch ]; then
    defaultplatform=`/usr/local/bin/arch -binv`;
    if [ ! -e "$baseomnitree/mk/platforms/$defaultplatform.mk" ]; then
      unset defaultplatform
    fi
  fi
}



###########################################################################
#
# Check arguments
#

if [ $# -eq 0 ]; then

  interactive=true

  interactive

else

  interactive=false

  while [ "$1" != "" ]; do
    case "$1" in

    -b)
      shift
      baseomnitree=$1
      shift
      ;;

    -p)
      shift
      platform=$1
      shift
      ;;

    -d)
      shift
      dest=$1
      shift
      ;;

    -e)
      shift
      exporttree=$1
      shift
      ;;

    -i)
      shift
      imports="$imports $1"
      shift
      ;;

    -s)
      shift
      sources="$sources $1"
      shift
      ;;

    *)
      echo "usage: obuildtree [-b baseomnitree] [-p platform] [-d dest] [-e export]"
      echo "                  [-i import]* [-s source]*"
      exit 1
      ;;

    esac

  done

  #
  # Fill in defaults not set on command line
  #
  
  if [ "$baseomnitree" = "" ]; then
    baseomnitree="$OMNI_TREE"
    if [ "$baseomnitree" = "" ]; then
      echo "Error: no base OMNI tree specified"
      exit 1
    fi
  fi

  if [ "$platform" = "" ]; then
    getdefaultplatform
    platform=$defaultplatform
  fi

  if [ "$dest" = "" ]; then
    dest="$platform"
  fi

  imports="$exporttree $imports $baseomnitree"

fi



###########################################################################
#
# A few sanity checks
#

if [ ! -r "$baseomnitree/mk/platforms/$platform.mk" ]; then
  echo
  echo "No such platform \"$platform\""
  echo
  exit 1
fi

if [ -e "$dest" ]; then
  echo "Error: \"$dest\" already exists."
  exit 1
fi


###########################################################################
#
# Create the destination directory and its config directory
#

set -e

mkdir -p $dest/config


###########################################################################
#
# Tell the user what's going on
#

echo
echo "************************************************************************"
echo
echo "Creating OMNI build tree \"$dest\" for platform \"$platform\""
echo
if [ "$exporttree" != "" ]; then
  echo "Export tree is $exporttree"
else
  echo "No export tree"
fi
echo
echo "Import trees are:"
for i in $imports; do
  if [ -d $i ]; then
    echo $i
  else
    echo "$i - DOESN'T EXIST"
  fi
done
echo
if [ "$sources" != "" ]; then
  (cd $dest
    echo "Source trees are:"
    for s in $sources; do
      if [ -d $s ]; then
	echo $s
      else
	echo "$s - DOESN'T EXIST"
      fi
    done
  )
else
  echo "No source trees"
fi
echo


###########################################################################
#
# Generate the header of "config.mk"
#

cat >$dest/config/config.mk <<EOF
#
# AUTOMATICALLY GENERATED by "obuildtree"
#
# Coming into this file, omake should have defined TOP, CURRENT and VPATH.
# VPATH should contain the equivalent of the CURRENT directory for each
# of the source trees.
#

platform = $platform

EXPORT_TREE = $exporttree

IMPORT_TREES = $imports

override VPATH := \$(subst :, ,\$(VPATH))

EOF


###########################################################################
#
# For each "import" tree include the "beforedir.mk" in "config.mk".
# THIS_IMPORT_TREE is set to let it know how to include other files in the
# same directory.  Note that the order is the reverse of the search order
# (because later .mk files can override variable settings in previous ones).
#

for i in $imports; do
  revimports="$i $revimports"
done

for i in $revimports; do

  cat >>$dest/config/config.mk <<EOF
THIS_IMPORT_TREE := $i
ifneq (\$(wildcard \$(THIS_IMPORT_TREE)/mk/beforedir.mk),)
include \$(THIS_IMPORT_TREE)/mk/beforedir.mk
endif

EOF

done


###########################################################################
#
# Include the "dir.mk" in "config.mk" - this is searched for in each of the
# source directories using -I flags given to gnumake by omake.
#

cat >>$dest/config/config.mk <<EOF
include dir.mk

EOF


###########################################################################
#
# For each "import" tree include the "afterdir.mk" in "config.mk"
#

for i in $imports; do

  cat >>$dest/config/config.mk <<EOF
THIS_IMPORT_TREE := $i
ifneq (\$(wildcard \$(THIS_IMPORT_TREE)/mk/afterdir.mk),)
include \$(THIS_IMPORT_TREE)/mk/afterdir.mk
endif

EOF

done


###########################################################################
#
# Generate the "sources" file
#

touch $dest/config/sources
for s in $sources; do

  echo $s >>$dest/config/sources

done
