#!/usr/bin/env perl
# ACL:license
#  ----------------------------------------------------------------------
#  This software and ancillary information (herein called "SOFTWARE")
#  called POOMA (Parallel Object-Oriented Methods and Applications) is
#  made available under the terms described here.  The SOFTWARE has been
#  approved for release with associated LA-CC Number LA-CC-98-65.
#  
#  Unless otherwise indicated, this SOFTWARE has been authored by an
#  employee or employees of the University of California, operator of the
#  Los Alamos National Laboratory under Contract No.  W-7405-ENG-36 with
#  the U.S. Department of Energy.  The U.S. Government has rights to use,
#  reproduce, and distribute this SOFTWARE, and to allow others to do so.
#  The public may copy and use this SOFTWARE, FOR NONCOMMERCIAL USE ONLY,
#  without charge, provided that this Notice and any statement of
#  authorship are reproduced on all copies.  Neither the Government nor
#  the University makes any warranty, express or implied, or assumes any
#  liability or responsibility for the use of this SOFTWARE.
#  
#  If SOFTWARE is modified to produce derivative works, such modified
#  SOFTWARE should be clearly marked, so as not to confuse it with the
#  version available from LANL.
#  
#  For more information about POOMA, send e-mail to pooma@acl.lanl.gov,
#  or visit the POOMA web page at http://www.acl.lanl.gov/pooma/.
#  ----------------------------------------------------------------------
# ACL:license

###########################################################################
#
# POOMA configuration
#
# This script is used to configure POOMA to be built for a specific
# platform and compiler with selected options.  It will generate the
# necessary files for the make system to compile the POOMA library.
# To use configure:
#
# 1. Decide which type of architecture you wish to build.  The
#    possible architectures are listed in the config/arch/ directory, as
#    *.conf.  For example, SGI64-KCC.conf is for building a 64-bit
#    library on SGI machines with the KCC compiler.
#
# 2. Edit the config/arch/<arch>.conf file, to correctly set the location
#    of the various packages that POOMA must include or link with.
#    You should only have to change path and library names, you should
#    not have to change any other settings in the conf file.
#
# 3. In the top-level of the POOMA directory, run configure as:
#
#       configure [--arch <arch> ] [--suite <suite>] [options]
#
#    where <arch> is the name of the <arch>.conf file you selected.  The
#    possible options may be found by running configure with no
#    arguments or with a --help argument.  If you do not specify --arch,
#    the current value of the POOMASUITE env var will be used.  If you do
#    not specify --suite, POOMASUITE will be used, unless it is not set, in
#    which case the value of <arch> will also be used for <suite>.
#
# 4. After running configure, you will have a new 'suite' file in the
#    config directory.  Set the POOMASUITE environment variable to this
#    suite name, and type 'make' (where make is the name of your GNU
#    make program, as POOMA requires GNU make in its build system).
#
###########################################################################


###########################################################################
#
# The default version number.  If the file "VERSION.NUM" exists, the
# version number found there (in the format MAJOR.MINOR.PATCH) will be
# used, otherwise the version number will be MAJOR.MINOR.devel.
# The procedure getversionnum is what tries to get version info from
# the version file.
#
###########################################################################

# set default values
$projectname  = "pooma";
$majorversion = 2;
$minorversion = 2;
$patchlevel   = "devel";
$versionfile  = "VERSION.NUM";


###########################################################################
#
# print out a welcome banner right away
#
###########################################################################

print "-" x 78 . "\n";
print "                     *** POOMA configuration utility ***\n";
print "Command: configure @ARGV\n";
print "-" x 78 . "\n";


###########################################################################
#
# Important configuration utility settings: filenames, etc.
#
###########################################################################

### the name of the make program
$makecmd         = gmake;

### the directory of the config and arch files, and the archfile extension
$configsuitedir  = "config";
$configarchdir   = "config/arch";
$archfileext     = ".conf";
$suitefileext    = ".suite.mk";

### the base name of the version header file produced by this script
$versionheaderbase = "PoomaConfiguration";
$versionheader     = "$versionheaderbase.h";

### the base name of the Makefile stub that application builders include
$makefilestub = "Makefile.pooma";

### date, user, machine settings used to print out values in files
$cmdstr  = "configure @ARGV";
$datestr = `date`;     chomp($datestr);
$userstr = `whoami`;   chomp($userstr);
$hoststr = `hostname`; chomp($hoststr);
$dirstr  = `pwd` ;     chomp($dirstr);

### Available schedulers for the Smarts system ... the --sched argument
### must select one from the schedulerlist set of names.

%schedulerhash = ();
%schedulerblockhash = ();
%schedulernamehash = ();

sub addScheduler {
  my ($hash, $name, $block) = @_;

  $schedulerhash{$hash} = $name;
  $schedulerblockhash{$hash} = $block;
  $schedulernamehash{$name} = 0;
}

addScheduler( "sync", "ASYNC", "POOMA_TRUE" );
addScheduler( "async", "ASYNC", "POOMA_FALSE" );
addScheduler( "serialAsync", "SERIALASYNC", "POOMA_FALSE" );
addScheduler( "mcveMultiQ", "MCVE_MULTIQ", "POOMA_FALSE" );

$schedulerdefault = "mcveMultiQ";

###########################################################################
#
# Create a list of possible command-line arguments, with their characteristics.
#
###########################################################################

### string names for the command-line arguments.  Put them in variables here
### so that they can be easily changed in the future.  The convention for
### the names is:
###   --name : an option to control how POOMA should be built
###   -name (generally a single char) : an option for how configure works

### POOMA options
$archnm = "--arch";
$suitenm = "--suite";
$prefixnm = "--prefix";
$serialnm = "--serial";
$threadsnm = "--threads";
$profilenm = "--profile";
$insurenm = "--insure";
$debugnm = "--debug";
$optnm = "--opt",
$exnm = "--ex";
$noexnm = "--noex";
$incnm = "--inc";
$defnm = "--def";
$cppnm = "--cpp";
$cppargnm = "--cpparg";
$cnm = "--c";
$cargnm = "--carg";
$f77nm = "--f77";
$f77argnm = "--f77arg";
$arnm = "--ar";
$arargnm = "--ararg";
$linknm = "--link";
$linkargnm = "--linkarg";
$verbosenm = "--v";
$noverbosenm = "--q";
$onepernm = "--oneper";
$noonepernm = "--nooneper";
$schednm = "--sched";
$boundsnm = "--bounds";
$preinstnm = "--preinst";
$printdbgnm = "--printdebug";
$finternm = "--with-fortran";
$nofinternm = "--without-fortran";
$purifynm = "--purify";
$staticnm = "--static";
$sharednm = "--shared";
$pawsnm = "--paws";
$pawsdevnm = "--pawsdev";
$poolyesnm = "--pool";
$poolnonm = "--no-pool";
$luxnm = "--lux";
$hdf5nm = "--hdf5";
$fftwnm = "--fftw";
$cheetahnm = "--messaging";
$strictnm = "--strict";
$archfnsnm = "--arch-specific-functions";

### configure options
$dbgprntnm = "-v";		# turn on verbose output from configure
$overwritenm = "-f";		# force overwrite of files
$nooverwritenm = "-i";		# force check of whether to overwrite files
$helpnm = "-h";	   	        # print out help message and exit
$questionnm = "-?";	        # print out help message and exit

### the list of possible command-line arguments and default values
### for each element in the list, give:
###   1. name of command-line argument
###   2. 1 if can have multiple values, 0 if it cannot
###   3. name of argument (empty if none),
###   4. description of argument.
### some items can have multiple values (so specifying the argument more than
### once will just add to a list).  If it is single-valued, only the first
### value specified will be used.
@arglist = (
  [$archnm,      "<arch>",   "the basic architecture to configure for."],
  [$suitenm,     "<suite>",  "use <suite> as suite file (def=<arch>)."],
  [$prefixnm,    "<dir>",    "install files under directory <dir>."],
  [$staticnm,    "",         "create a static library (default)."],
  [$sharednm,    "",         "create a shared library."],
  [$finternm,    "",         "include fortran support libraries."],
  [$nofinternm,  "",         "do not include the fortran libraries."],
  [$preinstnm,   "",         "build preinstantiations of several classes."],
  [$serialnm,    "",         "configure to run serially, no parallelism."],
  [$threadsnm,  "",         "include threads capability, if available."],
  [$cheetahnm,   "",         "enable use of CHEETAH communications package."],
  [$schednm,     "<scheduler>", "use <scheduler> for thread scheduling."],
  [$pawsnm,      "",         "enable PAWS program coupling, if available."],
  [$pawsdevnm,   "",         "enable PAWS program coupling for PAWS devel."],
  [$luxnm,       "",         "enable use of LUX visualization package."],
  [$hdf5nm,      "",         "enable use of the HDF5 package."],
  [$fftwnm,      "",         "enable use of the FFTW package."],
  [$profilenm,   "",         "use TAU automatic profiling, if available."],
  [$insurenm,    "",         "use Insure++ code checking, if available."],
  [$purifynm,    "",         "use Purify code checking, if available."],
  [$boundsnm,    "",         "turn on bounds checking for indexing operations."],
  [$debugnm,     "",         "by default, make will build debug library."],
  [$optnm,       "",         "by default, make will build optimized library."],
  [$strictnm,    "",         "enable ANSI conformance checking by compiler."],
  [$printdbgnm,  "",         "enable ability to print debug messages."],
  [$exnm,        "",         "enable use of exceptions, if available."],
  [$noexnm,      "",         "disable use of exceptions."],
  [$verbosenm,   "",         "enable verbose output from compiler/linker."],
  [$noverbosenm, "",         "disable verbose output from compiler/linker."],
  [$onepernm,    "",         "enable use of one-per option (if available)."],
  [$noonepernm,  "",         "disable use of one-per option (if available)."],
  [$poolyesnm,   "",         "enable use of the Pooled class for mem alloc."],
  [$poolnonm,    "",         "disable use of the Pooled class for mem alloc."],
  [$archfnsnm,   "",         "enable the use of arch-specific init functions."],
  [$incnm,       "<inc>",    "include <inc> statement in compile arguments."],
  [$defnm,       "<def>",    "include <def> define in compile arguments."],
  [$cppnm,       "<comp>",   "use <comp> for the C++ compiler."],
  [$cppargnm,    "<args>",   "include <args> in the C++ compiler args."],
  [$cnm,         "<comp>",   "use <comp> for the C compiler."],
  [$cargnm,      "<args>",   "include <args> in the C compiler args."],
  [$f77nm,       "<comp>",   "use <comp> for the F77 compiler."],
  [$f77argnm,    "<args>",   "include <args> in the F77 compiler args."],
  [$arnm,        "<ar>",     "use <ar> for the library archiver."],
  [$arargnm,     "<args>",   "include <args> in the archiver args."],
  [$linknm,      "<linker>", "use <linker> for the linker application."],
  [$linkargnm,   "<args>",   "include <args> in the linker args."],
  [$dbgprntnm,   "",         "turn on verbose output from configure."],
  [$nooverwritenm, "",       "force check of whether to overwrite files."],
  [$overwritenm, "",         "force overwrite of all files."],
  [$helpnm,      "",         "display this help message."],
  [$questionnm,  "",         "display this help message."],
);

### create a hash of the arguments, where we will store results.  Each
### argument entry has an array of scalars, where the first scalar is
### the name of the required argument (if any), and the
### rest of the list is the set of values for the argument.
%arghash = ();
for $i (0 .. $#arglist)
{
  my @arginfo = @{$arglist[$i]};
  $arghash{$arginfo[0]} = [ $arginfo[1] ];
}


###########################################################################
#
# Intialize variables that will store the actual values of the settings
# for use in creating the make files.  After parsing the command-line
# arguments, a file 'config/arch/<arch>.conf' is run as a perl script to set
# the values of these variables to any other settings necessary for that
# platform.  So within the <arch>.conf file, include perl commands to change
# the values of these variables when necessary (except for arch and suite).
# After the arch file is run, the command-line args will be used to modify
# the settings.
#
###########################################################################

### configure options
$dbgprnt = 0;
$overwrite = 1;

### our architecture name
$arch = "";
$archfile = "";
$archtype = "";

### our base suite name, and the suite filename
$suite = "";
$suitefile = "";

### the library extensions
$libext     = "a";

### should a shared library be built?
$canmakesharedlib = 0;
$shared = 0;
$sharedext = "so";

### the prefix for the installation directory
$prefix = $dirstr . "/build/$versiontag";

### extensions to add to the name of the library and makefile stub file
$extensions = "";
$compext    = "";

### build with preinstantiations?
$preinstantiate = 0;

### extra prelink step?
$prelinkstep = 0;
$prelink = "";
$prelinkargs = "";

### template instantiation repository?
$instrepo = 0;
$instantiationdir = "";

### build debug by default?  If not, build optimized by default instead.
$debug = 1;

### strict ANSI conformance checking?
$strict = 0;
$strictdefs = "";
$cppstrict = "";
$arstrict = "";
$arsharestrict = "";

### enable the ability to print debug information
$printdebug = 0;

### should the fortran libraries be included?
$finterface = 0;

### should the Pooled class be used?
$pool = 1;

### special characteristics that some architectures have
$no_stringstream = 0;		# if 1, lacks <stringstream> header
$no_complete_iomanips = 0;	# if 1, missing some IO manipulators (left etc)
$no_templated_friends = 0;	# if 1, cannot use template classes as friends
$no_ostream_iterator_1arg = 0;	# if 1, cannot use ostream_iterator w/1 param
$no_restrict = 0;		# if 1, does not allow 'restrict' keyword
$no_placement_delete = 0;       # if 1, does not allow placement delete opers
$no_dependent_templ_args = 0;   # if 1, has problems with dep template args
$small_dim_specializations = 0;	# if 1, include extra specializations for <dims
$no_templated_complex = 0;      # if 1, complex is not templated
$no_std_complex = 0;            # if 1, complex is not in std:: namespace
$o_binary_open_mode = 0;        # if 1, O_BINARY is defined
$no_std_iosbase = 0;            # if 1, does not have std::ios_base class
$inc_sys_stat_h_file_modes = 0; # if 1, must include <sys/stat.h> for file modes

### default settings for source code options like data types and bounds checks
$default_float_type               = "double";
$default_element_type             = $default_float_type;
$default_position_type            = $default_float_type;
$default_engine_type              = "Brick";
$default_bounds_checking          = "POOMA_FALSE";
$default_smarts_hardinit          = "POOMA_TRUE";
$default_smarts_hardrun           = "POOMA_FALSE";
$default_smarts_lockthreads       = "POOMA_FALSE";
$default_blocking_expressions     = $schedulerblockhash{$schedulerdefault};

### include PAWS usage?  Either paws or pawsdev can be used, they differ
### only in how the Makefile info is included and used.  Only one can be
### used.  If pawsdev is used, PAWS_ROOT and PAWS_ARCH env vars should be
### set (they are examined to find the PAWS directory and makefile).
$paws = 0;
$pawsdev = 0;
$paws_able = 0;
$paws_dir = "";
$paws_default_dir = "";
$paws_lib_subdir = "";
$paws_makefile = "";

### include HDF5 usage?
$hdf5 = 0;
$hdf5_able = 0;
$hdf5_default_dir = "";

### include fftw usage?
$fftw = 0;
$fftw_able = 0;
$fftw_default_dir = "";

### include cheetah usage?
$cheetah = 0;
$cheetah_able = 0;
$cheetah_arch = "";
$cheetah_default_dir = "";
$cheetah_lib_subdir = "";
$cheetah_include_makefile = "";

### special compiler script for compiling with cheetah?
$cheetah_compiler_script = 0;
$cheetah_cpp = "";
$cheetah_ar = "";
$cheetah_link = "";

### include LUX usage?
$lux = 0;
$lux_able = 0;
$lux_default_dir = "";
$lux_lib_subdir = "";
$lux_makefile = "";

### include threads capability?
$threads = 0;
$threads_able = 0;
$threads_dir = "";
$threads_default_dir = "";
$threads_basic_makefile = "";
$threads_profile_makefile = "";
$threads_include_makefile = "";
$cpp_threads_arg = "";

### if threads is used, what scheduler should be employed?
$scheduler = $schedulerdefault;

### use profiling?
$profile = 0;
$profile_able = 0;
$profile_inc = "";
$profile_def = "";
$profile_lib = "";

### use Purify?
$purify = 0;
$purify_able = 0;

### use Insure++?
$insure = 0;
$insure_able = 0;
$cppinsure = "";
$cinsure = "";
$cpp_insure_run = "";
$cpp_insure_arg = "";
$c_insure_run = "";
$c_insure_arg = "";
$ar_insure_run = "";
$ar_insure_arg = "";
$ld_insure_run = "";
$ld_insure_arg = "";

### use exceptions?
$exceptions = 0;
$cppex = "";
$cppnoex = "";

### do bounds checking?
$bounds_checking = 0;

### enable arch-specific functions
$archfns = 0;

### use verbose output from compiler/linker?
$verbose = 0;

### use one-per option, if available?
$oneper = 0;

### the name and arguments for the C++ compiler
$cpp = "";
$cppargs = "";
$cppshare = "";
$cppopt_lib = "";
$cppopt_app = "";
$cppdbg_lib = "";
$cppdbg_app = "";

### the name and arguments for the C compiler
$c = "";
$cargs = "";
$cshare = "";
$copt_lib = "";
$copt_app = "";
$cdbg_lib = "";
$cdbg_app = "";

### the name and arguments for the F77 compiler
$f77 = "";
$f77args = "";
$f77share = "";
$f77libs = "";
$f77opt_lib = "";
$f77opt_app = "";
$f77dbg_lib = "";
$f77dbg_app = "";

### the name and arguments for the library archiver for the C++ libraries
$ar = "";
$arargs = "";
$arshare = "";
$arshareargs = "";

### the name and arguments for the linker for applications
$link = "";
$linkargs = "";
$linkshare = "";

### libraries and lib dirs for compilation (-l and -L statements)
$preliblist = "";		# with -L and -l statements, for start of list
$midliblist = "";		# with -L and -l statements, for middle of list
$postliblist = "";		# with -L and -l statements, for end of list

### include dirs for compilation (-I statements)
$inclist = "";			# with -I statements

### list of statements that should be made into #define statements in header
@deflist = ();			# should be of form name[=value]

### list of defines that should be surrounded by #ifndef checks
@protecteddeflist = ();

### list of -D define statements that should go with each compilation
$defines = "";


###########################################################################
#
# Utility procedures for use in this script.
#
###########################################################################

### a procedure which will print out a usage message and exit
sub printusage
{
  print "Usage: configure $archnm <arch> [OPTIONS]\n";
  print "  where $archnm and [OPTIONS] are:\n";
  for $i (0 .. $#arglist)
  {
    my @arginfo = @{$arglist[$i]};
    my $outstring = $arginfo[0];
    my $desc = $arginfo[2];
    if ($arginfo[1])
    {
      $outstring .= " $arginfo[1]";
    }
    my $dots = 77 - (length $outstring) - (length $desc);
    print $outstring . " " . "." x $dots . " $desc\n";
  }

  print "\n";
  print "If --threads, --sched can select the thread scheduler from:\n";
  print join ' ', (keys %schedulerhash);
  print "  (default is $schedulerdefault)\n";
  print "\n";
  print "If conflicting arguments are given, it is an error.  If the\n";
  print "--arch option is not given, the current value of POOMASUITE will be\n";
  print "used (if POOMASUITE is not set in this case, it is an error).  If the\n";
  print "--suite option is not given, <suite> will be set to the <arch>\n";
  print "value, unless the POOMASUITE environment variable is set.\n";
  print "\n";
  print "For profiling, you may need to set env vars TAUDIR and PDTDIR\n";


  exit(1);
}


### a procedure to print an error message and quit
sub printerror
{
  if (@_)
    {
      print "\nERROR: @_\n\n";
    }
  printusage;
}


### print out final instructions
sub printinstructions
{
  print "-" x 78 . "\n";
  print "Configuration complete.  To build POOMA:\n";
  print "  1. Set environment variable POOMASUITE to the suite name '$suite'.\n";
  print "  2. Type 'make'.\n";
  print "-" x 78 . "\n";
}


### a procedure to set the version number, possibly from a file, otherwise
### use default settings
sub getversionnum
{
  my $majversionm;
  my $projectnm;

  # try to read in values from file, if it is available
  if (-f $versionfile)
    {
      $verstring = `cat $versionfile`; chomp($verstring);
      print "Read verstring = $verstring\n" if $dbgprnt;
      ($majversionnm, $minorversion, $patchlevel) = split /\./, $verstring, 3;
      ($projectnm, $majorversion) = split /-/, $majversionnm, 2;
      print "Read majorversion = $majorversion\n" if $dbgprnt;
      print "Read minorversion = $minorversion\n" if $dbgprnt;
      print "Read patchlevel = $patchlevel\n" if $dbgprnt;
    }

  # set the two strings with the version information
  $version       = "POOMA $majorversion.$minorversion.$patchlevel";
  $versionnumstr = "$majorversion.$minorversion.$patchlevel";
  $versiontag    = $projectname . "-" . $versionnumstr;
  print "Using version string = '$version'\n" if $dbgprnt;
  print "Using version tag = '$versiontag'\n" if $dbgprnt;

  # reset the prefix for the installation directory
  $prefix = $dirstr . "/build/$versiontag";
}


### if the second argument is true, add a define to our list of the form
### FIRSTARG=POOMA_YES; otherwise, add it as FIRSTARG=POOMA_NO
sub add_yesno_define
{
  my ($argstring, $argtest) = @_;
  if (not $argstring)
    {
      die "Error in add_yesno_define: must supply two arguments.\n";
    }
  if ($argtest)
    {
      $argstring .= "=POOMA_YES";
    }
  else
    {
      $argstring .= "=POOMA_NO";
    }
  print "  Adding final yes/no define string = $argstring.\n" if $dbgprnt;
  push @deflist, $argstring;
}


### if the second argument is true, add a define to our list of the form
### FIRSTARG=POOMA_YES; otherwise, add it as FIRSTARG=POOMA_NO
### Same as add_yesno_define, except protected
sub add_protected_yesno_define
{
  my ($argstring, $argtest) = @_;
  if (not $argstring)
    {
      die "Error in add_yesno_define: must supply two arguments.\n";
    }
  if ($argtest)
    {
      $argstring .= "=POOMA_YES";
    }
  else
    {
      $argstring .= "=POOMA_NO";
    }
  print "  Adding final yes/no define string = $argstring.\n" if $dbgprnt;
  push @protecteddeflist, $argstring;
}


### add in a define of the form FIRSTARG[=SECONDARG]
sub add_string_define
{
  my ($argstring, $argtest) = @_;
  if (not $argstring)
    {
      die "Error in add_string_define: must supply two arguments.\n";
    }
  if (length $argtest > 0)
    {
      $argstring .= "=$argtest";
    }
  print "  Adding define string = $argstring.\n" if $dbgprnt;
  push @deflist, $argstring;
}


### add in a protected define of the form FIRSTARG[=SECONDARG]
sub add_protected_string_define
{
  my ($argstring, $argtest) = @_;
  if (not $argstring)
    {
      die "Error in add_protected_string_define: must supply two arguments.\n";
    }
  if (length $argtest > 0)
    {
      $argstring .= "=$argtest";
    }
  print "  Adding protected define string = $argstring.\n" if $dbgprnt;
  push @protecteddeflist, $argstring;
}


### a procedure which will parse the command-line arguments and set the
### values in arglist
sub parseargs
{
  my @argvlist = @ARGV;
  while (@argvlist)
    {
      my $arg = $argvlist[0];
      if (exists $arghash{$arg})
	{
	  my $argval = 1;
	  if ($arghash{$arg}[0])
	    {
	      shift @argvlist;
	      if (@argvlist)
		{
		  $argval = $argvlist[0];
		}
	      else
		{
		  printerror "You must provide a value for $arghash{$arg}[1]";
		}
	    }
	  print "Found argument $arg, value $argval.\n" if $dbgprnt;
	  push @{$arghash{$arg}}, $argval;
	}
      else
	{
	  printerror "Unknown command-line argument \"$arg\".";
	}
      shift @argvlist;
    }
}


### a procedure to examine the values read from the command-line variables
### and get the arch and suite values, after which we read the arch input
### file.
sub getarchsuite
{
  # get architecture, which is required
  if (scalar @{$arghash{$archnm}} > 1)
    {
      $arch = $arghash{$archnm}[1];
    }
  elsif (exists $ENV{"POOMASUITE"})
    {
      $arch = $ENV{"POOMASUITE"};
    }
  elsif (exists $ENV{"SUITE"})
    {
      $arch = $ENV{"SUITE"};
    }
  else
    {
      printerror "You must specify an architecture with $archnm <arch>";
    }
  $archfile = $configarchdir . "/" . $arch . $archfileext;
  -r $archfile or die "Cannot find architecture file $archfile.";
  print "Got arch = $arch, archfile = $archfile\n" if $dbgprnt;

  # get suite name; if it is not provided, use the value of $arch, unless
  # the POOMASUITE env var is set, in which case that should be used
  if (scalar @{$arghash{$suitenm}} > 1)
    {
      $suite = $arghash{$suitenm}[1];
    }
  elsif (exists $ENV{"POOMASUITE"})
    {
      $suite = $ENV{"POOMASUITE"};
    }
  elsif (exists $ENV{"SUITE"})
    {
      $suite = $ENV{"SUITE"};
    }
  else
    {
      $suite = $arch;
    }
  $suitefile = $configsuitedir . "/" . $suite . $suitefileext;
  print "Got suite = $suite, suitefile = $suitefile\n" if $dbgprnt;

  # try to run the perl commands in the arch file
  -r $archfile or die "Cannot read architecture file $archfile: $!\n";
  print "Reading architecture information from $archfile ...\n";
  require $archfile;
}


### a procedure to reset variables based on the command-line parameters,
### and to set up other default values of compile parameters.
sub setvariables
{
  # get installation directory name, if given
  if (scalar @{$arghash{$prefixnm}} > 1)
    {
      $prefix = $arghash{$prefixnm}[1];
    }

  # reset names of compilers and applications, if necessary
  if (scalar @{$arghash{$cppnm}} > 1)
    {
      $cpp = $arghash{$cppnm}[1];
    }
  else
    {
      $extensions .= $compext;
    }

  if (scalar @{$arghash{$cnm}} > 1)
    {
      $c = $arghash{$cnm}[1];
    }

  if (scalar @{$arghash{$f77nm}} > 1)
    {
      $f77 = $arghash{$f77nm}[1];
    }

  if (scalar @{$arghash{$arnm}} > 1)
    {
      $ar = $arghash{$arnm}[1];
    }

  if (scalar @{$arghash{$linknm}} > 1)
    {
      $link = $arghash{$linknm}[1];
    }

  # add in extra include and define statements
  for $i (1 .. $#{$arghash{$incnm}})
    {
      $inclist .= " -I$arghash{$incnm}[$i]";
    }
  for $i (1 .. $#{$arghash{$defnm}})
    {
      $defines .= " -D$arghash{$defnm}[$i]";
    }
  
  # add in all extra compiler args specified on command line
  for $i (1 .. $#{$arghash{$cppargnm}})
    {
      $cppargs .= " $arghash{$cppargnm}[$i]";
    }
  for $i (2 .. $#{$arghash{$cargnm}})
    {
      $cargs .= " $arghash{$cargnm}[$i]";
    }
  for $i (2 .. $#{$arghash{$f77argnm}})
    {
      $f77args .= " $arghash{$f77argnm}[$i]";
    }
  for $i (2 .. $#{$arghash{$arargnm}})
    {
      $arargs .= " $arghash{$arargnm}[$i]";
    }
  for $i (2 .. $#{$arghash{$linkargnm}})
    {
      $linkargs .= " $arghash{$linkargnm}[$i]";
    }

  # update include path list and library list
  $inclist ="-I\$(POOMA_SRCDIR) -I\$(POOMA_LIBDIR) $inclist";
  $preliblist = "-L\$(POOMA_LIBDIR) -l\$(POOMA_LIBNAME)";
  $postliblist = "-lm";

  # update list of #define settings now that we have arch settings
  add_string_define("POOMA_YES", "1");
  add_string_define("POOMA_NO", "0");
  add_string_define("POOMA_TRUE", "true");
  add_string_define("POOMA_FALSE", "false");
  add_string_define("POOMA_SUITE", "\"$suite\"");
  add_string_define("POOMA_ARCH_TYPE", "\"$archtype\"");
  add_string_define("POOMA_COMP_TYPE", "\"$comptype\"");
  add_string_define("POOMA_MAJOR_VERSION", "$majorversion");
  add_string_define("POOMA_MINOR_VERSION", "$minorversion");
  add_string_define("POOMA_PATCH_LEVEL", "\"$patchlevel\"");
  add_string_define("POOMA_VERSION_STRING", "\"$version\"");
  add_string_define("POOMA_VERSION_NUM_STRING", "\"$versionnumstr\"");
  add_string_define("POOMA_CONFIGURE_ARGS", "\"@ARGV\"");
  add_string_define("POOMA_BUILD_DATE", "\"$datestr\"");
  add_string_define("POOMA_BUILD_USER", "\"$userstr\"");
  add_string_define("POOMA_BUILD_HOST", "\"$hoststr\"");
}


###########################################################################
#
# Procedures to examine the default settings, architecture settings,
# and command-line settings to figure out exactly what we should do.
#
###########################################################################

### figure out if we should do preinstantiation
sub setpreinstantiate
{

  if (scalar @{$arghash{$preinstnm}} > 1)
    {
      $preinstantiate = 1;
      $extensions .= "-preinst";
    }
  print "Set preinstantiate = $preinstantiate\n" if $dbgprnt;
  add_yesno_define("POOMA_PREINSTANTIATE", $preinstantiate);
}


### figure out if verbose output from comp/link should be used
sub setverbose
{
  if (scalar @{$arghash{$verbosenm}}> 1 and scalar @{$arghash{$noverbosenm}}>1)
    {
      printerror "$verbosenm and $noverbosenm both given.  Use only one.";
    }
  elsif (scalar @{$arghash{$verbosenm}} > 1)
    {
      $verbose = 1;
    }
  elsif (scalar @{$arghash{$noverbosenm}} > 1)
    {
      $verbose = 0;
    }
  print "Set verbose = $verbose\n" if $dbgprnt;

  # add verbose output settings
  if ($verbose)  {
      $cppargs  .= " $cppverbose";
      $cargs    .= " $cverbose";
      $f77args  .= " $f77verbose";
      $linkargs  = "$linkverbose $linkargs";
      $arargs    = "$arverbose $arargs";
      $arshareargs = "$arshareverbose $arshareargs";
  }
}


### figure out if one-per option should be used
sub setoneper
{
  if (scalar @{$arghash{$onepernm}}> 1 and scalar @{$arghash{$noonepernm}} > 1)
    {
      printerror "$oneper and $nooneper both given.  Use only one.";
    }
  elsif (scalar @{$arghash{$onepernm}} > 1)
    {
      $oneper = 1;
    }
  elsif (scalar @{$arghash{$noonepernm}} > 1)
    {
      $oneper = 0;
    }
  print "Set oneper = $oneper\n" if $dbgprnt;

  # add one-per settings, to library build and archiver settings
  if ($oneper and $cpponeper) {
      $cppdbg_lib .= " $cpponeper";
      $cppopt_lib .= " $cpponeper";
      $arargs      = "$aroneper $arargs";
      $arshareargs = "$arshareoneper $arshareargs";
  }
}

### figure out if one-per option should be used
sub setpool
{
  if (scalar @{$arghash{$poolyesnm}}> 1 and scalar @{$arghash{$poolnonm}} > 1)
    {
      printerror "$poolyesnm and $poolnonm both given.  Use only one.";
    }
  elsif (scalar @{$arghash{$poolyesnm}} > 1)
    {
      $pool = 1;
    }
  elsif (scalar @{$arghash{$poolnonm}} > 1)
    {
      $pool = 0;
    }
  print "Set pool = $pool\n" if $dbgprnt;

  # add in symbol indicating whether to use Pooled class
  add_yesno_define("POOMA_POOLED", $pool);
}


### figure out if the default case is to build debug or optimize
sub setdebug
{
  # set $debug variable properly
  if (scalar @{$arghash{$debugnm}} > 1 and scalar @{$arghash{$optnm}} > 1)
    {
      printerror "$debugnm and $optnm both given.  Use only one.";
    }
  elsif (scalar @{$arghash{$debugnm}} > 1)
    {
      $debug = 1;
    }
  elsif (scalar @{$arghash{$optnm}} > 1)
    {
      $debug = 0;
    }
  print "Set debug = $debug\n" if $dbgprnt;

  # determine if we should enable printing debug messages
  if (scalar @{$arghash{$printdbgnm}} > 1) { $printdebug = 1; }
  add_yesno_define("POOMA_PRINTDEBUG", $printdebug);
}


### figure out if the fortran interface should be included
sub setfinterface
{
  # set $finterface variable properly
  if (scalar @{$arghash{$finternm}} > 1 and scalar @{$arghash{$nofinternm}}>1)
    {
      printerror "$finternm and $nofinternm both given.  Use only one.";
    }
  elsif (scalar @{$arghash{$nofinternm}} > 1)
    {
      $finterface = 0;
    }
  elsif (scalar @{$arghash{$finternm}} > 1)
    {
      $finterface = 1;
    }
  print "Set finterface = $finterface\n" if $dbgprnt;

  # if the fortran libs are to be included, add them in to the post libs
  if ($finterface)
    {
      $postliblist .= " $f77libs";
    }
}


### figure out if we should include the PAWS library or not
sub setpaws
{
  # make sure only paws or pawsdev is used
  if (scalar @{$arghash{$pawsnm}}> 1 and scalar @{$arghash{$pawsdevnm}} > 1)
    {
      printerror "$pawsnm and $pawsdevnm both given.  Use only one.";
    }

  # set $paws variable properly
  if ($paws_able and scalar @{$arghash{$pawsnm}} > 1)
    {
      $paws = 1;
    }
  elsif ($paws_able and scalar @{$arghash{$pawsdevnm}} > 1)
    {
      $pawsdev = 1;
    }
  print "Set paws = $paws\n" if $dbgprnt;

  # add a define indicating whether PAWS is available, and configure
  # extra options to include and define lists
  my $defpaws = 0;
  if ($paws or $pawsdev)
    {
      $defpaws = 1;

      # add in the extra compilation settings for PAWS.  These will
      # be obtained from the PAWS makefile stub that will be included by
      # the suite file from the $paws_dir directory.
      $midliblist .= " \$(PAWS_LD_LIBS)";
      $inclist    .= " \$(PAWS_INCLUDES)";
      $defines    .= " \$(PAWS_DEFINES)";
    }
  add_yesno_define("POOMA_PAWS", $defpaws);

  # add in the paws library/include files
  if ($paws)
    {
      # set the base directory for the paws lib and header files
      # this will be from PAWSDIR if it is set, or from the default
      # setting in the architecture file if it is not set
      if (exists $ENV{"PAWSDIR"})
        {
          $paws_dir = $ENV{"PAWSDIR"};
        }
      elsif ($paws_default_dir)
        {
          $paws_dir = $paws_default_dir;
        }
      else
        {
          die "There is no known PAWS directory.  Select one by setting PAWSDIR or by editing the architecture configuration file.\n";
        }
    }
  elsif ($pawsdev)
    {
      # set the base directory for the paws lib and header files
      # this will be from PAWS_ROOT environment variable.  For the pawsdev
      # option, this must be set.  We must also have the PAWS_ARCH env
      # var set.
      if (exists $ENV{"PAWS_ROOT"} and exists $ENV{"PAWS_ARCH"})
        {
          $paws_dir = $ENV{"PAWS_ROOT"};
	  $paws_lib_subdir = "lib/";
	  $paws_lib_subdir .= $ENV{"PAWS_ARCH"};
	  $paws_makefile = "Makefile.app";
        }
      else
        {
          die "Please set PAWS_ROOT and PAWS_ARCH variables before you use the $pawsdevnm option.\n";
        }
    }
}


### figure out if we should include the LUX package or not
sub setlux
{
  # set $lux variable properly
  if ($lux_able and scalar @{$arghash{$luxnm}} > 1)
    {
      $lux = 1;
    }
  print "Set lux = $lux\n" if $dbgprnt;

  # add a define indicating whether LUX is available, and configure
  # extra options to include and define lists
  my $deflux = 0;
  if ($lux)
    {
      $deflux = 1;

      # add in the extra compilation settings for LUX.  These will
      # be obtained from the LUX makefile stub that will be included by
      # the suite file from the $lux_dir directory.
      $midliblist .= " \$(ACLVIS_LIBRARIES)";
      $inclist    .= " \$(ACLVIS_INCLUDES)";
      $defines    .= " \$(ACLVIS_DEFINES)";
    }
  add_yesno_define("POOMA_LUX", $deflux);

  # add in the LUX library/include files
  if ($lux)
    {
      # set the base directory for the LUX lib and header files
      # this will be from LUXDIR if it is set, or from the default
      # setting in the architecture file if it is not set
      if (exists $ENV{"LUXDIR"})
        {
          $lux_dir = $ENV{"LUXDIR"};
        }
      elsif ($lux_default_dir)
        {
          $lux_dir = $lux_default_dir;
        }
      else
        {
          die "There is no known LUX directory.  Select one by setting LUXDIR or by editing the architecture configuration file.\n";
        }
    }
}


### figure out if we should include the HDF5 package or not
sub sethdf5
{
  # set $hdf5 variable properly
  if ($hdf5_able and scalar @{$arghash{$hdf5nm}} > 1)
    {
      $hdf5 = 1;
    }
  print "Set hdf5 = $hdf5\n" if $dbgprnt;

  # add a define indicating whether HDF5 is available, and configure
  # extra options to include and define lists
  my $defhdf5 = 0;
  if ($hdf5)
    {
      if (exists $ENV{"HDF5DIR"})
        {
          $hdf5_dir = $ENV{"HDF5DIR"};
        }
      elsif ($hdf5_default_dir)
        {
          $hdf5_dir = $hdf5_default_dir;
        }
      else
        {
          die "There is no known HDF5 directory.  Select one by setting HDF5DIR or by editing the architecture configuration file.\n";
        }

      $defhdf5 = 1;

      # add in the extra compilation settings for HDF5.
      $midliblist .= " -L$hdf5_dir/lib -lhdf5";
      $inclist    .= " -I$hdf5_dir/include";
    }
  add_yesno_define("POOMA_HDF5", $defhdf5);
}


### figure out if we should include the FFTW package or not
sub setfftw
{
  # set $fftw variable properly
  if ($fftw_able and scalar @{$arghash{$fftwnm}} > 1)
    {
      $fftw = 1;
    }
  print "Set fftw = $fftw\n" if $dbgprnt;

  # add a define indicating whether FFTW is available, and configure
  # extra options to include and define lists
  my $deffftw = 0;
  if ($fftw)
    {
      if (exists $ENV{"FFTWDIR"})
        {
          $fftw_dir = $ENV{"FFTWDIR"};
        }
      elsif ($fftw_default_dir)
        {
          $fftw_dir = $fftw_default_dir;
        }
      else
        {
          die "There is no known FFTW directory.  Select one by setting FFTWDIR or by editing the architecture configuration file.\n";
        }

      $deffftw = 1;

      # add in the extra compilation settings for FFTW.
      $midliblist .= " -L$fftw_dir/lib -lfftw -lrfftw";
      $inclist    .= " -I$fftw_dir/include";
    }
  add_yesno_define("POOMA_FFTW", $deffftw);
}


### figure out if we should include the CHEETAH package or not
sub setcheetah
{
  # set $cheetah variable properly
  if ($cheetah_able and scalar @{$arghash{$cheetahnm}} > 1)
    {
      $cheetah = 1;
    }
  print "Set cheetah = $cheetah\n" if $dbgprnt;

  # add a define indicating whether CHEETAH is available, and configure
  # extra options to include and define lists
  my $defcheetah = 0;
  if ($cheetah)
    {
      if (exists $ENV{"CHEETAHDIR"})
        {
          $cheetah_dir = $ENV{"CHEETAHDIR"};
        }
      elsif ($cheetah_default_dir)
        {
          $cheetah_dir = $cheetah_default_dir;
        }
      else
        {
          die "There is no known CHEETAH directory.  Select one by setting CHEETAHDIR or by editing the architecture configuration file.\n";
        }

      $defcheetah = 1;

      $scheduler = "serialAsync";

      # add in the extra compilation settings for CHEETAH.
      $midliblist .= " \$(CHEETAH_LIBS)";
      $inclist    .= " \$(CHEETAH_INCLUDES)";
      $defines    .= " \$(CHEETAH_DEFINES)";

      # use special compiler script for CHEETAH if necessary.
      if ($cheetah_compiler_script)
        {
	  $cpp  = $cheetah_cpp;
	  $ar   = $cheetah_ar;
	  $link = $cheetah_link;
        } 
    }
  add_yesno_define("POOMA_CHEETAH", $defcheetah);
}


### figure out if we should include threads capabilities or not
sub setthreads
{
  # set $threads variable properly
  if (scalar @{$arghash{$threadsnm}} > 1 and scalar @{$arghash{$serialnm}}> 1)
    {
      printerror "$threadsnm and $serialnm both given.  Use only one.";
    }
  elsif (not $threads_able or scalar @{$arghash{$serialnm}} > 1)
    {
      $threads = 0;
    }
  elsif ($threads_able and scalar @{$arghash{$threadsnm}} > 1)
    {
      $threads = 1;
    }
  print "Set threads = $threads\n" if $dbgprnt;

  # add a define indicating whether threads is available, and
  # add in the threads library files if we're using threads
  add_yesno_define("POOMA_THREADS", $threads);
  if ($threads)
    {
      # add an extension to the user libs indicating we're using smarts
      $extensions .= "-smarts";

      # add any compiler specific arguments needed for thread safety
      $cppargs   = "$cpp_threads_arg $cppargs";

      # set the base directory for threads lib and header files
      # this will be from SMARTSDIR if it is set, or from the default
      # setting in the architecture file if it is not set
      if (exists $ENV{"SMARTSDIR"})
        {
          $threads_dir = $ENV{"SMARTSDIR"};
        }
      elsif ($threads_default_dir)
        {
          $threads_dir = $threads_default_dir;
        }
      else
        {
          die "There is no known SMARTS directory.  Select one by setting SMARTSDIR or by editing the architecture configuration file.\n";
        }

      # add in the extra compilation settings for threads.  These will
      # be obtained from the Smarts makefile stub that will be included by
      # the suite file from the $threads_dir directory.
      $midliblist .= " \$(SMARTS_LIB)";
      $inclist    .= " \$(SMARTS_INC)";
      $defines    .= " \$(SMARTS_DEF)";

      # if threads is used, we must also select the thread scheduler
      if (scalar @{$arghash{$schednm}} > 2)
	{
	  printerror "Please select only one thread scheduler.";
	}
      elsif (scalar @{$arghash{$schednm}} > 1)
	{
	  $scheduler = $arghash{$schednm}[1];
	}

      # make sure this scheduler is one we know about
      if (exists $schedulerhash{$scheduler})
	{
	  # indicate this scheduler is the one to use
	  $schedulernamehash{$schedulerhash{$scheduler}} = 1;
	  print "Got scheduler = $scheduler\n" if $prntdbg;

	  # set the default for blocking expressions based on the scheduler
	  $default_blocking_expressions = $schedulerblockhash{$scheduler};
	  print "Got blocking = $default_blocking_expressions\n" if $prntdbg;

	  # add defines for the schedulers
	  my $s = "";
	  foreach $s (keys %schedulernamehash)
	    {
	      my $schedulerdef = "POOMA_SMARTS_SCHEDULER_" . uc $s;
	      add_yesno_define($schedulerdef, $schedulernamehash{$s});
	    }
	  add_string_define("POOMA_SCHEDULER_NAME", "\"$scheduler\"");

	  if ($scheduler eq "serialAsync")
	    {
	      printerror "can't use serialAsync with --threads";
	    }
	}
      else
	{
	  printerror "Unknown scheduler '$scheduler'.";
	}
    }
  else
    {
      # In the non-threads case, we can still pick the serialAsync
      # scheduler.

      if (scalar @{$arghash{$schednm}} > 2)
	{
	  printerror "Please select only one thread scheduler.";
	}
      elsif (scalar @{$arghash{$schednm}} > 1)
	{
	  $scheduler = $arghash{$schednm}[1];
	}
      elsif ($scheduler ne "serialAsync")
	{
	  $scheduler = "none";
	}

      if ($scheduler eq "none")
	{
	  add_string_define("POOMA_SCHEDULER_NAME", "\"stub scheduler\"");
	}
      else
	{
	  if ($scheduler ne "serialAsync")
	    {
	      printerror
		"can't use $scheduler scheduler without --threads";
	    }
	  else
	    {
	      add_string_define("POOMA_SCHEDULER_NAME", "\"serialAsync\"");
	      add_yesno_define("POOMA_SMARTS_SCHEDULER_SERIALASYNC", 1);
	      $default_blocking_expressions =
		$schedulerblockhash{"serialAsync"};
	    }
	}
    }

  $pooma_reorder_iterates = $threads || ($scheduler eq "serialAsync");

  add_yesno_define("POOMA_REORDER_ITERATES", $pooma_reorder_iterates);
}


### figure out if we should include profiling capabilities or not
sub setprofile
{
  # set $profile variable properly
  if (not $profile_able)
    {
      $profile = 0;
    }
  elsif (scalar @{$arghash{$profilenm}} > 1)
    {
      $profile = 1;
    }
  print "Set profile = $profile\n" if $dbgprnt;

  # add a define indicating whether profiling is available,
  # add in the Tau profiling library files if we're using profiling, and
  # profiling uses a different profile directory
  add_yesno_define("POOMA_PROFILE", $profile);
  if ($profile)
    {
      # add an extension to the user libs indicating we're using profiling
      $extensions .= "-profile";

      # set the base directory for profiling lib and header files
      # this will be from TAUDIR if it is set, or from the default
      # setting in the architecture file if it is not set
      if (exists $ENV{"TAUDIR"})
        {
          $profile_dir = $ENV{"TAUDIR"};
        }
      elsif ($profile_default_dir)
        {
          $profile_dir = $profile_default_dir;
        }
      else
        { 
          die "There is no known TAU directory.\n";
        }

      # add in the extra compilation settings for profiling.  These will
      # be obtained from the TAU makefile stub that the suite file will
      # include from the $profile_dir directory.
      $midliblist .= " \$(TAULIBS)";
      $inclist    .= " \$(TAUINC)";
      $defines    .= " \$(TAUDEFS)";

      # set the base directory for PDT for automatic instrumentation.
      # this will be from TAUDIR if it is set, or from the default
      # setting in the architecture file if it is not set
      if (exists $ENV{"PDTDIR"})
        {
          $pdt_dir = $ENV{"PDTDIR"};
        }
      elsif ($pdt_default_dir)
        {
          $pdt_dir = $pdt_default_dir;
        }
      else
        {
          die "There is no known PDT directory.\n";
        }

    }
}

### figure out if we should use Purify or not
sub setpurify
{
  # set $purify variable properly
  if (not $purify_able)
    {
      $purify = 0;
    }
  elsif (scalar @{$arghash{$purifynm}} > 1)
    {
      $purify = 1;
    }
  print "Set purify = $purify\n" if $dbgprnt;

  # add a define indicating whether Purify is available, and
  # change the compile and link commands if using Purify
  add_yesno_define("PETE_MAKE_EMPTY_CONSTRUCTORS", $purify);
  add_yesno_define("POOMA_PURIFY", $purify);
  if ($purify)
    {
      $link      = "purify";

      print "purify: cpp      = |$cpp|\n" if $dbgprnt;
      print "purify: link     = |$link|\n" if $dbgprnt;
    }
}

### figure out if we should use Insure++ or not
sub setinsure
{
  # set $insure variable properly
  if (not $insure_able)
    {
      $insure = 0;
    }
  elsif (scalar @{$arghash{$insurenm}} > 1)
    {
      $insure = 1;
    }
  print "Set insure = $insure\n" if $dbgprnt;

  # add a define indicating whether Insure++ is available, and
  # change the compile and link commands if using Insure++
  add_yesno_define("POOMA_INSURE", $insure);
  if ($insure)
    {
      $cpp       = $cpp_insure_run;
      $c         = $c_insure_run;
      $ar        = $ar_insure_run;
      $link      = $ld_insure_run;
      $cppargs   = "$cpp_insure_arg $cppargs";
      $cargs     = "$c_insure_arg $cargs";
      $arargs    = "$ar_insure_arg $arargs";
      $arshareargs    = "$ar_insure_arg $arshareargs";
      $linkargs  = "$ld_insure_arg $linkargs";
    }
}


### figure out if exceptions should be enabled
sub setexceptions
{
  # set $exceptions variable properly
  if (scalar @{$arghash{$exnm}} > 1 and scalar @{$arghash{$noexnm}} > 1)
    {
      printerror "$exnm and $noexnm both given.  Use only one.";
    }
  elsif (scalar @{$arghash{$noexnm}} > 1)
    {
      $exceptions = 0;
    }
  elsif (scalar @{$arghash{$exnm}} > 1)
    {
      $exceptions = 1;
    }
  print "Set exceptions = $exceptions\n" if $dbgprnt;

  # add a define indicating whether exceptions should be used, and
  # modify build settings based on value of $exceptions
  add_yesno_define("POOMA_EXCEPTIONS", $exceptions);
  if ($exceptions)
    {
      $cppargs    .= " $cppex";
      $arargs      = "$arex $arargs";
      $arshareargs = "$arshareex $arshareargs";
      $linkargs    = "$cppex $linkargs";

      # add an extension to the user libs indicating we're using exceptions
      # note that this probably doesn't do what you expect because $cppex is
      # usually null.
      $extensions .= "-ex";

      # add correct extensions to libraries we use
      $cheetah_lib_subdir .= "-ex";
    }
  else
    {
      $cppargs    .= " $cppnoex";
      $arargs      = "$arnoex $arargs";
      $arshareargs = "$arsharenoex $arshareargs";
      $linkargs    = "$cppnoex $linkargs";

      # add correct extensions to libraries we use
      $threads_include_makefile .= "-noex";
      $profile_include_makefile .= "-noex";
      $cheetah_lib_subdir .= "-noex";
    }
}


### figure out if exceptions should be enabled
sub setstrict
{
  # set $strict variable properly
  if (scalar @{$arghash{$strictnm}} > 1)
    {
      $strict = 1;
    }
  print "Set strict = $strict\n" if $dbgprnt;

  # add a define indicating whether ANSI conformance 
  # checking should be performed, and
  # modify build settings based on value of $strict
  add_yesno_define("POOMA_STRICT", $strict);
  if ($strict)
    {
      $defines    .= " $strictdefs";
      $cppargs    .= " $cppstrict";
      $arargs      = "$arstrict $arargs";
      $arshareargs = "$arsharestrict $arshareargs";
      $linkargs    = "$cppstrict $linkargs";
    }
}


### figure out if a shared lib should be made
sub setshared
{
  # set $shared variable properly.  Some systems cannot build shared
  # libraries.
  if (scalar @{$arghash{$sharednm}} > 1 and scalar @{$arghash{$staticnm}} > 1)
    {
      printerror "$sharednm and $staticnm both given.  Use only one.";
    }
  elsif (scalar @{$arghash{$staticnm}} > 1 or not $canmakesharedlib)
    {
      $shared = 0;
    }
  elsif (scalar @{$arghash{$sharednm}} > 1)
    {
      $shared = 1;
    }
  print "Set shared = $shared\n" if $dbgprnt;

  # add in proper options to compilers and linker if we're building shared
  if ($shared)
    {
      # we keep all shared-lib flags, and change the library extensions
      $libext = $sharedext;
      # change to the arshare shared-lib archiver
      $ar = $arshare;
      $arargs = $arshareargs;
    }
  else
    {
      # erase any shared-lib flags
      $cppshare = "";
      $cshare = "";
      $f77share = "";
      $f90share = "";
      $linkshare = "";
    }
}

### figure out if we should enable arch-specific initialization functions
sub setarchfns
{

  if (scalar @{$arghash{$archfnsnm}} > 1)
    {
      $archfns = 1;
    }
  print "Set archfns = $archfns\n" if $dbgprnt;
  add_yesno_define("POOMA_ARCH_SPECIFIC_FUNCTIONS", $archfns);
}


### add settings for non-standard behavior
sub setcharacteristics
{
  # if the system does not have the stringstream class, must use workaround
  add_yesno_define("POOMA_NO_STRINGSTREAM",
		   $no_stringstream);

  # if the system is missing some of the iostream manipulators, must avoid them
  add_yesno_define("POOMA_MISSING_IOMANIPS",
		   $no_complete_iomanips);

  # if the C++ compiler does not allow templated friends, must say so
  add_yesno_define("POOMA_NO_TEMPLATE_FRIENDS",
		   $no_templated_friends);

  # if the C++ compiler does not allow restrict, must say so
  add_yesno_define("POOMA_NO_RESTRICT",
		   $no_restrict);

  # if the system does not have a version of ostream_iterator that can
  # be constructed with one template arg, must use two
  add_yesno_define("POOMA_NO_OSTREAM_ITERATOR_1ARG",
		   $no_ostream_iterator_1arg);

  # if the compiler does not allow definitions of placement delete operations
  add_yesno_define("POOMA_NO_PLACEMENT_DELETE",
		   $no_placement_delete);

  # should we include extra specializations of some things for small dim?
  add_yesno_define("POOMA_SMALL_DIM_SPECIALIZATIONS",
		   $small_dim_specializations);

  # if the C++ compiler does not allow template parameters to be dependent, 
  # on others (e.g., template<int D1, int D2=D1, ...>,  must say so
  add_yesno_define("POOMA_NO_DEPENDENT_TEMPLATE_ARGS",
		   $no_dependent_templ_args);

  # if the C++ library does not have templated complex number class, say so
  add_yesno_define("POOMA_NO_TEMPLATED_COMPLEX",
		   $no_templated_complex);

  # if the C++ library does not have complex number class in std::, say so
  add_yesno_define("POOMA_NO_STD_COMPLEX",
		   $no_std_complex);

  # if the C++ library has O_BINARY defined
  add_yesno_define("POOMA_HAS_O_BINARY_OPEN_MODE",
                   $o_binary_open_mode);

  # if the C++ library does not have ios_base class in std::, say so
  add_yesno_define("POOMA_NO_STD_IOSBASE",
		   $no_std_iosbase);

  # if must include <sys/stat.h> for POSIX file modes, say so
  add_yesno_define("POOMA_INC_SYS_STAT_H_FOR_FILE_MODES",
		   $inc_sys_stat_h_file_modes);
}


### set default source code options like default data types
sub setsourcedefaults
{
  # enable bounds checking if requested
  if (scalar @{$arghash{$boundsnm}} > 1)
    {
      $bounds_checking = 1;
      $default_bounds_checking = "POOMA_TRUE";
    }

  # add in all the source defaults defines
  add_protected_string_define("POOMA_DEFAULT_ENGINE_TYPE",
                              $default_engine_type);
  add_protected_string_define("POOMA_DEFAULT_FLOAT_TYPE",
                              $default_float_type);
  add_protected_string_define("POOMA_DEFAULT_ELEMENT_TYPE",
                              $default_element_type);
  add_protected_string_define("POOMA_DEFAULT_POSITION_TYPE",
                              $default_position_type);
  add_protected_yesno_define("POOMA_BOUNDS_CHECK", $bounds_checking);
  add_protected_string_define("POOMA_BOUNDS_CHECK_DEFAULT",
                              $default_bounds_checking);

  # add in all the threads defaults
  add_protected_string_define("POOMA_DEFAULT_SMARTS_HARDINIT",
                              $default_smarts_hardinit);
  add_protected_string_define("POOMA_DEFAULT_SMARTS_HARDRUN",
                              $default_smarts_hardrun);
  add_protected_string_define("POOMA_DEFAULT_SMARTS_LOCKTHREADS",
		              $default_smarts_lockthreads);
  add_protected_string_define("POOMA_DEFAULT_BLOCKING_EXPRESSIONS",
		              $default_blocking_expressions);
}


### set the names of makefiles to include for different packages, based on
### the previously set values of threads, profile, etc
sub setincludemakefiles
{
  # select the threads makefile to include, if necessary
  if ($threads and $profile)
    {
      $threads_include_makefile = $threads_profile_makefile;
    }
  elsif ($threads)
    {
      $threads_include_makefile = $threads_basic_makefile;
    }

  # select the profiling makefile to include, if necessary
  if ($profile and $threads)
    {
      $profile_include_makefile = $profile_smarts_makefile;
    }
  elsif ($profile)
    {
      $profile_include_makefile = $profile_basic_makefile;
    }
}

 
###########################################################################
#
# Procedures to write out the necessary files.
#
###########################################################################

### write out the suite file, and run 'make dirs'
sub writesuitefile
{
  # check for an existing file
  if (-f $suitefile and not $overwrite)
    {
      print "\nOverwrite suite file \"$suitefile\" (y/n) [n] ? ";
      die "configure exiting; $suitefile unchanged.\n" unless (uc getc eq "Y");
      getc;
    }

  # based on the debug/opt setting, figure out the suffix for some suite
  # file settings
  my $libdebsuffix = $debug ? "DBG" : "OPT";
  my $appdebsuffix = $debug ? "APPDBG" : "APPOPT";

  # put all the link options together
  my $totlibraries = "$preliblist $midliblist $postliblist";
  my $liblinkargs="$linkshare $totlibraries";
  my $totlinkargs = "$linkargs $liblinkargs";

  # open the suite file and write out a prefix
  print "Writing suite file $suitefile ...\n";
  open(FSUITE,">$suitefile") or die "Cannot open $suitefile for write.\n";
  print FSUITE "##########################################################\n";
  print FSUITE "# POOMA suite file for suite: $suite\n";
  print FSUITE "# Created $datestr by $userstr on $hoststr\n";
  print FSUITE "# Generated by $cmdstr\n";
  print FSUITE "##########################################################\n";
  print FSUITE "\n";

  # set location of src and lib directories
  print FSUITE "POOMA_SRCDIR        = \$(PROJECT_ROOT)/src\n";
  print FSUITE "POOMA_BINDIR        = \$(PROJECT_ROOT)/bin\n";
  print FSUITE "POOMA_LIBDIR        = \$(PROJECT_ROOT)/lib/$suite\n";
  print FSUITE "POOMA_LIBNAME       = $projectname$extensions\n";
  print FSUITE "POOMA_LIBEXT        = $libext\n";
  print FSUITE "POOMA_LIBRARY       = lib\$(POOMA_LIBNAME).\$(POOMA_LIBEXT)\n";
  print FSUITE "\n";

  # if we should do preinstantiation, set makefile variable
  if ($preinstantiate)
    {
      print FSUITE "### preinstantiate several classes\n";
      print FSUITE "POOMA_PREINSTANTIATE = 1\n";
      print FSUITE "\n";
    }

  # if we are using PAWS, must add extra statements to suite file
  if ($paws or $pawsdev)
    {
      print FSUITE "### settings needed to use PAWS\n";
      print FSUITE "PAWSDIR             = $paws_dir\n";
      print FSUITE "include $paws_dir/$paws_lib_subdir/$paws_makefile\n";
      print FSUITE "\n";
    }

  # if we are using LUX, must add extra statements to suite file
  if ($lux)
    {
      print FSUITE "### settings needed to use LUX\n";
      print FSUITE "ACLVISDIR           = $lux_dir\n";
      print FSUITE "include $lux_dir/$lux_lib_subdir/$lux_makefile\n";
      print FSUITE "\n";
    }

  # if we are using threads, must add extra statements to suite file
  if ($threads)
    {
      print FSUITE "### settings needed to use SMARTS for threads\n";
      print FSUITE "SMARTSDIR           = $threads_dir\n";
      print FSUITE "include $threads_dir/$threads_lib_subdir/$threads_include_makefile\n";
      print FSUITE "\n";
    }

  # if we are using cheetahism, must add extra statements to suite file
  if ($cheetah)
    {
      print FSUITE "### settings needed to use CHEETAH for communication\n";
      print FSUITE "CHEETAH_ROOT          = $cheetah_dir/$cheetah_arch\n";
      print FSUITE "include \$(CHEETAH_ROOT)/$cheetah_lib_subdir/$cheetah_include_makefile\n";
      print FSUITE "\n";
    }

  # if we are using profiling, must add extra include statements to suite file
  if ($profile)
    {
      print FSUITE "### settings needed to use TAU profiling\n";
      print FSUITE "TAUDIR              = $profile_dir\n";
      print FSUITE "include $profile_dir/$profile_lib_subdir/$profile_include_makefile\n";
      print FSUITE "TAUPROFILE		= 1\n";
      print FSUITE "PDTDIR		= $pdt_dir\n";
      print FSUITE "TAUINSTR		= \$(TAUDIR)/$archtype/bin/tau_instrumentor\n";
      print FSUITE "TAUPARSE		= \$(PDTDIR)/$archtype/bin/cxxparse\n";
      print FSUITE "\n";
    }

  # if we are using Insure++, must add extra statements to suite file
  if ($insure)
    {
      print FSUITE "### settings needed to use Insure++\n";
      print FSUITE "CXXINSURE           = $cppinsure\n";
      print FSUITE "\n";
    }

  # write out the necessary suite file settings
  print FSUITE "### names of applications\n";
  print FSUITE "CXX                 = $cpp\n";
  print FSUITE "CC                  = $c\n";
  print FSUITE "F77                 = $f77\n";
  print FSUITE "AR                  = $ar\n";
  print FSUITE "LD                  = $link\n";
  print FSUITE "\n";
  print FSUITE "### flags for applications\n";
  print FSUITE "CXX_OPT_LIB_ARGS    = $cppargs $cppshare $cppopt_lib\n";
  print FSUITE "CXX_DBG_LIB_ARGS    = $cppargs $cppshare $cppdbg_lib\n";
  print FSUITE "CXX_OPT_APP_ARGS    = $cppargs $cppopt_app\n";
  print FSUITE "CXX_DBG_APP_ARGS    = $cppargs $cppdbg_app\n";
  print FSUITE "\n";
  print FSUITE "C_OPT_LIB_ARGS      = $cargs $cshare $copt_lib\n";
  print FSUITE "C_DBG_LIB_ARGS      = $cargs $cshare $cdbg_lib\n";
  print FSUITE "C_OPT_APP_ARGS      = $cargs $copt_app\n";
  print FSUITE "C_DBG_APP_ARGS      = $cargs $cdbg_app\n";
  print FSUITE "\n";
  print FSUITE "F77_OPT_LIB_ARGS    = $f77args $f77share $f77opt_lib\n";
  print FSUITE "F77_DBG_LIB_ARGS    = $f77args $f77share $f77dbg_lib\n";
  print FSUITE "F77_OPT_APP_ARGS    = $f77args $f77opt_app\n";
  print FSUITE "F77_DBG_APP_ARGS    = $f77args $f77dbg_app\n";
  print FSUITE "\n";
  if ($shared) {
      print FSUITE "AR_OPT_ARGS         = $arshareopt\n";
      print FSUITE "AR_DBG_ARGS         = $arsharedbg\n";
  }
  else {
      print FSUITE "AR_OPT_ARGS         = $aropt\n";
      print FSUITE "AR_DBG_ARGS         = $ardbg\n";
  }
  print FSUITE "\n";
  print FSUITE "AR_ARGS             = $arargs\n";
  print FSUITE "LD_ARGS             = $totlinkargs\n";
  print FSUITE "\n";
  print FSUITE "SUITE_PURIFY_OPTS   = $purifyargs\n";
  print FSUITE "SUITE_INCLUDES      = $inclist\n";
  print FSUITE "SUITE_DEFINES       = $defines\n";
  print FSUITE "\n";
  print FSUITE "### settings for different passes\n";
  print FSUITE "SUITE_CXXOPTS_DBG   = \$(CXX_DBG_LIB_ARGS)\n";
  print FSUITE "SUITE_COPTS_DBG     = \$(C_DBG_LIB_ARGS)\n";
  print FSUITE "SUITE_F77OPTS_DBG   = \$(F77_DBG_LIB_ARGS)\n";
  print FSUITE "SUITE_LDOPTS_DBG    = \$(CXX_DBG_LIB_ARGS) \$(LD_ARGS)\n";
  print FSUITE "SUITE_AROPTS_DBG    = \$(AR_DBG_ARGS) \$(AR_ARGS)\n";
  print FSUITE "\n";
  print FSUITE "SUITE_CXXOPTS_OPT   = \$(CXX_OPT_LIB_ARGS)\n";
  print FSUITE "SUITE_COPTS_OPT     = \$(C_OPT_LIB_ARGS)\n";
  print FSUITE "SUITE_F77OPTS_OPT   = \$(F77_OPT_LIB_ARGS)\n";
  print FSUITE "SUITE_LDOPTS_OPT    = \$(CXX_OPT_LIB_ARGS) \$(LD_ARGS)\n";
  print FSUITE "SUITE_AROPTS_OPT    = \$(AR_OPT_ARGS) \$(AR_ARGS)\n";
  print FSUITE "\n";
  print FSUITE "SUITE_CXXOPTS_APPDBG = \$(CXX_DBG_APP_ARGS)\n";
  print FSUITE "SUITE_COPTS_APPDBG   = \$(C_DBG_APP_ARGS)\n";
  print FSUITE "SUITE_F77OPTS_APPDBG = \$(F77_DBG_APP_ARGS)\n";
  print FSUITE "SUITE_LDOPTS_APPDBG  = \$(CXX_DBG_APP_ARGS) \$(LD_ARGS)\n";
  print FSUITE "SUITE_AROPTS_APPDBG  = \$(AR_DBG_ARGS) \$(AR_ARGS)\n";
  print FSUITE "\n";
  print FSUITE "SUITE_CXXOPTS_APPOPT = \$(CXX_OPT_APP_ARGS)\n";
  print FSUITE "SUITE_COPTS_APPOPT   = \$(C_OPT_APP_ARGS)\n";
  print FSUITE "SUITE_F77OPTS_APPOPT = \$(F77_OPT_APP_ARGS)\n";
  print FSUITE "SUITE_LDOPTS_APPOPT  = \$(CXX_OPT_APP_ARGS) \$(LD_ARGS)\n";
  print FSUITE "SUITE_AROPTS_APPOPT  = \$(AR_OPT_ARGS) \$(AR_ARGS)\n";
  print FSUITE "\n";
  print FSUITE "### the default pass ('1') when building a library\n";
  print FSUITE "SUITE_CXXOPTS_1      = \$(SUITE_CXXOPTS_$libdebsuffix)\n";
  print FSUITE "SUITE_COPTS_1        = \$(SUITE_COPTS_$libdebsuffix)\n";
  print FSUITE "SUITE_F77OPTS_1      = \$(SUITE_F77OPTS_$libdebsuffix)\n";
  print FSUITE "SUITE_LDOPTS_1       = \$(SUITE_LDOPTS_$libdebsuffix)\n";
  print FSUITE "SUITE_AROPTS_1       = \$(SUITE_AROPTS_$libdebsuffix)\n";
  print FSUITE "\n";
  print FSUITE "### the 'APP' pass used when building an application\n";
  print FSUITE "SUITE_CXXOPTS_APP    = \$(SUITE_CXXOPTS_$appdebsuffix)\n";
  print FSUITE "SUITE_COPTS_APP      = \$(SUITE_COPTS_$appdebsuffix)\n";
  print FSUITE "SUITE_F77OPTS_APP    = \$(SUITE_F77OPTS_$appdebsuffix)\n";
  print FSUITE "SUITE_LDOPTS_APP     = \$(SUITE_LDOPTS_$appdebsuffix)\n";
  print FSUITE "SUITE_AROPTS_APP     = \$(SUITE_AROPTS_$appdebsuffix)\n";
  print FSUITE "\n";

  # if we should do an extra prelink step, add extra settings
  if ($prelinkstep && !($shared))
    {
      print FSUITE "### perform extra prelink step\n";
      print FSUITE "PRELINKSTEP          = 1\n";
      print FSUITE "PRELINK              = $prelink\n";
      print FSUITE "PRELINKARGS          = $prelinkargs\n";
      print FSUITE "SUITE_PRELINKOPTS_DBG= \$(CXX_DBG_LIB_ARGS) \$(PRELINKARGS)\n";
      print FSUITE "SUITE_PRELINKOPTS_OPT= \$(CXX_OPT_LIB_ARGS) \$(PRELINKARGS)\n";
      print FSUITE "SUITE_PRELINKOPTS_1  = \$(SUITE_PRELINKOPTS_$libdebsuffix)\n";
      print FSUITE "\n";
    }
  if ($instrepo)
    {
      print FSUITE "INSTREPO             = 1\n";
      print FSUITE "INSTANTIATION_DIR    = $instantiationdir\n";
      print FSUITE "\n";
    }

  print FSUITE "### installation and distribution information\n";
  print FSUITE "INSTALL_DIR          = $prefix\n";
  print FSUITE "INSTALL_ARCH         = $archtype\n";
  print FSUITE "INSTALL_EXT          = $extensions\n";
  print FSUITE "INSTALL_LIBEXT       = $libext\n";
  print FSUITE "DISTRIB_BASE         = $versiontag\n";
  print FSUITE "DISTRIB_FILE         = $versiontag.tgz\n";
  print FSUITE "\n";

  # finished writing suite file
  print FSUITE "##########################################################\n";
  print FSUITE "# End of suite file $suitefile\n";
  print FSUITE "##########################################################\n";
  close FSUITE;
}


### write out the header file with versions information
sub writeversions
{
  # check for an existing directory to write this
  my $suitelib = "lib/$suite";
  if (not -d $suitelib)
    {
      # run the 'make dirs' command to create the necessary directories
      print "Running 'make dirs' to create build dirs ...\n" if $dbgprnt;
      system("$makecmd dirs SUITE=$suite");
    }

  # if the directory still does not exist, we should just quit
  -d $suitelib or die "Could not find directory '$suitelib'.  Exiting.\n";

  # check if we should overwrite the file
  my $vheader = "$suitelib/$versionheader";
  if (-f $vheader and not $overwrite)
    {
      print "\nOverwrite config header \"$vheader\" (y/n) [n] ? ";
      die "configure exiting; $vheader unchanged.\n" unless (uc getc eq "Y");
      getc;
    }

  # open the output file, and write header
  print "Writing version info header file $vheader ...\n";
  open(FHEADER,">$vheader") or die "Cannot open $vheader for write.\n";
  print FHEADER "/*******************************************************\n";
  print FHEADER " * POOMA version information file for suite: $suite\n";
  print FHEADER " * Created $datestr by $userstr on $hoststr\n";
  print FHEADER " * Generated by $cmdstr\n";
  print FHEADER " *******************************************************/\n";
  print FHEADER "\n";
  print FHEADER "#ifndef POOMA_GENERATED_CONFIG_H\n";
  print FHEADER "#define POOMA_GENERATED_CONFIG_H\n";
  print FHEADER "\n";

  # go through all the defines, and write them out.  First find max length
  # of macro names to get spacing right
  my $maxmacrolen = 0;
  foreach $d (@deflist)
    {
      my $symbol = "";
      my $value  = "";
      ($symbol, $value) = split /=/, $d, 2;
      my $spaces = length $symbol;
      $maxmacrolen = $spaces + 1 if $spaces >= $maxmacrolen;
    }
  foreach $d (@protecteddeflist)
    {
      my $symbol = "";
      my $value  = "";
      ($symbol, $value) = split /=/, $d, 2;
      my $spaces = length $symbol;
      $maxmacrolen = $spaces + 1 if $spaces >= $maxmacrolen;
    }

  foreach $d (@deflist)
    {
      my $symbol = "";
      my $value  = "";
      ($symbol, $value) = split /=/, $d, 2;
      my $spaces = $maxmacrolen - (length $symbol);
      print FHEADER "#define $symbol" . " " x $spaces . "$value\n";
    }
  print FHEADER "\n";

  foreach $d (@protecteddeflist)
    {
      my $symbol = "";
      my $value  = "";
      ($symbol, $value) = split /=/, $d, 2;
      my $spaces = $maxmacrolen - (length $symbol);
      print FHEADER "#ifndef $symbol\n";
      print FHEADER "#define $symbol" . " " x $spaces . "$value\n";
      print FHEADER "#endif\n\n";
    }

  # finished writing header file
  print FHEADER "#endif\n";
  print FHEADER "\n";
  print FHEADER "/*******************************************************\n";
  print FHEADER " * End of version information file $versionheader\n";
  print FHEADER " *******************************************************/\n";
  close FHEADER;
}


### write out dependency information
sub writedependfile
{
  # check for an existing directory to write this
  my $suitelib = "lib/$suite";
  if (not -d $suitelib)
    {
      # run the 'make dirs' command to create the necessary directories
      print "Running 'make dirs' to create build dirs ...\n" if $dbgprnt;
      system("$makecmd dirs SUITE=$suite");
    }

  # if the directory still does not exist, we should just quit
  -d $suitelib or die "Could not find directory '$suitelib'.  Exiting.\n";

  # check for dependency info.  create it if not already there.
  my $dependfile = "$suitelib/depend.mk";
  if (not -f $dependfile)
    {
      # run the 'make depend' command to create the dependency info
      print "Running 'make depend' to create dependency info ...\n" if $dbgprnt;
      system("$makecmd depend SUITE=$suite");
    }
}


### write out a makefile stub that other users can include, in the lib dir
sub writemakestub
{
  # check for an existing directory to write this
  my $suitelib = "lib/$suite";
  if (not -d $suitelib)
    {
      # run the 'make dirs' command to create the necessary directories
      print "Running 'make dirs' to create build dirs ...\n" if $dbgprnt;
      system("$makecmd dirs SUITE=$suite");
    }

  # if the directory still does exist, we should just quit
  -d $suitelib or die "Could not find directory '$suitelib'.  Exiting.\n";

  # check for an existing file
  my $mfile = "lib/$suite/$makefilestub$extensions";
  if (-f $mfile and not $overwrite)
    {
      print "\nOverwrite makefile stub file \"$mfile\" (y/n) [n] ? ";
      die "configure exiting; $mfile unchanged.\n" unless (uc getc eq "Y");
      getc;
    }

  # put all the link options together
  my $totlinkargs = "$linkargs $linkshare $preliblist $midliblist $postliblist";

  # put all the includes together
  my $totinclist = "-I\$(POOMA_LIBDIR)/$versionheaderbase$extensions $inclist";

  # put all the defines together
  my $totdefines = "$defines";

  # open the makefile stub file and write out a prefix
  print "Writing makefile stub $mfile ...\n";
  open(MFILE,">$mfile") or die "Cannot open $mfile for write.\n";
  print MFILE "##########################################################\n";
  print MFILE "# POOMA application makefile stub for suite: $suite\n";
  print MFILE "# Created $datestr by $userstr on $hoststr\n";
  print MFILE "# Generated by $cmdstr\n";
  print MFILE "##########################################################\n";
  print MFILE "\n";

  # set default location of POOMADIR
  print MFILE "POOMADIR            = $prefix\n";
  print MFILE "POOMAARCH           = $archtype\n";
  print MFILE "POOMA_BASE          = \$(POOMADIR)/\$(POOMAARCH)\n";
  print MFILE "POOMA_SRCDIR        = \$(POOMA_BASE)/src\n";
  print MFILE "POOMA_BINDIR        = \$(POOMA_BASE)/bin\n";
  print MFILE "POOMA_LIBDIR        = \$(POOMA_BASE)/lib\n";
  print MFILE "POOMA_LIBNAME       = $projectname$extensions\n";
  print MFILE "POOMA_LIBEXT        = $libext\n";
  print MFILE "POOMA_LIBRARY       = lib\$(POOMA_LIBNAME).\$(POOMA_LIBEXT)\n";
  print MFILE "\n";

  # if we are using threads, must add extra statements to suite file
  if ($threads)
    {
      print MFILE "### settings needed to use SMARTS for threads\n";
      print MFILE "SMARTSDIR           = $threads_dir\n";
      print MFILE "-include $threads_dir/$threads_lib_subdir/$threads_include_makefile\n";
      print MFILE "\n";
    }
 
  # if we are using cheetahism, must add extra statements to suite file
  if ($cheetah)
    {
      print MFILE "### settings needed to use CHEETAH for communication\n";
      print MFILE "CHEETAH_ROOT          = $cheetah_dir\n";
      print MFILE "include \$(CHEETAH_ROOT)/$cheetah_lib_subdir/$cheetah_include_makefile\n";
      print MFILE "\n";
    }
 
  # if we are using PAWS, must add extra statements to suite file
  if ($paws or $pawsdev)
    {
      print MFILE "### settings needed to use PAWS\n";
      print MFILE "PAWSDIR             = $paws_dir\n";
      print MFILE "-include $paws_dir/$paws_lib_subdir/$paws_makefile\n";
      print MFILE "\n";
    }

  # if we are using LUX, must add extra statements to suite file
  if ($lux)
    {
      print MFILE "### settings needed to use LUX\n";
      print MFILE "ACLVISDIR           = $lux_dir\n";
      print MFILE "-include $lux_dir/$lux_lib_subdir/$lux_makefile\n";
      print MFILE "\n";
    }

  # if we are using profiling, must add extra include statements to suite file
  if ($profile)
    {
      print MFILE "### settings needed to use TAU profiling\n";
      print MFILE "TAUDIR              = $profile_dir\n";
      print MFILE "-include $profile_dir/$profile_lib_subdir/$profile_include_makefile\n";
      print MFILE "TAUPROFILE		= 1\n";
      print MFILE "PDTDIR		= $pdt_dir\n";
      print MFILE "TAUINSTR		= \$(TAUDIR)/$archtype/bin/tau_instrumentor\n";
      print MFILE "TAUPARSE		= \$(PDTDIR)/$archtype/bin/cxxparse\n";
      print MFILE "\n";
    }

  # if we are using Insure++, must add extra statements to suite file
  if ($insure)
    {
      print MFILE "### settings needed to use Insure++\n";
      print MFILE "CXXINSURE            = $cppinsure\n";
      print MFILE "\n";
    }

  # write out the necessary suite file settings
  print MFILE "### names of applications\n";
  print MFILE "POOMA_CXX                 = $cpp\n";
  print MFILE "POOMA_CC                  = $c\n";
  print MFILE "POOMA_F77                 = $f77\n";
  print MFILE "POOMA_AR                  = $ar $arargs\n";
  print MFILE "POOMA_LD                  = $link\n";
  print MFILE "LD_PARALLEL               = 1\n";
  print MFILE "\n";
  print MFILE "### flags for applications\n";
  print MFILE "POOMA_CXX_OPT_ARGS        = $cppargs $cppopt_app\n";
  print MFILE "POOMA_CXX_DBG_ARGS        = $cppargs $cppdbg_app\n";
  print MFILE "\n";
  print MFILE "POOMA_CC_OPT_ARGS          = $cargs $copt_app\n";
  print MFILE "POOMA_CC_DBG_ARGS          = $cargs $cdbg_app\n";
  print MFILE "\n";
  print MFILE "POOMA_F77_OPT_ARGS        = $f77args $f77opt_app\n";
  print MFILE "POOMA_F77_DBG_ARGS        = $f77args $f77dbg_app\n";
  print MFILE "\n";
  print MFILE "POOMA_INCLUDES            = $totinclist\n";
  print MFILE "\n";
  print MFILE "POOMA_DEFINES             = $totdefines\n";
  print MFILE "\n";
  print MFILE "POOMA_LIBS                = $totlinkargs\n";
  print MFILE "\n";

  # finished writing makefile stub file
  print MFILE "##########################################################\n";
  print MFILE "# End of user makefile stub file $mfile\n";
  print MFILE "##########################################################\n";
  close MFILE;
}


###########################################################################
#
# process simple configuration-script-only flags:
#       -v           Turns on verbosity (useful for debugging conf itself)
#       -f           Force overwrite of all files
# this must be done right away before the other parameters are parsed
###########################################################################

foreach $a (@ARGV)
  {
    if ($a eq $dbgprntnm)
      {
	$dbgprnt = 1;
      }
    elsif ($a eq $overwritenm)
      {
	$overwrite = 1;
      }
    elsif ($a eq $nooverwritenm)
      {
	$overwrite = 0;
      }
    elsif ($a eq $helpnm or $a eq $questionnm)
      {
	printusage;
      }
  }


###########################################################################
#
# The main actions for this configuration script:
#   - print intro
#   - parse command-line options
#   - read arch info
#   - write suite file
#   - write version file
#
###########################################################################

### parse the command-line arguments
parseargs;

### get the proper version number information
getversionnum;

### get info out of argument results and store into script variables
getarchsuite;
setvariables;

### from the arch file input, and the command-line arguments, determine
### exactly how we should write out our suite and header files.  Do this
### in several steps.
###
### setcheetah must precede setthreads
###
setpreinstantiate;		# figure out if we should do preinstantiation
setverbose;                     # figure out if verbose output from comp/link
setoneper;                      # figure out of one-per option should be used
setpool;                        # figure out if the Pooled class should be used
setdebug;			# figure out the default debug setting
setfinterface;                  # figure out if fortran libs should be included
setpaws;			# figure out whether to use PAWS
setlux;				# figure out whether to use LUX
sethdf5;			# figure out whether to use HDF5
setfftw;			# figure out whether to use FFTW
setcheetah;			# figure out whether to use CHEETAH
setthreads;			# figure out whether to include threads
setprofile;			# figure out whether to include profiling
setpurify;                      # figure out whether to use Purify
setinsure;                      # figure out whether to use Insure++
setcharacteristics;		# add settings for non-standard behavior
setsourcedefaults;		# add default source code settings
setincludemakefiles;            # select names of makefiles to include
setexceptions;			# figure out whether to include exceptions
setstrict;			# figure out whether to check ANSI conformance
setshared;                      # figure out if a shared lib should be made
setarchfns;                     # figure out if we enable arch-specific init fns 

### write out the suite file, and run 'make dirs' to create the directory
### where the header file will go
writesuitefile;

### write out the header file with versions information, in the lib dir
writeversions;

### write out a makefile stub that other users can include, in the lib dir
writemakestub;

### create dependencies
writedependfile;

### print out final instructions
printinstructions;


# ACL:rcsinfo
#  ----------------------------------------------------------------------
#  $RCSfile: configure,v $   $Author: sa_smith $
#  $Revision: 1.100 $   $Date: 2000/08/08 21:17:22 $
#  ----------------------------------------------------------------------
# ACL:rcsinfo
