xref: /petsc/config/install.py (revision 0ee81e68bb68cd9dc695ec5cb9812a4d87b703a0)
1*0ee81e68SLisandro Dalcin#!/usr/bin/env python
2*0ee81e68SLisandro Dalcinimport os, sys, shutil
3*0ee81e68SLisandro Dalcin
4*0ee81e68SLisandro Dalcinif os.environ.has_key('PETSC_DIR'):
5*0ee81e68SLisandro Dalcin  PETSC_DIR = os.environ['PETSC_DIR']
6*0ee81e68SLisandro Dalcinelse:
7*0ee81e68SLisandro Dalcin  fd = file(os.path.join('lib','petsc-conf','petscvariables'))
8*0ee81e68SLisandro Dalcin  a = fd.readline()
9*0ee81e68SLisandro Dalcin  a = fd.readline()
10*0ee81e68SLisandro Dalcin  PETSC_DIR = a.split('=')[1][0:-1]
11*0ee81e68SLisandro Dalcin  fd.close()
12*0ee81e68SLisandro Dalcin
13*0ee81e68SLisandro Dalcinif os.environ.has_key('PETSC_ARCH'):
14*0ee81e68SLisandro Dalcin  PETSC_ARCH = os.environ['PETSC_ARCH']
15*0ee81e68SLisandro Dalcinelse:
16*0ee81e68SLisandro Dalcin  fd = file(os.path.join('lib','petsc-conf','petscvariables'))
17*0ee81e68SLisandro Dalcin  a = fd.readline()
18*0ee81e68SLisandro Dalcin  PETSC_ARCH = a.split('=')[1][0:-1]
19*0ee81e68SLisandro Dalcin  fd.close()
20*0ee81e68SLisandro Dalcin
21*0ee81e68SLisandro Dalcinprint '*** Using PETSC_DIR='+PETSC_DIR+' PETSC_ARCH='+PETSC_ARCH+' ***'
22*0ee81e68SLisandro Dalcinsys.path.insert(0, os.path.join(PETSC_DIR, 'config'))
23*0ee81e68SLisandro Dalcinsys.path.insert(0, os.path.join(PETSC_DIR, 'config', 'BuildSystem'))
24*0ee81e68SLisandro Dalcin
25*0ee81e68SLisandro Dalcinimport script
26*0ee81e68SLisandro Dalcin
27*0ee81e68SLisandro Dalcintry:
28*0ee81e68SLisandro Dalcin  WindowsError
29*0ee81e68SLisandro Dalcinexcept NameError:
30*0ee81e68SLisandro Dalcin  WindowsError = None
31*0ee81e68SLisandro Dalcin
32*0ee81e68SLisandro Dalcinclass Installer(script.Script):
33*0ee81e68SLisandro Dalcin  def __init__(self, clArgs = None):
34*0ee81e68SLisandro Dalcin    import RDict
35*0ee81e68SLisandro Dalcin    argDB = RDict.RDict(None, None, 0, 0, readonly = True)
36*0ee81e68SLisandro Dalcin    argDB.saveFilename = os.path.join(PETSC_DIR, PETSC_ARCH, 'lib','petsc-conf', 'RDict.db')
37*0ee81e68SLisandro Dalcin    argDB.load()
38*0ee81e68SLisandro Dalcin    script.Script.__init__(self, argDB = argDB)
39*0ee81e68SLisandro Dalcin    if not clArgs is None: self.clArgs = clArgs
40*0ee81e68SLisandro Dalcin    self.copies = []
41*0ee81e68SLisandro Dalcin    return
42*0ee81e68SLisandro Dalcin
43*0ee81e68SLisandro Dalcin  def setupHelp(self, help):
44*0ee81e68SLisandro Dalcin    import nargs
45*0ee81e68SLisandro Dalcin    script.Script.setupHelp(self, help)
46*0ee81e68SLisandro Dalcin    help.addArgument('Installer', '-destDir=<path>', nargs.Arg(None, None, 'Destination Directory for install'))
47*0ee81e68SLisandro Dalcin    return
48*0ee81e68SLisandro Dalcin
49*0ee81e68SLisandro Dalcin
50*0ee81e68SLisandro Dalcin  def setupModules(self):
51*0ee81e68SLisandro Dalcin    self.setCompilers  = self.framework.require('config.setCompilers',         None)
52*0ee81e68SLisandro Dalcin    self.arch          = self.framework.require('PETSc.options.arch',        None)
53*0ee81e68SLisandro Dalcin    self.petscdir      = self.framework.require('PETSc.options.petscdir',    None)
54*0ee81e68SLisandro Dalcin    self.compilers     = self.framework.require('config.compilers',            None)
55*0ee81e68SLisandro Dalcin    return
56*0ee81e68SLisandro Dalcin
57*0ee81e68SLisandro Dalcin  def setup(self):
58*0ee81e68SLisandro Dalcin    script.Script.setup(self)
59*0ee81e68SLisandro Dalcin    self.framework = self.loadConfigure()
60*0ee81e68SLisandro Dalcin    self.setupModules()
61*0ee81e68SLisandro Dalcin    return
62*0ee81e68SLisandro Dalcin
63*0ee81e68SLisandro Dalcin  def setupDirectories(self):
64*0ee81e68SLisandro Dalcin    self.rootDir    = self.petscdir.dir
65*0ee81e68SLisandro Dalcin    self.destDir    = os.path.abspath(self.argDB['destDir'])
66*0ee81e68SLisandro Dalcin    self.installDir = self.framework.argDB['prefix']
67*0ee81e68SLisandro Dalcin    self.arch       = self.arch.arch
68*0ee81e68SLisandro Dalcin    self.rootIncludeDir    = os.path.join(self.rootDir, 'include')
69*0ee81e68SLisandro Dalcin    self.archIncludeDir    = os.path.join(self.rootDir, self.arch, 'include')
70*0ee81e68SLisandro Dalcin    self.rootConfDir       = os.path.join(self.rootDir, 'lib','petsc-conf')
71*0ee81e68SLisandro Dalcin    self.archConfDir       = os.path.join(self.rootDir, self.arch, 'lib','petsc-conf')
72*0ee81e68SLisandro Dalcin    self.rootBinDir        = os.path.join(self.rootDir, 'bin')
73*0ee81e68SLisandro Dalcin    self.archBinDir        = os.path.join(self.rootDir, self.arch, 'bin')
74*0ee81e68SLisandro Dalcin    self.archLibDir        = os.path.join(self.rootDir, self.arch, 'lib')
75*0ee81e68SLisandro Dalcin    self.destIncludeDir    = os.path.join(self.destDir, 'include')
76*0ee81e68SLisandro Dalcin    self.destConfDir       = os.path.join(self.destDir, 'lib','petsc-conf')
77*0ee81e68SLisandro Dalcin    self.destLibDir        = os.path.join(self.destDir, 'lib')
78*0ee81e68SLisandro Dalcin    self.destBinDir        = os.path.join(self.destDir, 'bin')
79*0ee81e68SLisandro Dalcin    self.installIncludeDir = os.path.join(self.installDir, 'include')
80*0ee81e68SLisandro Dalcin    self.installBinDir     = os.path.join(self.installDir, 'bin')
81*0ee81e68SLisandro Dalcin    self.rootShareDir      = os.path.join(self.rootDir, 'share')
82*0ee81e68SLisandro Dalcin    self.destShareDir      = os.path.join(self.destDir, 'share')
83*0ee81e68SLisandro Dalcin
84*0ee81e68SLisandro Dalcin    self.ranlib      = self.compilers.RANLIB
85*0ee81e68SLisandro Dalcin    self.arLibSuffix = self.compilers.AR_LIB_SUFFIX
86*0ee81e68SLisandro Dalcin    return
87*0ee81e68SLisandro Dalcin
88*0ee81e68SLisandro Dalcin  def checkPrefix(self):
89*0ee81e68SLisandro Dalcin    if not self.installDir:
90*0ee81e68SLisandro Dalcin      print '********************************************************************'
91*0ee81e68SLisandro Dalcin      print 'PETSc is built without prefix option. So "make install" is not appropriate.'
92*0ee81e68SLisandro Dalcin      print 'If you need a prefix install of PETSc - rerun configure with --prefix option.'
93*0ee81e68SLisandro Dalcin      print '********************************************************************'
94*0ee81e68SLisandro Dalcin      sys.exit(1)
95*0ee81e68SLisandro Dalcin    return
96*0ee81e68SLisandro Dalcin
97*0ee81e68SLisandro Dalcin  def checkDestdir(self):
98*0ee81e68SLisandro Dalcin    if os.path.exists(self.destDir):
99*0ee81e68SLisandro Dalcin      if os.path.samefile(self.destDir, self.rootDir):
100*0ee81e68SLisandro Dalcin        print '********************************************************************'
101*0ee81e68SLisandro Dalcin        print 'Incorrect prefix usage. Specified destDir same as current PETSC_DIR'
102*0ee81e68SLisandro Dalcin        print '********************************************************************'
103*0ee81e68SLisandro Dalcin        sys.exit(1)
104*0ee81e68SLisandro Dalcin      if os.path.samefile(self.destDir, os.path.join(self.rootDir,self.arch)):
105*0ee81e68SLisandro Dalcin        print '********************************************************************'
106*0ee81e68SLisandro Dalcin        print 'Incorrect prefix usage. Specified destDir same as current PETSC_DIR/PETSC_ARCH'
107*0ee81e68SLisandro Dalcin        print '********************************************************************'
108*0ee81e68SLisandro Dalcin        sys.exit(1)
109*0ee81e68SLisandro Dalcin      if not os.path.isdir(os.path.realpath(self.destDir)):
110*0ee81e68SLisandro Dalcin        print '********************************************************************'
111*0ee81e68SLisandro Dalcin        print 'Specified destDir', self.destDir, 'is not a directory. Cannot proceed!'
112*0ee81e68SLisandro Dalcin        print '********************************************************************'
113*0ee81e68SLisandro Dalcin        sys.exit(1)
114*0ee81e68SLisandro Dalcin      if not os.access(self.destDir, os.W_OK):
115*0ee81e68SLisandro Dalcin        print '********************************************************************'
116*0ee81e68SLisandro Dalcin        print 'Unable to write to ', self.destDir, 'Perhaps you need to do "sudo make install"'
117*0ee81e68SLisandro Dalcin        print '********************************************************************'
118*0ee81e68SLisandro Dalcin        sys.exit(1)
119*0ee81e68SLisandro Dalcin    return
120*0ee81e68SLisandro Dalcin
121*0ee81e68SLisandro Dalcin  def copyfile(self, src, dst, symlinks = False, copyFunc = shutil.copy2):
122*0ee81e68SLisandro Dalcin    """Copies a single file    """
123*0ee81e68SLisandro Dalcin    copies = []
124*0ee81e68SLisandro Dalcin    errors = []
125*0ee81e68SLisandro Dalcin    if not os.path.exists(dst):
126*0ee81e68SLisandro Dalcin      os.makedirs(dst)
127*0ee81e68SLisandro Dalcin    elif not os.path.isdir(dst):
128*0ee81e68SLisandro Dalcin      raise shutil.Error, 'Destination is not a directory'
129*0ee81e68SLisandro Dalcin    srcname = src
130*0ee81e68SLisandro Dalcin    dstname = os.path.join(dst, os.path.basename(src))
131*0ee81e68SLisandro Dalcin    try:
132*0ee81e68SLisandro Dalcin      if symlinks and os.path.islink(srcname):
133*0ee81e68SLisandro Dalcin        linkto = os.readlink(srcname)
134*0ee81e68SLisandro Dalcin        os.symlink(linkto, dstname)
135*0ee81e68SLisandro Dalcin      else:
136*0ee81e68SLisandro Dalcin        copyFunc(srcname, dstname)
137*0ee81e68SLisandro Dalcin        copies.append((srcname, dstname))
138*0ee81e68SLisandro Dalcin    except (IOError, os.error), why:
139*0ee81e68SLisandro Dalcin      errors.append((srcname, dstname, str(why)))
140*0ee81e68SLisandro Dalcin    except shutil.Error, err:
141*0ee81e68SLisandro Dalcin      errors.extend((srcname,dstname,str(err.args[0])))
142*0ee81e68SLisandro Dalcin    if errors:
143*0ee81e68SLisandro Dalcin      raise shutil.Error, errors
144*0ee81e68SLisandro Dalcin    return copies
145*0ee81e68SLisandro Dalcin
146*0ee81e68SLisandro Dalcin
147*0ee81e68SLisandro Dalcin  def copytree(self, src, dst, symlinks = False, copyFunc = shutil.copy2, exclude = []):
148*0ee81e68SLisandro Dalcin    """Recursively copy a directory tree using copyFunc, which defaults to shutil.copy2().
149*0ee81e68SLisandro Dalcin
150*0ee81e68SLisandro Dalcin       The copyFunc() you provide is only used on the top level, lower levels always use shutil.copy2
151*0ee81e68SLisandro Dalcin
152*0ee81e68SLisandro Dalcin    The destination directory must not already exist.
153*0ee81e68SLisandro Dalcin    If exception(s) occur, an shutil.Error is raised with a list of reasons.
154*0ee81e68SLisandro Dalcin
155*0ee81e68SLisandro Dalcin    If the optional symlinks flag is true, symbolic links in the
156*0ee81e68SLisandro Dalcin    source tree result in symbolic links in the destination tree; if
157*0ee81e68SLisandro Dalcin    it is false, the contents of the files pointed to by symbolic
158*0ee81e68SLisandro Dalcin    links are copied.
159*0ee81e68SLisandro Dalcin    """
160*0ee81e68SLisandro Dalcin    copies = []
161*0ee81e68SLisandro Dalcin    names  = os.listdir(src)
162*0ee81e68SLisandro Dalcin    if not os.path.exists(dst):
163*0ee81e68SLisandro Dalcin      os.makedirs(dst)
164*0ee81e68SLisandro Dalcin    elif not os.path.isdir(dst):
165*0ee81e68SLisandro Dalcin      raise shutil.Error, 'Destination is not a directory'
166*0ee81e68SLisandro Dalcin    errors = []
167*0ee81e68SLisandro Dalcin    for name in names:
168*0ee81e68SLisandro Dalcin      srcname = os.path.join(src, name)
169*0ee81e68SLisandro Dalcin      dstname = os.path.join(dst, name)
170*0ee81e68SLisandro Dalcin      try:
171*0ee81e68SLisandro Dalcin        if symlinks and os.path.islink(srcname):
172*0ee81e68SLisandro Dalcin          linkto = os.readlink(srcname)
173*0ee81e68SLisandro Dalcin          os.symlink(linkto, dstname)
174*0ee81e68SLisandro Dalcin        elif os.path.isdir(srcname):
175*0ee81e68SLisandro Dalcin          copies.extend(self.copytree(srcname, dstname, symlinks,exclude = exclude))
176*0ee81e68SLisandro Dalcin        elif not os.path.basename(srcname) in exclude:
177*0ee81e68SLisandro Dalcin          copyFunc(srcname, dstname)
178*0ee81e68SLisandro Dalcin          copies.append((srcname, dstname))
179*0ee81e68SLisandro Dalcin        # XXX What about devices, sockets etc.?
180*0ee81e68SLisandro Dalcin      except (IOError, os.error), why:
181*0ee81e68SLisandro Dalcin        errors.append((srcname, dstname, str(why)))
182*0ee81e68SLisandro Dalcin      # catch the Error from the recursive copytree so that we can
183*0ee81e68SLisandro Dalcin      # continue with other files
184*0ee81e68SLisandro Dalcin      except shutil.Error, err:
185*0ee81e68SLisandro Dalcin        errors.extend((srcname,dstname,str(err.args[0])))
186*0ee81e68SLisandro Dalcin    try:
187*0ee81e68SLisandro Dalcin      shutil.copystat(src, dst)
188*0ee81e68SLisandro Dalcin    except OSError, e:
189*0ee81e68SLisandro Dalcin      if WindowsError is not None and isinstance(e, WindowsError):
190*0ee81e68SLisandro Dalcin        # Copying file access times may fail on Windows
191*0ee81e68SLisandro Dalcin        pass
192*0ee81e68SLisandro Dalcin      else:
193*0ee81e68SLisandro Dalcin        errors.extend((src, dst, str(e)))
194*0ee81e68SLisandro Dalcin    if errors:
195*0ee81e68SLisandro Dalcin      raise shutil.Error, errors
196*0ee81e68SLisandro Dalcin    return copies
197*0ee81e68SLisandro Dalcin
198*0ee81e68SLisandro Dalcin
199*0ee81e68SLisandro Dalcin  def fixConfFile(self, src):
200*0ee81e68SLisandro Dalcin    lines   = []
201*0ee81e68SLisandro Dalcin    oldFile = open(src, 'r')
202*0ee81e68SLisandro Dalcin    for line in oldFile.readlines():
203*0ee81e68SLisandro Dalcin      # paths generated by configure could be different link-path than whats used by user, so fix both
204*0ee81e68SLisandro Dalcin      line = line.replace(os.path.join(self.rootDir, self.arch), self.installDir)
205*0ee81e68SLisandro Dalcin      line = line.replace(os.path.realpath(os.path.join(self.rootDir, self.arch)), self.installDir)
206*0ee81e68SLisandro Dalcin      line = line.replace(os.path.join(self.rootDir, 'bin'), self.installBinDir)
207*0ee81e68SLisandro Dalcin      line = line.replace(os.path.realpath(os.path.join(self.rootDir, 'bin')), self.installBinDir)
208*0ee81e68SLisandro Dalcin      line = line.replace(os.path.join(self.rootDir, 'include'), self.installIncludeDir)
209*0ee81e68SLisandro Dalcin      line = line.replace(os.path.realpath(os.path.join(self.rootDir, 'include')), self.installIncludeDir)
210*0ee81e68SLisandro Dalcin      # remove PETSC_DIR/PETSC_ARCH variables from conf-makefiles. They are no longer necessary
211*0ee81e68SLisandro Dalcin      line = line.replace('${PETSC_DIR}/${PETSC_ARCH}', self.installDir)
212*0ee81e68SLisandro Dalcin      line = line.replace('PETSC_ARCH=${PETSC_ARCH}', '')
213*0ee81e68SLisandro Dalcin      line = line.replace('${PETSC_DIR}', self.installDir)
214*0ee81e68SLisandro Dalcin      lines.append(line)
215*0ee81e68SLisandro Dalcin    oldFile.close()
216*0ee81e68SLisandro Dalcin    newFile = open(src, 'w')
217*0ee81e68SLisandro Dalcin    newFile.write(''.join(lines))
218*0ee81e68SLisandro Dalcin    newFile.close()
219*0ee81e68SLisandro Dalcin    return
220*0ee81e68SLisandro Dalcin
221*0ee81e68SLisandro Dalcin  def fixConf(self):
222*0ee81e68SLisandro Dalcin    import shutil
223*0ee81e68SLisandro Dalcin    for file in ['rules', 'variables','petscrules', 'petscvariables']:
224*0ee81e68SLisandro Dalcin      self.fixConfFile(os.path.join(self.destConfDir,file))
225*0ee81e68SLisandro Dalcin    self.fixConfFile(os.path.join(self.destLibDir,'pkgconfig','PETSc.pc'))
226*0ee81e68SLisandro Dalcin    return
227*0ee81e68SLisandro Dalcin
228*0ee81e68SLisandro Dalcin  def createUninstaller(self):
229*0ee81e68SLisandro Dalcin    uninstallscript = os.path.join(self.destConfDir, 'uninstall.py')
230*0ee81e68SLisandro Dalcin    f = open(uninstallscript, 'w')
231*0ee81e68SLisandro Dalcin    # Could use the Python AST to do this
232*0ee81e68SLisandro Dalcin    f.write('#!'+sys.executable+'\n')
233*0ee81e68SLisandro Dalcin    f.write('import os\n')
234*0ee81e68SLisandro Dalcin
235*0ee81e68SLisandro Dalcin    f.write('copies = '+repr(self.copies).replace(self.destDir,self.installDir))
236*0ee81e68SLisandro Dalcin    f.write('''
237*0ee81e68SLisandro Dalcinfor src, dst in copies:
238*0ee81e68SLisandro Dalcin  try:
239*0ee81e68SLisandro Dalcin    os.remove(dst)
240*0ee81e68SLisandro Dalcin  except:
241*0ee81e68SLisandro Dalcin    pass
242*0ee81e68SLisandro Dalcin''')
243*0ee81e68SLisandro Dalcin    #TODO: need to delete libXXX.YYY.dylib.dSYM directory on Mac
244*0ee81e68SLisandro Dalcin    dirs = [os.path.join('include','petsc-finclude'),os.path.join('include','petsc-mpiuni'),os.path.join('include','petsc-private'),os.path.join('bin','petsc-pythonscripts'),os.path.join('lib','petsc-conf')]
245*0ee81e68SLisandro Dalcin    newdirs = []
246*0ee81e68SLisandro Dalcin    for dir in dirs: newdirs.append(os.path.join(self.installDir,dir))
247*0ee81e68SLisandro Dalcin    f.write('dirs = '+str(newdirs))
248*0ee81e68SLisandro Dalcin    f.write('''
249*0ee81e68SLisandro Dalcinfor dir in dirs:
250*0ee81e68SLisandro Dalcin  import shutil
251*0ee81e68SLisandro Dalcin  try:
252*0ee81e68SLisandro Dalcin    shutil.rmtree(dir)
253*0ee81e68SLisandro Dalcin  except:
254*0ee81e68SLisandro Dalcin    pass
255*0ee81e68SLisandro Dalcin''')
256*0ee81e68SLisandro Dalcin    f.close()
257*0ee81e68SLisandro Dalcin    os.chmod(uninstallscript,0744)
258*0ee81e68SLisandro Dalcin    return
259*0ee81e68SLisandro Dalcin
260*0ee81e68SLisandro Dalcin  def installIncludes(self):
261*0ee81e68SLisandro Dalcin    # TODO: should exclude petsc-mpi.uni except for uni builds
262*0ee81e68SLisandro Dalcin    # TODO: should exclude petsc-finclude except for fortran builds
263*0ee81e68SLisandro Dalcin    self.copies.extend(self.copytree(self.rootIncludeDir, self.destIncludeDir,exclude = ['makefile']))
264*0ee81e68SLisandro Dalcin    self.copies.extend(self.copytree(self.archIncludeDir, self.destIncludeDir))
265*0ee81e68SLisandro Dalcin    return
266*0ee81e68SLisandro Dalcin
267*0ee81e68SLisandro Dalcin  def installConf(self):
268*0ee81e68SLisandro Dalcin    self.copies.extend(self.copytree(self.rootConfDir, self.destConfDir))
269*0ee81e68SLisandro Dalcin    self.copies.extend(self.copytree(self.archConfDir, self.destConfDir, exclude = ['sowing', 'configure.log.bkp']))
270*0ee81e68SLisandro Dalcin    return
271*0ee81e68SLisandro Dalcin
272*0ee81e68SLisandro Dalcin  def installBin(self):
273*0ee81e68SLisandro Dalcin    self.copies.extend(self.copytree(os.path.join(self.rootBinDir,'petsc-pythonscripts'), os.path.join(self.destBinDir,'petsc-pythonscripts')))
274*0ee81e68SLisandro Dalcin    # TODO: should copy over petsc-mpiexec.uni only for uni builds
275*0ee81e68SLisandro Dalcin    self.copies.extend(self.copyfile(os.path.join(self.rootBinDir,'petsc-mpiexec.uni'), self.destBinDir))
276*0ee81e68SLisandro Dalcin    self.copies.extend(self.copytree(self.archBinDir, self.destBinDir, exclude = ['bfort','bib2html','doc2lt','doctext','mapnames', 'pstogif','pstoxbm','tohtml']))
277*0ee81e68SLisandro Dalcin    return
278*0ee81e68SLisandro Dalcin
279*0ee81e68SLisandro Dalcin  def installShare(self):
280*0ee81e68SLisandro Dalcin    self.copies.extend(self.copytree(self.rootShareDir, self.destShareDir))
281*0ee81e68SLisandro Dalcin    return
282*0ee81e68SLisandro Dalcin
283*0ee81e68SLisandro Dalcin  def copyLib(self, src, dst):
284*0ee81e68SLisandro Dalcin    '''Run ranlib on the destination library if it is an archive. Also run install_name_tool on dylib on Mac'''
285*0ee81e68SLisandro Dalcin    # Symlinks (assumed local) are recreated at dst
286*0ee81e68SLisandro Dalcin    if os.path.islink(src):
287*0ee81e68SLisandro Dalcin      linkto = os.readlink(src)
288*0ee81e68SLisandro Dalcin      try:
289*0ee81e68SLisandro Dalcin        os.remove(dst)            # In case it already exists
290*0ee81e68SLisandro Dalcin      except OSError:
291*0ee81e68SLisandro Dalcin        pass
292*0ee81e68SLisandro Dalcin      os.symlink(linkto, dst)
293*0ee81e68SLisandro Dalcin      return
294*0ee81e68SLisandro Dalcin    # Do not install object files
295*0ee81e68SLisandro Dalcin    if not os.path.splitext(src)[1] == '.o':
296*0ee81e68SLisandro Dalcin      shutil.copy2(src, dst)
297*0ee81e68SLisandro Dalcin    if os.path.splitext(dst)[1] == '.'+self.arLibSuffix:
298*0ee81e68SLisandro Dalcin      self.executeShellCommand(self.ranlib+' '+dst)
299*0ee81e68SLisandro Dalcin    if os.path.splitext(dst)[1] == '.dylib' and os.path.isfile('/usr/bin/install_name_tool'):
300*0ee81e68SLisandro Dalcin      installName = dst.replace(self.destDir, self.installDir)
301*0ee81e68SLisandro Dalcin      self.executeShellCommand('/usr/bin/install_name_tool -id ' + installName + ' ' + dst)
302*0ee81e68SLisandro Dalcin    # preserve the original timestamps - so that the .a vs .so time order is preserved
303*0ee81e68SLisandro Dalcin    shutil.copystat(src,dst)
304*0ee81e68SLisandro Dalcin    return
305*0ee81e68SLisandro Dalcin
306*0ee81e68SLisandro Dalcin  def installLib(self):
307*0ee81e68SLisandro Dalcin    self.copies.extend(self.copytree(self.archLibDir, self.destLibDir, copyFunc = self.copyLib, exclude = ['sowing']))
308*0ee81e68SLisandro Dalcin    return
309*0ee81e68SLisandro Dalcin
310*0ee81e68SLisandro Dalcin
311*0ee81e68SLisandro Dalcin  def outputInstallDone(self):
312*0ee81e68SLisandro Dalcin    print '''\
313*0ee81e68SLisandro Dalcin====================================
314*0ee81e68SLisandro DalcinInstall complete.
315*0ee81e68SLisandro DalcinNow to check if the libraries are working do (in current directory):
316*0ee81e68SLisandro Dalcinmake PETSC_DIR=%s PETSC_ARCH="" test
317*0ee81e68SLisandro Dalcin====================================\
318*0ee81e68SLisandro Dalcin''' % (self.installDir)
319*0ee81e68SLisandro Dalcin    return
320*0ee81e68SLisandro Dalcin
321*0ee81e68SLisandro Dalcin  def outputDestDirDone(self):
322*0ee81e68SLisandro Dalcin    print '''\
323*0ee81e68SLisandro Dalcin====================================
324*0ee81e68SLisandro DalcinCopy to DESTDIR %s is now complete.
325*0ee81e68SLisandro DalcinBefore use - please copy/install over to specified prefix: %s
326*0ee81e68SLisandro Dalcin====================================\
327*0ee81e68SLisandro Dalcin''' % (self.destDir,self.installDir)
328*0ee81e68SLisandro Dalcin    return
329*0ee81e68SLisandro Dalcin
330*0ee81e68SLisandro Dalcin  def runsetup(self):
331*0ee81e68SLisandro Dalcin    self.setup()
332*0ee81e68SLisandro Dalcin    self.setupDirectories()
333*0ee81e68SLisandro Dalcin    self.checkPrefix()
334*0ee81e68SLisandro Dalcin    self.checkDestdir()
335*0ee81e68SLisandro Dalcin    return
336*0ee81e68SLisandro Dalcin
337*0ee81e68SLisandro Dalcin  def runcopy(self):
338*0ee81e68SLisandro Dalcin    if self.destDir == self.installDir:
339*0ee81e68SLisandro Dalcin      print '*** Installing PETSc at prefix location:',self.destDir, ' ***'
340*0ee81e68SLisandro Dalcin    else:
341*0ee81e68SLisandro Dalcin      print '*** Copying PETSc to DESTDIR location:',self.destDir, ' ***'
342*0ee81e68SLisandro Dalcin    if not os.path.exists(self.destDir):
343*0ee81e68SLisandro Dalcin      try:
344*0ee81e68SLisandro Dalcin        os.makedirs(self.destDir)
345*0ee81e68SLisandro Dalcin      except:
346*0ee81e68SLisandro Dalcin        print '********************************************************************'
347*0ee81e68SLisandro Dalcin        print 'Unable to create', self.destDir, 'Perhaps you need to do "sudo make install"'
348*0ee81e68SLisandro Dalcin        print '********************************************************************'
349*0ee81e68SLisandro Dalcin        sys.exit(1)
350*0ee81e68SLisandro Dalcin    self.installIncludes()
351*0ee81e68SLisandro Dalcin    self.installConf()
352*0ee81e68SLisandro Dalcin    self.installBin()
353*0ee81e68SLisandro Dalcin    self.installLib()
354*0ee81e68SLisandro Dalcin    self.installShare()
355*0ee81e68SLisandro Dalcin    return
356*0ee81e68SLisandro Dalcin
357*0ee81e68SLisandro Dalcin  def runfix(self):
358*0ee81e68SLisandro Dalcin    self.fixConf()
359*0ee81e68SLisandro Dalcin    return
360*0ee81e68SLisandro Dalcin
361*0ee81e68SLisandro Dalcin  def rundone(self):
362*0ee81e68SLisandro Dalcin    self.createUninstaller()
363*0ee81e68SLisandro Dalcin    if self.destDir == self.installDir:
364*0ee81e68SLisandro Dalcin      self.outputInstallDone()
365*0ee81e68SLisandro Dalcin    else:
366*0ee81e68SLisandro Dalcin      self.outputDestDirDone()
367*0ee81e68SLisandro Dalcin    return
368*0ee81e68SLisandro Dalcin
369*0ee81e68SLisandro Dalcin  def run(self):
370*0ee81e68SLisandro Dalcin    self.runsetup()
371*0ee81e68SLisandro Dalcin    self.runcopy()
372*0ee81e68SLisandro Dalcin    self.runfix()
373*0ee81e68SLisandro Dalcin    self.rundone()
374*0ee81e68SLisandro Dalcin    return
375*0ee81e68SLisandro Dalcin
376*0ee81e68SLisandro Dalcinif __name__ == '__main__':
377*0ee81e68SLisandro Dalcin  Installer(sys.argv[1:]).run()
378*0ee81e68SLisandro Dalcin  # temporary hack - delete log files created by BuildSystem - when 'sudo make install' is invoked
379*0ee81e68SLisandro Dalcin  delfiles=['RDict.db','RDict.log','build.log','default.log','build.log.bkp','default.log.bkp']
380*0ee81e68SLisandro Dalcin  for delfile in delfiles:
381*0ee81e68SLisandro Dalcin    if os.path.exists(delfile) and (os.stat(delfile).st_uid==0):
382*0ee81e68SLisandro Dalcin      os.remove(delfile)
383