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