xref: /petsc/config/PETSc/options/arch.py (revision dd328ec0ac57af7b498731da5d38edef20911fc9)
19d310bb7SBarry Smithimport config.base
29d310bb7SBarry Smithimport os
39d310bb7SBarry Smithimport re
49d310bb7SBarry Smith
59d310bb7SBarry Smithclass Configure(config.base.Configure):
69d310bb7SBarry Smith  def __init__(self, framework):
79d310bb7SBarry Smith    config.base.Configure.__init__(self, framework)
89d310bb7SBarry Smith    self.headerPrefix = 'PETSC'
99d310bb7SBarry Smith    self.substPrefix  = 'PETSC'
109d310bb7SBarry Smith    return
119d310bb7SBarry Smith
129d310bb7SBarry Smith  def __str1__(self):
139d310bb7SBarry Smith    if not hasattr(self, 'arch'):
149d310bb7SBarry Smith      return ''
159d310bb7SBarry Smith    desc = ['PETSc:']
169d310bb7SBarry Smith    desc.append('  PETSC_ARCH: '+str(self.arch))
179d310bb7SBarry Smith    return '\n'.join(desc)+'\n'
189d310bb7SBarry Smith
199d310bb7SBarry Smith  def setupHelp(self, help):
209d310bb7SBarry Smith    import nargs
219d310bb7SBarry Smith    help.addArgument('PETSc', '-PETSC_ARCH=<string>',     nargs.Arg(None, None, 'The configuration name'))
229d310bb7SBarry Smith    help.addArgument('PETSc', '-with-petsc-arch=<string>',nargs.Arg(None, None, 'The configuration name'))
23*dd328ec0SBarry Smith    help.addArgument('PETSc', '-force=<bool>',            nargs.ArgBool(None, 0, 'Bypass configure hash caching, and run to completion'))
24*dd328ec0SBarry Smith    return
25*dd328ec0SBarry Smith
26*dd328ec0SBarry Smith  def setupDependencies(self, framework):
27*dd328ec0SBarry Smith    self.sourceControl = framework.require('config.sourceControl',self)
28*dd328ec0SBarry Smith    self.petscdir = framework.require('PETSc.options.petscdir', self)
299d310bb7SBarry Smith    return
309d310bb7SBarry Smith
3170211a5bSSatish Balay  def createArchitecture(self):
3270211a5bSSatish Balay    import sys
3370211a5bSSatish Balay    arch = 'arch-' + sys.platform.replace('cygwin','mswin')
3470211a5bSSatish Balay    # use opt/debug, c/c++ tags.s
3570211a5bSSatish Balay    arch+= '-'+self.framework.argDB['with-clanguage'].lower().replace('+','x')
3670211a5bSSatish Balay    if self.framework.argDB['with-debugging']:
3770211a5bSSatish Balay      arch += '-debug'
3870211a5bSSatish Balay    else:
3970211a5bSSatish Balay      arch += '-opt'
4070211a5bSSatish Balay    return arch
4170211a5bSSatish Balay
429d310bb7SBarry Smith  def configureArchitecture(self):
439d310bb7SBarry Smith    '''Checks PETSC_ARCH and sets if not set'''
449d310bb7SBarry Smith    # Warn if PETSC_ARCH doesnt match env variable
459d310bb7SBarry Smith    if 'PETSC_ARCH' in self.framework.argDB and 'PETSC_ARCH' in os.environ and self.framework.argDB['PETSC_ARCH'] != os.environ['PETSC_ARCH']:
469d310bb7SBarry Smith      self.logPrintBox('''\
479d310bb7SBarry SmithWarning: PETSC_ARCH from environment does not match command-line or name of script.
489d310bb7SBarry SmithWarning: Using from command-line or name of script: %s, ignoring environment: %s''' % (str(self.framework.argDB['PETSC_ARCH']), str(os.environ['PETSC_ARCH'])))
4957ea55fdSJed Brown      os.environ['PETSC_ARCH'] = self.framework.argDB['PETSC_ARCH']
509d310bb7SBarry Smith    if 'with-petsc-arch' in self.framework.argDB:
519d310bb7SBarry Smith      self.arch = self.framework.argDB['with-petsc-arch']
5270211a5bSSatish Balay      msg = 'option -with-petsc-arch='+str(self.arch)
539d310bb7SBarry Smith    elif 'PETSC_ARCH' in self.framework.argDB:
549d310bb7SBarry Smith      self.arch = self.framework.argDB['PETSC_ARCH']
5570211a5bSSatish Balay      msg = 'option PETSC_ARCH='+str(self.arch)
5670211a5bSSatish Balay    elif 'PETSC_ARCH' in os.environ:
579d310bb7SBarry Smith      self.arch = os.environ['PETSC_ARCH']
5870211a5bSSatish Balay      msg = 'environment variable PETSC_ARCH='+str(self.arch)
599d310bb7SBarry Smith    else:
6070211a5bSSatish Balay      self.arch = self.createArchitecture()
619d310bb7SBarry Smith    if self.arch.find('/') >= 0 or self.arch.find('\\') >= 0:
6270211a5bSSatish Balay      raise RuntimeError('PETSC_ARCH should not contain path characters, but you have specified with '+msg)
63002ae2c9SLisandro Dalcin    if self.arch.startswith('-'):
6470211a5bSSatish Balay      raise RuntimeError('PETSC_ARCH should not start with "-", but you have specified with '+msg)
6570211a5bSSatish Balay    if self.arch.startswith('.'):
6670211a5bSSatish Balay      raise RuntimeError('PETSC_ARCH should not start with ".", but you have specified with '+msg)
6770211a5bSSatish Balay    if not len(self.arch):
6870211a5bSSatish Balay      raise RuntimeError('PETSC_ARCH cannot be empty string. Use a valid string or do not set one. Currently set with '+msg)
699d310bb7SBarry Smith    self.archBase = re.sub(r'^(\w+)[-_]?.*$', r'\1', self.arch)
709d310bb7SBarry Smith    return
719d310bb7SBarry Smith
72*dd328ec0SBarry Smith  def makeDependency(self,hash):
73*dd328ec0SBarry Smith    import os
74*dd328ec0SBarry Smith    try:
75*dd328ec0SBarry Smith      os.makedirs(os.path.join(self.arch,'lib','petsc','conf'))
76*dd328ec0SBarry Smith    except:
77*dd328ec0SBarry Smith      pass
78*dd328ec0SBarry Smith    try:
79*dd328ec0SBarry Smith      with open(os.path.join(self.arch,'lib','petsc','conf','configure-hash'), 'w') as f:
80*dd328ec0SBarry Smith        f.write(hash)
81*dd328ec0SBarry Smith    except:
82*dd328ec0SBarry Smith      self.logPrint('Unable to make configure hash file: '+os.path.join(self.arch,'lib','petsc','conf','configure-hash'))
83*dd328ec0SBarry Smith      return
84*dd328ec0SBarry Smith    self.logPrint('Wrote configure hash file: '+os.path.join(self.arch,'lib','petsc','conf','configure-hash'))
85*dd328ec0SBarry Smith
86*dd328ec0SBarry Smith  def checkDependency(self):
87*dd328ec0SBarry Smith    '''Checks if configure needs to be run'''
88*dd328ec0SBarry Smith    '''Checks if files in config have changed, the command line options have changed or the PATH has changed'''
89*dd328ec0SBarry Smith    import os
90*dd328ec0SBarry Smith    import sys
91*dd328ec0SBarry Smith    import hashlib
92*dd328ec0SBarry Smith    args = list(filter(lambda x: not (x.startswith('PETSC_ARCH') or x == '--force'),sys.argv[1:]))
93*dd328ec0SBarry Smith    args.sort()
94*dd328ec0SBarry Smith    hash = str(args) + '\n'
95*dd328ec0SBarry Smith    try: hash += os.environ['PATH'] + '\n'
96*dd328ec0SBarry Smith    except: pass
97*dd328ec0SBarry Smith    try:
98*dd328ec0SBarry Smith      for root, dirs, files in os.walk('config'):
99*dd328ec0SBarry Smith        for f in files:
100*dd328ec0SBarry Smith          if f.endswith('.pyc') or f.endswith('~') or f.startswith('.') or f.startswith('#'): continue
101*dd328ec0SBarry Smith          fname = os.path.join(root,f)
102*dd328ec0SBarry Smith          md5sum = hashlib.md5(open(fname,'rb').read()).hexdigest()
103*dd328ec0SBarry Smith          hash += md5sum + ' '+ fname + '\n'
104*dd328ec0SBarry Smith    except:
105*dd328ec0SBarry Smith      self.logPrint('Error generating file list/md5 from config directory for configure hash, forcing new configuration')
106*dd328ec0SBarry Smith      return
107*dd328ec0SBarry Smith    if self.argDB['force']:
108*dd328ec0SBarry Smith      self.makeDependency(hash)
109*dd328ec0SBarry Smith      return
110*dd328ec0SBarry Smith    a = ''
111*dd328ec0SBarry Smith    try:
112*dd328ec0SBarry Smith      with open(os.path.join(self.arch,'lib','petsc','conf','configure-hash'), 'r') as f:
113*dd328ec0SBarry Smith        a = f.read()
114*dd328ec0SBarry Smith    except:
115*dd328ec0SBarry Smith      # no previous record so write current hash
116*dd328ec0SBarry Smith      self.makeDependency(hash)
117*dd328ec0SBarry Smith      return
118*dd328ec0SBarry Smith    if a == hash:
119*dd328ec0SBarry Smith      self.logPrint('configure hash file: '+os.path.join(self.arch,'lib','petsc','conf','configure-hash')+' matches; no need to run configure.')
120*dd328ec0SBarry Smith      print('Your configure options and state has not changed; no need to run configure')
121*dd328ec0SBarry Smith      print('However you can force a configure run using the option: --force')
122*dd328ec0SBarry Smith      sys.exit()
123*dd328ec0SBarry Smith    self.makeDependency(hash)
124*dd328ec0SBarry Smith    self.logPrint('configure hash file: '+os.path.join(self.arch,'lib','petsc','conf','configure-hash')+' does not match\n'+a+'\n---\n'+hash+'\n need to run configure')
125*dd328ec0SBarry Smith
1269d310bb7SBarry Smith  def configure(self):
1279d310bb7SBarry Smith    self.executeTest(self.configureArchitecture)
1289d310bb7SBarry Smith    # required by top-level configure.py
1299d310bb7SBarry Smith    self.framework.arch = self.arch
130*dd328ec0SBarry Smith    self.checkDependency()
1319d310bb7SBarry Smith    return
132