Hi Jeff,

Recreating the problem will probably be a bit convoluted, but should be possible.  Things are also complicated by the fact that I'm using the current developers' version of petsc.  I am presently getting around the problem by reverting to an older version of g95, but I believe that this is a symptom of the problem rather than the cause.  The primary differences between the two versions is that the newer one does not include libgcc_s.dylib.  Anyway, assuming you have access to a Tiger system, here is how you should be able to recreate the situation:

1.  Install the current fink version of g95 (0.50-20051002).

2.  Configure and build Open MPI after setting FC and F77 to g95.

3.  Get the current developers' version of PETSc.  I believe there is a tarball version available at ftp.mcs.anl.gov/pub/petsc.  They used to hide it by putting a dot in front of the name, but I just looked and that no longer seems to be the case.  I am instead using the open-source BitKeeper client to grab things.  You will need to get both the main package (bk://petsc.bkbits.net/petsc-dev) as well as the BuildSystem package (bk://sidl.bkbits.net/BuildSystem), which should be installed in ${PETSC_DIR}/python/BuildSystem.

4.  This is where things get a little tricky.  So far, I have to edit a couple of the PETSc files to get things working properly with Open MPI.  Open MPI appears to build two-level namespace libraries on OSX by default, where PETSc attempts to build the old-style flat namespace libraries.  I haven't been able to get shared and dynamic libraries to build properly using their default setup with Open MPI.  The two files in question are ${PETSC_DIR}/bmake/common/rules.shared.basic and ${PETSC_DIR}/python/BuildSystem/config/setCompilers.py.  I have attached edited copies of both files.  If you want to build the python bindings using Open MPI, you also need to edit a third file (${PETSC_DIR}/python/config/base.py), which I have also attached.

5.  Configure PETSc:

./config/configure.py \
--PETSC_ARCH=darwin8.2.0-openmpi-opt \
--with-clanguage=c++ \
--with-c-support \
--with-cc=mpicc \
--with-cxx=mpic++ \
--with-fc=mpif90 \
--with-shared \
--with-dynamic \
--with-python \
--sharedLibraryFlags='-dynamiclib -single_module -undefined dynamic_lookup -multiply_defined suppress' \
--dynamicLibraryFlags='-bundle -undefined dynamic_lookup -multiply_defined suppress' \
--with-mpi-dir=/Users/willic3/geoframe/tools/openmpi

If the --sharedLibraryFlags and --dynamicLibraryFlags worked the way I think they should, editing the files would not be necessary.  If you don't edit the files, though, these settings get overridden.

6.  Build PETSc (things should build OK), and then try 'make test', which I believe will duplicate what is pasted below.

If you have any insights into what the problem might be, I would certainly appreciate it.  Thanks for your help.

Charles

Attachment: rules.shared.basic
Description: Binary data

'''
config.base.Configure is the base class for all configure objects. It handles several types of interaction:

Framework hooks
---------------

  The Framework will first instantiate the object and call setupDependencies(). All require()
  calls should be made in that method.

  The Framework will then call configure(). If it succeeds, the object will be marked as configured.

Generic test execution
----------------------

  All configure tests should be run using

  executeTest()

which formats the output and adds metadata for the log.

Preprocessing, Compiling, Linking, and Running
----------------------------------------------

  Two forms of this check are provided for each operation. The first is an "output" form which is
intended to provide the status and complete output of the command. The second, or "check" form will
return a success or failure indication based upon the status and output.

  outputPreprocess(), checkPreprocess(), preprocess()
  outputCompile(),    checkCompile()
  outputLink(),       checkLink()
  outputRun(),        checkRun()

  The language used for these operation is managed with a stack, similar to autoconf.

  pushLanguage(), popLanguage()

  We also provide special forms used to check for valid compiler and linker flags, optionally adding
them to the defaults.

  checkCompilerFlag(), addCompilerFlag()
  checkLinkerFlag(),   addLinkerFlag()

Finding Executables
-------------------

  getExecutable(), getExecutables(), checkExecutable()

Output
------

  addDefine(), addSubstitution(), addArgumentSubstitution(), addTypedef(), addPrototype()
  addMakeMacro(), addMakeRule()

  The object may define a headerPrefix member, which will be appended, followed
by an underscore, to every define which is output from it. Similarly, a substPrefix
can be defined which applies to every substitution from the object. Typedefs and
function prototypes are placed in a separate header in order to accomodate languges
such as Fortran whose preprocessor can sometimes fail at these statements.
'''
import script

import os

class Configure(script.Script):
  def __init__(self, framework):
    script.Script.__init__(self, framework.clArgs, framework.argDB)
    self.framework       = framework
    self.defines         = {}
    self.makeRules       = {}
    self.makeMacros      = {}        
    self.typedefs        = {}
    self.prototypes      = {}
    self.subst           = {}
    self.argSubst        = {}
    self.language        = []
    self.compilerDefines = 'confdefs.h'
    self.compilerFixes   = 'conffix.h'
    self.pushLanguage('C')
    return

  def __str__(self):
    return ''

  def executeTest(self, test, args = [], kargs = {}):
    self.logWrite('================================================================================\n')
    self.logWrite('TEST '+str(test.im_func.func_name)+' from '+str(test.im_class.__module__)+'('+str(test.im_func.func_code.co_filename)+':'+str(test.im_func.func_code.co_firstlineno)+')\n')
    self.logPrint('TESTING: '+str(test.im_func.func_name)+' from '+str(test.im_class.__module__)+'('+str(test.im_func.func_code.co_filename)+':'+str(test.im_func.func_code.co_firstlineno)+')', debugSection = 'screen', indent = 0)
    if test.__doc__: self.logWrite('  '+test.__doc__+'\n')
    if not isinstance(args, list): args = [args]
    return apply(test, args,kargs)

  #################################
  # Define and Substitution Support
  def addMakeRule(self, name, dependencies, rule = []):
    '''Designate that "name" should be rule in the makefile header (bmake file)'''
    self.framework.logPrint('Defined make rule "'+name+'" with dependencies "'+str(dependencies)+'" and code '+str(rule))
    if not isinstance(rule,list): rule = [rule]
    self.makeRules[name] = [dependencies,rule]
    return

  def addMakeMacro(self, name, value):
    '''Designate that "name" should be defined to "value" in the makefile header (bmake file)'''
    self.framework.logPrint('Defined make macro "'+name+'" to "'+str(value)+'"')
    self.makeMacros[name] = value
    return

  def delMakeMacro(self, name):
    '''Designate that "name" should be deleted (never put in) configuration header'''
    self.framework.logPrint('Deleting "'+name+'"')
    if name in self.makeMacros: del self.makeMacros[name]
    return

  def addDefine(self, name, value):
    '''Designate that "name" should be defined to "value" in the configuration header'''
    self.framework.logPrint('Defined "'+name+'" to "'+str(value)+'"')
    self.defines[name] = value
    return

  def delDefine(self, name):
    '''Designate that "name" should be deleted (never put in)  configuration header'''
    self.framework.logPrint('Deleting "'+name+'"')
    if name in self.defines: del self.defines[name]
    return

  def addTypedef(self, name, value):
    '''Designate that "name" should be typedefed to "value" in the configuration header'''
    self.framework.logPrint('Typedefed "'+name+'" to "'+str(value)+'"')
    self.typedefs[value] = name
    return

  def addPrototype(self, prototype, language = 'All'):
    '''Add a missing function prototype
       - The language argument defaults to "All"
       - Other language choices are C, Cxx, extern C'''
    self.framework.logPrint('Added prototype '+prototype+' to language '+language)
    language = language.replace('+', 'x')
    if not language in self.prototypes:
      self.prototypes[language] = []
    self.prototypes[language].append(prototype)
    return

  def addSubstitution(self, name, value):
    '''Designate that "@name@" should be replaced by "value" in all files which experience substitution'''
    self.framework.logPrint('Substituting "'+name+'" with "'+str(value)+'"')
    self.subst[name] = value
    return

  def addArgumentSubstitution(self, name, arg):
    '''Designate that "@name@" should be replaced by "arg" in all files which experience substitution'''
    self.framework.logPrint('Substituting "'+name+'" with '+str(arg)+'('+str(self.framework.argDB[arg])+')')
    self.argSubst[name] = arg
    return

  ################
  # Program Checks
  def checkExecutable(self, dir, name):
    prog  = os.path.join(dir, name)
    # also strip any \ before spaces so that we can specify paths the way we want them in makefiles.
    prog  = prog.replace('\ ',' ') 
    found = 0
    self.framework.log.write('Checking for program '+prog+'...')
    if os.path.isfile(prog) and os.access(prog, os.X_OK):
      found = 1
      self.framework.log.write('found\n')
    else:
      self.framework.log.write('not found\n')
    return found

  def getExecutable(self, names, path = [], getFullPath = 0, useDefaultPath = 0, resultName = '', setMakeMacro = 1):
    '''Search for an executable in the list names
       - Each name in the list is tried for each entry in the path
       - If found, the path is stored in the variable "name", or "resultName" if given
       - By default, a make macro "resultName" will hold the path'''
    found = 0
    if isinstance(names, str):
      names = [names]
    if isinstance(path, str):
      path = path.split(':')
    if not len(path):
      useDefaultPath = 1

    def getNames(name, resultName):
      index = name.find(' ')
      if index >= 0:
        options = name[index:]
        name    = name[:index]
      else:
        options = ''
      if not resultName:
        varName = name
      else:
        varName = resultName
      return name, options, varName

    varName = names[0]
    varPath = ''
    for d in path:
      for name in names:
        name, options, varName = getNames(name, resultName)
        if self.checkExecutable(d, name):
          found = 1
          getFullPath = 1
          varPath = d
          break
      if found: break
    if useDefaultPath and not found:
      for d in os.environ['PATH'].split(':'):
        for name in names:
          name, options, varName = getNames(name, resultName)
          if self.checkExecutable(d, name):
            found = 1
            varPath = d
            break
        if found: break
    if not found:
      for d in self.framework.argDB['search-dirs']:
        for name in names:
          name, options, varName = getNames(name, resultName)
          if self.checkExecutable(d, name):
            found = 1
            getFullPath = 1
            varPath = d
            break
        if found: break

    if found:
      if getFullPath:
        setattr(self, varName, os.path.abspath(os.path.join(varPath, name))+options)
      else:
        setattr(self, varName, name+options)
      if setMakeMacro:
        self.addMakeMacro(varName.upper(), getattr(self, varName))
    return found

  def getExecutables(self, names, path = '', getFullPath = 0, useDefaultPath = 0, resultName = ''):
    '''Search for an executable in the list names
       - The full path given is searched for each name in turn
       - If found, the path is stored in the variable "name", or "resultName" if given'''
    for name in names:
      if self.getExecutable(name, path = path, getFullPath = getFullPath, useDefaultPath = useDefaultPath, resultName = resultName):
        return name
    return None

  ###############################################
  # Preprocessor, Compiler, and Linker Operations
  def pushLanguage(self, language):
    if language == 'C++': language = 'Cxx'
    self.logPrint('Pushing language '+language)
    self.language.append(language)
    return self.language[-1]

  def popLanguage(self):
    self.logPrint('Popping language '+self.language[-1])
    self.language.pop()
    return self.language[-1]

  def getCompiler(self):
    compiler            = self.framework.getCompilerObject(self.language[-1])
    compiler.checkSetup()
    self.compilerSource = 'conftest'+compiler.sourceExtension
    self.compilerObj    = compiler.getTarget(self.compilerSource)
    return compiler.getProcessor()

  def getCompilerFlags(self):
    return self.framework.getCompilerObject(self.language[-1]).getFlags()

  def getLinker(self):
    linker            = self.framework.getLinkerObject(self.language[-1])
    linker.checkSetup()
    self.linkerSource = 'conftest'+linker.sourceExtension
    self.linkerObj    = linker.getTarget(self.linkerSource,0)
    return linker.getProcessor()

  def getLinkerFlags(self):
    return self.framework.getLinkerObject(self.language[-1]).getFlags()

  def getSharedLinker(self):
    linker            = self.framework.getSharedLinkerObject(self.language[-1])
    linker.checkSetup()
    self.linkerSource = 'conftest'+linker.sourceExtension
    self.linkerObj    = linker.getTarget(self.linkerSource,1)
    return linker.getProcessor()

  def getSharedLinkerFlags(self):
    return self.framework.getSharedLinkerObject(self.language[-1]).getFlags()

  def getDynamicLinker(self):
    linker            = self.framework.getDynamicLinkerObject(self.language[-1])
    linker.checkSetup()
    self.linkerSource = 'conftest'+linker.sourceExtension
    self.linkerObj    = linker.getTarget(self.linkerSource,1)
    return linker.getProcessor()

  def getDynamicLinkerFlags(self):
    return self.framework.getDynamicLinkerObject(self.language[-1]).getFlags()

  def getPreprocessorCmd(self):
    self.getCompiler()
    preprocessor = self.framework.getPreprocessorObject(self.language[-1])
    preprocessor.checkSetup()
    return preprocessor.getCommand(self.compilerSource)

  def getCompilerCmd(self):
    self.getCompiler()
    compiler = self.framework.getCompilerObject(self.language[-1])
    compiler.checkSetup()
    return compiler.getCommand(self.compilerSource, self.compilerObj)

  def getLinkerCmd(self):
    self.getLinker()
    linker = self.framework.getLinkerObject(self.language[-1])
    linker.checkSetup()
    return linker.getCommand(self.linkerSource, self.linkerObj)

  def getSharedLinkerCmd(self):
    self.getSharedLinker()
    linker = self.framework.getSharedLinkerObject(self.language[-1])
    linker.checkSetup()
    return linker.getCommand(self.linkerSource, self.linkerObj)

  def getDynamicLinkerCmd(self):
    self.getDynamicLinker()
    linker = self.framework.getDynamicLinkerObject(self.language[-1])
    linker.checkSetup()
    return linker.getCommand(self.linkerSource, self.linkerObj)

  def getCode(self, includes, body = None, codeBegin = None, codeEnd = None):
    language = self.language[-1]
    if includes and not includes[-1] == '\n':
      includes += '\n'
    if language in ['C','Cxx']:
      codeStr = ''
      if self.compilerDefines: codeStr = '#include "'+self.compilerDefines+'"\n'
      codeStr += '#include "conffix.h"\n'+includes
      if not body is None:
        if codeBegin is None:
          codeBegin = '\nint main() {\n'
        if codeEnd is None:
          codeEnd   = ';\n  return 0;\n}\n'
        codeStr += codeBegin+body+codeEnd
    elif language == 'FC':
      if not includes is None:
        codeStr = includes
      else:
        codeStr = ''
      if not body is None:
        if codeBegin is None:
          codeBegin = '      program main\n'
        if codeEnd is None:
          codeEnd   = '\n      end\n'
        codeStr += codeBegin+body+codeEnd
    else:
      raise RuntimeError('Invalid language: '+language)
    return codeStr

  def preprocess(self, codeStr):
    def report(command, status, output, error):
      if error or status:
        self.framework.log.write('Possible ERROR while running preprocessor: '+error)
        if status: self.framework.log.write('ret = '+str(status)+'\n')
        if error: self.framework.log.write('error message = {'+error+'}\n')
        self.framework.log.write('Source:\n'+self.getCode(codeStr))
      return

    command = self.getPreprocessorCmd()
    if self.compilerDefines: self.framework.outputHeader(self.compilerDefines)
    self.framework.outputCHeader(self.compilerFixes)
    f = file(self.compilerSource, 'w')
    f.write(self.getCode(codeStr))
    f.close()
    (out, err, ret) = Configure.executeShellCommand(command, checkCommand = report, log = self.framework.log)
    if os.path.isfile(self.compilerDefines): os.remove(self.compilerDefines)
    if os.path.isfile(self.compilerFixes): os.remove(self.compilerFixes)
    if os.path.isfile(self.compilerSource): os.remove(self.compilerSource)
    return (out, err, ret)

  def outputPreprocess(self, codeStr):
    '''Return the contents of stdout when preprocessing "codeStr"'''
    return self.preprocess(codeStr)[0]

  def checkPreprocess(self, codeStr):
    '''Return True if no error occurred
       - An error is signaled by a nonzero return code, or output on stderr'''
    (out, err, ret) = self.preprocess(codeStr)
    err = self.framework.filterPreprocessOutput(err)
    return not ret and not len(err)

  def filterCompileOutput(self, output):
    return self.framework.filterCompileOutput(output)

  def outputCompile(self, includes = '', body = '', cleanup = 1, codeBegin = None, codeEnd = None):
    '''Return the error output from this compile and the return code'''
    def report(command, status, output, error):
      if error or status:
        self.framework.log.write('Possible ERROR while running compiler: '+output)
        if status: self.framework.log.write('ret = '+str(status)+'\n')
        if error: self.framework.log.write('error message = {'+error+'}\n')
        self.framework.log.write('Source:\n'+self.getCode(includes, body, codeBegin, codeEnd))
      return

    cleanup = cleanup and self.framework.doCleanup
    command = self.getCompilerCmd()
    if self.compilerDefines: self.framework.outputHeader(self.compilerDefines)
    self.framework.outputCHeader(self.compilerFixes)
    f = file(self.compilerSource, 'w')
    f.write(self.getCode(includes, body, codeBegin, codeEnd))
    f.close()
    (out, err, ret) = Configure.executeShellCommand(command, checkCommand = report, log = self.framework.log)
    if not os.path.isfile(self.compilerObj):
      err += '\nPETSc Error: No output file produced'
    if os.path.isfile(self.compilerDefines): os.remove(self.compilerDefines)
    if os.path.isfile(self.compilerFixes): os.remove(self.compilerFixes)
    if os.path.isfile(self.compilerSource): os.remove(self.compilerSource)
    if cleanup and os.path.isfile(self.compilerObj): os.remove(self.compilerObj)
    return (out, err, ret)

  def checkCompile(self, includes = '', body = '', cleanup = 1, codeBegin = None, codeEnd = None):
    '''Returns True if the compile was successful'''
    (output, error, returnCode) = self.outputCompile(includes, body, cleanup, codeBegin, codeEnd)
    output = self.filterCompileOutput(output+'\n'+error)
    return not (returnCode or len(output))

  # Should be static
  def getCompilerFlagsName(self, language, compilerOnly = 0):
    if language == 'C':
      flagsArg = 'CFLAGS'
    elif language == 'Cxx':
      if compilerOnly:
        flagsArg = 'CXX_CXXFLAGS'
      else:
        flagsArg = 'CXXFLAGS'
    elif language == 'FC':
      flagsArg = 'FFLAGS'
    else:
      raise RuntimeError('Unknown language: '+language)
    return flagsArg

  def getCompilerFlagsArg(self, compilerOnly = 0):
    '''Return the name of the argument which holds the compiler flags for the current language'''
    return self.getCompilerFlagsName(self.language[-1], compilerOnly)

  def filterLinkOutput(self, output):
    return self.framework.filterLinkOutput(output)

  def outputLink(self, includes, body, cleanup = 1, codeBegin = None, codeEnd = None, shared = 0):
    import sys

    (out, err, ret) = self.outputCompile(includes, body, cleanup = 0, codeBegin = codeBegin, codeEnd = codeEnd)
    out = self.filterCompileOutput(out+'\n'+err)
    if ret or len(out):
      self.framework.logPrint('Compile failed inside link\n'+out)
      self.linkerObj = ''
      return (out, ret)

    cleanup = cleanup and self.framework.doCleanup
    if shared == 'dynamic':
      cmd = self.getDynamicLinkerCmd()
    elif shared:
      cmd = self.getSharedLinkerCmd()
    else:
      cmd = self.getLinkerCmd()
    linkerObj = self.linkerObj
    def report(command, status, output, error):
      if error or status:
        self.framework.log.write('Possible ERROR while running linker: '+error)
        self.framework.log.write(' output: '+output)
        if status: self.framework.log.write('ret = '+str(status)+'\n')
        if error: self.framework.log.write('error message = {'+error+'}\n')
        self.framework.log.write(' in '+self.getLinkerCmd()+'\n')
        self.framework.log.write('Source:\n'+self.getCode(includes, body, codeBegin, codeEnd))
      return
    (out, err, ret) = Configure.executeShellCommand(cmd, checkCommand = report, log = self.framework.log)
    self.linkerObj = linkerObj
    if os.path.isfile(self.compilerObj): os.remove(self.compilerObj)
    if cleanup:
      if os.path.isfile(self.linkerObj):os.remove(self.linkerObj)
      pdbfile = os.path.splitext(self.linkerObj)[0]+'.pdb'
      if os.path.isfile(pdbfile): os.remove(pdbfile)
    return (out+err, ret)

  def checkLink(self, includes = '', body = '', cleanup = 1, codeBegin = None, codeEnd = None, shared = 0):
    (output, returnCode) = self.outputLink(includes, body, cleanup, codeBegin, codeEnd, shared)
    output = self.filterLinkOutput(output)
    return not (returnCode or len(output))

  # Should be static
  def getLinkerFlagsName(self, language):
    if language == 'C':
      flagsArg = 'LDFLAGS'
    elif language == 'Cxx':
      flagsArg = 'LDFLAGS'
    elif language == 'FC':
      flagsArg = 'LDFLAGS'
    else:
      raise RuntimeError('Unknown language: '+language)
    return flagsArg

  def getLinkerFlagsArg(self):
    '''Return the name of the argument which holds the linker flags for the current language'''
    return self.getLinkerFlagsName(self.language[-1])

  def outputRun(self, includes, body, cleanup = 1, defaultOutputArg = '', executor = None):
    if not self.checkLink(includes, body, cleanup = 0): return ('', 1)
    if not os.path.isfile(self.linkerObj) or not os.access(self.linkerObj, os.X_OK):
      self.framework.log.write('ERROR while running executable: '+self.linkerObj+' is not executable')
      return ('', 1)
    if self.framework.argDB['with-batch']:
      if defaultOutputArg:
        if defaultOutputArg in self.framework.argDB:
          return (self.framework.argDB[defaultOutputArg], 0)
        else:
          raise RuntimeError('Must give a default value for '+defaultOutputArg+' since executables cannot be run')
      else:
        raise RuntimeError('Running executables on this system is not supported')
    cleanup = cleanup and self.framework.doCleanup
    if executor:
      command = executor+' -np 1 ./'+self.linkerObj
    else:
      command = './'+self.linkerObj
    output  = ''
    error   = ''
    status  = 1
    self.framework.log.write('Executing: '+command+'\n')
    try:
      (output, error, status) = Configure.executeShellCommand(command, log = self.framework.log)
    except RuntimeError, e:
      self.framework.log.write('ERROR while running executable: '+str(e)+'\n')
    if os.path.isfile(self.compilerObj): os.remove(self.compilerObj)
    if cleanup and os.path.isfile(self.linkerObj): os.remove(self.linkerObj)
    return (output+error, status)

  def checkRun(self, includes = '', body = '', cleanup = 1, defaultArg = '', executor = None):
    (output, returnCode) = self.outputRun(includes, body, cleanup, defaultArg, executor)
    return not returnCode

  def splitLibs(self,libArgs):
    '''Takes a string containing a list of libraries (including potentially -L, -l, -w etc) and generates a list of libraries'''
    dirs = []
    libs = []
    for arg in libArgs.split(' '):
      if not arg: continue
      if arg.startswith('-L'):
        dirs.append(arg[2:])
      elif arg.startswith('-l'):
        libs.append(arg[2:])
      elif not arg.startswith('-'):
        libs.append(arg)
    libArgs = []
    for lib in libs:
      if not os.path.isabs(lib):
        added = 0
        for dir in dirs:
          if added:
	    break
	  for ext in ['a', 'so','dylib']:
            filename = os.path.join(dir, 'lib'+lib+'.'+ext)
            if os.path.isfile(filename):
              libArgs.append(filename)
              added = 1
              break
      else:
        libArgs.append(lib)
    return libArgs

  def splitIncludes(self,incArgs):
    '''Takes a string containing a list of include directories with -I and generates a list of includes'''
    includes = []
    for inc in incArgs.split(' '):
      if inc.startswith('-I'):
        # check if directory exists?
        includes.append(inc[2:])
    return includes

  def setupPackageDependencies(self, framework):
    '''All calls to the framework addPackageDependency() should be made here'''
    pass

  def setupDependencies(self, framework):
    '''All calls to the framework require() should be made here'''
    self.framework = framework

  def configure(self):
    pass

  def no_configure(self):
    pass
from __future__ import generators
import config.base

import os

class Configure(config.base.Configure):
  def __init__(self, framework):
    config.base.Configure.__init__(self, framework)
    self.headerPrefix = ''
    self.substPrefix  = ''
    self.use64BitPointers = 0
    self.usedMPICompilers = 0
    self.mainLanguage = 'C'
    return

  def __str__(self):
    desc = ['Compilers:']
    if hasattr(self, 'CC'):
      self.pushLanguage('C')
      desc.append('  C Compiler:         '+self.getCompiler()+' '+self.getCompilerFlags())
      if not self.getLinker() == self.getCompiler(): desc.append('  C Linker:           '+self.getLinker()+' '+self.getLinkerFlags())
      self.popLanguage()
    if hasattr(self, 'CXX'):
      self.pushLanguage('Cxx')
      desc.append('  C++ Compiler:       '+self.getCompiler()+' '+self.getCompilerFlags())
      if not self.getLinker() == self.getCompiler(): desc.append('  C++ Linker:         '+self.getLinker()+' '+self.getLinkerFlags())
      self.popLanguage()
    if hasattr(self, 'FC'):
      self.pushLanguage('FC')
      desc.append('  Fortran Compiler:   '+self.getCompiler()+' '+self.getCompilerFlags())
      if not self.getLinker() == self.getCompiler(): desc.append('  Fortran Linker:     '+self.getLinker()+' '+self.getLinkerFlags())
      self.popLanguage()
    desc.append('Linkers:')
    if hasattr(self, 'staticLinker'):
      desc.append('  Static linker:   '+self.getSharedLinker()+' '+self.AR_FLAGS)
    elif hasattr(self, 'sharedLinker'):
      desc.append('  Shared linker:   '+self.getSharedLinker()+' '+self.getSharedLinkerFlags())
    if hasattr(self, 'dynamicLinker'):
      desc.append('  Dynamic linker:   '+self.getDynamicLinker()+' '+self.getDynamicLinkerFlags())
    return '\n'.join(desc)+'\n'

  def setupHelp(self, help):
    import nargs

    help.addArgument('Compilers', '-with-cpp=<prog>', nargs.Arg(None, None, 'Specify the C preprocessor'))
    help.addArgument('Compilers', '-with-cc=<prog>',  nargs.Arg(None, None, 'Specify the C compiler'))
    help.addArgument('Compilers', '-with-cxx=<prog>', nargs.Arg(None, None, 'Specify the C++ compiler'))
    help.addArgument('Compilers', '-with-fc=<prog>',  nargs.Arg(None, None, 'Specify the Fortran compiler'))

    help.addArgument('Compilers', '-with-gnu-compilers=<bool>',      nargs.ArgBool(None, 1, 'Try to use GNU compilers'))
    help.addArgument('Compilers', '-with-vendor-compilers=<vendor>', nargs.Arg(None, '', 'Try to use vendor compilers (no argument all vendors, 0 no vendors)'))
    help.addArgument('Compilers', '-with-64-bit-pointers=<bool>',    nargs.ArgBool(None, 0, 'Use 64 bit compilers and libraries (currently need to specify vendor)'))

    help.addArgument('Compilers', '-CPP=<prog>',            nargs.Arg(None, None, 'Specify the C preprocessor'))
    help.addArgument('Compilers', '-CPPFLAGS=<string>',     nargs.Arg(None, '',   'Specify the C preprocessor options'))
    help.addArgument('Compilers', '-CXXPP=<prog>',          nargs.Arg(None, None, 'Specify the C++ preprocessor'))
    help.addArgument('Compilers', '-CC=<prog>',             nargs.Arg(None, None, 'Specify the C compiler'))
    help.addArgument('Compilers', '-CFLAGS=<string>',       nargs.Arg(None, '',   'Specify the C compiler options'))
    help.addArgument('Compilers', '-CXX=<prog>',            nargs.Arg(None, None, 'Specify the C++ compiler'))
    help.addArgument('Compilers', '-CXXFLAGS=<string>',     nargs.Arg(None, '',   'Specify the C++ compiler options'))
    help.addArgument('Compilers', '-CXX_CXXFLAGS=<string>', nargs.Arg(None, '',   'Specify the C++ compiler-only options'))
    help.addArgument('Compilers', '-CXXCPPFLAGS=<string>',  nargs.Arg(None, '',   'Specify the C++ preprocessor options'))
    help.addArgument('Compilers', '-FC=<prog>',             nargs.Arg(None, None, 'Specify the Fortran compiler'))
    help.addArgument('Compilers', '-FFLAGS=<string>',       nargs.Arg(None, '',   'Specify the Fortran compiler options'))

##    help.addArgument('Compilers', '-LD=<prog>',              nargs.Arg(None, None, 'Specify the executable linker'))
##    help.addArgument('Compilers', '-CC_LD=<prog>',           nargs.Arg(None, None, 'Specify the linker for C only'))
##    help.addArgument('Compilers', '-CXX_LD=<prog>',          nargs.Arg(None, None, 'Specify the linker for C++ only'))
##    help.addArgument('Compilers', '-FC_LD=<prog>',           nargs.Arg(None, None, 'Specify the linker for Fortran only'))
    help.addArgument('Compilers', '-LD_SHARED=<prog>',       nargs.Arg(None, None, 'Specify the shared linker'))
    help.addArgument('Compilers', '-LDFLAGS=<string>',       nargs.Arg(None, '',   'Specify the linker options'))
    help.addArgument('Compilers', '-executableFlags',        nargs.Arg(None, [], 'Specify the executable linker flags'))
    help.addArgument('Compilers', '-with-ar',                nargs.Arg(None, None,   'Specify the archiver'))
    help.addArgument('Compilers', '-AR',                     nargs.Arg(None, None,   'Specify the archiver flags'))
    help.addArgument('Compilers', '-AR_FLAGS',               nargs.Arg(None, None,   'Specify the archiver flags'))
    help.addArgument('Compilers', '-with-ranlib',            nargs.Arg(None, None,   'Specify ranlib'))
    help.addArgument('Compilers', '-with-shared',            nargs.ArgBool(None, 1, 'Enable shared libraries'))
    help.addArgument('Compilers', '-with-shared-ld=<prog>',  nargs.Arg(None, None, 'Specify the shared linker'))
    help.addArgument('Compilers', '-sharedLibraryFlags',     nargs.Arg(None, [], 'Specify the shared library flags'))
    help.addArgument('Compilers', '-with-dynamic',           nargs.ArgBool(None, 0, 'Enable dynamic libraries'))
    help.addArgument('Compilers', '-dynamicLibraryFlags',    nargs.Arg(None, [], 'Specify the dynamic library flags'))
    help.addArgument('Compilers', '-LIBS=<string>',          nargs.Arg(None, None, 'Specify extra libraries for all links'))
    return

  def setupDependencies(self, framework):
    config.base.Configure.setupDependencies(self, framework)
    self.headers = framework.require('config.headers', None)
    self.libraries = framework.require('config.libraries', None)
    return

  def isGNU(compiler):
    '''Returns true if the compiler is a GNU compiler'''
    try:
      (output, error, status) = config.base.Configure.executeShellCommand(compiler+' --help')
      output = output + error
      if output.find('Unrecognised option --help passed to ld') >=0:    # NAG f95 compiler
        return 0
      if output.find('www.gnu.org') >= 0 or output.find('developer.apple.com') >= 0 or output.find('bugzilla.redhat.com') >= 0 or output.find('gcc.gnu.org') >= 0 or (output.find('gcc version')>=0 and not output.find('Intel(R)')>= 0):
        return 1
    except RuntimeError:
      pass
    return 0
  isGNU = staticmethod(isGNU)

  def isIntel(compiler):
    '''Returns true if the compiler is a Intel compiler'''
    try:
      (output, error, status) = config.base.Configure.executeShellCommand(compiler+' --help')
      output = output + error
      if output.find('Intel Corporation') >= 0 :
        return 1
    except RuntimeError:
      pass
    return 0
  isIntel = staticmethod(isIntel)

  def isCygwin():
    '''Returns true if system is cygwin'''
    (output, error, status) = config.base.Configure.executeShellCommand('uname -s')
    if not status and output.lower().strip().find('cygwin') >= 0:
      return 1
    else:
      return 0
  isCygwin = staticmethod(isCygwin)

  def isSolaris():
    '''Returns true if system is solaris'''
    (output, error, status) = config.base.Configure.executeShellCommand('uname -s')
    if not status and output.lower().strip().find('sunos') >= 0:
      return 1
    else:
      return 0
  isSolaris = staticmethod(isSolaris)

  def isDarwin():
    '''Returns true if system is Darwin/MacOSX'''
    #replace self.framework.host_cpu == 'powerpc' and self.framework.host_vendor == 'apple' and self.framework.host_os.startswith('darwin'):
    (output, error, status) = config.base.Configure.executeShellCommand('uname -s')
    if not status:
      return output.lower().strip() == 'darwin'
    return 0
  isDarwin = staticmethod(isDarwin)

  def isWindows(compiler):
    '''Returns true if the compiler is a Windows compiler'''
    if compiler in ['icl', 'cl', 'bcc32', 'ifl', 'df']:
      return 1
    if compiler in ['ifort','f90'] and Configure.isCygwin():
      return 1
    if compiler in ['lib', 'tlib']:
      return 1
    return 0
  isWindows = staticmethod(isWindows)

  def useMPICompilers(self):
    if ('with-cc' in self.argDB and self.argDB['with-cc'] != '0') or 'CC' in self.argDB:
      return 0
    if ('with-cxx' in self.argDB and self.argDB['with-cxx'] != '0') or 'CXX' in self.argDB:
      return 0
    if ('with-fc' in self.argDB and self.argDB['with-fc'] != '0') or 'FC' in self.argDB:
      return 0
    if 'with-mpi' in self.argDB and self.argDB['with-mpi'] and self.argDB['with-mpi-compilers'] and not self.argDB['download-mpich'] == 1 and not self.argDB['download-lam'] == 1:
      return 1
    return 0

  def checkVendor(self):
    '''Determine the compiler vendor'''
    self.vendor = self.framework.argDB['with-vendor-compilers']
    if self.framework.argDB['with-vendor-compilers'] == 'no' or self.framework.argDB['with-vendor-compilers'] == 'false':
      self.vendor = None
    if self.framework.argDB['with-vendor-compilers'] == '1' or self.framework.argDB['with-vendor-compilers'] == 'yes' or self.framework.argDB['with-vendor-compilers'] == 'true':
      self.vendor = ''
    self.logPrint('Compiler vendor is "'+str(self.vendor)+'"')
    return

  def checkInitialFlags(self):
    '''Initialize the compiler and linker flags'''
    for language in ['C', 'Cxx', 'FC']:
      self.pushLanguage(language)
      for flagsArg in [self.getCompilerFlagsName(language), self.getCompilerFlagsName(language, 1), self.getLinkerFlagsName(language)]:
        setattr(self, flagsArg, self.argDB[flagsArg])
        self.framework.logPrint('Initialized '+flagsArg+' to '+str(getattr(self, flagsArg)))
      self.popLanguage()
    for flagsArg in ['CPPFLAGS', 'executableFlags', 'sharedLibraryFlags', 'dynamicLibraryFlags']:
      setattr(self, flagsArg, self.argDB[flagsArg])
      self.framework.logPrint('Initialized '+flagsArg+' to '+str(getattr(self, flagsArg)))
    if 'LIBS' in self.argDB:
      self.LIBS = self.argDB['LIBS']
    else:
      self.LIBS = ''
    return

  def checkCompiler(self, language):
    '''Check that the given compiler is functional, and if not raise an exception'''
    self.pushLanguage(language)
    if not self.checkCompile():
      self.popLanguage()
      raise RuntimeError('Cannot compile '+language+' with '+self.getCompiler()+'.')
    if not self.checkLink():
      self.popLanguage()
      raise RuntimeError('Cannot compile/link '+language+' with '+self.getCompiler()+'.')
    if not self.framework.argDB['with-batch']:
      if not self.checkRun():
        self.popLanguage()
        raise OSError('Cannot run executables created with '+language+'. It is likely that you will need to configure using --with-batch which allows configuration without interactive sessions.')
    self.popLanguage()
    return

  def generateCCompilerGuesses(self):
    '''Determine the C compiler using CC, then --with-cc, then MPI, then GNU, then vendors
       - Any given category can be excluded'''
    import os

    if self.framework.argDB.has_key('with-cc'):
      if self.isWindows(self.framework.argDB['with-cc']):
        yield 'win32fe '+self.framework.argDB['with-cc']
      else:
        yield self.framework.argDB['with-cc']
      raise RuntimeError('C compiler you provided with -with-cc='+self.framework.argDB['with-cc']+' does not work')
    elif self.framework.argDB.has_key('CC'):
      if 'CC' in os.environ and os.environ['CC'] == self.framework.argDB['CC']:
        self.startLine()
        print '\n*****WARNING: Using C compiler '+self.framework.argDB['CC']+' from environmental variable CC****\nAre you sure this is what you want? If not, unset that environmental variable and run configure again'
      if self.isWindows(self.framework.argDB['CC']):
        yield 'win32fe '+self.framework.argDB['CC']
      else:
        yield self.framework.argDB['CC']
      raise RuntimeError('C compiler you provided with -CC='+self.framework.argDB['CC']+' does not work')
    elif self.useMPICompilers() and 'with-mpi-dir' in self.argDB and os.path.isdir(os.path.join(self.argDB['with-mpi-dir'], 'bin')):
      self.usedMPICompilers = 1
      yield os.path.join(self.framework.argDB['with-mpi-dir'], 'bin', 'mpicc')
      yield os.path.join(self.framework.argDB['with-mpi-dir'], 'bin', 'hcc')
      yield os.path.join(self.framework.argDB['with-mpi-dir'], 'bin', 'mpcc_r')
      self.usedMPICompilers = 0
      raise RuntimeError('bin/<mpicc,hcc/mpcc_r> you provided with -with-mpi-dir='+self.framework.argDB['with-mpi-dir']+' does not work')
    else:
      if self.useMPICompilers():
        self.usedMPICompilers = 1
        if Configure.isGNU('mpicc') and self.framework.argDB['with-gnu-compilers']:
          yield 'mpicc'
        if Configure.isGNU('hcc') and self.framework.argDB['with-gnu-compilers']:
          yield 'hcc'
        if not Configure.isGNU('mpicc') and (not self.vendor is None):
          yield 'mpicc'
        if not Configure.isGNU('hcc') and (not self.vendor is None):
          yield 'hcc'
        if not self.vendor is None:
          yield 'mpcc_r'
          yield 'mpcc'
          yield 'mpxlc'
        self.usedMPICompilers = 0
      vendor = self.vendor
      if (not vendor) and self.framework.argDB['with-gnu-compilers']:
        yield 'gcc'
      if not self.vendor is None:
        if not vendor and not Configure.isGNU('cc'):
          yield 'cc'
        if vendor == 'borland' or not vendor:
          yield 'win32fe bcc32'
        if vendor == 'kai' or not vendor:
          yield 'kcc'
        if vendor == 'ibm' or not vendor:
          yield 'xlc'
        if vendor == 'intel' or not vendor:
          yield 'icc'
          yield 'ecc'          
          yield 'win32fe icl'
        if vendor == 'microsoft' or not vendor:
          yield 'win32fe cl'
        if vendor == 'portland' or not vendor:
          yield 'pgcc'
        if vendor == 'solaris' or not vendor:
          if not Configure.isGNU('cc'):
            yield 'cc'
      if self.framework.argDB['with-gnu-compilers']:
        yield 'gcc'
    return

  def checkCCompiler(self):
    '''Locate a functional C compiler'''
    if 'with-cc' in self.framework.argDB and self.framework.argDB['with-cc'] == '0':
      raise RuntimeError('A functional C compiler is necessary for configure')
    for compiler in self.generateCCompilerGuesses():
      try:
        if self.getExecutable(compiler, resultName = 'CC'):
          self.checkCompiler('C')
          if self.framework.argDB['with-64-bit-pointers']:
            if Configure.isGNU(self.CC):
              self.pushLanguage('C')
              try:
                self.addCompilerFlag('-m64')
                self.use64BitPointers = 1
              except RuntimeError, e:
                self.logPrint('GNU 64-bit C compilation not working: '+str(e))
              self.popLanguage()
            elif self.vendor == 'solaris':
              self.pushLanguage('C')
              try:
                self.addCompilerFlag('-xarch=v9')
                self.use64BitPointers = 1
              except RuntimeError, e:
                self.logPrint('Solaris 64-bit C compilation not working: '+str(e))
              self.popLanguage()
          break
      except RuntimeError, e:
        import os

        if os.path.basename(self.CC) == 'mpicc':
          self.framework.logPrint(' MPI installation '+self.getCompiler()+' is likely incorrect.\n  Use --with-mpi-dir to indicate an alternate MPI.')
        del self.CC
    if not hasattr(self, 'CC'):
      raise RuntimeError('Could not locate a functional C compiler')
    return

  def generateCPreprocessorGuesses(self):
    '''Determines the C preprocessor from CPP, then --with-cpp, then the C compiler'''
    if 'with-cpp' in self.framework.argDB:
      yield self.framework.argDB['with-cpp']
    elif 'CPP' in self.framework.argDB:
      yield self.framework.argDB['CPP']
    else:
      yield self.CC+' -E'
      yield self.CC+' --use cpp32'
    return

  def checkCPreprocessor(self):
    '''Locate a functional C preprocessor'''
    for compiler in self.generateCPreprocessorGuesses():
      try:
        if self.getExecutable(compiler, resultName = 'CPP'):
          self.pushLanguage('C')
          if not self.checkPreprocess('#include <stdlib.h>\n'):
            raise RuntimeError('Cannot preprocess C with '+self.CPP+'.')
          self.popLanguage()
          return
      except RuntimeError, e:
        self.popLanguage()
    raise RuntimeError('Cannot find a C preprocessor')
    return

  def generateCxxCompilerGuesses(self):
    '''Determine the Cxx compiler using CXX, then --with-cxx, then MPI, then GNU, then vendors
       - Any given category can be excluded'''
    import os

    if self.framework.argDB.has_key('with-c++'):
      raise RuntimeError('Keyword --with-c++ is WRONG, use --with-cxx')
    if self.framework.argDB.has_key('with-CC'):
      raise RuntimeError('Keyword --with-CC is WRONG, use --with-cxx')

    if self.framework.argDB.has_key('with-cxx'):
      if self.isWindows(self.framework.argDB['with-cxx']):
        yield 'win32fe '+self.framework.argDB['with-cxx']
      else:
        yield self.framework.argDB['with-cxx']
      raise RuntimeError('C++ compiler you provided with -with-cxx='+self.framework.argDB['with-cxx']+' does not work')
    elif self.framework.argDB.has_key('CXX'):
      if 'CXX' in os.environ and os.environ['CXX'] == self.framework.argDB['CXX']:
        self.startLine()
        print '\n*****WARNING: Using C++ compiler '+self.framework.argDB['CXX']+' from environmental variable CXX****\nAre you sure this is what you want? If not, unset that environmental variable and run configure again'
      if self.isWindows(self.framework.argDB['CXX']):
        yield 'win32fe '+self.framework.argDB['CXX']
      else:
        yield self.framework.argDB['CXX']
      raise RuntimeError('C++ compiler you provided with -CXX='+self.framework.argDB['CXX']+' does not work')
    elif self.useMPICompilers() and 'with-mpi-dir' in self.argDB and os.path.isdir(os.path.join(self.argDB['with-mpi-dir'], 'bin')):
      self.usedMPICompilers = 1
      yield os.path.join(self.framework.argDB['with-mpi-dir'], 'bin', 'mpicxx')
      yield os.path.join(self.framework.argDB['with-mpi-dir'], 'bin', 'hcp')
      yield os.path.join(self.framework.argDB['with-mpi-dir'], 'bin', 'mpic++')
      yield os.path.join(self.framework.argDB['with-mpi-dir'], 'bin', 'mpiCC')
      yield os.path.join(self.framework.argDB['with-mpi-dir'], 'bin', 'mpCC_r')
      self.usedMPICompilers = 0
      raise RuntimeError('bin/<mpiCC,mpicxx,hcp,mpCC_r> you provided with -with-mpi-dir='+self.framework.argDB['with-mpi-dir']+' does not work')
    else:
      if self.useMPICompilers():
        self.usedMPICompilers = 1
        if Configure.isGNU('mpicxx') and self.framework.argDB['with-gnu-compilers']:
          yield 'mpicxx'
        if not Configure.isGNU('mpicxx') and (not self.vendor is None):
          yield 'mpicxx'
        if Configure.isGNU('mpiCC') and self.framework.argDB['with-gnu-compilers']:
          yield 'mpiCC'
        if not Configure.isGNU('mpiCC') and (not self.vendor is None):
          yield 'mpiCC'
        if Configure.isGNU('mpic++') and self.framework.argDB['with-gnu-compilers']:
          yield 'mpic++'
        if not Configure.isGNU('mpic++') and (not self.vendor is None):
          yield 'mpic++'
        if not self.vendor is None:
          yield 'mpCC_r'
          yield 'mpCC'          
        self.usedMPICompilers = 0
      vendor = self.vendor
      if (not vendor) and self.framework.argDB['with-gnu-compilers']:
        yield 'g++'
      if not self.vendor is None:
        if not vendor:
          if not Configure.isGNU('c++'):
            yield 'c++'
          if not Configure.isGNU('CC'):
            yield 'CC'
          yield 'cxx'
          yield 'cc++'
        if vendor == 'borland' or not vendor:
          yield 'win32fe bcc32'
        if vendor == 'ibm' or not vendor:
          yield 'xlC'
        if vendor == 'intel' or not vendor:
          yield 'icpc'
          yield 'ccpc'          
          yield 'icc'
          yield 'ecc'          
          yield 'win32fe icl'
        if vendor == 'microsoft' or not vendor:
          yield 'win32fe cl'
        if vendor == 'portland' or not vendor:
          yield 'pgCC'
        if vendor == 'solaris':
          yield 'CC'
      if self.framework.argDB['with-gnu-compilers']:
        yield 'g++'
    return

  def checkCxxCompiler(self):
    '''Locate a functional Cxx compiler'''
    if 'with-cxx' in self.framework.argDB and self.framework.argDB['with-cxx'] == '0':
      if 'CXX' in self.framework.argDB:
        del self.framework.argDB['CXX']
      return
    for compiler in self.generateCxxCompilerGuesses():
      # Determine an acceptable extensions for the C++ compiler
      for ext in ['.cc', '.cpp', '.C']:
        self.framework.getCompilerObject('Cxx').sourceExtension = ext
        try:
          if self.getExecutable(compiler, resultName = 'CXX'):
            self.checkCompiler('Cxx')
            if self.framework.argDB['with-64-bit-pointers']:
              if Configure.isGNU(self.CC):
                self.pushLanguage('C++')
                try:
                  self.addCompilerFlag('-m64')
                except RuntimeError, e:
                  self.logPrint('GNU 64-bit C++ compilation not working: '+str(e))
                self.popLanguage()
              elif self.vendor == 'solaris':
                self.pushLanguage('C++')
                try:
                  self.addCompilerFlag('-xarch=v9')
                except RuntimeError, e:
                  self.logPrint('Solaris 64-bit C++ compilation not working: '+str(e))
                self.popLanguage()
            break
        except RuntimeError, e:
          import os

          if os.path.basename(self.CXX) in ['mpicxx', 'mpiCC']:
            self.logPrint('  MPI installation '+self.getCompiler()+' is likely incorrect.\n  Use --with-mpi-dir to indicate an alternate MPI.')
          del self.CXX
      if hasattr(self, 'CXX'):
        break
    return

  def generateCxxPreprocessorGuesses(self):
    '''Determines the Cxx preprocessor from CXXCPP, then --with-cxxcpp, then the Cxx compiler'''
    if 'with-cxxcpp' in self.framework.argDB:
      yield self.framework.argDB['with-cxxcpp']
    elif 'CXXCPP' in self.framework.argDB:
      yield self.framework.argDB['CXXCPP']
    else:
      yield self.CXX+' -E'
      yield self.CXX+' --use cpp32'
    return

  def checkCxxPreprocessor(self):
    '''Locate a functional Cxx preprocessor'''
    if not hasattr(self, 'CXX'):
      return
    for compiler in self.generateCxxPreprocessorGuesses():
      try:
        if self.getExecutable(compiler, resultName = 'CXXCPP'):
          self.pushLanguage('Cxx')
          if not self.checkPreprocess('#include <cstdlib>\n'):
            raise RuntimeError('Cannot preprocess Cxx with '+self.CXXCPP+'.')
          self.popLanguage()
          break
      except RuntimeError, e:
        import os

        if os.path.basename(self.CXXCPP) in ['mpicxx', 'mpiCC']:
          self.framework.logPrint('MPI installation '+self.getCompiler()+' is likely incorrect.\n  Use --with-mpi-dir to indicate an alternate MPI')
        self.popLanguage()
        del self.CXXCPP
    return

  def generateFortranCompilerGuesses(self):
    '''Determine the Fortran compiler using FC, then --with-fc, then MPI, then GNU, then vendors
       - Any given category can be excluded'''
    import os

    if self.framework.argDB.has_key('with-fc'):
      if self.isWindows(self.framework.argDB['with-fc']):
        yield 'win32fe '+self.framework.argDB['with-fc']
      else:
        yield self.framework.argDB['with-fc']
      raise RuntimeError('Fortran compiler you provided with --with-fc='+self.framework.argDB['with-fc']+' does not work')
    elif self.framework.argDB.has_key('FC'):
      if 'FC' in os.environ and os.environ['FC'] == self.framework.argDB['FC']:
        self.startLine()
        print '\n*****WARNING: Using Fortran compiler '+self.framework.argDB['FC']+' from environmental variable FC****\nAre you sure this is what you want? If not, unset that environmental variable and run configure again'
      if self.isWindows(self.framework.argDB['FC']):
        yield 'win32fe '+self.framework.argDB['FC']
      else:
        yield self.framework.argDB['FC']
      yield self.framework.argDB['FC']
      raise RuntimeError('Fortran compiler you provided with -FC='+self.framework.argDB['FC']+' does not work')
    elif self.useMPICompilers() and 'with-mpi-dir' in self.argDB and os.path.isdir(os.path.join(self.argDB['with-mpi-dir'], 'bin')):
      self.usedMPICompilers = 1
      yield os.path.join(self.framework.argDB['with-mpi-dir'], 'bin', 'mpif90')
      yield os.path.join(self.framework.argDB['with-mpi-dir'], 'bin', 'mpif77')
      yield os.path.join(self.framework.argDB['with-mpi-dir'], 'bin', 'mpxlf95_r')
      yield os.path.join(self.framework.argDB['with-mpi-dir'], 'bin', 'mpxlf90_r')
      yield os.path.join(self.framework.argDB['with-mpi-dir'], 'bin', 'mpxlf_r')
      self.usedMPICompilers = 0
      if os.path.isfile(os.path.join(self.framework.argDB['with-mpi-dir'], 'bin', 'mpif90')) or os.path.isfile((os.path.join(self.framework.argDB['with-mpi-dir'], 'bin', 'mpif77'))):
        raise RuntimeError('bin/mpif90[f77] you provided with --with-mpi-dir='+self.framework.argDB['with-mpi-dir']+' does not work\nRun with --with-fc=0 if you wish to use this MPI and disable Fortran')
    else:
      if self.useMPICompilers():
        self.usedMPICompilers = 1
        if Configure.isGNU('mpif90') and self.framework.argDB['with-gnu-compilers']:
          yield 'mpif90'
        if not Configure.isGNU('mpif90') and (not self.vendor is None):
          yield 'mpif90'
        if Configure.isGNU('mpif77') and self.framework.argDB['with-gnu-compilers']:
          yield 'mpif77'
        if not Configure.isGNU('mpif77') and (not self.vendor is None):
          yield 'mpif77'
        if not self.vendor is None:
          yield 'mpxlf_r'
          yield 'mpxlf'          
        self.usedMPICompilers = 0
      vendor = self.vendor
      if (not vendor) and self.framework.argDB['with-gnu-compilers']:
        yield 'gfortran'
        yield 'g95'
        yield 'g77'
      if not self.vendor is None:
        if vendor == 'ibm' or not vendor:
          yield 'xlf'
          yield 'xlf90'
        if not vendor or vendor in ['absoft', 'cray', 'dec', 'hp', 'sgi']:
          yield 'f90'
        if vendor == 'lahaye' or not vendor:
          yield 'lf95'
        if vendor == 'intel' or not vendor:
          yield 'win32fe ifort'
          yield 'win32fe ifl'
          yield 'ifort'
          yield 'ifc'
          yield 'efc'          
        if vendor == 'portland' or not vendor:
          yield 'pgf90'
          yield 'pgf77'
        if vendor == 'solaris' or not vendor:
          yield 'f95'
          yield 'f90'
          if not Configure.isGNU('f77'):
            yield 'f77'
      if self.framework.argDB['with-gnu-compilers']:
        yield 'gfortran'
        yield 'g95'
        yield 'g77'
    return

  def checkFortranCompiler(self):
    '''Locate a functional Fortran compiler'''
    if 'with-fc' in self.framework.argDB and self.framework.argDB['with-fc'] == '0':
      if 'FC' in self.framework.argDB:
        del self.framework.argDB['FC']
      return
    for compiler in self.generateFortranCompilerGuesses():
      try:
        if self.getExecutable(compiler, resultName = 'FC'):
          self.checkCompiler('FC')
          if self.framework.argDB['with-64-bit-pointers']:
            if Configure.isGNU(self.CC):
              self.pushLanguage('FC')
              try:
                self.addCompilerFlag('-m64')
              except RuntimeError, e:
                self.logPrint('GNU 64-bit Fortran compilation not working: '+str(e))
              self.popLanguage()
            elif self.vendor == 'solaris':
              self.pushLanguage('FC')
              try:
                self.addCompilerFlag('-xarch=v9')
              except RuntimeError, e:
                self.logPrint('Solaris 64-bit Fortran compilation not working: '+str(e))
              self.popLanguage()
          break
      except RuntimeError, e:
        import os

        if os.path.basename(self.FC) in ['mpif90', 'mpif77']:
         self.framework.logPrint(' MPI installation '+self.getCompiler()+' is likely incorrect.\n  Use --with-mpi-dir to indicate an alternate MPI.')
        del self.FC
    return

  def checkFortranComments(self):
    '''Make sure fortran comment "!" works'''
    self.pushLanguage('FC')
    if not self.checkCompile('! comment'):
      raise RuntimeError(self.getCompiler()+' cannot process fortran comments.')
    self.framework.logPrint('Fortran comments can use ! in column 1')
    self.popLanguage()
    return

  def checkBrokenMpif90(self):
    '''mpif90 from mpich1 and older c-preprocessor combinations misbehave'''
    self.pushLanguage('FC')
    # [if necessary] replace this with an actual test - which breaks the compile
    if self.getCompiler().find('mpif90') >=0:
      # should be a FPPFLAGS - not FFLAGS - but currently FPPFLAGS don't exist.
      self.addCompilerFlag('-I.')
    self.popLanguage()
    return    

  def checkCompilerFlag(self, flag, includes = '', body = '', compilerOnly = 0):
    '''Determine whether the compiler accepts the given flag'''
    flagsArg = self.getCompilerFlagsArg(compilerOnly)
    oldFlags = getattr(self, flagsArg)
    setattr(self, flagsArg, oldFlags+' '+flag)
    (output, error, status) = self.outputCompile(includes, body)
    output += error
    valid   = 1
    # Please comment each entry and provide an example line
    if status:
      valid = 0
      self.framework.logPrint('Rejecting compiler flag '+flag+' due to nonzero status from link')
    # Lahaye F95
    if output.find('Invalid suboption') >= 0:
      valid = 0
    if output.find('unrecognized option') >= 0 or output.find('unknown flag') >= 0 or output.find('unknown option') >= 0 or output.find('ignoring option') >= 0 or output.find('not recognized') >= 0 or output.find('ignored') >= 0 or output.find('illegal option') >= 0  or output.find('linker input file unused because linking not done') >= 0 or output.find('Unknown switch') >= 0 or output.find('PETSc Error') >= 0:
      valid = 0
      self.framework.logPrint('Rejecting compiler flag '+flag+' due to \n'+output)
    setattr(self, flagsArg, oldFlags)
    return valid

  def addCompilerFlag(self, flag, includes = '', body = '', extraflags = '', compilerOnly = 0):
    '''Determine whether the compiler accepts the given flag, and add it if valid, otherwise throw an exception'''
    if self.checkCompilerFlag(flag+' '+extraflags, includes, body, compilerOnly):
      flagsArg = self.getCompilerFlagsArg(compilerOnly)
      setattr(self, flagsArg, getattr(self, flagsArg)+' '+flag)
      self.framework.log.write('Added '+self.language[-1]+' compiler flag '+flag+'\n')
      return
    raise RuntimeError('Bad compiler flag: '+flag)

  def checkPIC(self):
    '''Determine the PIC option for each compiler
       - There needs to be a test that checks that the functionality is actually working'''
    # Instead of this, I need to add a link check
    #
    #if self.framework.argDB['PETSC_ARCH'].startswith('hpux') and not self.setCompilers.isGNU(self.framework.argDB['CC']):
    #  return
    #
    # Borland compiler accepts -PIC as -P, which means compile as C++ code,
    # Using this will force compilation, not linking when used as a link flag!!!
    # Since this is not what we intend with -PIC, just kick out if using borland.
    if self.CC.find('bcc32') >= 0:
      self.framework.logPrint("Skip checking PIC options since we have a Borland compiler")
      return
    if not self.framework.argDB['with-shared']:
      self.framework.logPrint("Skip checking PIC options since shared libraries are turned off")
      return
    languages = ['C']
    if hasattr(self, 'CXX'):
      languages.append('Cxx')
    if hasattr(self, 'FC'):
      languages.append('FC')
    for language in languages:
      self.pushLanguage(language)
      for testFlag in ['-PIC', '-fPIC', '-KPIC']:
        try:
          self.framework.logPrint('Trying '+language+' compiler flag '+testFlag)
          if not self.checkLinkerFlag(testFlag):
            self.framework.logPrint('Rejected '+language+' compiler flag '+testFlag+' because linker cannot handle it')
            continue
          self.addCompilerFlag(testFlag, compilerOnly = 1)
          break
        except RuntimeError:
          self.framework.logPrint('Rejected '+language+' compiler flag '+testFlag)
      self.popLanguage()
    return

  def getArchiverFlags(self, archiver):
    prog = os.path.basename(archiver).split(' ')[0]
    flag = ''
    if 'AR_FLAGS' in self.framework.argDB: 
      flag = self.framework.argDB['AR_FLAGS']
    elif prog.endswith('ar'):
      flag = 'cr'
    elif prog == 'win32fe':
      args = os.path.basename(archiver).split(' ')
      if 'lib' in args:
        flag = '-a'
      elif 'tlib' in args:
        flag = '-a -P512'
    return flag

  def generateArchiverGuesses(self):
    defaultAr = None
    if 'with-ar' in self.framework.argDB:
      if self.isWindows(self.framework.argDB['with-ar']):
        defaultAr = 'win32fe '+self.framework.argDB['with-ar']
      else:
        defaultAr = self.framework.argDB['with-ar']
    envAr = None
    if 'AR' in self.framework.argDB:
      if self.isWindows(self.framework.argDB['AR']):
        envAr = 'win32fe '+self.framework.argDB['AR']
      else:
        envAr = self.framework.argDB['AR']
    defaultRanlib = None
    if 'with-ranlib' in self.framework.argDB:
      defaultRanlib = self.framework.argDB['with-ranlib']
    envRanlib = None
    if 'RANLIB' in self.framework.argDB:
      envRanlib = self.framework.argDB['RANLIB']
    if defaultAr and defaultRanlib:
      yield(defaultAr,self.getArchiverFlags(defaultAr),defaultRanlib)
      raise RuntimeError('The archiver set --with-ar="'+defaultAr+'" is incompatible with the ranlib set --with-ranlib="'+defaultRanlib+'".')
    if defaultAr and envRanlib:
      yield(defaultAr,self.getArchiverFlags(defaultAr),envRanlib)
      raise RuntimeError('The archiver set --with-ar="'+defaultAr+'" is incompatible with the ranlib set (perhaps in your environment) -RANLIB="'+envRanlib+'".')
    if envAr and defaultRanlib:
      yield(envAr,self.getArchiverFlags(envAr),defaultRanlib)
      raise RuntimeError('The archiver set --AR="'+envAr+'" is incompatible with the ranlib set --with-ranlib="'+defaultRanlib+'".')
    if envAr and envRanlib:
      yield(envAr,self.getArchiverFlags(envAr),envRanlib)
      raise RuntimeError('The archiver set --AR="'+envAr+'" is incompatible with the ranlib set (perhaps in your environment) -RANLIB="'+envRanlib+'".')
    if defaultAr:
      yield (defaultAr,self.getArchiverFlags(defaultAr),'ranlib')
      yield (defaultAr,self.getArchiverFlags(defaultAr),'true')
      raise RuntimeError('You set a value for --with-ar='+defaultAr+'", but '+defaultAr+' cannot be used\n')
    if envAr:
      yield (envAr,self.getArchiverFlags(envAr),'ranlib')
      yield (envAr,self.getArchiverFlags(envAr),'true')
      raise RuntimeError('You set a value for -AR="'+envAr+'" (perhaps in your environment), but '+envAr+' cannot be used\n')
    if defaultRanlib:
      yield ('ar',self.getArchiverFlags('ar'),defaultRanlib)
      yield ('win32fe tlib',self.getArchiverFlags('win32fe tlib'),defaultRanlib)
      yield ('win32fe lib',self.getArchiverFlags('win32fe lib'),defaultRanlib)
      raise RuntimeError('You set --with-ranlib="'+defaultRanlib+'", but '+defaultRanlib+' cannot be used\n')
    if envRanlib:
      yield ('ar',self.getArchiverFlags('ar'),envRanlib)
      yield ('win32fe tlib',self.getArchiverFlags('win32fe tlib'),envRanlib)
      yield ('win32fe lib',self.getArchiverFlags('win32fe lib'),envRanlib)
      raise RuntimeError('You set -RANLIB="'+envRanlib+'" (perhaps in your environment), but '+defaultRanlib+' cannot be used\n')
    yield ('ar',self.getArchiverFlags('ar'),'ranlib -c')
    yield ('ar',self.getArchiverFlags('ar'),'ranlib')
    yield ('ar',self.getArchiverFlags('ar'),'true')
    yield ('win32fe tlib',self.getArchiverFlags('win32fe tlib'),'true')
    yield ('win32fe lib',self.getArchiverFlags('win32fe lib'),'true')
    return

  def checkArchiver(self):
    '''Check that the archiver exists and can make a library usable by the compiler'''
    def checkArchive(command, status, output, error):
      if error or status:
        self.framework.logPrint('Possible ERROR while running archiver: '+output)
        if status: self.framework.logPrint('ret = '+str(status))
        if error: self.framework.logPrint('error message = {'+error+'}')
        if os.path.isfile('conf1.o'):
          os.remove('conf1.o')
        raise RuntimeError('Archiver is not functional')
      return
    def checkRanlib(command, status, output, error):
      if error or status:
        self.framework.logPrint('Possible ERROR while running ranlib: '+output)
        if status: self.framework.logPrint('ret = '+str(status))
        if error: self.framework.logPrint('error message = {'+error+'}')
        if os.path.isfile('libconf1.a'):
          os.remove('libconf1.a')
        raise RuntimeError('Ranlib is not functional with your archiver.  Try --with-ranlib=true if ranlib is unnecessary.')
      return
    oldLibs = self.LIBS
    self.pushLanguage('C')
    for (archiver, arflags, ranlib) in self.generateArchiverGuesses():
      if not self.checkCompile('', 'int foo(int a) {\n  return a+1;\n}\n\n', cleanup = 0, codeBegin = '', codeEnd = ''):
        raise RuntimeError('Compiler is not functional')
      if os.path.isfile('conf1.o'):
        os.remove('conf1.o')
      os.rename(self.compilerObj, 'conf1.o')
      if self.getExecutable(archiver, getFullPath = 1, resultName = 'AR'):
        if self.getExecutable(ranlib, getFullPath = 1, resultName = 'RANLIB'):
          arext = 'a'
          try:
            (output, error, status) = config.base.Configure.executeShellCommand(self.AR+' '+arflags+' libconf1.'+arext+' conf1.o', checkCommand = checkArchive, log = self.framework.log)
            (output, error, status) = config.base.Configure.executeShellCommand(self.RANLIB+' libconf1.'+arext, checkCommand = checkRanlib, log = self.framework.log)
          except RuntimeError, e:
            self.logPrint(str(e))
            continue
          self.LIBS = '-L. -lconf1'
          success =  self.checkLink('extern int foo(int);', '  int b = foo(1);  if (b);\n')
          os.rename('libconf1.a','libconf1.lib')
          if not success:
            arext = 'lib'
            success = self.checkLink('extern int foo(int);', '  int b = foo(1);  if (b);\n')
            os.remove('libconf1.lib')
            if success:
              break
          else:
            os.remove('libconf1.lib')
            break
    else:
      if os.path.isfile('conf1.o'):
        os.remove('conf1.o')
      self.LIBS = oldLibs
      self.popLanguage()
      raise RuntimeError('Could not find a suitable archiver.  Use --with-ar to specify an archiver.')
    self.AR_FLAGS      = arflags
    self.AR_LIB_SUFFIX = arext
    self.framework.addMakeMacro('AR_FLAGS', self.AR_FLAGS)
    self.addMakeMacro('AR_LIB_SUFFIX', self.AR_LIB_SUFFIX)
    os.remove('conf1.o')
    self.LIBS = oldLibs
    self.popLanguage()
    return

  def setStaticLinker(self):
    language = self.language[-1]
    return self.framework.setSharedLinkerObject(language, self.framework.getLanguageModule(language).StaticLinker(self.framework.argDB))

  def generateSharedLinkerGuesses(self):
    if not self.framework.argDB['with-shared']:
      self.setStaticLinker()
      self.staticLinker = self.AR
      self.staticLibraries = 1
      self.LDFLAGS = ''
      yield (self.AR, [], self.AR_LIB_SUFFIX)
      raise RuntimeError('Archiver failed static link check')
    if 'with-shared-ld' in self.framework.argDB:
      yield (self.framework.argDB['with-shared-ld'], [], 'so')
    if 'LD_SHARED' in self.framework.argDB:
      yield (self.framework.argDB['LD_SHARED'], [], 'so')
    if hasattr(self, 'CXX') and self.mainLanguage == 'Cxx':
      # C++ compiler default
      yield (self.CXX, ['-shared'], 'so')
    # C compiler default
    yield (self.CC, ['-shared'], 'so')
    # Solaris default
    if Configure.isSolaris():
      if hasattr(self, 'CXX') and self.mainLanguage == 'Cxx':
        yield (self.CXX, ['-G'], 'so')
      yield (self.CC, ['-G'], 'so')
    # Mac OSX
    # undefined warning must also have flat_namespace
    if Configure.isDarwin():
      # yield ('libtool', ['-noprebind','-dynamic','-single_module','-flat_namespace -undefined warning','-multiply_defined suppress'], 'dylib')
    #yield (self.CC, ['-dynamiclib', '-flat_namespace', '-undefined warning', '-multiply_defined suppress', '-single_module'], 'dylib')
        yield (self.CC, ['-dynamiclib', '-single_module', '-undefined dynamic_lookup', '-multiply_defined suppress'], 'dylib')
    # Default to static linker
    self.setStaticLinker()
    self.staticLinker = self.AR
    self.staticLibraries = 1
    self.LDFLAGS = ''
    yield (self.AR, [], self.AR_LIB_SUFFIX)
    raise RuntimeError('Archiver failed static link check')

  def checkSharedLinker(self):
    '''Check that the linker can produce shared libraries'''
    self.sharedLibraries = 0
    self.staticLibraries = 0
    for linker, flags, ext in self.generateSharedLinkerGuesses():
      self.logPrint('Checking shared linker '+linker+' using flags '+str(flags))
      if self.getExecutable(linker, resultName = 'LD_SHARED'):
        flagsArg = self.getLinkerFlagsArg()
        goodFlags = filter(self.checkLinkerFlag, flags)
        testMethod = 'foo'
        self.sharedLinker = self.LD_SHARED
        self.sharedLibraryFlags = goodFlags
        self.sharedLibraryExt = ext
        if self.checkLink(includes = 'int '+testMethod+'(void) {return 0;}\n', codeBegin = '', codeEnd = '', cleanup = 0, shared = 1):
          oldLibs = self.LIBS
          self.LIBS += ' -L. -lconftest'
          if self.checkLink(includes = 'int foo(void);', body = 'int ret = foo();\nif(ret);'):
            os.remove('libconftest.'+self.sharedLibraryExt)
            self.LIBS = oldLibs
            self.sharedLibraries = 1
            self.logPrint('Using shared linker '+self.sharedLinker+' with flags '+str(self.sharedLibraryFlags)+' and library extension '+self.sharedLibraryExt)
            break
          self.LIBS = oldLibs
          os.remove('libconftest.'+self.sharedLibraryExt)
        if os.path.isfile(self.linkerObj): os.remove(self.linkerObj)
        del self.LD_SHARED 
        del self.sharedLinker
    return

  def checkLinkerFlag(self, flag):
    '''Determine whether the linker accepts the given flag'''
    flagsArg = self.getLinkerFlagsArg()
    oldFlags = getattr(self, flagsArg)
    setattr(self, flagsArg, oldFlags+' '+flag)
    (output, status) = self.outputLink('', '')
    valid = 1
    if status:
      valid = 0
      self.framework.logPrint('Rejecting linker flag '+flag+' due to nonzero status from link')
    if output.find('Unrecognized command line option') >= 0 or output.find('unrecognized option') >= 0 or output.find('unknown flag') >= 0 or (output.find('bad ') >= 0 and output.find(' option') >= 0) or output.find('linker input file unused because linking not done') >= 0 or output.find('flag is ignored') >= 0 or output.find('Invalid option') >= 0 or output.find('unknown option') >= 0 or output.find('ignoring option') >= 0:
      valid = 0
      self.framework.logPrint('Rejecting '+self.language[-1]+' linker flag '+flag+' due to \n'+output)
    else:
      self.framework.logPrint('Valid '+self.language[-1]+' linker flag '+flag)
    setattr(self, flagsArg, oldFlags)
    return valid

  def addLinkerFlag(self, flag):
    '''Determine whether the linker accepts the given flag, and add it if valid, otherwise throw an exception'''
    if self.checkLinkerFlag(flag):
      flagsArg = self.getLinkerFlagsArg()
      setattr(self, flagsArg, getattr(self, flagsArg)+' '+flag)
      return
    raise RuntimeError('Bad linker flag: '+flag)

  def checkLinkerMac(self):
    '''Tests some Apple Mac specific linker flags'''
    languages = ['C']
    if hasattr(self, 'CXX'):
      languages.append('Cxx')
    if hasattr(self, 'FC'):
      languages.append('FC')
    for language in languages:
      self.pushLanguage(language)
      #for testFlag in [ '-flat_namespace']:
      #  try:
      #    self.addLinkerFlag(testFlag)
      #  except:
      #    pass
      #for testFlag in ['-force_flat_namespace','-Wl,-multiply_defined,suppress', '-Wl,-multiply_defined -Wl,suppress']:
      #  if self.checkLinkerFlag(testFlag):
      #    self.executableFlags.append(testFlag)
      self.popLanguage()
    return

  def checkSharedLinkerPaths(self):
    '''Determine the shared linker path options
       - IRIX: -rpath
       - Linux, OSF: -Wl,-rpath,
       - Solaris: -R
       - FreeBSD: -Wl,-R,'''
    languages = ['C']
    if hasattr(self, 'CXX'):
      languages.append('Cxx')
    if hasattr(self, 'FC'):
      languages.append('FC')
    for language in languages:
      flag = '-L'
      self.pushLanguage(language)
      for testFlag in ['-Wl,-rpath,', '-rpath ', '-R', '-Wl,-R,']:
        self.framework.logPrint('Trying '+language+' linker flag '+testFlag)
        if self.checkLinkerFlag(testFlag+os.path.abspath(os.getcwd())):
          flag = testFlag
          break
        else:
          self.framework.logPrint('Rejected '+language+' linker flag '+testFlag)
      self.popLanguage()
      setattr(self, language+'SharedLinkerFlag', flag)
    return

  def checkLibC(self):
    '''Test whether we need to explicitly include libc in shared linking
       - Mac OSX requires an explicit reference to libc for shared linking'''
    self.explicitLibc = None
    tmpCompilerDefines   = self.compilerDefines
    self.compilerDefines = ''
    code = '#include <stdlib.h> \nint foo(void) {void *chunk = malloc(31); free(chunk); return 0;}\n'
    if self.checkLink(includes = code, codeBegin = '', codeEnd = '', shared = 1):
      self.logPrint('Shared linking does not require an explicit libc reference')
      self.compilerDefines = tmpCompilerDefines
      return
    oldLibs = self.LIBS
    self.LIBS += '-lc '
    if self.checkLink(includes = code, codeBegin = '', codeEnd = '', shared = 1):
      self.logPrint('Shared linking requires an explicit libc reference')
      self.compilerDefines = tmpCompilerDefines
      self.explicitLibc = ['libc.so']
      return
    self.LIBS = oldLibs
    self.compilerDefines = tmpCompilerDefines
    self.logPrint('*** WARNING *** Shared linking may not function on this architecture')
    raise RuntimeError('Shared linking may not function on this architecture')

  def generateDynamicLinkerGuesses(self):
    if 'with-dynamic-ld' in self.framework.argDB:
      yield (self.framework.argDB['with-dynamic-ld'], [], 'so')
    # Mac OSX
    if Configure.isDarwin():
      if hasattr(self, 'CXX') and self.mainLanguage == 'Cxx':
        #yield (self.CXX, ['-bundle', '-flat_namespace', '-undefined warning', '-multiply_defined suppress'], 'so')
        yield (self.CXX, ['-bundle', '-undefined dynamic_lookup', '-multiply_defined suppress'], 'so')
      #yield (self.CC, ['-bundle', '-flat_namespace', '-undefined warning', '-multiply_defined suppress'], 'so')
      yield (self.CC, ['-bundle', '-undefined dynamic_lookup', '-multiply_defined suppress'], 'so')
    # Shared default
    if hasattr(self, 'sharedLinker'):
      yield (self.sharedLinker, self.sharedLibraryFlags, 'so')
    # C++ Compiler default
    if hasattr(self, 'CXX') and self.mainLanguage == 'Cxx':
      yield (self.CXX, ['-shared'], 'so')
    # C Compiler default
    yield (self.CC, ['-shared'], 'so')
    raise RuntimeError('Unable to find working dynamic linker')

  def checkDynamicLinker(self):
    '''Check that the linker can produce dynamic libraries'''
    self.dynamicLibraries = 0
    if not self.framework.argDB['with-dynamic']:
      return
    if not self.headers.check('dlfcn.h'):
      self.logPrint('Dynamic libraries disabled since dlfcn.h was missing')
      return
    if not self.libraries.add('dl', ['dlopen', 'dlsym', 'dlclose']):
      if not self.libraries.check('', ['dlopen', 'dlsym', 'dlclose']):
        self.logPrint('Dynamic linking disabled since functions dlopen(), dlsym(), and dlclose() were not found')
        return
    for linker, flags, ext in self.generateDynamicLinkerGuesses():
      self.logPrint('Checking dynamic linker '+linker+' using flags '+str(flags))
      if self.getExecutable(linker, resultName = 'dynamicLinker'):
        flagsArg = self.getLinkerFlagsArg()
        goodFlags = filter(self.checkLinkerFlag, flags)
        self.dynamicLibraryFlags = goodFlags
        self.dynamicLibraryExt = ext
        testMethod = 'foo'
        if self.checkLink(includes = 'int '+testMethod+'(void) {return 0;}\n', codeBegin = '', codeEnd = '', cleanup = 0, shared = 'dynamic'):
          code = '''
void *handle = dlopen("./libconftest.so", 0);
int (*foo)(void) = (int (*)(void)) dlsym(handle, "foo");

if (!foo) {
  printf("%s\\n", dlerror());
  return -1;
}
if ((*foo)()) {
  printf("Invalid return from foo()\\n");
  return -1;
}
if (dlclose(handle)) {
  printf("Could not close library\\n");
  return -1;
}
'''
          if self.checkLink(includes = '#include<dlfcn.h>', body = code):
            os.remove('libconftest.'+self.dynamicLibraryExt)
            self.dynamicLibraries = 1
            self.logPrint('Using dynamic linker '+self.dynamicLinker+' with flags '+str(self.dynamicLibraryFlags)+' and library extension '+self.dynamicLibraryExt)
            break
          os.remove('libconftest.'+self.dynamicLibraryExt)
        if os.path.isfile(self.linkerObj): os.remove(self.linkerObj)
        del self.dynamicLinker
    return

  def output(self):
    '''Output module data as defines and substitutions'''
    if hasattr(self, 'CC'):
      self.addSubstitution('CC', self.CC)
      self.addSubstitution('CFLAGS', self.CFLAGS)
      self.addMakeMacro('CC_LINKER_SLFLAG', self.CSharedLinkerFlag)
    if hasattr(self, 'CPP'):
      self.addSubstitution('CPP', self.CPP)
      self.addSubstitution('CPPFLAGS', self.CPPFLAGS)
    if hasattr(self, 'CXX'):
      self.addSubstitution('CXX', self.CXX)
      self.addSubstitution('CXX_CXXFLAGS', self.CXX_CXXFLAGS)
      self.addSubstitution('CXXFLAGS', self.CXXFLAGS)
      self.addSubstitution('CXX_LINKER_SLFLAG', self.CxxSharedLinkerFlag)
    else:
      self.addSubstitution('CXX', '')
    if hasattr(self, 'CXXCPP'):
      self.addSubstitution('CXXCPP', self.CXXCPP)
    if hasattr(self, 'FC'):
      self.addSubstitution('FC', self.FC)
      self.addSubstitution('FFLAGS', self.FFLAGS)
      self.addMakeMacro('FC_LINKER_SLFLAG', self.FCSharedLinkerFlag)
    else:
      self.addSubstitution('FC', '')
    self.addSubstitution('LDFLAGS', self.LDFLAGS)
    self.addSubstitution('LIBS', self.LIBS)
    if hasattr(self, 'sharedLibraryFlags'):
      self.addSubstitution('SHARED_LIBRARY_FLAG', ' '.join(self.sharedLibraryFlags))
    else:
      self.addSubstitution('SHARED_LIBRARY_FLAG','')
    return

  def configure(self):
    self.executeTest(self.checkVendor)
    self.executeTest(self.checkInitialFlags)
    self.executeTest(self.checkCCompiler)
    self.executeTest(self.checkCPreprocessor)
    self.executeTest(self.checkCxxCompiler)
    self.executeTest(self.checkFortranCompiler)
    if hasattr(self, 'FC'):
      self.executeTest(self.checkFortranComments)
      self.executeTest(self.checkBrokenMpif90)
    self.executeTest(self.checkPIC)
    self.executeTest(self.checkArchiver)
    self.executeTest(self.checkSharedLinker)
    if Configure.isDarwin():
      self.executeTest(self.checkLinkerMac)
    self.executeTest(self.checkSharedLinkerPaths)
    if not self.staticLibraries:
      self.executeTest(self.checkLibC)
    self.executeTest(self.checkDynamicLinker)
    self.executeTest(self.output)
    return

  def no_configure(self):
    if self.staticLibraries:
      self.setStaticLinker()
    return


On Oct 24, 2005, at 1:00 PM, users-requ...@open-mpi.org wrote:

Send users mailing list submissions to

To subscribe or unsubscribe via the World Wide Web, visit
or, via email, send a message with subject or body 'help' to

You can reach the person managing the list at

When replying, please edit your Subject line so it is more specific
than "Re: Contents of users digest..."


Today's Topics:

   1. Re: Correction to 'Questions about mpif90/g95' (Jeff Squyres)


----------------------------------------------------------------------

Message: 1
Date: Mon, 24 Oct 2005 11:01:37 -0500
From: Jeff Squyres <jsquy...@open-mpi.org>
Subject: Re: [O-MPI users] Correction to 'Questions about mpif90/g95'
To: Open MPI Users <us...@open-mpi.org>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed

We actually do not have profiling versions of the MPI_Wtick and 
MPI_Wtime functions -- the MPI standard says that we don't have to 
(indeed, in Open MPI, they're inline functions in mpi.h).

I just built the PETSc tests last week with no problem, however (but on 
Linux, not OSX).  Can you send more specific information about how you 
built PETSc so that I can try to replicate the problem?



Charles Williams wrote:

I'm sorry about my previous post.  It turns out that was an experiment 
of mine where I created a dynamic library for libmpi_f90, which doesn't 
happen normally.  My test example now runs, but I still have problems 
with PETSc:

make test
Running test examples to verify correct installation
/Users/willic3/geoframe/tools/petsc/src/snes/examples/tutorials
--------------Error detected during compile or link!-----------------------
mpic++ -c -Wall -g3 -fPIC 
-I/PETSc3/geodynamics/PetscSimulationsViewers/src 
-I/Users/willic3/geoframe/tools/petsc 
-I/Users/willic3/geoframe/tools/petsc/bmake/darwin8.2.0-openmpi-opt 
-I/Users/willic3/geoframe/tools/petsc/include 
-I/Users/willic3/geoframe/tools/openmpi/include 
-D__SDIR__="src/snes/examples/tutorials/" ex19.c
mpic++ -Wall -g3  -o ex19  ex19.o 
-L/Users/willic3/geoframe/tools/petsc/lib/darwin8.2.0-openmpi-opt 
-L/Users/willic3/geoframe/tools/petsc/lib/darwin8.2.0-openmpi-opt 
-lpetscsnes -lpetscksp -lpetscdm -lpetscmat -lpetscvec -lpetsc    
-L/usr/X11R6/lib -lX11 
/System/Library/Frameworks/vecLib.framework/vecLib 
-L/Users/willic3/geoframe/tools/openmpi/lib 
-L/Users/willic3/geoframe/export/pythia-0.8/lib 
-L/Users/willic3/geoframe/tools/lib 
-L/usr/lib/gcc/powerpc-apple-darwin8/4.0.0 
-L/usr/lib/gcc/powerpc-apple-darwin8/4.0.0/../../.. -ldl -lmpi -lorte 
-lopal -lgcc_eh -lSystemStubs -lmx -lSystem -lf95 -lm 
-L/sw/bin/../lib/gcc-lib/powerpc-apple-darwin8/4.0.2/ 
-L/sw/bin/../lib/gcc-lib/powerpc-apple-darwin8/4.0.2 
-L/Users/willic3/geoframe/export/pythia-0.8/lib// 
-L/Users/willic3/geoframe/tools/lib// 
-L/Users/willic3/geoframe/tools/openmpi/lib// 
-L/sw/lib/gcc-lib/powerpc-apple-darwin8/4.0.2/ -L/usr/lib/gcc// 
-L/sw/bin/../lib/gcc-lib/powerpc-apple-darwin8/4.0.2/// 
-L/sw/lib/gcc-lib/powerpc-apple-darwin8/4.0.2/// -L/usr/lib// -lm 
-L/Users/willic3/geoframe/tools/openmpi/lib 
-L/Users/willic3/geoframe/export/pythia-0.8/lib 
-L/Users/willic3/geoframe/tools/lib 
-L/usr/lib/gcc/powerpc-apple-darwin8/4.0.0 
-L/usr/lib/gcc/powerpc-apple-darwin8/4.0.0/../../.. -ldl -lmpi -lorte 
-lopal -lgcc_eh -lSystemStubs -lmx -lSystem -lmpi_cxx -lstdc++ -lgcc_s 
-L/Users/willic3/geoframe/tools/openmpi/lib 
-L/Users/willic3/geoframe/export/pythia-0.8/lib 
-L/Users/willic3/geoframe/tools/lib 
-L/usr/lib/gcc/powerpc-apple-darwin8/4.0.0 
-L/usr/lib/gcc/powerpc-apple-darwin8/4.0.0/../../.. -ldl -lmpi -lorte 
-lopal -lgcc_eh -lSystemStubs -lmx -lSystem -lmpi_cxx -lstdc++ -lgcc_s 
-L/Users/willic3/geoframe/tools/openmpi/lib 
-L/Users/willic3/geoframe/export/pythia-0.8/lib 
-L/Users/willic3/geoframe/tools/lib 
-L/usr/lib/gcc/powerpc-apple-darwin8/4.0.0 
-L/usr/lib/gcc/powerpc-apple-darwin8/4.0.0/../../.. -ldl -lmpi -lorte 
-lopal -lgcc_eh -lSystemStubs -lmx -lSystem -ldl
/usr/bin/ld: Undefined symbols:
_pmpi_wtick__
_pmpi_wtime__
collect2: ld returned 1 exit status
make[2]: [ex19] Error 1 (ignored)
etc., etc.

Does anyone have any ideas?

Thanks,
Charles


Charles A. Williams

Dept. of Earth & Environmental Sciences

Science Center, 2C01B

Rensselaer Polytechnic Institute

Troy, NY  12180

Phone:    (518) 276-3369

FAX:        (518) 276-2012

e-mail:    will...@rpi.edu <mailto:will...@rpi.edu>




------------------------------------------------------------------------

_______________________________________________
users mailing list



-- 
{+} Jeff Squyres
{+} The Open MPI Project


------------------------------

_______________________________________________
users mailing list

End of users Digest, Vol 117, Issue 1
*************************************



Charles A. Williams

Dept. of Earth & Environmental Sciences

Science Center, 2C01B

Rensselaer Polytechnic Institute

Troy, NY  12180

Phone:    (518) 276-3369

FAX:        (518) 276-2012

e-mail:    will...@rpi.edu



Reply via email to