Skip to content
Snippets Groups Projects
Forked from Core Modules / dune-common
7278 commits behind the upstream repository.
  • Markus Blatt's avatar
    9ff73a22
    · 9ff73a22
    Markus Blatt authored
    Fixed duplicate dependencies.
    
    Fixes Flyspray 198
    
    [[Imported from SVN: r4788]]
    9ff73a22
    History
    Markus Blatt authored
    Fixed duplicate dependencies.
    
    Fixes Flyspray 198
    
    [[Imported from SVN: r4788]]
duneproject 12.67 KiB
#!/bin/bash

#
# TODO:
#
# * In case of an installed Dune, it should not be necessary to pass the
#   dune-common dir to autogen.sh.
# * Check module names entered as dependencies.

set -e

canonicalname(){
  if test $# -ne 1; then
     echo Usage: canonicalname path > /dev/stderr
     return 1
  fi
  readlink $1 || echo "$(dirname $1)/$(basename $1)"
}

canonicalpath(){
  if test $# -ne 1; then
     echo Usage: canonicalpath path > /dev/stderr
     return 1
  fi
  (cd $(dirname $(canonicalname $1)) && pwd)
}

modulesexist(){
  allfound=0

  for dep in $1; do
      found=0
      for module in $2; do
	  if [ "$dep" = "$module" ]; then
	      found=1
	      break
	  fi
      done
      if [ "$found" = "0" ]; then
	  echo "ERROR:">/dev/stderr
	  echo "Module with name $dep was not found" > /dev/stderr
	  echo "Did you forget to specify it's location" > /dev/stderr
	  echo "in the DUNE_CONTROL_PATH variable?"> /dev/stderr
	  echo >/dev/stderr
	  allfound=1
      fi
  done
  return $allfound
}

make_unique(){
  if [ "$#" = "1" ]; then
      # take first word
      for exclude_word in $1; do
	  break;
      done
      make_unique $exclude_word "$1" 0
  else
      local exclude_word="$1"
      local words="$2"
      local pos="$3"
      local length=0
      local i=0
      local new_words=""
      local cur=0
      for word in $words; do
	  if [ $i -le $pos ]; then
	      i=$((i+1))
	      length=$((length+1))
	      new_words="$new_words $word"
	      continue
	  fi
	  if [ "$word" != "$exclude_word" ]; then
	      new_words="$new_words $word"
	      if [ "$((length-1))" = "$pos" ]; then
		  next_word="$word"
	      fi
	      length=$((length+1))
	  fi
      done
      if [ "$pos" -lt "$length" ]; then
       # process next word
	  make_unique "$next_word" "$new_words" $((pos+1))
      else
	  export UNIQUE_WORDS="$new_words"
      fi
  fi
}
       
echo
echo == Dune project/module generator ==
echo
echo duneproject will assist you in the creation of a new Dune application.
echo During this process a new directory with the name of your project will be
echo created. This directory will hold all configuration and Makefiles and a
echo simple example application.
echo

################## FIND AVAILABLE MODULES ##################

. $(canonicalpath $0)/dunemodules.inc

if [ "$MODULES" = "" ]; then
  find_modules_in_path
fi

if [ "$MODULES" = "" ]; then
  echo "ERROR">/dev/stderr
  echo "No dune modules were found!">/dev/stderr
  echo "Did you forget to specify the places where ">/dev/stderr
  echo "you installed your modules in the ">/dev/stderr
  echo "DUNE_CONTROL_PATH environment variable?" >/dev/stderr
  exit 1;
fi

# get the real module names
SRC_MODULES=""
for i in $MODULES; do
  mod=$(eval echo \$NAME_$i)
  SRC_MODULES="$SRC_MODULES $mod"
done

# get installed modules
PKG_MODULES="`pkg-config --list-all | grep dune | cut -d' ' -f1`"

# merge lists
ALL_MODULES="`echo $SRC_MODULES $PKG_MODULES | tr ' ' '\n' | sort | uniq`"

################## READ OPTIONS ##################

while [ "$DATACORRECT" != "y" -a "$DATACORRECT" != "Y" ]; do
  PROJECT=""
  while [ -z $PROJECT ]; do
    read -p "1) Name of your new Project? (e.g.: dune-grid): " PROJECT
    if echo "$ALL_MODULES" | grep -q ^$PROJECT$; then
      read -p "   A module named $PROJECT already exists. Continue anyway? [y/N] " CONT
      if test x$DELETE = xy -o x$DELETE = xY; then
        PROJECT=""
      fi
    fi
  done
  MODULE="$PROJECT"

  DEP_OK=1

  while [ "$DEPOK" != 0 ]; do
  DEPENDENCIES=""
  echo "2) Which modules should this module depend on?"
  echo "   Following modules are found:"
  for i in $ALL_MODULES; do echo -n " $i"; done
  echo ""
  while [ -z "$DEPENDENCIES" ]; do
      read -p "  Enter space separated list: " DEPENDENCIES
  done
  set +e
  modulesexist "$DEPENDENCIES" "$ALL_MODULES"
  DEPOK=$?
  set -e
  done

  VERSION=""
  while [ -z $VERSION ]; do
    read -p "3) Project/Module version? " VERSION
  done
  MAINTAINER=""
  while [ -z $MAINTAINER ]; do
    read -p "4) Maintainers email address? " MAINTAINER
  done

  echo
  echo "creating Project \"$PROJECT\", version $VERSION "
  echo "which depends on \"$DEPENDENCIES\""
  echo "with maintainer \"$MAINTAINER\""
  read -p "Are these informations correct? [y/N] " DATACORRECT
done

echo
echo "A sample code $MODULE.cc is generated in the \"$PROJECT\" directory."
echo "Look at the README and dune.module files there."
echo "Now you can run dunecontrol script which will setup the new module."
echo "Sometimes you may have to tweak configure.ac a bit."

if test -d $PROJECT; then
  echo WARNING:
  echo "A directory with the name $PROJECT already exists."
  echo "Do you want to continue anyway?"
  read -p "Type Y to overwrite the old directory, N to abort. [y/N] " DELETE
  if test x$DELETE != xy -a x$DELETE != xY; then
    echo Abort...
    exit 1
  fi
  rm -rf "$PROJECT"
fi
mkdir "$PROJECT"

################## dune.module ##################
cat > "$PROJECT/dune.module" <<C_DELIM

#dune module information file#
##############################

#Name of the module
Module:$MODULE
#depending on 
Depends:$DEPENDENCIES
C_DELIM

################## CONFIGURE.AC ##################

## Create the parameters passed to DUNE_CHECK_ALL
j=0
# save module list of dunemodules.inc
save_MODULES=$MODULES
for name in $DEPENDENCIES; do
  mod="`fix_variable_name $name`"
  if test "x$(eval echo \$HAVE_$mod)" != "x"; then
    # found via dunemodules.inc
    sort_modules "$mod"
    for mod in $MODULES; do
      M_DEPS="$M_DEPS $(eval echo \$NAME_$mod)"
    done
    MODULES=$save_MODULES
  else
    # found via pkg-config
    M_DEPS="`pkg-config --variable=Requires $name`"
  fi
  for dep in $M_DEPS; do
    if [ "$j" = "0" ]; then
      CHECK="[$dep]"
      j=1
    else
      CHECK="$CHECK [$dep]"
    fi
  done
done


make_unique "$CHECK"
CHECK=`echo $UNIQUE_WORDS| sed -e 's/\] \[/\], \[/g'`
# we need the module with _ instead of - to not confuse automake
fix_and_assign CMODULE $MODULE

cat > "$PROJECT/configure.ac" <<C_DELIM
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.50)
AC_INIT($PROJECT, $VERSION, $MAINTAINER)
AM_INIT_AUTOMAKE($PROJECT, $VERSION, $MAINTAINER)
AC_CONFIG_SRCDIR([$CMODULE.cc])
AM_CONFIG_HEADER([config.h])


# we need no more than the standard DE-stuff
# this module depends on $DEPENDENCIES
# this implies checking for $CHECK
DUNE_CHECK_ALL($CHECK)

# implicitly set the Dune-flags everywhere
AC_SUBST(AM_CPPFLAGS, \$DUNE_CPPFLAGS)
AC_SUBST(AM_LDFLAGS, \$DUNE_LDFLAGS)
LIBS="\$DUNE_LIBS"

AC_CONFIG_FILES([Makefile])
AC_OUTPUT
# finally print the summary information
DUNE_SUMMARY_ALL
C_DELIM

################## AUTOGEN.SH ##################
cat > "$PROJECT/autogen.sh" <<A_DELIM
#!/bin/sh
# $Id$

# barf on errors
set -e

usage () {
    echo "Usage: ./autogen.sh [options]"
    echo "  --ac=, --acversion=VERSION   use a specific VERSION of autoconf"
    echo "  --am=, --amversion=VERSION   use a specific VERSION of automake"
    echo "  -h,    --help                you already found this :-)"
}

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

    case "\$OPT" in
	--ac=*|--acversion=*)
			if test "x\$arg" = "x"; then
				usage; 
				exit 1;
			fi
			ACVERSION=\$arg
			;;
	--am=*|--amversion=*)
			if test "x\$arg" = "x"; then
				usage; 
				exit 1;
			fi
			AMVERSION=\$arg
			;;
	-h|--help) usage ; exit 0 ;;
	*)
            if test -d "\$OPT/m4"; then
              ACLOCAL_FLAGS="\$ACLOCAL_FLAGS -I \$OPT/m4"
            fi
            if test -d "$OPT/share/aclocal"; then
              ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I $OPT/share/aclocal"
            fi
            if test -d "\$OPT/am"; then
              am_dir="\$OPT/am"
            fi
            ;;
    esac
done

## report parameters
if test "x\$ACVERSION" != "x"; then
	echo "Forcing autoconf version \$ACVERSION"
	if ! which autoconf\$ACVERSION > /dev/null; then
		echo
		echo "Error: Could not find autoconf\$ACVERSION"
		echo "       Did you specify a wrong version?"
		exit 1
	fi
fi
if test "x\$AMVERSION" != "x"; then
	echo "Forcing automake version \$AMVERSION"
	if ! which automake\$AMVERSION > /dev/null; then
		echo
		echo "Error: Could not find automake\$AMVERSION"
		echo "       Did you specify a wrong version?"
		exit 1
	fi
fi


## run autotools

echo "--> libtoolize..."
# this script won't rewrite the files if they already exist. This is a
# PITA when you want to upgrade libtool, thus I'm setting --force
libtoolize --force

# prepare everything
echo "--> aclocal..."
aclocal\$AMVERSION \$ACLOCAL_FLAGS

# applications should provide a config.h for now
echo "--> autoheader..."
autoheader\$ACVERSION

# create a link to the dune-common am directory
echo "--> linking dune-common/am..."
rm -f am
ln -s \$am_dir am

# call automake/conf
echo "--> automake..."
automake\$AMVERSION --add-missing

echo "--> autoconf..."
autoconf\$ACVERSION

## tell the user what to do next
echo "Now run ./configure "

A_DELIM

chmod +x "$PROJECT/autogen.sh"

################## README ##################
cat > "$PROJECT/README" <<R_DELIM
Preparing the Sources
=========================

Additional to the software mentioned in README you'll need the
following programs installed on your system:

  automake >= 1.5

  autoconf >= 2.50

  libtool

Getting started
---------------

If these preliminaries are met, you should run the script

  ./autogen.sh

which calls the GNU autoconf/automake to create a ./configure-script
and the Makefiles. Most probably you'll have to provide where to find
the DUNE-files by

   ./autogen.sh --with-dune=PATH

where PATH is a directory with a dune/-subdirectory inside (this
convention is needed to keep the #include-syntax consistent even when
the headers are installed into /usr/include/dune later).


Passing options to ./configure
------------------------------

autogen.sh also calls the newly created configure-script to
conveniently pass on options about the used compiler. Thus you'll have
to provide autogen.sh any options you want configure to get, e.g.

  ./autogen.sh --with-dune=... --with-albert=... --without-x


Choosing the compiler and the options
-------------------------------------

The selection of the compiler works as follows: if --gnu or --intel is
passed to autogen it reads the content of gcc.opts or icc.opts to get
the default compiler flags. With the option --optim you can switch the
compiler-specific optimization parameters on.

If you want to change the compiler options to your favourites you can
either

 - adapt the appropriate .opts-file and rerun autogen.sh. Please don't
   commit this changed file to CVS if you're not sure if the options
   work for everybody.

 - copy an existing .opts-file to a new name, change the options and
   use

      ./autogen.sh --opts=my.opts


More info
---------

See

     ./autogen.sh --help
   
and (if it exists)
 
     ./configure --help

for further options.


The full build-system is described in the dune/doc/Buildsystem (not in
duneapps/doc!)

\$Id$

R_DELIM

################## MAKEFILE.AM ##################
cat> "$PROJECT/Makefile.am" << M_DELIM
# \$Id$

# we need the module file to be able to build via dunecontrol
EXTRA_DIST=dune.module

# possible options
#LDADD = \$(UG_LDFLAGS) \$(AMIRAMESH_LDFLAGS) \$(UG_LIBS) \$(AMIRAMESH_LIBS)
#AM_CPPFLAGS = \$(UG_CPPFLAGS) \$(AMIRAMESH_CPPFLAGS)

noinst_PROGRAMS = ${CMODULE}

${CMODULE}_SOURCES = $CMODULE.cc

${CMODULE}_CXXFLAGS = \$(MPI_CPPFLAGS) \$(UG_CPPFLAGS) \$(AMIRAMESH_CPPFLAGS) \$(ALBERTA_CPPFLAGS)
${CMODULE}_LDADD = \$(MPI_LDFLAGS) \$(ALBERTA_LDFLAGS) \$(ALBERTA_LIBS) \$(AMIRAMESH_LDFLAGS) \$(AMIRAMESH_LIBS) \$(UG_LDFLAGS) \$(UG_LIBS) \$(MPI_LDFLAGS) \$(DUNE_LDFLAGS) \$(DUNE_LIBS)

# don't follow the full GNU-standard
# we need automake 1.5
AUTOMAKE_OPTIONS = foreign 1.5
# pass most important options when "make distcheck" is used
DISTCHECK_CONFIGURE_FLAGS = --with-dune=\$(DUNEROOT) CXX="\$(CXX)" CC="\$(CC)"
M_DELIM

################## PROJECT.CC ##################
cat> "$PROJECT/$CMODULE.cc" << CC_DELIM
#ifdef HAVE_CONFIG_H
# include "config.h"     
#endif
#include <iostream>
#include"dune/common/mpihelper.hh" // An initializer of MPI
#include"dune/common/exceptions.hh" // We use exceptions

int main(int argc, char** argv)
{
  try{
    //Maybe initialize Mpi
    Dune::MPIHelper& helper = Dune::MPIHelper::instance(argc, argv);
    std::cout << "Hello World! This is ${PROJECT}." << std::endl;
    if(Dune::MPIHelper::isFake)
      std::cout<< "This is a sequential program." << std::endl;
    else
      std::cout<<"I am rank "<<helper.rank()<<" of "<<helper.size()
        <<" processes!"<<std::endl;
    return 0;
  }
  catch (Dune::Exception &e){
    std::cerr << "Dune reported error: " << e << std::endl;
  }
  catch (...){
    std::cerr << "Unknown exception thrown!" << std::endl;
  }
}
CC_DELIM