xref: /petsc/config/install.py (revision 5b6bfdb9644f185dbf5e5a09b808ec241507e1e7)
10ee81e68SLisandro Dalcin#!/usr/bin/env python
2*5b6bfdb9SJed Brownfrom __future__ import print_function
3e551db17SScott Krugerimport os, re, shutil, sys
40ee81e68SLisandro Dalcin
5*5b6bfdb9SJed Brownif 'PETSC_DIR' in os.environ:
60ee81e68SLisandro Dalcin  PETSC_DIR = os.environ['PETSC_DIR']
70ee81e68SLisandro Dalcinelse:
8af0996ceSBarry Smith  fd = file(os.path.join('lib','petsc','conf','petscvariables'))
90ee81e68SLisandro Dalcin  a = fd.readline()
100ee81e68SLisandro Dalcin  a = fd.readline()
110ee81e68SLisandro Dalcin  PETSC_DIR = a.split('=')[1][0:-1]
120ee81e68SLisandro Dalcin  fd.close()
130ee81e68SLisandro Dalcin
14*5b6bfdb9SJed Brownif 'PETSC_ARCH' in os.environ:
150ee81e68SLisandro Dalcin  PETSC_ARCH = os.environ['PETSC_ARCH']
160ee81e68SLisandro Dalcinelse:
17af0996ceSBarry Smith  fd = file(os.path.join('lib','petsc','conf','petscvariables'))
180ee81e68SLisandro Dalcin  a = fd.readline()
190ee81e68SLisandro Dalcin  PETSC_ARCH = a.split('=')[1][0:-1]
200ee81e68SLisandro Dalcin  fd.close()
210ee81e68SLisandro Dalcin
22*5b6bfdb9SJed Brownprint('*** Using PETSC_DIR='+PETSC_DIR+' PETSC_ARCH='+PETSC_ARCH+' ***')
230ee81e68SLisandro Dalcinsys.path.insert(0, os.path.join(PETSC_DIR, 'config'))
240ee81e68SLisandro Dalcinsys.path.insert(0, os.path.join(PETSC_DIR, 'config', 'BuildSystem'))
250ee81e68SLisandro Dalcin
260ee81e68SLisandro Dalcinimport script
270ee81e68SLisandro Dalcin
280ee81e68SLisandro Dalcintry:
290ee81e68SLisandro Dalcin  WindowsError
300ee81e68SLisandro Dalcinexcept NameError:
310ee81e68SLisandro Dalcin  WindowsError = None
320ee81e68SLisandro Dalcin
330ee81e68SLisandro Dalcinclass Installer(script.Script):
340ee81e68SLisandro Dalcin  def __init__(self, clArgs = None):
350ee81e68SLisandro Dalcin    import RDict
360ee81e68SLisandro Dalcin    argDB = RDict.RDict(None, None, 0, 0, readonly = True)
37af0996ceSBarry Smith    argDB.saveFilename = os.path.join(PETSC_DIR, PETSC_ARCH, 'lib','petsc','conf', 'RDict.db')
380ee81e68SLisandro Dalcin    argDB.load()
390ee81e68SLisandro Dalcin    script.Script.__init__(self, argDB = argDB)
400ee81e68SLisandro Dalcin    if not clArgs is None: self.clArgs = clArgs
410ee81e68SLisandro Dalcin    self.copies = []
420ee81e68SLisandro Dalcin    return
430ee81e68SLisandro Dalcin
440ee81e68SLisandro Dalcin  def setupHelp(self, help):
450ee81e68SLisandro Dalcin    import nargs
460ee81e68SLisandro Dalcin    script.Script.setupHelp(self, help)
47a26d7103SSatish Balay    help.addArgument('Installer', '-destDir=<path>', nargs.Arg(None, '', 'Destination Directory for install'))
480ee81e68SLisandro Dalcin    return
490ee81e68SLisandro Dalcin
500ee81e68SLisandro Dalcin
510ee81e68SLisandro Dalcin  def setupModules(self):
520ee81e68SLisandro Dalcin    self.setCompilers  = self.framework.require('config.setCompilers',         None)
530ee81e68SLisandro Dalcin    self.arch          = self.framework.require('PETSc.options.arch',          None)
540ee81e68SLisandro Dalcin    self.petscdir      = self.framework.require('PETSc.options.petscdir',      None)
550ee81e68SLisandro Dalcin    self.compilers     = self.framework.require('config.compilers',            None)
5632cabb2fSBarry Smith    self.mpi           = self.framework.require('config.packages.MPI',         None)
570ee81e68SLisandro Dalcin    return
580ee81e68SLisandro Dalcin
590ee81e68SLisandro Dalcin  def setup(self):
600ee81e68SLisandro Dalcin    script.Script.setup(self)
610ee81e68SLisandro Dalcin    self.framework = self.loadConfigure()
620ee81e68SLisandro Dalcin    self.setupModules()
630ee81e68SLisandro Dalcin    return
640ee81e68SLisandro Dalcin
650ee81e68SLisandro Dalcin  def setupDirectories(self):
660ee81e68SLisandro Dalcin    self.rootDir    = self.petscdir.dir
674a08bad0SBarry Smith    self.installDir = os.path.abspath(os.path.expanduser(self.framework.argDB['prefix']))
688727f567SSatish Balay    self.destDir    = os.path.abspath(self.argDB['destDir']+self.installDir)
690ee81e68SLisandro Dalcin    self.arch       = self.arch.arch
7002e047dfSSatish Balay    self.archDir           = os.path.join(self.rootDir, self.arch)
710ee81e68SLisandro Dalcin    self.rootIncludeDir    = os.path.join(self.rootDir, 'include')
720ee81e68SLisandro Dalcin    self.archIncludeDir    = os.path.join(self.rootDir, self.arch, 'include')
73af0996ceSBarry Smith    self.rootConfDir       = os.path.join(self.rootDir, 'lib','petsc','conf')
74af0996ceSBarry Smith    self.archConfDir       = os.path.join(self.rootDir, self.arch, 'lib','petsc','conf')
75c3a89c15SBarry Smith    self.rootBinDir        = os.path.join(self.rootDir, 'lib','petsc','bin')
760ee81e68SLisandro Dalcin    self.archBinDir        = os.path.join(self.rootDir, self.arch, 'bin')
770ee81e68SLisandro Dalcin    self.archLibDir        = os.path.join(self.rootDir, self.arch, 'lib')
780ee81e68SLisandro Dalcin    self.destIncludeDir    = os.path.join(self.destDir, 'include')
79af0996ceSBarry Smith    self.destConfDir       = os.path.join(self.destDir, 'lib','petsc','conf')
800ee81e68SLisandro Dalcin    self.destLibDir        = os.path.join(self.destDir, 'lib')
81c3a89c15SBarry Smith    self.destBinDir        = os.path.join(self.destDir, 'lib','petsc','bin')
820ee81e68SLisandro Dalcin    self.installIncludeDir = os.path.join(self.installDir, 'include')
83c3a89c15SBarry Smith    self.installBinDir     = os.path.join(self.installDir, 'lib','petsc','bin')
840ee81e68SLisandro Dalcin    self.rootShareDir      = os.path.join(self.rootDir, 'share')
850ee81e68SLisandro Dalcin    self.destShareDir      = os.path.join(self.destDir, 'share')
8679eaf171SScott Kruger    self.rootSrcDir        = os.path.join(self.rootDir, 'src')
870ee81e68SLisandro Dalcin
880ee81e68SLisandro Dalcin    self.ranlib      = self.compilers.RANLIB
890ee81e68SLisandro Dalcin    self.arLibSuffix = self.compilers.AR_LIB_SUFFIX
900ee81e68SLisandro Dalcin    return
910ee81e68SLisandro Dalcin
920ee81e68SLisandro Dalcin  def checkPrefix(self):
930ee81e68SLisandro Dalcin    if not self.installDir:
94*5b6bfdb9SJed Brown      print('********************************************************************')
95*5b6bfdb9SJed Brown      print('PETSc is built without prefix option. So "make install" is not appropriate.')
96*5b6bfdb9SJed Brown      print('If you need a prefix install of PETSc - rerun configure with --prefix option.')
97*5b6bfdb9SJed Brown      print('********************************************************************')
980ee81e68SLisandro Dalcin      sys.exit(1)
990ee81e68SLisandro Dalcin    return
1000ee81e68SLisandro Dalcin
1010ee81e68SLisandro Dalcin  def checkDestdir(self):
1020ee81e68SLisandro Dalcin    if os.path.exists(self.destDir):
1030ee81e68SLisandro Dalcin      if os.path.samefile(self.destDir, self.rootDir):
104*5b6bfdb9SJed Brown        print('********************************************************************')
105*5b6bfdb9SJed Brown        print('Incorrect prefix usage. Specified destDir same as current PETSC_DIR')
106*5b6bfdb9SJed Brown        print('********************************************************************')
1070ee81e68SLisandro Dalcin        sys.exit(1)
1080ee81e68SLisandro Dalcin      if os.path.samefile(self.destDir, os.path.join(self.rootDir,self.arch)):
109*5b6bfdb9SJed Brown        print('********************************************************************')
110*5b6bfdb9SJed Brown        print('Incorrect prefix usage. Specified destDir same as current PETSC_DIR/PETSC_ARCH')
111*5b6bfdb9SJed Brown        print('********************************************************************')
1120ee81e68SLisandro Dalcin        sys.exit(1)
1130ee81e68SLisandro Dalcin      if not os.path.isdir(os.path.realpath(self.destDir)):
114*5b6bfdb9SJed Brown        print('********************************************************************')
115*5b6bfdb9SJed Brown        print('Specified destDir', self.destDir, 'is not a directory. Cannot proceed!')
116*5b6bfdb9SJed Brown        print('********************************************************************')
1170ee81e68SLisandro Dalcin        sys.exit(1)
1180ee81e68SLisandro Dalcin      if not os.access(self.destDir, os.W_OK):
119*5b6bfdb9SJed Brown        print('********************************************************************')
120*5b6bfdb9SJed Brown        print('Unable to write to ', self.destDir, 'Perhaps you need to do "sudo make install"')
121*5b6bfdb9SJed Brown        print('********************************************************************')
1220ee81e68SLisandro Dalcin        sys.exit(1)
1230ee81e68SLisandro Dalcin    return
1240ee81e68SLisandro Dalcin
1250ee81e68SLisandro Dalcin  def copyfile(self, src, dst, symlinks = False, copyFunc = shutil.copy2):
1260ee81e68SLisandro Dalcin    """Copies a single file    """
1270ee81e68SLisandro Dalcin    copies = []
1280ee81e68SLisandro Dalcin    errors = []
1290ee81e68SLisandro Dalcin    if not os.path.exists(dst):
1300ee81e68SLisandro Dalcin      os.makedirs(dst)
1310ee81e68SLisandro Dalcin    elif not os.path.isdir(dst):
132*5b6bfdb9SJed Brown      raise shutil.Error('Destination is not a directory')
1330ee81e68SLisandro Dalcin    srcname = src
1340ee81e68SLisandro Dalcin    dstname = os.path.join(dst, os.path.basename(src))
1350ee81e68SLisandro Dalcin    try:
1360ee81e68SLisandro Dalcin      if symlinks and os.path.islink(srcname):
1370ee81e68SLisandro Dalcin        linkto = os.readlink(srcname)
1380ee81e68SLisandro Dalcin        os.symlink(linkto, dstname)
1390ee81e68SLisandro Dalcin      else:
1400ee81e68SLisandro Dalcin        copyFunc(srcname, dstname)
1410ee81e68SLisandro Dalcin        copies.append((srcname, dstname))
142*5b6bfdb9SJed Brown    except (IOError, os.error) as why:
1430ee81e68SLisandro Dalcin      errors.append((srcname, dstname, str(why)))
144*5b6bfdb9SJed Brown    except shutil.Error as err:
1450ee81e68SLisandro Dalcin      errors.extend((srcname,dstname,str(err.args[0])))
1460ee81e68SLisandro Dalcin    if errors:
147*5b6bfdb9SJed Brown      raise shutil.Error(errors)
1480ee81e68SLisandro Dalcin    return copies
1490ee81e68SLisandro Dalcin
15026e8aaceSBarry Smith  def fixExamplesMakefile(self, src):
15126e8aaceSBarry Smith    '''Change ././${PETSC_ARCH} in makefile in root petsc directory with ${PETSC_DIR}'''
15226e8aaceSBarry Smith    lines   = []
15326e8aaceSBarry Smith    oldFile = open(src, 'r')
154e551db17SScott Kruger    alllines=oldFile.read()
15526e8aaceSBarry Smith    oldFile.close()
156e551db17SScott Kruger    newlines=alllines.split('\n')[0]+'\n'  # Firstline
157e551db17SScott Kruger    # Hardcode PETSC_DIR and PETSC_ARCH to avoid users doing the worng thing
158e551db17SScott Kruger    newlines+='PETSC_DIR='+self.installDir+'\n'
159e551db17SScott Kruger    newlines+='PETSC_ARCH=\n'
160e551db17SScott Kruger    for line in alllines.split('\n')[1:]:
1614ff3c6a1SScott Kruger      if line.startswith('TESTLOGFILE'):
162c173c275SScott Kruger        newlines+='TESTLOGFILE = $(TESTDIR)/examples-install.log\n'
163e551db17SScott Kruger      elif line.startswith('CONFIGDIR'):
164e551db17SScott Kruger        newlines+='CONFIGDIR:=$(PETSC_DIR)/$(PETSC_ARCH)/share/petsc/examples/config\n'
165fc46264cSScott Kruger      elif line.startswith('$(generatedtest)') and 'petscvariables' in line:
166c173c275SScott Kruger        newlines+='all: test\n\n'+line+'\n'
167e551db17SScott Kruger      else:
1684ff3c6a1SScott Kruger        newlines+=line+'\n'
16926e8aaceSBarry Smith    newFile = open(src, 'w')
170e551db17SScott Kruger    newFile.write(newlines)
17126e8aaceSBarry Smith    newFile.close()
17226e8aaceSBarry Smith    return
17326e8aaceSBarry Smith
174e551db17SScott Kruger  def copyConfig(self, src, dst):
175e551db17SScott Kruger    """Recursively copy the examples directories
176e551db17SScott Kruger    """
177e551db17SScott Kruger    if not os.path.isdir(dst):
178*5b6bfdb9SJed Brown      raise shutil.Error('Destination is not a directory')
179e551db17SScott Kruger
180adf35c6eSSatish Balay    self.copies.extend(self.copyfile('gmakefile.test',dst))
181e551db17SScott Kruger    newConfigDir=os.path.join(dst,'config')  # Am not renaming at present
182e551db17SScott Kruger    if not os.path.isdir(newConfigDir): os.mkdir(newConfigDir)
183e551db17SScott Kruger    testConfFiles="gmakegentest.py gmakegen.py testparse.py example_template.py".split()
184a3ee17d7SJed Brown    testConfFiles+="petsc_harness.sh report_tests.py".split()
185c173c275SScott Kruger    testConfFiles+=["cmakegen.py"]
186e551db17SScott Kruger    for tf in testConfFiles:
187adf35c6eSSatish Balay      self.copies.extend(self.copyfile(os.path.join('config',tf),newConfigDir))
188e551db17SScott Kruger    return
189e551db17SScott Kruger
19026e8aaceSBarry Smith  def copyExamples(self, src, dst):
1914ff3c6a1SScott Kruger    """copy the examples directories
19226e8aaceSBarry Smith    """
1934ff3c6a1SScott Kruger    top=os.path.relpath(src,os.path.abspath(os.curdir))
1944ff3c6a1SScott Kruger    for root, dirs, files in os.walk(top, topdown=False):
1954ff3c6a1SScott Kruger        if not os.path.basename(root) == "examples": continue
1960080bb28SSatish Balay        self.copies.extend(self.copytree(root, os.path.join(dst,root)))
1974ff3c6a1SScott Kruger    return
1980ee81e68SLisandro Dalcin
1990080bb28SSatish Balay  def copytree(self, src, dst, symlinks = False, copyFunc = shutil.copy2, exclude = [], exclude_ext= ['.DSYM','.o','.pyc'], recurse = 1):
2000ee81e68SLisandro Dalcin    """Recursively copy a directory tree using copyFunc, which defaults to shutil.copy2().
2010ee81e68SLisandro Dalcin
2020ee81e68SLisandro Dalcin       The copyFunc() you provide is only used on the top level, lower levels always use shutil.copy2
2030ee81e68SLisandro Dalcin
2040ee81e68SLisandro Dalcin    The destination directory must not already exist.
2050ee81e68SLisandro Dalcin    If exception(s) occur, an shutil.Error is raised with a list of reasons.
2060ee81e68SLisandro Dalcin
2070ee81e68SLisandro Dalcin    If the optional symlinks flag is true, symbolic links in the
2080ee81e68SLisandro Dalcin    source tree result in symbolic links in the destination tree; if
2090ee81e68SLisandro Dalcin    it is false, the contents of the files pointed to by symbolic
2100ee81e68SLisandro Dalcin    links are copied.
2110ee81e68SLisandro Dalcin    """
2120ee81e68SLisandro Dalcin    copies = []
2130ee81e68SLisandro Dalcin    names  = os.listdir(src)
2140ee81e68SLisandro Dalcin    if not os.path.exists(dst):
2150ee81e68SLisandro Dalcin      os.makedirs(dst)
2160ee81e68SLisandro Dalcin    elif not os.path.isdir(dst):
217*5b6bfdb9SJed Brown      raise shutil.Error('Destination is not a directory')
2180ee81e68SLisandro Dalcin    errors = []
2190ee81e68SLisandro Dalcin    for name in names:
2200ee81e68SLisandro Dalcin      srcname = os.path.join(src, name)
2210ee81e68SLisandro Dalcin      dstname = os.path.join(dst, name)
2220ee81e68SLisandro Dalcin      try:
2230ee81e68SLisandro Dalcin        if symlinks and os.path.islink(srcname):
2240ee81e68SLisandro Dalcin          linkto = os.readlink(srcname)
2250ee81e68SLisandro Dalcin          os.symlink(linkto, dstname)
22632cabb2fSBarry Smith        elif os.path.isdir(srcname) and recurse and not os.path.basename(srcname) in exclude:
227adf35c6eSSatish Balay          copies.extend(self.copytree(srcname, dstname, symlinks,exclude = exclude, exclude_ext = exclude_ext))
228adf35c6eSSatish Balay        elif os.path.isfile(srcname) and not os.path.basename(srcname) in exclude and os.path.splitext(name)[1] not in exclude_ext :
2290ee81e68SLisandro Dalcin          copyFunc(srcname, dstname)
2300ee81e68SLisandro Dalcin          copies.append((srcname, dstname))
2310ee81e68SLisandro Dalcin        # XXX What about devices, sockets etc.?
232*5b6bfdb9SJed Brown      except (IOError, os.error) as why:
2330ee81e68SLisandro Dalcin        errors.append((srcname, dstname, str(why)))
2340ee81e68SLisandro Dalcin      # catch the Error from the recursive copytree so that we can
2350ee81e68SLisandro Dalcin      # continue with other files
236*5b6bfdb9SJed Brown      except shutil.Error as err:
2370ee81e68SLisandro Dalcin        errors.extend((srcname,dstname,str(err.args[0])))
2380ee81e68SLisandro Dalcin    try:
2390ee81e68SLisandro Dalcin      shutil.copystat(src, dst)
240*5b6bfdb9SJed Brown    except OSError as e:
2410ee81e68SLisandro Dalcin      if WindowsError is not None and isinstance(e, WindowsError):
2420ee81e68SLisandro Dalcin        # Copying file access times may fail on Windows
2430ee81e68SLisandro Dalcin        pass
2440ee81e68SLisandro Dalcin      else:
2450ee81e68SLisandro Dalcin        errors.extend((src, dst, str(e)))
2460ee81e68SLisandro Dalcin    if errors:
247*5b6bfdb9SJed Brown      raise shutil.Error(errors)
2480ee81e68SLisandro Dalcin    return copies
2490ee81e68SLisandro Dalcin
2500ee81e68SLisandro Dalcin
2510ee81e68SLisandro Dalcin  def fixConfFile(self, src):
2520ee81e68SLisandro Dalcin    lines   = []
2530ee81e68SLisandro Dalcin    oldFile = open(src, 'r')
2540ee81e68SLisandro Dalcin    for line in oldFile.readlines():
2550ee81e68SLisandro Dalcin      # paths generated by configure could be different link-path than whats used by user, so fix both
2560ee81e68SLisandro Dalcin      line = line.replace(os.path.join(self.rootDir, self.arch), self.installDir)
2570ee81e68SLisandro Dalcin      line = line.replace(os.path.realpath(os.path.join(self.rootDir, self.arch)), self.installDir)
2580ee81e68SLisandro Dalcin      line = line.replace(os.path.join(self.rootDir, 'bin'), self.installBinDir)
2590ee81e68SLisandro Dalcin      line = line.replace(os.path.realpath(os.path.join(self.rootDir, 'bin')), self.installBinDir)
2600ee81e68SLisandro Dalcin      line = line.replace(os.path.join(self.rootDir, 'include'), self.installIncludeDir)
2610ee81e68SLisandro Dalcin      line = line.replace(os.path.realpath(os.path.join(self.rootDir, 'include')), self.installIncludeDir)
2620ee81e68SLisandro Dalcin      # remove PETSC_DIR/PETSC_ARCH variables from conf-makefiles. They are no longer necessary
2630ee81e68SLisandro Dalcin      line = line.replace('${PETSC_DIR}/${PETSC_ARCH}', self.installDir)
2640ee81e68SLisandro Dalcin      line = line.replace('PETSC_ARCH=${PETSC_ARCH}', '')
2650ee81e68SLisandro Dalcin      line = line.replace('${PETSC_DIR}', self.installDir)
2660ee81e68SLisandro Dalcin      lines.append(line)
2670ee81e68SLisandro Dalcin    oldFile.close()
2680ee81e68SLisandro Dalcin    newFile = open(src, 'w')
2690ee81e68SLisandro Dalcin    newFile.write(''.join(lines))
2700ee81e68SLisandro Dalcin    newFile.close()
2710ee81e68SLisandro Dalcin    return
2720ee81e68SLisandro Dalcin
2730ee81e68SLisandro Dalcin  def fixConf(self):
2740ee81e68SLisandro Dalcin    import shutil
2750ee81e68SLisandro Dalcin    for file in ['rules', 'variables','petscrules', 'petscvariables']:
2760ee81e68SLisandro Dalcin      self.fixConfFile(os.path.join(self.destConfDir,file))
2770ee81e68SLisandro Dalcin    self.fixConfFile(os.path.join(self.destLibDir,'pkgconfig','PETSc.pc'))
2780ee81e68SLisandro Dalcin    return
2790ee81e68SLisandro Dalcin
2800ee81e68SLisandro Dalcin  def createUninstaller(self):
2810ee81e68SLisandro Dalcin    uninstallscript = os.path.join(self.destConfDir, 'uninstall.py')
2820ee81e68SLisandro Dalcin    f = open(uninstallscript, 'w')
2830ee81e68SLisandro Dalcin    # Could use the Python AST to do this
2840ee81e68SLisandro Dalcin    f.write('#!'+sys.executable+'\n')
2850ee81e68SLisandro Dalcin    f.write('import os\n')
286d97f9ea1SSatish Balay    f.write('prefixdir = "'+self.installDir+'"\n')
287d97f9ea1SSatish Balay    files = [dst.replace(self.destDir,self.installDir) for src, dst in self.copies]
288d97f9ea1SSatish Balay    files.append(uninstallscript.replace(self.destDir,self.installDir))
289d97f9ea1SSatish Balay    f.write('files = '+repr(files))
2900ee81e68SLisandro Dalcin    f.write('''
291d97f9ea1SSatish Balayfor file in files:
292d97f9ea1SSatish Balay  if os.path.exists(file) or os.path.islink(file):
293d97f9ea1SSatish Balay    os.remove(file)
294d97f9ea1SSatish Balay    dir = os.path.dirname(file)
2952b39596bSSatish Balay    while dir not in [os.path.dirname(prefixdir),'/']:
2962b39596bSSatish Balay      try: os.rmdir(dir)
2972b39596bSSatish Balay      except: break
298d97f9ea1SSatish Balay      dir = os.path.dirname(dir)
2990ee81e68SLisandro Dalcin''')
3000ee81e68SLisandro Dalcin    f.close()
301*5b6bfdb9SJed Brown    os.chmod(uninstallscript,0o744)
3020ee81e68SLisandro Dalcin    return
3030ee81e68SLisandro Dalcin
3040ee81e68SLisandro Dalcin  def installIncludes(self):
30532cabb2fSBarry Smith    exclude = ['makefile']
30632cabb2fSBarry Smith    if not hasattr(self.compilers.setCompilers, 'FC'):
30732cabb2fSBarry Smith      exclude.append('finclude')
30832cabb2fSBarry Smith    if not self.mpi.usingMPIUni:
30932cabb2fSBarry Smith      exclude.append('mpiuni')
31032cabb2fSBarry Smith    self.copies.extend(self.copytree(self.rootIncludeDir, self.destIncludeDir,exclude = exclude))
3110ee81e68SLisandro Dalcin    self.copies.extend(self.copytree(self.archIncludeDir, self.destIncludeDir))
3120ee81e68SLisandro Dalcin    return
3130ee81e68SLisandro Dalcin
3140ee81e68SLisandro Dalcin  def installConf(self):
31532cabb2fSBarry Smith    self.copies.extend(self.copytree(self.rootConfDir, self.destConfDir, exclude = ['uncrustify.cfg','bfort-base.txt','bfort-petsc.txt','bfort-mpi.txt','test.log']))
3160080bb28SSatish Balay    self.copies.extend(self.copytree(self.archConfDir, self.destConfDir, exclude = ['sowing', 'configure.log.bkp','configure.log','make.log','gmake.log','test.log','error.log','files','testfiles','RDict.db']))
3170ee81e68SLisandro Dalcin    return
3180ee81e68SLisandro Dalcin
3190ee81e68SLisandro Dalcin  def installBin(self):
32032cabb2fSBarry Smith    exclude = ['bfort','bib2html','doc2lt','doctext','mapnames', 'pstogif','pstoxbm','tohtml']
32132cabb2fSBarry Smith    self.copies.extend(self.copytree(self.archBinDir, self.destBinDir, exclude = exclude ))
32232cabb2fSBarry Smith    exclude = ['maint']
32332cabb2fSBarry Smith    if not self.mpi.usingMPIUni:
32432cabb2fSBarry Smith      exclude.append('petsc-mpiexec.uni')
32532cabb2fSBarry Smith    self.setCompilers.pushLanguage('C')
32632cabb2fSBarry Smith    if not self.setCompilers.isWindows(self.setCompilers.getCompiler(),self.log):
32732cabb2fSBarry Smith      exclude.append('win32fe')
32832cabb2fSBarry Smith    self.setCompilers.popLanguage()
32932cabb2fSBarry Smith    self.copies.extend(self.copytree(self.rootBinDir, self.destBinDir, exclude = exclude ))
3300ee81e68SLisandro Dalcin    return
3310ee81e68SLisandro Dalcin
3320ee81e68SLisandro Dalcin  def installShare(self):
3330ee81e68SLisandro Dalcin    self.copies.extend(self.copytree(self.rootShareDir, self.destShareDir))
334c173c275SScott Kruger    examplesdir=os.path.join(self.destShareDir,'petsc','examples')
335c173c275SScott Kruger    if os.path.exists(examplesdir):
336c173c275SScott Kruger      shutil.rmtree(examplesdir)
337c173c275SScott Kruger    os.mkdir(examplesdir)
33879eaf171SScott Kruger    os.mkdir(os.path.join(examplesdir,'src'))
3394ff3c6a1SScott Kruger    self.copyExamples(self.rootSrcDir,examplesdir)
340c173c275SScott Kruger    self.copyConfig(self.rootDir,examplesdir)
341c173c275SScott Kruger    self.fixExamplesMakefile(os.path.join(examplesdir,'gmakefile.test'))
3420ee81e68SLisandro Dalcin    return
3430ee81e68SLisandro Dalcin
3440ee81e68SLisandro Dalcin  def copyLib(self, src, dst):
3450ee81e68SLisandro Dalcin    '''Run ranlib on the destination library if it is an archive. Also run install_name_tool on dylib on Mac'''
3460ee81e68SLisandro Dalcin    # Symlinks (assumed local) are recreated at dst
3470ee81e68SLisandro Dalcin    if os.path.islink(src):
3480ee81e68SLisandro Dalcin      linkto = os.readlink(src)
3490ee81e68SLisandro Dalcin      try:
3500ee81e68SLisandro Dalcin        os.remove(dst)            # In case it already exists
3510ee81e68SLisandro Dalcin      except OSError:
3520ee81e68SLisandro Dalcin        pass
3530ee81e68SLisandro Dalcin      os.symlink(linkto, dst)
3540ee81e68SLisandro Dalcin      return
3550ee81e68SLisandro Dalcin    shutil.copy2(src, dst)
3560ee81e68SLisandro Dalcin    if os.path.splitext(dst)[1] == '.'+self.arLibSuffix:
3570ee81e68SLisandro Dalcin      self.executeShellCommand(self.ranlib+' '+dst)
3580ee81e68SLisandro Dalcin    if os.path.splitext(dst)[1] == '.dylib' and os.path.isfile('/usr/bin/install_name_tool'):
359af2c601bSBarry Smith      [output,err,flg] = self.executeShellCommand("otool -D "+src)
360af2c601bSBarry Smith      oldname = output[output.find("\n")+1:]
36102e047dfSSatish Balay      installName = oldname.replace(self.archDir, self.installDir)
3620ee81e68SLisandro Dalcin      self.executeShellCommand('/usr/bin/install_name_tool -id ' + installName + ' ' + dst)
3630ee81e68SLisandro Dalcin    # preserve the original timestamps - so that the .a vs .so time order is preserved
3640ee81e68SLisandro Dalcin    shutil.copystat(src,dst)
3650ee81e68SLisandro Dalcin    return
3660ee81e68SLisandro Dalcin
3670ee81e68SLisandro Dalcin  def installLib(self):
36832cabb2fSBarry Smith    self.copies.extend(self.copytree(self.archLibDir, self.destLibDir, copyFunc = self.copyLib, exclude = ['.DIR'],recurse = 0))
36932cabb2fSBarry Smith    self.copies.extend(self.copytree(os.path.join(self.archLibDir,'pkgconfig'), os.path.join(self.destLibDir,'pkgconfig'), copyFunc = self.copyLib, exclude = ['.DIR'],recurse = 0))
3700ee81e68SLisandro Dalcin    return
3710ee81e68SLisandro Dalcin
3720ee81e68SLisandro Dalcin
3730ee81e68SLisandro Dalcin  def outputInstallDone(self):
374*5b6bfdb9SJed Brown    print('''\
3750ee81e68SLisandro Dalcin====================================
3760ee81e68SLisandro DalcinInstall complete.
3770ee81e68SLisandro DalcinNow to check if the libraries are working do (in current directory):
3780ee81e68SLisandro Dalcinmake PETSC_DIR=%s PETSC_ARCH="" test
3790ee81e68SLisandro Dalcin====================================\
380*5b6bfdb9SJed Brown''' % (self.installDir))
3810ee81e68SLisandro Dalcin    return
3820ee81e68SLisandro Dalcin
3830ee81e68SLisandro Dalcin  def outputDestDirDone(self):
384*5b6bfdb9SJed Brown    print('''\
3850ee81e68SLisandro Dalcin====================================
3860ee81e68SLisandro DalcinCopy to DESTDIR %s is now complete.
3870ee81e68SLisandro DalcinBefore use - please copy/install over to specified prefix: %s
3880ee81e68SLisandro Dalcin====================================\
389*5b6bfdb9SJed Brown''' % (self.destDir,self.installDir))
3900ee81e68SLisandro Dalcin    return
3910ee81e68SLisandro Dalcin
3920ee81e68SLisandro Dalcin  def runsetup(self):
3930ee81e68SLisandro Dalcin    self.setup()
3940ee81e68SLisandro Dalcin    self.setupDirectories()
3950ee81e68SLisandro Dalcin    self.checkPrefix()
3960ee81e68SLisandro Dalcin    self.checkDestdir()
3970ee81e68SLisandro Dalcin    return
3980ee81e68SLisandro Dalcin
3990ee81e68SLisandro Dalcin  def runcopy(self):
4000ee81e68SLisandro Dalcin    if self.destDir == self.installDir:
401*5b6bfdb9SJed Brown      print('*** Installing PETSc at prefix location:',self.destDir, ' ***')
4020ee81e68SLisandro Dalcin    else:
403*5b6bfdb9SJed Brown      print('*** Copying PETSc to DESTDIR location:',self.destDir, ' ***')
4040ee81e68SLisandro Dalcin    if not os.path.exists(self.destDir):
4050ee81e68SLisandro Dalcin      try:
4060ee81e68SLisandro Dalcin        os.makedirs(self.destDir)
4070ee81e68SLisandro Dalcin      except:
408*5b6bfdb9SJed Brown        print('********************************************************************')
409*5b6bfdb9SJed Brown        print('Unable to create', self.destDir, 'Perhaps you need to do "sudo make install"')
410*5b6bfdb9SJed Brown        print('********************************************************************')
4110ee81e68SLisandro Dalcin        sys.exit(1)
4120ee81e68SLisandro Dalcin    self.installIncludes()
4130ee81e68SLisandro Dalcin    self.installConf()
4140ee81e68SLisandro Dalcin    self.installBin()
4150ee81e68SLisandro Dalcin    self.installLib()
4160ee81e68SLisandro Dalcin    self.installShare()
4170ee81e68SLisandro Dalcin    return
4180ee81e68SLisandro Dalcin
4190ee81e68SLisandro Dalcin  def runfix(self):
4200ee81e68SLisandro Dalcin    self.fixConf()
4210ee81e68SLisandro Dalcin    return
4220ee81e68SLisandro Dalcin
4230ee81e68SLisandro Dalcin  def rundone(self):
4240ee81e68SLisandro Dalcin    self.createUninstaller()
4250ee81e68SLisandro Dalcin    if self.destDir == self.installDir:
4260ee81e68SLisandro Dalcin      self.outputInstallDone()
4270ee81e68SLisandro Dalcin    else:
4280ee81e68SLisandro Dalcin      self.outputDestDirDone()
4290ee81e68SLisandro Dalcin    return
4300ee81e68SLisandro Dalcin
4310ee81e68SLisandro Dalcin  def run(self):
4320ee81e68SLisandro Dalcin    self.runsetup()
4330ee81e68SLisandro Dalcin    self.runcopy()
4340ee81e68SLisandro Dalcin    self.runfix()
4350ee81e68SLisandro Dalcin    self.rundone()
4360ee81e68SLisandro Dalcin    return
4370ee81e68SLisandro Dalcin
4380ee81e68SLisandro Dalcinif __name__ == '__main__':
4390ee81e68SLisandro Dalcin  Installer(sys.argv[1:]).run()
4400ee81e68SLisandro Dalcin  # temporary hack - delete log files created by BuildSystem - when 'sudo make install' is invoked
44103e6d329SSatish Balay  delfiles=['RDict.db','RDict.log','buildsystem.log','default.log','buildsystem.log.bkp','default.log.bkp']
4420ee81e68SLisandro Dalcin  for delfile in delfiles:
4430ee81e68SLisandro Dalcin    if os.path.exists(delfile) and (os.stat(delfile).st_uid==0):
4440ee81e68SLisandro Dalcin      os.remove(delfile)
445