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