xref: /petsc/config/configure.py (revision b0b472b02bae8575694e468aba26ed94309ce2c4)
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 move_configure_log(framework):
89  '''Move configure.log to PETSC_ARCH/conf - and update configure.log.bkp in both locations appropriately'''
90  global petsc_arch
91
92  if hasattr(framework,'arch'): petsc_arch = framework.arch
93  if hasattr(framework,'logName'): curr_file = framework.logName
94  else: curr_file = 'configure.log'
95
96  if petsc_arch:
97    import shutil
98    import os
99
100    # Just in case - confdir is not created
101    conf_dir = os.path.join(petsc_arch,'conf')
102    if not os.path.isdir(petsc_arch): os.mkdir(petsc_arch)
103    if not os.path.isdir(conf_dir): os.mkdir(conf_dir)
104
105    curr_bkp  = curr_file + '.bkp'
106    new_file  = os.path.join(conf_dir,curr_file)
107    new_bkp   = new_file + '.bkp'
108
109    # Keep backup in $PETSC_ARCH/conf location
110    if os.path.isfile(new_bkp): os.remove(new_bkp)
111    if os.path.isfile(new_file): os.rename(new_file,new_bkp)
112    shutil.move(curr_file,new_file)
113    os.symlink(new_file,curr_file)
114    # If the old bkp is using the same PETSC_ARCH/conf - then update bkp link
115    if os.path.realpath(curr_bkp) == os.path.realpath(new_file):
116      os.remove(curr_bkp)
117      os.symlink(new_bkp,curr_bkp)
118  return
119
120def petsc_configure(configure_options):
121  print '================================================================================='
122  print '             Configuring PETSc to compile on your system                         '
123  print '================================================================================='
124
125  # Command line arguments take precedence (but don't destroy argv[0])
126  sys.argv = sys.argv[:1] + configure_options + sys.argv[1:]
127  # check PETSC_ARCH
128  check_petsc_arch(sys.argv)
129
130  # support a few standard configure option types
131  for l in range(0,len(sys.argv)):
132    name = sys.argv[l]
133    if name.find('enable-') >= 0:
134      if name.find('=') == -1:
135        sys.argv[l] = name.replace('enable-','with-')+'=1'
136      else:
137        head, tail = name.split('=', 1)
138        sys.argv[l] = head.replace('enable-','with-')+'='+tail
139    if name.find('disable-') >= 0:
140      if name.find('=') == -1:
141        sys.argv[l] = name.replace('disable-','with-')+'=0'
142      else:
143        head, tail = name.split('=', 1)
144        if tail == '1': tail = '0'
145        sys.argv[l] = head.replace('disable-','with-')+'='+tail
146    if name.find('without-') >= 0:
147      if name.find('=') == -1:
148        sys.argv[l] = name.replace('without-','with-')+'=0'
149      else:
150        head, tail = name.split('=', 1)
151        if tail == '1': tail = '0'
152        sys.argv[l] = head.replace('without-','with-')+'='+tail
153
154  # Check for broken cygwin
155  chkbrokencygwin()
156  # Disable threads on RHL9
157  chkrhl9()
158  # Make sure cygwin-python is used on windows
159  chkusingwindowspython()
160  # Threads don't work for cygwin & python-2.4, 2.5 etc..
161  chkcygwinpythonver()
162
163  # Should be run from the toplevel
164  configDir = os.path.abspath('config')
165  bsDir     = os.path.join(configDir, 'BuildSystem')
166  if not os.path.isdir(configDir):
167    raise RuntimeError('Run configure from $PETSC_DIR, not '+os.path.abspath('.'))
168  if not os.path.isdir(bsDir):
169    print '================================================================================='
170    print '''++ Could not locate BuildSystem in %s.''' % configDir
171    print '''++ Downloading it using "hg clone http://hg.mcs.anl.gov/petsc/BuildSystem %s"''' % bsDir
172    print '================================================================================='
173    (status,output) = commands.getstatusoutput('hg clone http://petsc.cs.iit.edu/petsc/BuildSystem '+ bsDir)
174    if status:
175      if output.find('ommand not found') >= 0:
176        print '================================================================================='
177        print '''** Unable to locate hg (Mercurial) to download BuildSystem; make sure hg is in your path'''
178        print '''** or manually copy BuildSystem to $PETSC_DIR/config/BuildSystem from a machine where'''
179        print '''** you do have hg installed and can clone BuildSystem. '''
180        print '================================================================================='
181      elif output.find('Cannot resolve host') >= 0:
182        print '================================================================================='
183        print '''** Unable to download BuildSystem. You must be off the network.'''
184        print '''** Connect to the internet and run config/configure.py again.'''
185        print '================================================================================='
186      else:
187        print '================================================================================='
188        print '''** Unable to download BuildSystem. Please send this message to petsc-maint@mcs.anl.gov'''
189        print '================================================================================='
190      print output
191      sys.exit(3)
192
193  sys.path.insert(0, bsDir)
194  sys.path.insert(0, configDir)
195  import config.base
196  import config.framework
197  import cPickle
198
199  # Disable shared libraries by default
200  import nargs
201  if nargs.Arg.findArgument('with-shared', sys.argv[1:]) is None:
202    sys.argv.append('--with-shared=0')
203
204  framework = None
205  try:
206    framework = config.framework.Framework(['--configModules=PETSc.Configure','--optionsModule=PETSc.compilerOptions']+sys.argv[1:], loadArgDB = 0)
207    framework.setup()
208    framework.logPrint('\n'.join(extraLogs))
209    framework.configure(out = sys.stdout)
210    framework.storeSubstitutions(framework.argDB)
211    framework.argDB['configureCache'] = cPickle.dumps(framework)
212    import PETSc.packages
213    for i in framework.packages:
214      if hasattr(i,'postProcess'):
215        i.postProcess()
216    framework.logClear()
217    framework.closeLog()
218    move_configure_log(framework)
219    return 0
220  except (RuntimeError, config.base.ConfigureSetupError), e:
221    emsg = str(e)
222    if not emsg.endswith('\n'): emsg = emsg+'\n'
223    msg ='*********************************************************************************\n'\
224    +'         UNABLE to CONFIGURE with GIVEN OPTIONS    (see configure.log for details):\n' \
225    +'---------------------------------------------------------------------------------------\n'  \
226    +emsg+'*********************************************************************************\n'
227    se = ''
228  except (TypeError, ValueError), e:
229    emsg = str(e)
230    if not emsg.endswith('\n'): emsg = emsg+'\n'
231    msg ='*********************************************************************************\n'\
232    +'                ERROR in COMMAND LINE ARGUMENT to config/configure.py \n' \
233    +'---------------------------------------------------------------------------------------\n'  \
234    +emsg+'*********************************************************************************\n'
235    se = ''
236  except ImportError, e :
237    emsg = str(e)
238    if not emsg.endswith('\n'): emsg = emsg+'\n'
239    msg ='*********************************************************************************\n'\
240    +'                     UNABLE to FIND MODULE for config/configure.py \n' \
241    +'---------------------------------------------------------------------------------------\n'  \
242    +emsg+'*********************************************************************************\n'
243    se = ''
244  except OSError, e :
245    emsg = str(e)
246    if not emsg.endswith('\n'): emsg = emsg+'\n'
247    msg ='*********************************************************************************\n'\
248    +'                    UNABLE to EXECUTE BINARIES for config/configure.py \n' \
249    +'---------------------------------------------------------------------------------------\n'  \
250    +emsg+'*********************************************************************************\n'
251    se = ''
252  except SystemExit, e:
253    if e.code is None or e.code == 0:
254      return
255    msg ='*********************************************************************************\n'\
256    +'           CONFIGURATION CRASH  (Please send configure.log to petsc-maint@mcs.anl.gov)\n' \
257    +'*********************************************************************************\n'
258    se  = str(e)
259  except Exception, e:
260    msg ='*********************************************************************************\n'\
261    +'          CONFIGURATION CRASH  (Please send configure.log to petsc-maint@mcs.anl.gov)\n' \
262    +'*********************************************************************************\n'
263    se  = str(e)
264
265  print msg
266  if not framework is None:
267    framework.logClear()
268    if hasattr(framework, 'log'):
269      import traceback
270      framework.log.write(msg+se)
271      traceback.print_tb(sys.exc_info()[2], file = framework.log)
272      move_configure_log(framework)
273      sys.exit(1)
274  else:
275    print se
276    import traceback
277    traceback.print_tb(sys.exc_info()[2])
278  move_configure_log(framework)
279
280if __name__ == '__main__':
281  petsc_configure([])
282
283