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