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