1#!/usr/bin/env python3 2from __future__ import print_function 3import os, re, shutil, sys 4import sysconfig 5 6if 'PETSC_DIR' in os.environ: 7 PETSC_DIR = os.environ['PETSC_DIR'] 8else: 9 fd = open(os.path.join('lib','petsc','conf','petscvariables')) 10 a = fd.readline() 11 a = fd.readline() 12 PETSC_DIR = a.split('=')[1][0:-1] 13 fd.close() 14 15if 'PETSC_ARCH' in os.environ: 16 PETSC_ARCH = os.environ['PETSC_ARCH'] 17else: 18 fd = open(os.path.join('lib','petsc','conf','petscvariables')) 19 a = fd.readline() 20 PETSC_ARCH = a.split('=')[1][0:-1] 21 fd.close() 22 23print('*** Using PETSC_DIR='+PETSC_DIR+' PETSC_ARCH='+PETSC_ARCH+' ***') 24sys.path.insert(0, os.path.join(PETSC_DIR, 'config')) 25sys.path.insert(0, os.path.join(PETSC_DIR, 'config', 'BuildSystem')) 26 27import script 28 29try: 30 WindowsError 31except NameError: 32 WindowsError = None 33 34class Installer(script.Script): 35 def __init__(self, clArgs = None): 36 import RDict 37 argDB = RDict.RDict(None, None, 0, 0, readonly = True) 38 argDB.saveFilename = os.path.join(PETSC_DIR, PETSC_ARCH, 'lib','petsc','conf', 'RDict.db') 39 argDB.load() 40 script.Script.__init__(self, argDB = argDB) 41 if not clArgs is None: self.clArgs = clArgs 42 self.copies = [] 43 return 44 45 def setupHelp(self, help): 46 import nargs 47 script.Script.setupHelp(self, help) 48 help.addArgument('Installer', '-destDir=<path>', nargs.Arg(None, '', 'Destination Directory for install')) 49 help.addArgument('Installer', '-no-examples', nargs.Arg(None, '', 'Skip installing examples')) 50 return 51 52 53 def setupModules(self): 54 self.setCompilers = self.framework.require('config.setCompilers', None) 55 self.arch = self.framework.require('PETSc.options.arch', None) 56 self.petscdir = self.framework.require('PETSc.options.petscdir', None) 57 self.compilers = self.framework.require('config.compilers', None) 58 self.mpi = self.framework.require('config.packages.MPI', None) 59 return 60 61 def setup(self): 62 script.Script.setup(self) 63 self.framework = self.loadConfigure() 64 self.setupModules() 65 return 66 67 def setupDirectories(self): 68 self.rootDir = self.petscdir.dir 69 self.installDir = os.path.abspath(os.path.expanduser(self.framework.argDB['prefix'])) 70 self.destDir = os.path.abspath(self.argDB['destDir']+self.installDir) 71 self.arch = self.arch.arch 72 self.archDir = os.path.join(self.rootDir, self.arch) 73 self.rootIncludeDir = os.path.join(self.rootDir, 'include') 74 self.archIncludeDir = os.path.join(self.rootDir, self.arch, 'include') 75 self.rootConfDir = os.path.join(self.rootDir, 'lib','petsc','conf') 76 self.archConfDir = os.path.join(self.rootDir, self.arch, 'lib','petsc','conf') 77 self.rootBinDir = os.path.join(self.rootDir, 'lib','petsc','bin') 78 self.archBinDir = os.path.join(self.rootDir, self.arch, 'bin') 79 self.archLibDir = os.path.join(self.rootDir, self.arch, 'lib') 80 self.destIncludeDir = os.path.join(self.destDir, 'include') 81 self.destConfDir = os.path.join(self.destDir, 'lib','petsc','conf') 82 self.destLibDir = os.path.join(self.destDir, 'lib') 83 self.destBinDir = os.path.join(self.destDir, 'lib','petsc','bin') 84 self.installIncludeDir = os.path.join(self.installDir, 'include') 85 self.installLibDir = os.path.join(self.installDir, 'lib') 86 self.installBinDir = os.path.join(self.installDir, 'lib','petsc','bin') 87 self.rootShareDir = os.path.join(self.rootDir, 'share') 88 self.destShareDir = os.path.join(self.destDir, 'share') 89 self.rootSrcDir = os.path.join(self.rootDir, 'src') 90 91 self.ranlib = self.compilers.RANLIB 92 self.arLibSuffix = self.compilers.AR_LIB_SUFFIX 93 return 94 95 def checkPrefix(self): 96 if not self.installDir: 97 print('********************************************************************') 98 print('PETSc is built without prefix option. So "make install" is not appropriate.') 99 print('If you need a prefix install of PETSc - rerun configure with --prefix option.') 100 print('********************************************************************') 101 sys.exit(1) 102 return 103 104 def checkDestdir(self): 105 if os.path.exists(self.destDir): 106 if os.path.samefile(self.destDir, self.rootDir): 107 print('********************************************************************') 108 print('Incorrect prefix usage. Specified destDir same as current PETSC_DIR') 109 print('********************************************************************') 110 sys.exit(1) 111 if os.path.samefile(self.destDir, os.path.join(self.rootDir,self.arch)): 112 print('********************************************************************') 113 print('Incorrect prefix usage. Specified destDir same as current PETSC_DIR/PETSC_ARCH') 114 print('********************************************************************') 115 sys.exit(1) 116 if not os.path.isdir(os.path.realpath(self.destDir)): 117 print('********************************************************************') 118 print('Specified destDir', self.destDir, 'is not a directory. Cannot proceed!') 119 print('********************************************************************') 120 sys.exit(1) 121 if not os.access(self.destDir, os.W_OK): 122 print('********************************************************************') 123 print('Unable to write to ', self.destDir, 'Perhaps you need to do "sudo make install"') 124 print('********************************************************************') 125 sys.exit(1) 126 return 127 128 def setupBuild(self): 129 self.using_build_backend = any( 130 os.environ.get(prefix + '_BUILD_BACKEND') 131 for prefix in ('_PYPROJECT_HOOKS', 'PEP517') 132 ) 133 self.relocate_py_env = os.environ.get('CIBUILDWHEEL', '0') == '1' 134 135 def copyfile(self, src, dst, symlinks = False, copyFunc = shutil.copy2): 136 """Copies a single file """ 137 copies = [] 138 errors = [] 139 if not os.path.exists(dst): 140 os.makedirs(dst) 141 elif not os.path.isdir(dst): 142 raise shutil.Error('Destination is not a directory') 143 srcname = src 144 dstname = os.path.join(dst, os.path.basename(src)) 145 try: 146 if symlinks and os.path.islink(srcname): 147 linkto = os.readlink(srcname) 148 os.symlink(linkto, dstname) 149 else: 150 copyFunc(srcname, dstname) 151 copies.append((srcname, dstname)) 152 except (IOError, os.error) as why: 153 errors.append((srcname, dstname, str(why))) 154 except shutil.Error as err: 155 errors.append((srcname,dstname,str(err.args[0]))) 156 if errors: 157 raise shutil.Error(errors) 158 return copies 159 160 def fixExamplesMakefile(self, src): 161 '''Change ././${PETSC_ARCH} in makefile in root PETSc directory with ${PETSC_DIR}''' 162 lines = [] 163 oldFile = open(src, 'r') 164 alllines=oldFile.read() 165 oldFile.close() 166 newlines=alllines.split('\n')[0]+'\n' # Firstline 167 # Hardcode PETSC_DIR and PETSC_ARCH to avoid users doing the wrong thing 168 newlines+='PETSC_DIR='+self.installDir+'\n' 169 newlines+='PETSC_ARCH=\n' 170 for line in alllines.split('\n')[1:]: 171 if line.startswith('TESTLOGFILE'): 172 newlines+='TESTLOGFILE = $(TESTDIR)/examples-install.log\n' 173 elif line.startswith('CONFIGDIR'): 174 newlines+='CONFIGDIR:=$(PETSC_DIR)/$(PETSC_ARCH)/share/petsc/examples/config\n' 175 elif line.startswith('$(generatedtest)') and 'petscvariables' in line: 176 newlines+='all: test\n\n'+line+'\n' 177 else: 178 newlines+=line+'\n' 179 newFile = open(src, 'w') 180 newFile.write(newlines) 181 newFile.close() 182 return 183 184 def copyConfig(self, src, dst): 185 """Copy configuration/testing files 186 """ 187 if not os.path.isdir(dst): 188 raise shutil.Error('Destination is not a directory') 189 190 self.copies.extend(self.copyfile('gmakefile.test',dst)) 191 newConfigDir=os.path.join(dst,'config') # Am not renaming at present 192 if not os.path.isdir(newConfigDir): os.mkdir(newConfigDir) 193 testConfFiles="gmakegentest.py gmakegen.py testparse.py example_template.py".split() 194 testConfFiles+="petsc_harness.sh report_tests.py query_tests.py".split() 195 for tf in testConfFiles: 196 self.copies.extend(self.copyfile(os.path.join('config',tf),newConfigDir)) 197 return 198 199 def copyExamples(self, src, dst): 200 """copy the examples directories 201 """ 202 for root, dirs, files in os.walk(src, topdown=False): 203 if os.path.basename(root) not in ("tests", "tutorials"): continue 204 self.copies.extend(self.copytree(root, root.replace(src,dst))) 205 return 206 207 def copytree(self, src, dst, symlinks = False, copyFunc = shutil.copy2, exclude = [], exclude_ext= ['.DSYM','.o','.pyc'], recurse = 1): 208 """Recursively copy a directory tree using copyFunc, which defaults to shutil.copy2(). 209 210 The copyFunc() you provide is only used on the top level, lower levels always use shutil.copy2 211 212 The destination directory must not already exist. 213 If exception(s) occur, an shutil.Error is raised with a list of reasons. 214 215 If the optional symlinks flag is true, symbolic links in the 216 source tree result in symbolic links in the destination tree; if 217 it is false, the contents of the files pointed to by symbolic 218 links are copied. 219 """ 220 copies = [] 221 names = os.listdir(src) 222 if not os.path.exists(dst): 223 os.makedirs(dst) 224 elif not os.path.isdir(dst): 225 raise shutil.Error('Destination is not a directory') 226 errors = [] 227 srclinks = [] 228 dstlinks = [] 229 for name in names: 230 srcname = os.path.join(src, name) 231 dstname = os.path.join(dst, name) 232 try: 233 if symlinks and os.path.islink(srcname): 234 linkto = os.readlink(srcname) 235 os.symlink(linkto, dstname) 236 elif os.path.isdir(srcname) and recurse and not os.path.basename(srcname) in exclude: 237 copies.extend(self.copytree(srcname, dstname, symlinks,exclude = exclude, exclude_ext = exclude_ext)) 238 elif os.path.isfile(srcname) and not os.path.basename(srcname) in exclude and os.path.splitext(name)[1] not in exclude_ext : 239 if os.path.islink(srcname): 240 srclinks.append(srcname) 241 dstlinks.append(dstname) 242 else: 243 copyFunc(srcname, dstname) 244 copies.append((srcname, dstname)) 245 # XXX What about devices, sockets etc.? 246 except (IOError, os.error) as why: 247 errors.append((srcname, dstname, str(why))) 248 # catch the Error from the recursive copytree so that we can 249 # continue with other files 250 except shutil.Error as err: 251 errors.append((srcname,dstname,str(err.args[0]))) 252 for srcname, dstname in zip(srclinks, dstlinks): 253 try: 254 copyFunc(srcname, dstname) 255 copies.append((srcname, dstname)) 256 except (IOError, os.error) as why: 257 errors.append((srcname, dstname, str(why))) 258 # catch the Error from the recursive copytree so that we can 259 # continue with other files 260 except shutil.Error as err: 261 errors.append((srcname,dstname,str(err.args[0]))) 262 try: 263 shutil.copystat(src, dst) 264 except OSError as e: 265 if WindowsError is not None and isinstance(e, WindowsError): 266 # Copying file access times may fail on Windows 267 pass 268 else: 269 errors.append((src, dst, str(e))) 270 if errors: 271 raise shutil.Error(errors) 272 return copies 273 274 275 def fixConfFile(self, src): 276 lines = [] 277 oldFile = open(src, 'r') 278 for line in oldFile.readlines(): 279 if line.startswith('PETSC_CC_INCLUDES =') or line.startswith('PETSC_FC_INCLUDES ='): 280 continue 281 line = line.replace('PETSC_CC_INCLUDES_INSTALL', 'PETSC_CC_INCLUDES') 282 line = line.replace('PETSC_FC_INCLUDES_INSTALL', 'PETSC_FC_INCLUDES') 283 # remove PETSC_DIR/PETSC_ARCH variables from conf-makefiles. They are no longer necessary 284 line = line.replace('${PETSC_DIR}/${PETSC_ARCH}', self.installDir) 285 line = line.replace('PETSC_ARCH=${PETSC_ARCH}', '') 286 line = line.replace('${PETSC_DIR}', self.installDir) 287 # replace PETSC_DIR/PETSC_ARCH/lib (i.e., build location) with prefix/lib 288 line = line.replace(self.archLibDir,self.installLibDir) 289 # replace PETSC_DIR/lib/petsc/bin with prefix/lib/petsc/bin 290 line = line.replace(self.rootBinDir,self.destBinDir) 291 lines.append(line) 292 oldFile.close() 293 newFile = open(src, 'w') 294 newFile.write(''.join(lines)) 295 newFile.close() 296 return 297 298 def fixConf(self): 299 import shutil 300 for file in ['rules', 'rules_doc.mk', 'rules_util.mk', 'variables', 'petscrules', 'petscvariables']: 301 self.fixConfFile(os.path.join(self.destConfDir,file)) 302 return 303 304 def fixPythonWheel(self): 305 import glob 306 import shutil 307 # 308 for pattern in ( 309 self.destLibDir + '/*.a', 310 self.destLibDir + '/*.la', 311 self.destLibDir + '/pkgconfig', # TODO: keep? 312 self.destConfDir + '/configure-hash', 313 self.destConfDir + '/uninstall.py', 314 self.destConfDir + '/reconfigure-*.py', 315 self.destConfDir + '/pkg.conf.*', 316 self.destConfDir + '/pkg.git*.*', 317 self.destConfDir + '/modules', # TODO: keep? 318 self.destShareDir + '/*/examples/src/*', 319 self.destShareDir + '/*/datafiles', 320 ): 321 for pathname in glob.glob(pattern): 322 if os.path.isdir(pathname): 323 shutil.rmtree(pathname) 324 elif os.path.exists(pathname): 325 os.remove(pathname) 326 # 327 if self.relocate_py_env: 328 pydir = sys.prefix 329 pylibdir = os.path.join(pydir, 'lib') 330 pysitedir = sysconfig.get_paths()["platlib"] 331 # petsc is installed in site-packages 332 petscdir = os.path.join(pysitedir, 'petsc') 333 petsclibdir = os.path.join(petscdir, 'lib') 334 for filename in ( 335 self.destIncludeDir + '/petscconf.h', 336 self.destIncludeDir + '/petscconfiginfo.h', 337 self.destIncludeDir + '/petscmachineinfo.h', 338 self.destShareDir + '/petsc/examples/gmakefile.test', 339 self.destConfDir + '/rules', 340 self.destConfDir + '/rules_doc.mk', 341 self.destConfDir + '/rules_util.mk', 342 self.destConfDir + '/petscrules', 343 self.destConfDir + '/variables', 344 self.destConfDir + '/petscvariables', 345 ): 346 with open(filename, 'r') as oldFile: 347 contents = oldFile.read() 348 contents = contents.replace(self.installDir, '${PETSC_DIR}') 349 contents = contents.replace(self.rootDir, '${PETSC_DIR}') 350 if self.relocate_py_env: 351 pydir_from_petsc = os.path.relpath(pydir, petscdir) 352 contents = contents.replace(pydir, os.path.join('${PETSC_DIR}', pydir_from_petsc)) 353 contents = re.sub( 354 r'^(PYTHON(_EXE)?) = (.*)$', 355 r'\1 = python%d' % sys.version_info[0], 356 contents, flags=re.MULTILINE, 357 ) 358 with open(filename, 'w') as newFile: 359 newFile.write(contents) 360 # 361 def lsdir(dirname, *patterns): 362 return glob.glob(os.path.join(dirname, *patterns)) 363 def shell(*args): 364 return self.executeShellCommand(' '.join(args))[0] 365 libdir = os.path.join(self.installDir, 'lib') 366 if sys.platform == 'linux': 367 libraries = [ 368 lib for lib in lsdir(self.destLibDir, 'lib*.so*') 369 if not os.path.islink(lib) 370 ] 371 for shlib in libraries: 372 # fix shared library rpath 373 rpath = shell('patchelf', '--print-rpath', shlib) 374 rpath = rpath.split(os.path.pathsep) 375 if not self.relocate_py_env: 376 if libdir in rpath: 377 rpath.insert(0, '$ORIGIN') 378 while libdir in rpath: 379 rpath.remove(libdir) 380 else: 381 rpathold = rpath 382 rpath = [] 383 # strip all rpath info, except for libraries in Python 384 # sys prefix, site-packages, or petsc/lib 385 rpath.insert(0, '$ORIGIN') 386 for libdir in rpathold: 387 if libdir.startswith(pysitedir): 388 libdir_from_petsc = os.path.relpath(libdir, petsclibdir) 389 rpath.insert(0, os.path.join('$ORIGIN',libdir_from_petsc)) 390 pylibdir_from_petsc = os.path.relpath(pylibdir, petsclibdir) 391 rpath.insert(0, os.path.join('$ORIGIN',pylibdir_from_petsc)) 392 if rpath: 393 rpath = os.path.pathsep.join(rpath) 394 shell('patchelf', '--set-rpath', "'%s'" % rpath, shlib) 395 # fix shared library file and symlink 396 basename = os.path.basename(shlib) 397 libname, ext, _ = basename.partition('.so') 398 liblink = libname + ext 399 soname = shell('patchelf', '--print-soname', shlib) 400 for symlink in lsdir(self.destLibDir, liblink + '*'): 401 if os.path.islink(symlink): 402 os.unlink(symlink) 403 curdir = os.getcwd() 404 try: 405 os.chdir(os.path.dirname(shlib)) 406 if soname != basename: 407 os.rename(basename, soname) 408 if soname != liblink: 409 with open(liblink, 'w') as f: 410 f.write('INPUT(' + soname + ')\n') 411 finally: 412 os.chdir(curdir) 413 if sys.platform == 'darwin': 414 def otool(cmd, dylib): 415 pattern = r''' 416 ^\s+ cmd \s %s$\n 417 ^\s+ cmdsize \s \d+$\n 418 ^\s+ (?:name|path) \s (.*) \s \(offset \s \d+\)$ 419 ''' % cmd 420 return re.findall( 421 pattern, shell('otool', '-l', dylib), 422 flags=re.VERBOSE | re.MULTILINE, 423 ) 424 libraries = [ 425 lib for lib in lsdir(self.destLibDir, 'lib*.dylib') 426 if not os.path.islink(lib) 427 ] 428 for dylib in libraries: 429 install_name = otool('LC_ID_DYLIB', dylib)[0] 430 dependencies = otool('LC_LOAD_DYLIB', dylib) 431 runtime_path = otool('LC_RPATH', dylib) 432 # fix shared library install name and rpath 433 install_name = '@rpath/' + os.path.basename(install_name) 434 shell('install_name_tool', '-id', install_name, dylib) 435 if libdir in runtime_path: 436 shell('install_name_tool', '-delete_rpath', libdir, dylib) 437 for rpath in ('@loader_path',): 438 if rpath not in runtime_path: 439 shell('install_name_tool', '-add_rpath', rpath, dylib) 440 for dep in dependencies: 441 if os.path.dirname(dep) in (libdir,): 442 newid = '@rpath/' + os.path.basename(dep) 443 shell('install_name_tool', '-change', dep, newid, dylib) 444 # fix shared library file and symlink 445 basename = os.path.basename(dylib) 446 libname, ext = os.path.splitext(basename) 447 libname = libname.partition('.')[0] 448 liblink = libname + ext 449 dyname = os.path.basename(install_name) 450 for symlink in lsdir(self.destLibDir, libname + '*' + ext): 451 if os.path.islink(symlink): 452 os.unlink(symlink) 453 curdir = os.getcwd() 454 try: 455 os.chdir(os.path.dirname(dylib)) 456 if dyname != basename: 457 os.rename(basename, dyname) 458 if dyname != liblink: 459 os.symlink(dyname, liblink) 460 finally: 461 os.chdir(curdir) 462 # 463 return 464 465 def createUninstaller(self): 466 uninstallscript = os.path.join(self.destConfDir, 'uninstall.py') 467 f = open(uninstallscript, 'w') 468 # Could use the Python AST to do this 469 f.write('#!'+sys.executable+'\n') 470 f.write('import os\n') 471 f.write('prefixdir = "'+self.installDir+'"\n') 472 files = [dst.replace(self.destDir,self.installDir) for src, dst in self.copies] 473 files.append(uninstallscript.replace(self.destDir,self.installDir)) 474 f.write('files = '+repr(files)) 475 f.write(''' 476for file in files: 477 if os.path.exists(file) or os.path.islink(file): 478 os.remove(file) 479 dir = os.path.dirname(file) 480 while dir not in [os.path.dirname(prefixdir),'/']: 481 try: os.rmdir(dir) 482 except: break 483 dir = os.path.dirname(dir) 484''') 485 f.close() 486 os.chmod(uninstallscript,0o744) 487 return 488 489 def installIncludes(self): 490 exclude = ['makefile'] 491 if not hasattr(self.compilers.setCompilers, 'FC'): 492 exclude.append('finclude') 493 if not self.mpi.usingMPIUni: 494 exclude.append('mpiuni') 495 self.copies.extend(self.copytree(self.rootIncludeDir, self.destIncludeDir,exclude = exclude)) 496 self.copies.extend(self.copytree(self.archIncludeDir, self.destIncludeDir)) 497 return 498 499 def installConf(self): 500 self.copies.extend(self.copytree(self.rootConfDir, self.destConfDir, exclude = ['test.log'])) 501 self.copies.extend(self.copytree(self.archConfDir, self.destConfDir, exclude = ['sowing', 'configure.log.bkp','configure.log','make.log','gmake.log','test.log','error.log','memoryerror.log','files','testfiles','RDict.db'])) 502 return 503 504 def installBin(self): 505 exclude = ['bib2html','doc2lt','doctext','mapnames', 'pstogif','pstoxbm','tohtml'] 506 self.copies.extend(self.copytree(self.archBinDir, self.destBinDir, exclude = exclude )) 507 exclude = ['maint'] 508 if not self.mpi.usingMPIUni: 509 exclude.append('petsc-mpiexec.uni') 510 self.setCompilers.pushLanguage('C') 511 if self.setCompilers.getCompiler().find('win32fe') < 0: 512 exclude.append('win32fe') 513 self.setCompilers.popLanguage() 514 self.copies.extend(self.copytree(self.rootBinDir, self.destBinDir, exclude = exclude )) 515 return 516 517 def installShare(self): 518 self.copies.extend(self.copytree(self.rootShareDir, self.destShareDir)) 519 examplesdir=os.path.join(self.destShareDir,'petsc','examples') 520 if os.path.exists(examplesdir): 521 shutil.rmtree(examplesdir) 522 os.mkdir(examplesdir) 523 os.mkdir(os.path.join(examplesdir,'src')) 524 self.copyConfig(self.rootDir,examplesdir) 525 if not self.argDB['no-examples']: 526 self.copyExamples(self.rootSrcDir,os.path.join(examplesdir,'src')) 527 self.fixExamplesMakefile(os.path.join(examplesdir,'gmakefile.test')) 528 return 529 530 def copyLib(self, src, dst): 531 '''Run ranlib on the destination library if it is an archive. Also run install_name_tool on dylib on Mac''' 532 # Symlinks (assumed local) are recreated at dst 533 if os.path.islink(src): 534 linkto = os.readlink(src) 535 try: 536 os.remove(dst) # In case it already exists 537 except OSError: 538 pass 539 os.symlink(linkto, dst) 540 return 541 shutil.copy2(src, dst) 542 if self.setCompilers.getCompiler().find('win32fe') < 0 and os.path.splitext(dst)[1] == '.'+self.arLibSuffix: 543 import shlex 544 self.executeShellCommand(shlex.split(self.ranlib) + [dst]) 545 if os.path.splitext(dst)[1] == '.dylib' and shutil.which('otool') and shutil.which('install_name_tool'): 546 [output,err,flg] = self.executeShellCommand(['otool', '-D', src]) 547 oldname = output[output.find("\n")+1:] 548 installName = oldname.replace(os.path.realpath(self.archDir), self.installDir) 549 self.executeShellCommand(['install_name_tool', '-id', installName, dst]) 550 # preserve the original timestamps - so that the .a vs .so time order is preserved 551 shutil.copystat(src,dst) 552 return 553 554 def installLib(self): 555 self.copies.extend(self.copytree(self.archLibDir, self.destLibDir, copyFunc = self.copyLib, exclude = ['.DIR'],recurse = 0)) 556 self.copies.extend(self.copytree(os.path.join(self.archLibDir,'pkgconfig'), os.path.join(self.destLibDir,'pkgconfig'), copyFunc = self.copyLib, exclude = ['.DIR'],recurse = 0)) 557 return 558 559 560 def outputInstallDone(self): 561 from config.packages.make import getMakeUserPath 562 print('''\ 563==================================== 564Install complete. 565Now to check if the libraries are working do (in current directory): 566%s PETSC_DIR=%s PETSC_ARCH="" check 567====================================\ 568''' % (getMakeUserPath(self.arch), self.installDir)) 569 return 570 571 def outputDestDirDone(self): 572 print('''\ 573==================================== 574Copy to DESTDIR %s is now complete. 575Before use - please copy/install over to specified prefix: %s 576====================================\ 577''' % (self.destDir,self.installDir)) 578 return 579 580 def runsetup(self): 581 self.setup() 582 self.setupDirectories() 583 self.setupBuild() 584 self.checkPrefix() 585 self.checkDestdir() 586 return 587 588 def runcopy(self): 589 if self.destDir == self.installDir: 590 print('*** Installing PETSc at prefix location:',self.destDir, ' ***') 591 else: 592 print('*** Copying PETSc to DESTDIR location:',self.destDir, ' ***') 593 if not os.path.exists(self.destDir): 594 try: 595 os.makedirs(self.destDir) 596 except: 597 print('********************************************************************') 598 print('Unable to create', self.destDir, 'Perhaps you need to do "sudo make install"') 599 print('********************************************************************') 600 sys.exit(1) 601 self.installIncludes() 602 self.installConf() 603 self.installBin() 604 self.installLib() 605 self.installShare() 606 self.createUninstaller() 607 return 608 609 def runfix(self): 610 self.fixConf() 611 if self.using_build_backend: 612 self.fixPythonWheel() 613 return 614 615 def rundone(self): 616 if self.destDir == self.installDir: 617 self.outputInstallDone() 618 else: 619 self.outputDestDirDone() 620 return 621 622 def run(self): 623 self.runsetup() 624 self.runcopy() 625 self.runfix() 626 self.rundone() 627 return 628 629if __name__ == '__main__': 630 Installer(sys.argv[1:]).run() 631 # temporary hack - delete log files created by BuildSystem - when 'sudo make install' is invoked 632 delfiles=['RDict.db','RDict.log','buildsystem.log','default.log','buildsystem.log.bkp','default.log.bkp'] 633 for delfile in delfiles: 634 if os.path.exists(delfile) and (os.stat(delfile).st_uid==0): 635 os.remove(delfile) 636