#!/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 } 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 # 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 DUNE-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