xref: /petsc/config/install.py (revision d97f9ea1a840d0cf79153fdb5a6928022d178273)
10ee81e68SLisandro Dalcin#!/usr/bin/env python
2e551db17SScott Krugerimport os, re, shutil, sys
30ee81e68SLisandro Dalcin
40ee81e68SLisandro Dalcinif os.environ.has_key('PETSC_DIR'):
50ee81e68SLisandro Dalcin  PETSC_DIR = os.environ['PETSC_DIR']
60ee81e68SLisandro Dalcinelse:
7af0996ceSBarry Smith  fd = file(os.path.join('lib','petsc','conf','petscvariables'))
80ee81e68SLisandro Dalcin  a = fd.readline()
90ee81e68SLisandro Dalcin  a = fd.readline()
100ee81e68SLisandro Dalcin  PETSC_DIR = a.split('=')[1][0:-1]
110ee81e68SLisandro Dalcin  fd.close()
120ee81e68SLisandro Dalcin
130ee81e68SLisandro Dalcinif os.environ.has_key('PETSC_ARCH'):
140ee81e68SLisandro Dalcin  PETSC_ARCH = os.environ['PETSC_ARCH']
150ee81e68SLisandro Dalcinelse:
16af0996ceSBarry Smith  fd = file(os.path.join('lib','petsc','conf','petscvariables'))
170ee81e68SLisandro Dalcin  a = fd.readline()
180ee81e68SLisandro Dalcin  PETSC_ARCH = a.split('=')[1][0:-1]
190ee81e68SLisandro Dalcin  fd.close()
200ee81e68SLisandro Dalcin
210ee81e68SLisandro Dalcinprint '*** Using PETSC_DIR='+PETSC_DIR+' PETSC_ARCH='+PETSC_ARCH+' ***'
220ee81e68SLisandro Dalcinsys.path.insert(0, os.path.join(PETSC_DIR, 'config'))
230ee81e68SLisandro Dalcinsys.path.insert(0, os.path.join(PETSC_DIR, 'config', 'BuildSystem'))
240ee81e68SLisandro Dalcin
250ee81e68SLisandro Dalcinimport script
260ee81e68SLisandro Dalcin
270ee81e68SLisandro Dalcintry:
280ee81e68SLisandro Dalcin  WindowsError
290ee81e68SLisandro Dalcinexcept NameError:
300ee81e68SLisandro Dalcin  WindowsError = None
310ee81e68SLisandro Dalcin
320ee81e68SLisandro Dalcinclass Installer(script.Script):
330ee81e68SLisandro Dalcin  def __init__(self, clArgs = None):
340ee81e68SLisandro Dalcin    import RDict
350ee81e68SLisandro Dalcin    argDB = RDict.RDict(None, None, 0, 0, readonly = True)
36af0996ceSBarry Smith    argDB.saveFilename = os.path.join(PETSC_DIR, PETSC_ARCH, 'lib','petsc','conf', 'RDict.db')
370ee81e68SLisandro Dalcin    argDB.load()
380ee81e68SLisandro Dalcin    script.Script.__init__(self, argDB = argDB)
390ee81e68SLisandro Dalcin    if not clArgs is None: self.clArgs = clArgs
400ee81e68SLisandro Dalcin    self.copies = []
410ee81e68SLisandro Dalcin    return
420ee81e68SLisandro Dalcin
430ee81e68SLisandro Dalcin  def setupHelp(self, help):
440ee81e68SLisandro Dalcin    import nargs
450ee81e68SLisandro Dalcin    script.Script.setupHelp(self, help)
460ee81e68SLisandro Dalcin    help.addArgument('Installer', '-destDir=<path>', nargs.Arg(None, None, 'Destination Directory for install'))
470ee81e68SLisandro Dalcin    return
480ee81e68SLisandro Dalcin
490ee81e68SLisandro Dalcin
500ee81e68SLisandro Dalcin  def setupModules(self):
510ee81e68SLisandro Dalcin    self.setCompilers  = self.framework.require('config.setCompilers',         None)
520ee81e68SLisandro Dalcin    self.arch          = self.framework.require('PETSc.options.arch',          None)
530ee81e68SLisandro Dalcin    self.petscdir      = self.framework.require('PETSc.options.petscdir',      None)
540ee81e68SLisandro Dalcin    self.compilers     = self.framework.require('config.compilers',            None)
5532cabb2fSBarry Smith    self.mpi           = self.framework.require('config.packages.MPI',         None)
560ee81e68SLisandro Dalcin    return
570ee81e68SLisandro Dalcin
580ee81e68SLisandro Dalcin  def setup(self):
590ee81e68SLisandro Dalcin    script.Script.setup(self)
600ee81e68SLisandro Dalcin    self.framework = self.loadConfigure()
610ee81e68SLisandro Dalcin    self.setupModules()
620ee81e68SLisandro Dalcin    return
630ee81e68SLisandro Dalcin
640ee81e68SLisandro Dalcin  def setupDirectories(self):
650ee81e68SLisandro Dalcin    self.rootDir    = self.petscdir.dir
664a08bad0SBarry Smith    self.installDir = os.path.abspath(os.path.expanduser(self.framework.argDB['prefix']))
678727f567SSatish Balay    self.destDir    = os.path.abspath(self.argDB['destDir']+self.installDir)
680ee81e68SLisandro Dalcin    self.arch       = self.arch.arch
6902e047dfSSatish Balay    self.archDir           = os.path.join(self.rootDir, self.arch)
700ee81e68SLisandro Dalcin    self.rootIncludeDir    = os.path.join(self.rootDir, 'include')
710ee81e68SLisandro Dalcin    self.archIncludeDir    = os.path.join(self.rootDir, self.arch, 'include')
72af0996ceSBarry Smith    self.rootConfDir       = os.path.join(self.rootDir, 'lib','petsc','conf')
73af0996ceSBarry Smith    self.archConfDir       = os.path.join(self.rootDir, self.arch, 'lib','petsc','conf')
74c3a89c15SBarry Smith    self.rootBinDir        = os.path.join(self.rootDir, 'lib','petsc','bin')
750ee81e68SLisandro Dalcin    self.archBinDir        = os.path.join(self.rootDir, self.arch, 'bin')
760ee81e68SLisandro Dalcin    self.archLibDir        = os.path.join(self.rootDir, self.arch, 'lib')
770ee81e68SLisandro Dalcin    self.destIncludeDir    = os.path.join(self.destDir, 'include')
78af0996ceSBarry Smith    self.destConfDir       = os.path.join(self.destDir, 'lib','petsc','conf')
790ee81e68SLisandro Dalcin    self.destLibDir        = os.path.join(self.destDir, 'lib')
80c3a89c15SBarry Smith    self.destBinDir        = os.path.join(self.destDir, 'lib','petsc','bin')
810ee81e68SLisandro Dalcin    self.installIncludeDir = os.path.join(self.installDir, 'include')
82c3a89c15SBarry Smith    self.installBinDir     = os.path.join(self.installDir, 'lib','petsc','bin')
830ee81e68SLisandro Dalcin    self.rootShareDir      = os.path.join(self.rootDir, 'share')
840ee81e68SLisandro Dalcin    self.destShareDir      = os.path.join(self.destDir, 'share')
8579eaf171SScott Kruger    self.rootSrcDir        = os.path.join(self.rootDir, 'src')
860ee81e68SLisandro Dalcin
870ee81e68SLisandro Dalcin    self.ranlib      = self.compilers.RANLIB
880ee81e68SLisandro Dalcin    self.arLibSuffix = self.compilers.AR_LIB_SUFFIX
890ee81e68SLisandro Dalcin    return
900ee81e68SLisandro Dalcin
910ee81e68SLisandro Dalcin  def checkPrefix(self):
920ee81e68SLisandro Dalcin    if not self.installDir:
930ee81e68SLisandro Dalcin      print '********************************************************************'
940ee81e68SLisandro Dalcin      print 'PETSc is built without prefix option. So "make install" is not appropriate.'
950ee81e68SLisandro Dalcin      print 'If you need a prefix install of PETSc - rerun configure with --prefix option.'
960ee81e68SLisandro Dalcin      print '********************************************************************'
970ee81e68SLisandro Dalcin      sys.exit(1)
980ee81e68SLisandro Dalcin    return
990ee81e68SLisandro Dalcin
1000ee81e68SLisandro Dalcin  def checkDestdir(self):
1010ee81e68SLisandro Dalcin    if os.path.exists(self.destDir):
1020ee81e68SLisandro Dalcin      if os.path.samefile(self.destDir, self.rootDir):
1030ee81e68SLisandro Dalcin        print '********************************************************************'
1040ee81e68SLisandro Dalcin        print 'Incorrect prefix usage. Specified destDir same as current PETSC_DIR'
1050ee81e68SLisandro Dalcin        print '********************************************************************'
1060ee81e68SLisandro Dalcin        sys.exit(1)
1070ee81e68SLisandro Dalcin      if os.path.samefile(self.destDir, os.path.join(self.rootDir,self.arch)):
1080ee81e68SLisandro Dalcin        print '********************************************************************'
1090ee81e68SLisandro Dalcin        print 'Incorrect prefix usage. Specified destDir same as current PETSC_DIR/PETSC_ARCH'
1100ee81e68SLisandro Dalcin        print '********************************************************************'
1110ee81e68SLisandro Dalcin        sys.exit(1)
1120ee81e68SLisandro Dalcin      if not os.path.isdir(os.path.realpath(self.destDir)):
1130ee81e68SLisandro Dalcin        print '********************************************************************'
1140ee81e68SLisandro Dalcin        print 'Specified destDir', self.destDir, 'is not a directory. Cannot proceed!'
1150ee81e68SLisandro Dalcin        print '********************************************************************'
1160ee81e68SLisandro Dalcin        sys.exit(1)
1170ee81e68SLisandro Dalcin      if not os.access(self.destDir, os.W_OK):
1180ee81e68SLisandro Dalcin        print '********************************************************************'
1190ee81e68SLisandro Dalcin        print 'Unable to write to ', self.destDir, 'Perhaps you need to do "sudo make install"'
1200ee81e68SLisandro Dalcin        print '********************************************************************'
1210ee81e68SLisandro Dalcin        sys.exit(1)
1220ee81e68SLisandro Dalcin    return
1230ee81e68SLisandro Dalcin
1240ee81e68SLisandro Dalcin  def copyfile(self, src, dst, symlinks = False, copyFunc = shutil.copy2):
1250ee81e68SLisandro Dalcin    """Copies a single file    """
1260ee81e68SLisandro Dalcin    copies = []
1270ee81e68SLisandro Dalcin    errors = []
1280ee81e68SLisandro Dalcin    if not os.path.exists(dst):
1290ee81e68SLisandro Dalcin      os.makedirs(dst)
1300ee81e68SLisandro Dalcin    elif not os.path.isdir(dst):
1310ee81e68SLisandro Dalcin      raise shutil.Error, 'Destination is not a directory'
1320ee81e68SLisandro Dalcin    srcname = src
1330ee81e68SLisandro Dalcin    dstname = os.path.join(dst, os.path.basename(src))
1340ee81e68SLisandro Dalcin    try:
1350ee81e68SLisandro Dalcin      if symlinks and os.path.islink(srcname):
1360ee81e68SLisandro Dalcin        linkto = os.readlink(srcname)
1370ee81e68SLisandro Dalcin        os.symlink(linkto, dstname)
1380ee81e68SLisandro Dalcin      else:
1390ee81e68SLisandro Dalcin        copyFunc(srcname, dstname)
1400ee81e68SLisandro Dalcin        copies.append((srcname, dstname))
1410ee81e68SLisandro Dalcin    except (IOError, os.error), why:
1420ee81e68SLisandro Dalcin      errors.append((srcname, dstname, str(why)))
1430ee81e68SLisandro Dalcin    except shutil.Error, err:
1440ee81e68SLisandro Dalcin      errors.extend((srcname,dstname,str(err.args[0])))
1450ee81e68SLisandro Dalcin    if errors:
1460ee81e68SLisandro Dalcin      raise shutil.Error, errors
1470ee81e68SLisandro Dalcin    return copies
1480ee81e68SLisandro Dalcin
14926e8aaceSBarry Smith  def copyexamplefiles(self, src, dst, copyFunc = shutil.copy2):
15026e8aaceSBarry Smith    """Copies all files, but not directories in a single file    """
15126e8aaceSBarry Smith    names  = os.listdir(src)
15226e8aaceSBarry Smith    for name in names:
15326e8aaceSBarry Smith      if not name.endswith('.html'):
15426e8aaceSBarry Smith        srcname = os.path.join(src, name)
15526e8aaceSBarry Smith        if os.path.isfile(srcname):
15626e8aaceSBarry Smith           self.copyfile(srcname,dst)
15726e8aaceSBarry Smith
15826e8aaceSBarry Smith  def fixExamplesMakefile(self, src):
15926e8aaceSBarry Smith    '''Change ././${PETSC_ARCH} in makefile in root petsc directory with ${PETSC_DIR}'''
16026e8aaceSBarry Smith    lines   = []
16126e8aaceSBarry Smith    oldFile = open(src, 'r')
162e551db17SScott Kruger    alllines=oldFile.read()
16326e8aaceSBarry Smith    oldFile.close()
164e551db17SScott Kruger    newlines=alllines.split('\n')[0]+'\n'  # Firstline
165e551db17SScott Kruger    # Hardcode PETSC_DIR and PETSC_ARCH to avoid users doing the worng thing
166e551db17SScott Kruger    newlines+='PETSC_DIR='+self.installDir+'\n'
167e551db17SScott Kruger    newlines+='PETSC_ARCH=\n'
168e551db17SScott Kruger    for line in alllines.split('\n')[1:]:
1694ff3c6a1SScott Kruger      if line.startswith('TESTLOGFILE'):
170c173c275SScott Kruger        newlines+='TESTLOGFILE = $(TESTDIR)/examples-install.log\n'
171e551db17SScott Kruger      elif line.startswith('CONFIGDIR'):
172e551db17SScott Kruger        newlines+='CONFIGDIR:=$(PETSC_DIR)/$(PETSC_ARCH)/share/petsc/examples/config\n'
1734ff3c6a1SScott Kruger      elif line.startswith('EXAMPLESDIR'):
174e551db17SScott Kruger        newlines+='EXAMPLESDIR:=$(PETSC_DIR)/$(PETSC_ARCH)/share/petsc/examples\n'
175fc46264cSScott Kruger      elif line.startswith('$(generatedtest)') and 'petscvariables' in line:
176c173c275SScott Kruger        newlines+='all: test\n\n'+line+'\n'
177e551db17SScott Kruger      else:
1784ff3c6a1SScott Kruger        newlines+=line+'\n'
17926e8aaceSBarry Smith    newFile = open(src, 'w')
180e551db17SScott Kruger    newFile.write(newlines)
18126e8aaceSBarry Smith    newFile.close()
18226e8aaceSBarry Smith    return
18326e8aaceSBarry Smith
184e551db17SScott Kruger  def copyConfig(self, src, dst):
185e551db17SScott Kruger    """Recursively copy the examples directories
186e551db17SScott Kruger    """
187e551db17SScott Kruger    if not os.path.isdir(dst):
188e551db17SScott Kruger      raise shutil.Error, 'Destination is not a directory'
189e551db17SScott Kruger
19049da0fa4SScott Kruger    self.copyfile('gmakefile.test',dst)
191e551db17SScott Kruger    newConfigDir=os.path.join(dst,'config')  # Am not renaming at present
192e551db17SScott Kruger    if not os.path.isdir(newConfigDir): os.mkdir(newConfigDir)
193e551db17SScott Kruger    testConfFiles="gmakegentest.py gmakegen.py testparse.py example_template.py".split()
194c173c275SScott Kruger    testConfFiles+="petsc_harness.sh report_tests.py watchtime.sh".split()
195c173c275SScott Kruger    testConfFiles+=["cmakegen.py"]
196e551db17SScott Kruger    for tf in testConfFiles:
197e551db17SScott Kruger      self.copyfile(os.path.join('config',tf),newConfigDir)
198e551db17SScott Kruger    return
199e551db17SScott Kruger
20026e8aaceSBarry Smith  def copyExamples(self, src, dst):
2014ff3c6a1SScott Kruger    """copy the examples directories
20226e8aaceSBarry Smith    """
2034ff3c6a1SScott Kruger    top=os.path.relpath(src,os.path.abspath(os.curdir))
2044ff3c6a1SScott Kruger    for root, dirs, files in os.walk(top, topdown=False):
2054ff3c6a1SScott Kruger        if not os.path.basename(root) == "examples": continue
2064ff3c6a1SScott Kruger        shutil.copytree(root, os.path.join(dst,root),
2074ff3c6a1SScott Kruger                        ignore=shutil.ignore_patterns('*.dSYM'))
20826e8aaceSBarry Smith
2094ff3c6a1SScott Kruger    return
2100ee81e68SLisandro Dalcin
21132cabb2fSBarry Smith  def copytree(self, src, dst, symlinks = False, copyFunc = shutil.copy2, exclude = [],recurse = 1):
2120ee81e68SLisandro Dalcin    """Recursively copy a directory tree using copyFunc, which defaults to shutil.copy2().
2130ee81e68SLisandro Dalcin
2140ee81e68SLisandro Dalcin       The copyFunc() you provide is only used on the top level, lower levels always use shutil.copy2
2150ee81e68SLisandro Dalcin
2160ee81e68SLisandro Dalcin    The destination directory must not already exist.
2170ee81e68SLisandro Dalcin    If exception(s) occur, an shutil.Error is raised with a list of reasons.
2180ee81e68SLisandro Dalcin
2190ee81e68SLisandro Dalcin    If the optional symlinks flag is true, symbolic links in the
2200ee81e68SLisandro Dalcin    source tree result in symbolic links in the destination tree; if
2210ee81e68SLisandro Dalcin    it is false, the contents of the files pointed to by symbolic
2220ee81e68SLisandro Dalcin    links are copied.
2230ee81e68SLisandro Dalcin    """
2240ee81e68SLisandro Dalcin    copies = []
2250ee81e68SLisandro Dalcin    names  = os.listdir(src)
2260ee81e68SLisandro Dalcin    if not os.path.exists(dst):
2270ee81e68SLisandro Dalcin      os.makedirs(dst)
2280ee81e68SLisandro Dalcin    elif not os.path.isdir(dst):
2290ee81e68SLisandro Dalcin      raise shutil.Error, 'Destination is not a directory'
2300ee81e68SLisandro Dalcin    errors = []
2310ee81e68SLisandro Dalcin    for name in names:
2320ee81e68SLisandro Dalcin      srcname = os.path.join(src, name)
2330ee81e68SLisandro Dalcin      dstname = os.path.join(dst, name)
2340ee81e68SLisandro Dalcin      try:
2350ee81e68SLisandro Dalcin        if symlinks and os.path.islink(srcname):
2360ee81e68SLisandro Dalcin          linkto = os.readlink(srcname)
2370ee81e68SLisandro Dalcin          os.symlink(linkto, dstname)
23832cabb2fSBarry Smith        elif os.path.isdir(srcname) and recurse and not os.path.basename(srcname) in exclude:
2390ee81e68SLisandro Dalcin          copies.extend(self.copytree(srcname, dstname, symlinks,exclude = exclude))
24032cabb2fSBarry Smith        elif os.path.isfile(srcname) and not os.path.basename(srcname) in exclude:
2410ee81e68SLisandro Dalcin          copyFunc(srcname, dstname)
2420ee81e68SLisandro Dalcin          copies.append((srcname, dstname))
2430ee81e68SLisandro Dalcin        # XXX What about devices, sockets etc.?
2440ee81e68SLisandro Dalcin      except (IOError, os.error), why:
2450ee81e68SLisandro Dalcin        errors.append((srcname, dstname, str(why)))
2460ee81e68SLisandro Dalcin      # catch the Error from the recursive copytree so that we can
2470ee81e68SLisandro Dalcin      # continue with other files
2480ee81e68SLisandro Dalcin      except shutil.Error, err:
2490ee81e68SLisandro Dalcin        errors.extend((srcname,dstname,str(err.args[0])))
2500ee81e68SLisandro Dalcin    try:
2510ee81e68SLisandro Dalcin      shutil.copystat(src, dst)
2520ee81e68SLisandro Dalcin    except OSError, e:
2530ee81e68SLisandro Dalcin      if WindowsError is not None and isinstance(e, WindowsError):
2540ee81e68SLisandro Dalcin        # Copying file access times may fail on Windows
2550ee81e68SLisandro Dalcin        pass
2560ee81e68SLisandro Dalcin      else:
2570ee81e68SLisandro Dalcin        errors.extend((src, dst, str(e)))
2580ee81e68SLisandro Dalcin    if errors:
2590ee81e68SLisandro Dalcin      raise shutil.Error, errors
2600ee81e68SLisandro Dalcin    return copies
2610ee81e68SLisandro Dalcin
2620ee81e68SLisandro Dalcin
2630ee81e68SLisandro Dalcin  def fixConfFile(self, src):
2640ee81e68SLisandro Dalcin    lines   = []
2650ee81e68SLisandro Dalcin    oldFile = open(src, 'r')
2660ee81e68SLisandro Dalcin    for line in oldFile.readlines():
2670ee81e68SLisandro Dalcin      # paths generated by configure could be different link-path than whats used by user, so fix both
2680ee81e68SLisandro Dalcin      line = line.replace(os.path.join(self.rootDir, self.arch), self.installDir)
2690ee81e68SLisandro Dalcin      line = line.replace(os.path.realpath(os.path.join(self.rootDir, self.arch)), self.installDir)
2700ee81e68SLisandro Dalcin      line = line.replace(os.path.join(self.rootDir, 'bin'), self.installBinDir)
2710ee81e68SLisandro Dalcin      line = line.replace(os.path.realpath(os.path.join(self.rootDir, 'bin')), self.installBinDir)
2720ee81e68SLisandro Dalcin      line = line.replace(os.path.join(self.rootDir, 'include'), self.installIncludeDir)
2730ee81e68SLisandro Dalcin      line = line.replace(os.path.realpath(os.path.join(self.rootDir, 'include')), self.installIncludeDir)
2740ee81e68SLisandro Dalcin      # remove PETSC_DIR/PETSC_ARCH variables from conf-makefiles. They are no longer necessary
2750ee81e68SLisandro Dalcin      line = line.replace('${PETSC_DIR}/${PETSC_ARCH}', self.installDir)
2760ee81e68SLisandro Dalcin      line = line.replace('PETSC_ARCH=${PETSC_ARCH}', '')
2770ee81e68SLisandro Dalcin      line = line.replace('${PETSC_DIR}', self.installDir)
2780ee81e68SLisandro Dalcin      lines.append(line)
2790ee81e68SLisandro Dalcin    oldFile.close()
2800ee81e68SLisandro Dalcin    newFile = open(src, 'w')
2810ee81e68SLisandro Dalcin    newFile.write(''.join(lines))
2820ee81e68SLisandro Dalcin    newFile.close()
2830ee81e68SLisandro Dalcin    return
2840ee81e68SLisandro Dalcin
2850ee81e68SLisandro Dalcin  def fixConf(self):
2860ee81e68SLisandro Dalcin    import shutil
2870ee81e68SLisandro Dalcin    for file in ['rules', 'variables','petscrules', 'petscvariables']:
2880ee81e68SLisandro Dalcin      self.fixConfFile(os.path.join(self.destConfDir,file))
2890ee81e68SLisandro Dalcin    self.fixConfFile(os.path.join(self.destLibDir,'pkgconfig','PETSc.pc'))
2900ee81e68SLisandro Dalcin    return
2910ee81e68SLisandro Dalcin
2920ee81e68SLisandro Dalcin  def createUninstaller(self):
2930ee81e68SLisandro Dalcin    uninstallscript = os.path.join(self.destConfDir, 'uninstall.py')
2940ee81e68SLisandro Dalcin    f = open(uninstallscript, 'w')
2950ee81e68SLisandro Dalcin    # Could use the Python AST to do this
2960ee81e68SLisandro Dalcin    f.write('#!'+sys.executable+'\n')
2970ee81e68SLisandro Dalcin    f.write('import os\n')
298*d97f9ea1SSatish Balay    f.write('prefixdir = "'+self.installDir+'"\n')
299*d97f9ea1SSatish Balay    files = [dst.replace(self.destDir,self.installDir) for src, dst in self.copies]
300*d97f9ea1SSatish Balay    files.append(uninstallscript.replace(self.destDir,self.installDir))
301*d97f9ea1SSatish Balay    f.write('files = '+repr(files))
3020ee81e68SLisandro Dalcin    f.write('''
303*d97f9ea1SSatish Balayfor file in files:
304*d97f9ea1SSatish Balay  if os.path.exists(file) or os.path.islink(file):
305*d97f9ea1SSatish Balay    os.remove(file)
306*d97f9ea1SSatish Balay    dir = os.path.dirname(file)
307*d97f9ea1SSatish Balay    while dir not in [prefixdir,'/']:
308*d97f9ea1SSatish Balay      if not os.listdir(dir):
309*d97f9ea1SSatish Balay        os.rmdir(dir)
310*d97f9ea1SSatish Balay      dir = os.path.dirname(dir)
3110ee81e68SLisandro Dalcin''')
3120ee81e68SLisandro Dalcin    f.close()
3130ee81e68SLisandro Dalcin    os.chmod(uninstallscript,0744)
3140ee81e68SLisandro Dalcin    return
3150ee81e68SLisandro Dalcin
3160ee81e68SLisandro Dalcin  def installIncludes(self):
31732cabb2fSBarry Smith    exclude = ['makefile']
31832cabb2fSBarry Smith    if not hasattr(self.compilers.setCompilers, 'FC'):
31932cabb2fSBarry Smith      exclude.append('finclude')
32032cabb2fSBarry Smith    if not self.mpi.usingMPIUni:
32132cabb2fSBarry Smith      exclude.append('mpiuni')
32232cabb2fSBarry Smith    self.copies.extend(self.copytree(self.rootIncludeDir, self.destIncludeDir,exclude = exclude))
3230ee81e68SLisandro Dalcin    self.copies.extend(self.copytree(self.archIncludeDir, self.destIncludeDir))
3240ee81e68SLisandro Dalcin    return
3250ee81e68SLisandro Dalcin
3260ee81e68SLisandro Dalcin  def installConf(self):
32732cabb2fSBarry Smith    self.copies.extend(self.copytree(self.rootConfDir, self.destConfDir, exclude = ['uncrustify.cfg','bfort-base.txt','bfort-petsc.txt','bfort-mpi.txt','test.log']))
32832cabb2fSBarry Smith    self.copies.extend(self.copytree(self.archConfDir, self.destConfDir, exclude = ['sowing', 'configure.log.bkp','configure.log','make.log','gmake.log','test.log','error.log']))
3290ee81e68SLisandro Dalcin    return
3300ee81e68SLisandro Dalcin
3310ee81e68SLisandro Dalcin  def installBin(self):
33232cabb2fSBarry Smith    exclude = ['bfort','bib2html','doc2lt','doctext','mapnames', 'pstogif','pstoxbm','tohtml']
33332cabb2fSBarry Smith    self.copies.extend(self.copytree(self.archBinDir, self.destBinDir, exclude = exclude ))
33432cabb2fSBarry Smith    exclude = ['maint']
33532cabb2fSBarry Smith    if not self.mpi.usingMPIUni:
33632cabb2fSBarry Smith      exclude.append('petsc-mpiexec.uni')
33732cabb2fSBarry Smith    self.setCompilers.pushLanguage('C')
33832cabb2fSBarry Smith    if not self.setCompilers.isWindows(self.setCompilers.getCompiler(),self.log):
33932cabb2fSBarry Smith      exclude.append('win32fe')
34032cabb2fSBarry Smith    self.setCompilers.popLanguage()
34132cabb2fSBarry Smith    self.copies.extend(self.copytree(self.rootBinDir, self.destBinDir, exclude = exclude ))
3420ee81e68SLisandro Dalcin    return
3430ee81e68SLisandro Dalcin
3440ee81e68SLisandro Dalcin  def installShare(self):
3450ee81e68SLisandro Dalcin    self.copies.extend(self.copytree(self.rootShareDir, self.destShareDir))
346c173c275SScott Kruger    examplesdir=os.path.join(self.destShareDir,'petsc','examples')
347c173c275SScott Kruger    if os.path.exists(examplesdir):
348c173c275SScott Kruger      shutil.rmtree(examplesdir)
349c173c275SScott Kruger    os.mkdir(examplesdir)
35079eaf171SScott Kruger    os.mkdir(os.path.join(examplesdir,'src'))
3514ff3c6a1SScott Kruger    self.copyExamples(self.rootSrcDir,examplesdir)
352c173c275SScott Kruger    self.copyConfig(self.rootDir,examplesdir)
353c173c275SScott Kruger    self.fixExamplesMakefile(os.path.join(examplesdir,'gmakefile.test'))
3540ee81e68SLisandro Dalcin    return
3550ee81e68SLisandro Dalcin
3560ee81e68SLisandro Dalcin  def copyLib(self, src, dst):
3570ee81e68SLisandro Dalcin    '''Run ranlib on the destination library if it is an archive. Also run install_name_tool on dylib on Mac'''
3580ee81e68SLisandro Dalcin    # Symlinks (assumed local) are recreated at dst
3590ee81e68SLisandro Dalcin    if os.path.islink(src):
3600ee81e68SLisandro Dalcin      linkto = os.readlink(src)
3610ee81e68SLisandro Dalcin      try:
3620ee81e68SLisandro Dalcin        os.remove(dst)            # In case it already exists
3630ee81e68SLisandro Dalcin      except OSError:
3640ee81e68SLisandro Dalcin        pass
3650ee81e68SLisandro Dalcin      os.symlink(linkto, dst)
3660ee81e68SLisandro Dalcin      return
3670ee81e68SLisandro Dalcin    # Do not install object files
3680ee81e68SLisandro Dalcin    if not os.path.splitext(src)[1] == '.o':
3690ee81e68SLisandro Dalcin      shutil.copy2(src, dst)
3700ee81e68SLisandro Dalcin    if os.path.splitext(dst)[1] == '.'+self.arLibSuffix:
3710ee81e68SLisandro Dalcin      self.executeShellCommand(self.ranlib+' '+dst)
3720ee81e68SLisandro Dalcin    if os.path.splitext(dst)[1] == '.dylib' and os.path.isfile('/usr/bin/install_name_tool'):
373af2c601bSBarry Smith      [output,err,flg] = self.executeShellCommand("otool -D "+src)
374af2c601bSBarry Smith      oldname = output[output.find("\n")+1:]
37502e047dfSSatish Balay      installName = oldname.replace(self.archDir, self.installDir)
3760ee81e68SLisandro Dalcin      self.executeShellCommand('/usr/bin/install_name_tool -id ' + installName + ' ' + dst)
3770ee81e68SLisandro Dalcin    # preserve the original timestamps - so that the .a vs .so time order is preserved
3780ee81e68SLisandro Dalcin    shutil.copystat(src,dst)
3790ee81e68SLisandro Dalcin    return
3800ee81e68SLisandro Dalcin
3810ee81e68SLisandro Dalcin  def installLib(self):
38232cabb2fSBarry Smith    self.copies.extend(self.copytree(self.archLibDir, self.destLibDir, copyFunc = self.copyLib, exclude = ['.DIR'],recurse = 0))
38332cabb2fSBarry 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))
3840ee81e68SLisandro Dalcin    return
3850ee81e68SLisandro Dalcin
3860ee81e68SLisandro Dalcin
3870ee81e68SLisandro Dalcin  def outputInstallDone(self):
3880ee81e68SLisandro Dalcin    print '''\
3890ee81e68SLisandro Dalcin====================================
3900ee81e68SLisandro DalcinInstall complete.
3910ee81e68SLisandro DalcinNow to check if the libraries are working do (in current directory):
3920ee81e68SLisandro Dalcinmake PETSC_DIR=%s PETSC_ARCH="" test
3930ee81e68SLisandro Dalcin====================================\
3940ee81e68SLisandro Dalcin''' % (self.installDir)
3950ee81e68SLisandro Dalcin    return
3960ee81e68SLisandro Dalcin
3970ee81e68SLisandro Dalcin  def outputDestDirDone(self):
3980ee81e68SLisandro Dalcin    print '''\
3990ee81e68SLisandro Dalcin====================================
4000ee81e68SLisandro DalcinCopy to DESTDIR %s is now complete.
4010ee81e68SLisandro DalcinBefore use - please copy/install over to specified prefix: %s
4020ee81e68SLisandro Dalcin====================================\
4030ee81e68SLisandro Dalcin''' % (self.destDir,self.installDir)
4040ee81e68SLisandro Dalcin    return
4050ee81e68SLisandro Dalcin
4060ee81e68SLisandro Dalcin  def runsetup(self):
4070ee81e68SLisandro Dalcin    self.setup()
4080ee81e68SLisandro Dalcin    self.setupDirectories()
4090ee81e68SLisandro Dalcin    self.checkPrefix()
4100ee81e68SLisandro Dalcin    self.checkDestdir()
4110ee81e68SLisandro Dalcin    return
4120ee81e68SLisandro Dalcin
4130ee81e68SLisandro Dalcin  def runcopy(self):
4140ee81e68SLisandro Dalcin    if self.destDir == self.installDir:
4150ee81e68SLisandro Dalcin      print '*** Installing PETSc at prefix location:',self.destDir, ' ***'
4160ee81e68SLisandro Dalcin    else:
4170ee81e68SLisandro Dalcin      print '*** Copying PETSc to DESTDIR location:',self.destDir, ' ***'
4180ee81e68SLisandro Dalcin    if not os.path.exists(self.destDir):
4190ee81e68SLisandro Dalcin      try:
4200ee81e68SLisandro Dalcin        os.makedirs(self.destDir)
4210ee81e68SLisandro Dalcin      except:
4220ee81e68SLisandro Dalcin        print '********************************************************************'
4230ee81e68SLisandro Dalcin        print 'Unable to create', self.destDir, 'Perhaps you need to do "sudo make install"'
4240ee81e68SLisandro Dalcin        print '********************************************************************'
4250ee81e68SLisandro Dalcin        sys.exit(1)
4260ee81e68SLisandro Dalcin    self.installIncludes()
4270ee81e68SLisandro Dalcin    self.installConf()
4280ee81e68SLisandro Dalcin    self.installBin()
4290ee81e68SLisandro Dalcin    self.installLib()
4300ee81e68SLisandro Dalcin    self.installShare()
4310ee81e68SLisandro Dalcin    return
4320ee81e68SLisandro Dalcin
4330ee81e68SLisandro Dalcin  def runfix(self):
4340ee81e68SLisandro Dalcin    self.fixConf()
4350ee81e68SLisandro Dalcin    return
4360ee81e68SLisandro Dalcin
4370ee81e68SLisandro Dalcin  def rundone(self):
4380ee81e68SLisandro Dalcin    self.createUninstaller()
4390ee81e68SLisandro Dalcin    if self.destDir == self.installDir:
4400ee81e68SLisandro Dalcin      self.outputInstallDone()
4410ee81e68SLisandro Dalcin    else:
4420ee81e68SLisandro Dalcin      self.outputDestDirDone()
4430ee81e68SLisandro Dalcin    return
4440ee81e68SLisandro Dalcin
4450ee81e68SLisandro Dalcin  def run(self):
4460ee81e68SLisandro Dalcin    self.runsetup()
4470ee81e68SLisandro Dalcin    self.runcopy()
4480ee81e68SLisandro Dalcin    self.runfix()
4490ee81e68SLisandro Dalcin    self.rundone()
4500ee81e68SLisandro Dalcin    return
4510ee81e68SLisandro Dalcin
4520ee81e68SLisandro Dalcinif __name__ == '__main__':
4530ee81e68SLisandro Dalcin  Installer(sys.argv[1:]).run()
4540ee81e68SLisandro Dalcin  # temporary hack - delete log files created by BuildSystem - when 'sudo make install' is invoked
45503e6d329SSatish Balay  delfiles=['RDict.db','RDict.log','buildsystem.log','default.log','buildsystem.log.bkp','default.log.bkp']
4560ee81e68SLisandro Dalcin  for delfile in delfiles:
4570ee81e68SLisandro Dalcin    if os.path.exists(delfile) and (os.stat(delfile).st_uid==0):
4580ee81e68SLisandro Dalcin      os.remove(delfile)
459