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