xref: /petsc/config/configure.py (revision a0022257b2005a36de27f9cacb12af237791775b)
15d5a5a7bSMatthew Knepley#!/usr/bin/env python
25d5a5a7bSMatthew Knepleyimport os
35d5a5a7bSMatthew Knepleyimport sys
44f8a5b45SBarry Smithimport commands
5a1eda5bfSSatish Balay# to load ~/.pythonrc.py before inserting correct BuildSystem to path
6a1eda5bfSSatish Balayimport user
77c9abfe7SSatish BalayextraLogs = []
8b0b472b0SSatish Balaypetsc_arch = ''
94b8aa89bSBarry Smith
1044b0d7f9SSatish Balay# Use en_US as language so that BuildSystem parses compiler messages in english
119b436e4bSSatish Balayif 'LC_LOCAL' in os.environ and os.environ['LC_LOCAL'] != '' and os.environ['LC_LOCAL'] != 'en_US' and os.environ['LC_LOCAL']!= 'en_US.UTF-8': os.environ['LC_LOCAL'] = 'en_US.UTF-8'
129b436e4bSSatish Balayif 'LANG' in os.environ and os.environ['LANG'] != '' and os.environ['LANG'] != 'en_US' and os.environ['LANG'] != 'en_US.UTF-8': os.environ['LANG'] = 'en_US.UTF-8'
1344b0d7f9SSatish Balay
14378f148eSBarry Smithif not hasattr(sys, 'version_info') or not sys.version_info[1] >= 2 or not sys.version_info[0] >= 2:
15*a0022257SSatish Balay  print '*** You must have Python version 2.2 or higher to run config/configure.py *****'
16495ffa62SBarry Smith  print '*          Python is easy to install for end users or sys-admin.              *'
1732077d6dSBarry Smith  print '*                  http://www.python.org/download/                            *'
1832077d6dSBarry Smith  print '*                                                                             *'
19495ffa62SBarry Smith  print '*           You CANNOT configure PETSc without Python                         *'
20495ffa62SBarry Smith  print '*   http://www.mcs.anl.gov/petsc/petsc-as/documentation/installation.html     *'
21*a0022257SSatish Balay  print '*******************************************************************************'
22b26a8723SBarry Smith  sys.exit(4)
232fb34ac0SMatthew Knepley
24ccb279e1SMatthew Knepleydef check_for_option_mistakes(opts):
2545faeebdSBarry Smith  for opt in opts[1:]:
26cda0060aSMatthew Knepley    name = opt.split('=')[0]
27ccb279e1SMatthew Knepley    if name.find('_') >= 0:
28ccb279e1SMatthew Knepley      exception = False
29f3fbd535SBarry Smith      for exc in ['superlu_dist', 'PETSC_ARCH', 'PETSC_DIR', 'CXX_CXXFLAGS', 'LD_SHARED', 'CC_LINKER_FLAGS', 'CXX_LINKER_FLAGS', 'FC_LINKER_FLAGS', 'AR_FLAGS', 'C_VERSION', 'CXX_VERSION', 'FC_VERSION', 'size_t', 'MPI_Comm','MPI_Fint']:
30ccb279e1SMatthew Knepley        if name.find(exc) >= 0:
31ccb279e1SMatthew Knepley          exception = True
32ccb279e1SMatthew Knepley      if not exception:
33ccb279e1SMatthew Knepley        raise ValueError('The option '+name+' should probably be '+name.replace('_', '-'));
34ccb279e1SMatthew Knepley  return
35ccb279e1SMatthew Knepley
3659e9bfd6SSatish Balaydef check_petsc_arch(opts):
37c43ea0feSSatish Balay  # If PETSC_ARCH not specified - use script name (if not configure.py)
38b0b472b0SSatish Balay  global petsc_arch
39c43ea0feSSatish Balay  found = 0
4059e9bfd6SSatish Balay  for name in opts:
41c43ea0feSSatish Balay    if name.find('PETSC_ARCH=') >= 0:
42b0b472b0SSatish Balay      petsc_arch=name.split('=')[1]
43c43ea0feSSatish Balay      found = 1
4459e9bfd6SSatish Balay      break
4559e9bfd6SSatish Balay  # If not yet specified - use the filename of script
46c43ea0feSSatish Balay  if not found:
4759e9bfd6SSatish Balay      filename = os.path.basename(sys.argv[0])
487eed1879SBarry Smith      if not filename.startswith('configure') and not filename.startswith('reconfigure'):
49b0b472b0SSatish Balay        petsc_arch=os.path.splitext(os.path.basename(sys.argv[0]))[0]
50b0b472b0SSatish Balay        useName = 'PETSC_ARCH='+petsc_arch
5159e9bfd6SSatish Balay        opts.append(useName)
521937db7aSSatish Balay  return 0
534b8aa89bSBarry Smith
5485ef4d1eSSatish Balaydef chkbrokencygwin():
559dabcff0SSatish Balay  if os.path.exists('/usr/bin/cygcheck.exe'):
569dabcff0SSatish Balay    buf = os.popen('/usr/bin/cygcheck.exe -c cygwin').read()
579dabcff0SSatish Balay    if buf.find('1.5.11-1') > -1:
58*a0022257SSatish Balay      print '==============================================================================='
591937db7aSSatish Balay      print ' *** cygwin-1.5.11-1 detected. config/configure.py fails with this version ***'
601937db7aSSatish Balay      print ' *** Please upgrade to cygwin-1.5.12-1 or newer version. This can  ***'
611937db7aSSatish Balay      print ' *** be done by running cygwin-setup, selecting "next" all the way.***'
62*a0022257SSatish Balay      print '==============================================================================='
631937db7aSSatish Balay      sys.exit(3)
649dabcff0SSatish Balay  return 0
659dabcff0SSatish Balay
6685ef4d1eSSatish Balaydef chkusingwindowspython():
671937db7aSSatish Balay  if os.path.exists('/usr/bin/cygcheck.exe') and sys.platform != 'cygwin':
68*a0022257SSatish Balay    print '==============================================================================='
69*a0022257SSatish Balay    print ' *** Non-cygwin python detected. Please rerun config/configure.py **'
70*a0022257SSatish Balay    print ' *** with cygwin-python. ***'
71*a0022257SSatish Balay    print '==============================================================================='
721937db7aSSatish Balay    sys.exit(3)
7385ef4d1eSSatish Balay  return 0
7485ef4d1eSSatish Balay
7585ef4d1eSSatish Balaydef chkcygwinpythonver():
7671384062SSatish Balay  if os.path.exists('/usr/bin/cygcheck.exe'):
7771384062SSatish Balay    buf = os.popen('/usr/bin/cygcheck.exe -c python').read()
78c4b7e894SSatish Balay    if (buf.find('2.4') > -1) or (buf.find('2.5') > -1) or (buf.find('2.6') > -1):
791937db7aSSatish Balay      sys.argv.append('--useThreads=0')
801937db7aSSatish Balay      extraLogs.append('''\
81*a0022257SSatish Balay===============================================================================
82*a0022257SSatish Balay** Cygwin-python-2.4/2.5/2.6 detected. Threads do not work correctly with this
83*a0022257SSatish Balay** version. Disabling thread usage for this run of config/configure.py *******
84*a0022257SSatish Balay===============================================================================''')
8571384062SSatish Balay  return 0
8671384062SSatish Balay
871937db7aSSatish Balaydef chkrhl9():
881937db7aSSatish Balay  if os.path.exists('/etc/redhat-release'):
89836c2c52SSatish Balay    try:
90594eb360SSatish Balay      file = open('/etc/redhat-release','r')
91836c2c52SSatish Balay      buf = file.read()
92836c2c52SSatish Balay      file.close()
93836c2c52SSatish Balay    except:
94836c2c52SSatish Balay      # can't read file - assume dangerous RHL9
951937db7aSSatish Balay      buf = 'Shrike'
96836c2c52SSatish Balay    if buf.find('Shrike') > -1:
971937db7aSSatish Balay      sys.argv.append('--useThreads=0')
981937db7aSSatish Balay      extraLogs.append('''\
99*a0022257SSatish Balay==============================================================================
1001937db7aSSatish Balay   *** RHL9 detected. Threads do not work correctly with this distribution ***
101*a0022257SSatish Balay   ****** Disabling thread usage for this run of config/configure.py *********
102*a0022257SSatish Balay===============================================================================''')
103836c2c52SSatish Balay  return 0
104836c2c52SSatish Balay
105da58527dSSatish Balaydef check_broken_configure_log_links():
106da58527dSSatish Balay  '''Sometime symlinks can get broken if the original files are deleted. Delete such broken links'''
107da58527dSSatish Balay  import os
108da58527dSSatish Balay  for logfile in ['configure.log','configure.log.bkp']:
109da58527dSSatish Balay    if os.path.islink(logfile) and not os.path.isfile(logfile): os.remove(logfile)
110da58527dSSatish Balay  return
111da58527dSSatish Balay
112da1d79b4SSatish Balaydef move_configure_log(framework):
113da1d79b4SSatish Balay  '''Move configure.log to PETSC_ARCH/conf - and update configure.log.bkp in both locations appropriately'''
114b0b472b0SSatish Balay  global petsc_arch
115b0b472b0SSatish Balay
116b0b472b0SSatish Balay  if hasattr(framework,'arch'): petsc_arch = framework.arch
117b0b472b0SSatish Balay  if hasattr(framework,'logName'): curr_file = framework.logName
118b0b472b0SSatish Balay  else: curr_file = 'configure.log'
119b0b472b0SSatish Balay
120b0b472b0SSatish Balay  if petsc_arch:
121da1d79b4SSatish Balay    import shutil
122da1d79b4SSatish Balay    import os
123b0b472b0SSatish Balay
124b0b472b0SSatish Balay    # Just in case - confdir is not created
125b0b472b0SSatish Balay    conf_dir = os.path.join(petsc_arch,'conf')
126b0b472b0SSatish Balay    if not os.path.isdir(petsc_arch): os.mkdir(petsc_arch)
127b0b472b0SSatish Balay    if not os.path.isdir(conf_dir): os.mkdir(conf_dir)
128b0b472b0SSatish Balay
129da1d79b4SSatish Balay    curr_bkp  = curr_file + '.bkp'
130b0b472b0SSatish Balay    new_file  = os.path.join(conf_dir,curr_file)
131da1d79b4SSatish Balay    new_bkp   = new_file + '.bkp'
132da1d79b4SSatish Balay
133da1d79b4SSatish Balay    # Keep backup in $PETSC_ARCH/conf location
134da1d79b4SSatish Balay    if os.path.isfile(new_bkp): os.remove(new_bkp)
135da1d79b4SSatish Balay    if os.path.isfile(new_file): os.rename(new_file,new_bkp)
1369e50940cSSatish Balay    if os.path.isfile(curr_file):
1379e50940cSSatish Balay      shutil.copyfile(curr_file,new_file)
1389e50940cSSatish Balay      os.remove(curr_file)
139da58527dSSatish Balay    if os.path.isfile(new_file): os.symlink(new_file,curr_file)
140da1d79b4SSatish Balay    # If the old bkp is using the same PETSC_ARCH/conf - then update bkp link
141da1d79b4SSatish Balay    if os.path.realpath(curr_bkp) == os.path.realpath(new_file):
142da58527dSSatish Balay      if os.path.isfile(curr_bkp): os.remove(curr_bkp)
143da58527dSSatish Balay      if os.path.isfile(new_bkp): os.symlink(new_bkp,curr_bkp)
144da1d79b4SSatish Balay  return
145da1d79b4SSatish Balay
1465d5a5a7bSMatthew Knepleydef petsc_configure(configure_options):
147*a0022257SSatish Balay  print '==============================================================================='
14859e9bfd6SSatish Balay  print '             Configuring PETSc to compile on your system                       '
149*a0022257SSatish Balay  print '==============================================================================='
15059e9bfd6SSatish Balay
151c43ea0feSSatish Balay  # Command line arguments take precedence (but don't destroy argv[0])
152c43ea0feSSatish Balay  sys.argv = sys.argv[:1] + configure_options + sys.argv[1:]
153ccb279e1SMatthew Knepley  check_for_option_mistakes(sys.argv)
15459e9bfd6SSatish Balay  # check PETSC_ARCH
15559e9bfd6SSatish Balay  check_petsc_arch(sys.argv)
156da58527dSSatish Balay  check_broken_configure_log_links()
1575fb2c094SBarry Smith
158c22cdea9SBarry Smith  # support a few standard configure option types
159ed6a7445SBarry Smith  for l in range(0,len(sys.argv)):
160c22cdea9SBarry Smith    name = sys.argv[l]
161637cc2ebSSatish Balay    if name.find('enable-') >= 0:
162193cd51eSMatthew Knepley      if name.find('=') == -1:
163193cd51eSMatthew Knepley        sys.argv[l] = name.replace('enable-','with-')+'=1'
164193cd51eSMatthew Knepley      else:
165193cd51eSMatthew Knepley        head, tail = name.split('=', 1)
166193cd51eSMatthew Knepley        sys.argv[l] = head.replace('enable-','with-')+'='+tail
167637cc2ebSSatish Balay    if name.find('disable-') >= 0:
168193cd51eSMatthew Knepley      if name.find('=') == -1:
169193cd51eSMatthew Knepley        sys.argv[l] = name.replace('disable-','with-')+'=0'
170193cd51eSMatthew Knepley      else:
171193cd51eSMatthew Knepley        head, tail = name.split('=', 1)
172193cd51eSMatthew Knepley        if tail == '1': tail = '0'
173193cd51eSMatthew Knepley        sys.argv[l] = head.replace('disable-','with-')+'='+tail
174637cc2ebSSatish Balay    if name.find('without-') >= 0:
175193cd51eSMatthew Knepley      if name.find('=') == -1:
176193cd51eSMatthew Knepley        sys.argv[l] = name.replace('without-','with-')+'=0'
177193cd51eSMatthew Knepley      else:
178193cd51eSMatthew Knepley        head, tail = name.split('=', 1)
179193cd51eSMatthew Knepley        if tail == '1': tail = '0'
180193cd51eSMatthew Knepley        sys.argv[l] = head.replace('without-','with-')+'='+tail
181adc3e427SMatthew Knepley
1829dabcff0SSatish Balay  # Check for broken cygwin
1831937db7aSSatish Balay  chkbrokencygwin()
184d65f3bddSMatthew Knepley  # Disable threads on RHL9
1851937db7aSSatish Balay  chkrhl9()
18685ef4d1eSSatish Balay  # Make sure cygwin-python is used on windows
1871937db7aSSatish Balay  chkusingwindowspython()
18885ef4d1eSSatish Balay  # Threads don't work for cygwin & python-2.4, 2.5 etc..
1891937db7aSSatish Balay  chkcygwinpythonver()
1909dabcff0SSatish Balay
19187282423SMatthew Knepley  # Should be run from the toplevel
192dbca6d9dSSatish Balay  configDir = os.path.abspath('config')
193f8833479SBarry Smith  bsDir     = os.path.join(configDir, 'BuildSystem')
194f8833479SBarry Smith  if not os.path.isdir(configDir):
1955d5a5a7bSMatthew Knepley    raise RuntimeError('Run configure from $PETSC_DIR, not '+os.path.abspath('.'))
19687282423SMatthew Knepley  if not os.path.isdir(bsDir):
197*a0022257SSatish Balay    print '==============================================================================='
198dbca6d9dSSatish Balay    print '''++ Could not locate BuildSystem in %s.''' % configDir
1994564aff7SMatthew Knepley    print '''++ Downloading it using "hg clone http://hg.mcs.anl.gov/petsc/BuildSystem %s"''' % bsDir
200*a0022257SSatish Balay    print '==============================================================================='
2014564aff7SMatthew Knepley    (status,output) = commands.getstatusoutput('hg clone http://petsc.cs.iit.edu/petsc/BuildSystem '+ bsDir)
2027d7624c9SBarry Smith    if status:
2037d7624c9SBarry Smith      if output.find('ommand not found') >= 0:
204*a0022257SSatish Balay        print '==============================================================================='
205*a0022257SSatish Balay        print '''** Unable to locate hg (Mercurial) to download BuildSystem; make sure hg is'''
206*a0022257SSatish Balay        print '''** in your path or manually copy BuildSystem to $PETSC_DIR/config/BuildSystem'''
207*a0022257SSatish Balay        print '''**  from a machine where you do have hg installed and can clone BuildSystem. '''
208*a0022257SSatish Balay        print '==============================================================================='
2097d7624c9SBarry Smith      elif output.find('Cannot resolve host') >= 0:
210*a0022257SSatish Balay        print '==============================================================================='
211d688700cSSatish Balay        print '''** Unable to download BuildSystem. You must be off the network.'''
212d688700cSSatish Balay        print '''** Connect to the internet and run config/configure.py again.'''
213*a0022257SSatish Balay        print '==============================================================================='
2147d7624c9SBarry Smith      else:
215*a0022257SSatish Balay        print '==============================================================================='
216d688700cSSatish Balay        print '''** Unable to download BuildSystem. Please send this message to petsc-maint@mcs.anl.gov'''
217*a0022257SSatish Balay        print '==============================================================================='
2187d7624c9SBarry Smith      print output
21987282423SMatthew Knepley      sys.exit(3)
2204f8a5b45SBarry Smith
22187282423SMatthew Knepley  sys.path.insert(0, bsDir)
222f8833479SBarry Smith  sys.path.insert(0, configDir)
223e69ef9dfSMatthew Knepley  import config.base
2245d5a5a7bSMatthew Knepley  import config.framework
225f56be888SMatthew Knepley  import cPickle
2264f8a5b45SBarry Smith
2279dd2fdb1SMatthew Knepley  framework = None
2289dd2fdb1SMatthew Knepley  try:
2291a784507SMatthew Knepley    framework = config.framework.Framework(['--configModules=PETSc.Configure','--optionsModule=PETSc.compilerOptions']+sys.argv[1:], loadArgDB = 0)
230d65f3bddSMatthew Knepley    framework.setup()
231d65f3bddSMatthew Knepley    framework.logPrint('\n'.join(extraLogs))
232f24f64feSBarry Smith    framework.configure(out = sys.stdout)
233358ebc22SMatthew Knepley    framework.storeSubstitutions(framework.argDB)
234f56be888SMatthew Knepley    framework.argDB['configureCache'] = cPickle.dumps(framework)
2357cfd0b05SBarry Smith    import PETSc.packages
2367cfd0b05SBarry Smith    for i in framework.packages:
2377cfd0b05SBarry Smith      if hasattr(i,'postProcess'):
2387cfd0b05SBarry Smith        i.postProcess()
2397c939e48SSatish Balay    framework.printSummary()
2407cfd0b05SBarry Smith    framework.logClear()
241eefa2c0fSBarry Smith    framework.closeLog()
2429e50940cSSatish Balay    try:
243da1d79b4SSatish Balay      move_configure_log(framework)
2449e50940cSSatish Balay    except:
2459e50940cSSatish Balay      # perhaps print an error about unable to shuffle logs?
2469e50940cSSatish Balay      pass
247dd50d019SBarry Smith    return 0
248e69ef9dfSMatthew Knepley  except (RuntimeError, config.base.ConfigureSetupError), e:
2497d670a3cSBarry Smith    emsg = str(e)
25042351d26SSatish Balay    if not emsg.endswith('\n'): emsg = emsg+'\n'
251*a0022257SSatish Balay    msg ='*******************************************************************************\n'\
252fe09c992SBarry Smith    +'         UNABLE to CONFIGURE with GIVEN OPTIONS    (see configure.log for details):\n' \
253*a0022257SSatish Balay    +'-------------------------------------------------------------------------------\n'  \
254*a0022257SSatish Balay    +emsg+'*******************************************************************************\n'
255e9f3bb17SBarry Smith    se = ''
2569dd2fdb1SMatthew Knepley  except (TypeError, ValueError), e:
2577d670a3cSBarry Smith    emsg = str(e)
25842351d26SSatish Balay    if not emsg.endswith('\n'): emsg = emsg+'\n'
259*a0022257SSatish Balay    msg ='*******************************************************************************\n'\
260fe09c992SBarry Smith    +'                ERROR in COMMAND LINE ARGUMENT to config/configure.py \n' \
261*a0022257SSatish Balay    +'-------------------------------------------------------------------------------\n'  \
262*a0022257SSatish Balay    +emsg+'*******************************************************************************\n'
2631a02243aSBarry Smith    se = ''
26496dc2fe8SMatthew Knepley  except ImportError, e :
2657d670a3cSBarry Smith    emsg = str(e)
26642351d26SSatish Balay    if not emsg.endswith('\n'): emsg = emsg+'\n'
267*a0022257SSatish Balay    msg ='*******************************************************************************\n'\
268fe09c992SBarry Smith    +'                     UNABLE to FIND MODULE for config/configure.py \n' \
269*a0022257SSatish Balay    +'-------------------------------------------------------------------------------\n'  \
270*a0022257SSatish Balay    +emsg+'*******************************************************************************\n'
27196dc2fe8SMatthew Knepley    se = ''
27201def6f0SMatthew Knepley  except OSError, e :
27301def6f0SMatthew Knepley    emsg = str(e)
27401def6f0SMatthew Knepley    if not emsg.endswith('\n'): emsg = emsg+'\n'
275*a0022257SSatish Balay    msg ='*******************************************************************************\n'\
27601def6f0SMatthew Knepley    +'                    UNABLE to EXECUTE BINARIES for config/configure.py \n' \
277*a0022257SSatish Balay    +'-------------------------------------------------------------------------------\n'  \
278*a0022257SSatish Balay    +emsg+'*******************************************************************************\n'
27901def6f0SMatthew Knepley    se = ''
280d7d3c4beSMatthew Knepley  except SystemExit, e:
281d7d3c4beSMatthew Knepley    if e.code is None or e.code == 0:
282d7d3c4beSMatthew Knepley      return
283*a0022257SSatish Balay    msg ='*******************************************************************************\n'\
284b1dada7fSMatthew Knepley    +'         CONFIGURATION FAILURE  (Please send configure.log to petsc-maint@mcs.anl.gov)\n' \
285*a0022257SSatish Balay    +'*******************************************************************************\n'
286d7d3c4beSMatthew Knepley    se  = str(e)
287e9f3bb17SBarry Smith  except Exception, e:
288*a0022257SSatish Balay    msg ='*******************************************************************************\n'\
289fe09c992SBarry Smith    +'        CONFIGURATION CRASH  (Please send configure.log to petsc-maint@mcs.anl.gov)\n' \
290*a0022257SSatish Balay    +'*******************************************************************************\n'
291e9f3bb17SBarry Smith    se  = str(e)
292e9f3bb17SBarry Smith
293e9f3bb17SBarry Smith  print msg
2949dd2fdb1SMatthew Knepley  if not framework is None:
2959dd2fdb1SMatthew Knepley    framework.logClear()
296e9f3bb17SBarry Smith    if hasattr(framework, 'log'):
297f6614063SBarry Smith      import traceback
298b1dada7fSMatthew Knepley      try:
299f24f64feSBarry Smith        framework.log.write(msg+se)
300f24f64feSBarry Smith        traceback.print_tb(sys.exc_info()[2], file = framework.log)
301546d5c6fSSatish Balay        close(framework.log)
302da1d79b4SSatish Balay        move_configure_log(framework)
303b1dada7fSMatthew Knepley      except:
304b1dada7fSMatthew Knepley        pass
305e9f3bb17SBarry Smith      sys.exit(1)
3065a74f024SMatthew Knepley  else:
3075a74f024SMatthew Knepley    print se
3085a74f024SMatthew Knepley    import traceback
3095a74f024SMatthew Knepley    traceback.print_tb(sys.exc_info()[2])
310546d5c6fSSatish Balay  close(framework.log)
311da1d79b4SSatish Balay  move_configure_log(framework)
3125d5a5a7bSMatthew Knepley
3135d5a5a7bSMatthew Knepleyif __name__ == '__main__':
314a030c540SBarry Smith  petsc_configure([])
315759acf64SBarry Smith
316