1#!/usr/bin/env python 2import os 3import sys 4import commands 5# to load ~/.pythonrc.py before inserting correct BuildSystem to path 6import user 7extraLogs = [] 8petsc_arch = '' 9 10# Use en_US as language so that BuildSystem parses compiler messages in english 11os.environ['LANG'] = 'en_US' 12 13if not hasattr(sys, 'version_info') or not sys.version_info[1] >= 2 or not sys.version_info[0] >= 2: 14 print '**** You must have Python version 2.2 or higher to run config/configure.py ******' 15 print '* Python is easy to install for end users or sys-admin. *' 16 print '* http://www.python.org/download/ *' 17 print '* *' 18 print '* You CANNOT configure PETSc without Python *' 19 print '* http://www.mcs.anl.gov/petsc/petsc-as/documentation/installation.html *' 20 print '*********************************************************************************' 21 sys.exit(4) 22 23def check_petsc_arch(opts): 24 # If PETSC_ARCH not specified - use script name (if not configure.py) 25 global petsc_arch 26 found = 0 27 for name in opts: 28 if name.find('PETSC_ARCH=') >= 0: 29 petsc_arch=name.split('=')[1] 30 found = 1 31 break 32 # If not yet specified - use the filename of script 33 if not found: 34 filename = os.path.basename(sys.argv[0]) 35 if not filename.startswith('configure') and not filename.startswith('reconfigure'): 36 petsc_arch=os.path.splitext(os.path.basename(sys.argv[0]))[0] 37 useName = 'PETSC_ARCH='+petsc_arch 38 opts.append(useName) 39 return 0 40 41def chkbrokencygwin(): 42 if os.path.exists('/usr/bin/cygcheck.exe'): 43 buf = os.popen('/usr/bin/cygcheck.exe -c cygwin').read() 44 if buf.find('1.5.11-1') > -1: 45 print '=================================================================================' 46 print ' *** cygwin-1.5.11-1 detected. config/configure.py fails with this version ***' 47 print ' *** Please upgrade to cygwin-1.5.12-1 or newer version. This can ***' 48 print ' *** be done by running cygwin-setup, selecting "next" all the way.***' 49 print '=================================================================================' 50 sys.exit(3) 51 return 0 52 53def chkusingwindowspython(): 54 if os.path.exists('/usr/bin/cygcheck.exe') and sys.platform != 'cygwin': 55 print '=================================================================================' 56 print ' *** Non-cygwin python detected. Please rerun config/configure.py with cygwin-python ***' 57 print '=================================================================================' 58 sys.exit(3) 59 return 0 60 61def chkcygwinpythonver(): 62 if os.path.exists('/usr/bin/cygcheck.exe'): 63 buf = os.popen('/usr/bin/cygcheck.exe -c python').read() 64 if (buf.find('2.4') > -1) or (buf.find('2.5') > -1) or (buf.find('2.6') > -1): 65 sys.argv.append('--useThreads=0') 66 extraLogs.append('''\ 67================================================================================ 68** Cygwin-python-2.4/2.5 detected. Threads do not work correctly with this version * 69 ********* Disabling thread usage for this run of config/configure.py ********** 70================================================================================''') 71 return 0 72 73def chkrhl9(): 74 if os.path.exists('/etc/redhat-release'): 75 try: 76 file = open('/etc/redhat-release','r') 77 buf = file.read() 78 file.close() 79 except: 80 # can't read file - assume dangerous RHL9 81 buf = 'Shrike' 82 if buf.find('Shrike') > -1: 83 sys.argv.append('--useThreads=0') 84 extraLogs.append('''\ 85================================================================================ 86 *** RHL9 detected. Threads do not work correctly with this distribution *** 87 ****** Disabling thread usage for this run of config/configure.py ******* 88================================================================================''') 89 return 0 90 91def check_broken_configure_log_links(): 92 '''Sometime symlinks can get broken if the original files are deleted. Delete such broken links''' 93 import os 94 for logfile in ['configure.log','configure.log.bkp']: 95 if os.path.islink(logfile) and not os.path.isfile(logfile): os.remove(logfile) 96 return 97 98def move_configure_log(framework): 99 '''Move configure.log to PETSC_ARCH/conf - and update configure.log.bkp in both locations appropriately''' 100 global petsc_arch 101 102 if hasattr(framework,'arch'): petsc_arch = framework.arch 103 if hasattr(framework,'logName'): curr_file = framework.logName 104 else: curr_file = 'configure.log' 105 106 if petsc_arch: 107 import shutil 108 import os 109 110 # Just in case - confdir is not created 111 conf_dir = os.path.join(petsc_arch,'conf') 112 if not os.path.isdir(petsc_arch): os.mkdir(petsc_arch) 113 if not os.path.isdir(conf_dir): os.mkdir(conf_dir) 114 115 curr_bkp = curr_file + '.bkp' 116 new_file = os.path.join(conf_dir,curr_file) 117 new_bkp = new_file + '.bkp' 118 119 # Keep backup in $PETSC_ARCH/conf location 120 if os.path.isfile(new_bkp): os.remove(new_bkp) 121 if os.path.isfile(new_file): os.rename(new_file,new_bkp) 122 if os.path.isfile(curr_file): shutil.move(curr_file,new_file) 123 if os.path.isfile(new_file): os.symlink(new_file,curr_file) 124 # If the old bkp is using the same PETSC_ARCH/conf - then update bkp link 125 if os.path.realpath(curr_bkp) == os.path.realpath(new_file): 126 if os.path.isfile(curr_bkp): os.remove(curr_bkp) 127 if os.path.isfile(new_bkp): os.symlink(new_bkp,curr_bkp) 128 return 129 130def petsc_configure(configure_options): 131 print '=================================================================================' 132 print ' Configuring PETSc to compile on your system ' 133 print '=================================================================================' 134 135 # Command line arguments take precedence (but don't destroy argv[0]) 136 sys.argv = sys.argv[:1] + configure_options + sys.argv[1:] 137 # check PETSC_ARCH 138 check_petsc_arch(sys.argv) 139 check_broken_configure_log_links() 140 141 # support a few standard configure option types 142 for l in range(0,len(sys.argv)): 143 name = sys.argv[l] 144 if name.find('enable-') >= 0: 145 if name.find('=') == -1: 146 sys.argv[l] = name.replace('enable-','with-')+'=1' 147 else: 148 head, tail = name.split('=', 1) 149 sys.argv[l] = head.replace('enable-','with-')+'='+tail 150 if name.find('disable-') >= 0: 151 if name.find('=') == -1: 152 sys.argv[l] = name.replace('disable-','with-')+'=0' 153 else: 154 head, tail = name.split('=', 1) 155 if tail == '1': tail = '0' 156 sys.argv[l] = head.replace('disable-','with-')+'='+tail 157 if name.find('without-') >= 0: 158 if name.find('=') == -1: 159 sys.argv[l] = name.replace('without-','with-')+'=0' 160 else: 161 head, tail = name.split('=', 1) 162 if tail == '1': tail = '0' 163 sys.argv[l] = head.replace('without-','with-')+'='+tail 164 165 # Check for broken cygwin 166 chkbrokencygwin() 167 # Disable threads on RHL9 168 chkrhl9() 169 # Make sure cygwin-python is used on windows 170 chkusingwindowspython() 171 # Threads don't work for cygwin & python-2.4, 2.5 etc.. 172 chkcygwinpythonver() 173 174 # Should be run from the toplevel 175 configDir = os.path.abspath('config') 176 bsDir = os.path.join(configDir, 'BuildSystem') 177 if not os.path.isdir(configDir): 178 raise RuntimeError('Run configure from $PETSC_DIR, not '+os.path.abspath('.')) 179 if not os.path.isdir(bsDir): 180 print '=================================================================================' 181 print '''++ Could not locate BuildSystem in %s.''' % configDir 182 print '''++ Downloading it using "hg clone http://hg.mcs.anl.gov/petsc/BuildSystem %s"''' % os.path.join(bsDir, 'BuildSystem') 183 print '=================================================================================' 184 (status,output) = commands.getstatusoutput('hg clone http://petsc.cs.iit.edu/petsc/BuildSystem '+ os.path.join(bsDir, 'BuildSystem')) 185 if status: 186 if output.find('ommand not found') >= 0: 187 print '=================================================================================' 188 print '''** Unable to locate hg (Mercurial) to download BuildSystem; make sure hg is in your path''' 189 print '''** or manually copy BuildSystem to $PETSC_DIR/config/BuildSystem from a machine where''' 190 print '''** you do have hg installed and can clone BuildSystem. ''' 191 print '=================================================================================' 192 elif output.find('Cannot resolve host') >= 0: 193 print '=================================================================================' 194 print '''** Unable to download BuildSystem. You must be off the network.''' 195 print '''** Connect to the internet and run config/configure.py again.''' 196 print '=================================================================================' 197 else: 198 print '=================================================================================' 199 print '''** Unable to download BuildSystem. Please send this message to petsc-maint@mcs.anl.gov''' 200 print '=================================================================================' 201 print output 202 sys.exit(3) 203 204 sys.path.insert(0, bsDir) 205 sys.path.insert(0, configDir) 206 import config.base 207 import config.framework 208 import cPickle 209 210 # Disable shared libraries by default 211 import nargs 212 if nargs.Arg.findArgument('with-shared', sys.argv[1:]) is None: 213 sys.argv.append('--with-shared=0') 214 215 framework = None 216 try: 217 framework = config.framework.Framework(['--configModules=PETSc.Configure','--optionsModule=PETSc.compilerOptions']+sys.argv[1:], loadArgDB = 0) 218 framework.setup() 219 framework.logPrint('\n'.join(extraLogs)) 220 framework.configure(out = sys.stdout) 221 framework.storeSubstitutions(framework.argDB) 222 framework.argDB['configureCache'] = cPickle.dumps(framework) 223 import PETSc.packages 224 for i in framework.packages: 225 if hasattr(i,'postProcess'): 226 i.postProcess() 227 framework.logClear() 228 framework.closeLog() 229 move_configure_log(framework) 230 return 0 231 except (RuntimeError, config.base.ConfigureSetupError), e: 232 emsg = str(e) 233 if not emsg.endswith('\n'): emsg = emsg+'\n' 234 msg ='*********************************************************************************\n'\ 235 +' UNABLE to CONFIGURE with GIVEN OPTIONS (see configure.log for details):\n' \ 236 +'---------------------------------------------------------------------------------------\n' \ 237 +emsg+'*********************************************************************************\n' 238 se = '' 239 except (TypeError, ValueError), e: 240 emsg = str(e) 241 if not emsg.endswith('\n'): emsg = emsg+'\n' 242 msg ='*********************************************************************************\n'\ 243 +' ERROR in COMMAND LINE ARGUMENT to config/configure.py \n' \ 244 +'---------------------------------------------------------------------------------------\n' \ 245 +emsg+'*********************************************************************************\n' 246 se = '' 247 except ImportError, e : 248 emsg = str(e) 249 if not emsg.endswith('\n'): emsg = emsg+'\n' 250 msg ='*********************************************************************************\n'\ 251 +' UNABLE to FIND MODULE for config/configure.py \n' \ 252 +'---------------------------------------------------------------------------------------\n' \ 253 +emsg+'*********************************************************************************\n' 254 se = '' 255 except OSError, e : 256 emsg = str(e) 257 if not emsg.endswith('\n'): emsg = emsg+'\n' 258 msg ='*********************************************************************************\n'\ 259 +' UNABLE to EXECUTE BINARIES for config/configure.py \n' \ 260 +'---------------------------------------------------------------------------------------\n' \ 261 +emsg+'*********************************************************************************\n' 262 se = '' 263 except SystemExit, e: 264 if e.code is None or e.code == 0: 265 return 266 msg ='*********************************************************************************\n'\ 267 +' CONFIGURATION FAILURE (Please send configure.log to petsc-maint@mcs.anl.gov)\n' \ 268 +'*********************************************************************************\n' 269 se = str(e) 270 except Exception, e: 271 msg ='*********************************************************************************\n'\ 272 +' CONFIGURATION CRASH (Please send configure.log to petsc-maint@mcs.anl.gov)\n' \ 273 +'*********************************************************************************\n' 274 se = str(e) 275 276 print msg 277 if not framework is None: 278 framework.logClear() 279 if hasattr(framework, 'log'): 280 import traceback 281 try: 282 framework.log.write(msg+se) 283 traceback.print_tb(sys.exc_info()[2], file = framework.log) 284 move_configure_log(framework) 285 except: 286 pass 287 sys.exit(1) 288 else: 289 print se 290 import traceback 291 traceback.print_tb(sys.exc_info()[2]) 292 move_configure_log(framework) 293 294if __name__ == '__main__': 295 petsc_configure([]) 296 297