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 |
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:
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 |