xref: /petsc/config/configure.py (revision cda0060ada71f18dffce38d7b0a916510be6e1f6)
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:
15495ffa62SBarry Smith  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      *'
2132077d6dSBarry Smith  print '*********************************************************************************'
22b26a8723SBarry Smith  sys.exit(4)
232fb34ac0SMatthew Knepley
24ccb279e1SMatthew Knepleydef check_for_option_mistakes(opts):
25*cda0060aSMatthew Knepley  for opt in opts:
26*cda0060aSMatthew Knepley    name = opt.split('=')[0]
27ccb279e1SMatthew Knepley    if name.find('_') >= 0:
28ccb279e1SMatthew Knepley      exception = False
29ccb279e1SMatthew Knepley      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']:
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:
581937db7aSSatish 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.***'
621937db7aSSatish 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':
681937db7aSSatish Balay    print '================================================================================='
691937db7aSSatish Balay    print ' *** Non-cygwin python detected. Please rerun config/configure.py with cygwin-python ***'
701937db7aSSatish Balay    print '================================================================================='
711937db7aSSatish Balay    sys.exit(3)
7285ef4d1eSSatish Balay  return 0
7385ef4d1eSSatish Balay
7485ef4d1eSSatish Balaydef chkcygwinpythonver():
7571384062SSatish Balay  if os.path.exists('/usr/bin/cygcheck.exe'):
7671384062SSatish Balay    buf = os.popen('/usr/bin/cygcheck.exe -c python').read()
77c4b7e894SSatish Balay    if (buf.find('2.4') > -1) or (buf.find('2.5') > -1) or (buf.find('2.6') > -1):
781937db7aSSatish Balay      sys.argv.append('--useThreads=0')
791937db7aSSatish Balay      extraLogs.append('''\
801937db7aSSatish Balay================================================================================
811937db7aSSatish Balay** Cygwin-python-2.4/2.5 detected. Threads do not work correctly with this version *
821937db7aSSatish Balay ********* Disabling thread usage for this run of config/configure.py **********
831937db7aSSatish Balay================================================================================''')
8471384062SSatish Balay  return 0
8571384062SSatish Balay
861937db7aSSatish Balaydef chkrhl9():
871937db7aSSatish Balay  if os.path.exists('/etc/redhat-release'):
88836c2c52SSatish Balay    try:
89594eb360SSatish Balay      file = open('/etc/redhat-release','r')
90836c2c52SSatish Balay      buf = file.read()
91836c2c52SSatish Balay      file.close()
92836c2c52SSatish Balay    except:
93836c2c52SSatish Balay      # can't read file - assume dangerous RHL9
941937db7aSSatish Balay      buf = 'Shrike'
95836c2c52SSatish Balay    if buf.find('Shrike') > -1:
961937db7aSSatish Balay      sys.argv.append('--useThreads=0')
971937db7aSSatish Balay      extraLogs.append('''\
981937db7aSSatish Balay================================================================================
991937db7aSSatish Balay   *** RHL9 detected. Threads do not work correctly with this distribution ***
1001937db7aSSatish Balay    ****** Disabling thread usage for this run of config/configure.py *******
1011937db7aSSatish Balay================================================================================''')
102836c2c52SSatish Balay  return 0
103836c2c52SSatish Balay
104da58527dSSatish Balaydef check_broken_configure_log_links():
105da58527dSSatish Balay  '''Sometime symlinks can get broken if the original files are deleted. Delete such broken links'''
106da58527dSSatish Balay  import os
107da58527dSSatish Balay  for logfile in ['configure.log','configure.log.bkp']:
108da58527dSSatish Balay    if os.path.islink(logfile) and not os.path.isfile(logfile): os.remove(logfile)
109da58527dSSatish Balay  return
110da58527dSSatish Balay
111da1d79b4SSatish Balaydef move_configure_log(framework):
112da1d79b4SSatish Balay  '''Move configure.log to PETSC_ARCH/conf - and update configure.log.bkp in both locations appropriately'''
113b0b472b0SSatish Balay  global petsc_arch
114b0b472b0SSatish Balay
115b0b472b0SSatish Balay  if hasattr(framework,'arch'): petsc_arch = framework.arch
116b0b472b0SSatish Balay  if hasattr(framework,'logName'): curr_file = framework.logName
117b0b472b0SSatish Balay  else: curr_file = 'configure.log'
118b0b472b0SSatish Balay
119b0b472b0SSatish Balay  if petsc_arch:
120da1d79b4SSatish Balay    import shutil
121da1d79b4SSatish Balay    import os
122b0b472b0SSatish Balay
123b0b472b0SSatish Balay    # Just in case - confdir is not created
124b0b472b0SSatish Balay    conf_dir = os.path.join(petsc_arch,'conf')
125b0b472b0SSatish Balay    if not os.path.isdir(petsc_arch): os.mkdir(petsc_arch)
126b0b472b0SSatish Balay    if not os.path.isdir(conf_dir): os.mkdir(conf_dir)
127b0b472b0SSatish Balay
128da1d79b4SSatish Balay    curr_bkp  = curr_file + '.bkp'
129b0b472b0SSatish Balay    new_file  = os.path.join(conf_dir,curr_file)
130da1d79b4SSatish Balay    new_bkp   = new_file + '.bkp'
131da1d79b4SSatish Balay
132da1d79b4SSatish Balay    # Keep backup in $PETSC_ARCH/conf location
133da1d79b4SSatish Balay    if os.path.isfile(new_bkp): os.remove(new_bkp)
134da1d79b4SSatish Balay    if os.path.isfile(new_file): os.rename(new_file,new_bkp)
135da58527dSSatish Balay    if os.path.isfile(curr_file): shutil.move(curr_file,new_file)
136da58527dSSatish Balay    if os.path.isfile(new_file): os.symlink(new_file,curr_file)
137da1d79b4SSatish Balay    # If the old bkp is using the same PETSC_ARCH/conf - then update bkp link
138da1d79b4SSatish Balay    if os.path.realpath(curr_bkp) == os.path.realpath(new_file):
139da58527dSSatish Balay      if os.path.isfile(curr_bkp): os.remove(curr_bkp)
140da58527dSSatish Balay      if os.path.isfile(new_bkp): os.symlink(new_bkp,curr_bkp)
141da1d79b4SSatish Balay  return
142da1d79b4SSatish Balay
1435d5a5a7bSMatthew Knepleydef petsc_configure(configure_options):
14459e9bfd6SSatish Balay  print '================================================================================='
14559e9bfd6SSatish Balay  print '             Configuring PETSc to compile on your system                         '
14659e9bfd6SSatish Balay  print '================================================================================='
14759e9bfd6SSatish Balay
148c43ea0feSSatish Balay  # Command line arguments take precedence (but don't destroy argv[0])
149c43ea0feSSatish Balay  sys.argv = sys.argv[:1] + configure_options + sys.argv[1:]
150ccb279e1SMatthew Knepley  check_for_option_mistakes(sys.argv)
15159e9bfd6SSatish Balay  # check PETSC_ARCH
15259e9bfd6SSatish Balay  check_petsc_arch(sys.argv)
153da58527dSSatish Balay  check_broken_configure_log_links()
1545fb2c094SBarry Smith
155c22cdea9SBarry Smith  # support a few standard configure option types
156ed6a7445SBarry Smith  for l in range(0,len(sys.argv)):
157c22cdea9SBarry Smith    name = sys.argv[l]
158637cc2ebSSatish Balay    if name.find('enable-') >= 0:
159193cd51eSMatthew Knepley      if name.find('=') == -1:
160193cd51eSMatthew Knepley        sys.argv[l] = name.replace('enable-','with-')+'=1'
161193cd51eSMatthew Knepley      else:
162193cd51eSMatthew Knepley        head, tail = name.split('=', 1)
163193cd51eSMatthew Knepley        sys.argv[l] = head.replace('enable-','with-')+'='+tail
164637cc2ebSSatish Balay    if name.find('disable-') >= 0:
165193cd51eSMatthew Knepley      if name.find('=') == -1:
166193cd51eSMatthew Knepley        sys.argv[l] = name.replace('disable-','with-')+'=0'
167193cd51eSMatthew Knepley      else:
168193cd51eSMatthew Knepley        head, tail = name.split('=', 1)
169193cd51eSMatthew Knepley        if tail == '1': tail = '0'
170193cd51eSMatthew Knepley        sys.argv[l] = head.replace('disable-','with-')+'='+tail
171637cc2ebSSatish Balay    if name.find('without-') >= 0:
172193cd51eSMatthew Knepley      if name.find('=') == -1:
173193cd51eSMatthew Knepley        sys.argv[l] = name.replace('without-','with-')+'=0'
174193cd51eSMatthew Knepley      else:
175193cd51eSMatthew Knepley        head, tail = name.split('=', 1)
176193cd51eSMatthew Knepley        if tail == '1': tail = '0'
177193cd51eSMatthew Knepley        sys.argv[l] = head.replace('without-','with-')+'='+tail
178adc3e427SMatthew Knepley
1799dabcff0SSatish Balay  # Check for broken cygwin
1801937db7aSSatish Balay  chkbrokencygwin()
181d65f3bddSMatthew Knepley  # Disable threads on RHL9
1821937db7aSSatish Balay  chkrhl9()
18385ef4d1eSSatish Balay  # Make sure cygwin-python is used on windows
1841937db7aSSatish Balay  chkusingwindowspython()
18585ef4d1eSSatish Balay  # Threads don't work for cygwin & python-2.4, 2.5 etc..
1861937db7aSSatish Balay  chkcygwinpythonver()
1879dabcff0SSatish Balay
18887282423SMatthew Knepley  # Should be run from the toplevel
189dbca6d9dSSatish Balay  configDir = os.path.abspath('config')
190f8833479SBarry Smith  bsDir     = os.path.join(configDir, 'BuildSystem')
191f8833479SBarry Smith  if not os.path.isdir(configDir):
1925d5a5a7bSMatthew Knepley    raise RuntimeError('Run configure from $PETSC_DIR, not '+os.path.abspath('.'))
19387282423SMatthew Knepley  if not os.path.isdir(bsDir):
194ec1ee742SBarry Smith    print '================================================================================='
195dbca6d9dSSatish Balay    print '''++ Could not locate BuildSystem in %s.''' % configDir
1964564aff7SMatthew Knepley    print '''++ Downloading it using "hg clone http://hg.mcs.anl.gov/petsc/BuildSystem %s"''' % bsDir
197ec1ee742SBarry Smith    print '================================================================================='
1984564aff7SMatthew Knepley    (status,output) = commands.getstatusoutput('hg clone http://petsc.cs.iit.edu/petsc/BuildSystem '+ bsDir)
1997d7624c9SBarry Smith    if status:
2007d7624c9SBarry Smith      if output.find('ommand not found') >= 0:
201ec1ee742SBarry Smith        print '================================================================================='
20259dc5438SMatthew Knepley        print '''** Unable to locate hg (Mercurial) to download BuildSystem; make sure hg is in your path'''
203ab21cac3SMatthew Knepley        print '''** or manually copy BuildSystem to $PETSC_DIR/config/BuildSystem from a machine where'''
20459dc5438SMatthew Knepley        print '''** you do have hg installed and can clone BuildSystem. '''
205ec1ee742SBarry Smith        print '================================================================================='
2067d7624c9SBarry Smith      elif output.find('Cannot resolve host') >= 0:
207ec1ee742SBarry Smith        print '================================================================================='
208d688700cSSatish Balay        print '''** Unable to download BuildSystem. You must be off the network.'''
209d688700cSSatish Balay        print '''** Connect to the internet and run config/configure.py again.'''
210ec1ee742SBarry Smith        print '================================================================================='
2117d7624c9SBarry Smith      else:
212ec1ee742SBarry Smith        print '================================================================================='
213d688700cSSatish Balay        print '''** Unable to download BuildSystem. Please send this message to petsc-maint@mcs.anl.gov'''
214ec1ee742SBarry Smith        print '================================================================================='
2157d7624c9SBarry Smith      print output
21687282423SMatthew Knepley      sys.exit(3)
2174f8a5b45SBarry Smith
21887282423SMatthew Knepley  sys.path.insert(0, bsDir)
219f8833479SBarry Smith  sys.path.insert(0, configDir)
220e69ef9dfSMatthew Knepley  import config.base
2215d5a5a7bSMatthew Knepley  import config.framework
222f56be888SMatthew Knepley  import cPickle
2234f8a5b45SBarry Smith
2242e22a60eSMatthew Knepley  # Disable shared libraries by default
2252e22a60eSMatthew Knepley  import nargs
2262e22a60eSMatthew Knepley  if nargs.Arg.findArgument('with-shared', sys.argv[1:]) is None:
2272e22a60eSMatthew Knepley    sys.argv.append('--with-shared=0')
2282e22a60eSMatthew Knepley
2299dd2fdb1SMatthew Knepley  framework = None
2309dd2fdb1SMatthew Knepley  try:
2311a784507SMatthew Knepley    framework = config.framework.Framework(['--configModules=PETSc.Configure','--optionsModule=PETSc.compilerOptions']+sys.argv[1:], loadArgDB = 0)
232d65f3bddSMatthew Knepley    framework.setup()
233d65f3bddSMatthew Knepley    framework.logPrint('\n'.join(extraLogs))
234f24f64feSBarry Smith    framework.configure(out = sys.stdout)
235358ebc22SMatthew Knepley    framework.storeSubstitutions(framework.argDB)
236f56be888SMatthew Knepley    framework.argDB['configureCache'] = cPickle.dumps(framework)
2377cfd0b05SBarry Smith    import PETSc.packages
2387cfd0b05SBarry Smith    for i in framework.packages:
2397cfd0b05SBarry Smith      if hasattr(i,'postProcess'):
2407cfd0b05SBarry Smith        i.postProcess()
2417cfd0b05SBarry Smith    framework.logClear()
242eefa2c0fSBarry Smith    framework.closeLog()
243da1d79b4SSatish Balay    move_configure_log(framework)
244dd50d019SBarry Smith    return 0
245e69ef9dfSMatthew Knepley  except (RuntimeError, config.base.ConfigureSetupError), e:
2467d670a3cSBarry Smith    emsg = str(e)
24742351d26SSatish Balay    if not emsg.endswith('\n'): emsg = emsg+'\n'
248fe09c992SBarry Smith    msg ='*********************************************************************************\n'\
249fe09c992SBarry Smith    +'         UNABLE to CONFIGURE with GIVEN OPTIONS    (see configure.log for details):\n' \
250fe09c992SBarry Smith    +'---------------------------------------------------------------------------------------\n'  \
2517d670a3cSBarry Smith    +emsg+'*********************************************************************************\n'
252e9f3bb17SBarry Smith    se = ''
2539dd2fdb1SMatthew Knepley  except (TypeError, ValueError), e:
2547d670a3cSBarry Smith    emsg = str(e)
25542351d26SSatish Balay    if not emsg.endswith('\n'): emsg = emsg+'\n'
256fe09c992SBarry Smith    msg ='*********************************************************************************\n'\
257fe09c992SBarry Smith    +'                ERROR in COMMAND LINE ARGUMENT to config/configure.py \n' \
258fe09c992SBarry Smith    +'---------------------------------------------------------------------------------------\n'  \
2597d670a3cSBarry Smith    +emsg+'*********************************************************************************\n'
2601a02243aSBarry Smith    se = ''
26196dc2fe8SMatthew Knepley  except ImportError, e :
2627d670a3cSBarry Smith    emsg = str(e)
26342351d26SSatish Balay    if not emsg.endswith('\n'): emsg = emsg+'\n'
264fe09c992SBarry Smith    msg ='*********************************************************************************\n'\
265fe09c992SBarry Smith    +'                     UNABLE to FIND MODULE for config/configure.py \n' \
266fe09c992SBarry Smith    +'---------------------------------------------------------------------------------------\n'  \
2677d670a3cSBarry Smith    +emsg+'*********************************************************************************\n'
26896dc2fe8SMatthew Knepley    se = ''
26901def6f0SMatthew Knepley  except OSError, e :
27001def6f0SMatthew Knepley    emsg = str(e)
27101def6f0SMatthew Knepley    if not emsg.endswith('\n'): emsg = emsg+'\n'
27201def6f0SMatthew Knepley    msg ='*********************************************************************************\n'\
27301def6f0SMatthew Knepley    +'                    UNABLE to EXECUTE BINARIES for config/configure.py \n' \
27401def6f0SMatthew Knepley    +'---------------------------------------------------------------------------------------\n'  \
27501def6f0SMatthew Knepley    +emsg+'*********************************************************************************\n'
27601def6f0SMatthew Knepley    se = ''
277d7d3c4beSMatthew Knepley  except SystemExit, e:
278d7d3c4beSMatthew Knepley    if e.code is None or e.code == 0:
279d7d3c4beSMatthew Knepley      return
280fe09c992SBarry Smith    msg ='*********************************************************************************\n'\
281b1dada7fSMatthew Knepley    +'           CONFIGURATION FAILURE  (Please send configure.log to petsc-maint@mcs.anl.gov)\n' \
282fe09c992SBarry Smith    +'*********************************************************************************\n'
283d7d3c4beSMatthew Knepley    se  = str(e)
284e9f3bb17SBarry Smith  except Exception, e:
285fe09c992SBarry Smith    msg ='*********************************************************************************\n'\
286fe09c992SBarry Smith    +'          CONFIGURATION CRASH  (Please send configure.log to petsc-maint@mcs.anl.gov)\n' \
287fe09c992SBarry Smith    +'*********************************************************************************\n'
288e9f3bb17SBarry Smith    se  = str(e)
289e9f3bb17SBarry Smith
290e9f3bb17SBarry Smith  print msg
2919dd2fdb1SMatthew Knepley  if not framework is None:
2929dd2fdb1SMatthew Knepley    framework.logClear()
293e9f3bb17SBarry Smith    if hasattr(framework, 'log'):
294f6614063SBarry Smith      import traceback
295b1dada7fSMatthew Knepley      try:
296f24f64feSBarry Smith        framework.log.write(msg+se)
297f24f64feSBarry Smith        traceback.print_tb(sys.exc_info()[2], file = framework.log)
298da1d79b4SSatish Balay        move_configure_log(framework)
299b1dada7fSMatthew Knepley      except:
300b1dada7fSMatthew Knepley        pass
301e9f3bb17SBarry Smith      sys.exit(1)
3025a74f024SMatthew Knepley  else:
3035a74f024SMatthew Knepley    print se
3045a74f024SMatthew Knepley    import traceback
3055a74f024SMatthew Knepley    traceback.print_tb(sys.exc_info()[2])
306da1d79b4SSatish Balay  move_configure_log(framework)
3075d5a5a7bSMatthew Knepley
3085d5a5a7bSMatthew Knepleyif __name__ == '__main__':
309a030c540SBarry Smith  petsc_configure([])
310759acf64SBarry Smith
311