1import config.base 2import os 3import re 4 5class Configure(config.base.Configure): 6 def __init__(self, framework): 7 config.base.Configure.__init__(self, framework) 8 self.headerPrefix = 'PETSC' 9 self.substPrefix = 'PETSC' 10 return 11 12 def __str1__(self): 13 if not hasattr(self, 'arch'): 14 return '' 15 desc = ['PETSc:'] 16 desc.append(' PETSC_ARCH: '+str(self.arch)) 17 return '\n'.join(desc)+'\n' 18 19 def setupHelp(self, help): 20 import nargs 21 help.addArgument('PETSc', '-PETSC_ARCH=<string>', nargs.Arg(None, None, 'The configuration name')) 22 help.addArgument('PETSc', '-with-petsc-arch=<string>',nargs.Arg(None, None, 'The configuration name')) 23 help.addArgument('PETSc', '-force=<bool>', nargs.ArgBool(None, 0, 'Bypass configure hash caching, and run to completion')) 24 return 25 26 def setupDependencies(self, framework): 27 self.sourceControl = framework.require('config.sourceControl',self) 28 self.petscdir = framework.require('PETSc.options.petscdir', self) 29 return 30 31 def setNativeArchitecture(self): 32 import sys 33 arch = 'arch-' + sys.platform.replace('cygwin','mswin') 34 # use opt/debug, c/c++ tags.s 35 arch+= '-'+self.framework.argDB['with-clanguage'].lower().replace('+','x') 36 if self.framework.argDB['with-debugging']: 37 arch += '-debug' 38 else: 39 arch += '-opt' 40 self.nativeArch = arch 41 return 42 43 def configureArchitecture(self): 44 '''Checks PETSC_ARCH and sets if not set''' 45 # Warn if PETSC_ARCH doesnt match env variable 46 if 'PETSC_ARCH' in self.framework.argDB and 'PETSC_ARCH' in os.environ and self.framework.argDB['PETSC_ARCH'] != os.environ['PETSC_ARCH']: 47 self.logPrintBox('''\ 48Warning: PETSC_ARCH from environment does not match command-line or name of script. 49Warning: Using from command-line or name of script: %s, ignoring environment: %s''' % (str(self.framework.argDB['PETSC_ARCH']), str(os.environ['PETSC_ARCH']))) 50 os.environ['PETSC_ARCH'] = self.framework.argDB['PETSC_ARCH'] 51 if 'with-petsc-arch' in self.framework.argDB: 52 self.arch = self.framework.argDB['with-petsc-arch'] 53 msg = 'option -with-petsc-arch='+str(self.arch) 54 elif 'PETSC_ARCH' in self.framework.argDB: 55 self.arch = self.framework.argDB['PETSC_ARCH'] 56 msg = 'option PETSC_ARCH='+str(self.arch) 57 elif 'PETSC_ARCH' in os.environ: 58 self.arch = os.environ['PETSC_ARCH'] 59 msg = 'environment variable PETSC_ARCH='+str(self.arch) 60 else: 61 self.arch = self.nativeArch 62 if self.arch.find('/') >= 0 or self.arch.find('\\') >= 0: 63 raise RuntimeError('PETSC_ARCH should not contain path characters, but you have specified with '+msg) 64 if self.arch.startswith('-'): 65 raise RuntimeError('PETSC_ARCH should not start with "-", but you have specified with '+msg) 66 if self.arch.startswith('.'): 67 raise RuntimeError('PETSC_ARCH should not start with ".", but you have specified with '+msg) 68 if not len(self.arch): 69 raise RuntimeError('PETSC_ARCH cannot be empty string. Use a valid string or do not set one. Currently set with '+msg) 70 self.archBase = re.sub(r'^(\w+)[-_]?.*$', r'\1', self.arch) 71 return 72 73 def makeDependency(self,hash,hashfile): 74 '''Deletes the current hashfile and saves the hashfile name and its value in framework so that''' 75 '''framework.Configure can create the file upon success of configure''' 76 import os 77 if hash: 78 self.framework.hash = hash 79 self.framework.hashfile = hashfile 80 self.logPrint('Deleting configure hash file: '+hashfile) 81 try: 82 os.remove(hashfile) 83 except: 84 self.logPrint('Unable to delete configure hash file: '+hashfile) 85 return 86 self.logPrint('Deleted configure hash file: '+hashfile) 87 88 def checkDependency(self): 89 '''Checks if configure needs to be run''' 90 '''Checks if files in config have changed, the command line options have changed or the PATH has changed''' 91 import os 92 import sys 93 import hashlib 94 hashfile = os.path.join(self.arch,'lib','petsc','conf','configure-hash') 95 args = sorted(set(filter(lambda x: not (x.startswith('PETSC_ARCH') or x == '--force'),sys.argv[1:]))) 96 hash = 'args:\n' + '\n'.join(' '+a for a in args) + '\n' 97 hash += 'PATH=' + os.environ.get('PATH', '') + '\n' 98 try: 99 for root, dirs, files in os.walk('config'): 100 if root == 'config': 101 dirs.remove('examples') 102 for f in files: 103 if not f.endswith('.py') or f.startswith('.') or f.startswith('#'): 104 continue 105 fname = os.path.join(root, f) 106 with open(fname,'rb') as f: 107 hash += hashlib.sha256(f.read()).hexdigest() + ' ' + fname + '\n' 108 except: 109 self.logPrint('Error generating file list/hash from config directory for configure hash, forcing new configuration') 110 self.makeDependency(None,hashfile) 111 return 112 if self.argDB['force']: 113 self.makeDependency(hash,hashfile) 114 return 115 a = '' 116 try: 117 with open(hashfile, 'r') as f: 118 a = f.read() 119 except: 120 # no previous record so write current hash 121 self.makeDependency(hash,hashfile) 122 return 123 if a == hash: 124 self.logPrint('configure hash file: '+hashfile+' matches; no need to run configure.') 125 print('Your configure options and state has not changed; no need to run configure') 126 print('However you can force a configure run using the option: --force') 127 sys.exit() 128 self.makeDependency(hash,hashfile) 129 self.logPrint('configure hash file: '+hashfile+' does not match\n'+a+'\n---\n'+hash+'\n need to run configure') 130 131 def configure(self): 132 self.executeTest(self.setNativeArchitecture) 133 self.executeTest(self.configureArchitecture) 134 # required by top-level configure.py 135 self.framework.arch = self.arch 136 self.checkDependency() 137 return 138