xref: /petsc/config/install.py (revision 79eaf171441c89c500e31166c5bebb3ce81d5ec7)
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)
550ee81e68SLisandro Dalcin    return
560ee81e68SLisandro Dalcin
570ee81e68SLisandro Dalcin  def setup(self):
580ee81e68SLisandro Dalcin    script.Script.setup(self)
590ee81e68SLisandro Dalcin    self.framework = self.loadConfigure()
600ee81e68SLisandro Dalcin    self.setupModules()
610ee81e68SLisandro Dalcin    return
620ee81e68SLisandro Dalcin
630ee81e68SLisandro Dalcin  def setupDirectories(self):
640ee81e68SLisandro Dalcin    self.rootDir    = self.petscdir.dir
650ee81e68SLisandro Dalcin    self.destDir    = os.path.abspath(self.argDB['destDir'])
664a08bad0SBarry Smith    self.installDir = os.path.abspath(os.path.expanduser(self.framework.argDB['prefix']))
670ee81e68SLisandro Dalcin    self.arch       = self.arch.arch
6802e047dfSSatish Balay    self.archDir           = os.path.join(self.rootDir, self.arch)
690ee81e68SLisandro Dalcin    self.rootIncludeDir    = os.path.join(self.rootDir, 'include')
700ee81e68SLisandro Dalcin    self.archIncludeDir    = os.path.join(self.rootDir, self.arch, 'include')
71af0996ceSBarry Smith    self.rootConfDir       = os.path.join(self.rootDir, 'lib','petsc','conf')
72af0996ceSBarry Smith    self.archConfDir       = os.path.join(self.rootDir, self.arch, 'lib','petsc','conf')
730ee81e68SLisandro Dalcin    self.rootBinDir        = os.path.join(self.rootDir, 'bin')
740ee81e68SLisandro Dalcin    self.archBinDir        = os.path.join(self.rootDir, self.arch, 'bin')
750ee81e68SLisandro Dalcin    self.archLibDir        = os.path.join(self.rootDir, self.arch, 'lib')
760ee81e68SLisandro Dalcin    self.destIncludeDir    = os.path.join(self.destDir, 'include')
77af0996ceSBarry Smith    self.destConfDir       = os.path.join(self.destDir, 'lib','petsc','conf')
780ee81e68SLisandro Dalcin    self.destLibDir        = os.path.join(self.destDir, 'lib')
790ee81e68SLisandro Dalcin    self.destBinDir        = os.path.join(self.destDir, 'bin')
800ee81e68SLisandro Dalcin    self.installIncludeDir = os.path.join(self.installDir, 'include')
810ee81e68SLisandro Dalcin    self.installBinDir     = os.path.join(self.installDir, 'bin')
820ee81e68SLisandro Dalcin    self.rootShareDir      = os.path.join(self.rootDir, 'share')
830ee81e68SLisandro Dalcin    self.destShareDir      = os.path.join(self.destDir, 'share')
84*79eaf171SScott Kruger    self.rootSrcDir        = os.path.join(self.rootDir, 'src')
850ee81e68SLisandro Dalcin
860ee81e68SLisandro Dalcin    self.ranlib      = self.compilers.RANLIB
870ee81e68SLisandro Dalcin    self.arLibSuffix = self.compilers.AR_LIB_SUFFIX
880ee81e68SLisandro Dalcin    return
890ee81e68SLisandro Dalcin
900ee81e68SLisandro Dalcin  def checkPrefix(self):
910ee81e68SLisandro Dalcin    if not self.installDir:
920ee81e68SLisandro Dalcin      print '********************************************************************'
930ee81e68SLisandro Dalcin      print 'PETSc is built without prefix option. So "make install" is not appropriate.'
940ee81e68SLisandro Dalcin      print 'If you need a prefix install of PETSc - rerun configure with --prefix option.'
950ee81e68SLisandro Dalcin      print '********************************************************************'
960ee81e68SLisandro Dalcin      sys.exit(1)
970ee81e68SLisandro Dalcin    return
980ee81e68SLisandro Dalcin
990ee81e68SLisandro Dalcin  def checkDestdir(self):
1000ee81e68SLisandro Dalcin    if os.path.exists(self.destDir):
1010ee81e68SLisandro Dalcin      if os.path.samefile(self.destDir, self.rootDir):
1020ee81e68SLisandro Dalcin        print '********************************************************************'
1030ee81e68SLisandro Dalcin        print 'Incorrect prefix usage. Specified destDir same as current PETSC_DIR'
1040ee81e68SLisandro Dalcin        print '********************************************************************'
1050ee81e68SLisandro Dalcin        sys.exit(1)
1060ee81e68SLisandro Dalcin      if os.path.samefile(self.destDir, os.path.join(self.rootDir,self.arch)):
1070ee81e68SLisandro Dalcin        print '********************************************************************'
1080ee81e68SLisandro Dalcin        print 'Incorrect prefix usage. Specified destDir same as current PETSC_DIR/PETSC_ARCH'
1090ee81e68SLisandro Dalcin        print '********************************************************************'
1100ee81e68SLisandro Dalcin        sys.exit(1)
1110ee81e68SLisandro Dalcin      if not os.path.isdir(os.path.realpath(self.destDir)):
1120ee81e68SLisandro Dalcin        print '********************************************************************'
1130ee81e68SLisandro Dalcin        print 'Specified destDir', self.destDir, 'is not a directory. Cannot proceed!'
1140ee81e68SLisandro Dalcin        print '********************************************************************'
1150ee81e68SLisandro Dalcin        sys.exit(1)
1160ee81e68SLisandro Dalcin      if not os.access(self.destDir, os.W_OK):
1170ee81e68SLisandro Dalcin        print '********************************************************************'
1180ee81e68SLisandro Dalcin        print 'Unable to write to ', self.destDir, 'Perhaps you need to do "sudo make install"'
1190ee81e68SLisandro Dalcin        print '********************************************************************'
1200ee81e68SLisandro Dalcin        sys.exit(1)
1210ee81e68SLisandro Dalcin    return
1220ee81e68SLisandro Dalcin
1230ee81e68SLisandro Dalcin  def copyfile(self, src, dst, symlinks = False, copyFunc = shutil.copy2):
1240ee81e68SLisandro Dalcin    """Copies a single file    """
1250ee81e68SLisandro Dalcin    copies = []
1260ee81e68SLisandro Dalcin    errors = []
1270ee81e68SLisandro Dalcin    if not os.path.exists(dst):
1280ee81e68SLisandro Dalcin      os.makedirs(dst)
1290ee81e68SLisandro Dalcin    elif not os.path.isdir(dst):
1300ee81e68SLisandro Dalcin      raise shutil.Error, 'Destination is not a directory'
1310ee81e68SLisandro Dalcin    srcname = src
1320ee81e68SLisandro Dalcin    dstname = os.path.join(dst, os.path.basename(src))
1330ee81e68SLisandro Dalcin    try:
1340ee81e68SLisandro Dalcin      if symlinks and os.path.islink(srcname):
1350ee81e68SLisandro Dalcin        linkto = os.readlink(srcname)
1360ee81e68SLisandro Dalcin        os.symlink(linkto, dstname)
1370ee81e68SLisandro Dalcin      else:
1380ee81e68SLisandro Dalcin        copyFunc(srcname, dstname)
1390ee81e68SLisandro Dalcin        copies.append((srcname, dstname))
1400ee81e68SLisandro Dalcin    except (IOError, os.error), why:
1410ee81e68SLisandro Dalcin      errors.append((srcname, dstname, str(why)))
1420ee81e68SLisandro Dalcin    except shutil.Error, err:
1430ee81e68SLisandro Dalcin      errors.extend((srcname,dstname,str(err.args[0])))
1440ee81e68SLisandro Dalcin    if errors:
1450ee81e68SLisandro Dalcin      raise shutil.Error, errors
1460ee81e68SLisandro Dalcin    return copies
1470ee81e68SLisandro Dalcin
14826e8aaceSBarry Smith  def copyexamplefiles(self, src, dst, copyFunc = shutil.copy2):
14926e8aaceSBarry Smith    """Copies all files, but not directories in a single file    """
15026e8aaceSBarry Smith    names  = os.listdir(src)
15126e8aaceSBarry Smith    for name in names:
15226e8aaceSBarry Smith      if not name.endswith('.html'):
15326e8aaceSBarry Smith        srcname = os.path.join(src, name)
15426e8aaceSBarry Smith        if os.path.isfile(srcname):
15526e8aaceSBarry Smith           self.copyfile(srcname,dst)
15626e8aaceSBarry Smith
15726e8aaceSBarry Smith  def fixExamplesMakefile(self, src):
15826e8aaceSBarry Smith    '''Change ././${PETSC_ARCH} in makefile in root petsc directory with ${PETSC_DIR}'''
15926e8aaceSBarry Smith    lines   = []
16026e8aaceSBarry Smith    oldFile = open(src, 'r')
161e551db17SScott Kruger    alllines=oldFile.read()
16226e8aaceSBarry Smith    oldFile.close()
163e551db17SScott Kruger    newlines=alllines.split('\n')[0]+'\n'  # Firstline
164e551db17SScott Kruger    # Hardcode PETSC_DIR and PETSC_ARCH to avoid users doing the worng thing
165e551db17SScott Kruger    newlines+='PETSC_DIR='+self.installDir+'\n'
166e551db17SScott Kruger    newlines+='PETSC_ARCH=\n'
167e551db17SScott Kruger    for line in alllines.split('\n')[1:]:
168e551db17SScott Kruger      if line.startswith('#'):
169e551db17SScott Kruger        newlines+=line+'\n'
170c173c275SScott Kruger      elif line.startswith('TESTLOGFILE'):
171c173c275SScott Kruger        newlines+='TESTLOGFILE = $(TESTDIR)/examples-install.log\n'
172e551db17SScott Kruger      elif line.startswith('CONFIGDIR'):
173e551db17SScott Kruger        newlines+='CONFIGDIR:=$(PETSC_DIR)/$(PETSC_ARCH)/share/petsc/examples/config\n'
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      elif line.startswith('$(TESTDIR)/'):
178e551db17SScott Kruger        newlines+=re.sub(' %.',' $(EXAMPLESDIR)/%.',line)+'\n'
179e551db17SScott Kruger      elif line.startswith('include ./lib/petsc/conf/variables'):
180c173c275SScott Kruger        newlines+=re.sub('include ./lib/petsc/conf/variables',
181c173c275SScott Kruger                         'include $(PETSC_DIR)/$(PETSC_ARCH)/lib/petsc/conf/variables',
182c173c275SScott Kruger                         line)+'\n'
183e551db17SScott Kruger      else:
184e551db17SScott Kruger        newlines+=re.sub('PETSC_ARCH','PETSC_DIR)/$(PETSC_ARCH',line)+'\n'
18526e8aaceSBarry Smith    newFile = open(src, 'w')
186e551db17SScott Kruger    newFile.write(newlines)
18726e8aaceSBarry Smith    newFile.close()
18826e8aaceSBarry Smith    return
18926e8aaceSBarry Smith
190e551db17SScott Kruger  def copyConfig(self, src, dst):
191e551db17SScott Kruger    """Recursively copy the examples directories
192e551db17SScott Kruger    """
193e551db17SScott Kruger    if not os.path.isdir(dst):
194e551db17SScott Kruger      raise shutil.Error, 'Destination is not a directory'
195e551db17SScott Kruger
19649da0fa4SScott Kruger    self.copyfile('gmakefile.test',dst)
197e551db17SScott Kruger    newConfigDir=os.path.join(dst,'config')  # Am not renaming at present
198e551db17SScott Kruger    if not os.path.isdir(newConfigDir): os.mkdir(newConfigDir)
199e551db17SScott Kruger    testConfFiles="gmakegentest.py gmakegen.py testparse.py example_template.py".split()
200c173c275SScott Kruger    testConfFiles+="petsc_harness.sh report_tests.py watchtime.sh".split()
201c173c275SScott Kruger    testConfFiles+=["cmakegen.py"]
202e551db17SScott Kruger    for tf in testConfFiles:
203e551db17SScott Kruger      self.copyfile(os.path.join('config',tf),newConfigDir)
204e551db17SScott Kruger    return
205e551db17SScott Kruger
20626e8aaceSBarry Smith  def copyExamples(self, src, dst):
20726e8aaceSBarry Smith    """Recursively copy the examples directories
20826e8aaceSBarry Smith    """
20926e8aaceSBarry Smith    if not os.path.isdir(dst):
21026e8aaceSBarry Smith      raise shutil.Error, 'Destination is not a directory'
21126e8aaceSBarry Smith
21226e8aaceSBarry Smith    names  = os.listdir(src)
21396122cabSBarry Smith    nret2 = 0
21426e8aaceSBarry Smith    for name in names:
21526e8aaceSBarry Smith      srcname = os.path.join(src, name)
21626e8aaceSBarry Smith      dstname = os.path.join(dst, name)
217*79eaf171SScott Kruger      if os.path.isdir(srcname) and os.path.isfile(os.path.join(srcname,'makefile')):
21826e8aaceSBarry Smith        os.mkdir(dstname)
21996122cabSBarry Smith        nret = self.copyExamples(srcname,dstname)
220*79eaf171SScott Kruger        if 'examples' in srcname:
22126e8aaceSBarry Smith          self.copyexamplefiles(srcname,dstname)
22226e8aaceSBarry Smith          if os.path.isdir(os.path.join(srcname,'output')):
22326e8aaceSBarry Smith            os.mkdir(os.path.join(dstname,'output'))
22426e8aaceSBarry Smith            self.copyexamplefiles(os.path.join(srcname,'output'),os.path.join(dstname,'output'))
22596122cabSBarry Smith          nret = 1
22696122cabSBarry Smith        if not nret:
22796122cabSBarry Smith          # prune directory branches that don't have examples under them
22896122cabSBarry Smith          os.rmdir(dstname)
22996122cabSBarry Smith        nret2 = nret + nret2
23096122cabSBarry Smith    return nret2
2310ee81e68SLisandro Dalcin
2320ee81e68SLisandro Dalcin  def copytree(self, src, dst, symlinks = False, copyFunc = shutil.copy2, exclude = []):
2330ee81e68SLisandro Dalcin    """Recursively copy a directory tree using copyFunc, which defaults to shutil.copy2().
2340ee81e68SLisandro Dalcin
2350ee81e68SLisandro Dalcin       The copyFunc() you provide is only used on the top level, lower levels always use shutil.copy2
2360ee81e68SLisandro Dalcin
2370ee81e68SLisandro Dalcin    The destination directory must not already exist.
2380ee81e68SLisandro Dalcin    If exception(s) occur, an shutil.Error is raised with a list of reasons.
2390ee81e68SLisandro Dalcin
2400ee81e68SLisandro Dalcin    If the optional symlinks flag is true, symbolic links in the
2410ee81e68SLisandro Dalcin    source tree result in symbolic links in the destination tree; if
2420ee81e68SLisandro Dalcin    it is false, the contents of the files pointed to by symbolic
2430ee81e68SLisandro Dalcin    links are copied.
2440ee81e68SLisandro Dalcin    """
2450ee81e68SLisandro Dalcin    copies = []
2460ee81e68SLisandro Dalcin    names  = os.listdir(src)
2470ee81e68SLisandro Dalcin    if not os.path.exists(dst):
2480ee81e68SLisandro Dalcin      os.makedirs(dst)
2490ee81e68SLisandro Dalcin    elif not os.path.isdir(dst):
2500ee81e68SLisandro Dalcin      raise shutil.Error, 'Destination is not a directory'
2510ee81e68SLisandro Dalcin    errors = []
2520ee81e68SLisandro Dalcin    for name in names:
2530ee81e68SLisandro Dalcin      srcname = os.path.join(src, name)
2540ee81e68SLisandro Dalcin      dstname = os.path.join(dst, name)
2550ee81e68SLisandro Dalcin      try:
2560ee81e68SLisandro Dalcin        if symlinks and os.path.islink(srcname):
2570ee81e68SLisandro Dalcin          linkto = os.readlink(srcname)
2580ee81e68SLisandro Dalcin          os.symlink(linkto, dstname)
2590ee81e68SLisandro Dalcin        elif os.path.isdir(srcname):
2600ee81e68SLisandro Dalcin          copies.extend(self.copytree(srcname, dstname, symlinks,exclude = exclude))
2610ee81e68SLisandro Dalcin        elif not os.path.basename(srcname) in exclude:
2620ee81e68SLisandro Dalcin          copyFunc(srcname, dstname)
2630ee81e68SLisandro Dalcin          copies.append((srcname, dstname))
2640ee81e68SLisandro Dalcin        # XXX What about devices, sockets etc.?
2650ee81e68SLisandro Dalcin      except (IOError, os.error), why:
2660ee81e68SLisandro Dalcin        errors.append((srcname, dstname, str(why)))
2670ee81e68SLisandro Dalcin      # catch the Error from the recursive copytree so that we can
2680ee81e68SLisandro Dalcin      # continue with other files
2690ee81e68SLisandro Dalcin      except shutil.Error, err:
2700ee81e68SLisandro Dalcin        errors.extend((srcname,dstname,str(err.args[0])))
2710ee81e68SLisandro Dalcin    try:
2720ee81e68SLisandro Dalcin      shutil.copystat(src, dst)
2730ee81e68SLisandro Dalcin    except OSError, e:
2740ee81e68SLisandro Dalcin      if WindowsError is not None and isinstance(e, WindowsError):
2750ee81e68SLisandro Dalcin        # Copying file access times may fail on Windows
2760ee81e68SLisandro Dalcin        pass
2770ee81e68SLisandro Dalcin      else:
2780ee81e68SLisandro Dalcin        errors.extend((src, dst, str(e)))
2790ee81e68SLisandro Dalcin    if errors:
2800ee81e68SLisandro Dalcin      raise shutil.Error, errors
2810ee81e68SLisandro Dalcin    return copies
2820ee81e68SLisandro Dalcin
2830ee81e68SLisandro Dalcin
2840ee81e68SLisandro Dalcin  def fixConfFile(self, src):
2850ee81e68SLisandro Dalcin    lines   = []
2860ee81e68SLisandro Dalcin    oldFile = open(src, 'r')
2870ee81e68SLisandro Dalcin    for line in oldFile.readlines():
2880ee81e68SLisandro Dalcin      # paths generated by configure could be different link-path than whats used by user, so fix both
2890ee81e68SLisandro Dalcin      line = line.replace(os.path.join(self.rootDir, self.arch), self.installDir)
2900ee81e68SLisandro Dalcin      line = line.replace(os.path.realpath(os.path.join(self.rootDir, self.arch)), self.installDir)
2910ee81e68SLisandro Dalcin      line = line.replace(os.path.join(self.rootDir, 'bin'), self.installBinDir)
2920ee81e68SLisandro Dalcin      line = line.replace(os.path.realpath(os.path.join(self.rootDir, 'bin')), self.installBinDir)
2930ee81e68SLisandro Dalcin      line = line.replace(os.path.join(self.rootDir, 'include'), self.installIncludeDir)
2940ee81e68SLisandro Dalcin      line = line.replace(os.path.realpath(os.path.join(self.rootDir, 'include')), self.installIncludeDir)
2950ee81e68SLisandro Dalcin      # remove PETSC_DIR/PETSC_ARCH variables from conf-makefiles. They are no longer necessary
2960ee81e68SLisandro Dalcin      line = line.replace('${PETSC_DIR}/${PETSC_ARCH}', self.installDir)
2970ee81e68SLisandro Dalcin      line = line.replace('PETSC_ARCH=${PETSC_ARCH}', '')
2980ee81e68SLisandro Dalcin      line = line.replace('${PETSC_DIR}', self.installDir)
2990ee81e68SLisandro Dalcin      lines.append(line)
3000ee81e68SLisandro Dalcin    oldFile.close()
3010ee81e68SLisandro Dalcin    newFile = open(src, 'w')
3020ee81e68SLisandro Dalcin    newFile.write(''.join(lines))
3030ee81e68SLisandro Dalcin    newFile.close()
3040ee81e68SLisandro Dalcin    return
3050ee81e68SLisandro Dalcin
3060ee81e68SLisandro Dalcin  def fixConf(self):
3070ee81e68SLisandro Dalcin    import shutil
3080ee81e68SLisandro Dalcin    for file in ['rules', 'variables','petscrules', 'petscvariables']:
3090ee81e68SLisandro Dalcin      self.fixConfFile(os.path.join(self.destConfDir,file))
3100ee81e68SLisandro Dalcin    self.fixConfFile(os.path.join(self.destLibDir,'pkgconfig','PETSc.pc'))
3110ee81e68SLisandro Dalcin    return
3120ee81e68SLisandro Dalcin
3130ee81e68SLisandro Dalcin  def createUninstaller(self):
3140ee81e68SLisandro Dalcin    uninstallscript = os.path.join(self.destConfDir, 'uninstall.py')
3150ee81e68SLisandro Dalcin    f = open(uninstallscript, 'w')
3160ee81e68SLisandro Dalcin    # Could use the Python AST to do this
3170ee81e68SLisandro Dalcin    f.write('#!'+sys.executable+'\n')
3180ee81e68SLisandro Dalcin    f.write('import os\n')
3190ee81e68SLisandro Dalcin
3200ee81e68SLisandro Dalcin    f.write('copies = '+repr(self.copies).replace(self.destDir,self.installDir))
3210ee81e68SLisandro Dalcin    f.write('''
3220ee81e68SLisandro Dalcinfor src, dst in copies:
3230ee81e68SLisandro Dalcin  try:
3240ee81e68SLisandro Dalcin    os.remove(dst)
3250ee81e68SLisandro Dalcin  except:
3260ee81e68SLisandro Dalcin    pass
3270ee81e68SLisandro Dalcin''')
3280ee81e68SLisandro Dalcin    #TODO: need to delete libXXX.YYY.dylib.dSYM directory on Mac
329af0996ceSBarry Smith    dirs = [os.path.join('include','petsc','finclude'),os.path.join('include','petsc','mpiuni'),os.path.join('include','petsc','private'),os.path.join('bin'),os.path.join('lib','petsc','conf')]
3300ee81e68SLisandro Dalcin    newdirs = []
3310ee81e68SLisandro Dalcin    for dir in dirs: newdirs.append(os.path.join(self.installDir,dir))
3320ee81e68SLisandro Dalcin    f.write('dirs = '+str(newdirs))
3330ee81e68SLisandro Dalcin    f.write('''
3340ee81e68SLisandro Dalcinfor dir in dirs:
3350ee81e68SLisandro Dalcin  import shutil
3360ee81e68SLisandro Dalcin  try:
3370ee81e68SLisandro Dalcin    shutil.rmtree(dir)
3380ee81e68SLisandro Dalcin  except:
3390ee81e68SLisandro Dalcin    pass
3400ee81e68SLisandro Dalcin''')
3410ee81e68SLisandro Dalcin    f.close()
3420ee81e68SLisandro Dalcin    os.chmod(uninstallscript,0744)
3430ee81e68SLisandro Dalcin    return
3440ee81e68SLisandro Dalcin
3450ee81e68SLisandro Dalcin  def installIncludes(self):
3460ee81e68SLisandro Dalcin    # TODO: should exclude petsc-mpi.uni except for uni builds
347af0996ceSBarry Smith    # TODO: should exclude petsc/finclude except for fortran builds
3480ee81e68SLisandro Dalcin    self.copies.extend(self.copytree(self.rootIncludeDir, self.destIncludeDir,exclude = ['makefile']))
3490ee81e68SLisandro Dalcin    self.copies.extend(self.copytree(self.archIncludeDir, self.destIncludeDir))
3500ee81e68SLisandro Dalcin    return
3510ee81e68SLisandro Dalcin
3520ee81e68SLisandro Dalcin  def installConf(self):
3530ee81e68SLisandro Dalcin    self.copies.extend(self.copytree(self.rootConfDir, self.destConfDir))
3540ee81e68SLisandro Dalcin    self.copies.extend(self.copytree(self.archConfDir, self.destConfDir, exclude = ['sowing', 'configure.log.bkp']))
3550ee81e68SLisandro Dalcin    return
3560ee81e68SLisandro Dalcin
3570ee81e68SLisandro Dalcin  def installBin(self):
358af0996ceSBarry Smith    self.copies.extend(self.copytree(os.path.join(self.rootBinDir), os.path.join(self.destBinDir)))
3590ee81e68SLisandro Dalcin    # TODO: should copy over petsc-mpiexec.uni only for uni builds
3600ee81e68SLisandro Dalcin    self.copies.extend(self.copyfile(os.path.join(self.rootBinDir,'petsc-mpiexec.uni'), self.destBinDir))
3610ee81e68SLisandro Dalcin    self.copies.extend(self.copytree(self.archBinDir, self.destBinDir, exclude = ['bfort','bib2html','doc2lt','doctext','mapnames', 'pstogif','pstoxbm','tohtml']))
3620ee81e68SLisandro Dalcin    return
3630ee81e68SLisandro Dalcin
3640ee81e68SLisandro Dalcin  def installShare(self):
3650ee81e68SLisandro Dalcin    self.copies.extend(self.copytree(self.rootShareDir, self.destShareDir))
366c173c275SScott Kruger    examplesdir=os.path.join(self.destShareDir,'petsc','examples')
367c173c275SScott Kruger    if os.path.exists(examplesdir):
368c173c275SScott Kruger      shutil.rmtree(examplesdir)
369c173c275SScott Kruger    os.mkdir(examplesdir)
370*79eaf171SScott Kruger    os.mkdir(os.path.join(examplesdir,'src'))
371*79eaf171SScott Kruger    self.copyExamples(self.rootSrcDir,os.path.join(examplesdir,'src'))
372c173c275SScott Kruger    self.copyConfig(self.rootDir,examplesdir)
373c173c275SScott Kruger    self.fixExamplesMakefile(os.path.join(examplesdir,'gmakefile.test'))
3740ee81e68SLisandro Dalcin    return
3750ee81e68SLisandro Dalcin
3760ee81e68SLisandro Dalcin  def copyLib(self, src, dst):
3770ee81e68SLisandro Dalcin    '''Run ranlib on the destination library if it is an archive. Also run install_name_tool on dylib on Mac'''
3780ee81e68SLisandro Dalcin    # Symlinks (assumed local) are recreated at dst
3790ee81e68SLisandro Dalcin    if os.path.islink(src):
3800ee81e68SLisandro Dalcin      linkto = os.readlink(src)
3810ee81e68SLisandro Dalcin      try:
3820ee81e68SLisandro Dalcin        os.remove(dst)            # In case it already exists
3830ee81e68SLisandro Dalcin      except OSError:
3840ee81e68SLisandro Dalcin        pass
3850ee81e68SLisandro Dalcin      os.symlink(linkto, dst)
3860ee81e68SLisandro Dalcin      return
3870ee81e68SLisandro Dalcin    # Do not install object files
3880ee81e68SLisandro Dalcin    if not os.path.splitext(src)[1] == '.o':
3890ee81e68SLisandro Dalcin      shutil.copy2(src, dst)
3900ee81e68SLisandro Dalcin    if os.path.splitext(dst)[1] == '.'+self.arLibSuffix:
3910ee81e68SLisandro Dalcin      self.executeShellCommand(self.ranlib+' '+dst)
3920ee81e68SLisandro Dalcin    if os.path.splitext(dst)[1] == '.dylib' and os.path.isfile('/usr/bin/install_name_tool'):
393af2c601bSBarry Smith      [output,err,flg] = self.executeShellCommand("otool -D "+src)
394af2c601bSBarry Smith      oldname = output[output.find("\n")+1:]
39502e047dfSSatish Balay      installName = oldname.replace(self.archDir, self.installDir)
3960ee81e68SLisandro Dalcin      self.executeShellCommand('/usr/bin/install_name_tool -id ' + installName + ' ' + dst)
3970ee81e68SLisandro Dalcin    # preserve the original timestamps - so that the .a vs .so time order is preserved
3980ee81e68SLisandro Dalcin    shutil.copystat(src,dst)
3990ee81e68SLisandro Dalcin    return
4000ee81e68SLisandro Dalcin
4010ee81e68SLisandro Dalcin  def installLib(self):
402696e41a9SLisandro Dalcin    self.copies.extend(self.copytree(self.archLibDir, self.destLibDir, copyFunc = self.copyLib, exclude = ['.DIR', 'sowing']))
4030ee81e68SLisandro Dalcin    return
4040ee81e68SLisandro Dalcin
4050ee81e68SLisandro Dalcin
4060ee81e68SLisandro Dalcin  def outputInstallDone(self):
4070ee81e68SLisandro Dalcin    print '''\
4080ee81e68SLisandro Dalcin====================================
4090ee81e68SLisandro DalcinInstall complete.
4100ee81e68SLisandro DalcinNow to check if the libraries are working do (in current directory):
4110ee81e68SLisandro Dalcinmake PETSC_DIR=%s PETSC_ARCH="" test
4120ee81e68SLisandro Dalcin====================================\
4130ee81e68SLisandro Dalcin''' % (self.installDir)
4140ee81e68SLisandro Dalcin    return
4150ee81e68SLisandro Dalcin
4160ee81e68SLisandro Dalcin  def outputDestDirDone(self):
4170ee81e68SLisandro Dalcin    print '''\
4180ee81e68SLisandro Dalcin====================================
4190ee81e68SLisandro DalcinCopy to DESTDIR %s is now complete.
4200ee81e68SLisandro DalcinBefore use - please copy/install over to specified prefix: %s
4210ee81e68SLisandro Dalcin====================================\
4220ee81e68SLisandro Dalcin''' % (self.destDir,self.installDir)
4230ee81e68SLisandro Dalcin    return
4240ee81e68SLisandro Dalcin
4250ee81e68SLisandro Dalcin  def runsetup(self):
4260ee81e68SLisandro Dalcin    self.setup()
4270ee81e68SLisandro Dalcin    self.setupDirectories()
4280ee81e68SLisandro Dalcin    self.checkPrefix()
4290ee81e68SLisandro Dalcin    self.checkDestdir()
4300ee81e68SLisandro Dalcin    return
4310ee81e68SLisandro Dalcin
4320ee81e68SLisandro Dalcin  def runcopy(self):
4330ee81e68SLisandro Dalcin    if self.destDir == self.installDir:
4340ee81e68SLisandro Dalcin      print '*** Installing PETSc at prefix location:',self.destDir, ' ***'
4350ee81e68SLisandro Dalcin    else:
4360ee81e68SLisandro Dalcin      print '*** Copying PETSc to DESTDIR location:',self.destDir, ' ***'
4370ee81e68SLisandro Dalcin    if not os.path.exists(self.destDir):
4380ee81e68SLisandro Dalcin      try:
4390ee81e68SLisandro Dalcin        os.makedirs(self.destDir)
4400ee81e68SLisandro Dalcin      except:
4410ee81e68SLisandro Dalcin        print '********************************************************************'
4420ee81e68SLisandro Dalcin        print 'Unable to create', self.destDir, 'Perhaps you need to do "sudo make install"'
4430ee81e68SLisandro Dalcin        print '********************************************************************'
4440ee81e68SLisandro Dalcin        sys.exit(1)
4450ee81e68SLisandro Dalcin    self.installIncludes()
4460ee81e68SLisandro Dalcin    self.installConf()
4470ee81e68SLisandro Dalcin    self.installBin()
4480ee81e68SLisandro Dalcin    self.installLib()
4490ee81e68SLisandro Dalcin    self.installShare()
4500ee81e68SLisandro Dalcin    return
4510ee81e68SLisandro Dalcin
4520ee81e68SLisandro Dalcin  def runfix(self):
4530ee81e68SLisandro Dalcin    self.fixConf()
4540ee81e68SLisandro Dalcin    return
4550ee81e68SLisandro Dalcin
4560ee81e68SLisandro Dalcin  def rundone(self):
4570ee81e68SLisandro Dalcin    self.createUninstaller()
4580ee81e68SLisandro Dalcin    if self.destDir == self.installDir:
4590ee81e68SLisandro Dalcin      self.outputInstallDone()
4600ee81e68SLisandro Dalcin    else:
4610ee81e68SLisandro Dalcin      self.outputDestDirDone()
4620ee81e68SLisandro Dalcin    return
4630ee81e68SLisandro Dalcin
4640ee81e68SLisandro Dalcin  def run(self):
4650ee81e68SLisandro Dalcin    self.runsetup()
4660ee81e68SLisandro Dalcin    self.runcopy()
4670ee81e68SLisandro Dalcin    self.runfix()
4680ee81e68SLisandro Dalcin    self.rundone()
4690ee81e68SLisandro Dalcin    return
4700ee81e68SLisandro Dalcin
4710ee81e68SLisandro Dalcinif __name__ == '__main__':
4720ee81e68SLisandro Dalcin  Installer(sys.argv[1:]).run()
4730ee81e68SLisandro Dalcin  # temporary hack - delete log files created by BuildSystem - when 'sudo make install' is invoked
47403e6d329SSatish Balay  delfiles=['RDict.db','RDict.log','buildsystem.log','default.log','buildsystem.log.bkp','default.log.bkp']
4750ee81e68SLisandro Dalcin  for delfile in delfiles:
4760ee81e68SLisandro Dalcin    if os.path.exists(delfile) and (os.stat(delfile).st_uid==0):
4770ee81e68SLisandro Dalcin      os.remove(delfile)
478