Skip to content
Snippets Groups Projects
dunecontrol 8.24 KiB
#!/bin/sh

set -e

if test "x$1" = "x--debug"; then
  DEBUG=yes
fi

if test "x$DEBUG" = "xyes"; then
  set -x
  set -v
fi

###############################################

#
# Configuration
#

# name of the "control" files
CONTROL="dune.module"

###############################################

#
# LIB
#

parse_control() {
  if test -f "$1"; then
    export module=$(echo $(grep Module: "$1" | cut -d ':' -f2))
    local deps=$(echo $(grep Depends: "$1" | cut -d ':' -f2))
    local sugs=$(echo $(grep Suggests: "$1" | cut -d ':' -f2))
    local path=$(dirname "$1")
    if test "x$module" != "x"; then
      if check_modname "$module"; then
        export HAVE_${module}=yes
        export PATH_${module}="$path"
        export DEPS_${module}="$deps"
        export SUGS_${module}="$sugs"
      else
        echo "ERROR: $CONTROL files $1 contains an invalid Module entry"
		exit 1
      fi
    else
      echo "ERROR: $CONTROL files $1 does not contain a Module entry"
	  exit 1
    fi
  else
    echo "ERROR: could not read file $1"
    exit 1
  fi
}

find_modules() {
  if test -d "$1"; then
    local dir=$(cd "$1" && pwd)
    while read m; do
      if test "x$m" != "x"; then
        export module=""
        parse_control "$m"
        export MODULES="$MODULES $module"
      fi
    done <<EOF
 $(find "$dir" -name $CONTROL )
EOF
  else
    echo "ERROR: could not find directory $1"
    false
  fi
}

_sort_module() {
  local module=$1
  shift 1
  check_modname $module || (echo "ERROR: invalid module name $1"; exit 1)
  if test "x$(eval echo \$SORT_DONE_${command}_${module})" != "xyes"; then
    # resolve dependencies
    for dep in $(eval "echo \$DEPS_$module"); do
	  check_modname $dep || (echo "ERROR: invalid module name $1"; exit 1)
      if test "x$(eval echo \$HAVE_$dep)" != "x"; then
        _sort_module $dep
      else
        echo "ERROR: could not find module $dep"
        exit 1
      fi
    done
    # resolve suggestions
    for dep in $(eval "echo \$SUGS_$module"); do
	  check_modname $dep || (echo "ERROR: invalid module name $1"; exit 1)
      if test "x$(eval echo \$HAVE_$dep)" != "x"; then
        _sort_module $dep
      fi
    done
    # insert this module into the list
    export SORT_DONE_${command}_${module}=yes
    export SORTEDMODULES="$SORTEDMODULES $module"
  fi
}

sort_modules() {
  for m in "$@"; do
    _sort_module $m
  done
  export MODULES=$SORTEDMODULES
}

#
# load the $CONTROL file, skip all control variables
# and run a command
#
# parameters:
# $1 command to execute
# $2 full path of the $CONTROL file
#
eval_control() {
  local command=$1
  local file=$2
  shift 2
  if test -f "$file"; then
    # open subshell
    (
      set -e
      # load functions defined in $file
      # if $command is not defined in $file,
      # then the default implementation will be executed
      eval "$(grep -v -e '^[[:alnum:]]\+:' $file)"
      # execute $command
      $command
    ) || false
  else
    echo "ERROR: could not find $file"
    exit 1
  fi
}

build_modules() {
  load_opts $command
  local runcommand=run_$command
  for module in $MODULES; do
    local path=$(eval "echo \$PATH_${module}")
	echo "--- calling $command for $module ---"
    (
      set -e
      cd "$path"
      eval_control $runcommand $path/$CONTROL
    ) || (echo "--- Failed to build $module ---"; exit 1)
	echo "--- done ---"
  done
return
  local command=$1
  shift
  load_opts $command
  for m in $MODULES; do
    _build_module $runcommand $m
  done
}

check_modname() {
  if ! echo "$1" | grep -q '^[a-zA-Z0-9_]\+$'; then
    return 1
  fi
  return 0
}

load_opts() {
  local command=$1
  local COMMAND=$(echo $command | tr '[:lower:]' '[:upper:]')
  if test "x$OPTS_FILE" != "x"; then
    echo "----- loading default flags \$${COMMAND}_FLAGS from $OPTS_FILE -----"
    CMD_PARAMS="$(. $OPTS_FILE; eval echo \$${COMMAND}_FLAGS)"
  fi
}

###############################################

#
# default implementations for commands... 
# these can be overwritten in the $CONTROL files
#

COMMANDS="autogen configure make all exec"

run_default_nothing () { echo -n; }

run_default_exec () { bash -c "eval $CMD_PARAMS"; }

run_default_update () { echo "WARNING: Doing nothing"; }

run_default_autogen () {
  PARAMS="$CMD_PARAMS"
  if test -x autogen.sh; then
    for m in $MODULES; do
      path=$(eval "echo \$PATH_$m")
      if test -d $path/m4; then
        ACLOCAL_FLAGS="$path $ACLOCAL_FLAGS"
      fi
    done
    eval ./autogen.sh "$ACLOCAL_FLAGS" "$PARAMS" || exit 1
  fi
}

run_default_configure () {
  PARAMS="$CMD_PARAMS"
  if test -x configure; then
    if test "x$HAVE_dune_common" == "xyes"; then
      PARAMS="$PARAMS \"--with-dunecommon=$PATH_dune_common\""
    fi
    if test "x$HAVE_dune_grid" == "xyes"; then
      PARAMS="$PARAMS \"--with-dunegrid=$PATH_dune_grid\""
    fi
    if test "x$HAVE_dune_istl" == "xyes"; then
      PARAMS="$PARAMS \"--with-duneistl=$PATH_dune_istl\""
    fi
    if test "x$HAVE_dune_disc" == "xyes"; then
      PARAMS="$PARAMS \"--with-dunedisc=$PATH_dune_disc\""
    fi
    echo ./configure "$PARAMS"
    eval ./configure "$PARAMS" || exit 1
  else
    if test -f configure.in || test -f configure.ac; then
      echo "ERROR: configure.[in|ac] found, but configure missing"
      echo "did you forget to run autoconf?"
      exit 1
    fi
  fi
}

run_default_make () {
  PARAMS="$CMD_PARAMS"
  echo make "$PARAMS"
  eval make "$PARAMS"
}

run_default_all () {
  load_opts autogen
  run_autogen
  load_opts configure
  run_configure
  load_opts make
  run_make
}

run_nothing () {
  run_default_nothing
}
run_exec () {
  run_default_exec
}
run_update () {
  run_default_update
}
run_autogen () {
  run_default_autogen
}
run_configure () {
  run_default_configure
}
run_make () {
  run_default_make
}
run_all () {
  run_default_all
}

###############################################

#
# main
#

onfailure() {
  echo Execution terminated due to errors!
  exit 1
}

usage () {
    echo "Usage: $0 [OPTIONS] COMMAND [COMMAND-OPTIONS]"
    echo ""
    echo "Execute COMMAND for all Dune modules."
    echo "Dependencies are controlled by the dune.module files."
    echo ""
    echo "Options:"
    echo "  -h, --help         show this help"
    echo "      --debug        enable debug output of this script"
    echo "      --opts=FILE    load default options from FILE (see dune-common/bin/example.opts)"
    echo "Commands:"
    echo "  \`help'"
    for i in $COMMANDS; do
      echo "  \`$i'"
    done
    echo
}

if test "x$1" == "x"; then
  usage
  exit 1
fi

trap onfailure EXIT

while test "x$1" != "x"; do
    # get option
    option=$1
    shift

    # get args
    set +e
    # stolen from configure...
    # when no option is set, this returns an error code
    arg=`expr "x$option" : 'x[^=]*=\(.*\)'`
    set -e

    # switch
    case "$option" in
    --opts=*)
      if test "x$arg" == "x"; then
        usage
        echo "ERROR: Parameter for --opts is missing"
        echo
        exit 1;
      fi
      OPTS_FILE=$(cd $(dirname $arg); pwd)/$(basename $arg)
      if ! test -r "$OPTS_FILE"; then
        usage
        echo "ERROR: could not read opts file \"$OPTS_FILE\""
        echo
        exit 1;
      fi
    ;;
    -h|--help) 
      command=help
      break
    ;;
    -p|--print) 
      command=print
      break
    ;;
    --module=*)
      if test "x$arg" == "x"; then
        usage
        echo "ERROR: Parameter for --module is missing"
        echo
        exit 1;
      fi
      MODULE=$arg
    ;;
    --debug) true ;;
    *)
      command=$option
      break
    ;;
    esac
done

while test "x$1" != "x"; do
  # setup paramter list
  CMD_PARAMS="$CMD_PARAMS \"$1\""
  shift
  # disable usage of opts file
  if test "x$OPTS_FILE" != "x"; then
    echo "WARNING: commandline parameters will overwrite setting in opts file \"$OPTS_FILE\""
  fi 
  OPTS_FILE=""
done

case "$command" in
  update | autogen | configure | make | all | exec | nothing)
    find_modules .
	if test "x$MODULE" = "x"; then
      sort_modules $MODULES
    else
      sort_modules $MODULE
    fi
    echo "--- going to build $MODULES ---"
      build_modules $command
    ;;
  print)
    find_modules .
	if test "x$MODULE" = "x"; then
      sort_modules $MODULES
    else
      sort_modules $MODULE
    fi
    echo $MODULES
    ;;
  help)
    usage
    ;;
  *)
    echo "ERROR: unknown command \"$command\""
    usage
    exit 1
    ;;
esac

trap - EXIT

echo done